]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - drivers/scsi/advansys.c
[SCSI] advansys: Stop checking the scsi_cmnd belongs to our Scsi_Host
[mirror_ubuntu-artful-kernel.git] / drivers / scsi / advansys.c
CommitLineData
8c6af9e1 1#define ASC_VERSION "3.4" /* AdvanSys Driver Version */
1da177e4
LT
2
3/*
4 * advansys.c - Linux Host Driver for AdvanSys SCSI Adapters
5 *
6 * Copyright (c) 1995-2000 Advanced System Products, Inc.
7 * Copyright (c) 2000-2001 ConnectCom Solutions, Inc.
8c6af9e1 8 * Copyright (c) 2007 Matthew Wilcox <matthew@wil.cx>
1da177e4
LT
9 * All Rights Reserved.
10 *
8c6af9e1
MW
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 */
16
17/*
1da177e4
LT
18 * As of March 8, 2000 Advanced System Products, Inc. (AdvanSys)
19 * changed its name to ConnectCom Solutions, Inc.
8c6af9e1 20 * On June 18, 2001 Initio Corp. acquired ConnectCom's SCSI assets
1da177e4
LT
21 */
22
23/*
24
25 Documentation for the AdvanSys Driver
26
27 A. Linux Kernels Supported by this Driver
28 B. Adapters Supported by this Driver
29 C. Linux source files modified by AdvanSys Driver
30 D. Source Comments
31 E. Driver Compile Time Options and Debugging
32 F. Driver LILO Option
33 G. Tests to run before releasing new driver
34 H. Release History
35 I. Known Problems/Fix List
36 J. Credits (Chronological Order)
37
38 A. Linux Kernels Supported by this Driver
39
40 This driver has been tested in the following Linux kernels: v2.2.18
41 v2.4.0. The driver is supported on v2.2 and v2.4 kernels and on x86,
42 alpha, and PowerPC platforms.
43
44 B. Adapters Supported by this Driver
45
46 AdvanSys (Advanced System Products, Inc.) manufactures the following
47 RISC-based, Bus-Mastering, Fast (10 Mhz) and Ultra (20 Mhz) Narrow
48 (8-bit transfer) SCSI Host Adapters for the ISA, EISA, VL, and PCI
49 buses and RISC-based, Bus-Mastering, Ultra (20 Mhz) Wide (16-bit
50 transfer) SCSI Host Adapters for the PCI bus.
51
52 The CDB counts below indicate the number of SCSI CDB (Command
53 Descriptor Block) requests that can be stored in the RISC chip
54 cache and board LRAM. A CDB is a single SCSI command. The driver
55 detect routine will display the number of CDBs available for each
56 adapter detected. The number of CDBs used by the driver can be
57 lowered in the BIOS by changing the 'Host Queue Size' adapter setting.
58
59 Laptop Products:
60 ABP-480 - Bus-Master CardBus (16 CDB) (2.4 kernel and greater)
61
62 Connectivity Products:
63 ABP510/5150 - Bus-Master ISA (240 CDB)
64 ABP5140 - Bus-Master ISA PnP (16 CDB)
65 ABP5142 - Bus-Master ISA PnP with floppy (16 CDB)
66 ABP902/3902 - Bus-Master PCI (16 CDB)
67 ABP3905 - Bus-Master PCI (16 CDB)
68 ABP915 - Bus-Master PCI (16 CDB)
69 ABP920 - Bus-Master PCI (16 CDB)
70 ABP3922 - Bus-Master PCI (16 CDB)
71 ABP3925 - Bus-Master PCI (16 CDB)
72 ABP930 - Bus-Master PCI (16 CDB)
73 ABP930U - Bus-Master PCI Ultra (16 CDB)
74 ABP930UA - Bus-Master PCI Ultra (16 CDB)
75 ABP960 - Bus-Master PCI MAC/PC (16 CDB)
76 ABP960U - Bus-Master PCI MAC/PC Ultra (16 CDB)
77
78 Single Channel Products:
79 ABP542 - Bus-Master ISA with floppy (240 CDB)
80 ABP742 - Bus-Master EISA (240 CDB)
81 ABP842 - Bus-Master VL (240 CDB)
82 ABP940 - Bus-Master PCI (240 CDB)
83 ABP940U - Bus-Master PCI Ultra (240 CDB)
84 ABP940UA/3940UA - Bus-Master PCI Ultra (240 CDB)
85 ABP970 - Bus-Master PCI MAC/PC (240 CDB)
86 ABP970U - Bus-Master PCI MAC/PC Ultra (240 CDB)
87 ABP3960UA - Bus-Master PCI MAC/PC Ultra (240 CDB)
88 ABP940UW/3940UW - Bus-Master PCI Ultra-Wide (253 CDB)
89 ABP970UW - Bus-Master PCI MAC/PC Ultra-Wide (253 CDB)
90 ABP3940U2W - Bus-Master PCI LVD/Ultra2-Wide (253 CDB)
91
92 Multi-Channel Products:
93 ABP752 - Dual Channel Bus-Master EISA (240 CDB Per Channel)
94 ABP852 - Dual Channel Bus-Master VL (240 CDB Per Channel)
95 ABP950 - Dual Channel Bus-Master PCI (240 CDB Per Channel)
96 ABP950UW - Dual Channel Bus-Master PCI Ultra-Wide (253 CDB Per Channel)
97 ABP980 - Four Channel Bus-Master PCI (240 CDB Per Channel)
98 ABP980U - Four Channel Bus-Master PCI Ultra (240 CDB Per Channel)
99 ABP980UA/3980UA - Four Channel Bus-Master PCI Ultra (16 CDB Per Chan.)
100 ABP3950U2W - Bus-Master PCI LVD/Ultra2-Wide and Ultra-Wide (253 CDB)
101 ABP3950U3W - Bus-Master PCI Dual LVD2/Ultra3-Wide (253 CDB)
102
103 C. Linux source files modified by AdvanSys Driver
104
105 This section for historical purposes documents the changes
106 originally made to the Linux kernel source to add the advansys
107 driver. As Linux has changed some of these files have also
108 been modified.
109
110 1. linux/arch/i386/config.in:
111
112 bool 'AdvanSys SCSI support' CONFIG_SCSI_ADVANSYS y
113
114 2. linux/drivers/scsi/hosts.c:
115
116 #ifdef CONFIG_SCSI_ADVANSYS
117 #include "advansys.h"
118 #endif
119
d0be4a7d 120 and after "static struct scsi_host_template builtin_scsi_hosts[] =":
1da177e4
LT
121
122 #ifdef CONFIG_SCSI_ADVANSYS
123 ADVANSYS,
124 #endif
125
126 3. linux/drivers/scsi/Makefile:
127
128 ifdef CONFIG_SCSI_ADVANSYS
129 SCSI_SRCS := $(SCSI_SRCS) advansys.c
130 SCSI_OBJS := $(SCSI_OBJS) advansys.o
131 else
132 SCSI_MODULE_OBJS := $(SCSI_MODULE_OBJS) advansys.o
133 endif
134
135 4. linux/init/main.c:
136
137 extern void advansys_setup(char *str, int *ints);
138
139 and add the following lines to the bootsetups[] array.
140
141 #ifdef CONFIG_SCSI_ADVANSYS
142 { "advansys=", advansys_setup },
143 #endif
144
145 D. Source Comments
146
147 1. Use tab stops set to 4 for the source files. For vi use 'se tabstops=4'.
148
149 2. This driver should be maintained in multiple files. But to make
150 it easier to include with Linux and to follow Linux conventions,
151 the whole driver is maintained in the source files advansys.h and
152 advansys.c. In this file logical sections of the driver begin with
153 a comment that contains '---'. The following are the logical sections
154 of the driver below.
155
156 --- Linux Version
157 --- Linux Include File
158 --- Driver Options
159 --- Debugging Header
160 --- Asc Library Constants and Macros
161 --- Adv Library Constants and Macros
162 --- Driver Constants and Macros
163 --- Driver Structures
164 --- Driver Data
165 --- Driver Function Prototypes
d0be4a7d 166 --- Linux 'struct scsi_host_template' and advansys_setup() Functions
1da177e4
LT
167 --- Loadable Driver Support
168 --- Miscellaneous Driver Functions
169 --- Functions Required by the Asc Library
170 --- Functions Required by the Adv Library
171 --- Tracing and Debugging Functions
172 --- Asc Library Functions
173 --- Adv Library Functions
174
175 3. The string 'XXX' is used to flag code that needs to be re-written
176 or that contains a problem that needs to be addressed.
177
178 4. I have stripped comments from and reformatted the source for the
179 Asc Library and Adv Library to reduce the size of this file. This
180 source can be found under the following headings. The Asc Library
181 is used to support Narrow Boards. The Adv Library is used to
182 support Wide Boards.
183
184 --- Asc Library Constants and Macros
185 --- Adv Library Constants and Macros
186 --- Asc Library Functions
187 --- Adv Library Functions
188
189 E. Driver Compile Time Options and Debugging
190
191 In this source file the following constants can be defined. They are
192 defined in the source below. Both of these options are enabled by
193 default.
194
195 1. ADVANSYS_ASSERT - Enable driver assertions (Def: Enabled)
196
197 Enabling this option adds assertion logic statements to the
198 driver. If an assertion fails a message will be displayed to
199 the console, but the system will continue to operate. Any
200 assertions encountered should be reported to the person
201 responsible for the driver. Assertion statements may proactively
202 detect problems with the driver and facilitate fixing these
203 problems. Enabling assertions will add a small overhead to the
204 execution of the driver.
205
206 2. ADVANSYS_DEBUG - Enable driver debugging (Def: Disabled)
207
208 Enabling this option adds tracing functions to the driver and
209 the ability to set a driver tracing level at boot time. This
210 option will also export symbols not required outside the driver to
211 the kernel name space. This option is very useful for debugging
212 the driver, but it will add to the size of the driver execution
213 image and add overhead to the execution of the driver.
214
215 The amount of debugging output can be controlled with the global
216 variable 'asc_dbglvl'. The higher the number the more output. By
217 default the debug level is 0.
218
219 If the driver is loaded at boot time and the LILO Driver Option
220 is included in the system, the debug level can be changed by
221 specifying a 5th (ASC_NUM_IOPORT_PROBE + 1) I/O Port. The
222 first three hex digits of the pseudo I/O Port must be set to
223 'deb' and the fourth hex digit specifies the debug level: 0 - F.
224 The following command line will look for an adapter at 0x330
225 and set the debug level to 2.
226
227 linux advansys=0x330,0,0,0,0xdeb2
228
229 If the driver is built as a loadable module this variable can be
230 defined when the driver is loaded. The following insmod command
231 will set the debug level to one.
232
233 insmod advansys.o asc_dbglvl=1
234
235 Debugging Message Levels:
236 0: Errors Only
237 1: High-Level Tracing
238 2-N: Verbose Tracing
239
240 To enable debug output to console, please make sure that:
241
242 a. System and kernel logging is enabled (syslogd, klogd running).
243 b. Kernel messages are routed to console output. Check
244 /etc/syslog.conf for an entry similar to this:
245
246 kern.* /dev/console
247
248 c. klogd is started with the appropriate -c parameter
249 (e.g. klogd -c 8)
250
251 This will cause printk() messages to be be displayed on the
252 current console. Refer to the klogd(8) and syslogd(8) man pages
253 for details.
254
255 Alternatively you can enable printk() to console with this
256 program. However, this is not the 'official' way to do this.
257 Debug output is logged in /var/log/messages.
258
259 main()
260 {
261 syscall(103, 7, 0, 0);
262 }
263
264 Increasing LOG_BUF_LEN in kernel/printk.c to something like
265 40960 allows more debug messages to be buffered in the kernel
266 and written to the console or log file.
267
268 3. ADVANSYS_STATS - Enable statistics (Def: Enabled >= v1.3.0)
269
270 Enabling this option adds statistics collection and display
271 through /proc to the driver. The information is useful for
272 monitoring driver and device performance. It will add to the
273 size of the driver execution image and add minor overhead to
274 the execution of the driver.
275
276 Statistics are maintained on a per adapter basis. Driver entry
277 point call counts and transfer size counts are maintained.
278 Statistics are only available for kernels greater than or equal
279 to v1.3.0 with the CONFIG_PROC_FS (/proc) file system configured.
280
281 AdvanSys SCSI adapter files have the following path name format:
282
283 /proc/scsi/advansys/[0-(ASC_NUM_BOARD_SUPPORTED-1)]
284
285 This information can be displayed with cat. For example:
286
287 cat /proc/scsi/advansys/0
288
289 When ADVANSYS_STATS is not defined the AdvanSys /proc files only
290 contain adapter and device configuration information.
291
292 F. Driver LILO Option
293
294 If init/main.c is modified as described in the 'Directions for Adding
295 the AdvanSys Driver to Linux' section (B.4.) above, the driver will
296 recognize the 'advansys' LILO command line and /etc/lilo.conf option.
297 This option can be used to either disable I/O port scanning or to limit
298 scanning to 1 - 4 I/O ports. Regardless of the option setting EISA and
299 PCI boards will still be searched for and detected. This option only
300 affects searching for ISA and VL boards.
301
302 Examples:
303 1. Eliminate I/O port scanning:
304 boot: linux advansys=
305 or
306 boot: linux advansys=0x0
307 2. Limit I/O port scanning to one I/O port:
308 boot: linux advansys=0x110
309 3. Limit I/O port scanning to four I/O ports:
310 boot: linux advansys=0x110,0x210,0x230,0x330
311
312 For a loadable module the same effect can be achieved by setting
313 the 'asc_iopflag' variable and 'asc_ioport' array when loading
314 the driver, e.g.
315
316 insmod advansys.o asc_iopflag=1 asc_ioport=0x110,0x330
317
318 If ADVANSYS_DEBUG is defined a 5th (ASC_NUM_IOPORT_PROBE + 1)
319 I/O Port may be added to specify the driver debug level. Refer to
320 the 'Driver Compile Time Options and Debugging' section above for
321 more information.
322
323 G. Tests to run before releasing new driver
324
325 1. In the supported kernels verify there are no warning or compile
326 errors when the kernel is built as both a driver and as a module
327 and with the following options:
328
329 ADVANSYS_DEBUG - enabled and disabled
330 CONFIG_SMP - enabled and disabled
331 CONFIG_PROC_FS - enabled and disabled
332
333 2. Run tests on an x86, alpha, and PowerPC with at least one narrow
334 card and one wide card attached to a hard disk and CD-ROM drive:
335 fdisk, mkfs, fsck, bonnie, copy/compare test from the
336 CD-ROM to the hard drive.
337
338 H. Release History
339
340 BETA-1.0 (12/23/95):
341 First Release
342
343 BETA-1.1 (12/28/95):
344 1. Prevent advansys_detect() from being called twice.
345 2. Add LILO 0xdeb[0-f] option to set 'asc_dbglvl'.
346
347 1.2 (1/12/96):
348 1. Prevent re-entrancy in the interrupt handler which
349 resulted in the driver hanging Linux.
350 2. Fix problem that prevented ABP-940 cards from being
351 recognized on some PCI motherboards.
352 3. Add support for the ABP-5140 PnP ISA card.
353 4. Fix check condition return status.
354 5. Add conditionally compiled code for Linux v1.3.X.
355
356 1.3 (2/23/96):
357 1. Fix problem in advansys_biosparam() that resulted in the
358 wrong drive geometry being returned for drives > 1GB with
359 extended translation enabled.
360 2. Add additional tracing during device initialization.
361 3. Change code that only applies to ISA PnP adapter.
362 4. Eliminate 'make dep' warning.
363 5. Try to fix problem with handling resets by increasing their
364 timeout value.
365
366 1.4 (5/8/96):
367 1. Change definitions to eliminate conflicts with other subsystems.
368 2. Add versioning code for the shared interrupt changes.
369 3. Eliminate problem in asc_rmqueue() with iterating after removing
370 a request.
371 4. Remove reset request loop problem from the "Known Problems or
372 Issues" section. This problem was isolated and fixed in the
373 mid-level SCSI driver.
374
375 1.5 (8/8/96):
376 1. Add support for ABP-940U (PCI Ultra) adapter.
1d6f359a 377 2. Add support for IRQ sharing by setting the IRQF_SHARED flag for
1da177e4
LT
378 request_irq and supplying a dev_id pointer to both request_irq()
379 and free_irq().
380 3. In AscSearchIOPortAddr11() restore a call to check_region() which
381 should be used before I/O port probing.
382 4. Fix bug in asc_prt_hex() which resulted in the displaying
383 the wrong data.
384 5. Incorporate miscellaneous Asc Library bug fixes and new microcode.
385 6. Change driver versioning to be specific to each Linux sub-level.
386 7. Change statistics gathering to be per adapter instead of global
387 to the driver.
388 8. Add more information and statistics to the adapter /proc file:
389 /proc/scsi/advansys[0...].
390 9. Remove 'cmd_per_lun' from the "Known Problems or Issues" list.
391 This problem has been addressed with the SCSI mid-level changes
392 made in v1.3.89. The advansys_select_queue_depths() function
393 was added for the v1.3.89 changes.
394
395 1.6 (9/10/96):
396 1. Incorporate miscellaneous Asc Library bug fixes and new microcode.
397
398 1.7 (9/25/96):
399 1. Enable clustering and optimize the setting of the maximum number
400 of scatter gather elements for any particular board. Clustering
401 increases CPU utilization, but results in a relatively larger
402 increase in I/O throughput.
403 2. Improve the performance of the request queuing functions by
404 adding a last pointer to the queue structure.
405 3. Correct problems with reset and abort request handling that
406 could have hung or crashed Linux.
407 4. Add more information to the adapter /proc file:
408 /proc/scsi/advansys[0...].
409 5. Remove the request timeout issue form the driver issues list.
410 6. Miscellaneous documentation additions and changes.
411
412 1.8 (10/4/96):
413 1. Make changes to handle the new v2.1.0 kernel memory mapping
414 in which a kernel virtual address may not be equivalent to its
415 bus or DMA memory address.
416 2. Change abort and reset request handling to make it yet even
417 more robust.
418 3. Try to mitigate request starvation by sending ordered requests
419 to heavily loaded, tag queuing enabled devices.
420 4. Maintain statistics on request response time.
421 5. Add request response time statistics and other information to
422 the adapter /proc file: /proc/scsi/advansys[0...].
423
424 1.9 (10/21/96):
425 1. Add conditionally compiled code (ASC_QUEUE_FLOW_CONTROL) to
426 make use of mid-level SCSI driver device queue depth flow
427 control mechanism. This will eliminate aborts caused by a
428 device being unable to keep up with requests and eliminate
429 repeat busy or QUEUE FULL status returned by a device.
430 2. Incorporate miscellaneous Asc Library bug fixes.
431 3. To allow the driver to work in kernels with broken module
432 support set 'cmd_per_lun' if the driver is compiled as a
433 module. This change affects kernels v1.3.89 to present.
434 4. Remove PCI BIOS address from the driver banner. The PCI BIOS
435 is relocated by the motherboard BIOS and its new address can
436 not be determined by the driver.
437 5. Add mid-level SCSI queue depth information to the adapter
438 /proc file: /proc/scsi/advansys[0...].
439
440 2.0 (11/14/96):
441 1. Change allocation of global structures used for device
442 initialization to guarantee they are in DMA-able memory.
443 Previously when the driver was loaded as a module these
444 structures might not have been in DMA-able memory, causing
445 device initialization to fail.
446
447 2.1 (12/30/96):
448 1. In advansys_reset(), if the request is a synchronous reset
449 request, even if the request serial number has changed, then
450 complete the request.
451 2. Add Asc Library bug fixes including new microcode.
452 3. Clear inquiry buffer before using it.
453 4. Correct ifdef typo.
454
455 2.2 (1/15/97):
456 1. Add Asc Library bug fixes including new microcode.
457 2. Add synchronous data transfer rate information to the
458 adapter /proc file: /proc/scsi/advansys[0...].
459 3. Change ADVANSYS_DEBUG to be disabled by default. This
460 will reduce the size of the driver image, eliminate execution
461 overhead, and remove unneeded symbols from the kernel symbol
462 space that were previously added by the driver.
463 4. Add new compile-time option ADVANSYS_ASSERT for assertion
464 code that used to be defined within ADVANSYS_DEBUG. This
465 option is enabled by default.
466
467 2.8 (5/26/97):
468 1. Change version number to 2.8 to synchronize the Linux driver
469 version numbering with other AdvanSys drivers.
470 2. Reformat source files without tabs to present the same view
471 of the file to everyone regardless of the editor tab setting
472 being used.
473 3. Add Asc Library bug fixes.
474
475 3.1A (1/8/98):
476 1. Change version number to 3.1 to indicate that support for
477 Ultra-Wide adapters (ABP-940UW) is included in this release.
478 2. Add Asc Library (Narrow Board) bug fixes.
479 3. Report an underrun condition with the host status byte set
480 to DID_UNDERRUN. Currently DID_UNDERRUN is defined to 0 which
481 causes the underrun condition to be ignored. When Linux defines
482 its own DID_UNDERRUN the constant defined in this file can be
483 removed.
484 4. Add patch to AscWaitTixISRDone().
485 5. Add support for up to 16 different AdvanSys host adapter SCSI
486 channels in one system. This allows four cards with four channels
487 to be used in one system.
488
489 3.1B (1/9/98):
490 1. Handle that PCI register base addresses are not always page
491 aligned even though ioremap() requires that the address argument
492 be page aligned.
493
494 3.1C (1/10/98):
495 1. Update latest BIOS version checked for from the /proc file.
496 2. Don't set microcode SDTR variable at initialization. Instead
497 wait until device capabilities have been detected from an Inquiry
498 command.
499
500 3.1D (1/21/98):
501 1. Improve performance when the driver is compiled as module by
502 allowing up to 64 scatter-gather elements instead of 8.
503
504 3.1E (5/1/98):
505 1. Set time delay in AscWaitTixISRDone() to 1000 ms.
506 2. Include SMP locking changes.
507 3. For v2.1.93 and newer kernels use CONFIG_PCI and new PCI BIOS
508 access functions.
509 4. Update board serial number printing.
1d6f359a 510 5. Try allocating an IRQ both with and without the IRQF_DISABLED
1da177e4 511 flag set to allow IRQ sharing with drivers that do not set
1d6f359a 512 the IRQF_DISABLED flag. Also display a more descriptive error
1da177e4
LT
513 message if request_irq() fails.
514 6. Update to latest Asc and Adv Libraries.
515
516 3.2A (7/22/99):
517 1. Update Adv Library to 4.16 which includes support for
518 the ASC38C0800 (Ultra2/LVD) IC.
519
520 3.2B (8/23/99):
521 1. Correct PCI compile time option for v2.1.93 and greater
522 kernels, advansys_info() string, and debug compile time
523 option.
524 2. Correct DvcSleepMilliSecond() for v2.1.0 and greater
525 kernels. This caused an LVD detection/BIST problem problem
526 among other things.
527 3. Sort PCI cards by PCI Bus, Slot, Function ascending order
528 to be consistent with the BIOS.
529 4. Update to Asc Library S121 and Adv Library 5.2.
530
531 3.2C (8/24/99):
532 1. Correct PCI card detection bug introduced in 3.2B that
533 prevented PCI cards from being detected in kernels older
534 than v2.1.93.
535
536 3.2D (8/26/99):
537 1. Correct /proc device synchronous speed information display.
538 Also when re-negotiation is pending for a target device
539 note this condition with an * and footnote.
540 2. Correct initialization problem with Ultra-Wide cards that
541 have a pre-3.2 BIOS. A microcode variable changed locations
542 in 3.2 and greater BIOSes which caused WDTR to be attempted
543 erroneously with drives that don't support WDTR.
544
545 3.2E (8/30/99):
546 1. Fix compile error caused by v2.3.13 PCI structure change.
547 2. Remove field from ASCEEP_CONFIG that resulted in an EEPROM
548 checksum error for ISA cards.
549 3. Remove ASC_QUEUE_FLOW_CONTROL conditional code. The mid-level
550 SCSI changes that it depended on were never included in Linux.
551
552 3.2F (9/3/99):
553 1. Handle new initial function code added in v2.3.16 for all
554 driver versions.
555
556 3.2G (9/8/99):
557 1. Fix PCI board detection in v2.3.13 and greater kernels.
558 2. Fix comiple errors in v2.3.X with debugging enabled.
559
560 3.2H (9/13/99):
561 1. Add 64-bit address, long support for Alpha and UltraSPARC.
562 The driver has been verified to work on an Alpha system.
563 2. Add partial byte order handling support for Power PC and
564 other big-endian platforms. This support has not yet been
565 completed or verified.
566 3. For wide boards replace block zeroing of request and
567 scatter-gather structures with individual field initialization
568 to improve performance.
569 4. Correct and clarify ROM BIOS version detection.
570
571 3.2I (10/8/99):
572 1. Update to Adv Library 5.4.
573 2. Add v2.3.19 underrun reporting to asc_isr_callback() and
574 adv_isr_callback(). Remove DID_UNDERRUN constant and other
575 no longer needed code that previously documented the lack
576 of underrun handling.
577
578 3.2J (10/14/99):
579 1. Eliminate compile errors for v2.0 and earlier kernels.
580
581 3.2K (11/15/99):
582 1. Correct debug compile error in asc_prt_adv_scsi_req_q().
583 2. Update Adv Library to 5.5.
584 3. Add ifdef handling for /proc changes added in v2.3.28.
585 4. Increase Wide board scatter-gather list maximum length to
586 255 when the driver is compiled into the kernel.
587
588 3.2L (11/18/99):
589 1. Fix bug in adv_get_sglist() that caused an assertion failure
590 at line 7475. The reqp->sgblkp pointer must be initialized
591 to NULL in adv_get_sglist().
592
593 3.2M (11/29/99):
594 1. Really fix bug in adv_get_sglist().
595 2. Incorporate v2.3.29 changes into driver.
596
597 3.2N (4/1/00):
598 1. Add CONFIG_ISA ifdef code.
599 2. Include advansys_interrupts_enabled name change patch.
600 3. For >= v2.3.28 use new SCSI error handling with new function
601 advansys_eh_bus_reset(). Don't include an abort function
602 because of base library limitations.
603 4. For >= v2.3.28 use per board lock instead of io_request_lock.
604 5. For >= v2.3.28 eliminate advansys_command() and
605 advansys_command_done().
606 6. Add some changes for PowerPC (Big Endian) support, but it isn't
607 working yet.
608 7. Fix "nonexistent resource free" problem that occurred on a module
609 unload for boards with an I/O space >= 255. The 'n_io_port' field
610 is only one byte and can not be used to hold an ioport length more
611 than 255.
612
613 3.3A (4/4/00):
614 1. Update to Adv Library 5.8.
615 2. For wide cards add support for CDBs up to 16 bytes.
616 3. Eliminate warnings when CONFIG_PROC_FS is not defined.
617
618 3.3B (5/1/00):
619 1. Support for PowerPC (Big Endian) wide cards. Narrow cards
620 still need work.
621 2. Change bitfields to shift and mask access for endian
622 portability.
623
624 3.3C (10/13/00):
625 1. Update for latest 2.4 kernel.
626 2. Test ABP-480 CardBus support in 2.4 kernel - works!
627 3. Update to Asc Library S123.
628 4. Update to Adv Library 5.12.
629
630 3.3D (11/22/00):
631 1. Update for latest 2.4 kernel.
632 2. Create patches for 2.2 and 2.4 kernels.
633
634 3.3E (1/9/01):
635 1. Now that 2.4 is released remove ifdef code for kernel versions
636 less than 2.2. The driver is now only supported in kernels 2.2,
637 2.4, and greater.
638 2. Add code to release and acquire the io_request_lock in
639 the driver entrypoint functions: advansys_detect and
640 advansys_queuecommand. In kernel 2.4 the SCSI mid-level driver
641 still holds the io_request_lock on entry to SCSI low-level drivers.
642 This was supposed to be removed before 2.4 was released but never
643 happened. When the mid-level SCSI driver is changed all references
644 to the io_request_lock should be removed from the driver.
645 3. Simplify error handling by removing advansys_abort(),
646 AscAbortSRB(), AscResetDevice(). SCSI bus reset requests are
647 now handled by resetting the SCSI bus and fully re-initializing
648 the chip. This simple method of error recovery has proven to work
649 most reliably after attempts at different methods. Also now only
650 support the "new" error handling method and remove the obsolete
651 error handling interface.
652 4. Fix debug build errors.
653
654 3.3F (1/24/01):
655 1. Merge with ConnectCom version from Andy Kellner which
656 updates Adv Library to 5.14.
657 2. Make PowerPC (Big Endian) work for narrow cards and
658 fix problems writing EEPROM for wide cards.
659 3. Remove interrupts_enabled assertion function.
660
661 3.3G (2/16/01):
662 1. Return an error from narrow boards if passed a 16 byte
663 CDB. The wide board can already handle 16 byte CDBs.
664
665 3.3GJ (4/15/02):
666 1. hacks for lk 2.5 series (D. Gilbert)
667
668 3.3GJD (10/14/02):
669 1. change select_queue_depths to slave_configure
670 2. make cmd_per_lun be sane again
671
672 3.3K [2004/06/24]:
673 1. continuing cleanup for lk 2.6 series
674 2. Fix problem in lk 2.6.7-bk2 that broke PCI wide cards
675 3. Fix problem that oopsed ISA cards
676
677 I. Known Problems/Fix List (XXX)
678
679 1. Need to add memory mapping workaround. Test the memory mapping.
680 If it doesn't work revert to I/O port access. Can a test be done
681 safely?
682 2. Handle an interrupt not working. Keep an interrupt counter in
683 the interrupt handler. In the timeout function if the interrupt
684 has not occurred then print a message and run in polled mode.
685 3. Allow bus type scanning order to be changed.
686 4. Need to add support for target mode commands, cf. CAM XPT.
687
688 J. Credits (Chronological Order)
689
690 Bob Frey <bfrey@turbolinux.com.cn> wrote the AdvanSys SCSI driver
691 and maintained it up to 3.3F. He continues to answer questions
692 and help maintain the driver.
693
694 Nathan Hartwell <mage@cdc3.cdc.net> provided the directions and
695 basis for the Linux v1.3.X changes which were included in the
696 1.2 release.
697
698 Thomas E Zerucha <zerucha@shell.portal.com> pointed out a bug
699 in advansys_biosparam() which was fixed in the 1.3 release.
700
701 Erik Ratcliffe <erik@caldera.com> has done testing of the
702 AdvanSys driver in the Caldera releases.
703
704 Rik van Riel <H.H.vanRiel@fys.ruu.nl> provided a patch to
705 AscWaitTixISRDone() which he found necessary to make the
706 driver work with a SCSI-1 disk.
707
708 Mark Moran <mmoran@mmoran.com> has helped test Ultra-Wide
709 support in the 3.1A driver.
710
711 Doug Gilbert <dgilbert@interlog.com> has made changes and
712 suggestions to improve the driver and done a lot of testing.
713
714 Ken Mort <ken@mort.net> reported a DEBUG compile bug fixed
715 in 3.2K.
716
717 Tom Rini <trini@kernel.crashing.org> provided the CONFIG_ISA
718 patch and helped with PowerPC wide and narrow board support.
719
720 Philip Blundell <philb@gnu.org> provided an
721 advansys_interrupts_enabled patch.
722
723 Dave Jones <dave@denial.force9.co.uk> reported the compiler
724 warnings generated when CONFIG_PROC_FS was not defined in
725 the 3.2M driver.
726
727 Jerry Quinn <jlquinn@us.ibm.com> fixed PowerPC support (endian
728 problems) for wide cards.
729
730 Bryan Henderson <bryanh@giraffe-data.com> helped debug narrow
731 card error handling.
732
733 Manuel Veloso <veloso@pobox.com> worked hard on PowerPC narrow
734 board support and fixed a bug in AscGetEEPConfig().
735
736 Arnaldo Carvalho de Melo <acme@conectiva.com.br> made
737 save_flags/restore_flags changes.
738
739 Andy Kellner <AKellner@connectcom.net> continues the Advansys SCSI
740 driver development for ConnectCom (Version > 3.3F).
741
742 K. ConnectCom (AdvanSys) Contact Information
743
744 Mail: ConnectCom Solutions, Inc.
745 1150 Ringwood Court
746 San Jose, CA 95131
747 Operator/Sales: 1-408-383-9400
748 FAX: 1-408-383-9612
749 Tech Support: 1-408-467-2930
750 Tech Support E-Mail: linux@connectcom.net
751 FTP Site: ftp.connectcom.net (login: anonymous)
752 Web Site: http://www.connectcom.net
753
754*/
755
756/*
757 * --- Linux Include Files
758 */
759
1da177e4 760#include <linux/module.h>
1da177e4
LT
761#include <linux/string.h>
762#include <linux/kernel.h>
763#include <linux/types.h>
764#include <linux/ioport.h>
765#include <linux/interrupt.h>
766#include <linux/delay.h>
767#include <linux/slab.h>
768#include <linux/mm.h>
769#include <linux/proc_fs.h>
770#include <linux/init.h>
771#include <linux/blkdev.h>
8c6af9e1 772#include <linux/pci.h>
1da177e4
LT
773#include <linux/spinlock.h>
774#include <linux/dma-mapping.h>
775
776#include <asm/io.h>
777#include <asm/system.h>
778#include <asm/dma.h>
779
8c6af9e1
MW
780#include <scsi/scsi_cmnd.h>
781#include <scsi/scsi_device.h>
782#include <scsi/scsi_tcq.h>
783#include <scsi/scsi.h>
784#include <scsi/scsi_host.h>
785
1da177e4
LT
786/* FIXME: (by jejb@steeleye.com) This warning is present for two
787 * reasons:
788 *
789 * 1) This driver badly needs converting to the correct driver model
790 * probing API
791 *
792 * 2) Although all of the necessary command mapping places have the
793 * appropriate dma_map.. APIs, the driver still processes its internal
794 * queue using bus_to_virt() and virt_to_bus() which are illegal under
795 * the API. The entire queue processing structure will need to be
796 * altered to fix this.
797 */
798#warning this driver is still not properly converted to the DMA API
799
1da177e4
LT
800/*
801 * --- Driver Options
802 */
803
804/* Enable driver assertions. */
805#define ADVANSYS_ASSERT
806
807/* Enable driver /proc statistics. */
808#define ADVANSYS_STATS
809
810/* Enable driver tracing. */
811/* #define ADVANSYS_DEBUG */
812
1da177e4
LT
813/*
814 * --- Asc Library Constants and Macros
815 */
816
817#define ASC_LIB_VERSION_MAJOR 1
818#define ASC_LIB_VERSION_MINOR 24
819#define ASC_LIB_SERIAL_NUMBER 123
820
821/*
822 * Portable Data Types
823 *
824 * Any instance where a 32-bit long or pointer type is assumed
825 * for precision or HW defined structures, the following define
826 * types must be used. In Linux the char, short, and int types
827 * are all consistent at 8, 16, and 32 bits respectively. Pointers
828 * and long types are 64 bits on Alpha and UltraSPARC.
829 */
27c868c2
MW
830#define ASC_PADDR __u32 /* Physical/Bus address data type. */
831#define ASC_VADDR __u32 /* Virtual address data type. */
832#define ASC_DCNT __u32 /* Unsigned Data count type. */
833#define ASC_SDCNT __s32 /* Signed Data count type. */
1da177e4
LT
834
835/*
836 * These macros are used to convert a virtual address to a
837 * 32-bit value. This currently can be used on Linux Alpha
838 * which uses 64-bit virtual address but a 32-bit bus address.
839 * This is likely to break in the future, but doing this now
840 * will give us time to change the HW and FW to handle 64-bit
841 * addresses.
842 */
843#define ASC_VADDR_TO_U32 virt_to_bus
844#define ASC_U32_TO_VADDR bus_to_virt
845
846typedef unsigned char uchar;
847
848#ifndef TRUE
849#define TRUE (1)
850#endif
851#ifndef FALSE
852#define FALSE (0)
853#endif
854
855#define EOF (-1)
856#define ERR (-1)
857#define UW_ERR (uint)(0xFFFF)
858#define isodd_word(val) ((((uint)val) & (uint)0x0001) != 0)
859#define AscPCIConfigVendorIDRegister 0x0000
860#define AscPCIConfigDeviceIDRegister 0x0002
861#define AscPCIConfigCommandRegister 0x0004
862#define AscPCIConfigStatusRegister 0x0006
863#define AscPCIConfigRevisionIDRegister 0x0008
864#define AscPCIConfigCacheSize 0x000C
865#define AscPCIConfigLatencyTimer 0x000D
866#define AscPCIIOBaseRegister 0x0010
867#define AscPCICmdRegBits_IOMemBusMaster 0x0007
868#define ASC_PCI_ID2BUS(id) ((id) & 0xFF)
869#define ASC_PCI_ID2DEV(id) (((id) >> 11) & 0x1F)
870#define ASC_PCI_ID2FUNC(id) (((id) >> 8) & 0x7)
871#define ASC_PCI_MKID(bus, dev, func) ((((dev) & 0x1F) << 11) | (((func) & 0x7) << 8) | ((bus) & 0xFF))
1da177e4
LT
872#define ASC_PCI_REVISION_3150 0x02
873#define ASC_PCI_REVISION_3050 0x03
874
875#define ASC_DVCLIB_CALL_DONE (1)
876#define ASC_DVCLIB_CALL_FAILED (0)
877#define ASC_DVCLIB_CALL_ERROR (-1)
878
2672ea86
DJ
879#define PCI_VENDOR_ID_ASP 0x10cd
880#define PCI_DEVICE_ID_ASP_1200A 0x1100
881#define PCI_DEVICE_ID_ASP_ABP940 0x1200
882#define PCI_DEVICE_ID_ASP_ABP940U 0x1300
883#define PCI_DEVICE_ID_ASP_ABP940UW 0x2300
884#define PCI_DEVICE_ID_38C0800_REV1 0x2500
885#define PCI_DEVICE_ID_38C1600_REV1 0x2700
886
1da177e4
LT
887/*
888 * Enable CC_VERY_LONG_SG_LIST to support up to 64K element SG lists.
889 * The SRB structure will have to be changed and the ASC_SRB2SCSIQ()
890 * macro re-defined to be able to obtain a ASC_SCSI_Q pointer from the
891 * SRB structure.
892 */
893#define CC_VERY_LONG_SG_LIST 0
894#define ASC_SRB2SCSIQ(srb_ptr) (srb_ptr)
895
27c868c2 896#define PortAddr unsigned short /* port address size */
1da177e4
LT
897#define inp(port) inb(port)
898#define outp(port, byte) outb((byte), (port))
899
900#define inpw(port) inw(port)
901#define outpw(port, word) outw((word), (port))
902
903#define ASC_MAX_SG_QUEUE 7
904#define ASC_MAX_SG_LIST 255
905
906#define ASC_CS_TYPE unsigned short
907
908#define ASC_IS_ISA (0x0001)
909#define ASC_IS_ISAPNP (0x0081)
910#define ASC_IS_EISA (0x0002)
911#define ASC_IS_PCI (0x0004)
912#define ASC_IS_PCI_ULTRA (0x0104)
913#define ASC_IS_PCMCIA (0x0008)
914#define ASC_IS_MCA (0x0020)
915#define ASC_IS_VL (0x0040)
916#define ASC_ISA_PNP_PORT_ADDR (0x279)
917#define ASC_ISA_PNP_PORT_WRITE (ASC_ISA_PNP_PORT_ADDR+0x800)
918#define ASC_IS_WIDESCSI_16 (0x0100)
919#define ASC_IS_WIDESCSI_32 (0x0200)
920#define ASC_IS_BIG_ENDIAN (0x8000)
921#define ASC_CHIP_MIN_VER_VL (0x01)
922#define ASC_CHIP_MAX_VER_VL (0x07)
923#define ASC_CHIP_MIN_VER_PCI (0x09)
924#define ASC_CHIP_MAX_VER_PCI (0x0F)
925#define ASC_CHIP_VER_PCI_BIT (0x08)
926#define ASC_CHIP_MIN_VER_ISA (0x11)
927#define ASC_CHIP_MIN_VER_ISA_PNP (0x21)
928#define ASC_CHIP_MAX_VER_ISA (0x27)
929#define ASC_CHIP_VER_ISA_BIT (0x30)
930#define ASC_CHIP_VER_ISAPNP_BIT (0x20)
931#define ASC_CHIP_VER_ASYN_BUG (0x21)
932#define ASC_CHIP_VER_PCI 0x08
933#define ASC_CHIP_VER_PCI_ULTRA_3150 (ASC_CHIP_VER_PCI | 0x02)
934#define ASC_CHIP_VER_PCI_ULTRA_3050 (ASC_CHIP_VER_PCI | 0x03)
935#define ASC_CHIP_MIN_VER_EISA (0x41)
936#define ASC_CHIP_MAX_VER_EISA (0x47)
937#define ASC_CHIP_VER_EISA_BIT (0x40)
938#define ASC_CHIP_LATEST_VER_EISA ((ASC_CHIP_MIN_VER_EISA - 1) + 3)
939#define ASC_MAX_LIB_SUPPORTED_ISA_CHIP_VER 0x21
940#define ASC_MAX_LIB_SUPPORTED_PCI_CHIP_VER 0x0A
941#define ASC_MAX_VL_DMA_ADDR (0x07FFFFFFL)
942#define ASC_MAX_VL_DMA_COUNT (0x07FFFFFFL)
943#define ASC_MAX_PCI_DMA_ADDR (0xFFFFFFFFL)
944#define ASC_MAX_PCI_DMA_COUNT (0xFFFFFFFFL)
945#define ASC_MAX_ISA_DMA_ADDR (0x00FFFFFFL)
946#define ASC_MAX_ISA_DMA_COUNT (0x00FFFFFFL)
947#define ASC_MAX_EISA_DMA_ADDR (0x07FFFFFFL)
948#define ASC_MAX_EISA_DMA_COUNT (0x07FFFFFFL)
949
950#define ASC_SCSI_ID_BITS 3
951#define ASC_SCSI_TIX_TYPE uchar
952#define ASC_ALL_DEVICE_BIT_SET 0xFF
953#define ASC_SCSI_BIT_ID_TYPE uchar
954#define ASC_MAX_TID 7
955#define ASC_MAX_LUN 7
956#define ASC_SCSI_WIDTH_BIT_SET 0xFF
957#define ASC_MAX_SENSE_LEN 32
958#define ASC_MIN_SENSE_LEN 14
959#define ASC_MAX_CDB_LEN 12
960#define ASC_SCSI_RESET_HOLD_TIME_US 60
961
962#define ADV_INQ_CLOCKING_ST_ONLY 0x0
963#define ADV_INQ_CLOCKING_DT_ONLY 0x1
964#define ADV_INQ_CLOCKING_ST_AND_DT 0x3
965
966/*
967 * Inquiry SPC-2 SPI Byte 1 EVPD (Enable Vital Product Data)
968 * and CmdDt (Command Support Data) field bit definitions.
969 */
970#define ADV_INQ_RTN_VPD_AND_CMDDT 0x3
971#define ADV_INQ_RTN_CMDDT_FOR_OP_CODE 0x2
972#define ADV_INQ_RTN_VPD_FOR_PG_CODE 0x1
973#define ADV_INQ_RTN_STD_INQUIRY_DATA 0x0
974
975#define ASC_SCSIDIR_NOCHK 0x00
976#define ASC_SCSIDIR_T2H 0x08
977#define ASC_SCSIDIR_H2T 0x10
978#define ASC_SCSIDIR_NODATA 0x18
979#define SCSI_ASC_NOMEDIA 0x3A
980#define ASC_SRB_HOST(x) ((uchar)((uchar)(x) >> 4))
981#define ASC_SRB_TID(x) ((uchar)((uchar)(x) & (uchar)0x0F))
982#define ASC_SRB_LUN(x) ((uchar)((uint)(x) >> 13))
983#define PUT_CDB1(x) ((uchar)((uint)(x) >> 8))
984#define MS_CMD_DONE 0x00
985#define MS_EXTEND 0x01
986#define MS_SDTR_LEN 0x03
987#define MS_SDTR_CODE 0x01
988#define MS_WDTR_LEN 0x02
989#define MS_WDTR_CODE 0x03
990#define MS_MDP_LEN 0x05
991#define MS_MDP_CODE 0x00
992
993/*
994 * Inquiry data structure and bitfield macros
995 *
996 * Only quantities of more than 1 bit are shifted, since the others are
997 * just tested for true or false. C bitfields aren't portable between big
998 * and little-endian platforms so they are not used.
999 */
1000
1001#define ASC_INQ_DVC_TYPE(inq) ((inq)->periph & 0x1f)
1002#define ASC_INQ_QUALIFIER(inq) (((inq)->periph & 0xe0) >> 5)
1003#define ASC_INQ_DVC_TYPE_MOD(inq) ((inq)->devtype & 0x7f)
1004#define ASC_INQ_REMOVABLE(inq) ((inq)->devtype & 0x80)
1005#define ASC_INQ_ANSI_VER(inq) ((inq)->ver & 0x07)
1006#define ASC_INQ_ECMA_VER(inq) (((inq)->ver & 0x38) >> 3)
1007#define ASC_INQ_ISO_VER(inq) (((inq)->ver & 0xc0) >> 6)
1008#define ASC_INQ_RESPONSE_FMT(inq) ((inq)->byte3 & 0x0f)
1009#define ASC_INQ_TERM_IO(inq) ((inq)->byte3 & 0x40)
1010#define ASC_INQ_ASYNC_NOTIF(inq) ((inq)->byte3 & 0x80)
1011#define ASC_INQ_SOFT_RESET(inq) ((inq)->flags & 0x01)
1012#define ASC_INQ_CMD_QUEUE(inq) ((inq)->flags & 0x02)
1013#define ASC_INQ_LINK_CMD(inq) ((inq)->flags & 0x08)
1014#define ASC_INQ_SYNC(inq) ((inq)->flags & 0x10)
1015#define ASC_INQ_WIDE16(inq) ((inq)->flags & 0x20)
1016#define ASC_INQ_WIDE32(inq) ((inq)->flags & 0x40)
1017#define ASC_INQ_REL_ADDR(inq) ((inq)->flags & 0x80)
1018#define ASC_INQ_INFO_UNIT(inq) ((inq)->info & 0x01)
1019#define ASC_INQ_QUICK_ARB(inq) ((inq)->info & 0x02)
1020#define ASC_INQ_CLOCKING(inq) (((inq)->info & 0x0c) >> 2)
1021
1022typedef struct {
27c868c2
MW
1023 uchar periph;
1024 uchar devtype;
1025 uchar ver;
1026 uchar byte3;
1027 uchar add_len;
1028 uchar res1;
1029 uchar res2;
1030 uchar flags;
1031 uchar vendor_id[8];
1032 uchar product_id[16];
1033 uchar product_rev_level[4];
1da177e4
LT
1034} ASC_SCSI_INQUIRY;
1035
1036#define ASC_SG_LIST_PER_Q 7
1037#define QS_FREE 0x00
1038#define QS_READY 0x01
1039#define QS_DISC1 0x02
1040#define QS_DISC2 0x04
1041#define QS_BUSY 0x08
1042#define QS_ABORTED 0x40
1043#define QS_DONE 0x80
1044#define QC_NO_CALLBACK 0x01
1045#define QC_SG_SWAP_QUEUE 0x02
1046#define QC_SG_HEAD 0x04
1047#define QC_DATA_IN 0x08
1048#define QC_DATA_OUT 0x10
1049#define QC_URGENT 0x20
1050#define QC_MSG_OUT 0x40
1051#define QC_REQ_SENSE 0x80
1052#define QCSG_SG_XFER_LIST 0x02
1053#define QCSG_SG_XFER_MORE 0x04
1054#define QCSG_SG_XFER_END 0x08
1055#define QD_IN_PROGRESS 0x00
1056#define QD_NO_ERROR 0x01
1057#define QD_ABORTED_BY_HOST 0x02
1058#define QD_WITH_ERROR 0x04
1059#define QD_INVALID_REQUEST 0x80
1060#define QD_INVALID_HOST_NUM 0x81
1061#define QD_INVALID_DEVICE 0x82
1062#define QD_ERR_INTERNAL 0xFF
1063#define QHSTA_NO_ERROR 0x00
1064#define QHSTA_M_SEL_TIMEOUT 0x11
1065#define QHSTA_M_DATA_OVER_RUN 0x12
1066#define QHSTA_M_DATA_UNDER_RUN 0x12
1067#define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
1068#define QHSTA_M_BAD_BUS_PHASE_SEQ 0x14
1069#define QHSTA_D_QDONE_SG_LIST_CORRUPTED 0x21
1070#define QHSTA_D_ASC_DVC_ERROR_CODE_SET 0x22
1071#define QHSTA_D_HOST_ABORT_FAILED 0x23
1072#define QHSTA_D_EXE_SCSI_Q_FAILED 0x24
1073#define QHSTA_D_EXE_SCSI_Q_BUSY_TIMEOUT 0x25
1074#define QHSTA_D_ASPI_NO_BUF_POOL 0x26
1075#define QHSTA_M_WTM_TIMEOUT 0x41
1076#define QHSTA_M_BAD_CMPL_STATUS_IN 0x42
1077#define QHSTA_M_NO_AUTO_REQ_SENSE 0x43
1078#define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
1079#define QHSTA_M_TARGET_STATUS_BUSY 0x45
1080#define QHSTA_M_BAD_TAG_CODE 0x46
1081#define QHSTA_M_BAD_QUEUE_FULL_OR_BUSY 0x47
1082#define QHSTA_M_HUNG_REQ_SCSI_BUS_RESET 0x48
1083#define QHSTA_D_LRAM_CMP_ERROR 0x81
1084#define QHSTA_M_MICRO_CODE_ERROR_HALT 0xA1
1085#define ASC_FLAG_SCSIQ_REQ 0x01
1086#define ASC_FLAG_BIOS_SCSIQ_REQ 0x02
1087#define ASC_FLAG_BIOS_ASYNC_IO 0x04
1088#define ASC_FLAG_SRB_LINEAR_ADDR 0x08
1089#define ASC_FLAG_WIN16 0x10
1090#define ASC_FLAG_WIN32 0x20
1091#define ASC_FLAG_ISA_OVER_16MB 0x40
1092#define ASC_FLAG_DOS_VM_CALLBACK 0x80
1093#define ASC_TAG_FLAG_EXTRA_BYTES 0x10
1094#define ASC_TAG_FLAG_DISABLE_DISCONNECT 0x04
1095#define ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX 0x08
1096#define ASC_TAG_FLAG_DISABLE_CHK_COND_INT_HOST 0x40
1097#define ASC_SCSIQ_CPY_BEG 4
1098#define ASC_SCSIQ_SGHD_CPY_BEG 2
1099#define ASC_SCSIQ_B_FWD 0
1100#define ASC_SCSIQ_B_BWD 1
1101#define ASC_SCSIQ_B_STATUS 2
1102#define ASC_SCSIQ_B_QNO 3
1103#define ASC_SCSIQ_B_CNTL 4
1104#define ASC_SCSIQ_B_SG_QUEUE_CNT 5
1105#define ASC_SCSIQ_D_DATA_ADDR 8
1106#define ASC_SCSIQ_D_DATA_CNT 12
1107#define ASC_SCSIQ_B_SENSE_LEN 20
1108#define ASC_SCSIQ_DONE_INFO_BEG 22
1109#define ASC_SCSIQ_D_SRBPTR 22
1110#define ASC_SCSIQ_B_TARGET_IX 26
1111#define ASC_SCSIQ_B_CDB_LEN 28
1112#define ASC_SCSIQ_B_TAG_CODE 29
1113#define ASC_SCSIQ_W_VM_ID 30
1114#define ASC_SCSIQ_DONE_STATUS 32
1115#define ASC_SCSIQ_HOST_STATUS 33
1116#define ASC_SCSIQ_SCSI_STATUS 34
1117#define ASC_SCSIQ_CDB_BEG 36
1118#define ASC_SCSIQ_DW_REMAIN_XFER_ADDR 56
1119#define ASC_SCSIQ_DW_REMAIN_XFER_CNT 60
1120#define ASC_SCSIQ_B_FIRST_SG_WK_QP 48
1121#define ASC_SCSIQ_B_SG_WK_QP 49
1122#define ASC_SCSIQ_B_SG_WK_IX 50
1123#define ASC_SCSIQ_W_ALT_DC1 52
1124#define ASC_SCSIQ_B_LIST_CNT 6
1125#define ASC_SCSIQ_B_CUR_LIST_CNT 7
1126#define ASC_SGQ_B_SG_CNTL 4
1127#define ASC_SGQ_B_SG_HEAD_QP 5
1128#define ASC_SGQ_B_SG_LIST_CNT 6
1129#define ASC_SGQ_B_SG_CUR_LIST_CNT 7
1130#define ASC_SGQ_LIST_BEG 8
1131#define ASC_DEF_SCSI1_QNG 4
1132#define ASC_MAX_SCSI1_QNG 4
1133#define ASC_DEF_SCSI2_QNG 16
1134#define ASC_MAX_SCSI2_QNG 32
1135#define ASC_TAG_CODE_MASK 0x23
1136#define ASC_STOP_REQ_RISC_STOP 0x01
1137#define ASC_STOP_ACK_RISC_STOP 0x03
1138#define ASC_STOP_CLEAN_UP_BUSY_Q 0x10
1139#define ASC_STOP_CLEAN_UP_DISC_Q 0x20
1140#define ASC_STOP_HOST_REQ_RISC_HALT 0x40
1141#define ASC_TIDLUN_TO_IX(tid, lun) (ASC_SCSI_TIX_TYPE)((tid) + ((lun)<<ASC_SCSI_ID_BITS))
1142#define ASC_TID_TO_TARGET_ID(tid) (ASC_SCSI_BIT_ID_TYPE)(0x01 << (tid))
1143#define ASC_TIX_TO_TARGET_ID(tix) (0x01 << ((tix) & ASC_MAX_TID))
1144#define ASC_TIX_TO_TID(tix) ((tix) & ASC_MAX_TID)
1145#define ASC_TID_TO_TIX(tid) ((tid) & ASC_MAX_TID)
1146#define ASC_TIX_TO_LUN(tix) (((tix) >> ASC_SCSI_ID_BITS) & ASC_MAX_LUN)
1147#define ASC_QNO_TO_QADDR(q_no) ((ASC_QADR_BEG)+((int)(q_no) << 6))
1148
1149typedef struct asc_scsiq_1 {
27c868c2
MW
1150 uchar status;
1151 uchar q_no;
1152 uchar cntl;
1153 uchar sg_queue_cnt;
1154 uchar target_id;
1155 uchar target_lun;
1156 ASC_PADDR data_addr;
1157 ASC_DCNT data_cnt;
1158 ASC_PADDR sense_addr;
1159 uchar sense_len;
1160 uchar extra_bytes;
1da177e4
LT
1161} ASC_SCSIQ_1;
1162
1163typedef struct asc_scsiq_2 {
27c868c2
MW
1164 ASC_VADDR srb_ptr;
1165 uchar target_ix;
1166 uchar flag;
1167 uchar cdb_len;
1168 uchar tag_code;
1169 ushort vm_id;
1da177e4
LT
1170} ASC_SCSIQ_2;
1171
1172typedef struct asc_scsiq_3 {
27c868c2
MW
1173 uchar done_stat;
1174 uchar host_stat;
1175 uchar scsi_stat;
1176 uchar scsi_msg;
1da177e4
LT
1177} ASC_SCSIQ_3;
1178
1179typedef struct asc_scsiq_4 {
27c868c2
MW
1180 uchar cdb[ASC_MAX_CDB_LEN];
1181 uchar y_first_sg_list_qp;
1182 uchar y_working_sg_qp;
1183 uchar y_working_sg_ix;
1184 uchar y_res;
1185 ushort x_req_count;
1186 ushort x_reconnect_rtn;
1187 ASC_PADDR x_saved_data_addr;
1188 ASC_DCNT x_saved_data_cnt;
1da177e4
LT
1189} ASC_SCSIQ_4;
1190
1191typedef struct asc_q_done_info {
27c868c2
MW
1192 ASC_SCSIQ_2 d2;
1193 ASC_SCSIQ_3 d3;
1194 uchar q_status;
1195 uchar q_no;
1196 uchar cntl;
1197 uchar sense_len;
1198 uchar extra_bytes;
1199 uchar res;
1200 ASC_DCNT remain_bytes;
1da177e4
LT
1201} ASC_QDONE_INFO;
1202
1203typedef struct asc_sg_list {
27c868c2
MW
1204 ASC_PADDR addr;
1205 ASC_DCNT bytes;
1da177e4
LT
1206} ASC_SG_LIST;
1207
1208typedef struct asc_sg_head {
27c868c2
MW
1209 ushort entry_cnt;
1210 ushort queue_cnt;
1211 ushort entry_to_copy;
1212 ushort res;
1213 ASC_SG_LIST sg_list[ASC_MAX_SG_LIST];
1da177e4
LT
1214} ASC_SG_HEAD;
1215
1216#define ASC_MIN_SG_LIST 2
1217
1218typedef struct asc_min_sg_head {
27c868c2
MW
1219 ushort entry_cnt;
1220 ushort queue_cnt;
1221 ushort entry_to_copy;
1222 ushort res;
1223 ASC_SG_LIST sg_list[ASC_MIN_SG_LIST];
1da177e4
LT
1224} ASC_MIN_SG_HEAD;
1225
1226#define QCX_SORT (0x0001)
1227#define QCX_COALEASE (0x0002)
1228
1229typedef struct asc_scsi_q {
27c868c2
MW
1230 ASC_SCSIQ_1 q1;
1231 ASC_SCSIQ_2 q2;
1232 uchar *cdbptr;
1233 ASC_SG_HEAD *sg_head;
1234 ushort remain_sg_entry_cnt;
1235 ushort next_sg_index;
1da177e4
LT
1236} ASC_SCSI_Q;
1237
1238typedef struct asc_scsi_req_q {
27c868c2
MW
1239 ASC_SCSIQ_1 r1;
1240 ASC_SCSIQ_2 r2;
1241 uchar *cdbptr;
1242 ASC_SG_HEAD *sg_head;
1243 uchar *sense_ptr;
1244 ASC_SCSIQ_3 r3;
1245 uchar cdb[ASC_MAX_CDB_LEN];
1246 uchar sense[ASC_MIN_SENSE_LEN];
1da177e4
LT
1247} ASC_SCSI_REQ_Q;
1248
1249typedef struct asc_scsi_bios_req_q {
27c868c2
MW
1250 ASC_SCSIQ_1 r1;
1251 ASC_SCSIQ_2 r2;
1252 uchar *cdbptr;
1253 ASC_SG_HEAD *sg_head;
1254 uchar *sense_ptr;
1255 ASC_SCSIQ_3 r3;
1256 uchar cdb[ASC_MAX_CDB_LEN];
1257 uchar sense[ASC_MIN_SENSE_LEN];
1da177e4
LT
1258} ASC_SCSI_BIOS_REQ_Q;
1259
1260typedef struct asc_risc_q {
27c868c2
MW
1261 uchar fwd;
1262 uchar bwd;
1263 ASC_SCSIQ_1 i1;
1264 ASC_SCSIQ_2 i2;
1265 ASC_SCSIQ_3 i3;
1266 ASC_SCSIQ_4 i4;
1da177e4
LT
1267} ASC_RISC_Q;
1268
1269typedef struct asc_sg_list_q {
27c868c2
MW
1270 uchar seq_no;
1271 uchar q_no;
1272 uchar cntl;
1273 uchar sg_head_qp;
1274 uchar sg_list_cnt;
1275 uchar sg_cur_list_cnt;
1da177e4
LT
1276} ASC_SG_LIST_Q;
1277
1278typedef struct asc_risc_sg_list_q {
27c868c2
MW
1279 uchar fwd;
1280 uchar bwd;
1281 ASC_SG_LIST_Q sg;
1282 ASC_SG_LIST sg_list[7];
1da177e4
LT
1283} ASC_RISC_SG_LIST_Q;
1284
1285#define ASC_EXE_SCSI_IO_MAX_IDLE_LOOP 0x1000000UL
1286#define ASC_EXE_SCSI_IO_MAX_WAIT_LOOP 1024
1287#define ASCQ_ERR_NO_ERROR 0
1288#define ASCQ_ERR_IO_NOT_FOUND 1
1289#define ASCQ_ERR_LOCAL_MEM 2
1290#define ASCQ_ERR_CHKSUM 3
1291#define ASCQ_ERR_START_CHIP 4
1292#define ASCQ_ERR_INT_TARGET_ID 5
1293#define ASCQ_ERR_INT_LOCAL_MEM 6
1294#define ASCQ_ERR_HALT_RISC 7
1295#define ASCQ_ERR_GET_ASPI_ENTRY 8
1296#define ASCQ_ERR_CLOSE_ASPI 9
1297#define ASCQ_ERR_HOST_INQUIRY 0x0A
1298#define ASCQ_ERR_SAVED_SRB_BAD 0x0B
1299#define ASCQ_ERR_QCNTL_SG_LIST 0x0C
1300#define ASCQ_ERR_Q_STATUS 0x0D
1301#define ASCQ_ERR_WR_SCSIQ 0x0E
1302#define ASCQ_ERR_PC_ADDR 0x0F
1303#define ASCQ_ERR_SYN_OFFSET 0x10
1304#define ASCQ_ERR_SYN_XFER_TIME 0x11
1305#define ASCQ_ERR_LOCK_DMA 0x12
1306#define ASCQ_ERR_UNLOCK_DMA 0x13
1307#define ASCQ_ERR_VDS_CHK_INSTALL 0x14
1308#define ASCQ_ERR_MICRO_CODE_HALT 0x15
1309#define ASCQ_ERR_SET_LRAM_ADDR 0x16
1310#define ASCQ_ERR_CUR_QNG 0x17
1311#define ASCQ_ERR_SG_Q_LINKS 0x18
1312#define ASCQ_ERR_SCSIQ_PTR 0x19
1313#define ASCQ_ERR_ISR_RE_ENTRY 0x1A
1314#define ASCQ_ERR_CRITICAL_RE_ENTRY 0x1B
1315#define ASCQ_ERR_ISR_ON_CRITICAL 0x1C
1316#define ASCQ_ERR_SG_LIST_ODD_ADDRESS 0x1D
1317#define ASCQ_ERR_XFER_ADDRESS_TOO_BIG 0x1E
1318#define ASCQ_ERR_SCSIQ_NULL_PTR 0x1F
1319#define ASCQ_ERR_SCSIQ_BAD_NEXT_PTR 0x20
1320#define ASCQ_ERR_GET_NUM_OF_FREE_Q 0x21
1321#define ASCQ_ERR_SEND_SCSI_Q 0x22
1322#define ASCQ_ERR_HOST_REQ_RISC_HALT 0x23
1323#define ASCQ_ERR_RESET_SDTR 0x24
1324
1325/*
1326 * Warning code values are set in ASC_DVC_VAR 'warn_code'.
1327 */
1328#define ASC_WARN_NO_ERROR 0x0000
1329#define ASC_WARN_IO_PORT_ROTATE 0x0001
1330#define ASC_WARN_EEPROM_CHKSUM 0x0002
1331#define ASC_WARN_IRQ_MODIFIED 0x0004
1332#define ASC_WARN_AUTO_CONFIG 0x0008
1333#define ASC_WARN_CMD_QNG_CONFLICT 0x0010
1334#define ASC_WARN_EEPROM_RECOVER 0x0020
1335#define ASC_WARN_CFG_MSW_RECOVER 0x0040
1336#define ASC_WARN_SET_PCI_CONFIG_SPACE 0x0080
1337
1338/*
1339 * Error code values are set in ASC_DVC_VAR 'err_code'.
1340 */
1341#define ASC_IERR_WRITE_EEPROM 0x0001
1342#define ASC_IERR_MCODE_CHKSUM 0x0002
1343#define ASC_IERR_SET_PC_ADDR 0x0004
1344#define ASC_IERR_START_STOP_CHIP 0x0008
1345#define ASC_IERR_IRQ_NO 0x0010
1346#define ASC_IERR_SET_IRQ_NO 0x0020
1347#define ASC_IERR_CHIP_VERSION 0x0040
1348#define ASC_IERR_SET_SCSI_ID 0x0080
1349#define ASC_IERR_GET_PHY_ADDR 0x0100
1350#define ASC_IERR_BAD_SIGNATURE 0x0200
1351#define ASC_IERR_NO_BUS_TYPE 0x0400
1352#define ASC_IERR_SCAM 0x0800
1353#define ASC_IERR_SET_SDTR 0x1000
1354#define ASC_IERR_RW_LRAM 0x8000
1355
1356#define ASC_DEF_IRQ_NO 10
1357#define ASC_MAX_IRQ_NO 15
1358#define ASC_MIN_IRQ_NO 10
1359#define ASC_MIN_REMAIN_Q (0x02)
1360#define ASC_DEF_MAX_TOTAL_QNG (0xF0)
1361#define ASC_MIN_TAG_Q_PER_DVC (0x04)
1362#define ASC_DEF_TAG_Q_PER_DVC (0x04)
1363#define ASC_MIN_FREE_Q ASC_MIN_REMAIN_Q
1364#define ASC_MIN_TOTAL_QNG ((ASC_MAX_SG_QUEUE)+(ASC_MIN_FREE_Q))
1365#define ASC_MAX_TOTAL_QNG 240
1366#define ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG 16
1367#define ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG 8
1368#define ASC_MAX_PCI_INRAM_TOTAL_QNG 20
1369#define ASC_MAX_INRAM_TAG_QNG 16
1370#define ASC_IOADR_TABLE_MAX_IX 11
1371#define ASC_IOADR_GAP 0x10
1372#define ASC_SEARCH_IOP_GAP 0x10
1373#define ASC_MIN_IOP_ADDR (PortAddr)0x0100
1374#define ASC_MAX_IOP_ADDR (PortAddr)0x3F0
1375#define ASC_IOADR_1 (PortAddr)0x0110
1376#define ASC_IOADR_2 (PortAddr)0x0130
1377#define ASC_IOADR_3 (PortAddr)0x0150
1378#define ASC_IOADR_4 (PortAddr)0x0190
1379#define ASC_IOADR_5 (PortAddr)0x0210
1380#define ASC_IOADR_6 (PortAddr)0x0230
1381#define ASC_IOADR_7 (PortAddr)0x0250
1382#define ASC_IOADR_8 (PortAddr)0x0330
1383#define ASC_IOADR_DEF ASC_IOADR_8
1384#define ASC_LIB_SCSIQ_WK_SP 256
1385#define ASC_MAX_SYN_XFER_NO 16
1386#define ASC_SYN_MAX_OFFSET 0x0F
1387#define ASC_DEF_SDTR_OFFSET 0x0F
1388#define ASC_DEF_SDTR_INDEX 0x00
1389#define ASC_SDTR_ULTRA_PCI_10MB_INDEX 0x02
1390#define SYN_XFER_NS_0 25
1391#define SYN_XFER_NS_1 30
1392#define SYN_XFER_NS_2 35
1393#define SYN_XFER_NS_3 40
1394#define SYN_XFER_NS_4 50
1395#define SYN_XFER_NS_5 60
1396#define SYN_XFER_NS_6 70
1397#define SYN_XFER_NS_7 85
1398#define SYN_ULTRA_XFER_NS_0 12
1399#define SYN_ULTRA_XFER_NS_1 19
1400#define SYN_ULTRA_XFER_NS_2 25
1401#define SYN_ULTRA_XFER_NS_3 32
1402#define SYN_ULTRA_XFER_NS_4 38
1403#define SYN_ULTRA_XFER_NS_5 44
1404#define SYN_ULTRA_XFER_NS_6 50
1405#define SYN_ULTRA_XFER_NS_7 57
1406#define SYN_ULTRA_XFER_NS_8 63
1407#define SYN_ULTRA_XFER_NS_9 69
1408#define SYN_ULTRA_XFER_NS_10 75
1409#define SYN_ULTRA_XFER_NS_11 82
1410#define SYN_ULTRA_XFER_NS_12 88
1411#define SYN_ULTRA_XFER_NS_13 94
1412#define SYN_ULTRA_XFER_NS_14 100
1413#define SYN_ULTRA_XFER_NS_15 107
1414
1415typedef struct ext_msg {
27c868c2
MW
1416 uchar msg_type;
1417 uchar msg_len;
1418 uchar msg_req;
1419 union {
1420 struct {
1421 uchar sdtr_xfer_period;
1422 uchar sdtr_req_ack_offset;
1423 } sdtr;
1424 struct {
1425 uchar wdtr_width;
1426 } wdtr;
1427 struct {
1428 uchar mdp_b3;
1429 uchar mdp_b2;
1430 uchar mdp_b1;
1431 uchar mdp_b0;
1432 } mdp;
1433 } u_ext_msg;
1434 uchar res;
1da177e4
LT
1435} EXT_MSG;
1436
1437#define xfer_period u_ext_msg.sdtr.sdtr_xfer_period
1438#define req_ack_offset u_ext_msg.sdtr.sdtr_req_ack_offset
1439#define wdtr_width u_ext_msg.wdtr.wdtr_width
1440#define mdp_b3 u_ext_msg.mdp_b3
1441#define mdp_b2 u_ext_msg.mdp_b2
1442#define mdp_b1 u_ext_msg.mdp_b1
1443#define mdp_b0 u_ext_msg.mdp_b0
1444
1445typedef struct asc_dvc_cfg {
27c868c2
MW
1446 ASC_SCSI_BIT_ID_TYPE can_tagged_qng;
1447 ASC_SCSI_BIT_ID_TYPE cmd_qng_enabled;
1448 ASC_SCSI_BIT_ID_TYPE disc_enable;
1449 ASC_SCSI_BIT_ID_TYPE sdtr_enable;
1450 uchar chip_scsi_id;
1451 uchar isa_dma_speed;
1452 uchar isa_dma_channel;
1453 uchar chip_version;
1454 ushort lib_serial_no;
1455 ushort lib_version;
1456 ushort mcode_date;
1457 ushort mcode_version;
1458 uchar max_tag_qng[ASC_MAX_TID + 1];
1459 uchar *overrun_buf;
1460 uchar sdtr_period_offset[ASC_MAX_TID + 1];
1461 ushort pci_slot_info;
1462 uchar adapter_info[6];
1463 struct device *dev;
1da177e4
LT
1464} ASC_DVC_CFG;
1465
1466#define ASC_DEF_DVC_CNTL 0xFFFF
1467#define ASC_DEF_CHIP_SCSI_ID 7
1468#define ASC_DEF_ISA_DMA_SPEED 4
1469#define ASC_INIT_STATE_NULL 0x0000
1470#define ASC_INIT_STATE_BEG_GET_CFG 0x0001
1471#define ASC_INIT_STATE_END_GET_CFG 0x0002
1472#define ASC_INIT_STATE_BEG_SET_CFG 0x0004
1473#define ASC_INIT_STATE_END_SET_CFG 0x0008
1474#define ASC_INIT_STATE_BEG_LOAD_MC 0x0010
1475#define ASC_INIT_STATE_END_LOAD_MC 0x0020
1476#define ASC_INIT_STATE_BEG_INQUIRY 0x0040
1477#define ASC_INIT_STATE_END_INQUIRY 0x0080
1478#define ASC_INIT_RESET_SCSI_DONE 0x0100
1479#define ASC_INIT_STATE_WITHOUT_EEP 0x8000
1da177e4
LT
1480#define ASC_BUG_FIX_IF_NOT_DWB 0x0001
1481#define ASC_BUG_FIX_ASYN_USE_SYN 0x0002
1482#define ASYN_SDTR_DATA_FIX_PCI_REV_AB 0x41
1483#define ASC_MIN_TAGGED_CMD 7
1484#define ASC_MAX_SCSI_RESET_WAIT 30
1485
27c868c2 1486struct asc_dvc_var; /* Forward Declaration. */
1da177e4 1487
27c868c2
MW
1488typedef void (*ASC_ISR_CALLBACK) (struct asc_dvc_var *, ASC_QDONE_INFO *);
1489typedef int (*ASC_EXE_CALLBACK) (struct asc_dvc_var *, ASC_SCSI_Q *);
1da177e4
LT
1490
1491typedef struct asc_dvc_var {
27c868c2
MW
1492 PortAddr iop_base;
1493 ushort err_code;
1494 ushort dvc_cntl;
1495 ushort bug_fix_cntl;
1496 ushort bus_type;
1497 ASC_ISR_CALLBACK isr_callback;
1498 ASC_EXE_CALLBACK exe_callback;
1499 ASC_SCSI_BIT_ID_TYPE init_sdtr;
1500 ASC_SCSI_BIT_ID_TYPE sdtr_done;
1501 ASC_SCSI_BIT_ID_TYPE use_tagged_qng;
1502 ASC_SCSI_BIT_ID_TYPE unit_not_ready;
1503 ASC_SCSI_BIT_ID_TYPE queue_full_or_busy;
1504 ASC_SCSI_BIT_ID_TYPE start_motor;
1505 uchar scsi_reset_wait;
1506 uchar chip_no;
1507 char is_in_int;
1508 uchar max_total_qng;
1509 uchar cur_total_qng;
1510 uchar in_critical_cnt;
1511 uchar irq_no;
1512 uchar last_q_shortage;
1513 ushort init_state;
1514 uchar cur_dvc_qng[ASC_MAX_TID + 1];
1515 uchar max_dvc_qng[ASC_MAX_TID + 1];
1516 ASC_SCSI_Q *scsiq_busy_head[ASC_MAX_TID + 1];
1517 ASC_SCSI_Q *scsiq_busy_tail[ASC_MAX_TID + 1];
1518 uchar sdtr_period_tbl[ASC_MAX_SYN_XFER_NO];
1519 ASC_DVC_CFG *cfg;
1520 ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer_always;
1521 char redo_scam;
1522 ushort res2;
1523 uchar dos_int13_table[ASC_MAX_TID + 1];
1524 ASC_DCNT max_dma_count;
1525 ASC_SCSI_BIT_ID_TYPE no_scam;
1526 ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer;
1527 uchar max_sdtr_index;
1528 uchar host_init_sdtr_index;
1529 struct asc_board *drv_ptr;
1530 ASC_DCNT uc_break;
1da177e4
LT
1531} ASC_DVC_VAR;
1532
1533typedef struct asc_dvc_inq_info {
27c868c2 1534 uchar type[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
1da177e4
LT
1535} ASC_DVC_INQ_INFO;
1536
1537typedef struct asc_cap_info {
27c868c2
MW
1538 ASC_DCNT lba;
1539 ASC_DCNT blk_size;
1da177e4
LT
1540} ASC_CAP_INFO;
1541
1542typedef struct asc_cap_info_array {
27c868c2 1543 ASC_CAP_INFO cap_info[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
1da177e4
LT
1544} ASC_CAP_INFO_ARRAY;
1545
1546#define ASC_MCNTL_NO_SEL_TIMEOUT (ushort)0x0001
1547#define ASC_MCNTL_NULL_TARGET (ushort)0x0002
1548#define ASC_CNTL_INITIATOR (ushort)0x0001
1549#define ASC_CNTL_BIOS_GT_1GB (ushort)0x0002
1550#define ASC_CNTL_BIOS_GT_2_DISK (ushort)0x0004
1551#define ASC_CNTL_BIOS_REMOVABLE (ushort)0x0008
1552#define ASC_CNTL_NO_SCAM (ushort)0x0010
1553#define ASC_CNTL_INT_MULTI_Q (ushort)0x0080
1554#define ASC_CNTL_NO_LUN_SUPPORT (ushort)0x0040
1555#define ASC_CNTL_NO_VERIFY_COPY (ushort)0x0100
1556#define ASC_CNTL_RESET_SCSI (ushort)0x0200
1557#define ASC_CNTL_INIT_INQUIRY (ushort)0x0400
1558#define ASC_CNTL_INIT_VERBOSE (ushort)0x0800
1559#define ASC_CNTL_SCSI_PARITY (ushort)0x1000
1560#define ASC_CNTL_BURST_MODE (ushort)0x2000
1561#define ASC_CNTL_SDTR_ENABLE_ULTRA (ushort)0x4000
1562#define ASC_EEP_DVC_CFG_BEG_VL 2
1563#define ASC_EEP_MAX_DVC_ADDR_VL 15
1564#define ASC_EEP_DVC_CFG_BEG 32
1565#define ASC_EEP_MAX_DVC_ADDR 45
1566#define ASC_EEP_DEFINED_WORDS 10
1567#define ASC_EEP_MAX_ADDR 63
1568#define ASC_EEP_RES_WORDS 0
1569#define ASC_EEP_MAX_RETRY 20
1570#define ASC_MAX_INIT_BUSY_RETRY 8
1571#define ASC_EEP_ISA_PNP_WSIZE 16
1572
1573/*
1574 * These macros keep the chip SCSI id and ISA DMA speed
1575 * bitfields in board order. C bitfields aren't portable
1576 * between big and little-endian platforms so they are
1577 * not used.
1578 */
1579
1580#define ASC_EEP_GET_CHIP_ID(cfg) ((cfg)->id_speed & 0x0f)
1581#define ASC_EEP_GET_DMA_SPD(cfg) (((cfg)->id_speed & 0xf0) >> 4)
1582#define ASC_EEP_SET_CHIP_ID(cfg, sid) \
1583 ((cfg)->id_speed = ((cfg)->id_speed & 0xf0) | ((sid) & ASC_MAX_TID))
1584#define ASC_EEP_SET_DMA_SPD(cfg, spd) \
1585 ((cfg)->id_speed = ((cfg)->id_speed & 0x0f) | ((spd) & 0x0f) << 4)
1586
1587typedef struct asceep_config {
27c868c2
MW
1588 ushort cfg_lsw;
1589 ushort cfg_msw;
1590 uchar init_sdtr;
1591 uchar disc_enable;
1592 uchar use_cmd_qng;
1593 uchar start_motor;
1594 uchar max_total_qng;
1595 uchar max_tag_qng;
1596 uchar bios_scan;
1597 uchar power_up_wait;
1598 uchar no_scam;
1599 uchar id_speed; /* low order 4 bits is chip scsi id */
1600 /* high order 4 bits is isa dma speed */
1601 uchar dos_int13_table[ASC_MAX_TID + 1];
1602 uchar adapter_info[6];
1603 ushort cntl;
1604 ushort chksum;
1da177e4
LT
1605} ASCEEP_CONFIG;
1606
1607#define ASC_PCI_CFG_LSW_SCSI_PARITY 0x0800
1608#define ASC_PCI_CFG_LSW_BURST_MODE 0x0080
1609#define ASC_PCI_CFG_LSW_INTR_ABLE 0x0020
1610
1611#define ASC_EEP_CMD_READ 0x80
1612#define ASC_EEP_CMD_WRITE 0x40
1613#define ASC_EEP_CMD_WRITE_ABLE 0x30
1614#define ASC_EEP_CMD_WRITE_DISABLE 0x00
1615#define ASC_OVERRUN_BSIZE 0x00000048UL
1616#define ASC_CTRL_BREAK_ONCE 0x0001
1617#define ASC_CTRL_BREAK_STAY_IDLE 0x0002
1618#define ASCV_MSGOUT_BEG 0x0000
1619#define ASCV_MSGOUT_SDTR_PERIOD (ASCV_MSGOUT_BEG+3)
1620#define ASCV_MSGOUT_SDTR_OFFSET (ASCV_MSGOUT_BEG+4)
1621#define ASCV_BREAK_SAVED_CODE (ushort)0x0006
1622#define ASCV_MSGIN_BEG (ASCV_MSGOUT_BEG+8)
1623#define ASCV_MSGIN_SDTR_PERIOD (ASCV_MSGIN_BEG+3)
1624#define ASCV_MSGIN_SDTR_OFFSET (ASCV_MSGIN_BEG+4)
1625#define ASCV_SDTR_DATA_BEG (ASCV_MSGIN_BEG+8)
1626#define ASCV_SDTR_DONE_BEG (ASCV_SDTR_DATA_BEG+8)
1627#define ASCV_MAX_DVC_QNG_BEG (ushort)0x0020
1628#define ASCV_BREAK_ADDR (ushort)0x0028
1629#define ASCV_BREAK_NOTIFY_COUNT (ushort)0x002A
1630#define ASCV_BREAK_CONTROL (ushort)0x002C
1631#define ASCV_BREAK_HIT_COUNT (ushort)0x002E
1632
1633#define ASCV_ASCDVC_ERR_CODE_W (ushort)0x0030
1634#define ASCV_MCODE_CHKSUM_W (ushort)0x0032
1635#define ASCV_MCODE_SIZE_W (ushort)0x0034
1636#define ASCV_STOP_CODE_B (ushort)0x0036
1637#define ASCV_DVC_ERR_CODE_B (ushort)0x0037
1638#define ASCV_OVERRUN_PADDR_D (ushort)0x0038
1639#define ASCV_OVERRUN_BSIZE_D (ushort)0x003C
1640#define ASCV_HALTCODE_W (ushort)0x0040
1641#define ASCV_CHKSUM_W (ushort)0x0042
1642#define ASCV_MC_DATE_W (ushort)0x0044
1643#define ASCV_MC_VER_W (ushort)0x0046
1644#define ASCV_NEXTRDY_B (ushort)0x0048
1645#define ASCV_DONENEXT_B (ushort)0x0049
1646#define ASCV_USE_TAGGED_QNG_B (ushort)0x004A
1647#define ASCV_SCSIBUSY_B (ushort)0x004B
1648#define ASCV_Q_DONE_IN_PROGRESS_B (ushort)0x004C
1649#define ASCV_CURCDB_B (ushort)0x004D
1650#define ASCV_RCLUN_B (ushort)0x004E
1651#define ASCV_BUSY_QHEAD_B (ushort)0x004F
1652#define ASCV_DISC1_QHEAD_B (ushort)0x0050
1653#define ASCV_DISC_ENABLE_B (ushort)0x0052
1654#define ASCV_CAN_TAGGED_QNG_B (ushort)0x0053
1655#define ASCV_HOSTSCSI_ID_B (ushort)0x0055
1656#define ASCV_MCODE_CNTL_B (ushort)0x0056
1657#define ASCV_NULL_TARGET_B (ushort)0x0057
1658#define ASCV_FREE_Q_HEAD_W (ushort)0x0058
1659#define ASCV_DONE_Q_TAIL_W (ushort)0x005A
1660#define ASCV_FREE_Q_HEAD_B (ushort)(ASCV_FREE_Q_HEAD_W+1)
1661#define ASCV_DONE_Q_TAIL_B (ushort)(ASCV_DONE_Q_TAIL_W+1)
1662#define ASCV_HOST_FLAG_B (ushort)0x005D
1663#define ASCV_TOTAL_READY_Q_B (ushort)0x0064
1664#define ASCV_VER_SERIAL_B (ushort)0x0065
1665#define ASCV_HALTCODE_SAVED_W (ushort)0x0066
1666#define ASCV_WTM_FLAG_B (ushort)0x0068
1667#define ASCV_RISC_FLAG_B (ushort)0x006A
1668#define ASCV_REQ_SG_LIST_QP (ushort)0x006B
1669#define ASC_HOST_FLAG_IN_ISR 0x01
1670#define ASC_HOST_FLAG_ACK_INT 0x02
1671#define ASC_RISC_FLAG_GEN_INT 0x01
1672#define ASC_RISC_FLAG_REQ_SG_LIST 0x02
1673#define IOP_CTRL (0x0F)
1674#define IOP_STATUS (0x0E)
1675#define IOP_INT_ACK IOP_STATUS
1676#define IOP_REG_IFC (0x0D)
1677#define IOP_SYN_OFFSET (0x0B)
1678#define IOP_EXTRA_CONTROL (0x0D)
1679#define IOP_REG_PC (0x0C)
1680#define IOP_RAM_ADDR (0x0A)
1681#define IOP_RAM_DATA (0x08)
1682#define IOP_EEP_DATA (0x06)
1683#define IOP_EEP_CMD (0x07)
1684#define IOP_VERSION (0x03)
1685#define IOP_CONFIG_HIGH (0x04)
1686#define IOP_CONFIG_LOW (0x02)
1687#define IOP_SIG_BYTE (0x01)
1688#define IOP_SIG_WORD (0x00)
1689#define IOP_REG_DC1 (0x0E)
1690#define IOP_REG_DC0 (0x0C)
1691#define IOP_REG_SB (0x0B)
1692#define IOP_REG_DA1 (0x0A)
1693#define IOP_REG_DA0 (0x08)
1694#define IOP_REG_SC (0x09)
1695#define IOP_DMA_SPEED (0x07)
1696#define IOP_REG_FLAG (0x07)
1697#define IOP_FIFO_H (0x06)
1698#define IOP_FIFO_L (0x04)
1699#define IOP_REG_ID (0x05)
1700#define IOP_REG_QP (0x03)
1701#define IOP_REG_IH (0x02)
1702#define IOP_REG_IX (0x01)
1703#define IOP_REG_AX (0x00)
1704#define IFC_REG_LOCK (0x00)
1705#define IFC_REG_UNLOCK (0x09)
1706#define IFC_WR_EN_FILTER (0x10)
1707#define IFC_RD_NO_EEPROM (0x10)
1708#define IFC_SLEW_RATE (0x20)
1709#define IFC_ACT_NEG (0x40)
1710#define IFC_INP_FILTER (0x80)
1711#define IFC_INIT_DEFAULT (IFC_ACT_NEG | IFC_REG_UNLOCK)
1712#define SC_SEL (uchar)(0x80)
1713#define SC_BSY (uchar)(0x40)
1714#define SC_ACK (uchar)(0x20)
1715#define SC_REQ (uchar)(0x10)
1716#define SC_ATN (uchar)(0x08)
1717#define SC_IO (uchar)(0x04)
1718#define SC_CD (uchar)(0x02)
1719#define SC_MSG (uchar)(0x01)
1720#define SEC_SCSI_CTL (uchar)(0x80)
1721#define SEC_ACTIVE_NEGATE (uchar)(0x40)
1722#define SEC_SLEW_RATE (uchar)(0x20)
1723#define SEC_ENABLE_FILTER (uchar)(0x10)
1724#define ASC_HALT_EXTMSG_IN (ushort)0x8000
1725#define ASC_HALT_CHK_CONDITION (ushort)0x8100
1726#define ASC_HALT_SS_QUEUE_FULL (ushort)0x8200
1727#define ASC_HALT_DISABLE_ASYN_USE_SYN_FIX (ushort)0x8300
1728#define ASC_HALT_ENABLE_ASYN_USE_SYN_FIX (ushort)0x8400
1729#define ASC_HALT_SDTR_REJECTED (ushort)0x4000
1730#define ASC_HALT_HOST_COPY_SG_LIST_TO_RISC ( ushort )0x2000
1731#define ASC_MAX_QNO 0xF8
1732#define ASC_DATA_SEC_BEG (ushort)0x0080
1733#define ASC_DATA_SEC_END (ushort)0x0080
1734#define ASC_CODE_SEC_BEG (ushort)0x0080
1735#define ASC_CODE_SEC_END (ushort)0x0080
1736#define ASC_QADR_BEG (0x4000)
1737#define ASC_QADR_USED (ushort)(ASC_MAX_QNO * 64)
1738#define ASC_QADR_END (ushort)0x7FFF
1739#define ASC_QLAST_ADR (ushort)0x7FC0
1740#define ASC_QBLK_SIZE 0x40
1741#define ASC_BIOS_DATA_QBEG 0xF8
1742#define ASC_MIN_ACTIVE_QNO 0x01
1743#define ASC_QLINK_END 0xFF
1744#define ASC_EEPROM_WORDS 0x10
1745#define ASC_MAX_MGS_LEN 0x10
1746#define ASC_BIOS_ADDR_DEF 0xDC00
1747#define ASC_BIOS_SIZE 0x3800
1748#define ASC_BIOS_RAM_OFF 0x3800
1749#define ASC_BIOS_RAM_SIZE 0x800
1750#define ASC_BIOS_MIN_ADDR 0xC000
1751#define ASC_BIOS_MAX_ADDR 0xEC00
1752#define ASC_BIOS_BANK_SIZE 0x0400
1753#define ASC_MCODE_START_ADDR 0x0080
1754#define ASC_CFG0_HOST_INT_ON 0x0020
1755#define ASC_CFG0_BIOS_ON 0x0040
1756#define ASC_CFG0_VERA_BURST_ON 0x0080
1757#define ASC_CFG0_SCSI_PARITY_ON 0x0800
1758#define ASC_CFG1_SCSI_TARGET_ON 0x0080
1759#define ASC_CFG1_LRAM_8BITS_ON 0x0800
1760#define ASC_CFG_MSW_CLR_MASK 0x3080
1761#define CSW_TEST1 (ASC_CS_TYPE)0x8000
1762#define CSW_AUTO_CONFIG (ASC_CS_TYPE)0x4000
1763#define CSW_RESERVED1 (ASC_CS_TYPE)0x2000
1764#define CSW_IRQ_WRITTEN (ASC_CS_TYPE)0x1000
1765#define CSW_33MHZ_SELECTED (ASC_CS_TYPE)0x0800
1766#define CSW_TEST2 (ASC_CS_TYPE)0x0400
1767#define CSW_TEST3 (ASC_CS_TYPE)0x0200
1768#define CSW_RESERVED2 (ASC_CS_TYPE)0x0100
1769#define CSW_DMA_DONE (ASC_CS_TYPE)0x0080
1770#define CSW_FIFO_RDY (ASC_CS_TYPE)0x0040
1771#define CSW_EEP_READ_DONE (ASC_CS_TYPE)0x0020
1772#define CSW_HALTED (ASC_CS_TYPE)0x0010
1773#define CSW_SCSI_RESET_ACTIVE (ASC_CS_TYPE)0x0008
1774#define CSW_PARITY_ERR (ASC_CS_TYPE)0x0004
1775#define CSW_SCSI_RESET_LATCH (ASC_CS_TYPE)0x0002
1776#define CSW_INT_PENDING (ASC_CS_TYPE)0x0001
1777#define CIW_CLR_SCSI_RESET_INT (ASC_CS_TYPE)0x1000
1778#define CIW_INT_ACK (ASC_CS_TYPE)0x0100
1779#define CIW_TEST1 (ASC_CS_TYPE)0x0200
1780#define CIW_TEST2 (ASC_CS_TYPE)0x0400
1781#define CIW_SEL_33MHZ (ASC_CS_TYPE)0x0800
1782#define CIW_IRQ_ACT (ASC_CS_TYPE)0x1000
1783#define CC_CHIP_RESET (uchar)0x80
1784#define CC_SCSI_RESET (uchar)0x40
1785#define CC_HALT (uchar)0x20
1786#define CC_SINGLE_STEP (uchar)0x10
1787#define CC_DMA_ABLE (uchar)0x08
1788#define CC_TEST (uchar)0x04
1789#define CC_BANK_ONE (uchar)0x02
1790#define CC_DIAG (uchar)0x01
1791#define ASC_1000_ID0W 0x04C1
1792#define ASC_1000_ID0W_FIX 0x00C1
1793#define ASC_1000_ID1B 0x25
1794#define ASC_EISA_BIG_IOP_GAP (0x1C30-0x0C50)
1795#define ASC_EISA_SMALL_IOP_GAP (0x0020)
1796#define ASC_EISA_MIN_IOP_ADDR (0x0C30)
1797#define ASC_EISA_MAX_IOP_ADDR (0xFC50)
1798#define ASC_EISA_REV_IOP_MASK (0x0C83)
1799#define ASC_EISA_PID_IOP_MASK (0x0C80)
1800#define ASC_EISA_CFG_IOP_MASK (0x0C86)
1801#define ASC_GET_EISA_SLOT(iop) (PortAddr)((iop) & 0xF000)
1802#define ASC_EISA_ID_740 0x01745004UL
1803#define ASC_EISA_ID_750 0x01755004UL
1804#define INS_HALTINT (ushort)0x6281
1805#define INS_HALT (ushort)0x6280
1806#define INS_SINT (ushort)0x6200
1807#define INS_RFLAG_WTM (ushort)0x7380
1808#define ASC_MC_SAVE_CODE_WSIZE 0x500
1809#define ASC_MC_SAVE_DATA_WSIZE 0x40
1810
1811typedef struct asc_mc_saved {
27c868c2
MW
1812 ushort data[ASC_MC_SAVE_DATA_WSIZE];
1813 ushort code[ASC_MC_SAVE_CODE_WSIZE];
1da177e4
LT
1814} ASC_MC_SAVED;
1815
1816#define AscGetQDoneInProgress(port) AscReadLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B)
1817#define AscPutQDoneInProgress(port, val) AscWriteLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B, val)
1818#define AscGetVarFreeQHead(port) AscReadLramWord((port), ASCV_FREE_Q_HEAD_W)
1819#define AscGetVarDoneQTail(port) AscReadLramWord((port), ASCV_DONE_Q_TAIL_W)
1820#define AscPutVarFreeQHead(port, val) AscWriteLramWord((port), ASCV_FREE_Q_HEAD_W, val)
1821#define AscPutVarDoneQTail(port, val) AscWriteLramWord((port), ASCV_DONE_Q_TAIL_W, val)
1822#define AscGetRiscVarFreeQHead(port) AscReadLramByte((port), ASCV_NEXTRDY_B)
1823#define AscGetRiscVarDoneQTail(port) AscReadLramByte((port), ASCV_DONENEXT_B)
1824#define AscPutRiscVarFreeQHead(port, val) AscWriteLramByte((port), ASCV_NEXTRDY_B, val)
1825#define AscPutRiscVarDoneQTail(port, val) AscWriteLramByte((port), ASCV_DONENEXT_B, val)
1826#define AscPutMCodeSDTRDoneAtID(port, id, data) AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id), (data));
1827#define AscGetMCodeSDTRDoneAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id));
1828#define AscPutMCodeInitSDTRAtID(port, id, data) AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id), data);
1829#define AscGetMCodeInitSDTRAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id));
1830#define AscSynIndexToPeriod(index) (uchar)(asc_dvc->sdtr_period_tbl[ (index) ])
1831#define AscGetChipSignatureByte(port) (uchar)inp((port)+IOP_SIG_BYTE)
1832#define AscGetChipSignatureWord(port) (ushort)inpw((port)+IOP_SIG_WORD)
1833#define AscGetChipVerNo(port) (uchar)inp((port)+IOP_VERSION)
1834#define AscGetChipCfgLsw(port) (ushort)inpw((port)+IOP_CONFIG_LOW)
1835#define AscGetChipCfgMsw(port) (ushort)inpw((port)+IOP_CONFIG_HIGH)
1836#define AscSetChipCfgLsw(port, data) outpw((port)+IOP_CONFIG_LOW, data)
1837#define AscSetChipCfgMsw(port, data) outpw((port)+IOP_CONFIG_HIGH, data)
1838#define AscGetChipEEPCmd(port) (uchar)inp((port)+IOP_EEP_CMD)
1839#define AscSetChipEEPCmd(port, data) outp((port)+IOP_EEP_CMD, data)
1840#define AscGetChipEEPData(port) (ushort)inpw((port)+IOP_EEP_DATA)
1841#define AscSetChipEEPData(port, data) outpw((port)+IOP_EEP_DATA, data)
1842#define AscGetChipLramAddr(port) (ushort)inpw((PortAddr)((port)+IOP_RAM_ADDR))
1843#define AscSetChipLramAddr(port, addr) outpw((PortAddr)((port)+IOP_RAM_ADDR), addr)
1844#define AscGetChipLramData(port) (ushort)inpw((port)+IOP_RAM_DATA)
1845#define AscSetChipLramData(port, data) outpw((port)+IOP_RAM_DATA, data)
1846#define AscGetChipIFC(port) (uchar)inp((port)+IOP_REG_IFC)
1847#define AscSetChipIFC(port, data) outp((port)+IOP_REG_IFC, data)
1848#define AscGetChipStatus(port) (ASC_CS_TYPE)inpw((port)+IOP_STATUS)
1849#define AscSetChipStatus(port, cs_val) outpw((port)+IOP_STATUS, cs_val)
1850#define AscGetChipControl(port) (uchar)inp((port)+IOP_CTRL)
1851#define AscSetChipControl(port, cc_val) outp((port)+IOP_CTRL, cc_val)
1852#define AscGetChipSyn(port) (uchar)inp((port)+IOP_SYN_OFFSET)
1853#define AscSetChipSyn(port, data) outp((port)+IOP_SYN_OFFSET, data)
1854#define AscSetPCAddr(port, data) outpw((port)+IOP_REG_PC, data)
1855#define AscGetPCAddr(port) (ushort)inpw((port)+IOP_REG_PC)
1856#define AscIsIntPending(port) (AscGetChipStatus(port) & (CSW_INT_PENDING | CSW_SCSI_RESET_LATCH))
1857#define AscGetChipScsiID(port) ((AscGetChipCfgLsw(port) >> 8) & ASC_MAX_TID)
1858#define AscGetExtraControl(port) (uchar)inp((port)+IOP_EXTRA_CONTROL)
1859#define AscSetExtraControl(port, data) outp((port)+IOP_EXTRA_CONTROL, data)
1860#define AscReadChipAX(port) (ushort)inpw((port)+IOP_REG_AX)
1861#define AscWriteChipAX(port, data) outpw((port)+IOP_REG_AX, data)
1862#define AscReadChipIX(port) (uchar)inp((port)+IOP_REG_IX)
1863#define AscWriteChipIX(port, data) outp((port)+IOP_REG_IX, data)
1864#define AscReadChipIH(port) (ushort)inpw((port)+IOP_REG_IH)
1865#define AscWriteChipIH(port, data) outpw((port)+IOP_REG_IH, data)
1866#define AscReadChipQP(port) (uchar)inp((port)+IOP_REG_QP)
1867#define AscWriteChipQP(port, data) outp((port)+IOP_REG_QP, data)
1868#define AscReadChipFIFO_L(port) (ushort)inpw((port)+IOP_REG_FIFO_L)
1869#define AscWriteChipFIFO_L(port, data) outpw((port)+IOP_REG_FIFO_L, data)
1870#define AscReadChipFIFO_H(port) (ushort)inpw((port)+IOP_REG_FIFO_H)
1871#define AscWriteChipFIFO_H(port, data) outpw((port)+IOP_REG_FIFO_H, data)
1872#define AscReadChipDmaSpeed(port) (uchar)inp((port)+IOP_DMA_SPEED)
1873#define AscWriteChipDmaSpeed(port, data) outp((port)+IOP_DMA_SPEED, data)
1874#define AscReadChipDA0(port) (ushort)inpw((port)+IOP_REG_DA0)
1875#define AscWriteChipDA0(port) outpw((port)+IOP_REG_DA0, data)
1876#define AscReadChipDA1(port) (ushort)inpw((port)+IOP_REG_DA1)
1877#define AscWriteChipDA1(port) outpw((port)+IOP_REG_DA1, data)
1878#define AscReadChipDC0(port) (ushort)inpw((port)+IOP_REG_DC0)
1879#define AscWriteChipDC0(port) outpw((port)+IOP_REG_DC0, data)
1880#define AscReadChipDC1(port) (ushort)inpw((port)+IOP_REG_DC1)
1881#define AscWriteChipDC1(port) outpw((port)+IOP_REG_DC1, data)
1882#define AscReadChipDvcID(port) (uchar)inp((port)+IOP_REG_ID)
1883#define AscWriteChipDvcID(port, data) outp((port)+IOP_REG_ID, data)
1884
27c868c2
MW
1885static int AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg);
1886static int AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg);
1887static void AscWaitEEPRead(void);
1888static void AscWaitEEPWrite(void);
1889static ushort AscReadEEPWord(PortAddr, uchar);
1890static ushort AscWriteEEPWord(PortAddr, uchar, ushort);
1891static ushort AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
1892static int AscSetEEPConfigOnce(PortAddr, ASCEEP_CONFIG *, ushort);
1893static int AscSetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
1894static int AscStartChip(PortAddr);
1895static int AscStopChip(PortAddr);
1896static void AscSetChipIH(PortAddr, ushort);
1897static int AscIsChipHalted(PortAddr);
1898static void AscAckInterrupt(PortAddr);
1899static void AscDisableInterrupt(PortAddr);
1900static void AscEnableInterrupt(PortAddr);
1901static void AscSetBank(PortAddr, uchar);
1902static int AscResetChipAndScsiBus(ASC_DVC_VAR *);
1da177e4 1903#ifdef CONFIG_ISA
27c868c2
MW
1904static ushort AscGetIsaDmaChannel(PortAddr);
1905static ushort AscSetIsaDmaChannel(PortAddr, ushort);
1906static uchar AscSetIsaDmaSpeed(PortAddr, uchar);
1907static uchar AscGetIsaDmaSpeed(PortAddr);
1da177e4 1908#endif /* CONFIG_ISA */
27c868c2
MW
1909static uchar AscReadLramByte(PortAddr, ushort);
1910static ushort AscReadLramWord(PortAddr, ushort);
1da177e4 1911#if CC_VERY_LONG_SG_LIST
27c868c2 1912static ASC_DCNT AscReadLramDWord(PortAddr, ushort);
1da177e4 1913#endif /* CC_VERY_LONG_SG_LIST */
27c868c2
MW
1914static void AscWriteLramWord(PortAddr, ushort, ushort);
1915static void AscWriteLramByte(PortAddr, ushort, uchar);
1916static ASC_DCNT AscMemSumLramWord(PortAddr, ushort, int);
1917static void AscMemWordSetLram(PortAddr, ushort, ushort, int);
1918static void AscMemWordCopyPtrToLram(PortAddr, ushort, uchar *, int);
1919static void AscMemDWordCopyPtrToLram(PortAddr, ushort, uchar *, int);
1920static void AscMemWordCopyPtrFromLram(PortAddr, ushort, uchar *, int);
1921static ushort AscInitAscDvcVar(ASC_DVC_VAR *);
1922static ushort AscInitFromEEP(ASC_DVC_VAR *);
1923static ushort AscInitFromAscDvcVar(ASC_DVC_VAR *);
1924static ushort AscInitMicroCodeVar(ASC_DVC_VAR *);
1925static int AscTestExternalLram(ASC_DVC_VAR *);
1926static uchar AscMsgOutSDTR(ASC_DVC_VAR *, uchar, uchar);
1927static uchar AscCalSDTRData(ASC_DVC_VAR *, uchar, uchar);
1928static void AscSetChipSDTR(PortAddr, uchar, uchar);
1929static uchar AscGetSynPeriodIndex(ASC_DVC_VAR *, uchar);
1930static uchar AscAllocFreeQueue(PortAddr, uchar);
1931static uchar AscAllocMultipleFreeQueue(PortAddr, uchar, uchar);
1932static int AscHostReqRiscHalt(PortAddr);
1933static int AscStopQueueExe(PortAddr);
1934static int AscSendScsiQueue(ASC_DVC_VAR *,
1935 ASC_SCSI_Q *scsiq, uchar n_q_required);
1936static int AscPutReadyQueue(ASC_DVC_VAR *, ASC_SCSI_Q *, uchar);
1937static int AscPutReadySgListQueue(ASC_DVC_VAR *, ASC_SCSI_Q *, uchar);
1938static int AscSetChipSynRegAtID(PortAddr, uchar, uchar);
1939static int AscSetRunChipSynRegAtID(PortAddr, uchar, uchar);
1940static ushort AscInitLram(ASC_DVC_VAR *);
1941static ushort AscInitQLinkVar(ASC_DVC_VAR *);
1942static int AscSetLibErrorCode(ASC_DVC_VAR *, ushort);
1943static int AscIsrChipHalted(ASC_DVC_VAR *);
1944static uchar _AscCopyLramScsiDoneQ(PortAddr, ushort,
1945 ASC_QDONE_INFO *, ASC_DCNT);
1946static int AscIsrQDone(ASC_DVC_VAR *);
1947static int AscCompareString(uchar *, uchar *, int);
1da177e4 1948#ifdef CONFIG_ISA
27c868c2
MW
1949static ushort AscGetEisaChipCfg(PortAddr);
1950static ASC_DCNT AscGetEisaProductID(PortAddr);
1951static PortAddr AscSearchIOPortAddrEISA(PortAddr);
1952static PortAddr AscSearchIOPortAddr11(PortAddr);
1953static PortAddr AscSearchIOPortAddr(PortAddr, ushort);
1954static void AscSetISAPNPWaitForKey(void);
1da177e4 1955#endif /* CONFIG_ISA */
27c868c2
MW
1956static uchar AscGetChipScsiCtrl(PortAddr);
1957static uchar AscSetChipScsiID(PortAddr, uchar);
1958static uchar AscGetChipVersion(PortAddr, ushort);
1959static ushort AscGetChipBusType(PortAddr);
1960static ASC_DCNT AscLoadMicroCode(PortAddr, ushort, uchar *, ushort);
1961static int AscFindSignature(PortAddr);
1962static void AscToggleIRQAct(PortAddr);
1963static uchar AscGetChipIRQ(PortAddr, ushort);
1964static uchar AscSetChipIRQ(PortAddr, uchar, ushort);
1965static ushort AscGetChipBiosAddress(PortAddr, ushort);
1966static inline ulong DvcEnterCritical(void);
1967static inline void DvcLeaveCritical(ulong);
1da177e4 1968#ifdef CONFIG_PCI
27c868c2
MW
1969static uchar DvcReadPCIConfigByte(ASC_DVC_VAR *, ushort);
1970static void DvcWritePCIConfigByte(ASC_DVC_VAR *, ushort, uchar);
1da177e4 1971#endif /* CONFIG_PCI */
27c868c2
MW
1972static ushort AscGetChipBiosAddress(PortAddr, ushort);
1973static void DvcSleepMilliSecond(ASC_DCNT);
1974static void DvcDelayNanoSecond(ASC_DVC_VAR *, ASC_DCNT);
1975static void DvcPutScsiQ(PortAddr, ushort, uchar *, int);
1976static void DvcGetQinfo(PortAddr, ushort, uchar *, int);
1977static ushort AscInitGetConfig(ASC_DVC_VAR *);
1978static ushort AscInitSetConfig(ASC_DVC_VAR *);
1979static ushort AscInitAsc1000Driver(ASC_DVC_VAR *);
1980static void AscAsyncFix(ASC_DVC_VAR *, uchar, ASC_SCSI_INQUIRY *);
1981static int AscTagQueuingSafe(ASC_SCSI_INQUIRY *);
1982static void AscInquiryHandling(ASC_DVC_VAR *, uchar, ASC_SCSI_INQUIRY *);
1983static int AscExeScsiQueue(ASC_DVC_VAR *, ASC_SCSI_Q *);
1984static int AscISR(ASC_DVC_VAR *);
1985static uint AscGetNumOfFreeQueue(ASC_DVC_VAR *, uchar, uchar);
1986static int AscSgListToQueue(int);
1da177e4 1987#ifdef CONFIG_ISA
27c868c2 1988static void AscEnableIsaDma(uchar);
1da177e4 1989#endif /* CONFIG_ISA */
27c868c2
MW
1990static ASC_DCNT AscGetMaxDmaCount(ushort);
1991static const char *advansys_info(struct Scsi_Host *shost);
1da177e4
LT
1992
1993/*
1994 * --- Adv Library Constants and Macros
1995 */
1996
1997#define ADV_LIB_VERSION_MAJOR 5
1998#define ADV_LIB_VERSION_MINOR 14
1999
2000/*
2001 * Define Adv Library required special types.
2002 */
2003
2004/*
2005 * Portable Data Types
2006 *
2007 * Any instance where a 32-bit long or pointer type is assumed
2008 * for precision or HW defined structures, the following define
2009 * types must be used. In Linux the char, short, and int types
2010 * are all consistent at 8, 16, and 32 bits respectively. Pointers
2011 * and long types are 64 bits on Alpha and UltraSPARC.
2012 */
27c868c2
MW
2013#define ADV_PADDR __u32 /* Physical address data type. */
2014#define ADV_VADDR __u32 /* Virtual address data type. */
2015#define ADV_DCNT __u32 /* Unsigned Data count type. */
2016#define ADV_SDCNT __s32 /* Signed Data count type. */
1da177e4
LT
2017
2018/*
2019 * These macros are used to convert a virtual address to a
2020 * 32-bit value. This currently can be used on Linux Alpha
2021 * which uses 64-bit virtual address but a 32-bit bus address.
2022 * This is likely to break in the future, but doing this now
2023 * will give us time to change the HW and FW to handle 64-bit
2024 * addresses.
2025 */
2026#define ADV_VADDR_TO_U32 virt_to_bus
2027#define ADV_U32_TO_VADDR bus_to_virt
2028
27c868c2 2029#define AdvPortAddr void __iomem * /* Virtual memory address size */
1da177e4
LT
2030
2031/*
2032 * Define Adv Library required memory access macros.
2033 */
2034#define ADV_MEM_READB(addr) readb(addr)
2035#define ADV_MEM_READW(addr) readw(addr)
2036#define ADV_MEM_WRITEB(addr, byte) writeb(byte, addr)
2037#define ADV_MEM_WRITEW(addr, word) writew(word, addr)
2038#define ADV_MEM_WRITEDW(addr, dword) writel(dword, addr)
2039
2040#define ADV_CARRIER_COUNT (ASC_DEF_MAX_HOST_QNG + 15)
2041
2042/*
2043 * For wide boards a CDB length maximum of 16 bytes
2044 * is supported.
2045 */
2046#define ADV_MAX_CDB_LEN 16
2047
2048/*
2049 * Define total number of simultaneous maximum element scatter-gather
2050 * request blocks per wide adapter. ASC_DEF_MAX_HOST_QNG (253) is the
2051 * maximum number of outstanding commands per wide host adapter. Each
2052 * command uses one or more ADV_SG_BLOCK each with 15 scatter-gather
2053 * elements. Allow each command to have at least one ADV_SG_BLOCK structure.
2054 * This allows about 15 commands to have the maximum 17 ADV_SG_BLOCK
2055 * structures or 255 scatter-gather elements.
2056 *
2057 */
2058#define ADV_TOT_SG_BLOCK ASC_DEF_MAX_HOST_QNG
2059
2060/*
2061 * Define Adv Library required maximum number of scatter-gather
2062 * elements per request.
2063 */
2064#define ADV_MAX_SG_LIST 255
2065
2066/* Number of SG blocks needed. */
2067#define ADV_NUM_SG_BLOCK \
2068 ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK)
2069
2070/* Total contiguous memory needed for SG blocks. */
2071#define ADV_SG_TOTAL_MEM_SIZE \
2072 (sizeof(ADV_SG_BLOCK) * ADV_NUM_SG_BLOCK)
2073
2074#define ADV_PAGE_SIZE PAGE_SIZE
2075
2076#define ADV_NUM_PAGE_CROSSING \
2077 ((ADV_SG_TOTAL_MEM_SIZE + (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
2078
1da177e4
LT
2079#define ADV_EEP_DVC_CFG_BEGIN (0x00)
2080#define ADV_EEP_DVC_CFG_END (0x15)
27c868c2 2081#define ADV_EEP_DVC_CTL_BEGIN (0x16) /* location of OEM name */
1da177e4
LT
2082#define ADV_EEP_MAX_WORD_ADDR (0x1E)
2083
2084#define ADV_EEP_DELAY_MS 100
2085
27c868c2
MW
2086#define ADV_EEPROM_BIG_ENDIAN 0x8000 /* EEPROM Bit 15 */
2087#define ADV_EEPROM_BIOS_ENABLE 0x4000 /* EEPROM Bit 14 */
1da177e4
LT
2088/*
2089 * For the ASC3550 Bit 13 is Termination Polarity control bit.
2090 * For later ICs Bit 13 controls whether the CIS (Card Information
2091 * Service Section) is loaded from EEPROM.
2092 */
27c868c2
MW
2093#define ADV_EEPROM_TERM_POL 0x2000 /* EEPROM Bit 13 */
2094#define ADV_EEPROM_CIS_LD 0x2000 /* EEPROM Bit 13 */
1da177e4
LT
2095/*
2096 * ASC38C1600 Bit 11
2097 *
2098 * If EEPROM Bit 11 is 0 for Function 0, then Function 0 will specify
2099 * INT A in the PCI Configuration Space Int Pin field. If it is 1, then
2100 * Function 0 will specify INT B.
2101 *
2102 * If EEPROM Bit 11 is 0 for Function 1, then Function 1 will specify
2103 * INT B in the PCI Configuration Space Int Pin field. If it is 1, then
2104 * Function 1 will specify INT A.
2105 */
27c868c2
MW
2106#define ADV_EEPROM_INTAB 0x0800 /* EEPROM Bit 11 */
2107
2108typedef struct adveep_3550_config {
2109 /* Word Offset, Description */
2110
2111 ushort cfg_lsw; /* 00 power up initialization */
2112 /* bit 13 set - Term Polarity Control */
2113 /* bit 14 set - BIOS Enable */
2114 /* bit 15 set - Big Endian Mode */
2115 ushort cfg_msw; /* 01 unused */
2116 ushort disc_enable; /* 02 disconnect enable */
2117 ushort wdtr_able; /* 03 Wide DTR able */
2118 ushort sdtr_able; /* 04 Synchronous DTR able */
2119 ushort start_motor; /* 05 send start up motor */
2120 ushort tagqng_able; /* 06 tag queuing able */
2121 ushort bios_scan; /* 07 BIOS device control */
2122 ushort scam_tolerant; /* 08 no scam */
2123
2124 uchar adapter_scsi_id; /* 09 Host Adapter ID */
2125 uchar bios_boot_delay; /* power up wait */
2126
2127 uchar scsi_reset_delay; /* 10 reset delay */
2128 uchar bios_id_lun; /* first boot device scsi id & lun */
2129 /* high nibble is lun */
2130 /* low nibble is scsi id */
2131
2132 uchar termination; /* 11 0 - automatic */
2133 /* 1 - low off / high off */
2134 /* 2 - low off / high on */
2135 /* 3 - low on / high on */
2136 /* There is no low on / high off */
2137
2138 uchar reserved1; /* reserved byte (not used) */
2139
2140 ushort bios_ctrl; /* 12 BIOS control bits */
2141 /* bit 0 BIOS don't act as initiator. */
2142 /* bit 1 BIOS > 1 GB support */
2143 /* bit 2 BIOS > 2 Disk Support */
2144 /* bit 3 BIOS don't support removables */
2145 /* bit 4 BIOS support bootable CD */
2146 /* bit 5 BIOS scan enabled */
2147 /* bit 6 BIOS support multiple LUNs */
2148 /* bit 7 BIOS display of message */
2149 /* bit 8 SCAM disabled */
2150 /* bit 9 Reset SCSI bus during init. */
2151 /* bit 10 */
2152 /* bit 11 No verbose initialization. */
2153 /* bit 12 SCSI parity enabled */
2154 /* bit 13 */
2155 /* bit 14 */
2156 /* bit 15 */
2157 ushort ultra_able; /* 13 ULTRA speed able */
2158 ushort reserved2; /* 14 reserved */
2159 uchar max_host_qng; /* 15 maximum host queuing */
2160 uchar max_dvc_qng; /* maximum per device queuing */
2161 ushort dvc_cntl; /* 16 control bit for driver */
2162 ushort bug_fix; /* 17 control bit for bug fix */
2163 ushort serial_number_word1; /* 18 Board serial number word 1 */
2164 ushort serial_number_word2; /* 19 Board serial number word 2 */
2165 ushort serial_number_word3; /* 20 Board serial number word 3 */
2166 ushort check_sum; /* 21 EEP check sum */
2167 uchar oem_name[16]; /* 22 OEM name */
2168 ushort dvc_err_code; /* 30 last device driver error code */
2169 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
2170 ushort adv_err_addr; /* 32 last uc error address */
2171 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
2172 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
2173 ushort saved_adv_err_addr; /* 35 saved last uc error address */
2174 ushort num_of_err; /* 36 number of error */
1da177e4
LT
2175} ADVEEP_3550_CONFIG;
2176
27c868c2
MW
2177typedef struct adveep_38C0800_config {
2178 /* Word Offset, Description */
2179
2180 ushort cfg_lsw; /* 00 power up initialization */
2181 /* bit 13 set - Load CIS */
2182 /* bit 14 set - BIOS Enable */
2183 /* bit 15 set - Big Endian Mode */
2184 ushort cfg_msw; /* 01 unused */
2185 ushort disc_enable; /* 02 disconnect enable */
2186 ushort wdtr_able; /* 03 Wide DTR able */
2187 ushort sdtr_speed1; /* 04 SDTR Speed TID 0-3 */
2188 ushort start_motor; /* 05 send start up motor */
2189 ushort tagqng_able; /* 06 tag queuing able */
2190 ushort bios_scan; /* 07 BIOS device control */
2191 ushort scam_tolerant; /* 08 no scam */
2192
2193 uchar adapter_scsi_id; /* 09 Host Adapter ID */
2194 uchar bios_boot_delay; /* power up wait */
2195
2196 uchar scsi_reset_delay; /* 10 reset delay */
2197 uchar bios_id_lun; /* first boot device scsi id & lun */
2198 /* high nibble is lun */
2199 /* low nibble is scsi id */
2200
2201 uchar termination_se; /* 11 0 - automatic */
2202 /* 1 - low off / high off */
2203 /* 2 - low off / high on */
2204 /* 3 - low on / high on */
2205 /* There is no low on / high off */
2206
2207 uchar termination_lvd; /* 11 0 - automatic */
2208 /* 1 - low off / high off */
2209 /* 2 - low off / high on */
2210 /* 3 - low on / high on */
2211 /* There is no low on / high off */
2212
2213 ushort bios_ctrl; /* 12 BIOS control bits */
2214 /* bit 0 BIOS don't act as initiator. */
2215 /* bit 1 BIOS > 1 GB support */
2216 /* bit 2 BIOS > 2 Disk Support */
2217 /* bit 3 BIOS don't support removables */
2218 /* bit 4 BIOS support bootable CD */
2219 /* bit 5 BIOS scan enabled */
2220 /* bit 6 BIOS support multiple LUNs */
2221 /* bit 7 BIOS display of message */
2222 /* bit 8 SCAM disabled */
2223 /* bit 9 Reset SCSI bus during init. */
2224 /* bit 10 */
2225 /* bit 11 No verbose initialization. */
2226 /* bit 12 SCSI parity enabled */
2227 /* bit 13 */
2228 /* bit 14 */
2229 /* bit 15 */
2230 ushort sdtr_speed2; /* 13 SDTR speed TID 4-7 */
2231 ushort sdtr_speed3; /* 14 SDTR speed TID 8-11 */
2232 uchar max_host_qng; /* 15 maximum host queueing */
2233 uchar max_dvc_qng; /* maximum per device queuing */
2234 ushort dvc_cntl; /* 16 control bit for driver */
2235 ushort sdtr_speed4; /* 17 SDTR speed 4 TID 12-15 */
2236 ushort serial_number_word1; /* 18 Board serial number word 1 */
2237 ushort serial_number_word2; /* 19 Board serial number word 2 */
2238 ushort serial_number_word3; /* 20 Board serial number word 3 */
2239 ushort check_sum; /* 21 EEP check sum */
2240 uchar oem_name[16]; /* 22 OEM name */
2241 ushort dvc_err_code; /* 30 last device driver error code */
2242 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
2243 ushort adv_err_addr; /* 32 last uc error address */
2244 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
2245 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
2246 ushort saved_adv_err_addr; /* 35 saved last uc error address */
2247 ushort reserved36; /* 36 reserved */
2248 ushort reserved37; /* 37 reserved */
2249 ushort reserved38; /* 38 reserved */
2250 ushort reserved39; /* 39 reserved */
2251 ushort reserved40; /* 40 reserved */
2252 ushort reserved41; /* 41 reserved */
2253 ushort reserved42; /* 42 reserved */
2254 ushort reserved43; /* 43 reserved */
2255 ushort reserved44; /* 44 reserved */
2256 ushort reserved45; /* 45 reserved */
2257 ushort reserved46; /* 46 reserved */
2258 ushort reserved47; /* 47 reserved */
2259 ushort reserved48; /* 48 reserved */
2260 ushort reserved49; /* 49 reserved */
2261 ushort reserved50; /* 50 reserved */
2262 ushort reserved51; /* 51 reserved */
2263 ushort reserved52; /* 52 reserved */
2264 ushort reserved53; /* 53 reserved */
2265 ushort reserved54; /* 54 reserved */
2266 ushort reserved55; /* 55 reserved */
2267 ushort cisptr_lsw; /* 56 CIS PTR LSW */
2268 ushort cisprt_msw; /* 57 CIS PTR MSW */
2269 ushort subsysvid; /* 58 SubSystem Vendor ID */
2270 ushort subsysid; /* 59 SubSystem ID */
2271 ushort reserved60; /* 60 reserved */
2272 ushort reserved61; /* 61 reserved */
2273 ushort reserved62; /* 62 reserved */
2274 ushort reserved63; /* 63 reserved */
1da177e4
LT
2275} ADVEEP_38C0800_CONFIG;
2276
27c868c2
MW
2277typedef struct adveep_38C1600_config {
2278 /* Word Offset, Description */
2279
2280 ushort cfg_lsw; /* 00 power up initialization */
2281 /* bit 11 set - Func. 0 INTB, Func. 1 INTA */
2282 /* clear - Func. 0 INTA, Func. 1 INTB */
2283 /* bit 13 set - Load CIS */
2284 /* bit 14 set - BIOS Enable */
2285 /* bit 15 set - Big Endian Mode */
2286 ushort cfg_msw; /* 01 unused */
2287 ushort disc_enable; /* 02 disconnect enable */
2288 ushort wdtr_able; /* 03 Wide DTR able */
2289 ushort sdtr_speed1; /* 04 SDTR Speed TID 0-3 */
2290 ushort start_motor; /* 05 send start up motor */
2291 ushort tagqng_able; /* 06 tag queuing able */
2292 ushort bios_scan; /* 07 BIOS device control */
2293 ushort scam_tolerant; /* 08 no scam */
2294
2295 uchar adapter_scsi_id; /* 09 Host Adapter ID */
2296 uchar bios_boot_delay; /* power up wait */
2297
2298 uchar scsi_reset_delay; /* 10 reset delay */
2299 uchar bios_id_lun; /* first boot device scsi id & lun */
2300 /* high nibble is lun */
2301 /* low nibble is scsi id */
2302
2303 uchar termination_se; /* 11 0 - automatic */
2304 /* 1 - low off / high off */
2305 /* 2 - low off / high on */
2306 /* 3 - low on / high on */
2307 /* There is no low on / high off */
2308
2309 uchar termination_lvd; /* 11 0 - automatic */
2310 /* 1 - low off / high off */
2311 /* 2 - low off / high on */
2312 /* 3 - low on / high on */
2313 /* There is no low on / high off */
2314
2315 ushort bios_ctrl; /* 12 BIOS control bits */
2316 /* bit 0 BIOS don't act as initiator. */
2317 /* bit 1 BIOS > 1 GB support */
2318 /* bit 2 BIOS > 2 Disk Support */
2319 /* bit 3 BIOS don't support removables */
2320 /* bit 4 BIOS support bootable CD */
2321 /* bit 5 BIOS scan enabled */
2322 /* bit 6 BIOS support multiple LUNs */
2323 /* bit 7 BIOS display of message */
2324 /* bit 8 SCAM disabled */
2325 /* bit 9 Reset SCSI bus during init. */
2326 /* bit 10 Basic Integrity Checking disabled */
2327 /* bit 11 No verbose initialization. */
2328 /* bit 12 SCSI parity enabled */
2329 /* bit 13 AIPP (Asyn. Info. Ph. Prot.) dis. */
2330 /* bit 14 */
2331 /* bit 15 */
2332 ushort sdtr_speed2; /* 13 SDTR speed TID 4-7 */
2333 ushort sdtr_speed3; /* 14 SDTR speed TID 8-11 */
2334 uchar max_host_qng; /* 15 maximum host queueing */
2335 uchar max_dvc_qng; /* maximum per device queuing */
2336 ushort dvc_cntl; /* 16 control bit for driver */
2337 ushort sdtr_speed4; /* 17 SDTR speed 4 TID 12-15 */
2338 ushort serial_number_word1; /* 18 Board serial number word 1 */
2339 ushort serial_number_word2; /* 19 Board serial number word 2 */
2340 ushort serial_number_word3; /* 20 Board serial number word 3 */
2341 ushort check_sum; /* 21 EEP check sum */
2342 uchar oem_name[16]; /* 22 OEM name */
2343 ushort dvc_err_code; /* 30 last device driver error code */
2344 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
2345 ushort adv_err_addr; /* 32 last uc error address */
2346 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
2347 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
2348 ushort saved_adv_err_addr; /* 35 saved last uc error address */
2349 ushort reserved36; /* 36 reserved */
2350 ushort reserved37; /* 37 reserved */
2351 ushort reserved38; /* 38 reserved */
2352 ushort reserved39; /* 39 reserved */
2353 ushort reserved40; /* 40 reserved */
2354 ushort reserved41; /* 41 reserved */
2355 ushort reserved42; /* 42 reserved */
2356 ushort reserved43; /* 43 reserved */
2357 ushort reserved44; /* 44 reserved */
2358 ushort reserved45; /* 45 reserved */
2359 ushort reserved46; /* 46 reserved */
2360 ushort reserved47; /* 47 reserved */
2361 ushort reserved48; /* 48 reserved */
2362 ushort reserved49; /* 49 reserved */
2363 ushort reserved50; /* 50 reserved */
2364 ushort reserved51; /* 51 reserved */
2365 ushort reserved52; /* 52 reserved */
2366 ushort reserved53; /* 53 reserved */
2367 ushort reserved54; /* 54 reserved */
2368 ushort reserved55; /* 55 reserved */
2369 ushort cisptr_lsw; /* 56 CIS PTR LSW */
2370 ushort cisprt_msw; /* 57 CIS PTR MSW */
2371 ushort subsysvid; /* 58 SubSystem Vendor ID */
2372 ushort subsysid; /* 59 SubSystem ID */
2373 ushort reserved60; /* 60 reserved */
2374 ushort reserved61; /* 61 reserved */
2375 ushort reserved62; /* 62 reserved */
2376 ushort reserved63; /* 63 reserved */
1da177e4
LT
2377} ADVEEP_38C1600_CONFIG;
2378
2379/*
2380 * EEPROM Commands
2381 */
2382#define ASC_EEP_CMD_DONE 0x0200
2383#define ASC_EEP_CMD_DONE_ERR 0x0001
2384
2385/* cfg_word */
2386#define EEP_CFG_WORD_BIG_ENDIAN 0x8000
2387
2388/* bios_ctrl */
2389#define BIOS_CTRL_BIOS 0x0001
2390#define BIOS_CTRL_EXTENDED_XLAT 0x0002
2391#define BIOS_CTRL_GT_2_DISK 0x0004
2392#define BIOS_CTRL_BIOS_REMOVABLE 0x0008
2393#define BIOS_CTRL_BOOTABLE_CD 0x0010
2394#define BIOS_CTRL_MULTIPLE_LUN 0x0040
2395#define BIOS_CTRL_DISPLAY_MSG 0x0080
2396#define BIOS_CTRL_NO_SCAM 0x0100
2397#define BIOS_CTRL_RESET_SCSI_BUS 0x0200
2398#define BIOS_CTRL_INIT_VERBOSE 0x0800
2399#define BIOS_CTRL_SCSI_PARITY 0x1000
2400#define BIOS_CTRL_AIPP_DIS 0x2000
2401
27c868c2
MW
2402#define ADV_3550_MEMSIZE 0x2000 /* 8 KB Internal Memory */
2403#define ADV_3550_IOLEN 0x40 /* I/O Port Range in bytes */
1da177e4 2404
27c868c2
MW
2405#define ADV_38C0800_MEMSIZE 0x4000 /* 16 KB Internal Memory */
2406#define ADV_38C0800_IOLEN 0x100 /* I/O Port Range in bytes */
1da177e4
LT
2407
2408/*
2409 * XXX - Since ASC38C1600 Rev.3 has a local RAM failure issue, there is
2410 * a special 16K Adv Library and Microcode version. After the issue is
2411 * resolved, should restore 32K support.
2412 *
2413 * #define ADV_38C1600_MEMSIZE 0x8000L * 32 KB Internal Memory *
2414 */
27c868c2
MW
2415#define ADV_38C1600_MEMSIZE 0x4000 /* 16 KB Internal Memory */
2416#define ADV_38C1600_IOLEN 0x100 /* I/O Port Range 256 bytes */
2417#define ADV_38C1600_MEMLEN 0x1000 /* Memory Range 4KB bytes */
1da177e4
LT
2418
2419/*
2420 * Byte I/O register address from base of 'iop_base'.
2421 */
2422#define IOPB_INTR_STATUS_REG 0x00
2423#define IOPB_CHIP_ID_1 0x01
2424#define IOPB_INTR_ENABLES 0x02
2425#define IOPB_CHIP_TYPE_REV 0x03
2426#define IOPB_RES_ADDR_4 0x04
2427#define IOPB_RES_ADDR_5 0x05
2428#define IOPB_RAM_DATA 0x06
2429#define IOPB_RES_ADDR_7 0x07
2430#define IOPB_FLAG_REG 0x08
2431#define IOPB_RES_ADDR_9 0x09
2432#define IOPB_RISC_CSR 0x0A
2433#define IOPB_RES_ADDR_B 0x0B
2434#define IOPB_RES_ADDR_C 0x0C
2435#define IOPB_RES_ADDR_D 0x0D
2436#define IOPB_SOFT_OVER_WR 0x0E
2437#define IOPB_RES_ADDR_F 0x0F
2438#define IOPB_MEM_CFG 0x10
2439#define IOPB_RES_ADDR_11 0x11
2440#define IOPB_GPIO_DATA 0x12
2441#define IOPB_RES_ADDR_13 0x13
2442#define IOPB_FLASH_PAGE 0x14
2443#define IOPB_RES_ADDR_15 0x15
2444#define IOPB_GPIO_CNTL 0x16
2445#define IOPB_RES_ADDR_17 0x17
2446#define IOPB_FLASH_DATA 0x18
2447#define IOPB_RES_ADDR_19 0x19
2448#define IOPB_RES_ADDR_1A 0x1A
2449#define IOPB_RES_ADDR_1B 0x1B
2450#define IOPB_RES_ADDR_1C 0x1C
2451#define IOPB_RES_ADDR_1D 0x1D
2452#define IOPB_RES_ADDR_1E 0x1E
2453#define IOPB_RES_ADDR_1F 0x1F
2454#define IOPB_DMA_CFG0 0x20
2455#define IOPB_DMA_CFG1 0x21
2456#define IOPB_TICKLE 0x22
2457#define IOPB_DMA_REG_WR 0x23
2458#define IOPB_SDMA_STATUS 0x24
2459#define IOPB_SCSI_BYTE_CNT 0x25
2460#define IOPB_HOST_BYTE_CNT 0x26
2461#define IOPB_BYTE_LEFT_TO_XFER 0x27
2462#define IOPB_BYTE_TO_XFER_0 0x28
2463#define IOPB_BYTE_TO_XFER_1 0x29
2464#define IOPB_BYTE_TO_XFER_2 0x2A
2465#define IOPB_BYTE_TO_XFER_3 0x2B
2466#define IOPB_ACC_GRP 0x2C
2467#define IOPB_RES_ADDR_2D 0x2D
2468#define IOPB_DEV_ID 0x2E
2469#define IOPB_RES_ADDR_2F 0x2F
2470#define IOPB_SCSI_DATA 0x30
2471#define IOPB_RES_ADDR_31 0x31
2472#define IOPB_RES_ADDR_32 0x32
2473#define IOPB_SCSI_DATA_HSHK 0x33
2474#define IOPB_SCSI_CTRL 0x34
2475#define IOPB_RES_ADDR_35 0x35
2476#define IOPB_RES_ADDR_36 0x36
2477#define IOPB_RES_ADDR_37 0x37
2478#define IOPB_RAM_BIST 0x38
2479#define IOPB_PLL_TEST 0x39
2480#define IOPB_PCI_INT_CFG 0x3A
2481#define IOPB_RES_ADDR_3B 0x3B
2482#define IOPB_RFIFO_CNT 0x3C
2483#define IOPB_RES_ADDR_3D 0x3D
2484#define IOPB_RES_ADDR_3E 0x3E
2485#define IOPB_RES_ADDR_3F 0x3F
2486
2487/*
2488 * Word I/O register address from base of 'iop_base'.
2489 */
27c868c2
MW
2490#define IOPW_CHIP_ID_0 0x00 /* CID0 */
2491#define IOPW_CTRL_REG 0x02 /* CC */
2492#define IOPW_RAM_ADDR 0x04 /* LA */
2493#define IOPW_RAM_DATA 0x06 /* LD */
1da177e4 2494#define IOPW_RES_ADDR_08 0x08
27c868c2
MW
2495#define IOPW_RISC_CSR 0x0A /* CSR */
2496#define IOPW_SCSI_CFG0 0x0C /* CFG0 */
2497#define IOPW_SCSI_CFG1 0x0E /* CFG1 */
1da177e4 2498#define IOPW_RES_ADDR_10 0x10
27c868c2 2499#define IOPW_SEL_MASK 0x12 /* SM */
1da177e4 2500#define IOPW_RES_ADDR_14 0x14
27c868c2 2501#define IOPW_FLASH_ADDR 0x16 /* FA */
1da177e4 2502#define IOPW_RES_ADDR_18 0x18
27c868c2
MW
2503#define IOPW_EE_CMD 0x1A /* EC */
2504#define IOPW_EE_DATA 0x1C /* ED */
2505#define IOPW_SFIFO_CNT 0x1E /* SFC */
1da177e4 2506#define IOPW_RES_ADDR_20 0x20
27c868c2
MW
2507#define IOPW_Q_BASE 0x22 /* QB */
2508#define IOPW_QP 0x24 /* QP */
2509#define IOPW_IX 0x26 /* IX */
2510#define IOPW_SP 0x28 /* SP */
2511#define IOPW_PC 0x2A /* PC */
1da177e4
LT
2512#define IOPW_RES_ADDR_2C 0x2C
2513#define IOPW_RES_ADDR_2E 0x2E
27c868c2
MW
2514#define IOPW_SCSI_DATA 0x30 /* SD */
2515#define IOPW_SCSI_DATA_HSHK 0x32 /* SDH */
2516#define IOPW_SCSI_CTRL 0x34 /* SC */
2517#define IOPW_HSHK_CFG 0x36 /* HCFG */
2518#define IOPW_SXFR_STATUS 0x36 /* SXS */
2519#define IOPW_SXFR_CNTL 0x38 /* SXL */
2520#define IOPW_SXFR_CNTH 0x3A /* SXH */
1da177e4 2521#define IOPW_RES_ADDR_3C 0x3C
27c868c2 2522#define IOPW_RFIFO_DATA 0x3E /* RFD */
1da177e4
LT
2523
2524/*
2525 * Doubleword I/O register address from base of 'iop_base'.
2526 */
2527#define IOPDW_RES_ADDR_0 0x00
2528#define IOPDW_RAM_DATA 0x04
2529#define IOPDW_RES_ADDR_8 0x08
2530#define IOPDW_RES_ADDR_C 0x0C
2531#define IOPDW_RES_ADDR_10 0x10
2532#define IOPDW_COMMA 0x14
2533#define IOPDW_COMMB 0x18
2534#define IOPDW_RES_ADDR_1C 0x1C
2535#define IOPDW_SDMA_ADDR0 0x20
2536#define IOPDW_SDMA_ADDR1 0x24
2537#define IOPDW_SDMA_COUNT 0x28
2538#define IOPDW_SDMA_ERROR 0x2C
2539#define IOPDW_RDMA_ADDR0 0x30
2540#define IOPDW_RDMA_ADDR1 0x34
2541#define IOPDW_RDMA_COUNT 0x38
2542#define IOPDW_RDMA_ERROR 0x3C
2543
2544#define ADV_CHIP_ID_BYTE 0x25
2545#define ADV_CHIP_ID_WORD 0x04C1
2546
2547#define ADV_SC_SCSI_BUS_RESET 0x2000
2548
2549#define ADV_INTR_ENABLE_HOST_INTR 0x01
2550#define ADV_INTR_ENABLE_SEL_INTR 0x02
2551#define ADV_INTR_ENABLE_DPR_INTR 0x04
2552#define ADV_INTR_ENABLE_RTA_INTR 0x08
2553#define ADV_INTR_ENABLE_RMA_INTR 0x10
2554#define ADV_INTR_ENABLE_RST_INTR 0x20
2555#define ADV_INTR_ENABLE_DPE_INTR 0x40
2556#define ADV_INTR_ENABLE_GLOBAL_INTR 0x80
2557
2558#define ADV_INTR_STATUS_INTRA 0x01
2559#define ADV_INTR_STATUS_INTRB 0x02
2560#define ADV_INTR_STATUS_INTRC 0x04
2561
2562#define ADV_RISC_CSR_STOP (0x0000)
2563#define ADV_RISC_TEST_COND (0x2000)
2564#define ADV_RISC_CSR_RUN (0x4000)
2565#define ADV_RISC_CSR_SINGLE_STEP (0x8000)
2566
2567#define ADV_CTRL_REG_HOST_INTR 0x0100
2568#define ADV_CTRL_REG_SEL_INTR 0x0200
2569#define ADV_CTRL_REG_DPR_INTR 0x0400
2570#define ADV_CTRL_REG_RTA_INTR 0x0800
2571#define ADV_CTRL_REG_RMA_INTR 0x1000
2572#define ADV_CTRL_REG_RES_BIT14 0x2000
2573#define ADV_CTRL_REG_DPE_INTR 0x4000
2574#define ADV_CTRL_REG_POWER_DONE 0x8000
2575#define ADV_CTRL_REG_ANY_INTR 0xFF00
2576
2577#define ADV_CTRL_REG_CMD_RESET 0x00C6
2578#define ADV_CTRL_REG_CMD_WR_IO_REG 0x00C5
2579#define ADV_CTRL_REG_CMD_RD_IO_REG 0x00C4
2580#define ADV_CTRL_REG_CMD_WR_PCI_CFG_SPACE 0x00C3
2581#define ADV_CTRL_REG_CMD_RD_PCI_CFG_SPACE 0x00C2
2582
2583#define ADV_TICKLE_NOP 0x00
2584#define ADV_TICKLE_A 0x01
2585#define ADV_TICKLE_B 0x02
2586#define ADV_TICKLE_C 0x03
2587
2588#define ADV_SCSI_CTRL_RSTOUT 0x2000
2589
2590#define AdvIsIntPending(port) \
2591 (AdvReadWordRegister(port, IOPW_CTRL_REG) & ADV_CTRL_REG_HOST_INTR)
2592
2593/*
2594 * SCSI_CFG0 Register bit definitions
2595 */
27c868c2
MW
2596#define TIMER_MODEAB 0xC000 /* Watchdog, Second, and Select. Timer Ctrl. */
2597#define PARITY_EN 0x2000 /* Enable SCSI Parity Error detection */
2598#define EVEN_PARITY 0x1000 /* Select Even Parity */
2599#define WD_LONG 0x0800 /* Watchdog Interval, 1: 57 min, 0: 13 sec */
2600#define QUEUE_128 0x0400 /* Queue Size, 1: 128 byte, 0: 64 byte */
2601#define PRIM_MODE 0x0100 /* Primitive SCSI mode */
2602#define SCAM_EN 0x0080 /* Enable SCAM selection */
2603#define SEL_TMO_LONG 0x0040 /* Sel/Resel Timeout, 1: 400 ms, 0: 1.6 ms */
2604#define CFRM_ID 0x0020 /* SCAM id sel. confirm., 1: fast, 0: 6.4 ms */
2605#define OUR_ID_EN 0x0010 /* Enable OUR_ID bits */
2606#define OUR_ID 0x000F /* SCSI ID */
1da177e4
LT
2607
2608/*
2609 * SCSI_CFG1 Register bit definitions
2610 */
27c868c2
MW
2611#define BIG_ENDIAN 0x8000 /* Enable Big Endian Mode MIO:15, EEP:15 */
2612#define TERM_POL 0x2000 /* Terminator Polarity Ctrl. MIO:13, EEP:13 */
2613#define SLEW_RATE 0x1000 /* SCSI output buffer slew rate */
2614#define FILTER_SEL 0x0C00 /* Filter Period Selection */
2615#define FLTR_DISABLE 0x0000 /* Input Filtering Disabled */
2616#define FLTR_11_TO_20NS 0x0800 /* Input Filtering 11ns to 20ns */
2617#define FLTR_21_TO_39NS 0x0C00 /* Input Filtering 21ns to 39ns */
2618#define ACTIVE_DBL 0x0200 /* Disable Active Negation */
2619#define DIFF_MODE 0x0100 /* SCSI differential Mode (Read-Only) */
2620#define DIFF_SENSE 0x0080 /* 1: No SE cables, 0: SE cable (Read-Only) */
2621#define TERM_CTL_SEL 0x0040 /* Enable TERM_CTL_H and TERM_CTL_L */
2622#define TERM_CTL 0x0030 /* External SCSI Termination Bits */
2623#define TERM_CTL_H 0x0020 /* Enable External SCSI Upper Termination */
2624#define TERM_CTL_L 0x0010 /* Enable External SCSI Lower Termination */
2625#define CABLE_DETECT 0x000F /* External SCSI Cable Connection Status */
1da177e4
LT
2626
2627/*
2628 * Addendum for ASC-38C0800 Chip
2629 *
2630 * The ASC-38C1600 Chip uses the same definitions except that the
2631 * bus mode override bits [12:10] have been moved to byte register
2632 * offset 0xE (IOPB_SOFT_OVER_WR) bits [12:10]. The [12:10] bits in
2633 * SCSI_CFG1 are read-only and always available. Bit 14 (DIS_TERM_DRV)
2634 * is not needed. The [12:10] bits in IOPB_SOFT_OVER_WR are write-only.
2635 * Also each ASC-38C1600 function or channel uses only cable bits [5:4]
2636 * and [1:0]. Bits [14], [7:6], [3:2] are unused.
2637 */
27c868c2
MW
2638#define DIS_TERM_DRV 0x4000 /* 1: Read c_det[3:0], 0: cannot read */
2639#define HVD_LVD_SE 0x1C00 /* Device Detect Bits */
2640#define HVD 0x1000 /* HVD Device Detect */
2641#define LVD 0x0800 /* LVD Device Detect */
2642#define SE 0x0400 /* SE Device Detect */
2643#define TERM_LVD 0x00C0 /* LVD Termination Bits */
2644#define TERM_LVD_HI 0x0080 /* Enable LVD Upper Termination */
2645#define TERM_LVD_LO 0x0040 /* Enable LVD Lower Termination */
2646#define TERM_SE 0x0030 /* SE Termination Bits */
2647#define TERM_SE_HI 0x0020 /* Enable SE Upper Termination */
2648#define TERM_SE_LO 0x0010 /* Enable SE Lower Termination */
2649#define C_DET_LVD 0x000C /* LVD Cable Detect Bits */
2650#define C_DET3 0x0008 /* Cable Detect for LVD External Wide */
2651#define C_DET2 0x0004 /* Cable Detect for LVD Internal Wide */
2652#define C_DET_SE 0x0003 /* SE Cable Detect Bits */
2653#define C_DET1 0x0002 /* Cable Detect for SE Internal Wide */
2654#define C_DET0 0x0001 /* Cable Detect for SE Internal Narrow */
1da177e4
LT
2655
2656#define CABLE_ILLEGAL_A 0x7
2657 /* x 0 0 0 | on on | Illegal (all 3 connectors are used) */
2658
2659#define CABLE_ILLEGAL_B 0xB
2660 /* 0 x 0 0 | on on | Illegal (all 3 connectors are used) */
2661
2662/*
2663 * MEM_CFG Register bit definitions
2664 */
27c868c2
MW
2665#define BIOS_EN 0x40 /* BIOS Enable MIO:14,EEP:14 */
2666#define FAST_EE_CLK 0x20 /* Diagnostic Bit */
2667#define RAM_SZ 0x1C /* Specify size of RAM to RISC */
2668#define RAM_SZ_2KB 0x00 /* 2 KB */
2669#define RAM_SZ_4KB 0x04 /* 4 KB */
2670#define RAM_SZ_8KB 0x08 /* 8 KB */
2671#define RAM_SZ_16KB 0x0C /* 16 KB */
2672#define RAM_SZ_32KB 0x10 /* 32 KB */
2673#define RAM_SZ_64KB 0x14 /* 64 KB */
1da177e4
LT
2674
2675/*
2676 * DMA_CFG0 Register bit definitions
2677 *
2678 * This register is only accessible to the host.
2679 */
27c868c2
MW
2680#define BC_THRESH_ENB 0x80 /* PCI DMA Start Conditions */
2681#define FIFO_THRESH 0x70 /* PCI DMA FIFO Threshold */
2682#define FIFO_THRESH_16B 0x00 /* 16 bytes */
2683#define FIFO_THRESH_32B 0x20 /* 32 bytes */
2684#define FIFO_THRESH_48B 0x30 /* 48 bytes */
2685#define FIFO_THRESH_64B 0x40 /* 64 bytes */
2686#define FIFO_THRESH_80B 0x50 /* 80 bytes (default) */
2687#define FIFO_THRESH_96B 0x60 /* 96 bytes */
2688#define FIFO_THRESH_112B 0x70 /* 112 bytes */
2689#define START_CTL 0x0C /* DMA start conditions */
2690#define START_CTL_TH 0x00 /* Wait threshold level (default) */
2691#define START_CTL_ID 0x04 /* Wait SDMA/SBUS idle */
2692#define START_CTL_THID 0x08 /* Wait threshold and SDMA/SBUS idle */
2693#define START_CTL_EMFU 0x0C /* Wait SDMA FIFO empty/full */
2694#define READ_CMD 0x03 /* Memory Read Method */
2695#define READ_CMD_MR 0x00 /* Memory Read */
2696#define READ_CMD_MRL 0x02 /* Memory Read Long */
2697#define READ_CMD_MRM 0x03 /* Memory Read Multiple (default) */
1da177e4
LT
2698
2699/*
2700 * ASC-38C0800 RAM BIST Register bit definitions
2701 */
2702#define RAM_TEST_MODE 0x80
2703#define PRE_TEST_MODE 0x40
2704#define NORMAL_MODE 0x00
2705#define RAM_TEST_DONE 0x10
2706#define RAM_TEST_STATUS 0x0F
2707#define RAM_TEST_HOST_ERROR 0x08
2708#define RAM_TEST_INTRAM_ERROR 0x04
2709#define RAM_TEST_RISC_ERROR 0x02
2710#define RAM_TEST_SCSI_ERROR 0x01
2711#define RAM_TEST_SUCCESS 0x00
2712#define PRE_TEST_VALUE 0x05
2713#define NORMAL_VALUE 0x00
2714
2715/*
2716 * ASC38C1600 Definitions
2717 *
2718 * IOPB_PCI_INT_CFG Bit Field Definitions
2719 */
2720
27c868c2 2721#define INTAB_LD 0x80 /* Value loaded from EEPROM Bit 11. */
1da177e4
LT
2722
2723/*
2724 * Bit 1 can be set to change the interrupt for the Function to operate in
2725 * Totem Pole mode. By default Bit 1 is 0 and the interrupt operates in
2726 * Open Drain mode. Both functions of the ASC38C1600 must be set to the same
2727 * mode, otherwise the operating mode is undefined.
2728 */
2729#define TOTEMPOLE 0x02
2730
2731/*
2732 * Bit 0 can be used to change the Int Pin for the Function. The value is
2733 * 0 by default for both Functions with Function 0 using INT A and Function
2734 * B using INT B. For Function 0 if set, INT B is used. For Function 1 if set,
2735 * INT A is used.
2736 *
2737 * EEPROM Word 0 Bit 11 for each Function may change the initial Int Pin
2738 * value specified in the PCI Configuration Space.
2739 */
2740#define INTAB 0x01
2741
2742/* a_advlib.h */
2743
2744/*
2745 * Adv Library Status Definitions
2746 */
2747#define ADV_TRUE 1
2748#define ADV_FALSE 0
2749#define ADV_NOERROR 1
2750#define ADV_SUCCESS 1
2751#define ADV_BUSY 0
2752#define ADV_ERROR (-1)
2753
1da177e4
LT
2754/*
2755 * ADV_DVC_VAR 'warn_code' values
2756 */
27c868c2
MW
2757#define ASC_WARN_BUSRESET_ERROR 0x0001 /* SCSI Bus Reset error */
2758#define ASC_WARN_EEPROM_CHKSUM 0x0002 /* EEP check sum error */
2759#define ASC_WARN_EEPROM_TERMINATION 0x0004 /* EEP termination bad field */
2760#define ASC_WARN_SET_PCI_CONFIG_SPACE 0x0080 /* PCI config space set error */
2761#define ASC_WARN_ERROR 0xFFFF /* ADV_ERROR return */
1da177e4 2762
27c868c2
MW
2763#define ADV_MAX_TID 15 /* max. target identifier */
2764#define ADV_MAX_LUN 7 /* max. logical unit number */
1da177e4
LT
2765
2766/*
2767 * Error code values are set in ADV_DVC_VAR 'err_code'.
2768 */
27c868c2
MW
2769#define ASC_IERR_WRITE_EEPROM 0x0001 /* write EEPROM error */
2770#define ASC_IERR_MCODE_CHKSUM 0x0002 /* micro code check sum error */
2771#define ASC_IERR_NO_CARRIER 0x0004 /* No more carrier memory. */
2772#define ASC_IERR_START_STOP_CHIP 0x0008 /* start/stop chip failed */
2773#define ASC_IERR_CHIP_VERSION 0x0040 /* wrong chip version */
2774#define ASC_IERR_SET_SCSI_ID 0x0080 /* set SCSI ID failed */
2775#define ASC_IERR_HVD_DEVICE 0x0100 /* HVD attached to LVD connector. */
2776#define ASC_IERR_BAD_SIGNATURE 0x0200 /* signature not found */
2777#define ASC_IERR_ILLEGAL_CONNECTION 0x0400 /* Illegal cable connection */
2778#define ASC_IERR_SINGLE_END_DEVICE 0x0800 /* Single-end used w/differential */
2779#define ASC_IERR_REVERSED_CABLE 0x1000 /* Narrow flat cable reversed */
2780#define ASC_IERR_BIST_PRE_TEST 0x2000 /* BIST pre-test error */
2781#define ASC_IERR_BIST_RAM_TEST 0x4000 /* BIST RAM test error */
2782#define ASC_IERR_BAD_CHIPTYPE 0x8000 /* Invalid 'chip_type' setting. */
1da177e4
LT
2783
2784/*
2785 * Fixed locations of microcode operating variables.
2786 */
27c868c2
MW
2787#define ASC_MC_CODE_BEGIN_ADDR 0x0028 /* microcode start address */
2788#define ASC_MC_CODE_END_ADDR 0x002A /* microcode end address */
2789#define ASC_MC_CODE_CHK_SUM 0x002C /* microcode code checksum */
2790#define ASC_MC_VERSION_DATE 0x0038 /* microcode version */
2791#define ASC_MC_VERSION_NUM 0x003A /* microcode number */
2792#define ASC_MC_BIOSMEM 0x0040 /* BIOS RISC Memory Start */
2793#define ASC_MC_BIOSLEN 0x0050 /* BIOS RISC Memory Length */
2794#define ASC_MC_BIOS_SIGNATURE 0x0058 /* BIOS Signature 0x55AA */
2795#define ASC_MC_BIOS_VERSION 0x005A /* BIOS Version (2 bytes) */
2796#define ASC_MC_SDTR_SPEED1 0x0090 /* SDTR Speed for TID 0-3 */
2797#define ASC_MC_SDTR_SPEED2 0x0092 /* SDTR Speed for TID 4-7 */
2798#define ASC_MC_SDTR_SPEED3 0x0094 /* SDTR Speed for TID 8-11 */
2799#define ASC_MC_SDTR_SPEED4 0x0096 /* SDTR Speed for TID 12-15 */
1da177e4
LT
2800#define ASC_MC_CHIP_TYPE 0x009A
2801#define ASC_MC_INTRB_CODE 0x009B
2802#define ASC_MC_WDTR_ABLE 0x009C
2803#define ASC_MC_SDTR_ABLE 0x009E
2804#define ASC_MC_TAGQNG_ABLE 0x00A0
2805#define ASC_MC_DISC_ENABLE 0x00A2
2806#define ASC_MC_IDLE_CMD_STATUS 0x00A4
2807#define ASC_MC_IDLE_CMD 0x00A6
2808#define ASC_MC_IDLE_CMD_PARAMETER 0x00A8
2809#define ASC_MC_DEFAULT_SCSI_CFG0 0x00AC
2810#define ASC_MC_DEFAULT_SCSI_CFG1 0x00AE
2811#define ASC_MC_DEFAULT_MEM_CFG 0x00B0
2812#define ASC_MC_DEFAULT_SEL_MASK 0x00B2
2813#define ASC_MC_SDTR_DONE 0x00B6
2814#define ASC_MC_NUMBER_OF_QUEUED_CMD 0x00C0
2815#define ASC_MC_NUMBER_OF_MAX_CMD 0x00D0
2816#define ASC_MC_DEVICE_HSHK_CFG_TABLE 0x0100
27c868c2 2817#define ASC_MC_CONTROL_FLAG 0x0122 /* Microcode control flag. */
1da177e4 2818#define ASC_MC_WDTR_DONE 0x0124
27c868c2 2819#define ASC_MC_CAM_MODE_MASK 0x015E /* CAM mode TID bitmask. */
1da177e4
LT
2820#define ASC_MC_ICQ 0x0160
2821#define ASC_MC_IRQ 0x0164
2822#define ASC_MC_PPR_ABLE 0x017A
2823
2824/*
2825 * BIOS LRAM variable absolute offsets.
2826 */
2827#define BIOS_CODESEG 0x54
2828#define BIOS_CODELEN 0x56
2829#define BIOS_SIGNATURE 0x58
2830#define BIOS_VERSION 0x5A
2831
2832/*
2833 * Microcode Control Flags
2834 *
2835 * Flags set by the Adv Library in RISC variable 'control_flag' (0x122)
2836 * and handled by the microcode.
2837 */
27c868c2
MW
2838#define CONTROL_FLAG_IGNORE_PERR 0x0001 /* Ignore DMA Parity Errors */
2839#define CONTROL_FLAG_ENABLE_AIPP 0x0002 /* Enabled AIPP checking. */
1da177e4
LT
2840
2841/*
2842 * ASC_MC_DEVICE_HSHK_CFG_TABLE microcode table or HSHK_CFG register format
2843 */
2844#define HSHK_CFG_WIDE_XFR 0x8000
2845#define HSHK_CFG_RATE 0x0F00
2846#define HSHK_CFG_OFFSET 0x001F
2847
27c868c2
MW
2848#define ASC_DEF_MAX_HOST_QNG 0xFD /* Max. number of host commands (253) */
2849#define ASC_DEF_MIN_HOST_QNG 0x10 /* Min. number of host commands (16) */
2850#define ASC_DEF_MAX_DVC_QNG 0x3F /* Max. number commands per device (63) */
2851#define ASC_DEF_MIN_DVC_QNG 0x04 /* Min. number commands per device (4) */
2852
2853#define ASC_QC_DATA_CHECK 0x01 /* Require ASC_QC_DATA_OUT set or clear. */
2854#define ASC_QC_DATA_OUT 0x02 /* Data out DMA transfer. */
2855#define ASC_QC_START_MOTOR 0x04 /* Send auto-start motor before request. */
2856#define ASC_QC_NO_OVERRUN 0x08 /* Don't report overrun. */
2857#define ASC_QC_FREEZE_TIDQ 0x10 /* Freeze TID queue after request. XXX TBD */
2858
2859#define ASC_QSC_NO_DISC 0x01 /* Don't allow disconnect for request. */
2860#define ASC_QSC_NO_TAGMSG 0x02 /* Don't allow tag queuing for request. */
2861#define ASC_QSC_NO_SYNC 0x04 /* Don't use Synch. transfer on request. */
2862#define ASC_QSC_NO_WIDE 0x08 /* Don't use Wide transfer on request. */
2863#define ASC_QSC_REDO_DTR 0x10 /* Renegotiate WDTR/SDTR before request. */
1da177e4
LT
2864/*
2865 * Note: If a Tag Message is to be sent and neither ASC_QSC_HEAD_TAG or
2866 * ASC_QSC_ORDERED_TAG is set, then a Simple Tag Message (0x20) is used.
2867 */
27c868c2
MW
2868#define ASC_QSC_HEAD_TAG 0x40 /* Use Head Tag Message (0x21). */
2869#define ASC_QSC_ORDERED_TAG 0x80 /* Use Ordered Tag Message (0x22). */
1da177e4
LT
2870
2871/*
2872 * All fields here are accessed by the board microcode and need to be
2873 * little-endian.
2874 */
27c868c2
MW
2875typedef struct adv_carr_t {
2876 ADV_VADDR carr_va; /* Carrier Virtual Address */
2877 ADV_PADDR carr_pa; /* Carrier Physical Address */
2878 ADV_VADDR areq_vpa; /* ASC_SCSI_REQ_Q Virtual or Physical Address */
2879 /*
2880 * next_vpa [31:4] Carrier Virtual or Physical Next Pointer
2881 *
2882 * next_vpa [3:1] Reserved Bits
2883 * next_vpa [0] Done Flag set in Response Queue.
2884 */
2885 ADV_VADDR next_vpa;
1da177e4
LT
2886} ADV_CARR_T;
2887
2888/*
2889 * Mask used to eliminate low 4 bits of carrier 'next_vpa' field.
2890 */
2891#define ASC_NEXT_VPA_MASK 0xFFFFFFF0
2892
2893#define ASC_RQ_DONE 0x00000001
2894#define ASC_RQ_GOOD 0x00000002
2895#define ASC_CQ_STOPPER 0x00000000
2896
2897#define ASC_GET_CARRP(carrp) ((carrp) & ASC_NEXT_VPA_MASK)
2898
2899#define ADV_CARRIER_NUM_PAGE_CROSSING \
2900 (((ADV_CARRIER_COUNT * sizeof(ADV_CARR_T)) + \
2901 (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
2902
2903#define ADV_CARRIER_BUFSIZE \
2904 ((ADV_CARRIER_COUNT + ADV_CARRIER_NUM_PAGE_CROSSING) * sizeof(ADV_CARR_T))
2905
2906/*
2907 * ASC_SCSI_REQ_Q 'a_flag' definitions
2908 *
2909 * The Adv Library should limit use to the lower nibble (4 bits) of
2910 * a_flag. Drivers are free to use the upper nibble (4 bits) of a_flag.
2911 */
27c868c2
MW
2912#define ADV_POLL_REQUEST 0x01 /* poll for request completion */
2913#define ADV_SCSIQ_DONE 0x02 /* request done */
2914#define ADV_DONT_RETRY 0x08 /* don't do retry */
1da177e4 2915
27c868c2
MW
2916#define ADV_CHIP_ASC3550 0x01 /* Ultra-Wide IC */
2917#define ADV_CHIP_ASC38C0800 0x02 /* Ultra2-Wide/LVD IC */
2918#define ADV_CHIP_ASC38C1600 0x03 /* Ultra3-Wide/LVD2 IC */
1da177e4
LT
2919
2920/*
2921 * Adapter temporary configuration structure
2922 *
2923 * This structure can be discarded after initialization. Don't add
2924 * fields here needed after initialization.
2925 *
2926 * Field naming convention:
2927 *
2928 * *_enable indicates the field enables or disables a feature. The
2929 * value of the field is never reset.
2930 */
2931typedef struct adv_dvc_cfg {
27c868c2
MW
2932 ushort disc_enable; /* enable disconnection */
2933 uchar chip_version; /* chip version */
2934 uchar termination; /* Term. Ctrl. bits 6-5 of SCSI_CFG1 register */
2935 ushort lib_version; /* Adv Library version number */
2936 ushort control_flag; /* Microcode Control Flag */
2937 ushort mcode_date; /* Microcode date */
2938 ushort mcode_version; /* Microcode version */
2939 ushort pci_slot_info; /* high byte device/function number */
2940 /* bits 7-3 device num., bits 2-0 function num. */
2941 /* low byte bus num. */
2942 ushort serial1; /* EEPROM serial number word 1 */
2943 ushort serial2; /* EEPROM serial number word 2 */
2944 ushort serial3; /* EEPROM serial number word 3 */
2945 struct device *dev; /* pointer to the pci dev structure for this board */
1da177e4
LT
2946} ADV_DVC_CFG;
2947
2948struct adv_dvc_var;
2949struct adv_scsi_req_q;
2950
27c868c2
MW
2951typedef void (*ADV_ISR_CALLBACK)
2952 (struct adv_dvc_var *, struct adv_scsi_req_q *);
1da177e4 2953
27c868c2
MW
2954typedef void (*ADV_ASYNC_CALLBACK)
2955 (struct adv_dvc_var *, uchar);
1da177e4
LT
2956
2957/*
2958 * Adapter operation variable structure.
2959 *
2960 * One structure is required per host adapter.
2961 *
2962 * Field naming convention:
2963 *
2964 * *_able indicates both whether a feature should be enabled or disabled
2965 * and whether a device isi capable of the feature. At initialization
2966 * this field may be set, but later if a device is found to be incapable
2967 * of the feature, the field is cleared.
2968 */
2969typedef struct adv_dvc_var {
27c868c2
MW
2970 AdvPortAddr iop_base; /* I/O port address */
2971 ushort err_code; /* fatal error code */
2972 ushort bios_ctrl; /* BIOS control word, EEPROM word 12 */
2973 ADV_ISR_CALLBACK isr_callback;
2974 ADV_ASYNC_CALLBACK async_callback;
2975 ushort wdtr_able; /* try WDTR for a device */
2976 ushort sdtr_able; /* try SDTR for a device */
2977 ushort ultra_able; /* try SDTR Ultra speed for a device */
2978 ushort sdtr_speed1; /* EEPROM SDTR Speed for TID 0-3 */
2979 ushort sdtr_speed2; /* EEPROM SDTR Speed for TID 4-7 */
2980 ushort sdtr_speed3; /* EEPROM SDTR Speed for TID 8-11 */
2981 ushort sdtr_speed4; /* EEPROM SDTR Speed for TID 12-15 */
2982 ushort tagqng_able; /* try tagged queuing with a device */
2983 ushort ppr_able; /* PPR message capable per TID bitmask. */
2984 uchar max_dvc_qng; /* maximum number of tagged commands per device */
2985 ushort start_motor; /* start motor command allowed */
2986 uchar scsi_reset_wait; /* delay in seconds after scsi bus reset */
2987 uchar chip_no; /* should be assigned by caller */
2988 uchar max_host_qng; /* maximum number of Q'ed command allowed */
2989 uchar irq_no; /* IRQ number */
2990 ushort no_scam; /* scam_tolerant of EEPROM */
2991 struct asc_board *drv_ptr; /* driver pointer to private structure */
2992 uchar chip_scsi_id; /* chip SCSI target ID */
2993 uchar chip_type;
2994 uchar bist_err_code;
2995 ADV_CARR_T *carrier_buf;
2996 ADV_CARR_T *carr_freelist; /* Carrier free list. */
2997 ADV_CARR_T *icq_sp; /* Initiator command queue stopper pointer. */
2998 ADV_CARR_T *irq_sp; /* Initiator response queue stopper pointer. */
2999 ushort carr_pending_cnt; /* Count of pending carriers. */
3000 /*
3001 * Note: The following fields will not be used after initialization. The
3002 * driver may discard the buffer after initialization is done.
3003 */
3004 ADV_DVC_CFG *cfg; /* temporary configuration structure */
1da177e4
LT
3005} ADV_DVC_VAR;
3006
3007#define NO_OF_SG_PER_BLOCK 15
3008
3009typedef struct asc_sg_block {
27c868c2
MW
3010 uchar reserved1;
3011 uchar reserved2;
3012 uchar reserved3;
3013 uchar sg_cnt; /* Valid entries in block. */
3014 ADV_PADDR sg_ptr; /* Pointer to next sg block. */
3015 struct {
3016 ADV_PADDR sg_addr; /* SG element address. */
3017 ADV_DCNT sg_count; /* SG element count. */
3018 } sg_list[NO_OF_SG_PER_BLOCK];
1da177e4
LT
3019} ADV_SG_BLOCK;
3020
3021/*
3022 * ADV_SCSI_REQ_Q - microcode request structure
3023 *
3024 * All fields in this structure up to byte 60 are used by the microcode.
3025 * The microcode makes assumptions about the size and ordering of fields
3026 * in this structure. Do not change the structure definition here without
3027 * coordinating the change with the microcode.
3028 *
3029 * All fields accessed by microcode must be maintained in little_endian
3030 * order.
3031 */
3032typedef struct adv_scsi_req_q {
27c868c2
MW
3033 uchar cntl; /* Ucode flags and state (ASC_MC_QC_*). */
3034 uchar target_cmd;
3035 uchar target_id; /* Device target identifier. */
3036 uchar target_lun; /* Device target logical unit number. */
3037 ADV_PADDR data_addr; /* Data buffer physical address. */
3038 ADV_DCNT data_cnt; /* Data count. Ucode sets to residual. */
3039 ADV_PADDR sense_addr;
3040 ADV_PADDR carr_pa;
3041 uchar mflag;
3042 uchar sense_len;
3043 uchar cdb_len; /* SCSI CDB length. Must <= 16 bytes. */
3044 uchar scsi_cntl;
3045 uchar done_status; /* Completion status. */
3046 uchar scsi_status; /* SCSI status byte. */
3047 uchar host_status; /* Ucode host status. */
3048 uchar sg_working_ix;
3049 uchar cdb[12]; /* SCSI CDB bytes 0-11. */
3050 ADV_PADDR sg_real_addr; /* SG list physical address. */
3051 ADV_PADDR scsiq_rptr;
3052 uchar cdb16[4]; /* SCSI CDB bytes 12-15. */
3053 ADV_VADDR scsiq_ptr;
3054 ADV_VADDR carr_va;
3055 /*
3056 * End of microcode structure - 60 bytes. The rest of the structure
3057 * is used by the Adv Library and ignored by the microcode.
3058 */
3059 ADV_VADDR srb_ptr;
3060 ADV_SG_BLOCK *sg_list_ptr; /* SG list virtual address. */
3061 char *vdata_addr; /* Data buffer virtual address. */
3062 uchar a_flag;
3063 uchar pad[2]; /* Pad out to a word boundary. */
1da177e4
LT
3064} ADV_SCSI_REQ_Q;
3065
3066/*
3067 * Microcode idle loop commands
3068 */
3069#define IDLE_CMD_COMPLETED 0
3070#define IDLE_CMD_STOP_CHIP 0x0001
3071#define IDLE_CMD_STOP_CHIP_SEND_INT 0x0002
3072#define IDLE_CMD_SEND_INT 0x0004
3073#define IDLE_CMD_ABORT 0x0008
3074#define IDLE_CMD_DEVICE_RESET 0x0010
27c868c2
MW
3075#define IDLE_CMD_SCSI_RESET_START 0x0020 /* Assert SCSI Bus Reset */
3076#define IDLE_CMD_SCSI_RESET_END 0x0040 /* Deassert SCSI Bus Reset */
1da177e4
LT
3077#define IDLE_CMD_SCSIREQ 0x0080
3078
3079#define IDLE_CMD_STATUS_SUCCESS 0x0001
3080#define IDLE_CMD_STATUS_FAILURE 0x0002
3081
3082/*
3083 * AdvSendIdleCmd() flag definitions.
3084 */
3085#define ADV_NOWAIT 0x01
3086
3087/*
3088 * Wait loop time out values.
3089 */
27c868c2
MW
3090#define SCSI_WAIT_10_SEC 10UL /* 10 seconds */
3091#define SCSI_WAIT_100_MSEC 100UL /* 100 milliseconds */
3092#define SCSI_US_PER_MSEC 1000 /* microseconds per millisecond */
3093#define SCSI_MS_PER_SEC 1000UL /* milliseconds per second */
3094#define SCSI_MAX_RETRY 10 /* retry count */
1da177e4 3095
27c868c2
MW
3096#define ADV_ASYNC_RDMA_FAILURE 0x01 /* Fatal RDMA failure. */
3097#define ADV_ASYNC_SCSI_BUS_RESET_DET 0x02 /* Detected SCSI Bus Reset. */
3098#define ADV_ASYNC_CARRIER_READY_FAILURE 0x03 /* Carrier Ready failure. */
3099#define ADV_RDMA_IN_CARR_AND_Q_INVALID 0x04 /* RDMAed-in data invalid. */
1da177e4 3100
27c868c2 3101#define ADV_HOST_SCSI_BUS_RESET 0x80 /* Host Initiated SCSI Bus Reset. */
1da177e4
LT
3102
3103/*
3104 * Device drivers must define the following functions.
3105 */
27c868c2
MW
3106static inline ulong DvcEnterCritical(void);
3107static inline void DvcLeaveCritical(ulong);
3108static void DvcSleepMilliSecond(ADV_DCNT);
3109static uchar DvcAdvReadPCIConfigByte(ADV_DVC_VAR *, ushort);
3110static void DvcAdvWritePCIConfigByte(ADV_DVC_VAR *, ushort, uchar);
3111static ADV_PADDR DvcGetPhyAddr(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *,
3112 uchar *, ASC_SDCNT *, int);
3113static void DvcDelayMicroSecond(ADV_DVC_VAR *, ushort);
1da177e4
LT
3114
3115/*
3116 * Adv Library functions available to drivers.
3117 */
27c868c2
MW
3118static int AdvExeScsiQueue(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
3119static int AdvISR(ADV_DVC_VAR *);
3120static int AdvInitGetConfig(ADV_DVC_VAR *);
3121static int AdvInitAsc3550Driver(ADV_DVC_VAR *);
3122static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *);
3123static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *);
3124static int AdvResetChipAndSB(ADV_DVC_VAR *);
3125static int AdvResetSB(ADV_DVC_VAR *asc_dvc);
1da177e4
LT
3126
3127/*
3128 * Internal Adv Library functions.
3129 */
27c868c2
MW
3130static int AdvSendIdleCmd(ADV_DVC_VAR *, ushort, ADV_DCNT);
3131static void AdvInquiryHandling(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
3132static int AdvInitFrom3550EEP(ADV_DVC_VAR *);
3133static int AdvInitFrom38C0800EEP(ADV_DVC_VAR *);
3134static int AdvInitFrom38C1600EEP(ADV_DVC_VAR *);
3135static ushort AdvGet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *);
3136static void AdvSet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *);
3137static ushort AdvGet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *);
3138static void AdvSet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *);
3139static ushort AdvGet38C1600EEPConfig(AdvPortAddr, ADVEEP_38C1600_CONFIG *);
3140static void AdvSet38C1600EEPConfig(AdvPortAddr, ADVEEP_38C1600_CONFIG *);
3141static void AdvWaitEEPCmd(AdvPortAddr);
3142static ushort AdvReadEEPWord(AdvPortAddr, int);
1da177e4
LT
3143
3144/*
3145 * PCI Bus Definitions
3146 */
3147#define AscPCICmdRegBits_BusMastering 0x0007
3148#define AscPCICmdRegBits_ParErrRespCtrl 0x0040
3149
3150/* Read byte from a register. */
3151#define AdvReadByteRegister(iop_base, reg_off) \
3152 (ADV_MEM_READB((iop_base) + (reg_off)))
3153
3154/* Write byte to a register. */
3155#define AdvWriteByteRegister(iop_base, reg_off, byte) \
3156 (ADV_MEM_WRITEB((iop_base) + (reg_off), (byte)))
3157
3158/* Read word (2 bytes) from a register. */
3159#define AdvReadWordRegister(iop_base, reg_off) \
3160 (ADV_MEM_READW((iop_base) + (reg_off)))
3161
3162/* Write word (2 bytes) to a register. */
3163#define AdvWriteWordRegister(iop_base, reg_off, word) \
3164 (ADV_MEM_WRITEW((iop_base) + (reg_off), (word)))
3165
3166/* Write dword (4 bytes) to a register. */
3167#define AdvWriteDWordRegister(iop_base, reg_off, dword) \
3168 (ADV_MEM_WRITEDW((iop_base) + (reg_off), (dword)))
3169
3170/* Read byte from LRAM. */
3171#define AdvReadByteLram(iop_base, addr, byte) \
3172do { \
3173 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
3174 (byte) = ADV_MEM_READB((iop_base) + IOPB_RAM_DATA); \
3175} while (0)
3176
3177/* Write byte to LRAM. */
3178#define AdvWriteByteLram(iop_base, addr, byte) \
3179 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3180 ADV_MEM_WRITEB((iop_base) + IOPB_RAM_DATA, (byte)))
3181
3182/* Read word (2 bytes) from LRAM. */
3183#define AdvReadWordLram(iop_base, addr, word) \
3184do { \
3185 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
3186 (word) = (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA)); \
3187} while (0)
3188
3189/* Write word (2 bytes) to LRAM. */
3190#define AdvWriteWordLram(iop_base, addr, word) \
3191 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3192 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
3193
3194/* Write little-endian double word (4 bytes) to LRAM */
3195/* Because of unspecified C language ordering don't use auto-increment. */
3196#define AdvWriteDWordLramNoSwap(iop_base, addr, dword) \
3197 ((ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3198 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
3199 cpu_to_le16((ushort) ((dword) & 0xFFFF)))), \
3200 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr) + 2), \
3201 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
3202 cpu_to_le16((ushort) ((dword >> 16) & 0xFFFF)))))
3203
3204/* Read word (2 bytes) from LRAM assuming that the address is already set. */
3205#define AdvReadWordAutoIncLram(iop_base) \
3206 (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA))
3207
3208/* Write word (2 bytes) to LRAM assuming that the address is already set. */
3209#define AdvWriteWordAutoIncLram(iop_base, word) \
3210 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
3211
1da177e4
LT
3212/*
3213 * Define macro to check for Condor signature.
3214 *
3215 * Evaluate to ADV_TRUE if a Condor chip is found the specified port
3216 * address 'iop_base'. Otherwise evalue to ADV_FALSE.
3217 */
3218#define AdvFindSignature(iop_base) \
3219 (((AdvReadByteRegister((iop_base), IOPB_CHIP_ID_1) == \
3220 ADV_CHIP_ID_BYTE) && \
3221 (AdvReadWordRegister((iop_base), IOPW_CHIP_ID_0) == \
3222 ADV_CHIP_ID_WORD)) ? ADV_TRUE : ADV_FALSE)
3223
3224/*
3225 * Define macro to Return the version number of the chip at 'iop_base'.
3226 *
3227 * The second parameter 'bus_type' is currently unused.
3228 */
3229#define AdvGetChipVersion(iop_base, bus_type) \
3230 AdvReadByteRegister((iop_base), IOPB_CHIP_TYPE_REV)
3231
3232/*
3233 * Abort an SRB in the chip's RISC Memory. The 'srb_ptr' argument must
3234 * match the ASC_SCSI_REQ_Q 'srb_ptr' field.
3235 *
3236 * If the request has not yet been sent to the device it will simply be
3237 * aborted from RISC memory. If the request is disconnected it will be
3238 * aborted on reselection by sending an Abort Message to the target ID.
3239 *
3240 * Return value:
3241 * ADV_TRUE(1) - Queue was successfully aborted.
3242 * ADV_FALSE(0) - Queue was not found on the active queue list.
3243 */
3244#define AdvAbortQueue(asc_dvc, scsiq) \
3245 AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_ABORT, \
3246 (ADV_DCNT) (scsiq))
3247
3248/*
3249 * Send a Bus Device Reset Message to the specified target ID.
3250 *
3251 * All outstanding commands will be purged if sending the
3252 * Bus Device Reset Message is successful.
3253 *
3254 * Return Value:
3255 * ADV_TRUE(1) - All requests on the target are purged.
3256 * ADV_FALSE(0) - Couldn't issue Bus Device Reset Message; Requests
3257 * are not purged.
3258 */
3259#define AdvResetDevice(asc_dvc, target_id) \
3260 AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_DEVICE_RESET, \
3261 (ADV_DCNT) (target_id))
3262
3263/*
3264 * SCSI Wide Type definition.
3265 */
3266#define ADV_SCSI_BIT_ID_TYPE ushort
3267
3268/*
3269 * AdvInitScsiTarget() 'cntl_flag' options.
3270 */
3271#define ADV_SCAN_LUN 0x01
3272#define ADV_CAPINFO_NOLUN 0x02
3273
3274/*
3275 * Convert target id to target id bit mask.
3276 */
3277#define ADV_TID_TO_TIDMASK(tid) (0x01 << ((tid) & ADV_MAX_TID))
3278
3279/*
3280 * ASC_SCSI_REQ_Q 'done_status' and 'host_status' return values.
3281 */
3282
27c868c2 3283#define QD_NO_STATUS 0x00 /* Request not completed yet. */
1da177e4
LT
3284#define QD_NO_ERROR 0x01
3285#define QD_ABORTED_BY_HOST 0x02
3286#define QD_WITH_ERROR 0x04
3287
3288#define QHSTA_NO_ERROR 0x00
3289#define QHSTA_M_SEL_TIMEOUT 0x11
3290#define QHSTA_M_DATA_OVER_RUN 0x12
3291#define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
3292#define QHSTA_M_QUEUE_ABORTED 0x15
27c868c2
MW
3293#define QHSTA_M_SXFR_SDMA_ERR 0x16 /* SXFR_STATUS SCSI DMA Error */
3294#define QHSTA_M_SXFR_SXFR_PERR 0x17 /* SXFR_STATUS SCSI Bus Parity Error */
3295#define QHSTA_M_RDMA_PERR 0x18 /* RISC PCI DMA parity error */
3296#define QHSTA_M_SXFR_OFF_UFLW 0x19 /* SXFR_STATUS Offset Underflow */
3297#define QHSTA_M_SXFR_OFF_OFLW 0x20 /* SXFR_STATUS Offset Overflow */
3298#define QHSTA_M_SXFR_WD_TMO 0x21 /* SXFR_STATUS Watchdog Timeout */
3299#define QHSTA_M_SXFR_DESELECTED 0x22 /* SXFR_STATUS Deselected */
1da177e4 3300/* Note: QHSTA_M_SXFR_XFR_OFLW is identical to QHSTA_M_DATA_OVER_RUN. */
27c868c2
MW
3301#define QHSTA_M_SXFR_XFR_OFLW 0x12 /* SXFR_STATUS Transfer Overflow */
3302#define QHSTA_M_SXFR_XFR_PH_ERR 0x24 /* SXFR_STATUS Transfer Phase Error */
3303#define QHSTA_M_SXFR_UNKNOWN_ERROR 0x25 /* SXFR_STATUS Unknown Error */
3304#define QHSTA_M_SCSI_BUS_RESET 0x30 /* Request aborted from SBR */
3305#define QHSTA_M_SCSI_BUS_RESET_UNSOL 0x31 /* Request aborted from unsol. SBR */
3306#define QHSTA_M_BUS_DEVICE_RESET 0x32 /* Request aborted from BDR */
3307#define QHSTA_M_DIRECTION_ERR 0x35 /* Data Phase mismatch */
3308#define QHSTA_M_DIRECTION_ERR_HUNG 0x36 /* Data Phase mismatch and bus hang */
1da177e4
LT
3309#define QHSTA_M_WTM_TIMEOUT 0x41
3310#define QHSTA_M_BAD_CMPL_STATUS_IN 0x42
3311#define QHSTA_M_NO_AUTO_REQ_SENSE 0x43
3312#define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
27c868c2
MW
3313#define QHSTA_M_INVALID_DEVICE 0x45 /* Bad target ID */
3314#define QHSTA_M_FROZEN_TIDQ 0x46 /* TID Queue frozen. */
3315#define QHSTA_M_SGBACKUP_ERROR 0x47 /* Scatter-Gather backup error */
1da177e4
LT
3316
3317/*
3318 * Default EEPROM Configuration structure defined in a_init.c.
3319 */
3320static ADVEEP_3550_CONFIG Default_3550_EEPROM_Config;
3321static ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config;
3322static ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config;
3323
3324/*
3325 * DvcGetPhyAddr() flag arguments
3326 */
27c868c2
MW
3327#define ADV_IS_SCSIQ_FLAG 0x01 /* 'addr' is ASC_SCSI_REQ_Q pointer */
3328#define ADV_ASCGETSGLIST_VADDR 0x02 /* 'addr' is AscGetSGList() virtual addr */
3329#define ADV_IS_SENSE_FLAG 0x04 /* 'addr' is sense virtual pointer */
3330#define ADV_IS_DATA_FLAG 0x08 /* 'addr' is data virtual pointer */
3331#define ADV_IS_SGLIST_FLAG 0x10 /* 'addr' is sglist virtual pointer */
3332#define ADV_IS_CARRIER_FLAG 0x20 /* 'addr' is ADV_CARR_T pointer */
1da177e4
LT
3333
3334/* Return the address that is aligned at the next doubleword >= to 'addr'. */
3335#define ADV_8BALIGN(addr) (((ulong) (addr) + 0x7) & ~0x7)
3336#define ADV_16BALIGN(addr) (((ulong) (addr) + 0xF) & ~0xF)
3337#define ADV_32BALIGN(addr) (((ulong) (addr) + 0x1F) & ~0x1F)
3338
3339/*
3340 * Total contiguous memory needed for driver SG blocks.
3341 *
3342 * ADV_MAX_SG_LIST must be defined by a driver. It is the maximum
3343 * number of scatter-gather elements the driver supports in a
3344 * single request.
3345 */
3346
3347#define ADV_SG_LIST_MAX_BYTE_SIZE \
3348 (sizeof(ADV_SG_BLOCK) * \
3349 ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK))
3350
3351/*
3352 * Inquiry data structure and bitfield macros
3353 *
3354 * Using bitfields to access the subchar data isn't portable across
3355 * endianness, so instead mask and shift. Only quantities of more
3356 * than 1 bit are shifted, since the others are just tested for true
3357 * or false.
3358 */
3359
3360#define ADV_INQ_DVC_TYPE(inq) ((inq)->periph & 0x1f)
3361#define ADV_INQ_QUALIFIER(inq) (((inq)->periph & 0xe0) >> 5)
3362#define ADV_INQ_DVC_TYPE_MOD(inq) ((inq)->devtype & 0x7f)
3363#define ADV_INQ_REMOVABLE(inq) ((inq)->devtype & 0x80)
3364#define ADV_INQ_ANSI_VER(inq) ((inq)->ver & 0x07)
3365#define ADV_INQ_ECMA_VER(inq) (((inq)->ver & 0x38) >> 3)
3366#define ADV_INQ_ISO_VER(inq) (((inq)->ver & 0xc0) >> 6)
3367#define ADV_INQ_RESPONSE_FMT(inq) ((inq)->byte3 & 0x0f)
3368#define ADV_INQ_TERM_IO(inq) ((inq)->byte3 & 0x40)
3369#define ADV_INQ_ASYNC_NOTIF(inq) ((inq)->byte3 & 0x80)
3370#define ADV_INQ_SOFT_RESET(inq) ((inq)->flags & 0x01)
3371#define ADV_INQ_CMD_QUEUE(inq) ((inq)->flags & 0x02)
3372#define ADV_INQ_LINK_CMD(inq) ((inq)->flags & 0x08)
3373#define ADV_INQ_SYNC(inq) ((inq)->flags & 0x10)
3374#define ADV_INQ_WIDE16(inq) ((inq)->flags & 0x20)
3375#define ADV_INQ_WIDE32(inq) ((inq)->flags & 0x40)
3376#define ADV_INQ_REL_ADDR(inq) ((inq)->flags & 0x80)
3377#define ADV_INQ_INFO_UNIT(inq) ((inq)->info & 0x01)
3378#define ADV_INQ_QUICK_ARB(inq) ((inq)->info & 0x02)
3379#define ADV_INQ_CLOCKING(inq) (((inq)->info & 0x0c) >> 2)
3380
3381typedef struct {
27c868c2
MW
3382 uchar periph; /* peripheral device type [0:4] */
3383 /* peripheral qualifier [5:7] */
3384 uchar devtype; /* device type modifier (for SCSI I) [0:6] */
3385 /* RMB - removable medium bit [7] */
3386 uchar ver; /* ANSI approved version [0:2] */
3387 /* ECMA version [3:5] */
3388 /* ISO version [6:7] */
3389 uchar byte3; /* response data format [0:3] */
3390 /* 0 SCSI 1 */
3391 /* 1 CCS */
3392 /* 2 SCSI-2 */
3393 /* 3-F reserved */
3394 /* reserved [4:5] */
3395 /* terminate I/O process bit (see 5.6.22) [6] */
3396 /* asynch. event notification (processor) [7] */
3397 uchar add_len; /* additional length */
3398 uchar res1; /* reserved */
3399 uchar res2; /* reserved */
3400 uchar flags; /* soft reset implemented [0] */
3401 /* command queuing [1] */
3402 /* reserved [2] */
3403 /* linked command for this logical unit [3] */
3404 /* synchronous data transfer [4] */
3405 /* wide bus 16 bit data transfer [5] */
3406 /* wide bus 32 bit data transfer [6] */
3407 /* relative addressing mode [7] */
3408 uchar vendor_id[8]; /* vendor identification */
3409 uchar product_id[16]; /* product identification */
3410 uchar product_rev_level[4]; /* product revision level */
3411 uchar vendor_specific[20]; /* vendor specific */
3412 uchar info; /* information unit supported [0] */
3413 /* quick arbitrate supported [1] */
3414 /* clocking field [2:3] */
3415 /* reserved [4:7] */
3416 uchar res3; /* reserved */
3417} ADV_SCSI_INQUIRY; /* 58 bytes */
1da177e4
LT
3418
3419/*
3420 * --- Driver Constants and Macros
3421 */
3422
3423#define ASC_NUM_BOARD_SUPPORTED 16
3424#define ASC_NUM_IOPORT_PROBE 4
3425#define ASC_NUM_BUS 4
3426
3427/* Reference Scsi_Host hostdata */
3428#define ASC_BOARDP(host) ((asc_board_t *) &((host)->hostdata))
3429
3430/* asc_board_t flags */
3431#define ASC_HOST_IN_RESET 0x01
27c868c2 3432#define ASC_IS_WIDE_BOARD 0x04 /* AdvanSys Wide Board */
1da177e4
LT
3433#define ASC_SELECT_QUEUE_DEPTHS 0x08
3434
3435#define ASC_NARROW_BOARD(boardp) (((boardp)->flags & ASC_IS_WIDE_BOARD) == 0)
3436#define ASC_WIDE_BOARD(boardp) ((boardp)->flags & ASC_IS_WIDE_BOARD)
3437
27c868c2 3438#define NO_ISA_DMA 0xff /* No ISA DMA Channel Used */
1da177e4 3439
27c868c2 3440#define ASC_INFO_SIZE 128 /* advansys_info() line size */
1da177e4
LT
3441
3442#ifdef CONFIG_PROC_FS
3443/* /proc/scsi/advansys/[0...] related definitions */
3444#define ASC_PRTBUF_SIZE 2048
3445#define ASC_PRTLINE_SIZE 160
3446
3447#define ASC_PRT_NEXT() \
3448 if (cp) { \
3449 totlen += len; \
3450 leftlen -= len; \
3451 if (leftlen == 0) { \
3452 return totlen; \
3453 } \
3454 cp += len; \
3455 }
3456#endif /* CONFIG_PROC_FS */
3457
3458/* Asc Library return codes */
3459#define ASC_TRUE 1
3460#define ASC_FALSE 0
3461#define ASC_NOERROR 1
3462#define ASC_BUSY 0
3463#define ASC_ERROR (-1)
3464
3465/* struct scsi_cmnd function return codes */
3466#define STATUS_BYTE(byte) (byte)
3467#define MSG_BYTE(byte) ((byte) << 8)
3468#define HOST_BYTE(byte) ((byte) << 16)
3469#define DRIVER_BYTE(byte) ((byte) << 24)
3470
3471/*
3472 * The following definitions and macros are OS independent interfaces to
3473 * the queue functions:
3474 * REQ - SCSI request structure
3475 * REQP - pointer to SCSI request structure
3476 * REQPTID(reqp) - reqp's target id
3477 * REQPNEXT(reqp) - reqp's next pointer
3478 * REQPNEXTP(reqp) - pointer to reqp's next pointer
3479 * REQPTIME(reqp) - reqp's time stamp value
3480 * REQTIMESTAMP() - system time stamp value
3481 */
27c868c2 3482typedef struct scsi_cmnd REQ, *REQP;
1da177e4
LT
3483#define REQPNEXT(reqp) ((REQP) ((reqp)->host_scribble))
3484#define REQPNEXTP(reqp) ((REQP *) &((reqp)->host_scribble))
3485#define REQPTID(reqp) ((reqp)->device->id)
3486#define REQPTIME(reqp) ((reqp)->SCp.this_residual)
3487#define REQTIMESTAMP() (jiffies)
3488
3489#define REQTIMESTAT(function, ascq, reqp, tid) \
3490{ \
3491 /*
3492 * If the request time stamp is less than the system time stamp, then \
3493 * maybe the system time stamp wrapped. Set the request time to zero.\
3494 */ \
3495 if (REQPTIME(reqp) <= REQTIMESTAMP()) { \
3496 REQPTIME(reqp) = REQTIMESTAMP() - REQPTIME(reqp); \
3497 } else { \
3498 /* Indicate an error occurred with the assertion. */ \
3499 ASC_ASSERT(REQPTIME(reqp) <= REQTIMESTAMP()); \
3500 REQPTIME(reqp) = 0; \
3501 } \
3502 /* Handle first minimum time case without external initialization. */ \
3503 if (((ascq)->q_tot_cnt[tid] == 1) || \
3504 (REQPTIME(reqp) < (ascq)->q_min_tim[tid])) { \
3505 (ascq)->q_min_tim[tid] = REQPTIME(reqp); \
3506 ASC_DBG3(1, "%s: new q_min_tim[%d] %u\n", \
3507 (function), (tid), (ascq)->q_min_tim[tid]); \
3508 } \
3509 if (REQPTIME(reqp) > (ascq)->q_max_tim[tid]) { \
3510 (ascq)->q_max_tim[tid] = REQPTIME(reqp); \
3511 ASC_DBG3(1, "%s: new q_max_tim[%d] %u\n", \
3512 (function), tid, (ascq)->q_max_tim[tid]); \
3513 } \
3514 (ascq)->q_tot_tim[tid] += REQPTIME(reqp); \
3515 /* Reset the time stamp field. */ \
3516 REQPTIME(reqp) = 0; \
3517}
3518
3519/* asc_enqueue() flags */
3520#define ASC_FRONT 1
3521#define ASC_BACK 2
3522
3523/* asc_dequeue_list() argument */
3524#define ASC_TID_ALL (-1)
3525
3526/* Return non-zero, if the queue is empty. */
3527#define ASC_QUEUE_EMPTY(ascq) ((ascq)->q_tidmask == 0)
3528
3529#define PCI_MAX_SLOT 0x1F
3530#define PCI_MAX_BUS 0xFF
3531#define PCI_IOADDRESS_MASK 0xFFFE
27c868c2 3532#define ASC_PCI_DEVICE_ID_CNT 6 /* PCI Device ID count. */
1da177e4
LT
3533
3534#ifndef ADVANSYS_STATS
27c868c2
MW
3535#define ASC_STATS(shost, counter)
3536#define ASC_STATS_ADD(shost, counter, count)
1da177e4 3537#else /* ADVANSYS_STATS */
27c868c2
MW
3538#define ASC_STATS(shost, counter) \
3539 (ASC_BOARDP(shost)->asc_stats.counter++)
1da177e4 3540
27c868c2
MW
3541#define ASC_STATS_ADD(shost, counter, count) \
3542 (ASC_BOARDP(shost)->asc_stats.counter += (count))
1da177e4
LT
3543#endif /* ADVANSYS_STATS */
3544
3545#define ASC_CEILING(val, unit) (((val) + ((unit) - 1))/(unit))
3546
3547/* If the result wraps when calculating tenths, return 0. */
3548#define ASC_TENTHS(num, den) \
3549 (((10 * ((num)/(den))) > (((num) * 10)/(den))) ? \
3550 0 : ((((num) * 10)/(den)) - (10 * ((num)/(den)))))
3551
3552/*
3553 * Display a message to the console.
3554 */
3555#define ASC_PRINT(s) \
3556 { \
3557 printk("advansys: "); \
3558 printk(s); \
3559 }
3560
3561#define ASC_PRINT1(s, a1) \
3562 { \
3563 printk("advansys: "); \
3564 printk((s), (a1)); \
3565 }
3566
3567#define ASC_PRINT2(s, a1, a2) \
3568 { \
3569 printk("advansys: "); \
3570 printk((s), (a1), (a2)); \
3571 }
3572
3573#define ASC_PRINT3(s, a1, a2, a3) \
3574 { \
3575 printk("advansys: "); \
3576 printk((s), (a1), (a2), (a3)); \
3577 }
3578
3579#define ASC_PRINT4(s, a1, a2, a3, a4) \
3580 { \
3581 printk("advansys: "); \
3582 printk((s), (a1), (a2), (a3), (a4)); \
3583 }
3584
1da177e4
LT
3585#ifndef ADVANSYS_DEBUG
3586
3587#define ASC_DBG(lvl, s)
3588#define ASC_DBG1(lvl, s, a1)
3589#define ASC_DBG2(lvl, s, a1, a2)
3590#define ASC_DBG3(lvl, s, a1, a2, a3)
3591#define ASC_DBG4(lvl, s, a1, a2, a3, a4)
3592#define ASC_DBG_PRT_SCSI_HOST(lvl, s)
3593#define ASC_DBG_PRT_SCSI_CMND(lvl, s)
3594#define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp)
3595#define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
3596#define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone)
3597#define ADV_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
3598#define ASC_DBG_PRT_HEX(lvl, name, start, length)
3599#define ASC_DBG_PRT_CDB(lvl, cdb, len)
3600#define ASC_DBG_PRT_SENSE(lvl, sense, len)
3601#define ASC_DBG_PRT_INQUIRY(lvl, inq, len)
3602
3603#else /* ADVANSYS_DEBUG */
3604
3605/*
3606 * Debugging Message Levels:
3607 * 0: Errors Only
3608 * 1: High-Level Tracing
3609 * 2-N: Verbose Tracing
3610 */
3611
3612#define ASC_DBG(lvl, s) \
3613 { \
3614 if (asc_dbglvl >= (lvl)) { \
3615 printk(s); \
3616 } \
3617 }
3618
3619#define ASC_DBG1(lvl, s, a1) \
3620 { \
3621 if (asc_dbglvl >= (lvl)) { \
3622 printk((s), (a1)); \
3623 } \
3624 }
3625
3626#define ASC_DBG2(lvl, s, a1, a2) \
3627 { \
3628 if (asc_dbglvl >= (lvl)) { \
3629 printk((s), (a1), (a2)); \
3630 } \
3631 }
3632
3633#define ASC_DBG3(lvl, s, a1, a2, a3) \
3634 { \
3635 if (asc_dbglvl >= (lvl)) { \
3636 printk((s), (a1), (a2), (a3)); \
3637 } \
3638 }
3639
3640#define ASC_DBG4(lvl, s, a1, a2, a3, a4) \
3641 { \
3642 if (asc_dbglvl >= (lvl)) { \
3643 printk((s), (a1), (a2), (a3), (a4)); \
3644 } \
3645 }
3646
3647#define ASC_DBG_PRT_SCSI_HOST(lvl, s) \
3648 { \
3649 if (asc_dbglvl >= (lvl)) { \
3650 asc_prt_scsi_host(s); \
3651 } \
3652 }
3653
3654#define ASC_DBG_PRT_SCSI_CMND(lvl, s) \
3655 { \
3656 if (asc_dbglvl >= (lvl)) { \
3657 asc_prt_scsi_cmnd(s); \
3658 } \
3659 }
3660
3661#define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp) \
3662 { \
3663 if (asc_dbglvl >= (lvl)) { \
3664 asc_prt_asc_scsi_q(scsiqp); \
3665 } \
3666 }
3667
3668#define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone) \
3669 { \
3670 if (asc_dbglvl >= (lvl)) { \
3671 asc_prt_asc_qdone_info(qdone); \
3672 } \
3673 }
3674
3675#define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp) \
3676 { \
3677 if (asc_dbglvl >= (lvl)) { \
3678 asc_prt_adv_scsi_req_q(scsiqp); \
3679 } \
3680 }
3681
3682#define ASC_DBG_PRT_HEX(lvl, name, start, length) \
3683 { \
3684 if (asc_dbglvl >= (lvl)) { \
3685 asc_prt_hex((name), (start), (length)); \
3686 } \
3687 }
3688
3689#define ASC_DBG_PRT_CDB(lvl, cdb, len) \
3690 ASC_DBG_PRT_HEX((lvl), "CDB", (uchar *) (cdb), (len));
3691
3692#define ASC_DBG_PRT_SENSE(lvl, sense, len) \
3693 ASC_DBG_PRT_HEX((lvl), "SENSE", (uchar *) (sense), (len));
3694
3695#define ASC_DBG_PRT_INQUIRY(lvl, inq, len) \
3696 ASC_DBG_PRT_HEX((lvl), "INQUIRY", (uchar *) (inq), (len));
3697#endif /* ADVANSYS_DEBUG */
3698
3699#ifndef ADVANSYS_ASSERT
3700#define ASC_ASSERT(a)
3701#else /* ADVANSYS_ASSERT */
3702
3703#define ASC_ASSERT(a) \
3704 { \
3705 if (!(a)) { \
3706 printk("ASC_ASSERT() Failure: file %s, line %d\n", \
3707 __FILE__, __LINE__); \
3708 } \
3709 }
3710
3711#endif /* ADVANSYS_ASSERT */
3712
1da177e4
LT
3713/*
3714 * --- Driver Structures
3715 */
3716
3717#ifdef ADVANSYS_STATS
3718
3719/* Per board statistics structure */
3720struct asc_stats {
27c868c2
MW
3721 /* Driver Entrypoint Statistics */
3722 ADV_DCNT queuecommand; /* # calls to advansys_queuecommand() */
3723 ADV_DCNT reset; /* # calls to advansys_eh_bus_reset() */
3724 ADV_DCNT biosparam; /* # calls to advansys_biosparam() */
3725 ADV_DCNT interrupt; /* # advansys_interrupt() calls */
3726 ADV_DCNT callback; /* # calls to asc/adv_isr_callback() */
3727 ADV_DCNT done; /* # calls to request's scsi_done function */
3728 ADV_DCNT build_error; /* # asc/adv_build_req() ASC_ERROR returns. */
3729 ADV_DCNT adv_build_noreq; /* # adv_build_req() adv_req_t alloc. fail. */
3730 ADV_DCNT adv_build_nosg; /* # adv_build_req() adv_sgblk_t alloc. fail. */
3731 /* AscExeScsiQueue()/AdvExeScsiQueue() Statistics */
3732 ADV_DCNT exe_noerror; /* # ASC_NOERROR returns. */
3733 ADV_DCNT exe_busy; /* # ASC_BUSY returns. */
3734 ADV_DCNT exe_error; /* # ASC_ERROR returns. */
3735 ADV_DCNT exe_unknown; /* # unknown returns. */
3736 /* Data Transfer Statistics */
3737 ADV_DCNT cont_cnt; /* # non-scatter-gather I/O requests received */
3738 ADV_DCNT cont_xfer; /* # contiguous transfer 512-bytes */
3739 ADV_DCNT sg_cnt; /* # scatter-gather I/O requests received */
3740 ADV_DCNT sg_elem; /* # scatter-gather elements */
3741 ADV_DCNT sg_xfer; /* # scatter-gather transfer 512-bytes */
1da177e4
LT
3742};
3743#endif /* ADVANSYS_STATS */
3744
3745/*
3746 * Request queuing structure
3747 */
3748typedef struct asc_queue {
27c868c2
MW
3749 ADV_SCSI_BIT_ID_TYPE q_tidmask; /* queue mask */
3750 REQP q_first[ADV_MAX_TID + 1]; /* first queued request */
3751 REQP q_last[ADV_MAX_TID + 1]; /* last queued request */
1da177e4 3752#ifdef ADVANSYS_STATS
27c868c2
MW
3753 short q_cur_cnt[ADV_MAX_TID + 1]; /* current queue count */
3754 short q_max_cnt[ADV_MAX_TID + 1]; /* maximum queue count */
3755 ADV_DCNT q_tot_cnt[ADV_MAX_TID + 1]; /* total enqueue count */
3756 ADV_DCNT q_tot_tim[ADV_MAX_TID + 1]; /* total time queued */
3757 ushort q_max_tim[ADV_MAX_TID + 1]; /* maximum time queued */
3758 ushort q_min_tim[ADV_MAX_TID + 1]; /* minimum time queued */
3759#endif /* ADVANSYS_STATS */
1da177e4
LT
3760} asc_queue_t;
3761
3762/*
3763 * Adv Library Request Structures
3764 *
3765 * The following two structures are used to process Wide Board requests.
3766 *
3767 * The ADV_SCSI_REQ_Q structure in adv_req_t is passed to the Adv Library
3768 * and microcode with the ADV_SCSI_REQ_Q field 'srb_ptr' pointing to the
3769 * adv_req_t. The adv_req_t structure 'cmndp' field in turn points to the
3770 * Mid-Level SCSI request structure.
3771 *
3772 * Zero or more ADV_SG_BLOCK are used with each ADV_SCSI_REQ_Q. Each
3773 * ADV_SG_BLOCK structure holds 15 scatter-gather elements. Under Linux
3774 * up to 255 scatter-gather elements may be used per request or
3775 * ADV_SCSI_REQ_Q.
3776 *
3777 * Both structures must be 32 byte aligned.
3778 */
3779typedef struct adv_sgblk {
27c868c2
MW
3780 ADV_SG_BLOCK sg_block; /* Sgblock structure. */
3781 uchar align[32]; /* Sgblock structure padding. */
3782 struct adv_sgblk *next_sgblkp; /* Next scatter-gather structure. */
1da177e4
LT
3783} adv_sgblk_t;
3784
3785typedef struct adv_req {
27c868c2
MW
3786 ADV_SCSI_REQ_Q scsi_req_q; /* Adv Library request structure. */
3787 uchar align[32]; /* Request structure padding. */
3788 struct scsi_cmnd *cmndp; /* Mid-Level SCSI command pointer. */
3789 adv_sgblk_t *sgblkp; /* Adv Library scatter-gather pointer. */
3790 struct adv_req *next_reqp; /* Next Request Structure. */
1da177e4
LT
3791} adv_req_t;
3792
3793/*
3794 * Structure allocated for each board.
3795 *
3796 * This structure is allocated by scsi_register() at the end
3797 * of the 'Scsi_Host' structure starting at the 'hostdata'
3798 * field. It is guaranteed to be allocated from DMA-able memory.
3799 */
3800typedef struct asc_board {
27c868c2
MW
3801 int id; /* Board Id */
3802 uint flags; /* Board flags */
3803 union {
3804 ASC_DVC_VAR asc_dvc_var; /* Narrow board */
3805 ADV_DVC_VAR adv_dvc_var; /* Wide board */
3806 } dvc_var;
3807 union {
3808 ASC_DVC_CFG asc_dvc_cfg; /* Narrow board */
3809 ADV_DVC_CFG adv_dvc_cfg; /* Wide board */
3810 } dvc_cfg;
3811 ushort asc_n_io_port; /* Number I/O ports. */
3812 asc_queue_t active; /* Active command queue */
3813 asc_queue_t waiting; /* Waiting command queue */
3814 asc_queue_t done; /* Done command queue */
3815 ADV_SCSI_BIT_ID_TYPE init_tidmask; /* Target init./valid mask */
3816 struct scsi_device *device[ADV_MAX_TID + 1]; /* Mid-Level Scsi Device */
3817 ushort reqcnt[ADV_MAX_TID + 1]; /* Starvation request count */
3818 ADV_SCSI_BIT_ID_TYPE queue_full; /* Queue full mask */
3819 ushort queue_full_cnt[ADV_MAX_TID + 1]; /* Queue full count */
3820 union {
3821 ASCEEP_CONFIG asc_eep; /* Narrow EEPROM config. */
3822 ADVEEP_3550_CONFIG adv_3550_eep; /* 3550 EEPROM config. */
3823 ADVEEP_38C0800_CONFIG adv_38C0800_eep; /* 38C0800 EEPROM config. */
3824 ADVEEP_38C1600_CONFIG adv_38C1600_eep; /* 38C1600 EEPROM config. */
3825 } eep_config;
3826 ulong last_reset; /* Saved last reset time */
3827 spinlock_t lock; /* Board spinlock */
1da177e4 3828#ifdef CONFIG_PROC_FS
27c868c2
MW
3829 /* /proc/scsi/advansys/[0...] */
3830 char *prtbuf; /* /proc print buffer */
3831#endif /* CONFIG_PROC_FS */
1da177e4 3832#ifdef ADVANSYS_STATS
27c868c2
MW
3833 struct asc_stats asc_stats; /* Board statistics */
3834#endif /* ADVANSYS_STATS */
3835 /*
3836 * The following fields are used only for Narrow Boards.
3837 */
3838 /* The following three structures must be in DMA-able memory. */
3839 ASC_SCSI_REQ_Q scsireqq;
3840 ASC_CAP_INFO cap_info;
3841 ASC_SCSI_INQUIRY inquiry;
3842 uchar sdtr_data[ASC_MAX_TID + 1]; /* SDTR information */
3843 /*
3844 * The following fields are used only for Wide Boards.
3845 */
3846 void __iomem *ioremap_addr; /* I/O Memory remap address. */
3847 ushort ioport; /* I/O Port address. */
3848 ADV_CARR_T *orig_carrp; /* ADV_CARR_T memory block. */
3849 adv_req_t *orig_reqp; /* adv_req_t memory block. */
3850 adv_req_t *adv_reqp; /* Request structures. */
3851 adv_sgblk_t *adv_sgblkp; /* Scatter-gather structures. */
3852 ushort bios_signature; /* BIOS Signature. */
3853 ushort bios_version; /* BIOS Version. */
3854 ushort bios_codeseg; /* BIOS Code Segment. */
3855 ushort bios_codelen; /* BIOS Code Segment Length. */
1da177e4
LT
3856} asc_board_t;
3857
3858/*
3859 * PCI configuration structures
3860 */
27c868c2
MW
3861typedef struct _PCI_DATA_ {
3862 uchar type;
3863 uchar bus;
3864 uchar slot;
3865 uchar func;
3866 uchar offset;
1da177e4
LT
3867} PCI_DATA;
3868
27c868c2
MW
3869typedef struct _PCI_DEVICE_ {
3870 ushort vendorID;
3871 ushort deviceID;
3872 ushort slotNumber;
3873 ushort slotFound;
3874 uchar busNumber;
3875 uchar maxBusNumber;
3876 uchar devFunc;
3877 ushort startSlot;
3878 ushort endSlot;
3879 uchar bridge;
3880 uchar type;
1da177e4
LT
3881} PCI_DEVICE;
3882
27c868c2
MW
3883typedef struct _PCI_CONFIG_SPACE_ {
3884 ushort vendorID;
3885 ushort deviceID;
3886 ushort command;
3887 ushort status;
3888 uchar revision;
3889 uchar classCode[3];
3890 uchar cacheSize;
3891 uchar latencyTimer;
3892 uchar headerType;
3893 uchar bist;
3894 ADV_PADDR baseAddress[6];
3895 ushort reserved[4];
3896 ADV_PADDR optionRomAddr;
3897 ushort reserved2[4];
3898 uchar irqLine;
3899 uchar irqPin;
3900 uchar minGnt;
3901 uchar maxLatency;
1da177e4
LT
3902} PCI_CONFIG_SPACE;
3903
1da177e4
LT
3904/*
3905 * --- Driver Data
3906 */
3907
3908/* Note: All driver global data should be initialized. */
3909
3910/* Number of boards detected in system. */
27c868c2
MW
3911static int asc_board_count = 0;
3912static struct Scsi_Host *asc_host[ASC_NUM_BOARD_SUPPORTED] = { NULL };
1da177e4
LT
3913
3914/* Overrun buffer used by all narrow boards. */
27c868c2 3915static uchar overrun_buf[ASC_OVERRUN_BSIZE] = { 0 };
1da177e4
LT
3916
3917/*
3918 * Global structures required to issue a command.
3919 */
27c868c2
MW
3920static ASC_SCSI_Q asc_scsi_q = { {0} };
3921static ASC_SG_HEAD asc_sg_head = { 0 };
1da177e4
LT
3922
3923/* List of supported bus types. */
27c868c2
MW
3924static ushort asc_bus[ASC_NUM_BUS] __initdata = {
3925 ASC_IS_ISA,
3926 ASC_IS_VL,
3927 ASC_IS_EISA,
3928 ASC_IS_PCI,
1da177e4
LT
3929};
3930
27c868c2
MW
3931static int asc_iopflag = ASC_FALSE;
3932static int asc_ioport[ASC_NUM_IOPORT_PROBE] = { 0, 0, 0, 0 };
1da177e4
LT
3933
3934#ifdef ADVANSYS_DEBUG
27c868c2
MW
3935static char *asc_bus_name[ASC_NUM_BUS] = {
3936 "ASC_IS_ISA",
3937 "ASC_IS_VL",
3938 "ASC_IS_EISA",
3939 "ASC_IS_PCI",
1da177e4
LT
3940};
3941
27c868c2 3942static int asc_dbglvl = 3;
1da177e4
LT
3943#endif /* ADVANSYS_DEBUG */
3944
3945/* Declaration for Asc Library internal data referenced by driver. */
27c868c2 3946static PortAddr _asc_def_iop_base[];
1da177e4
LT
3947
3948/*
3949 * --- Driver Function Prototypes
3950 *
3951 * advansys.h contains function prototypes for functions global to Linux.
3952 */
3953
27c868c2
MW
3954static int advansys_slave_configure(struct scsi_device *);
3955static void asc_scsi_done_list(struct scsi_cmnd *);
3956static int asc_execute_scsi_cmnd(struct scsi_cmnd *);
3957static int asc_build_req(asc_board_t *, struct scsi_cmnd *);
3958static int adv_build_req(asc_board_t *, struct scsi_cmnd *, ADV_SCSI_REQ_Q **);
3959static int adv_get_sglist(asc_board_t *, adv_req_t *, struct scsi_cmnd *, int);
3960static void asc_isr_callback(ASC_DVC_VAR *, ASC_QDONE_INFO *);
3961static void adv_isr_callback(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
3962static void adv_async_callback(ADV_DVC_VAR *, uchar);
3963static void asc_enqueue(asc_queue_t *, REQP, int);
3964static REQP asc_dequeue(asc_queue_t *, int);
3965static REQP asc_dequeue_list(asc_queue_t *, REQP *, int);
3966static int asc_rmqueue(asc_queue_t *, REQP);
3967static void asc_execute_queue(asc_queue_t *);
1da177e4 3968#ifdef CONFIG_PROC_FS
27c868c2
MW
3969static int asc_proc_copy(off_t, off_t, char *, int, char *, int);
3970static int asc_prt_board_devices(struct Scsi_Host *, char *, int);
3971static int asc_prt_adv_bios(struct Scsi_Host *, char *, int);
3972static int asc_get_eeprom_string(ushort *serialnum, uchar *cp);
3973static int asc_prt_asc_board_eeprom(struct Scsi_Host *, char *, int);
3974static int asc_prt_adv_board_eeprom(struct Scsi_Host *, char *, int);
3975static int asc_prt_driver_conf(struct Scsi_Host *, char *, int);
3976static int asc_prt_asc_board_info(struct Scsi_Host *, char *, int);
3977static int asc_prt_adv_board_info(struct Scsi_Host *, char *, int);
3978static int asc_prt_line(char *, int, char *fmt, ...);
1da177e4
LT
3979#endif /* CONFIG_PROC_FS */
3980
3981/* Declaration for Asc Library internal functions referenced by driver. */
27c868c2
MW
3982static int AscFindSignature(PortAddr);
3983static ushort AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
1da177e4
LT
3984
3985/* Statistics function prototypes. */
3986#ifdef ADVANSYS_STATS
3987#ifdef CONFIG_PROC_FS
27c868c2
MW
3988static int asc_prt_board_stats(struct Scsi_Host *, char *, int);
3989static int asc_prt_target_stats(struct Scsi_Host *, int, char *, int);
1da177e4
LT
3990#endif /* CONFIG_PROC_FS */
3991#endif /* ADVANSYS_STATS */
3992
3993/* Debug function prototypes. */
3994#ifdef ADVANSYS_DEBUG
27c868c2
MW
3995static void asc_prt_scsi_host(struct Scsi_Host *);
3996static void asc_prt_scsi_cmnd(struct scsi_cmnd *);
3997static void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *);
3998static void asc_prt_asc_dvc_var(ASC_DVC_VAR *);
3999static void asc_prt_asc_scsi_q(ASC_SCSI_Q *);
4000static void asc_prt_asc_qdone_info(ASC_QDONE_INFO *);
4001static void asc_prt_adv_dvc_cfg(ADV_DVC_CFG *);
4002static void asc_prt_adv_dvc_var(ADV_DVC_VAR *);
4003static void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *);
4004static void asc_prt_adv_sgblock(int, ADV_SG_BLOCK *);
4005static void asc_prt_hex(char *f, uchar *, int);
1da177e4
LT
4006#endif /* ADVANSYS_DEBUG */
4007
1da177e4
LT
4008#ifdef CONFIG_PROC_FS
4009/*
4010 * advansys_proc_info() - /proc/scsi/advansys/[0-(ASC_NUM_BOARD_SUPPORTED-1)]
4011 *
4012 * *buffer: I/O buffer
4013 * **start: if inout == FALSE pointer into buffer where user read should start
4014 * offset: current offset into a /proc/scsi/advansys/[0...] file
4015 * length: length of buffer
4016 * hostno: Scsi_Host host_no
4017 * inout: TRUE - user is writing; FALSE - user is reading
4018 *
4019 * Return the number of bytes read from or written to a
4020 * /proc/scsi/advansys/[0...] file.
4021 *
4022 * Note: This function uses the per board buffer 'prtbuf' which is
4023 * allocated when the board is initialized in advansys_detect(). The
4024 * buffer is ASC_PRTBUF_SIZE bytes. The function asc_proc_copy() is
4025 * used to write to the buffer. The way asc_proc_copy() is written
4026 * if 'prtbuf' is too small it will not be overwritten. Instead the
4027 * user just won't get all the available statistics.
4028 */
70c8d897 4029static int
1da177e4 4030advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
27c868c2 4031 off_t offset, int length, int inout)
1da177e4 4032{
27c868c2 4033 asc_board_t *boardp;
27c868c2
MW
4034 char *cp;
4035 int cplen;
4036 int cnt;
4037 int totcnt;
4038 int leftlen;
4039 char *curbuf;
4040 off_t advoffset;
1da177e4 4041#ifdef ADVANSYS_STATS
27c868c2 4042 int tgt_id;
1da177e4
LT
4043#endif /* ADVANSYS_STATS */
4044
27c868c2 4045 ASC_DBG(1, "advansys_proc_info: begin\n");
1da177e4 4046
27c868c2
MW
4047 /*
4048 * User write not supported.
4049 */
4050 if (inout == TRUE) {
4051 return (-ENOSYS);
4052 }
1da177e4 4053
27c868c2
MW
4054 /*
4055 * User read of /proc/scsi/advansys/[0...] file.
4056 */
1da177e4 4057
2a437959 4058 boardp = ASC_BOARDP(shost);
27c868c2
MW
4059
4060 /* Copy read data starting at the beginning of the buffer. */
4061 *start = buffer;
4062 curbuf = buffer;
4063 advoffset = 0;
4064 totcnt = 0;
4065 leftlen = length;
4066
4067 /*
4068 * Get board configuration information.
4069 *
4070 * advansys_info() returns the board string from its own static buffer.
4071 */
2a437959 4072 cp = (char *)advansys_info(shost);
27c868c2
MW
4073 strcat(cp, "\n");
4074 cplen = strlen(cp);
4075 /* Copy board information. */
4076 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4077 totcnt += cnt;
4078 leftlen -= cnt;
4079 if (leftlen == 0) {
4080 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4081 return totcnt;
4082 }
4083 advoffset += cplen;
4084 curbuf += cnt;
4085
4086 /*
4087 * Display Wide Board BIOS Information.
4088 */
4089 if (ASC_WIDE_BOARD(boardp)) {
4090 cp = boardp->prtbuf;
2a437959 4091 cplen = asc_prt_adv_bios(shost, cp, ASC_PRTBUF_SIZE);
27c868c2
MW
4092 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4093 cnt =
4094 asc_proc_copy(advoffset, offset, curbuf, leftlen, cp,
4095 cplen);
4096 totcnt += cnt;
4097 leftlen -= cnt;
4098 if (leftlen == 0) {
4099 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4100 return totcnt;
4101 }
4102 advoffset += cplen;
4103 curbuf += cnt;
4104 }
1da177e4 4105
27c868c2
MW
4106 /*
4107 * Display driver information for each device attached to the board.
4108 */
4109 cp = boardp->prtbuf;
2a437959 4110 cplen = asc_prt_board_devices(shost, cp, ASC_PRTBUF_SIZE);
27c868c2
MW
4111 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4112 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4113 totcnt += cnt;
4114 leftlen -= cnt;
4115 if (leftlen == 0) {
4116 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4117 return totcnt;
4118 }
4119 advoffset += cplen;
4120 curbuf += cnt;
4121
4122 /*
4123 * Display EEPROM configuration for the board.
4124 */
4125 cp = boardp->prtbuf;
4126 if (ASC_NARROW_BOARD(boardp)) {
2a437959 4127 cplen = asc_prt_asc_board_eeprom(shost, cp, ASC_PRTBUF_SIZE);
27c868c2 4128 } else {
2a437959 4129 cplen = asc_prt_adv_board_eeprom(shost, cp, ASC_PRTBUF_SIZE);
27c868c2
MW
4130 }
4131 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4132 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4133 totcnt += cnt;
4134 leftlen -= cnt;
4135 if (leftlen == 0) {
4136 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4137 return totcnt;
4138 }
4139 advoffset += cplen;
4140 curbuf += cnt;
4141
4142 /*
4143 * Display driver configuration and information for the board.
4144 */
4145 cp = boardp->prtbuf;
2a437959 4146 cplen = asc_prt_driver_conf(shost, cp, ASC_PRTBUF_SIZE);
27c868c2
MW
4147 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4148 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4149 totcnt += cnt;
4150 leftlen -= cnt;
4151 if (leftlen == 0) {
4152 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4153 return totcnt;
4154 }
4155 advoffset += cplen;
4156 curbuf += cnt;
1da177e4
LT
4157
4158#ifdef ADVANSYS_STATS
27c868c2
MW
4159 /*
4160 * Display driver statistics for the board.
4161 */
4162 cp = boardp->prtbuf;
2a437959 4163 cplen = asc_prt_board_stats(shost, cp, ASC_PRTBUF_SIZE);
27c868c2
MW
4164 ASC_ASSERT(cplen <= ASC_PRTBUF_SIZE);
4165 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4166 totcnt += cnt;
4167 leftlen -= cnt;
4168 if (leftlen == 0) {
4169 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4170 return totcnt;
4171 }
4172 advoffset += cplen;
4173 curbuf += cnt;
4174
4175 /*
4176 * Display driver statistics for each target.
4177 */
4178 for (tgt_id = 0; tgt_id <= ADV_MAX_TID; tgt_id++) {
4179 cp = boardp->prtbuf;
2a437959
MW
4180 cplen = asc_prt_target_stats(shost, tgt_id, cp,
4181 ASC_PRTBUF_SIZE);
27c868c2
MW
4182 ASC_ASSERT(cplen <= ASC_PRTBUF_SIZE);
4183 cnt =
4184 asc_proc_copy(advoffset, offset, curbuf, leftlen, cp,
4185 cplen);
4186 totcnt += cnt;
4187 leftlen -= cnt;
4188 if (leftlen == 0) {
4189 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4190 return totcnt;
4191 }
4192 advoffset += cplen;
4193 curbuf += cnt;
4194 }
1da177e4
LT
4195#endif /* ADVANSYS_STATS */
4196
27c868c2
MW
4197 /*
4198 * Display Asc Library dynamic configuration information
4199 * for the board.
4200 */
4201 cp = boardp->prtbuf;
4202 if (ASC_NARROW_BOARD(boardp)) {
2a437959 4203 cplen = asc_prt_asc_board_info(shost, cp, ASC_PRTBUF_SIZE);
27c868c2 4204 } else {
2a437959 4205 cplen = asc_prt_adv_board_info(shost, cp, ASC_PRTBUF_SIZE);
27c868c2
MW
4206 }
4207 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4208 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4209 totcnt += cnt;
4210 leftlen -= cnt;
4211 if (leftlen == 0) {
4212 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4213 return totcnt;
4214 }
4215 advoffset += cplen;
4216 curbuf += cnt;
1da177e4 4217
27c868c2 4218 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
1da177e4 4219
27c868c2 4220 return totcnt;
1da177e4 4221}
1da177e4 4222#endif /* CONFIG_PROC_FS */
1da177e4
LT
4223
4224/*
4225 * advansys_info()
4226 *
4227 * Return suitable for printing on the console with the argument
4228 * adapter's configuration information.
4229 *
4230 * Note: The information line should not exceed ASC_INFO_SIZE bytes,
4231 * otherwise the static 'info' array will be overrun.
4232 */
27c868c2 4233static const char *advansys_info(struct Scsi_Host *shost)
1da177e4 4234{
27c868c2
MW
4235 static char info[ASC_INFO_SIZE];
4236 asc_board_t *boardp;
4237 ASC_DVC_VAR *asc_dvc_varp;
4238 ADV_DVC_VAR *adv_dvc_varp;
4239 char *busname;
4240 int iolen;
4241 char *widename = NULL;
4242
4243 boardp = ASC_BOARDP(shost);
4244 if (ASC_NARROW_BOARD(boardp)) {
4245 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
4246 ASC_DBG(1, "advansys_info: begin\n");
4247 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
4248 if ((asc_dvc_varp->bus_type & ASC_IS_ISAPNP) ==
4249 ASC_IS_ISAPNP) {
4250 busname = "ISA PnP";
4251 } else {
4252 busname = "ISA";
4253 }
4254 /* Don't reference 'shost->n_io_port'; It may be truncated. */
4255 sprintf(info,
4256 "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X, DMA 0x%X",
4257 ASC_VERSION, busname,
4258 (ulong)shost->io_port,
4259 (ulong)shost->io_port + boardp->asc_n_io_port -
4260 1, shost->irq, shost->dma_channel);
4261 } else {
4262 if (asc_dvc_varp->bus_type & ASC_IS_VL) {
4263 busname = "VL";
4264 } else if (asc_dvc_varp->bus_type & ASC_IS_EISA) {
4265 busname = "EISA";
4266 } else if (asc_dvc_varp->bus_type & ASC_IS_PCI) {
4267 if ((asc_dvc_varp->bus_type & ASC_IS_PCI_ULTRA)
4268 == ASC_IS_PCI_ULTRA) {
4269 busname = "PCI Ultra";
4270 } else {
4271 busname = "PCI";
4272 }
4273 } else {
4274 busname = "?";
4275 ASC_PRINT2
4276 ("advansys_info: board %d: unknown bus type %d\n",
4277 boardp->id, asc_dvc_varp->bus_type);
4278 }
4279 /* Don't reference 'shost->n_io_port'; It may be truncated. */
4280 sprintf(info,
4281 "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X",
4282 ASC_VERSION, busname,
4283 (ulong)shost->io_port,
4284 (ulong)shost->io_port + boardp->asc_n_io_port -
4285 1, shost->irq);
4286 }
4287 } else {
4288 /*
4289 * Wide Adapter Information
4290 *
4291 * Memory-mapped I/O is used instead of I/O space to access
4292 * the adapter, but display the I/O Port range. The Memory
4293 * I/O address is displayed through the driver /proc file.
4294 */
4295 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
4296 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
4297 iolen = ADV_3550_IOLEN;
4298 widename = "Ultra-Wide";
4299 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
4300 iolen = ADV_38C0800_IOLEN;
4301 widename = "Ultra2-Wide";
4302 } else {
4303 iolen = ADV_38C1600_IOLEN;
4304 widename = "Ultra3-Wide";
4305 }
4306 sprintf(info,
4307 "AdvanSys SCSI %s: PCI %s: PCIMEM 0x%lX-0x%lX, IRQ 0x%X",
4308 ASC_VERSION, widename, (ulong)adv_dvc_varp->iop_base,
4309 (ulong)adv_dvc_varp->iop_base + iolen - 1, shost->irq);
4310 }
4311 ASC_ASSERT(strlen(info) < ASC_INFO_SIZE);
4312 ASC_DBG(1, "advansys_info: end\n");
4313 return info;
1da177e4
LT
4314}
4315
4316/*
4317 * advansys_queuecommand() - interrupt-driven I/O entrypoint.
4318 *
4319 * This function always returns 0. Command return status is saved
4320 * in the 'scp' result field.
4321 */
70c8d897 4322static int
27c868c2 4323advansys_queuecommand(struct scsi_cmnd *scp, void (*done) (struct scsi_cmnd *))
1da177e4 4324{
27c868c2
MW
4325 struct Scsi_Host *shost;
4326 asc_board_t *boardp;
4327 ulong flags;
4328 struct scsi_cmnd *done_scp;
1da177e4 4329
27c868c2
MW
4330 shost = scp->device->host;
4331 boardp = ASC_BOARDP(shost);
4332 ASC_STATS(shost, queuecommand);
1da177e4 4333
27c868c2
MW
4334 /* host_lock taken by mid-level prior to call but need to protect */
4335 /* against own ISR */
4336 spin_lock_irqsave(&boardp->lock, flags);
1da177e4 4337
27c868c2
MW
4338 /*
4339 * Block new commands while handling a reset or abort request.
4340 */
4341 if (boardp->flags & ASC_HOST_IN_RESET) {
4342 ASC_DBG1(1,
4343 "advansys_queuecommand: scp 0x%lx blocked for reset request\n",
4344 (ulong)scp);
4345 scp->result = HOST_BYTE(DID_RESET);
1da177e4 4346
27c868c2
MW
4347 /*
4348 * Add blocked requests to the board's 'done' queue. The queued
4349 * requests will be completed at the end of the abort or reset
4350 * handling.
4351 */
4352 asc_enqueue(&boardp->done, scp, ASC_BACK);
4353 spin_unlock_irqrestore(&boardp->lock, flags);
4354 return 0;
4355 }
1da177e4 4356
27c868c2
MW
4357 /*
4358 * Attempt to execute any waiting commands for the board.
4359 */
4360 if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
4361 ASC_DBG(1,
4362 "advansys_queuecommand: before asc_execute_queue() waiting\n");
4363 asc_execute_queue(&boardp->waiting);
4364 }
4365
4366 /*
4367 * Save the function pointer to Linux mid-level 'done' function
4368 * and attempt to execute the command.
4369 *
4370 * If ASC_NOERROR is returned the request has been added to the
4371 * board's 'active' queue and will be completed by the interrupt
4372 * handler.
4373 *
4374 * If ASC_BUSY is returned add the request to the board's per
4375 * target waiting list. This is the first time the request has
4376 * been tried. Add it to the back of the waiting list. It will be
4377 * retried later.
4378 *
4379 * If an error occurred, the request will have been placed on the
4380 * board's 'done' queue and must be completed before returning.
4381 */
4382 scp->scsi_done = done;
4383 switch (asc_execute_scsi_cmnd(scp)) {
4384 case ASC_NOERROR:
4385 break;
4386 case ASC_BUSY:
4387 asc_enqueue(&boardp->waiting, scp, ASC_BACK);
4388 break;
4389 case ASC_ERROR:
4390 default:
4391 done_scp = asc_dequeue_list(&boardp->done, NULL, ASC_TID_ALL);
4392 /* Interrupts could be enabled here. */
4393 asc_scsi_done_list(done_scp);
4394 break;
4395 }
4396 spin_unlock_irqrestore(&boardp->lock, flags);
1da177e4 4397
27c868c2 4398 return 0;
1da177e4
LT
4399}
4400
4401/*
4402 * advansys_reset()
4403 *
4404 * Reset the bus associated with the command 'scp'.
4405 *
4406 * This function runs its own thread. Interrupts must be blocked but
4407 * sleeping is allowed and no locking other than for host structures is
4408 * required. Returns SUCCESS or FAILED.
4409 */
27c868c2 4410static int advansys_reset(struct scsi_cmnd *scp)
1da177e4 4411{
27c868c2
MW
4412 struct Scsi_Host *shost;
4413 asc_board_t *boardp;
4414 ASC_DVC_VAR *asc_dvc_varp;
4415 ADV_DVC_VAR *adv_dvc_varp;
4416 ulong flags;
4417 struct scsi_cmnd *done_scp = NULL, *last_scp = NULL;
4418 struct scsi_cmnd *tscp, *new_last_scp;
4419 int status;
4420 int ret = SUCCESS;
4421
4422 ASC_DBG1(1, "advansys_reset: 0x%lx\n", (ulong)scp);
1da177e4
LT
4423
4424#ifdef ADVANSYS_STATS
27c868c2
MW
4425 if (scp->device->host != NULL) {
4426 ASC_STATS(scp->device->host, reset);
4427 }
1da177e4
LT
4428#endif /* ADVANSYS_STATS */
4429
27c868c2
MW
4430 if ((shost = scp->device->host) == NULL) {
4431 scp->result = HOST_BYTE(DID_ERROR);
4432 return FAILED;
4433 }
1da177e4 4434
27c868c2 4435 boardp = ASC_BOARDP(shost);
1da177e4 4436
27c868c2
MW
4437 ASC_PRINT1("advansys_reset: board %d: SCSI bus reset started...\n",
4438 boardp->id);
4439 /*
4440 * Check for re-entrancy.
4441 */
1da177e4 4442 spin_lock_irqsave(&boardp->lock, flags);
27c868c2
MW
4443 if (boardp->flags & ASC_HOST_IN_RESET) {
4444 spin_unlock_irqrestore(&boardp->lock, flags);
4445 return FAILED;
4446 }
4447 boardp->flags |= ASC_HOST_IN_RESET;
4448 spin_unlock_irqrestore(&boardp->lock, flags);
1da177e4 4449
27c868c2
MW
4450 if (ASC_NARROW_BOARD(boardp)) {
4451 /*
4452 * Narrow Board
4453 */
4454 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
1da177e4 4455
27c868c2
MW
4456 /*
4457 * Reset the chip and SCSI bus.
4458 */
4459 ASC_DBG(1, "advansys_reset: before AscInitAsc1000Driver()\n");
4460 status = AscInitAsc1000Driver(asc_dvc_varp);
4461
4462 /* Refer to ASC_IERR_* defintions for meaning of 'err_code'. */
4463 if (asc_dvc_varp->err_code) {
4464 ASC_PRINT2
4465 ("advansys_reset: board %d: SCSI bus reset error: 0x%x\n",
4466 boardp->id, asc_dvc_varp->err_code);
4467 ret = FAILED;
4468 } else if (status) {
4469 ASC_PRINT2
4470 ("advansys_reset: board %d: SCSI bus reset warning: 0x%x\n",
4471 boardp->id, status);
4472 } else {
4473 ASC_PRINT1
4474 ("advansys_reset: board %d: SCSI bus reset successful.\n",
4475 boardp->id);
4476 }
4477
4478 ASC_DBG(1, "advansys_reset: after AscInitAsc1000Driver()\n");
4479 spin_lock_irqsave(&boardp->lock, flags);
1da177e4 4480
27c868c2
MW
4481 } else {
4482 /*
4483 * Wide Board
4484 *
4485 * If the suggest reset bus flags are set, then reset the bus.
4486 * Otherwise only reset the device.
4487 */
4488 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
1da177e4 4489
27c868c2
MW
4490 /*
4491 * Reset the target's SCSI bus.
4492 */
4493 ASC_DBG(1, "advansys_reset: before AdvResetChipAndSB()\n");
4494 switch (AdvResetChipAndSB(adv_dvc_varp)) {
4495 case ASC_TRUE:
4496 ASC_PRINT1
4497 ("advansys_reset: board %d: SCSI bus reset successful.\n",
4498 boardp->id);
4499 break;
4500 case ASC_FALSE:
4501 default:
4502 ASC_PRINT1
4503 ("advansys_reset: board %d: SCSI bus reset error.\n",
4504 boardp->id);
4505 ret = FAILED;
4506 break;
4507 }
4508 spin_lock_irqsave(&boardp->lock, flags);
4509 (void)AdvISR(adv_dvc_varp);
4510 }
4511 /* Board lock is held. */
4512
4513 /*
4514 * Dequeue all board 'done' requests. A pointer to the last request
4515 * is returned in 'last_scp'.
4516 */
4517 done_scp = asc_dequeue_list(&boardp->done, &last_scp, ASC_TID_ALL);
4518
4519 /*
4520 * Dequeue all board 'active' requests for all devices and set
4521 * the request status to DID_RESET. A pointer to the last request
4522 * is returned in 'last_scp'.
4523 */
4524 if (done_scp == NULL) {
4525 done_scp =
4526 asc_dequeue_list(&boardp->active, &last_scp, ASC_TID_ALL);
4527 for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) {
4528 tscp->result = HOST_BYTE(DID_RESET);
4529 }
4530 } else {
4531 /* Append to 'done_scp' at the end with 'last_scp'. */
4532 ASC_ASSERT(last_scp != NULL);
4533 last_scp->host_scribble =
4534 (unsigned char *)asc_dequeue_list(&boardp->active,
4535 &new_last_scp,
4536 ASC_TID_ALL);
4537 if (new_last_scp != NULL) {
4538 ASC_ASSERT(REQPNEXT(last_scp) != NULL);
4539 for (tscp = REQPNEXT(last_scp); tscp;
4540 tscp = REQPNEXT(tscp)) {
4541 tscp->result = HOST_BYTE(DID_RESET);
4542 }
4543 last_scp = new_last_scp;
4544 }
4545 }
1da177e4 4546
27c868c2
MW
4547 /*
4548 * Dequeue all 'waiting' requests and set the request status
4549 * to DID_RESET.
4550 */
4551 if (done_scp == NULL) {
4552 done_scp =
4553 asc_dequeue_list(&boardp->waiting, &last_scp, ASC_TID_ALL);
4554 for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) {
4555 tscp->result = HOST_BYTE(DID_RESET);
4556 }
4557 } else {
4558 /* Append to 'done_scp' at the end with 'last_scp'. */
4559 ASC_ASSERT(last_scp != NULL);
4560 last_scp->host_scribble =
4561 (unsigned char *)asc_dequeue_list(&boardp->waiting,
4562 &new_last_scp,
4563 ASC_TID_ALL);
4564 if (new_last_scp != NULL) {
4565 ASC_ASSERT(REQPNEXT(last_scp) != NULL);
4566 for (tscp = REQPNEXT(last_scp); tscp;
4567 tscp = REQPNEXT(tscp)) {
4568 tscp->result = HOST_BYTE(DID_RESET);
4569 }
4570 last_scp = new_last_scp;
4571 }
4572 }
1da177e4 4573
27c868c2
MW
4574 /* Save the time of the most recently completed reset. */
4575 boardp->last_reset = jiffies;
1da177e4 4576
27c868c2
MW
4577 /* Clear reset flag. */
4578 boardp->flags &= ~ASC_HOST_IN_RESET;
4579 spin_unlock_irqrestore(&boardp->lock, flags);
4580
4581 /*
4582 * Complete all the 'done_scp' requests.
4583 */
4584 if (done_scp != NULL) {
4585 asc_scsi_done_list(done_scp);
4586 }
1da177e4 4587
27c868c2 4588 ASC_DBG1(1, "advansys_reset: ret %d\n", ret);
1da177e4 4589
27c868c2 4590 return ret;
1da177e4
LT
4591}
4592
4593/*
4594 * advansys_biosparam()
4595 *
4596 * Translate disk drive geometry if the "BIOS greater than 1 GB"
4597 * support is enabled for a drive.
4598 *
4599 * ip (information pointer) is an int array with the following definition:
4600 * ip[0]: heads
4601 * ip[1]: sectors
4602 * ip[2]: cylinders
4603 */
70c8d897 4604static int
1da177e4 4605advansys_biosparam(struct scsi_device *sdev, struct block_device *bdev,
27c868c2 4606 sector_t capacity, int ip[])
1da177e4 4607{
27c868c2
MW
4608 asc_board_t *boardp;
4609
4610 ASC_DBG(1, "advansys_biosparam: begin\n");
4611 ASC_STATS(sdev->host, biosparam);
4612 boardp = ASC_BOARDP(sdev->host);
4613 if (ASC_NARROW_BOARD(boardp)) {
4614 if ((boardp->dvc_var.asc_dvc_var.dvc_cntl &
4615 ASC_CNTL_BIOS_GT_1GB) && capacity > 0x200000) {
4616 ip[0] = 255;
4617 ip[1] = 63;
4618 } else {
4619 ip[0] = 64;
4620 ip[1] = 32;
4621 }
4622 } else {
4623 if ((boardp->dvc_var.adv_dvc_var.bios_ctrl &
4624 BIOS_CTRL_EXTENDED_XLAT) && capacity > 0x200000) {
4625 ip[0] = 255;
4626 ip[1] = 63;
4627 } else {
4628 ip[0] = 64;
4629 ip[1] = 32;
4630 }
4631 }
4632 ip[2] = (unsigned long)capacity / (ip[0] * ip[1]);
4633 ASC_DBG(1, "advansys_biosparam: end\n");
4634 return 0;
1da177e4
LT
4635}
4636
27c868c2
MW
4637static int __init advansys_detect(struct scsi_host_template *tpnt);
4638static int advansys_release(struct Scsi_Host *shp);
1da177e4
LT
4639
4640static struct scsi_host_template driver_template = {
27c868c2 4641 .proc_name = "advansys",
1da177e4 4642#ifdef CONFIG_PROC_FS
27c868c2 4643 .proc_info = advansys_proc_info,
1da177e4 4644#endif
27c868c2
MW
4645 .name = "advansys",
4646 .detect = advansys_detect,
4647 .release = advansys_release,
4648 .info = advansys_info,
4649 .queuecommand = advansys_queuecommand,
4650 .eh_bus_reset_handler = advansys_reset,
4651 .bios_param = advansys_biosparam,
4652 .slave_configure = advansys_slave_configure,
4653 /*
4654 * Because the driver may control an ISA adapter 'unchecked_isa_dma'
4655 * must be set. The flag will be cleared in advansys_detect for non-ISA
4656 * adapters. Refer to the comment in scsi_module.c for more information.
4657 */
4658 .unchecked_isa_dma = 1,
4659 /*
4660 * All adapters controlled by this driver are capable of large
4661 * scatter-gather lists. According to the mid-level SCSI documentation
4662 * this obviates any performance gain provided by setting
4663 * 'use_clustering'. But empirically while CPU utilization is increased
4664 * by enabling clustering, I/O throughput increases as well.
4665 */
4666 .use_clustering = ENABLE_CLUSTERING,
1da177e4 4667};
1da177e4 4668
27c868c2 4669#include "scsi_module.c"
1da177e4
LT
4670
4671/*
4672 * --- Miscellaneous Driver Functions
4673 */
4674
4675/*
4676 * First-level interrupt handler.
4677 *
4678 * 'dev_id' is a pointer to the interrupting adapter's asc_board_t. Because
4679 * all boards are currently checked for interrupts on each interrupt, 'dev_id'
4680 * is not referenced. 'dev_id' could be used to identify an interrupt passed
4681 * to the AdvanSys driver which is for a device sharing an interrupt with
4682 * an AdvanSys adapter.
4683 */
27c868c2 4684static irqreturn_t advansys_interrupt(int irq, void *dev_id)
1da177e4 4685{
074c8fe4 4686 unsigned long flags;
27c868c2
MW
4687 struct scsi_cmnd *done_scp = NULL, *last_scp = NULL;
4688 struct scsi_cmnd *new_last_scp;
074c8fe4
MW
4689 struct Scsi_Host *shost = dev_id;
4690 asc_board_t *boardp = ASC_BOARDP(shost);
4691 irqreturn_t result = IRQ_NONE;
27c868c2 4692
074c8fe4
MW
4693 ASC_DBG1(2, "advansys_interrupt: boardp 0x%p\n", boardp);
4694 spin_lock_irqsave(&boardp->lock, flags);
4695 if (ASC_NARROW_BOARD(boardp)) {
4696 /*
4697 * Narrow Board
4698 */
4699 if (AscIsIntPending(shost->io_port)) {
4700 result = IRQ_HANDLED;
4701 ASC_STATS(shost, interrupt);
4702 ASC_DBG(1, "advansys_interrupt: before AscISR()\n");
4703 AscISR(&boardp->dvc_var.asc_dvc_var);
4704 }
4705 } else {
4706 /*
4707 * Wide Board
4708 */
4709 ASC_DBG(1, "advansys_interrupt: before AdvISR()\n");
4710 if (AdvISR(&boardp->dvc_var.adv_dvc_var)) {
4711 result = IRQ_HANDLED;
4712 ASC_STATS(shost, interrupt);
4713 }
4714 }
27c868c2
MW
4715
4716 /*
074c8fe4
MW
4717 * Start waiting requests and create a list of completed requests.
4718 *
4719 * If a reset request is being performed for the board, the reset
4720 * handler will complete pending requests after it has completed.
4721 */
4722 if ((boardp->flags & ASC_HOST_IN_RESET) == 0) {
4723 ASC_DBG2(1, "advansys_interrupt: done_scp 0x%p, "
4724 "last_scp 0x%p\n", done_scp, last_scp);
4725
4726 /* Start any waiting commands for the board. */
4727 if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
4728 ASC_DBG(1, "advansys_interrupt: before "
4729 "asc_execute_queue()\n");
4730 asc_execute_queue(&boardp->waiting);
27c868c2 4731 }
1da177e4 4732
27c868c2 4733 /*
074c8fe4 4734 * Add to the list of requests that must be completed.
27c868c2 4735 *
074c8fe4
MW
4736 * 'done_scp' will always be NULL on the first iteration of
4737 * this loop. 'last_scp' is set at the same time as 'done_scp'.
27c868c2 4738 */
074c8fe4
MW
4739 if (done_scp == NULL) {
4740 done_scp = asc_dequeue_list(&boardp->done,
4741 &last_scp, ASC_TID_ALL);
4742 } else {
4743 ASC_ASSERT(last_scp != NULL);
4744 last_scp->host_scribble =
4745 (unsigned char *)asc_dequeue_list(&boardp->
4746 done,
4747 &new_last_scp,
4748 ASC_TID_ALL);
4749 if (new_last_scp != NULL) {
4750 ASC_ASSERT(REQPNEXT(last_scp) != NULL);
4751 last_scp = new_last_scp;
27c868c2
MW
4752 }
4753 }
27c868c2 4754 }
074c8fe4 4755 spin_unlock_irqrestore(&boardp->lock, flags);
1da177e4 4756
27c868c2
MW
4757 /*
4758 * If interrupts were enabled on entry, then they
4759 * are now enabled here.
4760 *
4761 * Complete all requests on the done list.
4762 */
1da177e4 4763
27c868c2 4764 asc_scsi_done_list(done_scp);
1da177e4 4765
27c868c2 4766 ASC_DBG(1, "advansys_interrupt: end\n");
074c8fe4 4767 return result;
1da177e4
LT
4768}
4769
4770/*
4771 * Set the number of commands to queue per device for the
4772 * specified host adapter.
4773 */
27c868c2 4774static int advansys_slave_configure(struct scsi_device *device)
1da177e4 4775{
27c868c2 4776 asc_board_t *boardp;
1da177e4 4777
27c868c2
MW
4778 boardp = ASC_BOARDP(device->host);
4779 boardp->flags |= ASC_SELECT_QUEUE_DEPTHS;
4780 /*
4781 * Save a pointer to the device and set its initial/maximum
4782 * queue depth. Only save the pointer for a lun0 dev though.
4783 */
4784 if (device->lun == 0)
4785 boardp->device[device->id] = device;
4786 if (device->tagged_supported) {
4787 if (ASC_NARROW_BOARD(boardp)) {
4788 scsi_adjust_queue_depth(device, MSG_ORDERED_TAG,
4789 boardp->dvc_var.asc_dvc_var.
4790 max_dvc_qng[device->id]);
4791 } else {
4792 scsi_adjust_queue_depth(device, MSG_ORDERED_TAG,
4793 boardp->dvc_var.adv_dvc_var.
4794 max_dvc_qng);
4795 }
4796 } else {
4797 scsi_adjust_queue_depth(device, 0, device->host->cmd_per_lun);
4798 }
4799 ASC_DBG4(1,
4800 "advansys_slave_configure: device 0x%lx, boardp 0x%lx, id %d, depth %d\n",
4801 (ulong)device, (ulong)boardp, device->id, device->queue_depth);
4802 return 0;
1da177e4
LT
4803}
4804
4805/*
4806 * Complete all requests on the singly linked list pointed
4807 * to by 'scp'.
4808 *
4809 * Interrupts can be enabled on entry.
4810 */
27c868c2 4811static void asc_scsi_done_list(struct scsi_cmnd *scp)
1da177e4 4812{
27c868c2 4813 struct scsi_cmnd *tscp;
1da177e4 4814
27c868c2
MW
4815 ASC_DBG(2, "asc_scsi_done_list: begin\n");
4816 while (scp != NULL) {
4817 asc_board_t *boardp;
4818 struct device *dev;
1da177e4 4819
27c868c2
MW
4820 ASC_DBG1(3, "asc_scsi_done_list: scp 0x%lx\n", (ulong)scp);
4821 tscp = REQPNEXT(scp);
4822 scp->host_scribble = NULL;
1da177e4 4823
27c868c2 4824 boardp = ASC_BOARDP(scp->device->host);
1da177e4 4825
27c868c2
MW
4826 if (ASC_NARROW_BOARD(boardp))
4827 dev = boardp->dvc_cfg.asc_dvc_cfg.dev;
4828 else
4829 dev = boardp->dvc_cfg.adv_dvc_cfg.dev;
1da177e4 4830
27c868c2
MW
4831 if (scp->use_sg)
4832 dma_unmap_sg(dev,
4833 (struct scatterlist *)scp->request_buffer,
4834 scp->use_sg, scp->sc_data_direction);
4835 else if (scp->request_bufflen)
4836 dma_unmap_single(dev, scp->SCp.dma_handle,
4837 scp->request_bufflen,
4838 scp->sc_data_direction);
1da177e4 4839
27c868c2
MW
4840 ASC_STATS(scp->device->host, done);
4841 ASC_ASSERT(scp->scsi_done != NULL);
1da177e4 4842
27c868c2 4843 scp->scsi_done(scp);
1da177e4 4844
27c868c2
MW
4845 scp = tscp;
4846 }
4847 ASC_DBG(2, "asc_scsi_done_list: done\n");
4848 return;
1da177e4
LT
4849}
4850
4851/*
4852 * Execute a single 'Scsi_Cmnd'.
4853 *
4854 * The function 'done' is called when the request has been completed.
4855 *
4856 * Scsi_Cmnd:
4857 *
4858 * host - board controlling device
4859 * device - device to send command
4860 * target - target of device
4861 * lun - lun of device
4862 * cmd_len - length of SCSI CDB
4863 * cmnd - buffer for SCSI 8, 10, or 12 byte CDB
4864 * use_sg - if non-zero indicates scatter-gather request with use_sg elements
4865 *
4866 * if (use_sg == 0) {
4867 * request_buffer - buffer address for request
4868 * request_bufflen - length of request buffer
4869 * } else {
4870 * request_buffer - pointer to scatterlist structure
4871 * }
4872 *
4873 * sense_buffer - sense command buffer
4874 *
4875 * result (4 bytes of an int):
4876 * Byte Meaning
4877 * 0 SCSI Status Byte Code
4878 * 1 SCSI One Byte Message Code
4879 * 2 Host Error Code
4880 * 3 Mid-Level Error Code
4881 *
4882 * host driver fields:
4883 * SCp - Scsi_Pointer used for command processing status
4884 * scsi_done - used to save caller's done function
4885 * host_scribble - used for pointer to another struct scsi_cmnd
4886 *
4887 * If this function returns ASC_NOERROR the request has been enqueued
4888 * on the board's 'active' queue and will be completed from the
4889 * interrupt handler.
4890 *
4891 * If this function returns ASC_NOERROR the request has been enqueued
4892 * on the board's 'done' queue and must be completed by the caller.
4893 *
4894 * If ASC_BUSY is returned the request will be enqueued by the
4895 * caller on the target's waiting queue and re-tried later.
4896 */
27c868c2 4897static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp)
1da177e4 4898{
27c868c2
MW
4899 asc_board_t *boardp;
4900 ASC_DVC_VAR *asc_dvc_varp;
4901 ADV_DVC_VAR *adv_dvc_varp;
4902 ADV_SCSI_REQ_Q *adv_scsiqp;
4903 struct scsi_device *device;
4904 int ret;
4905
4906 ASC_DBG2(1, "asc_execute_scsi_cmnd: scp 0x%lx, done 0x%lx\n",
4907 (ulong)scp, (ulong)scp->scsi_done);
4908
4909 boardp = ASC_BOARDP(scp->device->host);
4910 device = boardp->device[scp->device->id];
4911
4912 if (ASC_NARROW_BOARD(boardp)) {
4913 /*
4914 * Build and execute Narrow Board request.
4915 */
4916
4917 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
4918
4919 /*
4920 * Build Asc Library request structure using the
4921 * global structures 'asc_scsi_req' and 'asc_sg_head'.
4922 *
4923 * If an error is returned, then the request has been
4924 * queued on the board done queue. It will be completed
4925 * by the caller.
4926 *
4927 * asc_build_req() can not return ASC_BUSY.
4928 */
4929 if (asc_build_req(boardp, scp) == ASC_ERROR) {
4930 ASC_STATS(scp->device->host, build_error);
4931 return ASC_ERROR;
4932 }
4933
4934 /*
4935 * Execute the command. If there is no error, add the command
4936 * to the active queue.
4937 */
4938 switch (ret = AscExeScsiQueue(asc_dvc_varp, &asc_scsi_q)) {
4939 case ASC_NOERROR:
4940 ASC_STATS(scp->device->host, exe_noerror);
4941 /*
4942 * Increment monotonically increasing per device successful
4943 * request counter. Wrapping doesn't matter.
4944 */
4945 boardp->reqcnt[scp->device->id]++;
4946 asc_enqueue(&boardp->active, scp, ASC_BACK);
4947 ASC_DBG(1,
4948 "asc_execute_scsi_cmnd: AscExeScsiQueue(), ASC_NOERROR\n");
4949 break;
4950 case ASC_BUSY:
4951 /*
4952 * Caller will enqueue request on the target's waiting queue
4953 * and retry later.
4954 */
4955 ASC_STATS(scp->device->host, exe_busy);
4956 break;
4957 case ASC_ERROR:
4958 ASC_PRINT2
4959 ("asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
4960 boardp->id, asc_dvc_varp->err_code);
4961 ASC_STATS(scp->device->host, exe_error);
4962 scp->result = HOST_BYTE(DID_ERROR);
4963 asc_enqueue(&boardp->done, scp, ASC_BACK);
4964 break;
4965 default:
4966 ASC_PRINT2
4967 ("asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() unknown, err_code 0x%x\n",
4968 boardp->id, asc_dvc_varp->err_code);
4969 ASC_STATS(scp->device->host, exe_unknown);
4970 scp->result = HOST_BYTE(DID_ERROR);
4971 asc_enqueue(&boardp->done, scp, ASC_BACK);
4972 break;
4973 }
4974 } else {
4975 /*
4976 * Build and execute Wide Board request.
4977 */
4978 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
4979
4980 /*
4981 * Build and get a pointer to an Adv Library request structure.
4982 *
4983 * If the request is successfully built then send it below,
4984 * otherwise return with an error.
4985 */
4986 switch (adv_build_req(boardp, scp, &adv_scsiqp)) {
4987 case ASC_NOERROR:
4988 ASC_DBG(3,
4989 "asc_execute_scsi_cmnd: adv_build_req ASC_NOERROR\n");
4990 break;
4991 case ASC_BUSY:
4992 ASC_DBG(1,
4993 "asc_execute_scsi_cmnd: adv_build_req ASC_BUSY\n");
4994 /*
4995 * If busy is returned the request has not been enqueued.
4996 * It will be enqueued by the caller on the target's waiting
4997 * queue and retried later.
4998 *
4999 * The asc_stats fields 'adv_build_noreq' and 'adv_build_nosg'
5000 * count wide board busy conditions. They are updated in
5001 * adv_build_req and adv_get_sglist, respectively.
5002 */
5003 return ASC_BUSY;
5004 case ASC_ERROR:
5005 /*
5006 * If an error is returned, then the request has been
5007 * queued on the board done queue. It will be completed
5008 * by the caller.
5009 */
5010 default:
5011 ASC_DBG(1,
5012 "asc_execute_scsi_cmnd: adv_build_req ASC_ERROR\n");
5013 ASC_STATS(scp->device->host, build_error);
5014 return ASC_ERROR;
5015 }
1da177e4 5016
27c868c2
MW
5017 /*
5018 * Execute the command. If there is no error, add the command
5019 * to the active queue.
5020 */
5021 switch (ret = AdvExeScsiQueue(adv_dvc_varp, adv_scsiqp)) {
5022 case ASC_NOERROR:
5023 ASC_STATS(scp->device->host, exe_noerror);
5024 /*
5025 * Increment monotonically increasing per device successful
5026 * request counter. Wrapping doesn't matter.
5027 */
5028 boardp->reqcnt[scp->device->id]++;
5029 asc_enqueue(&boardp->active, scp, ASC_BACK);
5030 ASC_DBG(1,
5031 "asc_execute_scsi_cmnd: AdvExeScsiQueue(), ASC_NOERROR\n");
5032 break;
5033 case ASC_BUSY:
5034 /*
5035 * Caller will enqueue request on the target's waiting queue
5036 * and retry later.
5037 */
5038 ASC_STATS(scp->device->host, exe_busy);
5039 break;
5040 case ASC_ERROR:
5041 ASC_PRINT2
5042 ("asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
5043 boardp->id, adv_dvc_varp->err_code);
5044 ASC_STATS(scp->device->host, exe_error);
5045 scp->result = HOST_BYTE(DID_ERROR);
5046 asc_enqueue(&boardp->done, scp, ASC_BACK);
5047 break;
5048 default:
5049 ASC_PRINT2
5050 ("asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() unknown, err_code 0x%x\n",
5051 boardp->id, adv_dvc_varp->err_code);
5052 ASC_STATS(scp->device->host, exe_unknown);
5053 scp->result = HOST_BYTE(DID_ERROR);
5054 asc_enqueue(&boardp->done, scp, ASC_BACK);
5055 break;
5056 }
5057 }
5058
5059 ASC_DBG(1, "asc_execute_scsi_cmnd: end\n");
5060 return ret;
1da177e4
LT
5061}
5062
5063/*
5064 * Build a request structure for the Asc Library (Narrow Board).
5065 *
5066 * The global structures 'asc_scsi_q' and 'asc_sg_head' are
5067 * used to build the request.
5068 *
5069 * If an error occurs, then queue the request on the board done
5070 * queue and return ASC_ERROR.
5071 */
27c868c2 5072static int asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp)
1da177e4 5073{
27c868c2
MW
5074 struct device *dev = boardp->dvc_cfg.asc_dvc_cfg.dev;
5075
5076 /*
5077 * Mutually exclusive access is required to 'asc_scsi_q' and
5078 * 'asc_sg_head' until after the request is started.
5079 */
5080 memset(&asc_scsi_q, 0, sizeof(ASC_SCSI_Q));
5081
5082 /*
5083 * Point the ASC_SCSI_Q to the 'struct scsi_cmnd'.
5084 */
5085 asc_scsi_q.q2.srb_ptr = ASC_VADDR_TO_U32(scp);
5086
5087 /*
5088 * Build the ASC_SCSI_Q request.
5089 *
5090 * For narrow boards a CDB length maximum of 12 bytes
5091 * is supported.
5092 */
5093 if (scp->cmd_len > ASC_MAX_CDB_LEN) {
5094 ASC_PRINT3
5095 ("asc_build_req: board %d: cmd_len %d > ASC_MAX_CDB_LEN %d\n",
5096 boardp->id, scp->cmd_len, ASC_MAX_CDB_LEN);
5097 scp->result = HOST_BYTE(DID_ERROR);
5098 asc_enqueue(&boardp->done, scp, ASC_BACK);
5099 return ASC_ERROR;
5100 }
5101 asc_scsi_q.cdbptr = &scp->cmnd[0];
5102 asc_scsi_q.q2.cdb_len = scp->cmd_len;
5103 asc_scsi_q.q1.target_id = ASC_TID_TO_TARGET_ID(scp->device->id);
5104 asc_scsi_q.q1.target_lun = scp->device->lun;
5105 asc_scsi_q.q2.target_ix =
5106 ASC_TIDLUN_TO_IX(scp->device->id, scp->device->lun);
5107 asc_scsi_q.q1.sense_addr =
5108 cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
5109 asc_scsi_q.q1.sense_len = sizeof(scp->sense_buffer);
5110
5111 /*
5112 * If there are any outstanding requests for the current target,
5113 * then every 255th request send an ORDERED request. This heuristic
5114 * tries to retain the benefit of request sorting while preventing
5115 * request starvation. 255 is the max number of tags or pending commands
5116 * a device may have outstanding.
5117 *
5118 * The request count is incremented below for every successfully
5119 * started request.
5120 *
5121 */
5122 if ((boardp->dvc_var.asc_dvc_var.cur_dvc_qng[scp->device->id] > 0) &&
5123 (boardp->reqcnt[scp->device->id] % 255) == 0) {
5124 asc_scsi_q.q2.tag_code = MSG_ORDERED_TAG;
5125 } else {
5126 asc_scsi_q.q2.tag_code = MSG_SIMPLE_TAG;
5127 }
1da177e4 5128
27c868c2
MW
5129 /*
5130 * Build ASC_SCSI_Q for a contiguous buffer or a scatter-gather
5131 * buffer command.
5132 */
5133 if (scp->use_sg == 0) {
5134 /*
5135 * CDB request of single contiguous buffer.
5136 */
5137 ASC_STATS(scp->device->host, cont_cnt);
5138 scp->SCp.dma_handle = scp->request_bufflen ?
5139 dma_map_single(dev, scp->request_buffer,
5140 scp->request_bufflen,
5141 scp->sc_data_direction) : 0;
5142 asc_scsi_q.q1.data_addr = cpu_to_le32(scp->SCp.dma_handle);
5143 asc_scsi_q.q1.data_cnt = cpu_to_le32(scp->request_bufflen);
5144 ASC_STATS_ADD(scp->device->host, cont_xfer,
5145 ASC_CEILING(scp->request_bufflen, 512));
5146 asc_scsi_q.q1.sg_queue_cnt = 0;
5147 asc_scsi_q.sg_head = NULL;
5148 } else {
5149 /*
5150 * CDB scatter-gather request list.
5151 */
5152 int sgcnt;
5153 int use_sg;
5154 struct scatterlist *slp;
5155
5156 slp = (struct scatterlist *)scp->request_buffer;
5157 use_sg =
5158 dma_map_sg(dev, slp, scp->use_sg, scp->sc_data_direction);
5159
5160 if (use_sg > scp->device->host->sg_tablesize) {
5161 ASC_PRINT3
5162 ("asc_build_req: board %d: use_sg %d > sg_tablesize %d\n",
5163 boardp->id, use_sg,
5164 scp->device->host->sg_tablesize);
5165 dma_unmap_sg(dev, slp, scp->use_sg,
5166 scp->sc_data_direction);
5167 scp->result = HOST_BYTE(DID_ERROR);
5168 asc_enqueue(&boardp->done, scp, ASC_BACK);
5169 return ASC_ERROR;
5170 }
5171
5172 ASC_STATS(scp->device->host, sg_cnt);
1da177e4 5173
27c868c2
MW
5174 /*
5175 * Use global ASC_SG_HEAD structure and set the ASC_SCSI_Q
5176 * structure to point to it.
5177 */
5178 memset(&asc_sg_head, 0, sizeof(ASC_SG_HEAD));
5179
5180 asc_scsi_q.q1.cntl |= QC_SG_HEAD;
5181 asc_scsi_q.sg_head = &asc_sg_head;
5182 asc_scsi_q.q1.data_cnt = 0;
5183 asc_scsi_q.q1.data_addr = 0;
5184 /* This is a byte value, otherwise it would need to be swapped. */
5185 asc_sg_head.entry_cnt = asc_scsi_q.q1.sg_queue_cnt = use_sg;
5186 ASC_STATS_ADD(scp->device->host, sg_elem,
5187 asc_sg_head.entry_cnt);
1da177e4 5188
27c868c2
MW
5189 /*
5190 * Convert scatter-gather list into ASC_SG_HEAD list.
5191 */
5192 for (sgcnt = 0; sgcnt < use_sg; sgcnt++, slp++) {
5193 asc_sg_head.sg_list[sgcnt].addr =
5194 cpu_to_le32(sg_dma_address(slp));
5195 asc_sg_head.sg_list[sgcnt].bytes =
5196 cpu_to_le32(sg_dma_len(slp));
5197 ASC_STATS_ADD(scp->device->host, sg_xfer,
5198 ASC_CEILING(sg_dma_len(slp), 512));
5199 }
5200 }
1da177e4 5201
27c868c2
MW
5202 ASC_DBG_PRT_ASC_SCSI_Q(2, &asc_scsi_q);
5203 ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
1da177e4 5204
27c868c2 5205 return ASC_NOERROR;
1da177e4
LT
5206}
5207
5208/*
5209 * Build a request structure for the Adv Library (Wide Board).
5210 *
5211 * If an adv_req_t can not be allocated to issue the request,
5212 * then return ASC_BUSY. If an error occurs, then return ASC_ERROR.
5213 *
5214 * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the
5215 * microcode for DMA addresses or math operations are byte swapped
5216 * to little-endian order.
5217 */
27c868c2 5218static int
1da177e4 5219adv_build_req(asc_board_t *boardp, struct scsi_cmnd *scp,
27c868c2 5220 ADV_SCSI_REQ_Q **adv_scsiqpp)
1da177e4 5221{
27c868c2
MW
5222 adv_req_t *reqp;
5223 ADV_SCSI_REQ_Q *scsiqp;
5224 int i;
5225 int ret;
5226 struct device *dev = boardp->dvc_cfg.adv_dvc_cfg.dev;
5227
5228 /*
5229 * Allocate an adv_req_t structure from the board to execute
5230 * the command.
5231 */
5232 if (boardp->adv_reqp == NULL) {
5233 ASC_DBG(1, "adv_build_req: no free adv_req_t\n");
5234 ASC_STATS(scp->device->host, adv_build_noreq);
5235 return ASC_BUSY;
5236 } else {
5237 reqp = boardp->adv_reqp;
5238 boardp->adv_reqp = reqp->next_reqp;
5239 reqp->next_reqp = NULL;
5240 }
1da177e4 5241
27c868c2
MW
5242 /*
5243 * Get 32-byte aligned ADV_SCSI_REQ_Q and ADV_SG_BLOCK pointers.
5244 */
5245 scsiqp = (ADV_SCSI_REQ_Q *)ADV_32BALIGN(&reqp->scsi_req_q);
5246
5247 /*
5248 * Initialize the structure.
5249 */
5250 scsiqp->cntl = scsiqp->scsi_cntl = scsiqp->done_status = 0;
5251
5252 /*
5253 * Set the ADV_SCSI_REQ_Q 'srb_ptr' to point to the adv_req_t structure.
5254 */
5255 scsiqp->srb_ptr = ASC_VADDR_TO_U32(reqp);
5256
5257 /*
5258 * Set the adv_req_t 'cmndp' to point to the struct scsi_cmnd structure.
5259 */
5260 reqp->cmndp = scp;
5261
5262 /*
5263 * Build the ADV_SCSI_REQ_Q request.
5264 */
5265
5266 /*
5267 * Set CDB length and copy it to the request structure.
5268 * For wide boards a CDB length maximum of 16 bytes
5269 * is supported.
5270 */
5271 if (scp->cmd_len > ADV_MAX_CDB_LEN) {
5272 ASC_PRINT3
5273 ("adv_build_req: board %d: cmd_len %d > ADV_MAX_CDB_LEN %d\n",
5274 boardp->id, scp->cmd_len, ADV_MAX_CDB_LEN);
5275 scp->result = HOST_BYTE(DID_ERROR);
5276 asc_enqueue(&boardp->done, scp, ASC_BACK);
5277 return ASC_ERROR;
5278 }
5279 scsiqp->cdb_len = scp->cmd_len;
5280 /* Copy first 12 CDB bytes to cdb[]. */
5281 for (i = 0; i < scp->cmd_len && i < 12; i++) {
5282 scsiqp->cdb[i] = scp->cmnd[i];
5283 }
5284 /* Copy last 4 CDB bytes, if present, to cdb16[]. */
5285 for (; i < scp->cmd_len; i++) {
5286 scsiqp->cdb16[i - 12] = scp->cmnd[i];
5287 }
1da177e4 5288
27c868c2
MW
5289 scsiqp->target_id = scp->device->id;
5290 scsiqp->target_lun = scp->device->lun;
1da177e4 5291
27c868c2
MW
5292 scsiqp->sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
5293 scsiqp->sense_len = sizeof(scp->sense_buffer);
1da177e4 5294
27c868c2
MW
5295 /*
5296 * Build ADV_SCSI_REQ_Q for a contiguous buffer or a scatter-gather
5297 * buffer command.
5298 */
1da177e4 5299
1da177e4 5300 scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
27c868c2
MW
5301 scsiqp->vdata_addr = scp->request_buffer;
5302 scsiqp->data_addr = cpu_to_le32(virt_to_bus(scp->request_buffer));
1da177e4 5303
27c868c2
MW
5304 if (scp->use_sg == 0) {
5305 /*
5306 * CDB request of single contiguous buffer.
5307 */
5308 reqp->sgblkp = NULL;
5309 scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
5310 if (scp->request_bufflen) {
5311 scsiqp->vdata_addr = scp->request_buffer;
5312 scp->SCp.dma_handle =
5313 dma_map_single(dev, scp->request_buffer,
5314 scp->request_bufflen,
5315 scp->sc_data_direction);
5316 } else {
5317 scsiqp->vdata_addr = NULL;
5318 scp->SCp.dma_handle = 0;
5319 }
5320 scsiqp->data_addr = cpu_to_le32(scp->SCp.dma_handle);
5321 scsiqp->sg_list_ptr = NULL;
5322 scsiqp->sg_real_addr = 0;
5323 ASC_STATS(scp->device->host, cont_cnt);
5324 ASC_STATS_ADD(scp->device->host, cont_xfer,
5325 ASC_CEILING(scp->request_bufflen, 512));
5326 } else {
5327 /*
5328 * CDB scatter-gather request list.
5329 */
5330 struct scatterlist *slp;
5331 int use_sg;
5332
5333 slp = (struct scatterlist *)scp->request_buffer;
5334 use_sg =
5335 dma_map_sg(dev, slp, scp->use_sg, scp->sc_data_direction);
5336
5337 if (use_sg > ADV_MAX_SG_LIST) {
5338 ASC_PRINT3
5339 ("adv_build_req: board %d: use_sg %d > ADV_MAX_SG_LIST %d\n",
5340 boardp->id, use_sg,
5341 scp->device->host->sg_tablesize);
5342 dma_unmap_sg(dev, slp, scp->use_sg,
5343 scp->sc_data_direction);
5344 scp->result = HOST_BYTE(DID_ERROR);
5345 asc_enqueue(&boardp->done, scp, ASC_BACK);
5346
5347 /*
5348 * Free the 'adv_req_t' structure by adding it back to the
5349 * board free list.
5350 */
5351 reqp->next_reqp = boardp->adv_reqp;
5352 boardp->adv_reqp = reqp;
5353
5354 return ASC_ERROR;
5355 }
5356
5357 if ((ret =
5358 adv_get_sglist(boardp, reqp, scp,
5359 use_sg)) != ADV_SUCCESS) {
5360 /*
5361 * Free the adv_req_t structure by adding it back to the
5362 * board free list.
5363 */
5364 reqp->next_reqp = boardp->adv_reqp;
5365 boardp->adv_reqp = reqp;
5366
5367 return ret;
5368 }
5369
5370 ASC_STATS(scp->device->host, sg_cnt);
5371 ASC_STATS_ADD(scp->device->host, sg_elem, use_sg);
5372 }
1da177e4 5373
27c868c2
MW
5374 ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
5375 ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
1da177e4 5376
27c868c2 5377 *adv_scsiqpp = scsiqp;
1da177e4 5378
27c868c2 5379 return ASC_NOERROR;
1da177e4
LT
5380}
5381
5382/*
5383 * Build scatter-gather list for Adv Library (Wide Board).
5384 *
5385 * Additional ADV_SG_BLOCK structures will need to be allocated
5386 * if the total number of scatter-gather elements exceeds
5387 * NO_OF_SG_PER_BLOCK (15). The ADV_SG_BLOCK structures are
5388 * assumed to be physically contiguous.
5389 *
5390 * Return:
5391 * ADV_SUCCESS(1) - SG List successfully created
5392 * ADV_ERROR(-1) - SG List creation failed
5393 */
27c868c2
MW
5394static int
5395adv_get_sglist(asc_board_t *boardp, adv_req_t *reqp, struct scsi_cmnd *scp,
5396 int use_sg)
1da177e4 5397{
27c868c2
MW
5398 adv_sgblk_t *sgblkp;
5399 ADV_SCSI_REQ_Q *scsiqp;
5400 struct scatterlist *slp;
5401 int sg_elem_cnt;
5402 ADV_SG_BLOCK *sg_block, *prev_sg_block;
5403 ADV_PADDR sg_block_paddr;
5404 int i;
5405
5406 scsiqp = (ADV_SCSI_REQ_Q *)ADV_32BALIGN(&reqp->scsi_req_q);
5407 slp = (struct scatterlist *)scp->request_buffer;
5408 sg_elem_cnt = use_sg;
5409 prev_sg_block = NULL;
5410 reqp->sgblkp = NULL;
5411
5412 do {
5413 /*
5414 * Allocate a 'adv_sgblk_t' structure from the board free
5415 * list. One 'adv_sgblk_t' structure holds NO_OF_SG_PER_BLOCK
5416 * (15) scatter-gather elements.
5417 */
5418 if ((sgblkp = boardp->adv_sgblkp) == NULL) {
5419 ASC_DBG(1, "adv_get_sglist: no free adv_sgblk_t\n");
5420 ASC_STATS(scp->device->host, adv_build_nosg);
5421
5422 /*
5423 * Allocation failed. Free 'adv_sgblk_t' structures already
5424 * allocated for the request.
5425 */
5426 while ((sgblkp = reqp->sgblkp) != NULL) {
5427 /* Remove 'sgblkp' from the request list. */
5428 reqp->sgblkp = sgblkp->next_sgblkp;
5429
5430 /* Add 'sgblkp' to the board free list. */
5431 sgblkp->next_sgblkp = boardp->adv_sgblkp;
5432 boardp->adv_sgblkp = sgblkp;
5433 }
5434 return ASC_BUSY;
5435 } else {
5436 /* Complete 'adv_sgblk_t' board allocation. */
5437 boardp->adv_sgblkp = sgblkp->next_sgblkp;
5438 sgblkp->next_sgblkp = NULL;
5439
5440 /*
5441 * Get 8 byte aligned virtual and physical addresses for
5442 * the allocated ADV_SG_BLOCK structure.
5443 */
5444 sg_block =
5445 (ADV_SG_BLOCK *)ADV_8BALIGN(&sgblkp->sg_block);
5446 sg_block_paddr = virt_to_bus(sg_block);
5447
5448 /*
5449 * Check if this is the first 'adv_sgblk_t' for the request.
5450 */
5451 if (reqp->sgblkp == NULL) {
5452 /* Request's first scatter-gather block. */
5453 reqp->sgblkp = sgblkp;
5454
5455 /*
5456 * Set ADV_SCSI_REQ_T ADV_SG_BLOCK virtual and physical
5457 * address pointers.
5458 */
5459 scsiqp->sg_list_ptr = sg_block;
5460 scsiqp->sg_real_addr =
5461 cpu_to_le32(sg_block_paddr);
5462 } else {
5463 /* Request's second or later scatter-gather block. */
5464 sgblkp->next_sgblkp = reqp->sgblkp;
5465 reqp->sgblkp = sgblkp;
5466
5467 /*
5468 * Point the previous ADV_SG_BLOCK structure to
5469 * the newly allocated ADV_SG_BLOCK structure.
5470 */
5471 ASC_ASSERT(prev_sg_block != NULL);
5472 prev_sg_block->sg_ptr =
5473 cpu_to_le32(sg_block_paddr);
5474 }
5475 }
5476
5477 for (i = 0; i < NO_OF_SG_PER_BLOCK; i++) {
5478 sg_block->sg_list[i].sg_addr =
5479 cpu_to_le32(sg_dma_address(slp));
5480 sg_block->sg_list[i].sg_count =
5481 cpu_to_le32(sg_dma_len(slp));
5482 ASC_STATS_ADD(scp->device->host, sg_xfer,
5483 ASC_CEILING(sg_dma_len(slp), 512));
5484
5485 if (--sg_elem_cnt == 0) { /* Last ADV_SG_BLOCK and scatter-gather entry. */
5486 sg_block->sg_cnt = i + 1;
5487 sg_block->sg_ptr = 0L; /* Last ADV_SG_BLOCK in list. */
5488 return ADV_SUCCESS;
5489 }
5490 slp++;
5491 }
5492 sg_block->sg_cnt = NO_OF_SG_PER_BLOCK;
5493 prev_sg_block = sg_block;
5494 }
5495 while (1);
5496 /* NOTREACHED */
1da177e4
LT
5497}
5498
5499/*
5500 * asc_isr_callback() - Second Level Interrupt Handler called by AscISR().
5501 *
5502 * Interrupt callback function for the Narrow SCSI Asc Library.
5503 */
27c868c2 5504static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
1da177e4 5505{
27c868c2
MW
5506 asc_board_t *boardp;
5507 struct scsi_cmnd *scp;
5508 struct Scsi_Host *shost;
27c868c2
MW
5509
5510 ASC_DBG2(1, "asc_isr_callback: asc_dvc_varp 0x%lx, qdonep 0x%lx\n",
5511 (ulong)asc_dvc_varp, (ulong)qdonep);
5512 ASC_DBG_PRT_ASC_QDONE_INFO(2, qdonep);
5513
5514 /*
5515 * Get the struct scsi_cmnd structure and Scsi_Host structure for the
5516 * command that has been completed.
5517 */
5518 scp = (struct scsi_cmnd *)ASC_U32_TO_VADDR(qdonep->d2.srb_ptr);
5519 ASC_DBG1(1, "asc_isr_callback: scp 0x%lx\n", (ulong)scp);
5520
5521 if (scp == NULL) {
5522 ASC_PRINT("asc_isr_callback: scp is NULL\n");
5523 return;
5524 }
5525 ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
5526
27c868c2 5527 shost = scp->device->host;
27c868c2
MW
5528 ASC_STATS(shost, callback);
5529 ASC_DBG1(1, "asc_isr_callback: shost 0x%lx\n", (ulong)shost);
5530
5531 /*
5532 * If the request isn't found on the active queue, it may
5533 * have been removed to handle a reset request.
5534 * Display a message and return.
5535 */
5536 boardp = ASC_BOARDP(shost);
5537 ASC_ASSERT(asc_dvc_varp == &boardp->dvc_var.asc_dvc_var);
5538 if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) {
5539 ASC_PRINT2
5540 ("asc_isr_callback: board %d: scp 0x%lx not on active queue\n",
5541 boardp->id, (ulong)scp);
5542 return;
5543 }
1da177e4 5544
27c868c2
MW
5545 /*
5546 * 'qdonep' contains the command's ending status.
5547 */
5548 switch (qdonep->d3.done_stat) {
5549 case QD_NO_ERROR:
5550 ASC_DBG(2, "asc_isr_callback: QD_NO_ERROR\n");
5551 scp->result = 0;
1da177e4 5552
27c868c2
MW
5553 /*
5554 * If an INQUIRY command completed successfully, then call
5555 * the AscInquiryHandling() function to set-up the device.
5556 */
5557 if (scp->cmnd[0] == INQUIRY && scp->device->lun == 0 &&
5558 (scp->request_bufflen - qdonep->remain_bytes) >= 8) {
5559 AscInquiryHandling(asc_dvc_varp, scp->device->id & 0x7,
5560 (ASC_SCSI_INQUIRY *)scp->
5561 request_buffer);
5562 }
1da177e4 5563
27c868c2
MW
5564 /*
5565 * Check for an underrun condition.
5566 *
5567 * If there was no error and an underrun condition, then
5568 * then return the number of underrun bytes.
5569 */
5570 if (scp->request_bufflen != 0 && qdonep->remain_bytes != 0 &&
5571 qdonep->remain_bytes <= scp->request_bufflen) {
5572 ASC_DBG1(1,
5573 "asc_isr_callback: underrun condition %u bytes\n",
5574 (unsigned)qdonep->remain_bytes);
5575 scp->resid = qdonep->remain_bytes;
5576 }
5577 break;
5578
5579 case QD_WITH_ERROR:
5580 ASC_DBG(2, "asc_isr_callback: QD_WITH_ERROR\n");
5581 switch (qdonep->d3.host_stat) {
5582 case QHSTA_NO_ERROR:
5583 if (qdonep->d3.scsi_stat == SAM_STAT_CHECK_CONDITION) {
5584 ASC_DBG(2,
5585 "asc_isr_callback: SAM_STAT_CHECK_CONDITION\n");
5586 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
5587 sizeof(scp->sense_buffer));
5588 /*
5589 * Note: The 'status_byte()' macro used by target drivers
5590 * defined in scsi.h shifts the status byte returned by
5591 * host drivers right by 1 bit. This is why target drivers
5592 * also use right shifted status byte definitions. For
5593 * instance target drivers use CHECK_CONDITION, defined to
5594 * 0x1, instead of the SCSI defined check condition value
5595 * of 0x2. Host drivers are supposed to return the status
5596 * byte as it is defined by SCSI.
5597 */
5598 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
5599 STATUS_BYTE(qdonep->d3.scsi_stat);
5600 } else {
5601 scp->result = STATUS_BYTE(qdonep->d3.scsi_stat);
5602 }
5603 break;
5604
5605 default:
5606 /* QHSTA error occurred */
5607 ASC_DBG1(1, "asc_isr_callback: host_stat 0x%x\n",
5608 qdonep->d3.host_stat);
5609 scp->result = HOST_BYTE(DID_BAD_TARGET);
5610 break;
5611 }
5612 break;
5613
5614 case QD_ABORTED_BY_HOST:
5615 ASC_DBG(1, "asc_isr_callback: QD_ABORTED_BY_HOST\n");
5616 scp->result =
5617 HOST_BYTE(DID_ABORT) | MSG_BYTE(qdonep->d3.
5618 scsi_msg) |
5619 STATUS_BYTE(qdonep->d3.scsi_stat);
5620 break;
5621
5622 default:
5623 ASC_DBG1(1, "asc_isr_callback: done_stat 0x%x\n",
5624 qdonep->d3.done_stat);
5625 scp->result =
5626 HOST_BYTE(DID_ERROR) | MSG_BYTE(qdonep->d3.
5627 scsi_msg) |
5628 STATUS_BYTE(qdonep->d3.scsi_stat);
5629 break;
5630 }
1da177e4 5631
27c868c2
MW
5632 /*
5633 * If the 'init_tidmask' bit isn't already set for the target and the
5634 * current request finished normally, then set the bit for the target
5635 * to indicate that a device is present.
5636 */
5637 if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
5638 qdonep->d3.done_stat == QD_NO_ERROR &&
5639 qdonep->d3.host_stat == QHSTA_NO_ERROR) {
5640 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
5641 }
1da177e4 5642
27c868c2
MW
5643 /*
5644 * Because interrupts may be enabled by the 'struct scsi_cmnd' done
5645 * function, add the command to the end of the board's done queue.
5646 * The done function for the command will be called from
5647 * advansys_interrupt().
5648 */
5649 asc_enqueue(&boardp->done, scp, ASC_BACK);
1da177e4 5650
27c868c2 5651 return;
1da177e4
LT
5652}
5653
5654/*
5655 * adv_isr_callback() - Second Level Interrupt Handler called by AdvISR().
5656 *
5657 * Callback function for the Wide SCSI Adv Library.
5658 */
27c868c2 5659static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp)
1da177e4 5660{
27c868c2
MW
5661 asc_board_t *boardp;
5662 adv_req_t *reqp;
5663 adv_sgblk_t *sgblkp;
5664 struct scsi_cmnd *scp;
5665 struct Scsi_Host *shost;
27c868c2
MW
5666 ADV_DCNT resid_cnt;
5667
5668 ASC_DBG2(1, "adv_isr_callback: adv_dvc_varp 0x%lx, scsiqp 0x%lx\n",
5669 (ulong)adv_dvc_varp, (ulong)scsiqp);
5670 ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
5671
5672 /*
5673 * Get the adv_req_t structure for the command that has been
5674 * completed. The adv_req_t structure actually contains the
5675 * completed ADV_SCSI_REQ_Q structure.
5676 */
5677 reqp = (adv_req_t *)ADV_U32_TO_VADDR(scsiqp->srb_ptr);
5678 ASC_DBG1(1, "adv_isr_callback: reqp 0x%lx\n", (ulong)reqp);
5679 if (reqp == NULL) {
5680 ASC_PRINT("adv_isr_callback: reqp is NULL\n");
5681 return;
5682 }
1da177e4 5683
27c868c2
MW
5684 /*
5685 * Get the struct scsi_cmnd structure and Scsi_Host structure for the
5686 * command that has been completed.
5687 *
5688 * Note: The adv_req_t request structure and adv_sgblk_t structure,
5689 * if any, are dropped, because a board structure pointer can not be
5690 * determined.
5691 */
5692 scp = reqp->cmndp;
5693 ASC_DBG1(1, "adv_isr_callback: scp 0x%lx\n", (ulong)scp);
5694 if (scp == NULL) {
5695 ASC_PRINT
5696 ("adv_isr_callback: scp is NULL; adv_req_t dropped.\n");
5697 return;
5698 }
5699 ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
5700
27c868c2 5701 shost = scp->device->host;
27c868c2
MW
5702 ASC_STATS(shost, callback);
5703 ASC_DBG1(1, "adv_isr_callback: shost 0x%lx\n", (ulong)shost);
5704
5705 /*
5706 * If the request isn't found on the active queue, it may have been
5707 * removed to handle a reset request. Display a message and return.
5708 *
5709 * Note: Because the structure may still be in use don't attempt
5710 * to free the adv_req_t and adv_sgblk_t, if any, structures.
5711 */
5712 boardp = ASC_BOARDP(shost);
5713 ASC_ASSERT(adv_dvc_varp == &boardp->dvc_var.adv_dvc_var);
5714 if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) {
5715 ASC_PRINT2
5716 ("adv_isr_callback: board %d: scp 0x%lx not on active queue\n",
5717 boardp->id, (ulong)scp);
5718 return;
5719 }
1da177e4 5720
27c868c2
MW
5721 /*
5722 * 'done_status' contains the command's ending status.
5723 */
5724 switch (scsiqp->done_status) {
5725 case QD_NO_ERROR:
5726 ASC_DBG(2, "adv_isr_callback: QD_NO_ERROR\n");
5727 scp->result = 0;
1da177e4 5728
27c868c2
MW
5729 /*
5730 * Check for an underrun condition.
5731 *
5732 * If there was no error and an underrun condition, then
5733 * then return the number of underrun bytes.
5734 */
5735 resid_cnt = le32_to_cpu(scsiqp->data_cnt);
5736 if (scp->request_bufflen != 0 && resid_cnt != 0 &&
5737 resid_cnt <= scp->request_bufflen) {
5738 ASC_DBG1(1,
5739 "adv_isr_callback: underrun condition %lu bytes\n",
5740 (ulong)resid_cnt);
5741 scp->resid = resid_cnt;
5742 }
5743 break;
5744
5745 case QD_WITH_ERROR:
5746 ASC_DBG(2, "adv_isr_callback: QD_WITH_ERROR\n");
5747 switch (scsiqp->host_status) {
5748 case QHSTA_NO_ERROR:
5749 if (scsiqp->scsi_status == SAM_STAT_CHECK_CONDITION) {
5750 ASC_DBG(2,
5751 "adv_isr_callback: SAM_STAT_CHECK_CONDITION\n");
5752 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
5753 sizeof(scp->sense_buffer));
5754 /*
5755 * Note: The 'status_byte()' macro used by target drivers
5756 * defined in scsi.h shifts the status byte returned by
5757 * host drivers right by 1 bit. This is why target drivers
5758 * also use right shifted status byte definitions. For
5759 * instance target drivers use CHECK_CONDITION, defined to
5760 * 0x1, instead of the SCSI defined check condition value
5761 * of 0x2. Host drivers are supposed to return the status
5762 * byte as it is defined by SCSI.
5763 */
5764 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
5765 STATUS_BYTE(scsiqp->scsi_status);
5766 } else {
5767 scp->result = STATUS_BYTE(scsiqp->scsi_status);
5768 }
5769 break;
5770
5771 default:
5772 /* Some other QHSTA error occurred. */
5773 ASC_DBG1(1, "adv_isr_callback: host_status 0x%x\n",
5774 scsiqp->host_status);
5775 scp->result = HOST_BYTE(DID_BAD_TARGET);
5776 break;
5777 }
5778 break;
5779
5780 case QD_ABORTED_BY_HOST:
5781 ASC_DBG(1, "adv_isr_callback: QD_ABORTED_BY_HOST\n");
5782 scp->result =
5783 HOST_BYTE(DID_ABORT) | STATUS_BYTE(scsiqp->scsi_status);
5784 break;
5785
5786 default:
5787 ASC_DBG1(1, "adv_isr_callback: done_status 0x%x\n",
5788 scsiqp->done_status);
5789 scp->result =
5790 HOST_BYTE(DID_ERROR) | STATUS_BYTE(scsiqp->scsi_status);
5791 break;
5792 }
1da177e4 5793
27c868c2
MW
5794 /*
5795 * If the 'init_tidmask' bit isn't already set for the target and the
5796 * current request finished normally, then set the bit for the target
5797 * to indicate that a device is present.
5798 */
5799 if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
5800 scsiqp->done_status == QD_NO_ERROR &&
5801 scsiqp->host_status == QHSTA_NO_ERROR) {
5802 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
5803 }
1da177e4 5804
27c868c2
MW
5805 /*
5806 * Because interrupts may be enabled by the 'struct scsi_cmnd' done
5807 * function, add the command to the end of the board's done queue.
5808 * The done function for the command will be called from
5809 * advansys_interrupt().
5810 */
5811 asc_enqueue(&boardp->done, scp, ASC_BACK);
5812
5813 /*
5814 * Free all 'adv_sgblk_t' structures allocated for the request.
5815 */
5816 while ((sgblkp = reqp->sgblkp) != NULL) {
5817 /* Remove 'sgblkp' from the request list. */
5818 reqp->sgblkp = sgblkp->next_sgblkp;
5819
5820 /* Add 'sgblkp' to the board free list. */
5821 sgblkp->next_sgblkp = boardp->adv_sgblkp;
5822 boardp->adv_sgblkp = sgblkp;
5823 }
1da177e4 5824
27c868c2
MW
5825 /*
5826 * Free the adv_req_t structure used with the command by adding
5827 * it back to the board free list.
5828 */
5829 reqp->next_reqp = boardp->adv_reqp;
5830 boardp->adv_reqp = reqp;
1da177e4 5831
27c868c2 5832 ASC_DBG(1, "adv_isr_callback: done\n");
1da177e4 5833
27c868c2 5834 return;
1da177e4
LT
5835}
5836
5837/*
5838 * adv_async_callback() - Adv Library asynchronous event callback function.
5839 */
27c868c2 5840static void adv_async_callback(ADV_DVC_VAR *adv_dvc_varp, uchar code)
1da177e4 5841{
27c868c2
MW
5842 switch (code) {
5843 case ADV_ASYNC_SCSI_BUS_RESET_DET:
5844 /*
5845 * The firmware detected a SCSI Bus reset.
5846 */
5847 ASC_DBG(0,
5848 "adv_async_callback: ADV_ASYNC_SCSI_BUS_RESET_DET\n");
5849 break;
5850
5851 case ADV_ASYNC_RDMA_FAILURE:
5852 /*
5853 * Handle RDMA failure by resetting the SCSI Bus and
5854 * possibly the chip if it is unresponsive. Log the error
5855 * with a unique code.
5856 */
5857 ASC_DBG(0, "adv_async_callback: ADV_ASYNC_RDMA_FAILURE\n");
5858 AdvResetChipAndSB(adv_dvc_varp);
5859 break;
5860
5861 case ADV_HOST_SCSI_BUS_RESET:
5862 /*
5863 * Host generated SCSI bus reset occurred.
5864 */
5865 ASC_DBG(0, "adv_async_callback: ADV_HOST_SCSI_BUS_RESET\n");
5866 break;
5867
5868 default:
5869 ASC_DBG1(0, "DvcAsyncCallBack: unknown code 0x%x\n", code);
5870 break;
5871 }
1da177e4
LT
5872}
5873
5874/*
5875 * Add a 'REQP' to the end of specified queue. Set 'tidmask'
5876 * to indicate a command is queued for the device.
5877 *
5878 * 'flag' may be either ASC_FRONT or ASC_BACK.
5879 *
5880 * 'REQPNEXT(reqp)' returns reqp's next pointer.
5881 */
27c868c2 5882static void asc_enqueue(asc_queue_t *ascq, REQP reqp, int flag)
1da177e4 5883{
27c868c2
MW
5884 int tid;
5885
5886 ASC_DBG3(3, "asc_enqueue: ascq 0x%lx, reqp 0x%lx, flag %d\n",
5887 (ulong)ascq, (ulong)reqp, flag);
5888 ASC_ASSERT(reqp != NULL);
5889 ASC_ASSERT(flag == ASC_FRONT || flag == ASC_BACK);
5890 tid = REQPTID(reqp);
5891 ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
5892 if (flag == ASC_FRONT) {
5893 reqp->host_scribble = (unsigned char *)ascq->q_first[tid];
5894 ascq->q_first[tid] = reqp;
5895 /* If the queue was empty, set the last pointer. */
5896 if (ascq->q_last[tid] == NULL) {
5897 ascq->q_last[tid] = reqp;
5898 }
5899 } else { /* ASC_BACK */
5900 if (ascq->q_last[tid] != NULL) {
5901 ascq->q_last[tid]->host_scribble =
5902 (unsigned char *)reqp;
5903 }
5904 ascq->q_last[tid] = reqp;
5905 reqp->host_scribble = NULL;
5906 /* If the queue was empty, set the first pointer. */
5907 if (ascq->q_first[tid] == NULL) {
5908 ascq->q_first[tid] = reqp;
5909 }
5910 }
5911 /* The queue has at least one entry, set its bit. */
5912 ascq->q_tidmask |= ADV_TID_TO_TIDMASK(tid);
1da177e4 5913#ifdef ADVANSYS_STATS
27c868c2
MW
5914 /* Maintain request queue statistics. */
5915 ascq->q_tot_cnt[tid]++;
5916 ascq->q_cur_cnt[tid]++;
5917 if (ascq->q_cur_cnt[tid] > ascq->q_max_cnt[tid]) {
5918 ascq->q_max_cnt[tid] = ascq->q_cur_cnt[tid];
5919 ASC_DBG2(2, "asc_enqueue: new q_max_cnt[%d] %d\n",
5920 tid, ascq->q_max_cnt[tid]);
5921 }
5922 REQPTIME(reqp) = REQTIMESTAMP();
1da177e4 5923#endif /* ADVANSYS_STATS */
27c868c2
MW
5924 ASC_DBG1(3, "asc_enqueue: reqp 0x%lx\n", (ulong)reqp);
5925 return;
1da177e4
LT
5926}
5927
5928/*
5929 * Return first queued 'REQP' on the specified queue for
5930 * the specified target device. Clear the 'tidmask' bit for
5931 * the device if no more commands are left queued for it.
5932 *
5933 * 'REQPNEXT(reqp)' returns reqp's next pointer.
5934 */
27c868c2 5935static REQP asc_dequeue(asc_queue_t *ascq, int tid)
1da177e4 5936{
27c868c2
MW
5937 REQP reqp;
5938
5939 ASC_DBG2(3, "asc_dequeue: ascq 0x%lx, tid %d\n", (ulong)ascq, tid);
5940 ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
5941 if ((reqp = ascq->q_first[tid]) != NULL) {
5942 ASC_ASSERT(ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid));
5943 ascq->q_first[tid] = REQPNEXT(reqp);
5944 /* If the queue is empty, clear its bit and the last pointer. */
5945 if (ascq->q_first[tid] == NULL) {
5946 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
5947 ASC_ASSERT(ascq->q_last[tid] == reqp);
5948 ascq->q_last[tid] = NULL;
5949 }
1da177e4 5950#ifdef ADVANSYS_STATS
27c868c2
MW
5951 /* Maintain request queue statistics. */
5952 ascq->q_cur_cnt[tid]--;
5953 ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0);
5954 REQTIMESTAT("asc_dequeue", ascq, reqp, tid);
1da177e4 5955#endif /* ADVANSYS_STATS */
27c868c2
MW
5956 }
5957 ASC_DBG1(3, "asc_dequeue: reqp 0x%lx\n", (ulong)reqp);
5958 return reqp;
1da177e4
LT
5959}
5960
5961/*
5962 * Return a pointer to a singly linked list of all the requests queued
5963 * for 'tid' on the 'asc_queue_t' pointed to by 'ascq'.
5964 *
5965 * If 'lastpp' is not NULL, '*lastpp' will be set to point to the
5966 * the last request returned in the singly linked list.
5967 *
5968 * 'tid' should either be a valid target id or if it is ASC_TID_ALL,
5969 * then all queued requests are concatenated into one list and
5970 * returned.
5971 *
5972 * Note: If 'lastpp' is used to append a new list to the end of
5973 * an old list, only change the old list last pointer if '*lastpp'
5974 * (or the function return value) is not NULL, i.e. use a temporary
5975 * variable for 'lastpp' and check its value after the function return
5976 * before assigning it to the list last pointer.
5977 *
5978 * Unfortunately collecting queuing time statistics adds overhead to
5979 * the function that isn't inherent to the function's algorithm.
5980 */
27c868c2 5981static REQP asc_dequeue_list(asc_queue_t *ascq, REQP *lastpp, int tid)
1da177e4 5982{
27c868c2
MW
5983 REQP firstp, lastp;
5984 int i;
5985
5986 ASC_DBG2(3, "asc_dequeue_list: ascq 0x%lx, tid %d\n", (ulong)ascq, tid);
5987 ASC_ASSERT((tid == ASC_TID_ALL) || (tid >= 0 && tid <= ADV_MAX_TID));
5988
5989 /*
5990 * If 'tid' is not ASC_TID_ALL, return requests only for
5991 * the specified 'tid'. If 'tid' is ASC_TID_ALL, return all
5992 * requests for all tids.
5993 */
5994 if (tid != ASC_TID_ALL) {
5995 /* Return all requests for the specified 'tid'. */
5996 if ((ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid)) == 0) {
5997 /* List is empty; Set first and last return pointers to NULL. */
5998 firstp = lastp = NULL;
5999 } else {
6000 firstp = ascq->q_first[tid];
6001 lastp = ascq->q_last[tid];
6002 ascq->q_first[tid] = ascq->q_last[tid] = NULL;
6003 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
1da177e4 6004#ifdef ADVANSYS_STATS
27c868c2
MW
6005 {
6006 REQP reqp;
6007 ascq->q_cur_cnt[tid] = 0;
6008 for (reqp = firstp; reqp; reqp = REQPNEXT(reqp)) {
6009 REQTIMESTAT("asc_dequeue_list", ascq,
6010 reqp, tid);
6011 }
6012 }
1da177e4 6013#endif /* ADVANSYS_STATS */
27c868c2
MW
6014 }
6015 } else {
6016 /* Return all requests for all tids. */
6017 firstp = lastp = NULL;
6018 for (i = 0; i <= ADV_MAX_TID; i++) {
6019 if (ascq->q_tidmask & ADV_TID_TO_TIDMASK(i)) {
6020 if (firstp == NULL) {
6021 firstp = ascq->q_first[i];
6022 lastp = ascq->q_last[i];
6023 } else {
6024 ASC_ASSERT(lastp != NULL);
6025 lastp->host_scribble =
6026 (unsigned char *)ascq->q_first[i];
6027 lastp = ascq->q_last[i];
6028 }
6029 ascq->q_first[i] = ascq->q_last[i] = NULL;
6030 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(i);
1da177e4 6031#ifdef ADVANSYS_STATS
27c868c2 6032 ascq->q_cur_cnt[i] = 0;
1da177e4 6033#endif /* ADVANSYS_STATS */
27c868c2
MW
6034 }
6035 }
1da177e4 6036#ifdef ADVANSYS_STATS
27c868c2
MW
6037 {
6038 REQP reqp;
6039 for (reqp = firstp; reqp; reqp = REQPNEXT(reqp)) {
6040 REQTIMESTAT("asc_dequeue_list", ascq, reqp,
6041 reqp->device->id);
6042 }
6043 }
1da177e4 6044#endif /* ADVANSYS_STATS */
27c868c2
MW
6045 }
6046 if (lastpp) {
6047 *lastpp = lastp;
6048 }
6049 ASC_DBG1(3, "asc_dequeue_list: firstp 0x%lx\n", (ulong)firstp);
6050 return firstp;
1da177e4
LT
6051}
6052
6053/*
6054 * Remove the specified 'REQP' from the specified queue for
6055 * the specified target device. Clear the 'tidmask' bit for the
6056 * device if no more commands are left queued for it.
6057 *
6058 * 'REQPNEXT(reqp)' returns reqp's the next pointer.
6059 *
6060 * Return ASC_TRUE if the command was found and removed,
6061 * otherwise return ASC_FALSE.
6062 */
27c868c2 6063static int asc_rmqueue(asc_queue_t *ascq, REQP reqp)
1da177e4 6064{
27c868c2
MW
6065 REQP currp, prevp;
6066 int tid;
6067 int ret = ASC_FALSE;
6068
6069 ASC_DBG2(3, "asc_rmqueue: ascq 0x%lx, reqp 0x%lx\n",
6070 (ulong)ascq, (ulong)reqp);
6071 ASC_ASSERT(reqp != NULL);
6072
6073 tid = REQPTID(reqp);
6074 ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
6075
6076 /*
6077 * Handle the common case of 'reqp' being the first
6078 * entry on the queue.
6079 */
6080 if (reqp == ascq->q_first[tid]) {
6081 ret = ASC_TRUE;
6082 ascq->q_first[tid] = REQPNEXT(reqp);
6083 /* If the queue is now empty, clear its bit and the last pointer. */
6084 if (ascq->q_first[tid] == NULL) {
6085 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
6086 ASC_ASSERT(ascq->q_last[tid] == reqp);
6087 ascq->q_last[tid] = NULL;
6088 }
6089 } else if (ascq->q_first[tid] != NULL) {
6090 ASC_ASSERT(ascq->q_last[tid] != NULL);
6091 /*
6092 * Because the case of 'reqp' being the first entry has been
6093 * handled above and it is known the queue is not empty, if
6094 * 'reqp' is found on the queue it is guaranteed the queue will
6095 * not become empty and that 'q_first[tid]' will not be changed.
6096 *
6097 * Set 'prevp' to the first entry, 'currp' to the second entry,
6098 * and search for 'reqp'.
6099 */
6100 for (prevp = ascq->q_first[tid], currp = REQPNEXT(prevp);
6101 currp; prevp = currp, currp = REQPNEXT(currp)) {
6102 if (currp == reqp) {
6103 ret = ASC_TRUE;
6104 prevp->host_scribble =
6105 (unsigned char *)REQPNEXT(currp);
6106 reqp->host_scribble = NULL;
6107 if (ascq->q_last[tid] == reqp) {
6108 ascq->q_last[tid] = prevp;
6109 }
6110 break;
6111 }
6112 }
6113 }
1da177e4 6114#ifdef ADVANSYS_STATS
27c868c2
MW
6115 /* Maintain request queue statistics. */
6116 if (ret == ASC_TRUE) {
6117 ascq->q_cur_cnt[tid]--;
6118 REQTIMESTAT("asc_rmqueue", ascq, reqp, tid);
6119 }
6120 ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0);
1da177e4 6121#endif /* ADVANSYS_STATS */
27c868c2
MW
6122 ASC_DBG2(3, "asc_rmqueue: reqp 0x%lx, ret %d\n", (ulong)reqp, ret);
6123 return ret;
1da177e4
LT
6124}
6125
6126/*
6127 * Execute as many queued requests as possible for the specified queue.
6128 *
6129 * Calls asc_execute_scsi_cmnd() to execute a REQP/struct scsi_cmnd.
6130 */
27c868c2 6131static void asc_execute_queue(asc_queue_t *ascq)
1da177e4 6132{
27c868c2
MW
6133 ADV_SCSI_BIT_ID_TYPE scan_tidmask;
6134 REQP reqp;
6135 int i;
6136
6137 ASC_DBG1(1, "asc_execute_queue: ascq 0x%lx\n", (ulong)ascq);
6138 /*
6139 * Execute queued commands for devices attached to
6140 * the current board in round-robin fashion.
6141 */
6142 scan_tidmask = ascq->q_tidmask;
6143 do {
6144 for (i = 0; i <= ADV_MAX_TID; i++) {
6145 if (scan_tidmask & ADV_TID_TO_TIDMASK(i)) {
6146 if ((reqp = asc_dequeue(ascq, i)) == NULL) {
6147 scan_tidmask &= ~ADV_TID_TO_TIDMASK(i);
6148 } else
6149 if (asc_execute_scsi_cmnd
6150 ((struct scsi_cmnd *)reqp)
6151 == ASC_BUSY) {
6152 scan_tidmask &= ~ADV_TID_TO_TIDMASK(i);
6153 /*
6154 * The request returned ASC_BUSY. Enqueue at the front of
6155 * target's waiting list to maintain correct ordering.
6156 */
6157 asc_enqueue(ascq, reqp, ASC_FRONT);
6158 }
6159 }
6160 }
6161 } while (scan_tidmask);
6162 return;
1da177e4
LT
6163}
6164
6165#ifdef CONFIG_PROC_FS
6166/*
6167 * asc_prt_board_devices()
6168 *
6169 * Print driver information for devices attached to the board.
6170 *
6171 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6172 * cf. asc_prt_line().
6173 *
6174 * Return the number of characters copied into 'cp'. No more than
6175 * 'cplen' characters will be copied to 'cp'.
6176 */
27c868c2 6177static int asc_prt_board_devices(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 6178{
27c868c2
MW
6179 asc_board_t *boardp;
6180 int leftlen;
6181 int totlen;
6182 int len;
6183 int chip_scsi_id;
6184 int i;
6185
6186 boardp = ASC_BOARDP(shost);
6187 leftlen = cplen;
6188 totlen = len = 0;
6189
6190 len = asc_prt_line(cp, leftlen,
6191 "\nDevice Information for AdvanSys SCSI Host %d:\n",
6192 shost->host_no);
6193 ASC_PRT_NEXT();
6194
6195 if (ASC_NARROW_BOARD(boardp)) {
6196 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
6197 } else {
6198 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
6199 }
1da177e4 6200
27c868c2
MW
6201 len = asc_prt_line(cp, leftlen, "Target IDs Detected:");
6202 ASC_PRT_NEXT();
6203 for (i = 0; i <= ADV_MAX_TID; i++) {
6204 if (boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) {
6205 len = asc_prt_line(cp, leftlen, " %X,", i);
6206 ASC_PRT_NEXT();
6207 }
6208 }
6209 len = asc_prt_line(cp, leftlen, " (%X=Host Adapter)\n", chip_scsi_id);
6210 ASC_PRT_NEXT();
1da177e4 6211
27c868c2 6212 return totlen;
1da177e4
LT
6213}
6214
6215/*
6216 * Display Wide Board BIOS Information.
6217 */
27c868c2 6218static int asc_prt_adv_bios(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 6219{
27c868c2
MW
6220 asc_board_t *boardp;
6221 int leftlen;
6222 int totlen;
6223 int len;
6224 ushort major, minor, letter;
6225
6226 boardp = ASC_BOARDP(shost);
6227 leftlen = cplen;
6228 totlen = len = 0;
6229
6230 len = asc_prt_line(cp, leftlen, "\nROM BIOS Version: ");
6231 ASC_PRT_NEXT();
6232
6233 /*
6234 * If the BIOS saved a valid signature, then fill in
6235 * the BIOS code segment base address.
6236 */
6237 if (boardp->bios_signature != 0x55AA) {
6238 len = asc_prt_line(cp, leftlen, "Disabled or Pre-3.1\n");
6239 ASC_PRT_NEXT();
6240 len = asc_prt_line(cp, leftlen,
6241 "BIOS either disabled or Pre-3.1. If it is pre-3.1, then a newer version\n");
6242 ASC_PRT_NEXT();
6243 len = asc_prt_line(cp, leftlen,
6244 "can be found at the ConnectCom FTP site: ftp://ftp.connectcom.net/pub\n");
6245 ASC_PRT_NEXT();
6246 } else {
6247 major = (boardp->bios_version >> 12) & 0xF;
6248 minor = (boardp->bios_version >> 8) & 0xF;
6249 letter = (boardp->bios_version & 0xFF);
1da177e4 6250
27c868c2
MW
6251 len = asc_prt_line(cp, leftlen, "%d.%d%c\n",
6252 major, minor,
6253 letter >= 26 ? '?' : letter + 'A');
6254 ASC_PRT_NEXT();
1da177e4 6255
27c868c2
MW
6256 /*
6257 * Current available ROM BIOS release is 3.1I for UW
6258 * and 3.2I for U2W. This code doesn't differentiate
6259 * UW and U2W boards.
6260 */
6261 if (major < 3 || (major <= 3 && minor < 1) ||
6262 (major <= 3 && minor <= 1 && letter < ('I' - 'A'))) {
6263 len = asc_prt_line(cp, leftlen,
6264 "Newer version of ROM BIOS is available at the ConnectCom FTP site:\n");
6265 ASC_PRT_NEXT();
6266 len = asc_prt_line(cp, leftlen,
6267 "ftp://ftp.connectcom.net/pub\n");
6268 ASC_PRT_NEXT();
6269 }
6270 }
1da177e4 6271
27c868c2 6272 return totlen;
1da177e4
LT
6273}
6274
6275/*
6276 * Add serial number to information bar if signature AAh
6277 * is found in at bit 15-9 (7 bits) of word 1.
6278 *
6279 * Serial Number consists fo 12 alpha-numeric digits.
6280 *
6281 * 1 - Product type (A,B,C,D..) Word0: 15-13 (3 bits)
6282 * 2 - MFG Location (A,B,C,D..) Word0: 12-10 (3 bits)
6283 * 3-4 - Product ID (0-99) Word0: 9-0 (10 bits)
6284 * 5 - Product revision (A-J) Word0: " "
6285 *
6286 * Signature Word1: 15-9 (7 bits)
6287 * 6 - Year (0-9) Word1: 8-6 (3 bits) & Word2: 15 (1 bit)
6288 * 7-8 - Week of the year (1-52) Word1: 5-0 (6 bits)
6289 *
6290 * 9-12 - Serial Number (A001-Z999) Word2: 14-0 (15 bits)
6291 *
6292 * Note 1: Only production cards will have a serial number.
6293 *
6294 * Note 2: Signature is most significant 7 bits (0xFE).
6295 *
6296 * Returns ASC_TRUE if serial number found, otherwise returns ASC_FALSE.
6297 */
27c868c2 6298static int asc_get_eeprom_string(ushort *serialnum, uchar *cp)
1da177e4 6299{
27c868c2
MW
6300 ushort w, num;
6301
6302 if ((serialnum[1] & 0xFE00) != ((ushort)0xAA << 8)) {
6303 return ASC_FALSE;
6304 } else {
6305 /*
6306 * First word - 6 digits.
6307 */
6308 w = serialnum[0];
6309
6310 /* Product type - 1st digit. */
6311 if ((*cp = 'A' + ((w & 0xE000) >> 13)) == 'H') {
6312 /* Product type is P=Prototype */
6313 *cp += 0x8;
6314 }
6315 cp++;
6316
6317 /* Manufacturing location - 2nd digit. */
6318 *cp++ = 'A' + ((w & 0x1C00) >> 10);
6319
6320 /* Product ID - 3rd, 4th digits. */
6321 num = w & 0x3FF;
6322 *cp++ = '0' + (num / 100);
6323 num %= 100;
6324 *cp++ = '0' + (num / 10);
6325
6326 /* Product revision - 5th digit. */
6327 *cp++ = 'A' + (num % 10);
6328
6329 /*
6330 * Second word
6331 */
6332 w = serialnum[1];
6333
6334 /*
6335 * Year - 6th digit.
6336 *
6337 * If bit 15 of third word is set, then the
6338 * last digit of the year is greater than 7.
6339 */
6340 if (serialnum[2] & 0x8000) {
6341 *cp++ = '8' + ((w & 0x1C0) >> 6);
6342 } else {
6343 *cp++ = '0' + ((w & 0x1C0) >> 6);
6344 }
6345
6346 /* Week of year - 7th, 8th digits. */
6347 num = w & 0x003F;
6348 *cp++ = '0' + num / 10;
6349 num %= 10;
6350 *cp++ = '0' + num;
6351
6352 /*
6353 * Third word
6354 */
6355 w = serialnum[2] & 0x7FFF;
6356
6357 /* Serial number - 9th digit. */
6358 *cp++ = 'A' + (w / 1000);
6359
6360 /* 10th, 11th, 12th digits. */
6361 num = w % 1000;
6362 *cp++ = '0' + num / 100;
6363 num %= 100;
6364 *cp++ = '0' + num / 10;
6365 num %= 10;
6366 *cp++ = '0' + num;
6367
6368 *cp = '\0'; /* Null Terminate the string. */
6369 return ASC_TRUE;
6370 }
1da177e4
LT
6371}
6372
6373/*
6374 * asc_prt_asc_board_eeprom()
6375 *
6376 * Print board EEPROM configuration.
6377 *
6378 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6379 * cf. asc_prt_line().
6380 *
6381 * Return the number of characters copied into 'cp'. No more than
6382 * 'cplen' characters will be copied to 'cp'.
6383 */
27c868c2 6384static int asc_prt_asc_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 6385{
27c868c2
MW
6386 asc_board_t *boardp;
6387 ASC_DVC_VAR *asc_dvc_varp;
6388 int leftlen;
6389 int totlen;
6390 int len;
6391 ASCEEP_CONFIG *ep;
6392 int i;
1da177e4 6393#ifdef CONFIG_ISA
27c868c2 6394 int isa_dma_speed[] = { 10, 8, 7, 6, 5, 4, 3, 2 };
1da177e4 6395#endif /* CONFIG_ISA */
27c868c2
MW
6396 uchar serialstr[13];
6397
6398 boardp = ASC_BOARDP(shost);
6399 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
6400 ep = &boardp->eep_config.asc_eep;
6401
6402 leftlen = cplen;
6403 totlen = len = 0;
6404
6405 len = asc_prt_line(cp, leftlen,
6406 "\nEEPROM Settings for AdvanSys SCSI Host %d:\n",
6407 shost->host_no);
6408 ASC_PRT_NEXT();
6409
6410 if (asc_get_eeprom_string((ushort *)&ep->adapter_info[0], serialstr)
6411 == ASC_TRUE) {
6412 len =
6413 asc_prt_line(cp, leftlen, " Serial Number: %s\n",
6414 serialstr);
6415 ASC_PRT_NEXT();
6416 } else {
6417 if (ep->adapter_info[5] == 0xBB) {
6418 len = asc_prt_line(cp, leftlen,
6419 " Default Settings Used for EEPROM-less Adapter.\n");
6420 ASC_PRT_NEXT();
6421 } else {
6422 len = asc_prt_line(cp, leftlen,
6423 " Serial Number Signature Not Present.\n");
6424 ASC_PRT_NEXT();
6425 }
6426 }
1da177e4 6427
27c868c2
MW
6428 len = asc_prt_line(cp, leftlen,
6429 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
6430 ASC_EEP_GET_CHIP_ID(ep), ep->max_total_qng,
6431 ep->max_tag_qng);
6432 ASC_PRT_NEXT();
6433
6434 len = asc_prt_line(cp, leftlen,
6435 " cntl 0x%x, no_scam 0x%x\n", ep->cntl, ep->no_scam);
6436 ASC_PRT_NEXT();
6437
6438 len = asc_prt_line(cp, leftlen, " Target ID: ");
6439 ASC_PRT_NEXT();
6440 for (i = 0; i <= ASC_MAX_TID; i++) {
6441 len = asc_prt_line(cp, leftlen, " %d", i);
6442 ASC_PRT_NEXT();
6443 }
6444 len = asc_prt_line(cp, leftlen, "\n");
6445 ASC_PRT_NEXT();
6446
6447 len = asc_prt_line(cp, leftlen, " Disconnects: ");
6448 ASC_PRT_NEXT();
6449 for (i = 0; i <= ASC_MAX_TID; i++) {
6450 len = asc_prt_line(cp, leftlen, " %c",
6451 (ep->
6452 disc_enable & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6453 'N');
6454 ASC_PRT_NEXT();
6455 }
6456 len = asc_prt_line(cp, leftlen, "\n");
6457 ASC_PRT_NEXT();
6458
6459 len = asc_prt_line(cp, leftlen, " Command Queuing: ");
6460 ASC_PRT_NEXT();
6461 for (i = 0; i <= ASC_MAX_TID; i++) {
6462 len = asc_prt_line(cp, leftlen, " %c",
6463 (ep->
6464 use_cmd_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6465 'N');
6466 ASC_PRT_NEXT();
6467 }
6468 len = asc_prt_line(cp, leftlen, "\n");
6469 ASC_PRT_NEXT();
6470
6471 len = asc_prt_line(cp, leftlen, " Start Motor: ");
6472 ASC_PRT_NEXT();
6473 for (i = 0; i <= ASC_MAX_TID; i++) {
6474 len = asc_prt_line(cp, leftlen, " %c",
6475 (ep->
6476 start_motor & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6477 'N');
6478 ASC_PRT_NEXT();
6479 }
6480 len = asc_prt_line(cp, leftlen, "\n");
6481 ASC_PRT_NEXT();
6482
6483 len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
6484 ASC_PRT_NEXT();
6485 for (i = 0; i <= ASC_MAX_TID; i++) {
6486 len = asc_prt_line(cp, leftlen, " %c",
6487 (ep->
6488 init_sdtr & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6489 'N');
6490 ASC_PRT_NEXT();
6491 }
6492 len = asc_prt_line(cp, leftlen, "\n");
6493 ASC_PRT_NEXT();
1da177e4
LT
6494
6495#ifdef CONFIG_ISA
27c868c2
MW
6496 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
6497 len = asc_prt_line(cp, leftlen,
6498 " Host ISA DMA speed: %d MB/S\n",
6499 isa_dma_speed[ASC_EEP_GET_DMA_SPD(ep)]);
6500 ASC_PRT_NEXT();
6501 }
1da177e4
LT
6502#endif /* CONFIG_ISA */
6503
27c868c2 6504 return totlen;
1da177e4
LT
6505}
6506
6507/*
6508 * asc_prt_adv_board_eeprom()
6509 *
6510 * Print board EEPROM configuration.
6511 *
6512 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6513 * cf. asc_prt_line().
6514 *
6515 * Return the number of characters copied into 'cp'. No more than
6516 * 'cplen' characters will be copied to 'cp'.
6517 */
27c868c2 6518static int asc_prt_adv_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 6519{
27c868c2
MW
6520 asc_board_t *boardp;
6521 ADV_DVC_VAR *adv_dvc_varp;
6522 int leftlen;
6523 int totlen;
6524 int len;
6525 int i;
6526 char *termstr;
6527 uchar serialstr[13];
6528 ADVEEP_3550_CONFIG *ep_3550 = NULL;
6529 ADVEEP_38C0800_CONFIG *ep_38C0800 = NULL;
6530 ADVEEP_38C1600_CONFIG *ep_38C1600 = NULL;
6531 ushort word;
6532 ushort *wordp;
6533 ushort sdtr_speed = 0;
6534
6535 boardp = ASC_BOARDP(shost);
6536 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
6537 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6538 ep_3550 = &boardp->eep_config.adv_3550_eep;
6539 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6540 ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
6541 } else {
6542 ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
6543 }
1da177e4 6544
27c868c2
MW
6545 leftlen = cplen;
6546 totlen = len = 0;
1da177e4 6547
27c868c2
MW
6548 len = asc_prt_line(cp, leftlen,
6549 "\nEEPROM Settings for AdvanSys SCSI Host %d:\n",
6550 shost->host_no);
6551 ASC_PRT_NEXT();
1da177e4 6552
27c868c2
MW
6553 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6554 wordp = &ep_3550->serial_number_word1;
6555 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6556 wordp = &ep_38C0800->serial_number_word1;
6557 } else {
6558 wordp = &ep_38C1600->serial_number_word1;
6559 }
1da177e4 6560
27c868c2
MW
6561 if (asc_get_eeprom_string(wordp, serialstr) == ASC_TRUE) {
6562 len =
6563 asc_prt_line(cp, leftlen, " Serial Number: %s\n",
6564 serialstr);
6565 ASC_PRT_NEXT();
6566 } else {
6567 len = asc_prt_line(cp, leftlen,
6568 " Serial Number Signature Not Present.\n");
6569 ASC_PRT_NEXT();
6570 }
1da177e4 6571
27c868c2
MW
6572 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6573 len = asc_prt_line(cp, leftlen,
6574 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
6575 ep_3550->adapter_scsi_id,
6576 ep_3550->max_host_qng, ep_3550->max_dvc_qng);
6577 ASC_PRT_NEXT();
6578 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6579 len = asc_prt_line(cp, leftlen,
6580 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
6581 ep_38C0800->adapter_scsi_id,
6582 ep_38C0800->max_host_qng,
6583 ep_38C0800->max_dvc_qng);
6584 ASC_PRT_NEXT();
6585 } else {
6586 len = asc_prt_line(cp, leftlen,
6587 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
6588 ep_38C1600->adapter_scsi_id,
6589 ep_38C1600->max_host_qng,
6590 ep_38C1600->max_dvc_qng);
6591 ASC_PRT_NEXT();
6592 }
6593 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6594 word = ep_3550->termination;
6595 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6596 word = ep_38C0800->termination_lvd;
6597 } else {
6598 word = ep_38C1600->termination_lvd;
6599 }
6600 switch (word) {
6601 case 1:
6602 termstr = "Low Off/High Off";
6603 break;
6604 case 2:
6605 termstr = "Low Off/High On";
6606 break;
6607 case 3:
6608 termstr = "Low On/High On";
6609 break;
6610 default:
6611 case 0:
6612 termstr = "Automatic";
6613 break;
6614 }
1da177e4 6615
27c868c2
MW
6616 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6617 len = asc_prt_line(cp, leftlen,
6618 " termination: %u (%s), bios_ctrl: 0x%x\n",
6619 ep_3550->termination, termstr,
6620 ep_3550->bios_ctrl);
6621 ASC_PRT_NEXT();
6622 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6623 len = asc_prt_line(cp, leftlen,
6624 " termination: %u (%s), bios_ctrl: 0x%x\n",
6625 ep_38C0800->termination_lvd, termstr,
6626 ep_38C0800->bios_ctrl);
6627 ASC_PRT_NEXT();
6628 } else {
6629 len = asc_prt_line(cp, leftlen,
6630 " termination: %u (%s), bios_ctrl: 0x%x\n",
6631 ep_38C1600->termination_lvd, termstr,
6632 ep_38C1600->bios_ctrl);
6633 ASC_PRT_NEXT();
6634 }
1da177e4 6635
27c868c2
MW
6636 len = asc_prt_line(cp, leftlen, " Target ID: ");
6637 ASC_PRT_NEXT();
6638 for (i = 0; i <= ADV_MAX_TID; i++) {
6639 len = asc_prt_line(cp, leftlen, " %X", i);
6640 ASC_PRT_NEXT();
6641 }
6642 len = asc_prt_line(cp, leftlen, "\n");
6643 ASC_PRT_NEXT();
1da177e4 6644
27c868c2
MW
6645 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6646 word = ep_3550->disc_enable;
6647 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6648 word = ep_38C0800->disc_enable;
6649 } else {
6650 word = ep_38C1600->disc_enable;
6651 }
6652 len = asc_prt_line(cp, leftlen, " Disconnects: ");
6653 ASC_PRT_NEXT();
6654 for (i = 0; i <= ADV_MAX_TID; i++) {
6655 len = asc_prt_line(cp, leftlen, " %c",
6656 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
6657 ASC_PRT_NEXT();
6658 }
6659 len = asc_prt_line(cp, leftlen, "\n");
6660 ASC_PRT_NEXT();
1da177e4 6661
27c868c2
MW
6662 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6663 word = ep_3550->tagqng_able;
6664 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6665 word = ep_38C0800->tagqng_able;
6666 } else {
6667 word = ep_38C1600->tagqng_able;
6668 }
6669 len = asc_prt_line(cp, leftlen, " Command Queuing: ");
6670 ASC_PRT_NEXT();
6671 for (i = 0; i <= ADV_MAX_TID; i++) {
6672 len = asc_prt_line(cp, leftlen, " %c",
6673 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
6674 ASC_PRT_NEXT();
6675 }
6676 len = asc_prt_line(cp, leftlen, "\n");
6677 ASC_PRT_NEXT();
6678
6679 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6680 word = ep_3550->start_motor;
6681 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6682 word = ep_38C0800->start_motor;
6683 } else {
6684 word = ep_38C1600->start_motor;
6685 }
6686 len = asc_prt_line(cp, leftlen, " Start Motor: ");
6687 ASC_PRT_NEXT();
6688 for (i = 0; i <= ADV_MAX_TID; i++) {
6689 len = asc_prt_line(cp, leftlen, " %c",
6690 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
6691 ASC_PRT_NEXT();
6692 }
6693 len = asc_prt_line(cp, leftlen, "\n");
6694 ASC_PRT_NEXT();
6695
6696 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6697 len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
6698 ASC_PRT_NEXT();
6699 for (i = 0; i <= ADV_MAX_TID; i++) {
6700 len = asc_prt_line(cp, leftlen, " %c",
6701 (ep_3550->
6702 sdtr_able & ADV_TID_TO_TIDMASK(i)) ?
6703 'Y' : 'N');
6704 ASC_PRT_NEXT();
6705 }
6706 len = asc_prt_line(cp, leftlen, "\n");
6707 ASC_PRT_NEXT();
6708 }
6709
6710 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6711 len = asc_prt_line(cp, leftlen, " Ultra Transfer: ");
6712 ASC_PRT_NEXT();
6713 for (i = 0; i <= ADV_MAX_TID; i++) {
6714 len = asc_prt_line(cp, leftlen, " %c",
6715 (ep_3550->
6716 ultra_able & ADV_TID_TO_TIDMASK(i))
6717 ? 'Y' : 'N');
6718 ASC_PRT_NEXT();
6719 }
6720 len = asc_prt_line(cp, leftlen, "\n");
6721 ASC_PRT_NEXT();
6722 }
6723
6724 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6725 word = ep_3550->wdtr_able;
6726 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6727 word = ep_38C0800->wdtr_able;
6728 } else {
6729 word = ep_38C1600->wdtr_able;
6730 }
6731 len = asc_prt_line(cp, leftlen, " Wide Transfer: ");
6732 ASC_PRT_NEXT();
6733 for (i = 0; i <= ADV_MAX_TID; i++) {
6734 len = asc_prt_line(cp, leftlen, " %c",
6735 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
6736 ASC_PRT_NEXT();
6737 }
6738 len = asc_prt_line(cp, leftlen, "\n");
6739 ASC_PRT_NEXT();
6740
6741 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800 ||
6742 adv_dvc_varp->chip_type == ADV_CHIP_ASC38C1600) {
6743 len = asc_prt_line(cp, leftlen,
6744 " Synchronous Transfer Speed (Mhz):\n ");
6745 ASC_PRT_NEXT();
6746 for (i = 0; i <= ADV_MAX_TID; i++) {
6747 char *speed_str;
6748
6749 if (i == 0) {
6750 sdtr_speed = adv_dvc_varp->sdtr_speed1;
6751 } else if (i == 4) {
6752 sdtr_speed = adv_dvc_varp->sdtr_speed2;
6753 } else if (i == 8) {
6754 sdtr_speed = adv_dvc_varp->sdtr_speed3;
6755 } else if (i == 12) {
6756 sdtr_speed = adv_dvc_varp->sdtr_speed4;
6757 }
6758 switch (sdtr_speed & ADV_MAX_TID) {
6759 case 0:
6760 speed_str = "Off";
6761 break;
6762 case 1:
6763 speed_str = " 5";
6764 break;
6765 case 2:
6766 speed_str = " 10";
6767 break;
6768 case 3:
6769 speed_str = " 20";
6770 break;
6771 case 4:
6772 speed_str = " 40";
6773 break;
6774 case 5:
6775 speed_str = " 80";
6776 break;
6777 default:
6778 speed_str = "Unk";
6779 break;
6780 }
6781 len = asc_prt_line(cp, leftlen, "%X:%s ", i, speed_str);
6782 ASC_PRT_NEXT();
6783 if (i == 7) {
6784 len = asc_prt_line(cp, leftlen, "\n ");
6785 ASC_PRT_NEXT();
6786 }
6787 sdtr_speed >>= 4;
6788 }
6789 len = asc_prt_line(cp, leftlen, "\n");
6790 ASC_PRT_NEXT();
6791 }
6792
6793 return totlen;
6794}
6795
6796/*
6797 * asc_prt_driver_conf()
6798 *
6799 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6800 * cf. asc_prt_line().
1da177e4
LT
6801 *
6802 * Return the number of characters copied into 'cp'. No more than
6803 * 'cplen' characters will be copied to 'cp'.
6804 */
27c868c2 6805static int asc_prt_driver_conf(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 6806{
27c868c2
MW
6807 asc_board_t *boardp;
6808 int leftlen;
6809 int totlen;
6810 int len;
6811 int chip_scsi_id;
6812
6813 boardp = ASC_BOARDP(shost);
6814
6815 leftlen = cplen;
6816 totlen = len = 0;
6817
6818 len = asc_prt_line(cp, leftlen,
6819 "\nLinux Driver Configuration and Information for AdvanSys SCSI Host %d:\n",
6820 shost->host_no);
6821 ASC_PRT_NEXT();
6822
6823 len = asc_prt_line(cp, leftlen,
6824 " host_busy %u, last_reset %u, max_id %u, max_lun %u, max_channel %u\n",
6825 shost->host_busy, shost->last_reset, shost->max_id,
6826 shost->max_lun, shost->max_channel);
6827 ASC_PRT_NEXT();
6828
6829 len = asc_prt_line(cp, leftlen,
6830 " unique_id %d, can_queue %d, this_id %d, sg_tablesize %u, cmd_per_lun %u\n",
6831 shost->unique_id, shost->can_queue, shost->this_id,
6832 shost->sg_tablesize, shost->cmd_per_lun);
6833 ASC_PRT_NEXT();
6834
6835 len = asc_prt_line(cp, leftlen,
6836 " unchecked_isa_dma %d, use_clustering %d\n",
6837 shost->unchecked_isa_dma, shost->use_clustering);
6838 ASC_PRT_NEXT();
6839
6840 len = asc_prt_line(cp, leftlen,
6841 " flags 0x%x, last_reset 0x%x, jiffies 0x%x, asc_n_io_port 0x%x\n",
6842 boardp->flags, boardp->last_reset, jiffies,
6843 boardp->asc_n_io_port);
6844 ASC_PRT_NEXT();
6845
6846 /* 'shost->n_io_port' may be truncated because it is only one byte. */
6847 len = asc_prt_line(cp, leftlen,
6848 " io_port 0x%x, n_io_port 0x%x\n",
6849 shost->io_port, shost->n_io_port);
6850 ASC_PRT_NEXT();
6851
6852 if (ASC_NARROW_BOARD(boardp)) {
6853 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
6854 } else {
6855 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
6856 }
1da177e4 6857
27c868c2 6858 return totlen;
1da177e4
LT
6859}
6860
6861/*
6862 * asc_prt_asc_board_info()
6863 *
6864 * Print dynamic board configuration information.
6865 *
6866 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6867 * cf. asc_prt_line().
6868 *
6869 * Return the number of characters copied into 'cp'. No more than
6870 * 'cplen' characters will be copied to 'cp'.
6871 */
27c868c2 6872static int asc_prt_asc_board_info(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 6873{
27c868c2
MW
6874 asc_board_t *boardp;
6875 int chip_scsi_id;
6876 int leftlen;
6877 int totlen;
6878 int len;
6879 ASC_DVC_VAR *v;
6880 ASC_DVC_CFG *c;
6881 int i;
6882 int renegotiate = 0;
6883
6884 boardp = ASC_BOARDP(shost);
6885 v = &boardp->dvc_var.asc_dvc_var;
6886 c = &boardp->dvc_cfg.asc_dvc_cfg;
6887 chip_scsi_id = c->chip_scsi_id;
6888
6889 leftlen = cplen;
6890 totlen = len = 0;
6891
6892 len = asc_prt_line(cp, leftlen,
6893 "\nAsc Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
6894 shost->host_no);
6895 ASC_PRT_NEXT();
6896
6897 len = asc_prt_line(cp, leftlen,
6898 " chip_version %u, lib_version 0x%x, lib_serial_no %u, mcode_date 0x%x\n",
6899 c->chip_version, c->lib_version, c->lib_serial_no,
6900 c->mcode_date);
6901 ASC_PRT_NEXT();
6902
6903 len = asc_prt_line(cp, leftlen,
6904 " mcode_version 0x%x, err_code %u\n",
6905 c->mcode_version, v->err_code);
6906 ASC_PRT_NEXT();
6907
6908 /* Current number of commands waiting for the host. */
6909 len = asc_prt_line(cp, leftlen,
6910 " Total Command Pending: %d\n", v->cur_total_qng);
6911 ASC_PRT_NEXT();
6912
6913 len = asc_prt_line(cp, leftlen, " Command Queuing:");
6914 ASC_PRT_NEXT();
6915 for (i = 0; i <= ASC_MAX_TID; i++) {
6916 if ((chip_scsi_id == i) ||
6917 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6918 continue;
6919 }
6920 len = asc_prt_line(cp, leftlen, " %X:%c",
6921 i,
6922 (v->
6923 use_tagged_qng & ADV_TID_TO_TIDMASK(i)) ?
6924 'Y' : 'N');
6925 ASC_PRT_NEXT();
6926 }
6927 len = asc_prt_line(cp, leftlen, "\n");
6928 ASC_PRT_NEXT();
6929
6930 /* Current number of commands waiting for a device. */
6931 len = asc_prt_line(cp, leftlen, " Command Queue Pending:");
6932 ASC_PRT_NEXT();
6933 for (i = 0; i <= ASC_MAX_TID; i++) {
6934 if ((chip_scsi_id == i) ||
6935 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6936 continue;
6937 }
6938 len = asc_prt_line(cp, leftlen, " %X:%u", i, v->cur_dvc_qng[i]);
6939 ASC_PRT_NEXT();
6940 }
6941 len = asc_prt_line(cp, leftlen, "\n");
6942 ASC_PRT_NEXT();
6943
6944 /* Current limit on number of commands that can be sent to a device. */
6945 len = asc_prt_line(cp, leftlen, " Command Queue Limit:");
6946 ASC_PRT_NEXT();
6947 for (i = 0; i <= ASC_MAX_TID; i++) {
6948 if ((chip_scsi_id == i) ||
6949 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6950 continue;
6951 }
6952 len = asc_prt_line(cp, leftlen, " %X:%u", i, v->max_dvc_qng[i]);
6953 ASC_PRT_NEXT();
6954 }
6955 len = asc_prt_line(cp, leftlen, "\n");
6956 ASC_PRT_NEXT();
6957
6958 /* Indicate whether the device has returned queue full status. */
6959 len = asc_prt_line(cp, leftlen, " Command Queue Full:");
6960 ASC_PRT_NEXT();
6961 for (i = 0; i <= ASC_MAX_TID; i++) {
6962 if ((chip_scsi_id == i) ||
6963 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6964 continue;
6965 }
6966 if (boardp->queue_full & ADV_TID_TO_TIDMASK(i)) {
6967 len = asc_prt_line(cp, leftlen, " %X:Y-%d",
6968 i, boardp->queue_full_cnt[i]);
6969 } else {
6970 len = asc_prt_line(cp, leftlen, " %X:N", i);
6971 }
6972 ASC_PRT_NEXT();
6973 }
6974 len = asc_prt_line(cp, leftlen, "\n");
6975 ASC_PRT_NEXT();
6976
6977 len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
6978 ASC_PRT_NEXT();
6979 for (i = 0; i <= ASC_MAX_TID; i++) {
6980 if ((chip_scsi_id == i) ||
6981 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6982 continue;
6983 }
6984 len = asc_prt_line(cp, leftlen, " %X:%c",
6985 i,
6986 (v->
6987 sdtr_done & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6988 'N');
6989 ASC_PRT_NEXT();
6990 }
6991 len = asc_prt_line(cp, leftlen, "\n");
6992 ASC_PRT_NEXT();
6993
6994 for (i = 0; i <= ASC_MAX_TID; i++) {
6995 uchar syn_period_ix;
6996
6997 if ((chip_scsi_id == i) ||
6998 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
6999 ((v->init_sdtr & ADV_TID_TO_TIDMASK(i)) == 0)) {
7000 continue;
7001 }
7002
7003 len = asc_prt_line(cp, leftlen, " %X:", i);
7004 ASC_PRT_NEXT();
7005
7006 if ((boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET) == 0) {
7007 len = asc_prt_line(cp, leftlen, " Asynchronous");
7008 ASC_PRT_NEXT();
7009 } else {
7010 syn_period_ix =
7011 (boardp->sdtr_data[i] >> 4) & (v->max_sdtr_index -
7012 1);
7013
7014 len = asc_prt_line(cp, leftlen,
7015 " Transfer Period Factor: %d (%d.%d Mhz),",
7016 v->sdtr_period_tbl[syn_period_ix],
7017 250 /
7018 v->sdtr_period_tbl[syn_period_ix],
7019 ASC_TENTHS(250,
7020 v->
7021 sdtr_period_tbl
7022 [syn_period_ix]));
7023 ASC_PRT_NEXT();
7024
7025 len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
7026 boardp->
7027 sdtr_data[i] & ASC_SYN_MAX_OFFSET);
7028 ASC_PRT_NEXT();
7029 }
7030
7031 if ((v->sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
7032 len = asc_prt_line(cp, leftlen, "*\n");
7033 renegotiate = 1;
7034 } else {
7035 len = asc_prt_line(cp, leftlen, "\n");
7036 }
7037 ASC_PRT_NEXT();
7038 }
1da177e4 7039
27c868c2
MW
7040 if (renegotiate) {
7041 len = asc_prt_line(cp, leftlen,
7042 " * = Re-negotiation pending before next command.\n");
7043 ASC_PRT_NEXT();
7044 }
1da177e4 7045
27c868c2 7046 return totlen;
1da177e4
LT
7047}
7048
7049/*
7050 * asc_prt_adv_board_info()
7051 *
7052 * Print dynamic board configuration information.
7053 *
7054 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
7055 * cf. asc_prt_line().
7056 *
7057 * Return the number of characters copied into 'cp'. No more than
7058 * 'cplen' characters will be copied to 'cp'.
7059 */
27c868c2 7060static int asc_prt_adv_board_info(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 7061{
27c868c2
MW
7062 asc_board_t *boardp;
7063 int leftlen;
7064 int totlen;
7065 int len;
7066 int i;
7067 ADV_DVC_VAR *v;
7068 ADV_DVC_CFG *c;
7069 AdvPortAddr iop_base;
7070 ushort chip_scsi_id;
7071 ushort lramword;
7072 uchar lrambyte;
7073 ushort tagqng_able;
7074 ushort sdtr_able, wdtr_able;
7075 ushort wdtr_done, sdtr_done;
7076 ushort period = 0;
7077 int renegotiate = 0;
7078
7079 boardp = ASC_BOARDP(shost);
7080 v = &boardp->dvc_var.adv_dvc_var;
7081 c = &boardp->dvc_cfg.adv_dvc_cfg;
7082 iop_base = v->iop_base;
7083 chip_scsi_id = v->chip_scsi_id;
7084
7085 leftlen = cplen;
7086 totlen = len = 0;
7087
7088 len = asc_prt_line(cp, leftlen,
7089 "\nAdv Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
7090 shost->host_no);
7091 ASC_PRT_NEXT();
7092
7093 len = asc_prt_line(cp, leftlen,
7094 " iop_base 0x%lx, cable_detect: %X, err_code %u\n",
7095 v->iop_base,
7096 AdvReadWordRegister(iop_base,
7097 IOPW_SCSI_CFG1) & CABLE_DETECT,
7098 v->err_code);
7099 ASC_PRT_NEXT();
7100
7101 len = asc_prt_line(cp, leftlen,
7102 " chip_version %u, lib_version 0x%x, mcode_date 0x%x, mcode_version 0x%x\n",
7103 c->chip_version, c->lib_version, c->mcode_date,
7104 c->mcode_version);
7105 ASC_PRT_NEXT();
7106
7107 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
7108 len = asc_prt_line(cp, leftlen, " Queuing Enabled:");
7109 ASC_PRT_NEXT();
7110 for (i = 0; i <= ADV_MAX_TID; i++) {
7111 if ((chip_scsi_id == i) ||
7112 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
7113 continue;
7114 }
7115
7116 len = asc_prt_line(cp, leftlen, " %X:%c",
7117 i,
7118 (tagqng_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
7119 'N');
7120 ASC_PRT_NEXT();
7121 }
7122 len = asc_prt_line(cp, leftlen, "\n");
7123 ASC_PRT_NEXT();
7124
7125 len = asc_prt_line(cp, leftlen, " Queue Limit:");
7126 ASC_PRT_NEXT();
7127 for (i = 0; i <= ADV_MAX_TID; i++) {
7128 if ((chip_scsi_id == i) ||
7129 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
7130 continue;
7131 }
7132
7133 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + i,
7134 lrambyte);
7135
7136 len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
7137 ASC_PRT_NEXT();
7138 }
7139 len = asc_prt_line(cp, leftlen, "\n");
7140 ASC_PRT_NEXT();
7141
7142 len = asc_prt_line(cp, leftlen, " Command Pending:");
7143 ASC_PRT_NEXT();
7144 for (i = 0; i <= ADV_MAX_TID; i++) {
7145 if ((chip_scsi_id == i) ||
7146 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
7147 continue;
7148 }
7149
7150 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_QUEUED_CMD + i,
7151 lrambyte);
7152
7153 len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
7154 ASC_PRT_NEXT();
7155 }
7156 len = asc_prt_line(cp, leftlen, "\n");
7157 ASC_PRT_NEXT();
7158
7159 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
7160 len = asc_prt_line(cp, leftlen, " Wide Enabled:");
7161 ASC_PRT_NEXT();
7162 for (i = 0; i <= ADV_MAX_TID; i++) {
7163 if ((chip_scsi_id == i) ||
7164 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
7165 continue;
7166 }
7167
7168 len = asc_prt_line(cp, leftlen, " %X:%c",
7169 i,
7170 (wdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
7171 'N');
7172 ASC_PRT_NEXT();
7173 }
7174 len = asc_prt_line(cp, leftlen, "\n");
7175 ASC_PRT_NEXT();
7176
7177 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, wdtr_done);
7178 len = asc_prt_line(cp, leftlen, " Transfer Bit Width:");
7179 ASC_PRT_NEXT();
7180 for (i = 0; i <= ADV_MAX_TID; i++) {
7181 if ((chip_scsi_id == i) ||
7182 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
7183 continue;
7184 }
7185
7186 AdvReadWordLram(iop_base,
7187 ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
7188 lramword);
7189
7190 len = asc_prt_line(cp, leftlen, " %X:%d",
7191 i, (lramword & 0x8000) ? 16 : 8);
7192 ASC_PRT_NEXT();
7193
7194 if ((wdtr_able & ADV_TID_TO_TIDMASK(i)) &&
7195 (wdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
7196 len = asc_prt_line(cp, leftlen, "*");
7197 ASC_PRT_NEXT();
7198 renegotiate = 1;
7199 }
7200 }
7201 len = asc_prt_line(cp, leftlen, "\n");
7202 ASC_PRT_NEXT();
7203
7204 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
7205 len = asc_prt_line(cp, leftlen, " Synchronous Enabled:");
7206 ASC_PRT_NEXT();
7207 for (i = 0; i <= ADV_MAX_TID; i++) {
7208 if ((chip_scsi_id == i) ||
7209 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
7210 continue;
7211 }
7212
7213 len = asc_prt_line(cp, leftlen, " %X:%c",
7214 i,
7215 (sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
7216 'N');
7217 ASC_PRT_NEXT();
7218 }
7219 len = asc_prt_line(cp, leftlen, "\n");
7220 ASC_PRT_NEXT();
7221
7222 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, sdtr_done);
7223 for (i = 0; i <= ADV_MAX_TID; i++) {
7224
7225 AdvReadWordLram(iop_base,
7226 ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
7227 lramword);
7228 lramword &= ~0x8000;
7229
7230 if ((chip_scsi_id == i) ||
7231 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
7232 ((sdtr_able & ADV_TID_TO_TIDMASK(i)) == 0)) {
7233 continue;
7234 }
7235
7236 len = asc_prt_line(cp, leftlen, " %X:", i);
7237 ASC_PRT_NEXT();
7238
7239 if ((lramword & 0x1F) == 0) { /* Check for REQ/ACK Offset 0. */
7240 len = asc_prt_line(cp, leftlen, " Asynchronous");
7241 ASC_PRT_NEXT();
7242 } else {
7243 len =
7244 asc_prt_line(cp, leftlen,
7245 " Transfer Period Factor: ");
7246 ASC_PRT_NEXT();
7247
7248 if ((lramword & 0x1F00) == 0x1100) { /* 80 Mhz */
7249 len =
7250 asc_prt_line(cp, leftlen, "9 (80.0 Mhz),");
7251 ASC_PRT_NEXT();
7252 } else if ((lramword & 0x1F00) == 0x1000) { /* 40 Mhz */
7253 len =
7254 asc_prt_line(cp, leftlen, "10 (40.0 Mhz),");
7255 ASC_PRT_NEXT();
7256 } else { /* 20 Mhz or below. */
7257
7258 period = (((lramword >> 8) * 25) + 50) / 4;
7259
7260 if (period == 0) { /* Should never happen. */
7261 len =
7262 asc_prt_line(cp, leftlen,
7263 "%d (? Mhz), ");
7264 ASC_PRT_NEXT();
7265 } else {
7266 len = asc_prt_line(cp, leftlen,
7267 "%d (%d.%d Mhz),",
7268 period, 250 / period,
7269 ASC_TENTHS(250,
7270 period));
7271 ASC_PRT_NEXT();
7272 }
7273 }
7274
7275 len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
7276 lramword & 0x1F);
7277 ASC_PRT_NEXT();
7278 }
7279
7280 if ((sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
7281 len = asc_prt_line(cp, leftlen, "*\n");
7282 renegotiate = 1;
7283 } else {
7284 len = asc_prt_line(cp, leftlen, "\n");
7285 }
7286 ASC_PRT_NEXT();
7287 }
1da177e4 7288
27c868c2
MW
7289 if (renegotiate) {
7290 len = asc_prt_line(cp, leftlen,
7291 " * = Re-negotiation pending before next command.\n");
7292 ASC_PRT_NEXT();
7293 }
1da177e4 7294
27c868c2 7295 return totlen;
1da177e4
LT
7296}
7297
7298/*
7299 * asc_proc_copy()
7300 *
7301 * Copy proc information to a read buffer taking into account the current
7302 * read offset in the file and the remaining space in the read buffer.
7303 */
27c868c2 7304static int
1da177e4 7305asc_proc_copy(off_t advoffset, off_t offset, char *curbuf, int leftlen,
27c868c2 7306 char *cp, int cplen)
1da177e4 7307{
27c868c2
MW
7308 int cnt = 0;
7309
7310 ASC_DBG3(2, "asc_proc_copy: offset %d, advoffset %d, cplen %d\n",
7311 (unsigned)offset, (unsigned)advoffset, cplen);
7312 if (offset <= advoffset) {
7313 /* Read offset below current offset, copy everything. */
7314 cnt = min(cplen, leftlen);
7315 ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
7316 (ulong)curbuf, (ulong)cp, cnt);
7317 memcpy(curbuf, cp, cnt);
7318 } else if (offset < advoffset + cplen) {
7319 /* Read offset within current range, partial copy. */
7320 cnt = (advoffset + cplen) - offset;
7321 cp = (cp + cplen) - cnt;
7322 cnt = min(cnt, leftlen);
7323 ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
7324 (ulong)curbuf, (ulong)cp, cnt);
7325 memcpy(curbuf, cp, cnt);
7326 }
7327 return cnt;
1da177e4
LT
7328}
7329
7330/*
7331 * asc_prt_line()
7332 *
7333 * If 'cp' is NULL print to the console, otherwise print to a buffer.
7334 *
7335 * Return 0 if printing to the console, otherwise return the number of
7336 * bytes written to the buffer.
7337 *
7338 * Note: If any single line is greater than ASC_PRTLINE_SIZE bytes the stack
7339 * will be corrupted. 's[]' is defined to be ASC_PRTLINE_SIZE bytes.
7340 */
27c868c2 7341static int asc_prt_line(char *buf, int buflen, char *fmt, ...)
1da177e4 7342{
27c868c2
MW
7343 va_list args;
7344 int ret;
7345 char s[ASC_PRTLINE_SIZE];
7346
7347 va_start(args, fmt);
7348 ret = vsprintf(s, fmt, args);
7349 ASC_ASSERT(ret < ASC_PRTLINE_SIZE);
7350 if (buf == NULL) {
7351 (void)printk(s);
7352 ret = 0;
7353 } else {
7354 ret = min(buflen, ret);
7355 memcpy(buf, s, ret);
7356 }
7357 va_end(args);
7358 return ret;
1da177e4
LT
7359}
7360#endif /* CONFIG_PROC_FS */
7361
1da177e4
LT
7362/*
7363 * --- Functions Required by the Asc Library
7364 */
7365
7366/*
7367 * Delay for 'n' milliseconds. Don't use the 'jiffies'
7368 * global variable which is incremented once every 5 ms
7369 * from a timer interrupt, because this function may be
7370 * called when interrupts are disabled.
7371 */
27c868c2 7372static void DvcSleepMilliSecond(ADV_DCNT n)
1da177e4 7373{
27c868c2
MW
7374 ASC_DBG1(4, "DvcSleepMilliSecond: %lu\n", (ulong)n);
7375 mdelay(n);
1da177e4
LT
7376}
7377
7378/*
7379 * Currently and inline noop but leave as a placeholder.
7380 * Leave DvcEnterCritical() as a noop placeholder.
7381 */
27c868c2 7382static inline ulong DvcEnterCritical(void)
1da177e4 7383{
27c868c2 7384 return 0;
1da177e4
LT
7385}
7386
7387/*
7388 * Critical sections are all protected by the board spinlock.
7389 * Leave DvcLeaveCritical() as a noop placeholder.
7390 */
27c868c2 7391static inline void DvcLeaveCritical(ulong flags)
1da177e4 7392{
27c868c2 7393 return;
1da177e4
LT
7394}
7395
7396/*
7397 * void
7398 * DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
7399 *
7400 * Calling/Exit State:
7401 * none
7402 *
7403 * Description:
7404 * Output an ASC_SCSI_Q structure to the chip
7405 */
27c868c2 7406static void
1da177e4
LT
7407DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
7408{
27c868c2
MW
7409 int i;
7410
7411 ASC_DBG_PRT_HEX(2, "DvcPutScsiQ", outbuf, 2 * words);
7412 AscSetChipLramAddr(iop_base, s_addr);
7413 for (i = 0; i < 2 * words; i += 2) {
7414 if (i == 4 || i == 20) {
7415 continue;
7416 }
7417 outpw(iop_base + IOP_RAM_DATA,
7418 ((ushort)outbuf[i + 1] << 8) | outbuf[i]);
7419 }
1da177e4
LT
7420}
7421
7422/*
7423 * void
7424 * DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
7425 *
7426 * Calling/Exit State:
7427 * none
7428 *
7429 * Description:
7430 * Input an ASC_QDONE_INFO structure from the chip
7431 */
27c868c2 7432static void
1da177e4
LT
7433DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
7434{
27c868c2
MW
7435 int i;
7436 ushort word;
7437
7438 AscSetChipLramAddr(iop_base, s_addr);
7439 for (i = 0; i < 2 * words; i += 2) {
7440 if (i == 10) {
7441 continue;
7442 }
7443 word = inpw(iop_base + IOP_RAM_DATA);
7444 inbuf[i] = word & 0xff;
7445 inbuf[i + 1] = (word >> 8) & 0xff;
7446 }
7447 ASC_DBG_PRT_HEX(2, "DvcGetQinfo", inbuf, 2 * words);
1da177e4
LT
7448}
7449
7450/*
7451 * Read a PCI configuration byte.
7452 */
27c868c2 7453static uchar __init DvcReadPCIConfigByte(ASC_DVC_VAR *asc_dvc, ushort offset)
1da177e4
LT
7454{
7455#ifdef CONFIG_PCI
27c868c2
MW
7456 uchar byte_data;
7457 pci_read_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, &byte_data);
7458 return byte_data;
1da177e4 7459#else /* !defined(CONFIG_PCI) */
27c868c2 7460 return 0;
1da177e4
LT
7461#endif /* !defined(CONFIG_PCI) */
7462}
7463
7464/*
7465 * Write a PCI configuration byte.
7466 */
27c868c2
MW
7467static void __init
7468DvcWritePCIConfigByte(ASC_DVC_VAR *asc_dvc, ushort offset, uchar byte_data)
1da177e4
LT
7469{
7470#ifdef CONFIG_PCI
27c868c2 7471 pci_write_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, byte_data);
1da177e4
LT
7472#endif /* CONFIG_PCI */
7473}
7474
7475/*
7476 * Return the BIOS address of the adapter at the specified
7477 * I/O port and with the specified bus type.
7478 */
27c868c2 7479static ushort __init AscGetChipBiosAddress(PortAddr iop_base, ushort bus_type)
1da177e4 7480{
27c868c2
MW
7481 ushort cfg_lsw;
7482 ushort bios_addr;
7483
7484 /*
7485 * The PCI BIOS is re-located by the motherboard BIOS. Because
7486 * of this the driver can not determine where a PCI BIOS is
7487 * loaded and executes.
7488 */
7489 if (bus_type & ASC_IS_PCI) {
7490 return (0);
7491 }
1da177e4 7492#ifdef CONFIG_ISA
27c868c2
MW
7493 if ((bus_type & ASC_IS_EISA) != 0) {
7494 cfg_lsw = AscGetEisaChipCfg(iop_base);
7495 cfg_lsw &= 0x000F;
7496 bios_addr = (ushort)(ASC_BIOS_MIN_ADDR +
7497 (cfg_lsw * ASC_BIOS_BANK_SIZE));
7498 return (bios_addr);
7499 } /* if */
1da177e4
LT
7500#endif /* CONFIG_ISA */
7501
27c868c2 7502 cfg_lsw = AscGetChipCfgLsw(iop_base);
1da177e4 7503
27c868c2
MW
7504 /*
7505 * ISA PnP uses the top bit as the 32K BIOS flag
7506 */
7507 if (bus_type == ASC_IS_ISAPNP) {
7508 cfg_lsw &= 0x7FFF;
7509 }
7510 /* if */
7511 bios_addr = (ushort)(((cfg_lsw >> 12) * ASC_BIOS_BANK_SIZE) +
7512 ASC_BIOS_MIN_ADDR);
7513 return (bios_addr);
1da177e4
LT
7514}
7515
1da177e4
LT
7516/*
7517 * --- Functions Required by the Adv Library
7518 */
7519
7520/*
7521 * DvcGetPhyAddr()
7522 *
7523 * Return the physical address of 'vaddr' and set '*lenp' to the
7524 * number of physically contiguous bytes that follow 'vaddr'.
7525 * 'flag' indicates the type of structure whose physical address
7526 * is being translated.
7527 *
7528 * Note: Because Linux currently doesn't page the kernel and all
7529 * kernel buffers are physically contiguous, leave '*lenp' unchanged.
7530 */
7531ADV_PADDR
7532DvcGetPhyAddr(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq,
27c868c2 7533 uchar *vaddr, ADV_SDCNT *lenp, int flag)
1da177e4 7534{
27c868c2 7535 ADV_PADDR paddr;
1da177e4 7536
27c868c2 7537 paddr = virt_to_bus(vaddr);
1da177e4 7538
27c868c2
MW
7539 ASC_DBG4(4,
7540 "DvcGetPhyAddr: vaddr 0x%lx, lenp 0x%lx *lenp %lu, paddr 0x%lx\n",
7541 (ulong)vaddr, (ulong)lenp, (ulong)*((ulong *)lenp),
7542 (ulong)paddr);
1da177e4 7543
27c868c2 7544 return paddr;
1da177e4
LT
7545}
7546
7547/*
7548 * Read a PCI configuration byte.
7549 */
27c868c2 7550static uchar __init DvcAdvReadPCIConfigByte(ADV_DVC_VAR *asc_dvc, ushort offset)
1da177e4
LT
7551{
7552#ifdef CONFIG_PCI
27c868c2
MW
7553 uchar byte_data;
7554 pci_read_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, &byte_data);
7555 return byte_data;
1da177e4 7556#else /* CONFIG_PCI */
27c868c2 7557 return 0;
1da177e4
LT
7558#endif /* CONFIG_PCI */
7559}
7560
7561/*
7562 * Write a PCI configuration byte.
7563 */
27c868c2
MW
7564static void __init
7565DvcAdvWritePCIConfigByte(ADV_DVC_VAR *asc_dvc, ushort offset, uchar byte_data)
1da177e4
LT
7566{
7567#ifdef CONFIG_PCI
27c868c2 7568 pci_write_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, byte_data);
1da177e4 7569#else /* CONFIG_PCI */
27c868c2 7570 return;
1da177e4
LT
7571#endif /* CONFIG_PCI */
7572}
7573
7574/*
7575 * --- Tracing and Debugging Functions
7576 */
7577
7578#ifdef ADVANSYS_STATS
7579#ifdef CONFIG_PROC_FS
7580/*
7581 * asc_prt_board_stats()
7582 *
7583 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
7584 * cf. asc_prt_line().
7585 *
7586 * Return the number of characters copied into 'cp'. No more than
7587 * 'cplen' characters will be copied to 'cp'.
7588 */
27c868c2 7589static int asc_prt_board_stats(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 7590{
27c868c2
MW
7591 int leftlen;
7592 int totlen;
7593 int len;
7594 struct asc_stats *s;
7595 asc_board_t *boardp;
1da177e4 7596
27c868c2
MW
7597 leftlen = cplen;
7598 totlen = len = 0;
7599
7600 boardp = ASC_BOARDP(shost);
7601 s = &boardp->asc_stats;
7602
7603 len = asc_prt_line(cp, leftlen,
7604 "\nLinux Driver Statistics for AdvanSys SCSI Host %d:\n",
7605 shost->host_no);
7606 ASC_PRT_NEXT();
7607
7608 len = asc_prt_line(cp, leftlen,
7609 " queuecommand %lu, reset %lu, biosparam %lu, interrupt %lu\n",
7610 s->queuecommand, s->reset, s->biosparam,
7611 s->interrupt);
7612 ASC_PRT_NEXT();
7613
7614 len = asc_prt_line(cp, leftlen,
7615 " callback %lu, done %lu, build_error %lu, build_noreq %lu, build_nosg %lu\n",
7616 s->callback, s->done, s->build_error,
7617 s->adv_build_noreq, s->adv_build_nosg);
7618 ASC_PRT_NEXT();
7619
7620 len = asc_prt_line(cp, leftlen,
7621 " exe_noerror %lu, exe_busy %lu, exe_error %lu, exe_unknown %lu\n",
7622 s->exe_noerror, s->exe_busy, s->exe_error,
7623 s->exe_unknown);
7624 ASC_PRT_NEXT();
7625
7626 /*
7627 * Display data transfer statistics.
7628 */
7629 if (s->cont_cnt > 0) {
7630 len = asc_prt_line(cp, leftlen, " cont_cnt %lu, ", s->cont_cnt);
7631 ASC_PRT_NEXT();
7632
7633 len = asc_prt_line(cp, leftlen, "cont_xfer %lu.%01lu kb ",
7634 s->cont_xfer / 2,
7635 ASC_TENTHS(s->cont_xfer, 2));
7636 ASC_PRT_NEXT();
7637
7638 /* Contiguous transfer average size */
7639 len = asc_prt_line(cp, leftlen, "avg_xfer %lu.%01lu kb\n",
7640 (s->cont_xfer / 2) / s->cont_cnt,
7641 ASC_TENTHS((s->cont_xfer / 2), s->cont_cnt));
7642 ASC_PRT_NEXT();
7643 }
1da177e4 7644
27c868c2 7645 if (s->sg_cnt > 0) {
1da177e4 7646
27c868c2
MW
7647 len = asc_prt_line(cp, leftlen, " sg_cnt %lu, sg_elem %lu, ",
7648 s->sg_cnt, s->sg_elem);
7649 ASC_PRT_NEXT();
1da177e4 7650
27c868c2
MW
7651 len = asc_prt_line(cp, leftlen, "sg_xfer %lu.%01lu kb\n",
7652 s->sg_xfer / 2, ASC_TENTHS(s->sg_xfer, 2));
7653 ASC_PRT_NEXT();
1da177e4 7654
27c868c2
MW
7655 /* Scatter gather transfer statistics */
7656 len = asc_prt_line(cp, leftlen, " avg_num_elem %lu.%01lu, ",
7657 s->sg_elem / s->sg_cnt,
7658 ASC_TENTHS(s->sg_elem, s->sg_cnt));
7659 ASC_PRT_NEXT();
1da177e4 7660
27c868c2
MW
7661 len = asc_prt_line(cp, leftlen, "avg_elem_size %lu.%01lu kb, ",
7662 (s->sg_xfer / 2) / s->sg_elem,
7663 ASC_TENTHS((s->sg_xfer / 2), s->sg_elem));
7664 ASC_PRT_NEXT();
1da177e4 7665
27c868c2
MW
7666 len = asc_prt_line(cp, leftlen, "avg_xfer_size %lu.%01lu kb\n",
7667 (s->sg_xfer / 2) / s->sg_cnt,
7668 ASC_TENTHS((s->sg_xfer / 2), s->sg_cnt));
7669 ASC_PRT_NEXT();
7670 }
1da177e4 7671
27c868c2
MW
7672 /*
7673 * Display request queuing statistics.
7674 */
7675 len = asc_prt_line(cp, leftlen,
7676 " Active and Waiting Request Queues (Time Unit: %d HZ):\n",
7677 HZ);
7678 ASC_PRT_NEXT();
1da177e4 7679
27c868c2 7680 return totlen;
1da177e4
LT
7681}
7682
7683/*
7684 * asc_prt_target_stats()
7685 *
7686 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
7687 * cf. asc_prt_line().
7688 *
7689 * This is separated from asc_prt_board_stats because a full set
7690 * of targets will overflow ASC_PRTBUF_SIZE.
7691 *
7692 * Return the number of characters copied into 'cp'. No more than
7693 * 'cplen' characters will be copied to 'cp'.
7694 */
27c868c2
MW
7695static int
7696asc_prt_target_stats(struct Scsi_Host *shost, int tgt_id, char *cp, int cplen)
1da177e4 7697{
27c868c2
MW
7698 int leftlen;
7699 int totlen;
7700 int len;
7701 struct asc_stats *s;
7702 ushort chip_scsi_id;
7703 asc_board_t *boardp;
7704 asc_queue_t *active;
7705 asc_queue_t *waiting;
1da177e4 7706
27c868c2
MW
7707 leftlen = cplen;
7708 totlen = len = 0;
7709
7710 boardp = ASC_BOARDP(shost);
7711 s = &boardp->asc_stats;
7712
7713 active = &ASC_BOARDP(shost)->active;
7714 waiting = &ASC_BOARDP(shost)->waiting;
7715
7716 if (ASC_NARROW_BOARD(boardp)) {
7717 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
7718 } else {
7719 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
7720 }
7721
7722 if ((chip_scsi_id == tgt_id) ||
7723 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(tgt_id)) == 0)) {
7724 return 0;
7725 }
1da177e4 7726
27c868c2
MW
7727 do {
7728 if (active->q_tot_cnt[tgt_id] > 0
7729 || waiting->q_tot_cnt[tgt_id] > 0) {
7730 len = asc_prt_line(cp, leftlen, " target %d\n", tgt_id);
7731 ASC_PRT_NEXT();
7732
7733 len = asc_prt_line(cp, leftlen,
7734 " active: cnt [cur %d, max %d, tot %u], time [min %d, max %d, avg %lu.%01lu]\n",
7735 active->q_cur_cnt[tgt_id],
7736 active->q_max_cnt[tgt_id],
7737 active->q_tot_cnt[tgt_id],
7738 active->q_min_tim[tgt_id],
7739 active->q_max_tim[tgt_id],
7740 (active->q_tot_cnt[tgt_id] ==
7741 0) ? 0 : (active->
7742 q_tot_tim[tgt_id] /
7743 active->
7744 q_tot_cnt[tgt_id]),
7745 (active->q_tot_cnt[tgt_id] ==
7746 0) ? 0 : ASC_TENTHS(active->
7747 q_tot_tim
7748 [tgt_id],
7749 active->
7750 q_tot_cnt
7751 [tgt_id]));
7752 ASC_PRT_NEXT();
7753
7754 len = asc_prt_line(cp, leftlen,
7755 " waiting: cnt [cur %d, max %d, tot %u], time [min %u, max %u, avg %lu.%01lu]\n",
7756 waiting->q_cur_cnt[tgt_id],
7757 waiting->q_max_cnt[tgt_id],
7758 waiting->q_tot_cnt[tgt_id],
7759 waiting->q_min_tim[tgt_id],
7760 waiting->q_max_tim[tgt_id],
7761 (waiting->q_tot_cnt[tgt_id] ==
7762 0) ? 0 : (waiting->
7763 q_tot_tim[tgt_id] /
7764 waiting->
7765 q_tot_cnt[tgt_id]),
7766 (waiting->q_tot_cnt[tgt_id] ==
7767 0) ? 0 : ASC_TENTHS(waiting->
7768 q_tot_tim
7769 [tgt_id],
7770 waiting->
7771 q_tot_cnt
7772 [tgt_id]));
7773 ASC_PRT_NEXT();
7774 }
7775 } while (0);
7776
7777 return totlen;
1da177e4
LT
7778}
7779#endif /* CONFIG_PROC_FS */
7780#endif /* ADVANSYS_STATS */
7781
7782#ifdef ADVANSYS_DEBUG
7783/*
7784 * asc_prt_scsi_host()
7785 */
27c868c2 7786static void asc_prt_scsi_host(struct Scsi_Host *s)
1da177e4 7787{
27c868c2
MW
7788 asc_board_t *boardp;
7789
7790 boardp = ASC_BOARDP(s);
7791
7792 printk("Scsi_Host at addr 0x%lx\n", (ulong)s);
7793 printk(" host_busy %u, host_no %d, last_reset %d,\n",
7794 s->host_busy, s->host_no, (unsigned)s->last_reset);
7795
7796 printk(" base 0x%lx, io_port 0x%lx, n_io_port %u, irq 0x%x,\n",
7797 (ulong)s->base, (ulong)s->io_port, s->n_io_port, s->irq);
7798
7799 printk(" dma_channel %d, this_id %d, can_queue %d,\n",
7800 s->dma_channel, s->this_id, s->can_queue);
7801
7802 printk(" cmd_per_lun %d, sg_tablesize %d, unchecked_isa_dma %d\n",
7803 s->cmd_per_lun, s->sg_tablesize, s->unchecked_isa_dma);
7804
7805 if (ASC_NARROW_BOARD(boardp)) {
7806 asc_prt_asc_dvc_var(&ASC_BOARDP(s)->dvc_var.asc_dvc_var);
7807 asc_prt_asc_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.asc_dvc_cfg);
7808 } else {
7809 asc_prt_adv_dvc_var(&ASC_BOARDP(s)->dvc_var.adv_dvc_var);
7810 asc_prt_adv_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.adv_dvc_cfg);
7811 }
1da177e4
LT
7812}
7813
7814/*
7815 * asc_prt_scsi_cmnd()
7816 */
27c868c2 7817static void asc_prt_scsi_cmnd(struct scsi_cmnd *s)
1da177e4 7818{
27c868c2 7819 printk("struct scsi_cmnd at addr 0x%lx\n", (ulong)s);
1da177e4 7820
27c868c2
MW
7821 printk(" host 0x%lx, device 0x%lx, target %u, lun %u, channel %u,\n",
7822 (ulong)s->device->host, (ulong)s->device, s->device->id,
7823 s->device->lun, s->device->channel);
1da177e4 7824
27c868c2 7825 asc_prt_hex(" CDB", s->cmnd, s->cmd_len);
1da177e4 7826
27c868c2
MW
7827 printk("sc_data_direction %u, resid %d\n",
7828 s->sc_data_direction, s->resid);
1da177e4 7829
27c868c2 7830 printk(" use_sg %u, sglist_len %u\n", s->use_sg, s->sglist_len);
1da177e4 7831
27c868c2
MW
7832 printk(" serial_number 0x%x, retries %d, allowed %d\n",
7833 (unsigned)s->serial_number, s->retries, s->allowed);
1da177e4 7834
27c868c2 7835 printk(" timeout_per_command %d\n", s->timeout_per_command);
1da177e4 7836
27c868c2
MW
7837 printk
7838 (" scsi_done 0x%lx, done 0x%lx, host_scribble 0x%lx, result 0x%x\n",
7839 (ulong)s->scsi_done, (ulong)s->done, (ulong)s->host_scribble,
7840 s->result);
1da177e4 7841
27c868c2 7842 printk(" tag %u, pid %u\n", (unsigned)s->tag, (unsigned)s->pid);
1da177e4
LT
7843}
7844
7845/*
7846 * asc_prt_asc_dvc_var()
7847 */
27c868c2 7848static void asc_prt_asc_dvc_var(ASC_DVC_VAR *h)
1da177e4 7849{
27c868c2
MW
7850 printk("ASC_DVC_VAR at addr 0x%lx\n", (ulong)h);
7851
7852 printk
7853 (" iop_base 0x%x, err_code 0x%x, dvc_cntl 0x%x, bug_fix_cntl %d,\n",
7854 h->iop_base, h->err_code, h->dvc_cntl, h->bug_fix_cntl);
7855
7856 printk
7857 (" bus_type %d, isr_callback 0x%lx, exe_callback 0x%lx, init_sdtr 0x%x,\n",
7858 h->bus_type, (ulong)h->isr_callback, (ulong)h->exe_callback,
7859 (unsigned)h->init_sdtr);
7860
7861 printk
7862 (" sdtr_done 0x%x, use_tagged_qng 0x%x, unit_not_ready 0x%x, chip_no 0x%x,\n",
7863 (unsigned)h->sdtr_done, (unsigned)h->use_tagged_qng,
7864 (unsigned)h->unit_not_ready, (unsigned)h->chip_no);
7865
7866 printk
7867 (" queue_full_or_busy 0x%x, start_motor 0x%x, scsi_reset_wait %u,\n",
7868 (unsigned)h->queue_full_or_busy, (unsigned)h->start_motor,
7869 (unsigned)h->scsi_reset_wait);
7870
7871 printk
7872 (" is_in_int %u, max_total_qng %u, cur_total_qng %u, in_critical_cnt %u,\n",
7873 (unsigned)h->is_in_int, (unsigned)h->max_total_qng,
7874 (unsigned)h->cur_total_qng, (unsigned)h->in_critical_cnt);
7875
7876 printk
7877 (" last_q_shortage %u, init_state 0x%x, no_scam 0x%x, pci_fix_asyn_xfer 0x%x,\n",
7878 (unsigned)h->last_q_shortage, (unsigned)h->init_state,
7879 (unsigned)h->no_scam, (unsigned)h->pci_fix_asyn_xfer);
7880
7881 printk(" cfg 0x%lx, irq_no 0x%x\n", (ulong)h->cfg, (unsigned)h->irq_no);
1da177e4
LT
7882}
7883
7884/*
7885 * asc_prt_asc_dvc_cfg()
7886 */
27c868c2 7887static void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *h)
1da177e4 7888{
27c868c2
MW
7889 printk("ASC_DVC_CFG at addr 0x%lx\n", (ulong)h);
7890
7891 printk(" can_tagged_qng 0x%x, cmd_qng_enabled 0x%x,\n",
7892 h->can_tagged_qng, h->cmd_qng_enabled);
7893 printk(" disc_enable 0x%x, sdtr_enable 0x%x,\n",
7894 h->disc_enable, h->sdtr_enable);
7895
7896 printk
7897 (" chip_scsi_id %d, isa_dma_speed %d, isa_dma_channel %d, chip_version %d,\n",
7898 h->chip_scsi_id, h->isa_dma_speed, h->isa_dma_channel,
7899 h->chip_version);
7900
7901 printk
7902 (" pci_device_id %d, lib_serial_no %u, lib_version %u, mcode_date 0x%x,\n",
7903 to_pci_dev(h->dev)->device, h->lib_serial_no, h->lib_version,
7904 h->mcode_date);
7905
7906 printk(" mcode_version %d, overrun_buf 0x%lx\n",
7907 h->mcode_version, (ulong)h->overrun_buf);
1da177e4
LT
7908}
7909
7910/*
7911 * asc_prt_asc_scsi_q()
7912 */
27c868c2 7913static void asc_prt_asc_scsi_q(ASC_SCSI_Q *q)
1da177e4 7914{
27c868c2
MW
7915 ASC_SG_HEAD *sgp;
7916 int i;
7917
7918 printk("ASC_SCSI_Q at addr 0x%lx\n", (ulong)q);
7919
7920 printk
7921 (" target_ix 0x%x, target_lun %u, srb_ptr 0x%lx, tag_code 0x%x,\n",
7922 q->q2.target_ix, q->q1.target_lun, (ulong)q->q2.srb_ptr,
7923 q->q2.tag_code);
7924
7925 printk
7926 (" data_addr 0x%lx, data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
7927 (ulong)le32_to_cpu(q->q1.data_addr),
7928 (ulong)le32_to_cpu(q->q1.data_cnt),
7929 (ulong)le32_to_cpu(q->q1.sense_addr), q->q1.sense_len);
7930
7931 printk(" cdbptr 0x%lx, cdb_len %u, sg_head 0x%lx, sg_queue_cnt %u\n",
7932 (ulong)q->cdbptr, q->q2.cdb_len,
7933 (ulong)q->sg_head, q->q1.sg_queue_cnt);
7934
7935 if (q->sg_head) {
7936 sgp = q->sg_head;
7937 printk("ASC_SG_HEAD at addr 0x%lx\n", (ulong)sgp);
7938 printk(" entry_cnt %u, queue_cnt %u\n", sgp->entry_cnt,
7939 sgp->queue_cnt);
7940 for (i = 0; i < sgp->entry_cnt; i++) {
7941 printk(" [%u]: addr 0x%lx, bytes %lu\n",
7942 i, (ulong)le32_to_cpu(sgp->sg_list[i].addr),
7943 (ulong)le32_to_cpu(sgp->sg_list[i].bytes));
7944 }
1da177e4 7945
27c868c2 7946 }
1da177e4
LT
7947}
7948
7949/*
7950 * asc_prt_asc_qdone_info()
7951 */
27c868c2 7952static void asc_prt_asc_qdone_info(ASC_QDONE_INFO *q)
1da177e4 7953{
27c868c2
MW
7954 printk("ASC_QDONE_INFO at addr 0x%lx\n", (ulong)q);
7955 printk(" srb_ptr 0x%lx, target_ix %u, cdb_len %u, tag_code %u,\n",
7956 (ulong)q->d2.srb_ptr, q->d2.target_ix, q->d2.cdb_len,
7957 q->d2.tag_code);
7958 printk
7959 (" done_stat 0x%x, host_stat 0x%x, scsi_stat 0x%x, scsi_msg 0x%x\n",
7960 q->d3.done_stat, q->d3.host_stat, q->d3.scsi_stat, q->d3.scsi_msg);
1da177e4
LT
7961}
7962
7963/*
7964 * asc_prt_adv_dvc_var()
7965 *
7966 * Display an ADV_DVC_VAR structure.
7967 */
27c868c2 7968static void asc_prt_adv_dvc_var(ADV_DVC_VAR *h)
1da177e4 7969{
27c868c2
MW
7970 printk(" ADV_DVC_VAR at addr 0x%lx\n", (ulong)h);
7971
7972 printk(" iop_base 0x%lx, err_code 0x%x, ultra_able 0x%x\n",
7973 (ulong)h->iop_base, h->err_code, (unsigned)h->ultra_able);
7974
7975 printk(" isr_callback 0x%lx, sdtr_able 0x%x, wdtr_able 0x%x\n",
7976 (ulong)h->isr_callback, (unsigned)h->sdtr_able,
7977 (unsigned)h->wdtr_able);
7978
7979 printk(" start_motor 0x%x, scsi_reset_wait 0x%x, irq_no 0x%x,\n",
7980 (unsigned)h->start_motor,
7981 (unsigned)h->scsi_reset_wait, (unsigned)h->irq_no);
7982
7983 printk(" max_host_qng %u, max_dvc_qng %u, carr_freelist 0x%lxn\n",
7984 (unsigned)h->max_host_qng, (unsigned)h->max_dvc_qng,
7985 (ulong)h->carr_freelist);
7986
7987 printk(" icq_sp 0x%lx, irq_sp 0x%lx\n",
7988 (ulong)h->icq_sp, (ulong)h->irq_sp);
7989
7990 printk(" no_scam 0x%x, tagqng_able 0x%x\n",
7991 (unsigned)h->no_scam, (unsigned)h->tagqng_able);
7992
7993 printk(" chip_scsi_id 0x%x, cfg 0x%lx\n",
7994 (unsigned)h->chip_scsi_id, (ulong)h->cfg);
1da177e4
LT
7995}
7996
7997/*
7998 * asc_prt_adv_dvc_cfg()
7999 *
8000 * Display an ADV_DVC_CFG structure.
8001 */
27c868c2 8002static void asc_prt_adv_dvc_cfg(ADV_DVC_CFG *h)
1da177e4 8003{
27c868c2 8004 printk(" ADV_DVC_CFG at addr 0x%lx\n", (ulong)h);
1da177e4 8005
27c868c2
MW
8006 printk(" disc_enable 0x%x, termination 0x%x\n",
8007 h->disc_enable, h->termination);
1da177e4 8008
27c868c2
MW
8009 printk(" chip_version 0x%x, mcode_date 0x%x\n",
8010 h->chip_version, h->mcode_date);
1da177e4 8011
27c868c2
MW
8012 printk(" mcode_version 0x%x, pci_device_id 0x%x, lib_version %u\n",
8013 h->mcode_version, to_pci_dev(h->dev)->device, h->lib_version);
1da177e4 8014
27c868c2
MW
8015 printk(" control_flag 0x%x, pci_slot_info 0x%x\n",
8016 h->control_flag, h->pci_slot_info);
1da177e4
LT
8017}
8018
8019/*
8020 * asc_prt_adv_scsi_req_q()
8021 *
8022 * Display an ADV_SCSI_REQ_Q structure.
8023 */
27c868c2 8024static void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *q)
1da177e4 8025{
27c868c2
MW
8026 int sg_blk_cnt;
8027 struct asc_sg_block *sg_ptr;
8028
8029 printk("ADV_SCSI_REQ_Q at addr 0x%lx\n", (ulong)q);
8030
8031 printk(" target_id %u, target_lun %u, srb_ptr 0x%lx, a_flag 0x%x\n",
8032 q->target_id, q->target_lun, (ulong)q->srb_ptr, q->a_flag);
8033
8034 printk(" cntl 0x%x, data_addr 0x%lx, vdata_addr 0x%lx\n",
8035 q->cntl, (ulong)le32_to_cpu(q->data_addr), (ulong)q->vdata_addr);
8036
8037 printk(" data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
8038 (ulong)le32_to_cpu(q->data_cnt),
8039 (ulong)le32_to_cpu(q->sense_addr), q->sense_len);
8040
8041 printk
8042 (" cdb_len %u, done_status 0x%x, host_status 0x%x, scsi_status 0x%x\n",
8043 q->cdb_len, q->done_status, q->host_status, q->scsi_status);
8044
8045 printk(" sg_working_ix 0x%x, target_cmd %u\n",
8046 q->sg_working_ix, q->target_cmd);
8047
8048 printk(" scsiq_rptr 0x%lx, sg_real_addr 0x%lx, sg_list_ptr 0x%lx\n",
8049 (ulong)le32_to_cpu(q->scsiq_rptr),
8050 (ulong)le32_to_cpu(q->sg_real_addr), (ulong)q->sg_list_ptr);
8051
8052 /* Display the request's ADV_SG_BLOCK structures. */
8053 if (q->sg_list_ptr != NULL) {
8054 sg_blk_cnt = 0;
8055 while (1) {
8056 /*
8057 * 'sg_ptr' is a physical address. Convert it to a virtual
8058 * address by indexing 'sg_blk_cnt' into the virtual address
8059 * array 'sg_list_ptr'.
8060 *
8061 * XXX - Assumes all SG physical blocks are virtually contiguous.
8062 */
8063 sg_ptr =
8064 &(((ADV_SG_BLOCK *)(q->sg_list_ptr))[sg_blk_cnt]);
8065 asc_prt_adv_sgblock(sg_blk_cnt, sg_ptr);
8066 if (sg_ptr->sg_ptr == 0) {
8067 break;
8068 }
8069 sg_blk_cnt++;
8070 }
8071 }
1da177e4
LT
8072}
8073
8074/*
8075 * asc_prt_adv_sgblock()
8076 *
8077 * Display an ADV_SG_BLOCK structure.
8078 */
27c868c2 8079static void asc_prt_adv_sgblock(int sgblockno, ADV_SG_BLOCK *b)
1da177e4 8080{
27c868c2
MW
8081 int i;
8082
8083 printk(" ASC_SG_BLOCK at addr 0x%lx (sgblockno %d)\n",
8084 (ulong)b, sgblockno);
8085 printk(" sg_cnt %u, sg_ptr 0x%lx\n",
8086 b->sg_cnt, (ulong)le32_to_cpu(b->sg_ptr));
8087 ASC_ASSERT(b->sg_cnt <= NO_OF_SG_PER_BLOCK);
8088 if (b->sg_ptr != 0) {
8089 ASC_ASSERT(b->sg_cnt == NO_OF_SG_PER_BLOCK);
8090 }
8091 for (i = 0; i < b->sg_cnt; i++) {
8092 printk(" [%u]: sg_addr 0x%lx, sg_count 0x%lx\n",
8093 i, (ulong)b->sg_list[i].sg_addr,
8094 (ulong)b->sg_list[i].sg_count);
8095 }
1da177e4
LT
8096}
8097
8098/*
8099 * asc_prt_hex()
8100 *
8101 * Print hexadecimal output in 4 byte groupings 32 bytes
8102 * or 8 double-words per line.
8103 */
27c868c2 8104static void asc_prt_hex(char *f, uchar *s, int l)
1da177e4 8105{
27c868c2
MW
8106 int i;
8107 int j;
8108 int k;
8109 int m;
8110
8111 printk("%s: (%d bytes)\n", f, l);
8112
8113 for (i = 0; i < l; i += 32) {
8114
8115 /* Display a maximum of 8 double-words per line. */
8116 if ((k = (l - i) / 4) >= 8) {
8117 k = 8;
8118 m = 0;
8119 } else {
8120 m = (l - i) % 4;
8121 }
8122
8123 for (j = 0; j < k; j++) {
8124 printk(" %2.2X%2.2X%2.2X%2.2X",
8125 (unsigned)s[i + (j * 4)],
8126 (unsigned)s[i + (j * 4) + 1],
8127 (unsigned)s[i + (j * 4) + 2],
8128 (unsigned)s[i + (j * 4) + 3]);
8129 }
8130
8131 switch (m) {
8132 case 0:
8133 default:
8134 break;
8135 case 1:
8136 printk(" %2.2X", (unsigned)s[i + (j * 4)]);
8137 break;
8138 case 2:
8139 printk(" %2.2X%2.2X",
8140 (unsigned)s[i + (j * 4)],
8141 (unsigned)s[i + (j * 4) + 1]);
8142 break;
8143 case 3:
8144 printk(" %2.2X%2.2X%2.2X",
8145 (unsigned)s[i + (j * 4) + 1],
8146 (unsigned)s[i + (j * 4) + 2],
8147 (unsigned)s[i + (j * 4) + 3]);
8148 break;
8149 }
8150
8151 printk("\n");
8152 }
1da177e4
LT
8153}
8154#endif /* ADVANSYS_DEBUG */
8155
8156/*
8157 * --- Asc Library Functions
8158 */
8159
27c868c2 8160static ushort __init AscGetEisaChipCfg(PortAddr iop_base)
1da177e4 8161{
27c868c2 8162 PortAddr eisa_cfg_iop;
1da177e4 8163
27c868c2
MW
8164 eisa_cfg_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
8165 (PortAddr) (ASC_EISA_CFG_IOP_MASK);
8166 return (inpw(eisa_cfg_iop));
1da177e4
LT
8167}
8168
27c868c2 8169static uchar __init AscSetChipScsiID(PortAddr iop_base, uchar new_host_id)
1da177e4 8170{
27c868c2 8171 ushort cfg_lsw;
1da177e4 8172
27c868c2
MW
8173 if (AscGetChipScsiID(iop_base) == new_host_id) {
8174 return (new_host_id);
8175 }
8176 cfg_lsw = AscGetChipCfgLsw(iop_base);
8177 cfg_lsw &= 0xF8FF;
8178 cfg_lsw |= (ushort)((new_host_id & ASC_MAX_TID) << 8);
8179 AscSetChipCfgLsw(iop_base, cfg_lsw);
8180 return (AscGetChipScsiID(iop_base));
1da177e4
LT
8181}
8182
27c868c2 8183static uchar __init AscGetChipScsiCtrl(PortAddr iop_base)
1da177e4 8184{
27c868c2 8185 uchar sc;
1da177e4 8186
27c868c2
MW
8187 AscSetBank(iop_base, 1);
8188 sc = inp(iop_base + IOP_REG_SC);
8189 AscSetBank(iop_base, 0);
8190 return (sc);
1da177e4
LT
8191}
8192
27c868c2 8193static uchar __init AscGetChipVersion(PortAddr iop_base, ushort bus_type)
1da177e4 8194{
27c868c2
MW
8195 if ((bus_type & ASC_IS_EISA) != 0) {
8196 PortAddr eisa_iop;
8197 uchar revision;
8198 eisa_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
8199 (PortAddr) ASC_EISA_REV_IOP_MASK;
8200 revision = inp(eisa_iop);
8201 return ((uchar)((ASC_CHIP_MIN_VER_EISA - 1) + revision));
8202 }
8203 return (AscGetChipVerNo(iop_base));
1da177e4
LT
8204}
8205
27c868c2 8206static ushort __init AscGetChipBusType(PortAddr iop_base)
1da177e4 8207{
27c868c2
MW
8208 ushort chip_ver;
8209
8210 chip_ver = AscGetChipVerNo(iop_base);
8211 if ((chip_ver >= ASC_CHIP_MIN_VER_VL)
8212 && (chip_ver <= ASC_CHIP_MAX_VER_VL)
8213 ) {
8214 if (((iop_base & 0x0C30) == 0x0C30)
8215 || ((iop_base & 0x0C50) == 0x0C50)
8216 ) {
8217 return (ASC_IS_EISA);
8218 }
8219 return (ASC_IS_VL);
8220 }
8221 if ((chip_ver >= ASC_CHIP_MIN_VER_ISA) &&
8222 (chip_ver <= ASC_CHIP_MAX_VER_ISA)) {
8223 if (chip_ver >= ASC_CHIP_MIN_VER_ISA_PNP) {
8224 return (ASC_IS_ISAPNP);
8225 }
8226 return (ASC_IS_ISA);
8227 } else if ((chip_ver >= ASC_CHIP_MIN_VER_PCI) &&
8228 (chip_ver <= ASC_CHIP_MAX_VER_PCI)) {
8229 return (ASC_IS_PCI);
8230 }
8231 return (0);
1da177e4
LT
8232}
8233
27c868c2
MW
8234static ASC_DCNT
8235AscLoadMicroCode(PortAddr iop_base,
8236 ushort s_addr, uchar *mcode_buf, ushort mcode_size)
1da177e4 8237{
27c868c2
MW
8238 ASC_DCNT chksum;
8239 ushort mcode_word_size;
8240 ushort mcode_chksum;
8241
8242 /* Write the microcode buffer starting at LRAM address 0. */
8243 mcode_word_size = (ushort)(mcode_size >> 1);
8244 AscMemWordSetLram(iop_base, s_addr, 0, mcode_word_size);
8245 AscMemWordCopyPtrToLram(iop_base, s_addr, mcode_buf, mcode_word_size);
8246
8247 chksum = AscMemSumLramWord(iop_base, s_addr, mcode_word_size);
8248 ASC_DBG1(1, "AscLoadMicroCode: chksum 0x%lx\n", (ulong)chksum);
8249 mcode_chksum = (ushort)AscMemSumLramWord(iop_base,
8250 (ushort)ASC_CODE_SEC_BEG,
8251 (ushort)((mcode_size -
8252 s_addr - (ushort)
8253 ASC_CODE_SEC_BEG) /
8254 2));
8255 ASC_DBG1(1, "AscLoadMicroCode: mcode_chksum 0x%lx\n",
8256 (ulong)mcode_chksum);
8257 AscWriteLramWord(iop_base, ASCV_MCODE_CHKSUM_W, mcode_chksum);
8258 AscWriteLramWord(iop_base, ASCV_MCODE_SIZE_W, mcode_size);
8259 return (chksum);
1da177e4
LT
8260}
8261
27c868c2 8262static int AscFindSignature(PortAddr iop_base)
1da177e4 8263{
27c868c2
MW
8264 ushort sig_word;
8265
8266 ASC_DBG2(1, "AscFindSignature: AscGetChipSignatureByte(0x%x) 0x%x\n",
8267 iop_base, AscGetChipSignatureByte(iop_base));
8268 if (AscGetChipSignatureByte(iop_base) == (uchar)ASC_1000_ID1B) {
8269 ASC_DBG2(1,
8270 "AscFindSignature: AscGetChipSignatureWord(0x%x) 0x%x\n",
8271 iop_base, AscGetChipSignatureWord(iop_base));
8272 sig_word = AscGetChipSignatureWord(iop_base);
8273 if ((sig_word == (ushort)ASC_1000_ID0W) ||
8274 (sig_word == (ushort)ASC_1000_ID0W_FIX)) {
8275 return (1);
8276 }
8277 }
8278 return (0);
1da177e4
LT
8279}
8280
27c868c2
MW
8281static PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] __initdata = {
8282 0x100, ASC_IOADR_1, 0x120, ASC_IOADR_2, 0x140, ASC_IOADR_3, ASC_IOADR_4,
8283 ASC_IOADR_5, ASC_IOADR_6, ASC_IOADR_7, ASC_IOADR_8
1da177e4
LT
8284};
8285
8286#ifdef CONFIG_ISA
27c868c2 8287static uchar _isa_pnp_inited __initdata = 0;
1da177e4 8288
27c868c2 8289static PortAddr __init AscSearchIOPortAddr(PortAddr iop_beg, ushort bus_type)
1da177e4 8290{
27c868c2
MW
8291 if (bus_type & ASC_IS_VL) {
8292 while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) {
8293 if (AscGetChipVersion(iop_beg, bus_type) <=
8294 ASC_CHIP_MAX_VER_VL) {
8295 return (iop_beg);
8296 }
8297 }
8298 return (0);
8299 }
8300 if (bus_type & ASC_IS_ISA) {
8301 if (_isa_pnp_inited == 0) {
8302 AscSetISAPNPWaitForKey();
8303 _isa_pnp_inited++;
8304 }
8305 while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) {
8306 if ((AscGetChipVersion(iop_beg, bus_type) &
8307 ASC_CHIP_VER_ISA_BIT) != 0) {
8308 return (iop_beg);
8309 }
8310 }
8311 return (0);
8312 }
8313 if (bus_type & ASC_IS_EISA) {
8314 if ((iop_beg = AscSearchIOPortAddrEISA(iop_beg)) != 0) {
8315 return (iop_beg);
8316 }
8317 return (0);
8318 }
8319 return (0);
1da177e4
LT
8320}
8321
27c868c2 8322static PortAddr __init AscSearchIOPortAddr11(PortAddr s_addr)
1da177e4 8323{
27c868c2
MW
8324 int i;
8325 PortAddr iop_base;
1da177e4 8326
27c868c2
MW
8327 for (i = 0; i < ASC_IOADR_TABLE_MAX_IX; i++) {
8328 if (_asc_def_iop_base[i] > s_addr) {
8329 break;
8330 }
8331 }
8332 for (; i < ASC_IOADR_TABLE_MAX_IX; i++) {
8333 iop_base = _asc_def_iop_base[i];
8334 if (!request_region(iop_base, ASC_IOADR_GAP, "advansys")) {
8335 ASC_DBG1(1,
8336 "AscSearchIOPortAddr11: check_region() failed I/O port 0x%x\n",
8337 iop_base);
8338 continue;
8339 }
8340 ASC_DBG1(1, "AscSearchIOPortAddr11: probing I/O port 0x%x\n",
8341 iop_base);
8342 release_region(iop_base, ASC_IOADR_GAP);
8343 if (AscFindSignature(iop_base)) {
8344 return (iop_base);
8345 }
8346 }
8347 return (0);
1da177e4
LT
8348}
8349
27c868c2 8350static void __init AscSetISAPNPWaitForKey(void)
1da177e4 8351{
27c868c2
MW
8352 outp(ASC_ISA_PNP_PORT_ADDR, 0x02);
8353 outp(ASC_ISA_PNP_PORT_WRITE, 0x02);
8354 return;
1da177e4
LT
8355}
8356#endif /* CONFIG_ISA */
8357
27c868c2 8358static void __init AscToggleIRQAct(PortAddr iop_base)
1da177e4 8359{
27c868c2
MW
8360 AscSetChipStatus(iop_base, CIW_IRQ_ACT);
8361 AscSetChipStatus(iop_base, 0);
8362 return;
1da177e4
LT
8363}
8364
27c868c2 8365static uchar __init AscGetChipIRQ(PortAddr iop_base, ushort bus_type)
1da177e4 8366{
27c868c2
MW
8367 ushort cfg_lsw;
8368 uchar chip_irq;
8369
8370 if ((bus_type & ASC_IS_EISA) != 0) {
8371 cfg_lsw = AscGetEisaChipCfg(iop_base);
8372 chip_irq = (uchar)(((cfg_lsw >> 8) & 0x07) + 10);
8373 if ((chip_irq == 13) || (chip_irq > 15)) {
8374 return (0);
8375 }
8376 return (chip_irq);
8377 }
8378 if ((bus_type & ASC_IS_VL) != 0) {
8379 cfg_lsw = AscGetChipCfgLsw(iop_base);
8380 chip_irq = (uchar)(((cfg_lsw >> 2) & 0x07));
8381 if ((chip_irq == 0) || (chip_irq == 4) || (chip_irq == 7)) {
8382 return (0);
8383 }
8384 return ((uchar)(chip_irq + (ASC_MIN_IRQ_NO - 1)));
8385 }
8386 cfg_lsw = AscGetChipCfgLsw(iop_base);
8387 chip_irq = (uchar)(((cfg_lsw >> 2) & 0x03));
8388 if (chip_irq == 3)
8389 chip_irq += (uchar)2;
8390 return ((uchar)(chip_irq + ASC_MIN_IRQ_NO));
1da177e4
LT
8391}
8392
27c868c2
MW
8393static uchar __init
8394AscSetChipIRQ(PortAddr iop_base, uchar irq_no, ushort bus_type)
1da177e4 8395{
27c868c2
MW
8396 ushort cfg_lsw;
8397
8398 if ((bus_type & ASC_IS_VL) != 0) {
8399 if (irq_no != 0) {
8400 if ((irq_no < ASC_MIN_IRQ_NO)
8401 || (irq_no > ASC_MAX_IRQ_NO)) {
8402 irq_no = 0;
8403 } else {
8404 irq_no -= (uchar)((ASC_MIN_IRQ_NO - 1));
8405 }
8406 }
8407 cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFE3);
8408 cfg_lsw |= (ushort)0x0010;
8409 AscSetChipCfgLsw(iop_base, cfg_lsw);
8410 AscToggleIRQAct(iop_base);
8411 cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFE0);
8412 cfg_lsw |= (ushort)((irq_no & 0x07) << 2);
8413 AscSetChipCfgLsw(iop_base, cfg_lsw);
8414 AscToggleIRQAct(iop_base);
8415 return (AscGetChipIRQ(iop_base, bus_type));
8416 }
8417 if ((bus_type & (ASC_IS_ISA)) != 0) {
8418 if (irq_no == 15)
8419 irq_no -= (uchar)2;
8420 irq_no -= (uchar)ASC_MIN_IRQ_NO;
8421 cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFF3);
8422 cfg_lsw |= (ushort)((irq_no & 0x03) << 2);
8423 AscSetChipCfgLsw(iop_base, cfg_lsw);
8424 return (AscGetChipIRQ(iop_base, bus_type));
8425 }
8426 return (0);
1da177e4
LT
8427}
8428
8429#ifdef CONFIG_ISA
27c868c2 8430static void __init AscEnableIsaDma(uchar dma_channel)
1da177e4 8431{
27c868c2
MW
8432 if (dma_channel < 4) {
8433 outp(0x000B, (ushort)(0xC0 | dma_channel));
8434 outp(0x000A, dma_channel);
8435 } else if (dma_channel < 8) {
8436 outp(0x00D6, (ushort)(0xC0 | (dma_channel - 4)));
8437 outp(0x00D4, (ushort)(dma_channel - 4));
8438 }
8439 return;
1da177e4
LT
8440}
8441#endif /* CONFIG_ISA */
8442
27c868c2 8443static int AscIsrChipHalted(ASC_DVC_VAR *asc_dvc)
1da177e4 8444{
27c868c2
MW
8445 EXT_MSG ext_msg;
8446 EXT_MSG out_msg;
8447 ushort halt_q_addr;
8448 int sdtr_accept;
8449 ushort int_halt_code;
8450 ASC_SCSI_BIT_ID_TYPE scsi_busy;
8451 ASC_SCSI_BIT_ID_TYPE target_id;
8452 PortAddr iop_base;
8453 uchar tag_code;
8454 uchar q_status;
8455 uchar halt_qp;
8456 uchar sdtr_data;
8457 uchar target_ix;
8458 uchar q_cntl, tid_no;
8459 uchar cur_dvc_qng;
8460 uchar asyn_sdtr;
8461 uchar scsi_status;
8462 asc_board_t *boardp;
8463
8464 ASC_ASSERT(asc_dvc->drv_ptr != NULL);
8465 boardp = asc_dvc->drv_ptr;
8466
8467 iop_base = asc_dvc->iop_base;
8468 int_halt_code = AscReadLramWord(iop_base, ASCV_HALTCODE_W);
8469
8470 halt_qp = AscReadLramByte(iop_base, ASCV_CURCDB_B);
8471 halt_q_addr = ASC_QNO_TO_QADDR(halt_qp);
8472 target_ix = AscReadLramByte(iop_base,
8473 (ushort)(halt_q_addr +
8474 (ushort)ASC_SCSIQ_B_TARGET_IX));
8475 q_cntl =
8476 AscReadLramByte(iop_base,
8477 (ushort)(halt_q_addr + (ushort)ASC_SCSIQ_B_CNTL));
8478 tid_no = ASC_TIX_TO_TID(target_ix);
8479 target_id = (uchar)ASC_TID_TO_TARGET_ID(tid_no);
8480 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
8481 asyn_sdtr = ASYN_SDTR_DATA_FIX_PCI_REV_AB;
8482 } else {
8483 asyn_sdtr = 0;
8484 }
8485 if (int_halt_code == ASC_HALT_DISABLE_ASYN_USE_SYN_FIX) {
8486 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
8487 AscSetChipSDTR(iop_base, 0, tid_no);
8488 boardp->sdtr_data[tid_no] = 0;
8489 }
8490 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8491 return (0);
8492 } else if (int_halt_code == ASC_HALT_ENABLE_ASYN_USE_SYN_FIX) {
8493 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
8494 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
8495 boardp->sdtr_data[tid_no] = asyn_sdtr;
8496 }
8497 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8498 return (0);
8499 } else if (int_halt_code == ASC_HALT_EXTMSG_IN) {
8500
8501 AscMemWordCopyPtrFromLram(iop_base,
8502 ASCV_MSGIN_BEG,
8503 (uchar *)&ext_msg,
8504 sizeof(EXT_MSG) >> 1);
8505
8506 if (ext_msg.msg_type == MS_EXTEND &&
8507 ext_msg.msg_req == MS_SDTR_CODE &&
8508 ext_msg.msg_len == MS_SDTR_LEN) {
8509 sdtr_accept = TRUE;
8510 if ((ext_msg.req_ack_offset > ASC_SYN_MAX_OFFSET)) {
8511
8512 sdtr_accept = FALSE;
8513 ext_msg.req_ack_offset = ASC_SYN_MAX_OFFSET;
8514 }
8515 if ((ext_msg.xfer_period <
8516 asc_dvc->sdtr_period_tbl[asc_dvc->
8517 host_init_sdtr_index])
8518 || (ext_msg.xfer_period >
8519 asc_dvc->sdtr_period_tbl[asc_dvc->
8520 max_sdtr_index])) {
8521 sdtr_accept = FALSE;
8522 ext_msg.xfer_period =
8523 asc_dvc->sdtr_period_tbl[asc_dvc->
8524 host_init_sdtr_index];
8525 }
8526 if (sdtr_accept) {
8527 sdtr_data =
8528 AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
8529 ext_msg.req_ack_offset);
8530 if ((sdtr_data == 0xFF)) {
8531
8532 q_cntl |= QC_MSG_OUT;
8533 asc_dvc->init_sdtr &= ~target_id;
8534 asc_dvc->sdtr_done &= ~target_id;
8535 AscSetChipSDTR(iop_base, asyn_sdtr,
8536 tid_no);
8537 boardp->sdtr_data[tid_no] = asyn_sdtr;
8538 }
8539 }
8540 if (ext_msg.req_ack_offset == 0) {
8541
8542 q_cntl &= ~QC_MSG_OUT;
8543 asc_dvc->init_sdtr &= ~target_id;
8544 asc_dvc->sdtr_done &= ~target_id;
8545 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
8546 } else {
8547 if (sdtr_accept && (q_cntl & QC_MSG_OUT)) {
8548
8549 q_cntl &= ~QC_MSG_OUT;
8550 asc_dvc->sdtr_done |= target_id;
8551 asc_dvc->init_sdtr |= target_id;
8552 asc_dvc->pci_fix_asyn_xfer &=
8553 ~target_id;
8554 sdtr_data =
8555 AscCalSDTRData(asc_dvc,
8556 ext_msg.xfer_period,
8557 ext_msg.
8558 req_ack_offset);
8559 AscSetChipSDTR(iop_base, sdtr_data,
8560 tid_no);
8561 boardp->sdtr_data[tid_no] = sdtr_data;
8562 } else {
8563
8564 q_cntl |= QC_MSG_OUT;
8565 AscMsgOutSDTR(asc_dvc,
8566 ext_msg.xfer_period,
8567 ext_msg.req_ack_offset);
8568 asc_dvc->pci_fix_asyn_xfer &=
8569 ~target_id;
8570 sdtr_data =
8571 AscCalSDTRData(asc_dvc,
8572 ext_msg.xfer_period,
8573 ext_msg.
8574 req_ack_offset);
8575 AscSetChipSDTR(iop_base, sdtr_data,
8576 tid_no);
8577 boardp->sdtr_data[tid_no] = sdtr_data;
8578 asc_dvc->sdtr_done |= target_id;
8579 asc_dvc->init_sdtr |= target_id;
8580 }
8581 }
8582
8583 AscWriteLramByte(iop_base,
8584 (ushort)(halt_q_addr +
8585 (ushort)ASC_SCSIQ_B_CNTL),
8586 q_cntl);
8587 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8588 return (0);
8589 } else if (ext_msg.msg_type == MS_EXTEND &&
8590 ext_msg.msg_req == MS_WDTR_CODE &&
8591 ext_msg.msg_len == MS_WDTR_LEN) {
8592
8593 ext_msg.wdtr_width = 0;
8594 AscMemWordCopyPtrToLram(iop_base,
8595 ASCV_MSGOUT_BEG,
8596 (uchar *)&ext_msg,
8597 sizeof(EXT_MSG) >> 1);
8598 q_cntl |= QC_MSG_OUT;
8599 AscWriteLramByte(iop_base,
8600 (ushort)(halt_q_addr +
8601 (ushort)ASC_SCSIQ_B_CNTL),
8602 q_cntl);
8603 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8604 return (0);
8605 } else {
8606
8607 ext_msg.msg_type = MESSAGE_REJECT;
8608 AscMemWordCopyPtrToLram(iop_base,
8609 ASCV_MSGOUT_BEG,
8610 (uchar *)&ext_msg,
8611 sizeof(EXT_MSG) >> 1);
8612 q_cntl |= QC_MSG_OUT;
8613 AscWriteLramByte(iop_base,
8614 (ushort)(halt_q_addr +
8615 (ushort)ASC_SCSIQ_B_CNTL),
8616 q_cntl);
8617 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8618 return (0);
8619 }
8620 } else if (int_halt_code == ASC_HALT_CHK_CONDITION) {
8621
8622 q_cntl |= QC_REQ_SENSE;
8623
8624 if ((asc_dvc->init_sdtr & target_id) != 0) {
8625
8626 asc_dvc->sdtr_done &= ~target_id;
8627
8628 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
8629 q_cntl |= QC_MSG_OUT;
8630 AscMsgOutSDTR(asc_dvc,
8631 asc_dvc->
8632 sdtr_period_tbl[(sdtr_data >> 4) &
8633 (uchar)(asc_dvc->
8634 max_sdtr_index -
8635 1)],
8636 (uchar)(sdtr_data & (uchar)
8637 ASC_SYN_MAX_OFFSET));
8638 }
8639
8640 AscWriteLramByte(iop_base,
8641 (ushort)(halt_q_addr +
8642 (ushort)ASC_SCSIQ_B_CNTL), q_cntl);
8643
8644 tag_code = AscReadLramByte(iop_base,
8645 (ushort)(halt_q_addr + (ushort)
8646 ASC_SCSIQ_B_TAG_CODE));
8647 tag_code &= 0xDC;
8648 if ((asc_dvc->pci_fix_asyn_xfer & target_id)
8649 && !(asc_dvc->pci_fix_asyn_xfer_always & target_id)
8650 ) {
8651
8652 tag_code |= (ASC_TAG_FLAG_DISABLE_DISCONNECT
8653 | ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX);
8654
8655 }
8656 AscWriteLramByte(iop_base,
8657 (ushort)(halt_q_addr +
8658 (ushort)ASC_SCSIQ_B_TAG_CODE),
8659 tag_code);
8660
8661 q_status = AscReadLramByte(iop_base,
8662 (ushort)(halt_q_addr + (ushort)
8663 ASC_SCSIQ_B_STATUS));
8664 q_status |= (QS_READY | QS_BUSY);
8665 AscWriteLramByte(iop_base,
8666 (ushort)(halt_q_addr +
8667 (ushort)ASC_SCSIQ_B_STATUS),
8668 q_status);
8669
8670 scsi_busy = AscReadLramByte(iop_base, (ushort)ASCV_SCSIBUSY_B);
8671 scsi_busy &= ~target_id;
8672 AscWriteLramByte(iop_base, (ushort)ASCV_SCSIBUSY_B, scsi_busy);
8673
8674 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8675 return (0);
8676 } else if (int_halt_code == ASC_HALT_SDTR_REJECTED) {
8677
8678 AscMemWordCopyPtrFromLram(iop_base,
8679 ASCV_MSGOUT_BEG,
8680 (uchar *)&out_msg,
8681 sizeof(EXT_MSG) >> 1);
8682
8683 if ((out_msg.msg_type == MS_EXTEND) &&
8684 (out_msg.msg_len == MS_SDTR_LEN) &&
8685 (out_msg.msg_req == MS_SDTR_CODE)) {
8686
8687 asc_dvc->init_sdtr &= ~target_id;
8688 asc_dvc->sdtr_done &= ~target_id;
8689 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
8690 boardp->sdtr_data[tid_no] = asyn_sdtr;
8691 }
8692 q_cntl &= ~QC_MSG_OUT;
8693 AscWriteLramByte(iop_base,
8694 (ushort)(halt_q_addr +
8695 (ushort)ASC_SCSIQ_B_CNTL), q_cntl);
8696 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8697 return (0);
8698 } else if (int_halt_code == ASC_HALT_SS_QUEUE_FULL) {
8699
8700 scsi_status = AscReadLramByte(iop_base,
8701 (ushort)((ushort)halt_q_addr +
8702 (ushort)
8703 ASC_SCSIQ_SCSI_STATUS));
8704 cur_dvc_qng =
8705 AscReadLramByte(iop_base,
8706 (ushort)((ushort)ASC_QADR_BEG +
8707 (ushort)target_ix));
8708 if ((cur_dvc_qng > 0) && (asc_dvc->cur_dvc_qng[tid_no] > 0)) {
8709
8710 scsi_busy = AscReadLramByte(iop_base,
8711 (ushort)ASCV_SCSIBUSY_B);
8712 scsi_busy |= target_id;
8713 AscWriteLramByte(iop_base,
8714 (ushort)ASCV_SCSIBUSY_B, scsi_busy);
8715 asc_dvc->queue_full_or_busy |= target_id;
8716
8717 if (scsi_status == SAM_STAT_TASK_SET_FULL) {
8718 if (cur_dvc_qng > ASC_MIN_TAGGED_CMD) {
8719 cur_dvc_qng -= 1;
8720 asc_dvc->max_dvc_qng[tid_no] =
8721 cur_dvc_qng;
8722
8723 AscWriteLramByte(iop_base,
8724 (ushort)((ushort)
8725 ASCV_MAX_DVC_QNG_BEG
8726 + (ushort)
8727 tid_no),
8728 cur_dvc_qng);
8729
8730 /*
8731 * Set the device queue depth to the number of
8732 * active requests when the QUEUE FULL condition
8733 * was encountered.
8734 */
8735 boardp->queue_full |= target_id;
8736 boardp->queue_full_cnt[tid_no] =
8737 cur_dvc_qng;
8738 }
8739 }
8740 }
8741 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8742 return (0);
8743 }
1da177e4 8744#if CC_VERY_LONG_SG_LIST
27c868c2
MW
8745 else if (int_halt_code == ASC_HALT_HOST_COPY_SG_LIST_TO_RISC) {
8746 uchar q_no;
8747 ushort q_addr;
8748 uchar sg_wk_q_no;
8749 uchar first_sg_wk_q_no;
8750 ASC_SCSI_Q *scsiq; /* Ptr to driver request. */
8751 ASC_SG_HEAD *sg_head; /* Ptr to driver SG request. */
8752 ASC_SG_LIST_Q scsi_sg_q; /* Structure written to queue. */
8753 ushort sg_list_dwords;
8754 ushort sg_entry_cnt;
8755 uchar next_qp;
8756 int i;
8757
8758 q_no = AscReadLramByte(iop_base, (ushort)ASCV_REQ_SG_LIST_QP);
8759 if (q_no == ASC_QLINK_END) {
8760 return (0);
8761 }
8762
8763 q_addr = ASC_QNO_TO_QADDR(q_no);
8764
8765 /*
8766 * Convert the request's SRB pointer to a host ASC_SCSI_REQ
8767 * structure pointer using a macro provided by the driver.
8768 * The ASC_SCSI_REQ pointer provides a pointer to the
8769 * host ASC_SG_HEAD structure.
8770 */
8771 /* Read request's SRB pointer. */
8772 scsiq = (ASC_SCSI_Q *)
8773 ASC_SRB2SCSIQ(ASC_U32_TO_VADDR(AscReadLramDWord(iop_base,
8774 (ushort)
8775 (q_addr +
8776 ASC_SCSIQ_D_SRBPTR))));
8777
8778 /*
8779 * Get request's first and working SG queue.
8780 */
8781 sg_wk_q_no = AscReadLramByte(iop_base,
8782 (ushort)(q_addr +
8783 ASC_SCSIQ_B_SG_WK_QP));
8784
8785 first_sg_wk_q_no = AscReadLramByte(iop_base,
8786 (ushort)(q_addr +
8787 ASC_SCSIQ_B_FIRST_SG_WK_QP));
8788
8789 /*
8790 * Reset request's working SG queue back to the
8791 * first SG queue.
8792 */
8793 AscWriteLramByte(iop_base,
8794 (ushort)(q_addr +
8795 (ushort)ASC_SCSIQ_B_SG_WK_QP),
8796 first_sg_wk_q_no);
8797
8798 sg_head = scsiq->sg_head;
8799
8800 /*
8801 * Set sg_entry_cnt to the number of SG elements
8802 * that will be completed on this interrupt.
8803 *
8804 * Note: The allocated SG queues contain ASC_MAX_SG_LIST - 1
8805 * SG elements. The data_cnt and data_addr fields which
8806 * add 1 to the SG element capacity are not used when
8807 * restarting SG handling after a halt.
8808 */
8809 if (scsiq->remain_sg_entry_cnt > (ASC_MAX_SG_LIST - 1)) {
8810 sg_entry_cnt = ASC_MAX_SG_LIST - 1;
8811
8812 /*
8813 * Keep track of remaining number of SG elements that will
8814 * need to be handled on the next interrupt.
8815 */
8816 scsiq->remain_sg_entry_cnt -= (ASC_MAX_SG_LIST - 1);
8817 } else {
8818 sg_entry_cnt = scsiq->remain_sg_entry_cnt;
8819 scsiq->remain_sg_entry_cnt = 0;
8820 }
8821
8822 /*
8823 * Copy SG elements into the list of allocated SG queues.
8824 *
8825 * Last index completed is saved in scsiq->next_sg_index.
8826 */
8827 next_qp = first_sg_wk_q_no;
8828 q_addr = ASC_QNO_TO_QADDR(next_qp);
8829 scsi_sg_q.sg_head_qp = q_no;
8830 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
8831 for (i = 0; i < sg_head->queue_cnt; i++) {
8832 scsi_sg_q.seq_no = i + 1;
8833 if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
8834 sg_list_dwords = (uchar)(ASC_SG_LIST_PER_Q * 2);
8835 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
8836 /*
8837 * After very first SG queue RISC FW uses next
8838 * SG queue first element then checks sg_list_cnt
8839 * against zero and then decrements, so set
8840 * sg_list_cnt 1 less than number of SG elements
8841 * in each SG queue.
8842 */
8843 scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q - 1;
8844 scsi_sg_q.sg_cur_list_cnt =
8845 ASC_SG_LIST_PER_Q - 1;
8846 } else {
8847 /*
8848 * This is the last SG queue in the list of
8849 * allocated SG queues. If there are more
8850 * SG elements than will fit in the allocated
8851 * queues, then set the QCSG_SG_XFER_MORE flag.
8852 */
8853 if (scsiq->remain_sg_entry_cnt != 0) {
8854 scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
8855 } else {
8856 scsi_sg_q.cntl |= QCSG_SG_XFER_END;
8857 }
8858 /* equals sg_entry_cnt * 2 */
8859 sg_list_dwords = sg_entry_cnt << 1;
8860 scsi_sg_q.sg_list_cnt = sg_entry_cnt - 1;
8861 scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt - 1;
8862 sg_entry_cnt = 0;
8863 }
8864
8865 scsi_sg_q.q_no = next_qp;
8866 AscMemWordCopyPtrToLram(iop_base,
8867 q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
8868 (uchar *)&scsi_sg_q,
8869 sizeof(ASC_SG_LIST_Q) >> 1);
8870
8871 AscMemDWordCopyPtrToLram(iop_base,
8872 q_addr + ASC_SGQ_LIST_BEG,
8873 (uchar *)&sg_head->
8874 sg_list[scsiq->next_sg_index],
8875 sg_list_dwords);
8876
8877 scsiq->next_sg_index += ASC_SG_LIST_PER_Q;
8878
8879 /*
8880 * If the just completed SG queue contained the
8881 * last SG element, then no more SG queues need
8882 * to be written.
8883 */
8884 if (scsi_sg_q.cntl & QCSG_SG_XFER_END) {
8885 break;
8886 }
8887
8888 next_qp = AscReadLramByte(iop_base,
8889 (ushort)(q_addr +
8890 ASC_SCSIQ_B_FWD));
8891 q_addr = ASC_QNO_TO_QADDR(next_qp);
8892 }
8893
8894 /*
8895 * Clear the halt condition so the RISC will be restarted
8896 * after the return.
8897 */
8898 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8899 return (0);
8900 }
1da177e4 8901#endif /* CC_VERY_LONG_SG_LIST */
27c868c2 8902 return (0);
1da177e4
LT
8903}
8904
27c868c2
MW
8905static uchar
8906_AscCopyLramScsiDoneQ(PortAddr iop_base,
8907 ushort q_addr,
8908 ASC_QDONE_INFO *scsiq, ASC_DCNT max_dma_count)
1da177e4 8909{
27c868c2
MW
8910 ushort _val;
8911 uchar sg_queue_cnt;
8912
8913 DvcGetQinfo(iop_base,
8914 q_addr + ASC_SCSIQ_DONE_INFO_BEG,
8915 (uchar *)scsiq,
8916 (sizeof(ASC_SCSIQ_2) + sizeof(ASC_SCSIQ_3)) / 2);
8917
8918 _val = AscReadLramWord(iop_base,
8919 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_STATUS));
8920 scsiq->q_status = (uchar)_val;
8921 scsiq->q_no = (uchar)(_val >> 8);
8922 _val = AscReadLramWord(iop_base,
8923 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_CNTL));
8924 scsiq->cntl = (uchar)_val;
8925 sg_queue_cnt = (uchar)(_val >> 8);
8926 _val = AscReadLramWord(iop_base,
8927 (ushort)(q_addr +
8928 (ushort)ASC_SCSIQ_B_SENSE_LEN));
8929 scsiq->sense_len = (uchar)_val;
8930 scsiq->extra_bytes = (uchar)(_val >> 8);
8931
8932 /*
8933 * Read high word of remain bytes from alternate location.
8934 */
8935 scsiq->remain_bytes = (((ADV_DCNT)AscReadLramWord(iop_base,
8936 (ushort)(q_addr +
8937 (ushort)
8938 ASC_SCSIQ_W_ALT_DC1)))
8939 << 16);
8940 /*
8941 * Read low word of remain bytes from original location.
8942 */
8943 scsiq->remain_bytes += AscReadLramWord(iop_base,
8944 (ushort)(q_addr + (ushort)
8945 ASC_SCSIQ_DW_REMAIN_XFER_CNT));
8946
8947 scsiq->remain_bytes &= max_dma_count;
8948 return (sg_queue_cnt);
1da177e4
LT
8949}
8950
27c868c2 8951static int AscIsrQDone(ASC_DVC_VAR *asc_dvc)
1da177e4 8952{
27c868c2
MW
8953 uchar next_qp;
8954 uchar n_q_used;
8955 uchar sg_list_qp;
8956 uchar sg_queue_cnt;
8957 uchar q_cnt;
8958 uchar done_q_tail;
8959 uchar tid_no;
8960 ASC_SCSI_BIT_ID_TYPE scsi_busy;
8961 ASC_SCSI_BIT_ID_TYPE target_id;
8962 PortAddr iop_base;
8963 ushort q_addr;
8964 ushort sg_q_addr;
8965 uchar cur_target_qng;
8966 ASC_QDONE_INFO scsiq_buf;
8967 ASC_QDONE_INFO *scsiq;
8968 int false_overrun;
8969 ASC_ISR_CALLBACK asc_isr_callback;
8970
8971 iop_base = asc_dvc->iop_base;
8972 asc_isr_callback = asc_dvc->isr_callback;
8973 n_q_used = 1;
8974 scsiq = (ASC_QDONE_INFO *)&scsiq_buf;
8975 done_q_tail = (uchar)AscGetVarDoneQTail(iop_base);
8976 q_addr = ASC_QNO_TO_QADDR(done_q_tail);
8977 next_qp = AscReadLramByte(iop_base,
8978 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_FWD));
8979 if (next_qp != ASC_QLINK_END) {
8980 AscPutVarDoneQTail(iop_base, next_qp);
8981 q_addr = ASC_QNO_TO_QADDR(next_qp);
8982 sg_queue_cnt = _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq,
8983 asc_dvc->max_dma_count);
8984 AscWriteLramByte(iop_base,
8985 (ushort)(q_addr +
8986 (ushort)ASC_SCSIQ_B_STATUS),
8987 (uchar)(scsiq->
8988 q_status & (uchar)~(QS_READY |
8989 QS_ABORTED)));
8990 tid_no = ASC_TIX_TO_TID(scsiq->d2.target_ix);
8991 target_id = ASC_TIX_TO_TARGET_ID(scsiq->d2.target_ix);
8992 if ((scsiq->cntl & QC_SG_HEAD) != 0) {
8993 sg_q_addr = q_addr;
8994 sg_list_qp = next_qp;
8995 for (q_cnt = 0; q_cnt < sg_queue_cnt; q_cnt++) {
8996 sg_list_qp = AscReadLramByte(iop_base,
8997 (ushort)(sg_q_addr
8998 + (ushort)
8999 ASC_SCSIQ_B_FWD));
9000 sg_q_addr = ASC_QNO_TO_QADDR(sg_list_qp);
9001 if (sg_list_qp == ASC_QLINK_END) {
9002 AscSetLibErrorCode(asc_dvc,
9003 ASCQ_ERR_SG_Q_LINKS);
9004 scsiq->d3.done_stat = QD_WITH_ERROR;
9005 scsiq->d3.host_stat =
9006 QHSTA_D_QDONE_SG_LIST_CORRUPTED;
9007 goto FATAL_ERR_QDONE;
9008 }
9009 AscWriteLramByte(iop_base,
9010 (ushort)(sg_q_addr + (ushort)
9011 ASC_SCSIQ_B_STATUS),
9012 QS_FREE);
9013 }
9014 n_q_used = sg_queue_cnt + 1;
9015 AscPutVarDoneQTail(iop_base, sg_list_qp);
9016 }
9017 if (asc_dvc->queue_full_or_busy & target_id) {
9018 cur_target_qng = AscReadLramByte(iop_base,
9019 (ushort)((ushort)
9020 ASC_QADR_BEG
9021 + (ushort)
9022 scsiq->d2.
9023 target_ix));
9024 if (cur_target_qng < asc_dvc->max_dvc_qng[tid_no]) {
9025 scsi_busy = AscReadLramByte(iop_base, (ushort)
9026 ASCV_SCSIBUSY_B);
9027 scsi_busy &= ~target_id;
9028 AscWriteLramByte(iop_base,
9029 (ushort)ASCV_SCSIBUSY_B,
9030 scsi_busy);
9031 asc_dvc->queue_full_or_busy &= ~target_id;
9032 }
9033 }
9034 if (asc_dvc->cur_total_qng >= n_q_used) {
9035 asc_dvc->cur_total_qng -= n_q_used;
9036 if (asc_dvc->cur_dvc_qng[tid_no] != 0) {
9037 asc_dvc->cur_dvc_qng[tid_no]--;
9038 }
9039 } else {
9040 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CUR_QNG);
9041 scsiq->d3.done_stat = QD_WITH_ERROR;
9042 goto FATAL_ERR_QDONE;
9043 }
9044 if ((scsiq->d2.srb_ptr == 0UL) ||
9045 ((scsiq->q_status & QS_ABORTED) != 0)) {
9046 return (0x11);
9047 } else if (scsiq->q_status == QS_DONE) {
9048 false_overrun = FALSE;
9049 if (scsiq->extra_bytes != 0) {
9050 scsiq->remain_bytes +=
9051 (ADV_DCNT)scsiq->extra_bytes;
9052 }
9053 if (scsiq->d3.done_stat == QD_WITH_ERROR) {
9054 if (scsiq->d3.host_stat ==
9055 QHSTA_M_DATA_OVER_RUN) {
9056 if ((scsiq->
9057 cntl & (QC_DATA_IN | QC_DATA_OUT))
9058 == 0) {
9059 scsiq->d3.done_stat =
9060 QD_NO_ERROR;
9061 scsiq->d3.host_stat =
9062 QHSTA_NO_ERROR;
9063 } else if (false_overrun) {
9064 scsiq->d3.done_stat =
9065 QD_NO_ERROR;
9066 scsiq->d3.host_stat =
9067 QHSTA_NO_ERROR;
9068 }
9069 } else if (scsiq->d3.host_stat ==
9070 QHSTA_M_HUNG_REQ_SCSI_BUS_RESET) {
9071 AscStopChip(iop_base);
9072 AscSetChipControl(iop_base,
9073 (uchar)(CC_SCSI_RESET
9074 | CC_HALT));
9075 DvcDelayNanoSecond(asc_dvc, 60000);
9076 AscSetChipControl(iop_base, CC_HALT);
9077 AscSetChipStatus(iop_base,
9078 CIW_CLR_SCSI_RESET_INT);
9079 AscSetChipStatus(iop_base, 0);
9080 AscSetChipControl(iop_base, 0);
9081 }
9082 }
9083 if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
9084 (*asc_isr_callback) (asc_dvc, scsiq);
9085 } else {
9086 if ((AscReadLramByte(iop_base,
9087 (ushort)(q_addr + (ushort)
9088 ASC_SCSIQ_CDB_BEG))
9089 == START_STOP)) {
9090 asc_dvc->unit_not_ready &= ~target_id;
9091 if (scsiq->d3.done_stat != QD_NO_ERROR) {
9092 asc_dvc->start_motor &=
9093 ~target_id;
9094 }
9095 }
9096 }
9097 return (1);
9098 } else {
9099 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_Q_STATUS);
9100 FATAL_ERR_QDONE:
9101 if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
9102 (*asc_isr_callback) (asc_dvc, scsiq);
9103 }
9104 return (0x80);
9105 }
9106 }
9107 return (0);
1da177e4
LT
9108}
9109
27c868c2 9110static int AscISR(ASC_DVC_VAR *asc_dvc)
1da177e4 9111{
27c868c2
MW
9112 ASC_CS_TYPE chipstat;
9113 PortAddr iop_base;
9114 ushort saved_ram_addr;
9115 uchar ctrl_reg;
9116 uchar saved_ctrl_reg;
9117 int int_pending;
9118 int status;
9119 uchar host_flag;
9120
9121 iop_base = asc_dvc->iop_base;
9122 int_pending = FALSE;
9123
9124 if (AscIsIntPending(iop_base) == 0) {
9125 return int_pending;
9126 }
1da177e4 9127
27c868c2
MW
9128 if (((asc_dvc->init_state & ASC_INIT_STATE_END_LOAD_MC) == 0)
9129 || (asc_dvc->isr_callback == 0)
9130 ) {
9131 return (ERR);
9132 }
9133 if (asc_dvc->in_critical_cnt != 0) {
9134 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_ON_CRITICAL);
9135 return (ERR);
9136 }
9137 if (asc_dvc->is_in_int) {
9138 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_RE_ENTRY);
9139 return (ERR);
9140 }
9141 asc_dvc->is_in_int = TRUE;
9142 ctrl_reg = AscGetChipControl(iop_base);
9143 saved_ctrl_reg = ctrl_reg & (~(CC_SCSI_RESET | CC_CHIP_RESET |
9144 CC_SINGLE_STEP | CC_DIAG | CC_TEST));
9145 chipstat = AscGetChipStatus(iop_base);
9146 if (chipstat & CSW_SCSI_RESET_LATCH) {
9147 if (!(asc_dvc->bus_type & (ASC_IS_VL | ASC_IS_EISA))) {
9148 int i = 10;
9149 int_pending = TRUE;
9150 asc_dvc->sdtr_done = 0;
9151 saved_ctrl_reg &= (uchar)(~CC_HALT);
9152 while ((AscGetChipStatus(iop_base) &
9153 CSW_SCSI_RESET_ACTIVE) && (i-- > 0)) {
9154 DvcSleepMilliSecond(100);
9155 }
9156 AscSetChipControl(iop_base, (CC_CHIP_RESET | CC_HALT));
9157 AscSetChipControl(iop_base, CC_HALT);
9158 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
9159 AscSetChipStatus(iop_base, 0);
9160 chipstat = AscGetChipStatus(iop_base);
9161 }
9162 }
9163 saved_ram_addr = AscGetChipLramAddr(iop_base);
9164 host_flag = AscReadLramByte(iop_base,
9165 ASCV_HOST_FLAG_B) &
9166 (uchar)(~ASC_HOST_FLAG_IN_ISR);
9167 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
9168 (uchar)(host_flag | (uchar)ASC_HOST_FLAG_IN_ISR));
9169 if ((chipstat & CSW_INT_PENDING)
9170 || (int_pending)
9171 ) {
9172 AscAckInterrupt(iop_base);
9173 int_pending = TRUE;
9174 if ((chipstat & CSW_HALTED) && (ctrl_reg & CC_SINGLE_STEP)) {
9175 if (AscIsrChipHalted(asc_dvc) == ERR) {
9176 goto ISR_REPORT_QDONE_FATAL_ERROR;
9177 } else {
9178 saved_ctrl_reg &= (uchar)(~CC_HALT);
9179 }
9180 } else {
9181 ISR_REPORT_QDONE_FATAL_ERROR:
9182 if ((asc_dvc->dvc_cntl & ASC_CNTL_INT_MULTI_Q) != 0) {
9183 while (((status =
9184 AscIsrQDone(asc_dvc)) & 0x01) != 0) {
9185 }
9186 } else {
9187 do {
9188 if ((status =
9189 AscIsrQDone(asc_dvc)) == 1) {
9190 break;
9191 }
9192 } while (status == 0x11);
9193 }
9194 if ((status & 0x80) != 0)
9195 int_pending = ERR;
9196 }
9197 }
9198 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
9199 AscSetChipLramAddr(iop_base, saved_ram_addr);
9200 AscSetChipControl(iop_base, saved_ctrl_reg);
9201 asc_dvc->is_in_int = FALSE;
9202 return (int_pending);
1da177e4
LT
9203}
9204
9205/* Microcode buffer is kept after initialization for error recovery. */
27c868c2
MW
9206static uchar _asc_mcode_buf[] = {
9207 0x01, 0x03, 0x01, 0x19, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9208 0x00, 0x00, 0x00, 0x00,
9209 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00,
9210 0x00, 0x00, 0x00, 0x00,
9211 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9212 0x00, 0x00, 0x00, 0x00,
9213 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9214 0x00, 0x00, 0x00, 0x00,
9215 0x00, 0x00, 0x00, 0x00, 0xC3, 0x12, 0x0D, 0x05, 0x01, 0x00, 0x00, 0x00,
9216 0x00, 0xFF, 0x00, 0x00,
9217 0x00, 0x00, 0x00, 0x00, 0xFF, 0x80, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00,
9218 0x00, 0x00, 0x00, 0x00,
9219 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0xFF,
9220 0x00, 0x00, 0x00, 0x00,
9221 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE4, 0x88,
9222 0x00, 0x00, 0x00, 0x00,
9223 0x80, 0x73, 0x48, 0x04, 0x36, 0x00, 0x00, 0xA2, 0xC2, 0x00, 0x80, 0x73,
9224 0x03, 0x23, 0x36, 0x40,
9225 0xB6, 0x00, 0x36, 0x00, 0x05, 0xD6, 0x0C, 0xD2, 0x12, 0xDA, 0x00, 0xA2,
9226 0xC2, 0x00, 0x92, 0x80,
9227 0x1E, 0x98, 0x50, 0x00, 0xF5, 0x00, 0x48, 0x98, 0xDF, 0x23, 0x36, 0x60,
9228 0xB6, 0x00, 0x92, 0x80,
9229 0x4F, 0x00, 0xF5, 0x00, 0x48, 0x98, 0xEF, 0x23, 0x36, 0x60, 0xB6, 0x00,
9230 0x92, 0x80, 0x80, 0x62,
9231 0x92, 0x80, 0x00, 0x46, 0x15, 0xEE, 0x13, 0xEA, 0x02, 0x01, 0x09, 0xD8,
9232 0xCD, 0x04, 0x4D, 0x00,
9233 0x00, 0xA3, 0xD6, 0x00, 0xA6, 0x97, 0x7F, 0x23, 0x04, 0x61, 0x84, 0x01,
9234 0xE6, 0x84, 0xD2, 0xC1,
9235 0x80, 0x73, 0xCD, 0x04, 0x4D, 0x00, 0x00, 0xA3, 0xDA, 0x01, 0xA6, 0x97,
9236 0xC6, 0x81, 0xC2, 0x88,
9237 0x80, 0x73, 0x80, 0x77, 0x00, 0x01, 0x01, 0xA1, 0xFE, 0x00, 0x4F, 0x00,
9238 0x84, 0x97, 0x07, 0xA6,
9239 0x08, 0x01, 0x00, 0x33, 0x03, 0x00, 0xC2, 0x88, 0x03, 0x03, 0x01, 0xDE,
9240 0xC2, 0x88, 0xCE, 0x00,
9241 0x69, 0x60, 0xCE, 0x00, 0x02, 0x03, 0x4A, 0x60, 0x00, 0xA2, 0x78, 0x01,
9242 0x80, 0x63, 0x07, 0xA6,
9243 0x24, 0x01, 0x78, 0x81, 0x03, 0x03, 0x80, 0x63, 0xE2, 0x00, 0x07, 0xA6,
9244 0x34, 0x01, 0x00, 0x33,
9245 0x04, 0x00, 0xC2, 0x88, 0x03, 0x07, 0x02, 0x01, 0x04, 0xCA, 0x0D, 0x23,
9246 0x68, 0x98, 0x4D, 0x04,
9247 0x04, 0x85, 0x05, 0xD8, 0x0D, 0x23, 0x68, 0x98, 0xCD, 0x04, 0x15, 0x23,
9248 0xF8, 0x88, 0xFB, 0x23,
9249 0x02, 0x61, 0x82, 0x01, 0x80, 0x63, 0x02, 0x03, 0x06, 0xA3, 0x62, 0x01,
9250 0x00, 0x33, 0x0A, 0x00,
9251 0xC2, 0x88, 0x4E, 0x00, 0x07, 0xA3, 0x6E, 0x01, 0x00, 0x33, 0x0B, 0x00,
9252 0xC2, 0x88, 0xCD, 0x04,
9253 0x36, 0x2D, 0x00, 0x33, 0x1A, 0x00, 0xC2, 0x88, 0x50, 0x04, 0x88, 0x81,
9254 0x06, 0xAB, 0x82, 0x01,
9255 0x88, 0x81, 0x4E, 0x00, 0x07, 0xA3, 0x92, 0x01, 0x50, 0x00, 0x00, 0xA3,
9256 0x3C, 0x01, 0x00, 0x05,
9257 0x7C, 0x81, 0x46, 0x97, 0x02, 0x01, 0x05, 0xC6, 0x04, 0x23, 0xA0, 0x01,
9258 0x15, 0x23, 0xA1, 0x01,
9259 0xBE, 0x81, 0xFD, 0x23, 0x02, 0x61, 0x82, 0x01, 0x0A, 0xDA, 0x4A, 0x00,
9260 0x06, 0x61, 0x00, 0xA0,
9261 0xB4, 0x01, 0x80, 0x63, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33, 0x1B, 0x00,
9262 0xC2, 0x88, 0x06, 0x23,
9263 0x68, 0x98, 0xCD, 0x04, 0xE6, 0x84, 0x06, 0x01, 0x00, 0xA2, 0xD4, 0x01,
9264 0x57, 0x60, 0x00, 0xA0,
9265 0xDA, 0x01, 0xE6, 0x84, 0x80, 0x23, 0xA0, 0x01, 0xE6, 0x84, 0x80, 0x73,
9266 0x4B, 0x00, 0x06, 0x61,
9267 0x00, 0xA2, 0x00, 0x02, 0x04, 0x01, 0x0C, 0xDE, 0x02, 0x01, 0x03, 0xCC,
9268 0x4F, 0x00, 0x84, 0x97,
9269 0xFC, 0x81, 0x08, 0x23, 0x02, 0x41, 0x82, 0x01, 0x4F, 0x00, 0x62, 0x97,
9270 0x48, 0x04, 0x84, 0x80,
9271 0xF0, 0x97, 0x00, 0x46, 0x56, 0x00, 0x03, 0xC0, 0x01, 0x23, 0xE8, 0x00,
9272 0x81, 0x73, 0x06, 0x29,
9273 0x03, 0x42, 0x06, 0xE2, 0x03, 0xEE, 0x6B, 0xEB, 0x11, 0x23, 0xF8, 0x88,
9274 0x04, 0x98, 0xF0, 0x80,
9275 0x80, 0x73, 0x80, 0x77, 0x07, 0xA4, 0x2A, 0x02, 0x7C, 0x95, 0x06, 0xA6,
9276 0x34, 0x02, 0x03, 0xA6,
9277 0x4C, 0x04, 0x46, 0x82, 0x04, 0x01, 0x03, 0xD8, 0xB4, 0x98, 0x6A, 0x96,
9278 0x46, 0x82, 0xFE, 0x95,
9279 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0xB6, 0x2D, 0x02, 0xA6, 0x6C, 0x02,
9280 0x07, 0xA6, 0x5A, 0x02,
9281 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x62, 0x02, 0xC2, 0x88, 0x7C, 0x95,
9282 0x48, 0x82, 0x60, 0x96,
9283 0x48, 0x82, 0x04, 0x23, 0xA0, 0x01, 0x14, 0x23, 0xA1, 0x01, 0x3C, 0x84,
9284 0x04, 0x01, 0x0C, 0xDC,
9285 0xE0, 0x23, 0x25, 0x61, 0xEF, 0x00, 0x14, 0x01, 0x4F, 0x04, 0xA8, 0x01,
9286 0x6F, 0x00, 0xA5, 0x01,
9287 0x03, 0x23, 0xA4, 0x01, 0x06, 0x23, 0x9C, 0x01, 0x24, 0x2B, 0x1C, 0x01,
9288 0x02, 0xA6, 0xAA, 0x02,
9289 0x07, 0xA6, 0x5A, 0x02, 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x20, 0x04,
9290 0x01, 0xA6, 0xB4, 0x02,
9291 0x00, 0xA6, 0xB4, 0x02, 0x00, 0x33, 0x12, 0x00, 0xC2, 0x88, 0x00, 0x0E,
9292 0x80, 0x63, 0x00, 0x43,
9293 0x00, 0xA0, 0x8C, 0x02, 0x4D, 0x04, 0x04, 0x01, 0x0B, 0xDC, 0xE7, 0x23,
9294 0x04, 0x61, 0x84, 0x01,
9295 0x10, 0x31, 0x12, 0x35, 0x14, 0x01, 0xEC, 0x00, 0x6C, 0x38, 0x00, 0x3F,
9296 0x00, 0x00, 0xEA, 0x82,
9297 0x18, 0x23, 0x04, 0x61, 0x18, 0xA0, 0xE2, 0x02, 0x04, 0x01, 0xA2, 0xC8,
9298 0x00, 0x33, 0x1F, 0x00,
9299 0xC2, 0x88, 0x08, 0x31, 0x0A, 0x35, 0x0C, 0x39, 0x0E, 0x3D, 0x7E, 0x98,
9300 0xB6, 0x2D, 0x01, 0xA6,
9301 0x14, 0x03, 0x00, 0xA6, 0x14, 0x03, 0x07, 0xA6, 0x0C, 0x03, 0x06, 0xA6,
9302 0x10, 0x03, 0x03, 0xA6,
9303 0x20, 0x04, 0x02, 0xA6, 0x6C, 0x02, 0x00, 0x33, 0x33, 0x00, 0xC2, 0x88,
9304 0x7C, 0x95, 0xEE, 0x82,
9305 0x60, 0x96, 0xEE, 0x82, 0x82, 0x98, 0x80, 0x42, 0x7E, 0x98, 0x64, 0xE4,
9306 0x04, 0x01, 0x2D, 0xC8,
9307 0x31, 0x05, 0x07, 0x01, 0x00, 0xA2, 0x54, 0x03, 0x00, 0x43, 0x87, 0x01,
9308 0x05, 0x05, 0x86, 0x98,
9309 0x7E, 0x98, 0x00, 0xA6, 0x16, 0x03, 0x07, 0xA6, 0x4C, 0x03, 0x03, 0xA6,
9310 0x3C, 0x04, 0x06, 0xA6,
9311 0x50, 0x03, 0x01, 0xA6, 0x16, 0x03, 0x00, 0x33, 0x25, 0x00, 0xC2, 0x88,
9312 0x7C, 0x95, 0x32, 0x83,
9313 0x60, 0x96, 0x32, 0x83, 0x04, 0x01, 0x10, 0xCE, 0x07, 0xC8, 0x05, 0x05,
9314 0xEB, 0x04, 0x00, 0x33,
9315 0x00, 0x20, 0xC0, 0x20, 0x81, 0x62, 0x72, 0x83, 0x00, 0x01, 0x05, 0x05,
9316 0xFF, 0xA2, 0x7A, 0x03,
9317 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x2E, 0x83, 0x05, 0x05, 0x15, 0x01,
9318 0x00, 0xA2, 0x9A, 0x03,
9319 0xEC, 0x00, 0x6E, 0x00, 0x95, 0x01, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00,
9320 0x01, 0xA6, 0x96, 0x03,
9321 0x00, 0xA6, 0x96, 0x03, 0x10, 0x84, 0x80, 0x42, 0x7E, 0x98, 0x01, 0xA6,
9322 0xA4, 0x03, 0x00, 0xA6,
9323 0xBC, 0x03, 0x10, 0x84, 0xA8, 0x98, 0x80, 0x42, 0x01, 0xA6, 0xA4, 0x03,
9324 0x07, 0xA6, 0xB2, 0x03,
9325 0xD4, 0x83, 0x7C, 0x95, 0xA8, 0x83, 0x00, 0x33, 0x2F, 0x00, 0xC2, 0x88,
9326 0xA8, 0x98, 0x80, 0x42,
9327 0x00, 0xA6, 0xBC, 0x03, 0x07, 0xA6, 0xCA, 0x03, 0xD4, 0x83, 0x7C, 0x95,
9328 0xC0, 0x83, 0x00, 0x33,
9329 0x26, 0x00, 0xC2, 0x88, 0x38, 0x2B, 0x80, 0x32, 0x80, 0x36, 0x04, 0x23,
9330 0xA0, 0x01, 0x12, 0x23,
9331 0xA1, 0x01, 0x10, 0x84, 0x07, 0xF0, 0x06, 0xA4, 0xF4, 0x03, 0x80, 0x6B,
9332 0x80, 0x67, 0x05, 0x23,
9333 0x83, 0x03, 0x80, 0x63, 0x03, 0xA6, 0x0E, 0x04, 0x07, 0xA6, 0x06, 0x04,
9334 0x06, 0xA6, 0x0A, 0x04,
9335 0x00, 0x33, 0x17, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0xF4, 0x83, 0x60, 0x96,
9336 0xF4, 0x83, 0x20, 0x84,
9337 0x07, 0xF0, 0x06, 0xA4, 0x20, 0x04, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23,
9338 0x83, 0x03, 0x80, 0x63,
9339 0xB6, 0x2D, 0x03, 0xA6, 0x3C, 0x04, 0x07, 0xA6, 0x34, 0x04, 0x06, 0xA6,
9340 0x38, 0x04, 0x00, 0x33,
9341 0x30, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x20, 0x84, 0x60, 0x96, 0x20, 0x84,
9342 0x1D, 0x01, 0x06, 0xCC,
9343 0x00, 0x33, 0x00, 0x84, 0xC0, 0x20, 0x00, 0x23, 0xEA, 0x00, 0x81, 0x62,
9344 0xA2, 0x0D, 0x80, 0x63,
9345 0x07, 0xA6, 0x5A, 0x04, 0x00, 0x33, 0x18, 0x00, 0xC2, 0x88, 0x03, 0x03,
9346 0x80, 0x63, 0xA3, 0x01,
9347 0x07, 0xA4, 0x64, 0x04, 0x23, 0x01, 0x00, 0xA2, 0x86, 0x04, 0x0A, 0xA0,
9348 0x76, 0x04, 0xE0, 0x00,
9349 0x00, 0x33, 0x1D, 0x00, 0xC2, 0x88, 0x0B, 0xA0, 0x82, 0x04, 0xE0, 0x00,
9350 0x00, 0x33, 0x1E, 0x00,
9351 0xC2, 0x88, 0x42, 0x23, 0xF8, 0x88, 0x00, 0x23, 0x22, 0xA3, 0xE6, 0x04,
9352 0x08, 0x23, 0x22, 0xA3,
9353 0xA2, 0x04, 0x28, 0x23, 0x22, 0xA3, 0xAE, 0x04, 0x02, 0x23, 0x22, 0xA3,
9354 0xC4, 0x04, 0x42, 0x23,
9355 0xF8, 0x88, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA0, 0xAE, 0x04, 0x45, 0x23,
9356 0xF8, 0x88, 0x04, 0x98,
9357 0x00, 0xA2, 0xC0, 0x04, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x82, 0xC0, 0x20,
9358 0x81, 0x62, 0xE8, 0x81,
9359 0x47, 0x23, 0xF8, 0x88, 0x04, 0x01, 0x0B, 0xDE, 0x04, 0x98, 0xB4, 0x98,
9360 0x00, 0x33, 0x00, 0x81,
9361 0xC0, 0x20, 0x81, 0x62, 0x14, 0x01, 0x00, 0xA0, 0x00, 0x02, 0x43, 0x23,
9362 0xF8, 0x88, 0x04, 0x23,
9363 0xA0, 0x01, 0x44, 0x23, 0xA1, 0x01, 0x80, 0x73, 0x4D, 0x00, 0x03, 0xA3,
9364 0xF4, 0x04, 0x00, 0x33,
9365 0x27, 0x00, 0xC2, 0x88, 0x04, 0x01, 0x04, 0xDC, 0x02, 0x23, 0xA2, 0x01,
9366 0x04, 0x23, 0xA0, 0x01,
9367 0x04, 0x98, 0x26, 0x95, 0x4B, 0x00, 0xF6, 0x00, 0x4F, 0x04, 0x4F, 0x00,
9368 0x00, 0xA3, 0x22, 0x05,
9369 0x00, 0x05, 0x76, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x1C, 0x05, 0x0A, 0x85,
9370 0x46, 0x97, 0xCD, 0x04,
9371 0x24, 0x85, 0x48, 0x04, 0x84, 0x80, 0x02, 0x01, 0x03, 0xDA, 0x80, 0x23,
9372 0x82, 0x01, 0x34, 0x85,
9373 0x02, 0x23, 0xA0, 0x01, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x40, 0x05,
9374 0x1D, 0x01, 0x04, 0xD6,
9375 0xFF, 0x23, 0x86, 0x41, 0x4B, 0x60, 0xCB, 0x00, 0xFF, 0x23, 0x80, 0x01,
9376 0x49, 0x00, 0x81, 0x01,
9377 0x04, 0x01, 0x02, 0xC8, 0x30, 0x01, 0x80, 0x01, 0xF7, 0x04, 0x03, 0x01,
9378 0x49, 0x04, 0x80, 0x01,
9379 0xC9, 0x00, 0x00, 0x05, 0x00, 0x01, 0xFF, 0xA0, 0x60, 0x05, 0x77, 0x04,
9380 0x01, 0x23, 0xEA, 0x00,
9381 0x5D, 0x00, 0xFE, 0xC7, 0x00, 0x62, 0x00, 0x23, 0xEA, 0x00, 0x00, 0x63,
9382 0x07, 0xA4, 0xF8, 0x05,
9383 0x03, 0x03, 0x02, 0xA0, 0x8E, 0x05, 0xF4, 0x85, 0x00, 0x33, 0x2D, 0x00,
9384 0xC2, 0x88, 0x04, 0xA0,
9385 0xB8, 0x05, 0x80, 0x63, 0x00, 0x23, 0xDF, 0x00, 0x4A, 0x00, 0x06, 0x61,
9386 0x00, 0xA2, 0xA4, 0x05,
9387 0x1D, 0x01, 0x06, 0xD6, 0x02, 0x23, 0x02, 0x41, 0x82, 0x01, 0x50, 0x00,
9388 0x62, 0x97, 0x04, 0x85,
9389 0x04, 0x23, 0x02, 0x41, 0x82, 0x01, 0x04, 0x85, 0x08, 0xA0, 0xBE, 0x05,
9390 0xF4, 0x85, 0x03, 0xA0,
9391 0xC4, 0x05, 0xF4, 0x85, 0x01, 0xA0, 0xCE, 0x05, 0x88, 0x00, 0x80, 0x63,
9392 0xCC, 0x86, 0x07, 0xA0,
9393 0xEE, 0x05, 0x5F, 0x00, 0x00, 0x2B, 0xDF, 0x08, 0x00, 0xA2, 0xE6, 0x05,
9394 0x80, 0x67, 0x80, 0x63,
9395 0x01, 0xA2, 0x7A, 0x06, 0x7C, 0x85, 0x06, 0x23, 0x68, 0x98, 0x48, 0x23,
9396 0xF8, 0x88, 0x07, 0x23,
9397 0x80, 0x00, 0x06, 0x87, 0x80, 0x63, 0x7C, 0x85, 0x00, 0x23, 0xDF, 0x00,
9398 0x00, 0x63, 0x4A, 0x00,
9399 0x06, 0x61, 0x00, 0xA2, 0x36, 0x06, 0x1D, 0x01, 0x16, 0xD4, 0xC0, 0x23,
9400 0x07, 0x41, 0x83, 0x03,
9401 0x80, 0x63, 0x06, 0xA6, 0x1C, 0x06, 0x00, 0x33, 0x37, 0x00, 0xC2, 0x88,
9402 0x1D, 0x01, 0x01, 0xD6,
9403 0x20, 0x23, 0x63, 0x60, 0x83, 0x03, 0x80, 0x63, 0x02, 0x23, 0xDF, 0x00,
9404 0x07, 0xA6, 0x7C, 0x05,
9405 0xEF, 0x04, 0x6F, 0x00, 0x00, 0x63, 0x4B, 0x00, 0x06, 0x41, 0xCB, 0x00,
9406 0x52, 0x00, 0x06, 0x61,
9407 0x00, 0xA2, 0x4E, 0x06, 0x1D, 0x01, 0x03, 0xCA, 0xC0, 0x23, 0x07, 0x41,
9408 0x00, 0x63, 0x1D, 0x01,
9409 0x04, 0xCC, 0x00, 0x33, 0x00, 0x83, 0xC0, 0x20, 0x81, 0x62, 0x80, 0x23,
9410 0x07, 0x41, 0x00, 0x63,
9411 0x80, 0x67, 0x08, 0x23, 0x83, 0x03, 0x80, 0x63, 0x00, 0x63, 0x01, 0x23,
9412 0xDF, 0x00, 0x06, 0xA6,
9413 0x84, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67, 0x80, 0x63, 0x00, 0x33,
9414 0x00, 0x40, 0xC0, 0x20,
9415 0x81, 0x62, 0x00, 0x63, 0x00, 0x00, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63,
9416 0x06, 0xA6, 0x94, 0x06,
9417 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x00, 0x01, 0xA0, 0x14, 0x07, 0x00, 0x2B,
9418 0x40, 0x0E, 0x80, 0x63,
9419 0x01, 0x00, 0x06, 0xA6, 0xAA, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x40, 0x0E,
9420 0x80, 0x63, 0x00, 0x43,
9421 0x00, 0xA0, 0xA2, 0x06, 0x06, 0xA6, 0xBC, 0x06, 0x07, 0xA6, 0x7C, 0x05,
9422 0x80, 0x67, 0x40, 0x0E,
9423 0x80, 0x63, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63,
9424 0x07, 0xA6, 0xD6, 0x06,
9425 0x00, 0x33, 0x2A, 0x00, 0xC2, 0x88, 0x03, 0x03, 0x80, 0x63, 0x89, 0x00,
9426 0x0A, 0x2B, 0x07, 0xA6,
9427 0xE8, 0x06, 0x00, 0x33, 0x29, 0x00, 0xC2, 0x88, 0x00, 0x43, 0x00, 0xA2,
9428 0xF4, 0x06, 0xC0, 0x0E,
9429 0x80, 0x63, 0xDE, 0x86, 0xC0, 0x0E, 0x00, 0x33, 0x00, 0x80, 0xC0, 0x20,
9430 0x81, 0x62, 0x04, 0x01,
9431 0x02, 0xDA, 0x80, 0x63, 0x7C, 0x85, 0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6,
9432 0x8C, 0x06, 0x00, 0x33,
9433 0x2C, 0x00, 0xC2, 0x88, 0x0C, 0xA2, 0x2E, 0x07, 0xFE, 0x95, 0x83, 0x03,
9434 0x80, 0x63, 0x06, 0xA6,
9435 0x2C, 0x07, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x33, 0x3D, 0x00, 0xC2, 0x88,
9436 0x00, 0x00, 0x80, 0x67,
9437 0x83, 0x03, 0x80, 0x63, 0x0C, 0xA0, 0x44, 0x07, 0x07, 0xA6, 0x7C, 0x05,
9438 0xBF, 0x23, 0x04, 0x61,
9439 0x84, 0x01, 0xE6, 0x84, 0x00, 0x63, 0xF0, 0x04, 0x01, 0x01, 0xF1, 0x00,
9440 0x00, 0x01, 0xF2, 0x00,
9441 0x01, 0x05, 0x80, 0x01, 0x72, 0x04, 0x71, 0x00, 0x81, 0x01, 0x70, 0x04,
9442 0x80, 0x05, 0x81, 0x05,
9443 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x01, 0x01, 0xF1, 0x00,
9444 0x70, 0x00, 0x81, 0x01,
9445 0x70, 0x04, 0x71, 0x00, 0x81, 0x01, 0x72, 0x00, 0x80, 0x01, 0x71, 0x04,
9446 0x70, 0x00, 0x80, 0x01,
9447 0x70, 0x04, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x00, 0x01,
9448 0xF1, 0x00, 0x70, 0x00,
9449 0x80, 0x01, 0x70, 0x04, 0x71, 0x00, 0x80, 0x01, 0x72, 0x00, 0x81, 0x01,
9450 0x71, 0x04, 0x70, 0x00,
9451 0x81, 0x01, 0x70, 0x04, 0x00, 0x63, 0x00, 0x23, 0xB3, 0x01, 0x83, 0x05,
9452 0xA3, 0x01, 0xA2, 0x01,
9453 0xA1, 0x01, 0x01, 0x23, 0xA0, 0x01, 0x00, 0x01, 0xC8, 0x00, 0x03, 0xA1,
9454 0xC4, 0x07, 0x00, 0x33,
9455 0x07, 0x00, 0xC2, 0x88, 0x80, 0x05, 0x81, 0x05, 0x04, 0x01, 0x11, 0xC8,
9456 0x48, 0x00, 0xB0, 0x01,
9457 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x05, 0x01, 0x48, 0x04, 0x00, 0x43,
9458 0x00, 0xA2, 0xE4, 0x07,
9459 0x00, 0x05, 0xDA, 0x87, 0x00, 0x01, 0xC8, 0x00, 0xFF, 0x23, 0x80, 0x01,
9460 0x05, 0x05, 0x00, 0x63,
9461 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, 0x00, 0x02, 0x80, 0x43,
9462 0x76, 0x08, 0x80, 0x02,
9463 0x77, 0x04, 0x00, 0x63, 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04,
9464 0x00, 0x02, 0x00, 0xA0,
9465 0x14, 0x08, 0x16, 0x88, 0x00, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04,
9466 0x00, 0x63, 0xF3, 0x04,
9467 0x00, 0x23, 0xF4, 0x00, 0x74, 0x00, 0x80, 0x43, 0xF4, 0x00, 0xCF, 0x40,
9468 0x00, 0xA2, 0x44, 0x08,
9469 0x74, 0x04, 0x02, 0x01, 0xF7, 0xC9, 0xF6, 0xD9, 0x00, 0x01, 0x01, 0xA1,
9470 0x24, 0x08, 0x04, 0x98,
9471 0x26, 0x95, 0x24, 0x88, 0x73, 0x04, 0x00, 0x63, 0xF3, 0x04, 0x75, 0x04,
9472 0x5A, 0x88, 0x02, 0x01,
9473 0x04, 0xD8, 0x46, 0x97, 0x04, 0x98, 0x26, 0x95, 0x4A, 0x88, 0x75, 0x00,
9474 0x00, 0xA3, 0x64, 0x08,
9475 0x00, 0x05, 0x4E, 0x88, 0x73, 0x04, 0x00, 0x63, 0x80, 0x7B, 0x80, 0x63,
9476 0x06, 0xA6, 0x76, 0x08,
9477 0x00, 0x33, 0x3E, 0x00, 0xC2, 0x88, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63,
9478 0x00, 0x63, 0x38, 0x2B,
9479 0x9C, 0x88, 0x38, 0x2B, 0x92, 0x88, 0x32, 0x09, 0x31, 0x05, 0x92, 0x98,
9480 0x05, 0x05, 0xB2, 0x09,
9481 0x00, 0x63, 0x00, 0x32, 0x00, 0x36, 0x00, 0x3A, 0x00, 0x3E, 0x00, 0x63,
9482 0x80, 0x32, 0x80, 0x36,
9483 0x80, 0x3A, 0x80, 0x3E, 0xB4, 0x3D, 0x00, 0x63, 0x38, 0x2B, 0x40, 0x32,
9484 0x40, 0x36, 0x40, 0x3A,
9485 0x40, 0x3E, 0x00, 0x63, 0x5A, 0x20, 0xC9, 0x40, 0x00, 0xA0, 0xB4, 0x08,
9486 0x5D, 0x00, 0xFE, 0xC3,
9487 0x00, 0x63, 0x80, 0x73, 0xE6, 0x20, 0x02, 0x23, 0xE8, 0x00, 0x82, 0x73,
9488 0xFF, 0xFD, 0x80, 0x73,
9489 0x13, 0x23, 0xF8, 0x88, 0x66, 0x20, 0xC0, 0x20, 0x04, 0x23, 0xA0, 0x01,
9490 0xA1, 0x23, 0xA1, 0x01,
9491 0x81, 0x62, 0xE2, 0x88, 0x80, 0x73, 0x80, 0x77, 0x68, 0x00, 0x00, 0xA2,
9492 0x80, 0x00, 0x03, 0xC2,
9493 0xF1, 0xC7, 0x41, 0x23, 0xF8, 0x88, 0x11, 0x23, 0xA1, 0x01, 0x04, 0x23,
9494 0xA0, 0x01, 0xE6, 0x84,
1da177e4
LT
9495};
9496
27c868c2
MW
9497static ushort _asc_mcode_size = sizeof(_asc_mcode_buf);
9498static ADV_DCNT _asc_mcode_chksum = 0x012C453FUL;
1da177e4
LT
9499
9500#define ASC_SYN_OFFSET_ONE_DISABLE_LIST 16
27c868c2
MW
9501static uchar _syn_offset_one_disable_cmd[ASC_SYN_OFFSET_ONE_DISABLE_LIST] = {
9502 INQUIRY,
9503 REQUEST_SENSE,
9504 READ_CAPACITY,
9505 READ_TOC,
9506 MODE_SELECT,
9507 MODE_SENSE,
9508 MODE_SELECT_10,
9509 MODE_SENSE_10,
9510 0xFF,
9511 0xFF,
9512 0xFF,
9513 0xFF,
9514 0xFF,
9515 0xFF,
9516 0xFF,
9517 0xFF
1da177e4
LT
9518};
9519
27c868c2 9520static int AscExeScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq)
1da177e4 9521{
27c868c2
MW
9522 PortAddr iop_base;
9523 ulong last_int_level;
9524 int sta;
9525 int n_q_required;
9526 int disable_syn_offset_one_fix;
9527 int i;
9528 ASC_PADDR addr;
9529 ASC_EXE_CALLBACK asc_exe_callback;
9530 ushort sg_entry_cnt = 0;
9531 ushort sg_entry_cnt_minus_one = 0;
9532 uchar target_ix;
9533 uchar tid_no;
9534 uchar sdtr_data;
9535 uchar extra_bytes;
9536 uchar scsi_cmd;
9537 uchar disable_cmd;
9538 ASC_SG_HEAD *sg_head;
9539 ASC_DCNT data_cnt;
9540
9541 iop_base = asc_dvc->iop_base;
9542 sg_head = scsiq->sg_head;
9543 asc_exe_callback = asc_dvc->exe_callback;
9544 if (asc_dvc->err_code != 0)
9545 return (ERR);
9546 if (scsiq == (ASC_SCSI_Q *)0L) {
9547 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SCSIQ_NULL_PTR);
9548 return (ERR);
9549 }
9550 scsiq->q1.q_no = 0;
9551 if ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES) == 0) {
9552 scsiq->q1.extra_bytes = 0;
9553 }
9554 sta = 0;
9555 target_ix = scsiq->q2.target_ix;
9556 tid_no = ASC_TIX_TO_TID(target_ix);
9557 n_q_required = 1;
9558 if (scsiq->cdbptr[0] == REQUEST_SENSE) {
9559 if ((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) {
9560 asc_dvc->sdtr_done &= ~scsiq->q1.target_id;
9561 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
9562 AscMsgOutSDTR(asc_dvc,
9563 asc_dvc->
9564 sdtr_period_tbl[(sdtr_data >> 4) &
9565 (uchar)(asc_dvc->
9566 max_sdtr_index -
9567 1)],
9568 (uchar)(sdtr_data & (uchar)
9569 ASC_SYN_MAX_OFFSET));
9570 scsiq->q1.cntl |= (QC_MSG_OUT | QC_URGENT);
9571 }
9572 }
9573 last_int_level = DvcEnterCritical();
9574 if (asc_dvc->in_critical_cnt != 0) {
9575 DvcLeaveCritical(last_int_level);
9576 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CRITICAL_RE_ENTRY);
9577 return (ERR);
9578 }
9579 asc_dvc->in_critical_cnt++;
9580 if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
9581 if ((sg_entry_cnt = sg_head->entry_cnt) == 0) {
9582 asc_dvc->in_critical_cnt--;
9583 DvcLeaveCritical(last_int_level);
9584 return (ERR);
9585 }
1da177e4 9586#if !CC_VERY_LONG_SG_LIST
27c868c2
MW
9587 if (sg_entry_cnt > ASC_MAX_SG_LIST) {
9588 asc_dvc->in_critical_cnt--;
9589 DvcLeaveCritical(last_int_level);
9590 return (ERR);
9591 }
1da177e4 9592#endif /* !CC_VERY_LONG_SG_LIST */
27c868c2
MW
9593 if (sg_entry_cnt == 1) {
9594 scsiq->q1.data_addr =
9595 (ADV_PADDR)sg_head->sg_list[0].addr;
9596 scsiq->q1.data_cnt =
9597 (ADV_DCNT)sg_head->sg_list[0].bytes;
9598 scsiq->q1.cntl &= ~(QC_SG_HEAD | QC_SG_SWAP_QUEUE);
9599 }
9600 sg_entry_cnt_minus_one = sg_entry_cnt - 1;
9601 }
9602 scsi_cmd = scsiq->cdbptr[0];
9603 disable_syn_offset_one_fix = FALSE;
9604 if ((asc_dvc->pci_fix_asyn_xfer & scsiq->q1.target_id) &&
9605 !(asc_dvc->pci_fix_asyn_xfer_always & scsiq->q1.target_id)) {
9606 if (scsiq->q1.cntl & QC_SG_HEAD) {
9607 data_cnt = 0;
9608 for (i = 0; i < sg_entry_cnt; i++) {
9609 data_cnt +=
9610 (ADV_DCNT)le32_to_cpu(sg_head->sg_list[i].
9611 bytes);
9612 }
9613 } else {
9614 data_cnt = le32_to_cpu(scsiq->q1.data_cnt);
9615 }
9616 if (data_cnt != 0UL) {
9617 if (data_cnt < 512UL) {
9618 disable_syn_offset_one_fix = TRUE;
9619 } else {
9620 for (i = 0; i < ASC_SYN_OFFSET_ONE_DISABLE_LIST;
9621 i++) {
9622 disable_cmd =
9623 _syn_offset_one_disable_cmd[i];
9624 if (disable_cmd == 0xFF) {
9625 break;
9626 }
9627 if (scsi_cmd == disable_cmd) {
9628 disable_syn_offset_one_fix =
9629 TRUE;
9630 break;
9631 }
9632 }
9633 }
9634 }
9635 }
9636 if (disable_syn_offset_one_fix) {
9637 scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG;
9638 scsiq->q2.tag_code |= (ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX |
9639 ASC_TAG_FLAG_DISABLE_DISCONNECT);
9640 } else {
9641 scsiq->q2.tag_code &= 0x27;
9642 }
9643 if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
9644 if (asc_dvc->bug_fix_cntl) {
9645 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
9646 if ((scsi_cmd == READ_6) ||
9647 (scsi_cmd == READ_10)) {
9648 addr =
9649 (ADV_PADDR)le32_to_cpu(sg_head->
9650 sg_list
9651 [sg_entry_cnt_minus_one].
9652 addr) +
9653 (ADV_DCNT)le32_to_cpu(sg_head->
9654 sg_list
9655 [sg_entry_cnt_minus_one].
9656 bytes);
9657 extra_bytes =
9658 (uchar)((ushort)addr & 0x0003);
9659 if ((extra_bytes != 0)
9660 &&
9661 ((scsiq->q2.
9662 tag_code &
9663 ASC_TAG_FLAG_EXTRA_BYTES)
9664 == 0)) {
9665 scsiq->q2.tag_code |=
9666 ASC_TAG_FLAG_EXTRA_BYTES;
9667 scsiq->q1.extra_bytes =
9668 extra_bytes;
9669 data_cnt =
9670 le32_to_cpu(sg_head->
9671 sg_list
9672 [sg_entry_cnt_minus_one].
9673 bytes);
9674 data_cnt -=
9675 (ASC_DCNT) extra_bytes;
9676 sg_head->
9677 sg_list
9678 [sg_entry_cnt_minus_one].
9679 bytes =
9680 cpu_to_le32(data_cnt);
9681 }
9682 }
9683 }
9684 }
9685 sg_head->entry_to_copy = sg_head->entry_cnt;
1da177e4 9686#if CC_VERY_LONG_SG_LIST
27c868c2
MW
9687 /*
9688 * Set the sg_entry_cnt to the maximum possible. The rest of
9689 * the SG elements will be copied when the RISC completes the
9690 * SG elements that fit and halts.
9691 */
9692 if (sg_entry_cnt > ASC_MAX_SG_LIST) {
9693 sg_entry_cnt = ASC_MAX_SG_LIST;
9694 }
1da177e4 9695#endif /* CC_VERY_LONG_SG_LIST */
27c868c2
MW
9696 n_q_required = AscSgListToQueue(sg_entry_cnt);
9697 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, n_q_required) >=
9698 (uint) n_q_required)
9699 || ((scsiq->q1.cntl & QC_URGENT) != 0)) {
9700 if ((sta =
9701 AscSendScsiQueue(asc_dvc, scsiq,
9702 n_q_required)) == 1) {
9703 asc_dvc->in_critical_cnt--;
9704 if (asc_exe_callback != 0) {
9705 (*asc_exe_callback) (asc_dvc, scsiq);
9706 }
9707 DvcLeaveCritical(last_int_level);
9708 return (sta);
9709 }
9710 }
9711 } else {
9712 if (asc_dvc->bug_fix_cntl) {
9713 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
9714 if ((scsi_cmd == READ_6) ||
9715 (scsi_cmd == READ_10)) {
9716 addr =
9717 le32_to_cpu(scsiq->q1.data_addr) +
9718 le32_to_cpu(scsiq->q1.data_cnt);
9719 extra_bytes =
9720 (uchar)((ushort)addr & 0x0003);
9721 if ((extra_bytes != 0)
9722 &&
9723 ((scsiq->q2.
9724 tag_code &
9725 ASC_TAG_FLAG_EXTRA_BYTES)
9726 == 0)) {
9727 data_cnt =
9728 le32_to_cpu(scsiq->q1.
9729 data_cnt);
9730 if (((ushort)data_cnt & 0x01FF)
9731 == 0) {
9732 scsiq->q2.tag_code |=
9733 ASC_TAG_FLAG_EXTRA_BYTES;
9734 data_cnt -= (ASC_DCNT)
9735 extra_bytes;
9736 scsiq->q1.data_cnt =
9737 cpu_to_le32
9738 (data_cnt);
9739 scsiq->q1.extra_bytes =
9740 extra_bytes;
9741 }
9742 }
9743 }
9744 }
9745 }
9746 n_q_required = 1;
9747 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, 1) >= 1) ||
9748 ((scsiq->q1.cntl & QC_URGENT) != 0)) {
9749 if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
9750 n_q_required)) == 1) {
9751 asc_dvc->in_critical_cnt--;
9752 if (asc_exe_callback != 0) {
9753 (*asc_exe_callback) (asc_dvc, scsiq);
9754 }
9755 DvcLeaveCritical(last_int_level);
9756 return (sta);
9757 }
9758 }
9759 }
9760 asc_dvc->in_critical_cnt--;
9761 DvcLeaveCritical(last_int_level);
9762 return (sta);
1da177e4
LT
9763}
9764
27c868c2
MW
9765static int
9766AscSendScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar n_q_required)
1da177e4 9767{
27c868c2
MW
9768 PortAddr iop_base;
9769 uchar free_q_head;
9770 uchar next_qp;
9771 uchar tid_no;
9772 uchar target_ix;
9773 int sta;
9774
9775 iop_base = asc_dvc->iop_base;
9776 target_ix = scsiq->q2.target_ix;
9777 tid_no = ASC_TIX_TO_TID(target_ix);
9778 sta = 0;
9779 free_q_head = (uchar)AscGetVarFreeQHead(iop_base);
9780 if (n_q_required > 1) {
9781 if ((next_qp = AscAllocMultipleFreeQueue(iop_base,
9782 free_q_head, (uchar)
9783 (n_q_required)))
9784 != (uchar)ASC_QLINK_END) {
9785 asc_dvc->last_q_shortage = 0;
9786 scsiq->sg_head->queue_cnt = n_q_required - 1;
9787 scsiq->q1.q_no = free_q_head;
9788 if ((sta = AscPutReadySgListQueue(asc_dvc, scsiq,
9789 free_q_head)) == 1) {
9790 AscPutVarFreeQHead(iop_base, next_qp);
9791 asc_dvc->cur_total_qng += (uchar)(n_q_required);
9792 asc_dvc->cur_dvc_qng[tid_no]++;
9793 }
9794 return (sta);
9795 }
9796 } else if (n_q_required == 1) {
9797 if ((next_qp = AscAllocFreeQueue(iop_base,
9798 free_q_head)) !=
9799 ASC_QLINK_END) {
9800 scsiq->q1.q_no = free_q_head;
9801 if ((sta = AscPutReadyQueue(asc_dvc, scsiq,
9802 free_q_head)) == 1) {
9803 AscPutVarFreeQHead(iop_base, next_qp);
9804 asc_dvc->cur_total_qng++;
9805 asc_dvc->cur_dvc_qng[tid_no]++;
9806 }
9807 return (sta);
9808 }
9809 }
9810 return (sta);
1da177e4
LT
9811}
9812
27c868c2 9813static int AscSgListToQueue(int sg_list)
1da177e4 9814{
27c868c2 9815 int n_sg_list_qs;
1da177e4 9816
27c868c2
MW
9817 n_sg_list_qs = ((sg_list - 1) / ASC_SG_LIST_PER_Q);
9818 if (((sg_list - 1) % ASC_SG_LIST_PER_Q) != 0)
9819 n_sg_list_qs++;
9820 return (n_sg_list_qs + 1);
1da177e4
LT
9821}
9822
27c868c2
MW
9823static uint
9824AscGetNumOfFreeQueue(ASC_DVC_VAR *asc_dvc, uchar target_ix, uchar n_qs)
1da177e4 9825{
27c868c2
MW
9826 uint cur_used_qs;
9827 uint cur_free_qs;
9828 ASC_SCSI_BIT_ID_TYPE target_id;
9829 uchar tid_no;
9830
9831 target_id = ASC_TIX_TO_TARGET_ID(target_ix);
9832 tid_no = ASC_TIX_TO_TID(target_ix);
9833 if ((asc_dvc->unit_not_ready & target_id) ||
9834 (asc_dvc->queue_full_or_busy & target_id)) {
9835 return (0);
9836 }
9837 if (n_qs == 1) {
9838 cur_used_qs = (uint) asc_dvc->cur_total_qng +
9839 (uint) asc_dvc->last_q_shortage + (uint) ASC_MIN_FREE_Q;
9840 } else {
9841 cur_used_qs = (uint) asc_dvc->cur_total_qng +
9842 (uint) ASC_MIN_FREE_Q;
9843 }
9844 if ((uint) (cur_used_qs + n_qs) <= (uint) asc_dvc->max_total_qng) {
9845 cur_free_qs = (uint) asc_dvc->max_total_qng - cur_used_qs;
9846 if (asc_dvc->cur_dvc_qng[tid_no] >=
9847 asc_dvc->max_dvc_qng[tid_no]) {
9848 return (0);
9849 }
9850 return (cur_free_qs);
9851 }
9852 if (n_qs > 1) {
9853 if ((n_qs > asc_dvc->last_q_shortage)
9854 && (n_qs <= (asc_dvc->max_total_qng - ASC_MIN_FREE_Q))) {
9855 asc_dvc->last_q_shortage = n_qs;
9856 }
9857 }
9858 return (0);
1da177e4
LT
9859}
9860
27c868c2 9861static int AscPutReadyQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no)
1da177e4 9862{
27c868c2
MW
9863 ushort q_addr;
9864 uchar tid_no;
9865 uchar sdtr_data;
9866 uchar syn_period_ix;
9867 uchar syn_offset;
9868 PortAddr iop_base;
9869
9870 iop_base = asc_dvc->iop_base;
9871 if (((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) &&
9872 ((asc_dvc->sdtr_done & scsiq->q1.target_id) == 0)) {
9873 tid_no = ASC_TIX_TO_TID(scsiq->q2.target_ix);
9874 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
9875 syn_period_ix =
9876 (sdtr_data >> 4) & (asc_dvc->max_sdtr_index - 1);
9877 syn_offset = sdtr_data & ASC_SYN_MAX_OFFSET;
9878 AscMsgOutSDTR(asc_dvc,
9879 asc_dvc->sdtr_period_tbl[syn_period_ix],
9880 syn_offset);
9881 scsiq->q1.cntl |= QC_MSG_OUT;
9882 }
9883 q_addr = ASC_QNO_TO_QADDR(q_no);
9884 if ((scsiq->q1.target_id & asc_dvc->use_tagged_qng) == 0) {
9885 scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG;
9886 }
9887 scsiq->q1.status = QS_FREE;
9888 AscMemWordCopyPtrToLram(iop_base,
9889 q_addr + ASC_SCSIQ_CDB_BEG,
9890 (uchar *)scsiq->cdbptr, scsiq->q2.cdb_len >> 1);
9891
9892 DvcPutScsiQ(iop_base,
9893 q_addr + ASC_SCSIQ_CPY_BEG,
9894 (uchar *)&scsiq->q1.cntl,
9895 ((sizeof(ASC_SCSIQ_1) + sizeof(ASC_SCSIQ_2)) / 2) - 1);
9896 AscWriteLramWord(iop_base,
9897 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_STATUS),
9898 (ushort)(((ushort)scsiq->q1.
9899 q_no << 8) | (ushort)QS_READY));
9900 return (1);
1da177e4
LT
9901}
9902
27c868c2
MW
9903static int
9904AscPutReadySgListQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no)
1da177e4 9905{
27c868c2
MW
9906 int sta;
9907 int i;
9908 ASC_SG_HEAD *sg_head;
9909 ASC_SG_LIST_Q scsi_sg_q;
9910 ASC_DCNT saved_data_addr;
9911 ASC_DCNT saved_data_cnt;
9912 PortAddr iop_base;
9913 ushort sg_list_dwords;
9914 ushort sg_index;
9915 ushort sg_entry_cnt;
9916 ushort q_addr;
9917 uchar next_qp;
9918
9919 iop_base = asc_dvc->iop_base;
9920 sg_head = scsiq->sg_head;
9921 saved_data_addr = scsiq->q1.data_addr;
9922 saved_data_cnt = scsiq->q1.data_cnt;
9923 scsiq->q1.data_addr = (ASC_PADDR) sg_head->sg_list[0].addr;
9924 scsiq->q1.data_cnt = (ASC_DCNT) sg_head->sg_list[0].bytes;
1da177e4 9925#if CC_VERY_LONG_SG_LIST
27c868c2
MW
9926 /*
9927 * If sg_head->entry_cnt is greater than ASC_MAX_SG_LIST
9928 * then not all SG elements will fit in the allocated queues.
9929 * The rest of the SG elements will be copied when the RISC
9930 * completes the SG elements that fit and halts.
9931 */
9932 if (sg_head->entry_cnt > ASC_MAX_SG_LIST) {
9933 /*
9934 * Set sg_entry_cnt to be the number of SG elements that
9935 * will fit in the allocated SG queues. It is minus 1, because
9936 * the first SG element is handled above. ASC_MAX_SG_LIST is
9937 * already inflated by 1 to account for this. For example it
9938 * may be 50 which is 1 + 7 queues * 7 SG elements.
9939 */
9940 sg_entry_cnt = ASC_MAX_SG_LIST - 1;
9941
9942 /*
9943 * Keep track of remaining number of SG elements that will
9944 * need to be handled from a_isr.c.
9945 */
9946 scsiq->remain_sg_entry_cnt =
9947 sg_head->entry_cnt - ASC_MAX_SG_LIST;
9948 } else {
1da177e4 9949#endif /* CC_VERY_LONG_SG_LIST */
27c868c2
MW
9950 /*
9951 * Set sg_entry_cnt to be the number of SG elements that
9952 * will fit in the allocated SG queues. It is minus 1, because
9953 * the first SG element is handled above.
9954 */
9955 sg_entry_cnt = sg_head->entry_cnt - 1;
1da177e4 9956#if CC_VERY_LONG_SG_LIST
27c868c2 9957 }
1da177e4 9958#endif /* CC_VERY_LONG_SG_LIST */
27c868c2
MW
9959 if (sg_entry_cnt != 0) {
9960 scsiq->q1.cntl |= QC_SG_HEAD;
9961 q_addr = ASC_QNO_TO_QADDR(q_no);
9962 sg_index = 1;
9963 scsiq->q1.sg_queue_cnt = sg_head->queue_cnt;
9964 scsi_sg_q.sg_head_qp = q_no;
9965 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
9966 for (i = 0; i < sg_head->queue_cnt; i++) {
9967 scsi_sg_q.seq_no = i + 1;
9968 if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
9969 sg_list_dwords = (uchar)(ASC_SG_LIST_PER_Q * 2);
9970 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
9971 if (i == 0) {
9972 scsi_sg_q.sg_list_cnt =
9973 ASC_SG_LIST_PER_Q;
9974 scsi_sg_q.sg_cur_list_cnt =
9975 ASC_SG_LIST_PER_Q;
9976 } else {
9977 scsi_sg_q.sg_list_cnt =
9978 ASC_SG_LIST_PER_Q - 1;
9979 scsi_sg_q.sg_cur_list_cnt =
9980 ASC_SG_LIST_PER_Q - 1;
9981 }
9982 } else {
1da177e4 9983#if CC_VERY_LONG_SG_LIST
27c868c2
MW
9984 /*
9985 * This is the last SG queue in the list of
9986 * allocated SG queues. If there are more
9987 * SG elements than will fit in the allocated
9988 * queues, then set the QCSG_SG_XFER_MORE flag.
9989 */
9990 if (sg_head->entry_cnt > ASC_MAX_SG_LIST) {
9991 scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
9992 } else {
1da177e4 9993#endif /* CC_VERY_LONG_SG_LIST */
27c868c2 9994 scsi_sg_q.cntl |= QCSG_SG_XFER_END;
1da177e4 9995#if CC_VERY_LONG_SG_LIST
27c868c2 9996 }
1da177e4 9997#endif /* CC_VERY_LONG_SG_LIST */
27c868c2
MW
9998 sg_list_dwords = sg_entry_cnt << 1;
9999 if (i == 0) {
10000 scsi_sg_q.sg_list_cnt = sg_entry_cnt;
10001 scsi_sg_q.sg_cur_list_cnt =
10002 sg_entry_cnt;
10003 } else {
10004 scsi_sg_q.sg_list_cnt =
10005 sg_entry_cnt - 1;
10006 scsi_sg_q.sg_cur_list_cnt =
10007 sg_entry_cnt - 1;
10008 }
10009 sg_entry_cnt = 0;
10010 }
10011 next_qp = AscReadLramByte(iop_base,
10012 (ushort)(q_addr +
10013 ASC_SCSIQ_B_FWD));
10014 scsi_sg_q.q_no = next_qp;
10015 q_addr = ASC_QNO_TO_QADDR(next_qp);
10016 AscMemWordCopyPtrToLram(iop_base,
10017 q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
10018 (uchar *)&scsi_sg_q,
10019 sizeof(ASC_SG_LIST_Q) >> 1);
10020 AscMemDWordCopyPtrToLram(iop_base,
10021 q_addr + ASC_SGQ_LIST_BEG,
10022 (uchar *)&sg_head->
10023 sg_list[sg_index],
10024 sg_list_dwords);
10025 sg_index += ASC_SG_LIST_PER_Q;
10026 scsiq->next_sg_index = sg_index;
10027 }
10028 } else {
10029 scsiq->q1.cntl &= ~QC_SG_HEAD;
10030 }
10031 sta = AscPutReadyQueue(asc_dvc, scsiq, q_no);
10032 scsiq->q1.data_addr = saved_data_addr;
10033 scsiq->q1.data_cnt = saved_data_cnt;
10034 return (sta);
1da177e4
LT
10035}
10036
27c868c2
MW
10037static int
10038AscSetRunChipSynRegAtID(PortAddr iop_base, uchar tid_no, uchar sdtr_data)
1da177e4 10039{
27c868c2 10040 int sta = FALSE;
1da177e4 10041
27c868c2
MW
10042 if (AscHostReqRiscHalt(iop_base)) {
10043 sta = AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
10044 AscStartChip(iop_base);
10045 return (sta);
10046 }
10047 return (sta);
1da177e4
LT
10048}
10049
27c868c2 10050static int AscSetChipSynRegAtID(PortAddr iop_base, uchar id, uchar sdtr_data)
1da177e4 10051{
27c868c2
MW
10052 ASC_SCSI_BIT_ID_TYPE org_id;
10053 int i;
10054 int sta = TRUE;
10055
10056 AscSetBank(iop_base, 1);
10057 org_id = AscReadChipDvcID(iop_base);
10058 for (i = 0; i <= ASC_MAX_TID; i++) {
10059 if (org_id == (0x01 << i))
10060 break;
10061 }
10062 org_id = (ASC_SCSI_BIT_ID_TYPE) i;
10063 AscWriteChipDvcID(iop_base, id);
10064 if (AscReadChipDvcID(iop_base) == (0x01 << id)) {
10065 AscSetBank(iop_base, 0);
10066 AscSetChipSyn(iop_base, sdtr_data);
10067 if (AscGetChipSyn(iop_base) != sdtr_data) {
10068 sta = FALSE;
10069 }
10070 } else {
10071 sta = FALSE;
10072 }
10073 AscSetBank(iop_base, 1);
10074 AscWriteChipDvcID(iop_base, org_id);
10075 AscSetBank(iop_base, 0);
10076 return (sta);
10077}
1da177e4 10078
27c868c2 10079static ushort AscInitLram(ASC_DVC_VAR *asc_dvc)
1da177e4 10080{
27c868c2
MW
10081 uchar i;
10082 ushort s_addr;
10083 PortAddr iop_base;
10084 ushort warn_code;
10085
10086 iop_base = asc_dvc->iop_base;
10087 warn_code = 0;
10088 AscMemWordSetLram(iop_base, ASC_QADR_BEG, 0,
10089 (ushort)(((int)(asc_dvc->max_total_qng + 2 + 1) *
10090 64) >> 1)
10091 );
10092 i = ASC_MIN_ACTIVE_QNO;
10093 s_addr = ASC_QADR_BEG + ASC_QBLK_SIZE;
10094 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
10095 (uchar)(i + 1));
10096 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
10097 (uchar)(asc_dvc->max_total_qng));
10098 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
10099 (uchar)i);
10100 i++;
10101 s_addr += ASC_QBLK_SIZE;
10102 for (; i < asc_dvc->max_total_qng; i++, s_addr += ASC_QBLK_SIZE) {
10103 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
10104 (uchar)(i + 1));
10105 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
10106 (uchar)(i - 1));
10107 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
10108 (uchar)i);
10109 }
10110 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
10111 (uchar)ASC_QLINK_END);
10112 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
10113 (uchar)(asc_dvc->max_total_qng - 1));
10114 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
10115 (uchar)asc_dvc->max_total_qng);
10116 i++;
10117 s_addr += ASC_QBLK_SIZE;
10118 for (; i <= (uchar)(asc_dvc->max_total_qng + 3);
10119 i++, s_addr += ASC_QBLK_SIZE) {
10120 AscWriteLramByte(iop_base,
10121 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_FWD), i);
10122 AscWriteLramByte(iop_base,
10123 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_BWD), i);
10124 AscWriteLramByte(iop_base,
10125 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_QNO), i);
10126 }
10127 return (warn_code);
1da177e4
LT
10128}
10129
27c868c2 10130static ushort AscInitQLinkVar(ASC_DVC_VAR *asc_dvc)
1da177e4 10131{
27c868c2
MW
10132 PortAddr iop_base;
10133 int i;
10134 ushort lram_addr;
10135
10136 iop_base = asc_dvc->iop_base;
10137 AscPutRiscVarFreeQHead(iop_base, 1);
10138 AscPutRiscVarDoneQTail(iop_base, asc_dvc->max_total_qng);
10139 AscPutVarFreeQHead(iop_base, 1);
10140 AscPutVarDoneQTail(iop_base, asc_dvc->max_total_qng);
10141 AscWriteLramByte(iop_base, ASCV_BUSY_QHEAD_B,
10142 (uchar)((int)asc_dvc->max_total_qng + 1));
10143 AscWriteLramByte(iop_base, ASCV_DISC1_QHEAD_B,
10144 (uchar)((int)asc_dvc->max_total_qng + 2));
10145 AscWriteLramByte(iop_base, (ushort)ASCV_TOTAL_READY_Q_B,
10146 asc_dvc->max_total_qng);
10147 AscWriteLramWord(iop_base, ASCV_ASCDVC_ERR_CODE_W, 0);
10148 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10149 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 0);
10150 AscWriteLramByte(iop_base, ASCV_SCSIBUSY_B, 0);
10151 AscWriteLramByte(iop_base, ASCV_WTM_FLAG_B, 0);
10152 AscPutQDoneInProgress(iop_base, 0);
10153 lram_addr = ASC_QADR_BEG;
10154 for (i = 0; i < 32; i++, lram_addr += 2) {
10155 AscWriteLramWord(iop_base, lram_addr, 0);
10156 }
10157 return (0);
1da177e4
LT
10158}
10159
27c868c2 10160static int AscSetLibErrorCode(ASC_DVC_VAR *asc_dvc, ushort err_code)
1da177e4 10161{
27c868c2
MW
10162 if (asc_dvc->err_code == 0) {
10163 asc_dvc->err_code = err_code;
10164 AscWriteLramWord(asc_dvc->iop_base, ASCV_ASCDVC_ERR_CODE_W,
10165 err_code);
10166 }
10167 return (err_code);
1da177e4
LT
10168}
10169
27c868c2
MW
10170static uchar
10171AscMsgOutSDTR(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar sdtr_offset)
1da177e4 10172{
27c868c2
MW
10173 EXT_MSG sdtr_buf;
10174 uchar sdtr_period_index;
10175 PortAddr iop_base;
10176
10177 iop_base = asc_dvc->iop_base;
10178 sdtr_buf.msg_type = MS_EXTEND;
10179 sdtr_buf.msg_len = MS_SDTR_LEN;
10180 sdtr_buf.msg_req = MS_SDTR_CODE;
10181 sdtr_buf.xfer_period = sdtr_period;
10182 sdtr_offset &= ASC_SYN_MAX_OFFSET;
10183 sdtr_buf.req_ack_offset = sdtr_offset;
10184 if ((sdtr_period_index =
10185 AscGetSynPeriodIndex(asc_dvc, sdtr_period)) <=
10186 asc_dvc->max_sdtr_index) {
10187 AscMemWordCopyPtrToLram(iop_base,
10188 ASCV_MSGOUT_BEG,
10189 (uchar *)&sdtr_buf,
10190 sizeof(EXT_MSG) >> 1);
10191 return ((sdtr_period_index << 4) | sdtr_offset);
10192 } else {
10193
10194 sdtr_buf.req_ack_offset = 0;
10195 AscMemWordCopyPtrToLram(iop_base,
10196 ASCV_MSGOUT_BEG,
10197 (uchar *)&sdtr_buf,
10198 sizeof(EXT_MSG) >> 1);
10199 return (0);
10200 }
1da177e4
LT
10201}
10202
27c868c2
MW
10203static uchar
10204AscCalSDTRData(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar syn_offset)
1da177e4 10205{
27c868c2
MW
10206 uchar byte;
10207 uchar sdtr_period_ix;
10208
10209 sdtr_period_ix = AscGetSynPeriodIndex(asc_dvc, sdtr_period);
10210 if ((sdtr_period_ix > asc_dvc->max_sdtr_index)
10211 ) {
10212 return (0xFF);
10213 }
10214 byte = (sdtr_period_ix << 4) | (syn_offset & ASC_SYN_MAX_OFFSET);
10215 return (byte);
1da177e4
LT
10216}
10217
27c868c2 10218static void AscSetChipSDTR(PortAddr iop_base, uchar sdtr_data, uchar tid_no)
1da177e4 10219{
27c868c2
MW
10220 AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
10221 AscPutMCodeSDTRDoneAtID(iop_base, tid_no, sdtr_data);
10222 return;
1da177e4
LT
10223}
10224
27c868c2 10225static uchar AscGetSynPeriodIndex(ASC_DVC_VAR *asc_dvc, uchar syn_time)
1da177e4 10226{
27c868c2
MW
10227 uchar *period_table;
10228 int max_index;
10229 int min_index;
10230 int i;
10231
10232 period_table = asc_dvc->sdtr_period_tbl;
10233 max_index = (int)asc_dvc->max_sdtr_index;
10234 min_index = (int)asc_dvc->host_init_sdtr_index;
10235 if ((syn_time <= period_table[max_index])) {
10236 for (i = min_index; i < (max_index - 1); i++) {
10237 if (syn_time <= period_table[i]) {
10238 return ((uchar)i);
10239 }
10240 }
10241 return ((uchar)max_index);
10242 } else {
10243 return ((uchar)(max_index + 1));
10244 }
1da177e4
LT
10245}
10246
27c868c2 10247static uchar AscAllocFreeQueue(PortAddr iop_base, uchar free_q_head)
1da177e4 10248{
27c868c2
MW
10249 ushort q_addr;
10250 uchar next_qp;
10251 uchar q_status;
10252
10253 q_addr = ASC_QNO_TO_QADDR(free_q_head);
10254 q_status = (uchar)AscReadLramByte(iop_base,
10255 (ushort)(q_addr +
10256 ASC_SCSIQ_B_STATUS));
10257 next_qp = AscReadLramByte(iop_base, (ushort)(q_addr + ASC_SCSIQ_B_FWD));
10258 if (((q_status & QS_READY) == 0) && (next_qp != ASC_QLINK_END)) {
10259 return (next_qp);
10260 }
10261 return (ASC_QLINK_END);
1da177e4
LT
10262}
10263
27c868c2
MW
10264static uchar
10265AscAllocMultipleFreeQueue(PortAddr iop_base, uchar free_q_head, uchar n_free_q)
1da177e4 10266{
27c868c2 10267 uchar i;
1da177e4 10268
27c868c2
MW
10269 for (i = 0; i < n_free_q; i++) {
10270 if ((free_q_head = AscAllocFreeQueue(iop_base, free_q_head))
10271 == ASC_QLINK_END) {
10272 return (ASC_QLINK_END);
10273 }
10274 }
10275 return (free_q_head);
1da177e4
LT
10276}
10277
27c868c2 10278static int AscHostReqRiscHalt(PortAddr iop_base)
1da177e4 10279{
27c868c2
MW
10280 int count = 0;
10281 int sta = 0;
10282 uchar saved_stop_code;
10283
10284 if (AscIsChipHalted(iop_base))
10285 return (1);
10286 saved_stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
10287 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
10288 ASC_STOP_HOST_REQ_RISC_HALT | ASC_STOP_REQ_RISC_STOP);
10289 do {
10290 if (AscIsChipHalted(iop_base)) {
10291 sta = 1;
10292 break;
10293 }
10294 DvcSleepMilliSecond(100);
10295 } while (count++ < 20);
10296 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, saved_stop_code);
10297 return (sta);
1da177e4
LT
10298}
10299
27c868c2 10300static int AscStopQueueExe(PortAddr iop_base)
1da177e4 10301{
27c868c2
MW
10302 int count = 0;
10303
10304 if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) == 0) {
10305 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
10306 ASC_STOP_REQ_RISC_STOP);
10307 do {
10308 if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) &
10309 ASC_STOP_ACK_RISC_STOP) {
10310 return (1);
10311 }
10312 DvcSleepMilliSecond(100);
10313 } while (count++ < 20);
10314 }
10315 return (0);
1da177e4
LT
10316}
10317
27c868c2 10318static void DvcDelayMicroSecond(ADV_DVC_VAR *asc_dvc, ushort micro_sec)
1da177e4 10319{
27c868c2 10320 udelay(micro_sec);
1da177e4
LT
10321}
10322
27c868c2 10323static void DvcDelayNanoSecond(ASC_DVC_VAR *asc_dvc, ASC_DCNT nano_sec)
1da177e4 10324{
27c868c2 10325 udelay((nano_sec + 999) / 1000);
1da177e4
LT
10326}
10327
10328#ifdef CONFIG_ISA
27c868c2 10329static ASC_DCNT __init AscGetEisaProductID(PortAddr iop_base)
1da177e4 10330{
27c868c2
MW
10331 PortAddr eisa_iop;
10332 ushort product_id_high, product_id_low;
10333 ASC_DCNT product_id;
10334
10335 eisa_iop = ASC_GET_EISA_SLOT(iop_base) | ASC_EISA_PID_IOP_MASK;
10336 product_id_low = inpw(eisa_iop);
10337 product_id_high = inpw(eisa_iop + 2);
10338 product_id = ((ASC_DCNT) product_id_high << 16) |
10339 (ASC_DCNT) product_id_low;
10340 return (product_id);
1da177e4
LT
10341}
10342
27c868c2 10343static PortAddr __init AscSearchIOPortAddrEISA(PortAddr iop_base)
1da177e4 10344{
27c868c2
MW
10345 ASC_DCNT eisa_product_id;
10346
10347 if (iop_base == 0) {
10348 iop_base = ASC_EISA_MIN_IOP_ADDR;
10349 } else {
10350 if (iop_base == ASC_EISA_MAX_IOP_ADDR)
10351 return (0);
10352 if ((iop_base & 0x0050) == 0x0050) {
10353 iop_base += ASC_EISA_BIG_IOP_GAP;
10354 } else {
10355 iop_base += ASC_EISA_SMALL_IOP_GAP;
10356 }
10357 }
10358 while (iop_base <= ASC_EISA_MAX_IOP_ADDR) {
10359 eisa_product_id = AscGetEisaProductID(iop_base);
10360 if ((eisa_product_id == ASC_EISA_ID_740) ||
10361 (eisa_product_id == ASC_EISA_ID_750)) {
10362 if (AscFindSignature(iop_base)) {
10363 inpw(iop_base + 4);
10364 return (iop_base);
10365 }
10366 }
10367 if (iop_base == ASC_EISA_MAX_IOP_ADDR)
10368 return (0);
10369 if ((iop_base & 0x0050) == 0x0050) {
10370 iop_base += ASC_EISA_BIG_IOP_GAP;
10371 } else {
10372 iop_base += ASC_EISA_SMALL_IOP_GAP;
10373 }
10374 }
10375 return (0);
1da177e4
LT
10376}
10377#endif /* CONFIG_ISA */
10378
27c868c2 10379static int AscStartChip(PortAddr iop_base)
1da177e4 10380{
27c868c2
MW
10381 AscSetChipControl(iop_base, 0);
10382 if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
10383 return (0);
10384 }
10385 return (1);
1da177e4
LT
10386}
10387
27c868c2 10388static int AscStopChip(PortAddr iop_base)
1da177e4 10389{
27c868c2
MW
10390 uchar cc_val;
10391
10392 cc_val =
10393 AscGetChipControl(iop_base) &
10394 (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG));
10395 AscSetChipControl(iop_base, (uchar)(cc_val | CC_HALT));
10396 AscSetChipIH(iop_base, INS_HALT);
10397 AscSetChipIH(iop_base, INS_RFLAG_WTM);
10398 if ((AscGetChipStatus(iop_base) & CSW_HALTED) == 0) {
10399 return (0);
10400 }
10401 return (1);
1da177e4
LT
10402}
10403
27c868c2 10404static int AscIsChipHalted(PortAddr iop_base)
1da177e4 10405{
27c868c2
MW
10406 if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
10407 if ((AscGetChipControl(iop_base) & CC_HALT) != 0) {
10408 return (1);
10409 }
10410 }
10411 return (0);
1da177e4
LT
10412}
10413
27c868c2 10414static void AscSetChipIH(PortAddr iop_base, ushort ins_code)
1da177e4 10415{
27c868c2
MW
10416 AscSetBank(iop_base, 1);
10417 AscWriteChipIH(iop_base, ins_code);
10418 AscSetBank(iop_base, 0);
10419 return;
1da177e4
LT
10420}
10421
27c868c2 10422static void AscAckInterrupt(PortAddr iop_base)
1da177e4 10423{
27c868c2
MW
10424 uchar host_flag;
10425 uchar risc_flag;
10426 ushort loop;
10427
10428 loop = 0;
10429 do {
10430 risc_flag = AscReadLramByte(iop_base, ASCV_RISC_FLAG_B);
10431 if (loop++ > 0x7FFF) {
10432 break;
10433 }
10434 } while ((risc_flag & ASC_RISC_FLAG_GEN_INT) != 0);
10435 host_flag =
10436 AscReadLramByte(iop_base,
10437 ASCV_HOST_FLAG_B) & (~ASC_HOST_FLAG_ACK_INT);
10438 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
10439 (uchar)(host_flag | ASC_HOST_FLAG_ACK_INT));
10440 AscSetChipStatus(iop_base, CIW_INT_ACK);
10441 loop = 0;
10442 while (AscGetChipStatus(iop_base) & CSW_INT_PENDING) {
10443 AscSetChipStatus(iop_base, CIW_INT_ACK);
10444 if (loop++ > 3) {
10445 break;
10446 }
10447 }
10448 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
10449 return;
1da177e4
LT
10450}
10451
27c868c2 10452static void AscDisableInterrupt(PortAddr iop_base)
1da177e4 10453{
27c868c2 10454 ushort cfg;
1da177e4 10455
27c868c2
MW
10456 cfg = AscGetChipCfgLsw(iop_base);
10457 AscSetChipCfgLsw(iop_base, cfg & (~ASC_CFG0_HOST_INT_ON));
10458 return;
1da177e4
LT
10459}
10460
27c868c2 10461static void AscEnableInterrupt(PortAddr iop_base)
1da177e4 10462{
27c868c2 10463 ushort cfg;
1da177e4 10464
27c868c2
MW
10465 cfg = AscGetChipCfgLsw(iop_base);
10466 AscSetChipCfgLsw(iop_base, cfg | ASC_CFG0_HOST_INT_ON);
10467 return;
1da177e4
LT
10468}
10469
27c868c2 10470static void AscSetBank(PortAddr iop_base, uchar bank)
1da177e4 10471{
27c868c2
MW
10472 uchar val;
10473
10474 val = AscGetChipControl(iop_base) &
10475 (~
10476 (CC_SINGLE_STEP | CC_TEST | CC_DIAG | CC_SCSI_RESET |
10477 CC_CHIP_RESET));
10478 if (bank == 1) {
10479 val |= CC_BANK_ONE;
10480 } else if (bank == 2) {
10481 val |= CC_DIAG | CC_BANK_ONE;
10482 } else {
10483 val &= ~CC_BANK_ONE;
10484 }
10485 AscSetChipControl(iop_base, val);
10486 return;
1da177e4
LT
10487}
10488
27c868c2 10489static int AscResetChipAndScsiBus(ASC_DVC_VAR *asc_dvc)
1da177e4 10490{
27c868c2
MW
10491 PortAddr iop_base;
10492 int i = 10;
1da177e4 10493
27c868c2
MW
10494 iop_base = asc_dvc->iop_base;
10495 while ((AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE)
10496 && (i-- > 0)) {
10497 DvcSleepMilliSecond(100);
10498 }
10499 AscStopChip(iop_base);
10500 AscSetChipControl(iop_base, CC_CHIP_RESET | CC_SCSI_RESET | CC_HALT);
10501 DvcDelayNanoSecond(asc_dvc, 60000);
10502 AscSetChipIH(iop_base, INS_RFLAG_WTM);
10503 AscSetChipIH(iop_base, INS_HALT);
10504 AscSetChipControl(iop_base, CC_CHIP_RESET | CC_HALT);
10505 AscSetChipControl(iop_base, CC_HALT);
10506 DvcSleepMilliSecond(200);
10507 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
10508 AscSetChipStatus(iop_base, 0);
10509 return (AscIsChipHalted(iop_base));
1da177e4
LT
10510}
10511
27c868c2 10512static ASC_DCNT __init AscGetMaxDmaCount(ushort bus_type)
1da177e4 10513{
27c868c2
MW
10514 if (bus_type & ASC_IS_ISA)
10515 return (ASC_MAX_ISA_DMA_COUNT);
10516 else if (bus_type & (ASC_IS_EISA | ASC_IS_VL))
10517 return (ASC_MAX_VL_DMA_COUNT);
10518 return (ASC_MAX_PCI_DMA_COUNT);
1da177e4
LT
10519}
10520
10521#ifdef CONFIG_ISA
27c868c2 10522static ushort __init AscGetIsaDmaChannel(PortAddr iop_base)
1da177e4 10523{
27c868c2
MW
10524 ushort channel;
10525
10526 channel = AscGetChipCfgLsw(iop_base) & 0x0003;
10527 if (channel == 0x03)
10528 return (0);
10529 else if (channel == 0x00)
10530 return (7);
10531 return (channel + 4);
1da177e4
LT
10532}
10533
27c868c2 10534static ushort __init AscSetIsaDmaChannel(PortAddr iop_base, ushort dma_channel)
1da177e4 10535{
27c868c2
MW
10536 ushort cfg_lsw;
10537 uchar value;
10538
10539 if ((dma_channel >= 5) && (dma_channel <= 7)) {
10540 if (dma_channel == 7)
10541 value = 0x00;
10542 else
10543 value = dma_channel - 4;
10544 cfg_lsw = AscGetChipCfgLsw(iop_base) & 0xFFFC;
10545 cfg_lsw |= value;
10546 AscSetChipCfgLsw(iop_base, cfg_lsw);
10547 return (AscGetIsaDmaChannel(iop_base));
10548 }
10549 return (0);
1da177e4
LT
10550}
10551
27c868c2 10552static uchar __init AscSetIsaDmaSpeed(PortAddr iop_base, uchar speed_value)
1da177e4 10553{
27c868c2
MW
10554 speed_value &= 0x07;
10555 AscSetBank(iop_base, 1);
10556 AscWriteChipDmaSpeed(iop_base, speed_value);
10557 AscSetBank(iop_base, 0);
10558 return (AscGetIsaDmaSpeed(iop_base));
1da177e4
LT
10559}
10560
27c868c2 10561static uchar __init AscGetIsaDmaSpeed(PortAddr iop_base)
1da177e4 10562{
27c868c2 10563 uchar speed_value;
1da177e4 10564
27c868c2
MW
10565 AscSetBank(iop_base, 1);
10566 speed_value = AscReadChipDmaSpeed(iop_base);
10567 speed_value &= 0x07;
10568 AscSetBank(iop_base, 0);
10569 return (speed_value);
1da177e4
LT
10570}
10571#endif /* CONFIG_ISA */
10572
27c868c2
MW
10573static ushort __init
10574AscReadPCIConfigWord(ASC_DVC_VAR *asc_dvc, ushort pci_config_offset)
1da177e4 10575{
27c868c2 10576 uchar lsb, msb;
1da177e4 10577
27c868c2
MW
10578 lsb = DvcReadPCIConfigByte(asc_dvc, pci_config_offset);
10579 msb = DvcReadPCIConfigByte(asc_dvc, pci_config_offset + 1);
10580 return ((ushort)((msb << 8) | lsb));
1da177e4
LT
10581}
10582
27c868c2 10583static ushort __init AscInitGetConfig(ASC_DVC_VAR *asc_dvc)
1da177e4 10584{
27c868c2
MW
10585 ushort warn_code;
10586 PortAddr iop_base;
10587 ushort PCIDeviceID;
10588 ushort PCIVendorID;
10589 uchar PCIRevisionID;
10590 uchar prevCmdRegBits;
10591
10592 warn_code = 0;
10593 iop_base = asc_dvc->iop_base;
10594 asc_dvc->init_state = ASC_INIT_STATE_BEG_GET_CFG;
10595 if (asc_dvc->err_code != 0) {
10596 return (UW_ERR);
10597 }
10598 if (asc_dvc->bus_type == ASC_IS_PCI) {
10599 PCIVendorID = AscReadPCIConfigWord(asc_dvc,
10600 AscPCIConfigVendorIDRegister);
10601
10602 PCIDeviceID = AscReadPCIConfigWord(asc_dvc,
10603 AscPCIConfigDeviceIDRegister);
10604
10605 PCIRevisionID = DvcReadPCIConfigByte(asc_dvc,
10606 AscPCIConfigRevisionIDRegister);
10607
10608 if (PCIVendorID != PCI_VENDOR_ID_ASP) {
10609 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
10610 }
10611 prevCmdRegBits = DvcReadPCIConfigByte(asc_dvc,
10612 AscPCIConfigCommandRegister);
10613
10614 if ((prevCmdRegBits & AscPCICmdRegBits_IOMemBusMaster) !=
10615 AscPCICmdRegBits_IOMemBusMaster) {
10616 DvcWritePCIConfigByte(asc_dvc,
10617 AscPCIConfigCommandRegister,
10618 (prevCmdRegBits |
10619 AscPCICmdRegBits_IOMemBusMaster));
10620
10621 if ((DvcReadPCIConfigByte(asc_dvc,
10622 AscPCIConfigCommandRegister)
10623 & AscPCICmdRegBits_IOMemBusMaster)
10624 != AscPCICmdRegBits_IOMemBusMaster) {
10625 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
10626 }
10627 }
10628 if ((PCIDeviceID == PCI_DEVICE_ID_ASP_1200A) ||
10629 (PCIDeviceID == PCI_DEVICE_ID_ASP_ABP940)) {
10630 DvcWritePCIConfigByte(asc_dvc,
10631 AscPCIConfigLatencyTimer, 0x00);
10632 if (DvcReadPCIConfigByte
10633 (asc_dvc, AscPCIConfigLatencyTimer)
10634 != 0x00) {
10635 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
10636 }
10637 } else if (PCIDeviceID == PCI_DEVICE_ID_ASP_ABP940U) {
10638 if (DvcReadPCIConfigByte(asc_dvc,
10639 AscPCIConfigLatencyTimer) <
10640 0x20) {
10641 DvcWritePCIConfigByte(asc_dvc,
10642 AscPCIConfigLatencyTimer,
10643 0x20);
10644
10645 if (DvcReadPCIConfigByte(asc_dvc,
10646 AscPCIConfigLatencyTimer)
10647 < 0x20) {
10648 warn_code |=
10649 ASC_WARN_SET_PCI_CONFIG_SPACE;
10650 }
10651 }
10652 }
10653 }
1da177e4 10654
27c868c2
MW
10655 if (AscFindSignature(iop_base)) {
10656 warn_code |= AscInitAscDvcVar(asc_dvc);
10657 warn_code |= AscInitFromEEP(asc_dvc);
10658 asc_dvc->init_state |= ASC_INIT_STATE_END_GET_CFG;
10659 if (asc_dvc->scsi_reset_wait > ASC_MAX_SCSI_RESET_WAIT) {
10660 asc_dvc->scsi_reset_wait = ASC_MAX_SCSI_RESET_WAIT;
10661 }
10662 } else {
10663 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
10664 }
10665 return (warn_code);
1da177e4
LT
10666}
10667
27c868c2 10668static ushort __init AscInitSetConfig(ASC_DVC_VAR *asc_dvc)
1da177e4 10669{
27c868c2
MW
10670 ushort warn_code = 0;
10671
10672 asc_dvc->init_state |= ASC_INIT_STATE_BEG_SET_CFG;
10673 if (asc_dvc->err_code != 0)
10674 return (UW_ERR);
10675 if (AscFindSignature(asc_dvc->iop_base)) {
10676 warn_code |= AscInitFromAscDvcVar(asc_dvc);
10677 asc_dvc->init_state |= ASC_INIT_STATE_END_SET_CFG;
10678 } else {
10679 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
10680 }
10681 return (warn_code);
1da177e4
LT
10682}
10683
27c868c2 10684static ushort __init AscInitFromAscDvcVar(ASC_DVC_VAR *asc_dvc)
1da177e4 10685{
27c868c2
MW
10686 PortAddr iop_base;
10687 ushort cfg_msw;
10688 ushort warn_code;
10689 ushort pci_device_id = 0;
1da177e4 10690
27c868c2 10691 iop_base = asc_dvc->iop_base;
1da177e4 10692#ifdef CONFIG_PCI
27c868c2
MW
10693 if (asc_dvc->cfg->dev)
10694 pci_device_id = to_pci_dev(asc_dvc->cfg->dev)->device;
1da177e4 10695#endif
27c868c2
MW
10696 warn_code = 0;
10697 cfg_msw = AscGetChipCfgMsw(iop_base);
10698 if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
10699 cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
10700 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
10701 AscSetChipCfgMsw(iop_base, cfg_msw);
10702 }
10703 if ((asc_dvc->cfg->cmd_qng_enabled & asc_dvc->cfg->disc_enable) !=
10704 asc_dvc->cfg->cmd_qng_enabled) {
10705 asc_dvc->cfg->disc_enable = asc_dvc->cfg->cmd_qng_enabled;
10706 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
10707 }
10708 if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
10709 warn_code |= ASC_WARN_AUTO_CONFIG;
10710 }
10711 if ((asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL)) != 0) {
10712 if (AscSetChipIRQ(iop_base, asc_dvc->irq_no, asc_dvc->bus_type)
10713 != asc_dvc->irq_no) {
10714 asc_dvc->err_code |= ASC_IERR_SET_IRQ_NO;
10715 }
10716 }
10717 if (asc_dvc->bus_type & ASC_IS_PCI) {
10718 cfg_msw &= 0xFFC0;
10719 AscSetChipCfgMsw(iop_base, cfg_msw);
10720 if ((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) {
10721 } else {
10722 if ((pci_device_id == PCI_DEVICE_ID_ASP_1200A) ||
10723 (pci_device_id == PCI_DEVICE_ID_ASP_ABP940)) {
10724 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_IF_NOT_DWB;
10725 asc_dvc->bug_fix_cntl |=
10726 ASC_BUG_FIX_ASYN_USE_SYN;
10727 }
10728 }
10729 } else if (asc_dvc->bus_type == ASC_IS_ISAPNP) {
10730 if (AscGetChipVersion(iop_base, asc_dvc->bus_type)
10731 == ASC_CHIP_VER_ASYN_BUG) {
10732 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN;
10733 }
10734 }
10735 if (AscSetChipScsiID(iop_base, asc_dvc->cfg->chip_scsi_id) !=
10736 asc_dvc->cfg->chip_scsi_id) {
10737 asc_dvc->err_code |= ASC_IERR_SET_SCSI_ID;
10738 }
1da177e4 10739#ifdef CONFIG_ISA
27c868c2
MW
10740 if (asc_dvc->bus_type & ASC_IS_ISA) {
10741 AscSetIsaDmaChannel(iop_base, asc_dvc->cfg->isa_dma_channel);
10742 AscSetIsaDmaSpeed(iop_base, asc_dvc->cfg->isa_dma_speed);
10743 }
1da177e4 10744#endif /* CONFIG_ISA */
27c868c2 10745 return (warn_code);
1da177e4
LT
10746}
10747
27c868c2 10748static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc)
1da177e4 10749{
27c868c2
MW
10750 ushort warn_code;
10751 PortAddr iop_base;
10752
10753 iop_base = asc_dvc->iop_base;
10754 warn_code = 0;
10755 if ((asc_dvc->dvc_cntl & ASC_CNTL_RESET_SCSI) &&
10756 !(asc_dvc->init_state & ASC_INIT_RESET_SCSI_DONE)) {
10757 AscResetChipAndScsiBus(asc_dvc);
10758 DvcSleepMilliSecond((ASC_DCNT)
10759 ((ushort)asc_dvc->scsi_reset_wait * 1000));
10760 }
10761 asc_dvc->init_state |= ASC_INIT_STATE_BEG_LOAD_MC;
10762 if (asc_dvc->err_code != 0)
10763 return (UW_ERR);
10764 if (!AscFindSignature(asc_dvc->iop_base)) {
10765 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
10766 return (warn_code);
10767 }
10768 AscDisableInterrupt(iop_base);
10769 warn_code |= AscInitLram(asc_dvc);
10770 if (asc_dvc->err_code != 0)
10771 return (UW_ERR);
10772 ASC_DBG1(1, "AscInitAsc1000Driver: _asc_mcode_chksum 0x%lx\n",
10773 (ulong)_asc_mcode_chksum);
10774 if (AscLoadMicroCode(iop_base, 0, _asc_mcode_buf,
10775 _asc_mcode_size) != _asc_mcode_chksum) {
10776 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
10777 return (warn_code);
10778 }
10779 warn_code |= AscInitMicroCodeVar(asc_dvc);
10780 asc_dvc->init_state |= ASC_INIT_STATE_END_LOAD_MC;
10781 AscEnableInterrupt(iop_base);
10782 return (warn_code);
1da177e4
LT
10783}
10784
27c868c2 10785static ushort __init AscInitAscDvcVar(ASC_DVC_VAR *asc_dvc)
1da177e4 10786{
27c868c2
MW
10787 int i;
10788 PortAddr iop_base;
10789 ushort warn_code;
10790 uchar chip_version;
10791
10792 iop_base = asc_dvc->iop_base;
10793 warn_code = 0;
10794 asc_dvc->err_code = 0;
10795 if ((asc_dvc->bus_type &
10796 (ASC_IS_ISA | ASC_IS_PCI | ASC_IS_EISA | ASC_IS_VL)) == 0) {
10797 asc_dvc->err_code |= ASC_IERR_NO_BUS_TYPE;
10798 }
10799 AscSetChipControl(iop_base, CC_HALT);
10800 AscSetChipStatus(iop_base, 0);
10801 asc_dvc->bug_fix_cntl = 0;
10802 asc_dvc->pci_fix_asyn_xfer = 0;
10803 asc_dvc->pci_fix_asyn_xfer_always = 0;
10804 /* asc_dvc->init_state initalized in AscInitGetConfig(). */
10805 asc_dvc->sdtr_done = 0;
10806 asc_dvc->cur_total_qng = 0;
10807 asc_dvc->is_in_int = 0;
10808 asc_dvc->in_critical_cnt = 0;
10809 asc_dvc->last_q_shortage = 0;
10810 asc_dvc->use_tagged_qng = 0;
10811 asc_dvc->no_scam = 0;
10812 asc_dvc->unit_not_ready = 0;
10813 asc_dvc->queue_full_or_busy = 0;
10814 asc_dvc->redo_scam = 0;
10815 asc_dvc->res2 = 0;
10816 asc_dvc->host_init_sdtr_index = 0;
10817 asc_dvc->cfg->can_tagged_qng = 0;
10818 asc_dvc->cfg->cmd_qng_enabled = 0;
10819 asc_dvc->dvc_cntl = ASC_DEF_DVC_CNTL;
10820 asc_dvc->init_sdtr = 0;
10821 asc_dvc->max_total_qng = ASC_DEF_MAX_TOTAL_QNG;
10822 asc_dvc->scsi_reset_wait = 3;
10823 asc_dvc->start_motor = ASC_SCSI_WIDTH_BIT_SET;
10824 asc_dvc->max_dma_count = AscGetMaxDmaCount(asc_dvc->bus_type);
10825 asc_dvc->cfg->sdtr_enable = ASC_SCSI_WIDTH_BIT_SET;
10826 asc_dvc->cfg->disc_enable = ASC_SCSI_WIDTH_BIT_SET;
10827 asc_dvc->cfg->chip_scsi_id = ASC_DEF_CHIP_SCSI_ID;
10828 asc_dvc->cfg->lib_serial_no = ASC_LIB_SERIAL_NUMBER;
10829 asc_dvc->cfg->lib_version = (ASC_LIB_VERSION_MAJOR << 8) |
10830 ASC_LIB_VERSION_MINOR;
10831 chip_version = AscGetChipVersion(iop_base, asc_dvc->bus_type);
10832 asc_dvc->cfg->chip_version = chip_version;
10833 asc_dvc->sdtr_period_tbl[0] = SYN_XFER_NS_0;
10834 asc_dvc->sdtr_period_tbl[1] = SYN_XFER_NS_1;
10835 asc_dvc->sdtr_period_tbl[2] = SYN_XFER_NS_2;
10836 asc_dvc->sdtr_period_tbl[3] = SYN_XFER_NS_3;
10837 asc_dvc->sdtr_period_tbl[4] = SYN_XFER_NS_4;
10838 asc_dvc->sdtr_period_tbl[5] = SYN_XFER_NS_5;
10839 asc_dvc->sdtr_period_tbl[6] = SYN_XFER_NS_6;
10840 asc_dvc->sdtr_period_tbl[7] = SYN_XFER_NS_7;
10841 asc_dvc->max_sdtr_index = 7;
10842 if ((asc_dvc->bus_type & ASC_IS_PCI) &&
10843 (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3150)) {
10844 asc_dvc->bus_type = ASC_IS_PCI_ULTRA;
10845 asc_dvc->sdtr_period_tbl[0] = SYN_ULTRA_XFER_NS_0;
10846 asc_dvc->sdtr_period_tbl[1] = SYN_ULTRA_XFER_NS_1;
10847 asc_dvc->sdtr_period_tbl[2] = SYN_ULTRA_XFER_NS_2;
10848 asc_dvc->sdtr_period_tbl[3] = SYN_ULTRA_XFER_NS_3;
10849 asc_dvc->sdtr_period_tbl[4] = SYN_ULTRA_XFER_NS_4;
10850 asc_dvc->sdtr_period_tbl[5] = SYN_ULTRA_XFER_NS_5;
10851 asc_dvc->sdtr_period_tbl[6] = SYN_ULTRA_XFER_NS_6;
10852 asc_dvc->sdtr_period_tbl[7] = SYN_ULTRA_XFER_NS_7;
10853 asc_dvc->sdtr_period_tbl[8] = SYN_ULTRA_XFER_NS_8;
10854 asc_dvc->sdtr_period_tbl[9] = SYN_ULTRA_XFER_NS_9;
10855 asc_dvc->sdtr_period_tbl[10] = SYN_ULTRA_XFER_NS_10;
10856 asc_dvc->sdtr_period_tbl[11] = SYN_ULTRA_XFER_NS_11;
10857 asc_dvc->sdtr_period_tbl[12] = SYN_ULTRA_XFER_NS_12;
10858 asc_dvc->sdtr_period_tbl[13] = SYN_ULTRA_XFER_NS_13;
10859 asc_dvc->sdtr_period_tbl[14] = SYN_ULTRA_XFER_NS_14;
10860 asc_dvc->sdtr_period_tbl[15] = SYN_ULTRA_XFER_NS_15;
10861 asc_dvc->max_sdtr_index = 15;
10862 if (chip_version == ASC_CHIP_VER_PCI_ULTRA_3150) {
10863 AscSetExtraControl(iop_base,
10864 (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
10865 } else if (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3050) {
10866 AscSetExtraControl(iop_base,
10867 (SEC_ACTIVE_NEGATE |
10868 SEC_ENABLE_FILTER));
10869 }
10870 }
10871 if (asc_dvc->bus_type == ASC_IS_PCI) {
10872 AscSetExtraControl(iop_base,
10873 (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
10874 }
1da177e4 10875
27c868c2
MW
10876 asc_dvc->cfg->isa_dma_speed = ASC_DEF_ISA_DMA_SPEED;
10877 if (AscGetChipBusType(iop_base) == ASC_IS_ISAPNP) {
10878 AscSetChipIFC(iop_base, IFC_INIT_DEFAULT);
10879 asc_dvc->bus_type = ASC_IS_ISAPNP;
10880 }
1da177e4 10881#ifdef CONFIG_ISA
27c868c2
MW
10882 if ((asc_dvc->bus_type & ASC_IS_ISA) != 0) {
10883 asc_dvc->cfg->isa_dma_channel =
10884 (uchar)AscGetIsaDmaChannel(iop_base);
10885 }
1da177e4 10886#endif /* CONFIG_ISA */
27c868c2
MW
10887 for (i = 0; i <= ASC_MAX_TID; i++) {
10888 asc_dvc->cur_dvc_qng[i] = 0;
10889 asc_dvc->max_dvc_qng[i] = ASC_MAX_SCSI1_QNG;
10890 asc_dvc->scsiq_busy_head[i] = (ASC_SCSI_Q *)0L;
10891 asc_dvc->scsiq_busy_tail[i] = (ASC_SCSI_Q *)0L;
10892 asc_dvc->cfg->max_tag_qng[i] = ASC_MAX_INRAM_TAG_QNG;
10893 }
10894 return (warn_code);
1da177e4
LT
10895}
10896
27c868c2 10897static ushort __init AscInitFromEEP(ASC_DVC_VAR *asc_dvc)
1da177e4 10898{
27c868c2
MW
10899 ASCEEP_CONFIG eep_config_buf;
10900 ASCEEP_CONFIG *eep_config;
10901 PortAddr iop_base;
10902 ushort chksum;
10903 ushort warn_code;
10904 ushort cfg_msw, cfg_lsw;
10905 int i;
10906 int write_eep = 0;
10907
10908 iop_base = asc_dvc->iop_base;
10909 warn_code = 0;
10910 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0x00FE);
10911 AscStopQueueExe(iop_base);
10912 if ((AscStopChip(iop_base) == FALSE) ||
10913 (AscGetChipScsiCtrl(iop_base) != 0)) {
10914 asc_dvc->init_state |= ASC_INIT_RESET_SCSI_DONE;
10915 AscResetChipAndScsiBus(asc_dvc);
10916 DvcSleepMilliSecond((ASC_DCNT)
10917 ((ushort)asc_dvc->scsi_reset_wait * 1000));
10918 }
10919 if (AscIsChipHalted(iop_base) == FALSE) {
10920 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
10921 return (warn_code);
10922 }
10923 AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
10924 if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
10925 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
10926 return (warn_code);
10927 }
10928 eep_config = (ASCEEP_CONFIG *)&eep_config_buf;
10929 cfg_msw = AscGetChipCfgMsw(iop_base);
10930 cfg_lsw = AscGetChipCfgLsw(iop_base);
10931 if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
10932 cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
10933 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
10934 AscSetChipCfgMsw(iop_base, cfg_msw);
10935 }
10936 chksum = AscGetEEPConfig(iop_base, eep_config, asc_dvc->bus_type);
10937 ASC_DBG1(1, "AscInitFromEEP: chksum 0x%x\n", chksum);
10938 if (chksum == 0) {
10939 chksum = 0xaa55;
10940 }
10941 if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
10942 warn_code |= ASC_WARN_AUTO_CONFIG;
10943 if (asc_dvc->cfg->chip_version == 3) {
10944 if (eep_config->cfg_lsw != cfg_lsw) {
10945 warn_code |= ASC_WARN_EEPROM_RECOVER;
10946 eep_config->cfg_lsw =
10947 AscGetChipCfgLsw(iop_base);
10948 }
10949 if (eep_config->cfg_msw != cfg_msw) {
10950 warn_code |= ASC_WARN_EEPROM_RECOVER;
10951 eep_config->cfg_msw =
10952 AscGetChipCfgMsw(iop_base);
10953 }
10954 }
10955 }
10956 eep_config->cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
10957 eep_config->cfg_lsw |= ASC_CFG0_HOST_INT_ON;
10958 ASC_DBG1(1, "AscInitFromEEP: eep_config->chksum 0x%x\n",
10959 eep_config->chksum);
10960 if (chksum != eep_config->chksum) {
10961 if (AscGetChipVersion(iop_base, asc_dvc->bus_type) ==
10962 ASC_CHIP_VER_PCI_ULTRA_3050) {
10963 ASC_DBG(1,
10964 "AscInitFromEEP: chksum error ignored; EEPROM-less board\n");
10965 eep_config->init_sdtr = 0xFF;
10966 eep_config->disc_enable = 0xFF;
10967 eep_config->start_motor = 0xFF;
10968 eep_config->use_cmd_qng = 0;
10969 eep_config->max_total_qng = 0xF0;
10970 eep_config->max_tag_qng = 0x20;
10971 eep_config->cntl = 0xBFFF;
10972 ASC_EEP_SET_CHIP_ID(eep_config, 7);
10973 eep_config->no_scam = 0;
10974 eep_config->adapter_info[0] = 0;
10975 eep_config->adapter_info[1] = 0;
10976 eep_config->adapter_info[2] = 0;
10977 eep_config->adapter_info[3] = 0;
10978 eep_config->adapter_info[4] = 0;
10979 /* Indicate EEPROM-less board. */
10980 eep_config->adapter_info[5] = 0xBB;
10981 } else {
10982 ASC_PRINT
10983 ("AscInitFromEEP: EEPROM checksum error; Will try to re-write EEPROM.\n");
10984 write_eep = 1;
10985 warn_code |= ASC_WARN_EEPROM_CHKSUM;
10986 }
10987 }
10988 asc_dvc->cfg->sdtr_enable = eep_config->init_sdtr;
10989 asc_dvc->cfg->disc_enable = eep_config->disc_enable;
10990 asc_dvc->cfg->cmd_qng_enabled = eep_config->use_cmd_qng;
10991 asc_dvc->cfg->isa_dma_speed = ASC_EEP_GET_DMA_SPD(eep_config);
10992 asc_dvc->start_motor = eep_config->start_motor;
10993 asc_dvc->dvc_cntl = eep_config->cntl;
10994 asc_dvc->no_scam = eep_config->no_scam;
10995 asc_dvc->cfg->adapter_info[0] = eep_config->adapter_info[0];
10996 asc_dvc->cfg->adapter_info[1] = eep_config->adapter_info[1];
10997 asc_dvc->cfg->adapter_info[2] = eep_config->adapter_info[2];
10998 asc_dvc->cfg->adapter_info[3] = eep_config->adapter_info[3];
10999 asc_dvc->cfg->adapter_info[4] = eep_config->adapter_info[4];
11000 asc_dvc->cfg->adapter_info[5] = eep_config->adapter_info[5];
11001 if (!AscTestExternalLram(asc_dvc)) {
11002 if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) ==
11003 ASC_IS_PCI_ULTRA)) {
11004 eep_config->max_total_qng =
11005 ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG;
11006 eep_config->max_tag_qng =
11007 ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG;
11008 } else {
11009 eep_config->cfg_msw |= 0x0800;
11010 cfg_msw |= 0x0800;
11011 AscSetChipCfgMsw(iop_base, cfg_msw);
11012 eep_config->max_total_qng = ASC_MAX_PCI_INRAM_TOTAL_QNG;
11013 eep_config->max_tag_qng = ASC_MAX_INRAM_TAG_QNG;
11014 }
11015 } else {
11016 }
11017 if (eep_config->max_total_qng < ASC_MIN_TOTAL_QNG) {
11018 eep_config->max_total_qng = ASC_MIN_TOTAL_QNG;
11019 }
11020 if (eep_config->max_total_qng > ASC_MAX_TOTAL_QNG) {
11021 eep_config->max_total_qng = ASC_MAX_TOTAL_QNG;
11022 }
11023 if (eep_config->max_tag_qng > eep_config->max_total_qng) {
11024 eep_config->max_tag_qng = eep_config->max_total_qng;
11025 }
11026 if (eep_config->max_tag_qng < ASC_MIN_TAG_Q_PER_DVC) {
11027 eep_config->max_tag_qng = ASC_MIN_TAG_Q_PER_DVC;
11028 }
11029 asc_dvc->max_total_qng = eep_config->max_total_qng;
11030 if ((eep_config->use_cmd_qng & eep_config->disc_enable) !=
11031 eep_config->use_cmd_qng) {
11032 eep_config->disc_enable = eep_config->use_cmd_qng;
11033 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
11034 }
11035 if (asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL | ASC_IS_EISA)) {
11036 asc_dvc->irq_no = AscGetChipIRQ(iop_base, asc_dvc->bus_type);
11037 }
11038 ASC_EEP_SET_CHIP_ID(eep_config,
11039 ASC_EEP_GET_CHIP_ID(eep_config) & ASC_MAX_TID);
11040 asc_dvc->cfg->chip_scsi_id = ASC_EEP_GET_CHIP_ID(eep_config);
11041 if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) &&
11042 !(asc_dvc->dvc_cntl & ASC_CNTL_SDTR_ENABLE_ULTRA)) {
11043 asc_dvc->host_init_sdtr_index = ASC_SDTR_ULTRA_PCI_10MB_INDEX;
11044 }
1da177e4 11045
27c868c2
MW
11046 for (i = 0; i <= ASC_MAX_TID; i++) {
11047 asc_dvc->dos_int13_table[i] = eep_config->dos_int13_table[i];
11048 asc_dvc->cfg->max_tag_qng[i] = eep_config->max_tag_qng;
11049 asc_dvc->cfg->sdtr_period_offset[i] =
11050 (uchar)(ASC_DEF_SDTR_OFFSET |
11051 (asc_dvc->host_init_sdtr_index << 4));
11052 }
11053 eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
11054 if (write_eep) {
11055 if ((i =
11056 AscSetEEPConfig(iop_base, eep_config,
11057 asc_dvc->bus_type)) != 0) {
11058 ASC_PRINT1
11059 ("AscInitFromEEP: Failed to re-write EEPROM with %d errors.\n",
11060 i);
11061 } else {
11062 ASC_PRINT
11063 ("AscInitFromEEP: Successfully re-wrote EEPROM.\n");
11064 }
11065 }
11066 return (warn_code);
1da177e4
LT
11067}
11068
27c868c2 11069static ushort AscInitMicroCodeVar(ASC_DVC_VAR *asc_dvc)
1da177e4 11070{
27c868c2
MW
11071 int i;
11072 ushort warn_code;
11073 PortAddr iop_base;
11074 ASC_PADDR phy_addr;
11075 ASC_DCNT phy_size;
11076
11077 iop_base = asc_dvc->iop_base;
11078 warn_code = 0;
11079 for (i = 0; i <= ASC_MAX_TID; i++) {
11080 AscPutMCodeInitSDTRAtID(iop_base, i,
11081 asc_dvc->cfg->sdtr_period_offset[i]
11082 );
11083 }
1da177e4 11084
27c868c2
MW
11085 AscInitQLinkVar(asc_dvc);
11086 AscWriteLramByte(iop_base, ASCV_DISC_ENABLE_B,
11087 asc_dvc->cfg->disc_enable);
11088 AscWriteLramByte(iop_base, ASCV_HOSTSCSI_ID_B,
11089 ASC_TID_TO_TARGET_ID(asc_dvc->cfg->chip_scsi_id));
11090
11091 /* Align overrun buffer on an 8 byte boundary. */
11092 phy_addr = virt_to_bus(asc_dvc->cfg->overrun_buf);
11093 phy_addr = cpu_to_le32((phy_addr + 7) & ~0x7);
11094 AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_PADDR_D,
11095 (uchar *)&phy_addr, 1);
11096 phy_size = cpu_to_le32(ASC_OVERRUN_BSIZE - 8);
11097 AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_BSIZE_D,
11098 (uchar *)&phy_size, 1);
11099
11100 asc_dvc->cfg->mcode_date =
11101 AscReadLramWord(iop_base, (ushort)ASCV_MC_DATE_W);
11102 asc_dvc->cfg->mcode_version =
11103 AscReadLramWord(iop_base, (ushort)ASCV_MC_VER_W);
11104
11105 AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
11106 if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
11107 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
11108 return (warn_code);
11109 }
11110 if (AscStartChip(iop_base) != 1) {
11111 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
11112 return (warn_code);
11113 }
1da177e4 11114
27c868c2 11115 return (warn_code);
1da177e4
LT
11116}
11117
27c868c2 11118static int __init AscTestExternalLram(ASC_DVC_VAR *asc_dvc)
1da177e4 11119{
27c868c2
MW
11120 PortAddr iop_base;
11121 ushort q_addr;
11122 ushort saved_word;
11123 int sta;
11124
11125 iop_base = asc_dvc->iop_base;
11126 sta = 0;
11127 q_addr = ASC_QNO_TO_QADDR(241);
11128 saved_word = AscReadLramWord(iop_base, q_addr);
11129 AscSetChipLramAddr(iop_base, q_addr);
11130 AscSetChipLramData(iop_base, 0x55AA);
11131 DvcSleepMilliSecond(10);
11132 AscSetChipLramAddr(iop_base, q_addr);
11133 if (AscGetChipLramData(iop_base) == 0x55AA) {
11134 sta = 1;
11135 AscWriteLramWord(iop_base, q_addr, saved_word);
11136 }
11137 return (sta);
1da177e4
LT
11138}
11139
27c868c2 11140static int __init AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg)
1da177e4 11141{
27c868c2
MW
11142 uchar read_back;
11143 int retry;
11144
11145 retry = 0;
11146 while (TRUE) {
11147 AscSetChipEEPCmd(iop_base, cmd_reg);
11148 DvcSleepMilliSecond(1);
11149 read_back = AscGetChipEEPCmd(iop_base);
11150 if (read_back == cmd_reg) {
11151 return (1);
11152 }
11153 if (retry++ > ASC_EEP_MAX_RETRY) {
11154 return (0);
11155 }
11156 }
1da177e4
LT
11157}
11158
27c868c2 11159static int __init AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg)
1da177e4 11160{
27c868c2
MW
11161 ushort read_back;
11162 int retry;
11163
11164 retry = 0;
11165 while (TRUE) {
11166 AscSetChipEEPData(iop_base, data_reg);
11167 DvcSleepMilliSecond(1);
11168 read_back = AscGetChipEEPData(iop_base);
11169 if (read_back == data_reg) {
11170 return (1);
11171 }
11172 if (retry++ > ASC_EEP_MAX_RETRY) {
11173 return (0);
11174 }
11175 }
1da177e4
LT
11176}
11177
27c868c2 11178static void __init AscWaitEEPRead(void)
1da177e4 11179{
27c868c2
MW
11180 DvcSleepMilliSecond(1);
11181 return;
1da177e4
LT
11182}
11183
27c868c2 11184static void __init AscWaitEEPWrite(void)
1da177e4 11185{
27c868c2
MW
11186 DvcSleepMilliSecond(20);
11187 return;
1da177e4
LT
11188}
11189
27c868c2 11190static ushort __init AscReadEEPWord(PortAddr iop_base, uchar addr)
1da177e4 11191{
27c868c2
MW
11192 ushort read_wval;
11193 uchar cmd_reg;
11194
11195 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
11196 AscWaitEEPRead();
11197 cmd_reg = addr | ASC_EEP_CMD_READ;
11198 AscWriteEEPCmdReg(iop_base, cmd_reg);
11199 AscWaitEEPRead();
11200 read_wval = AscGetChipEEPData(iop_base);
11201 AscWaitEEPRead();
11202 return (read_wval);
1da177e4
LT
11203}
11204
27c868c2
MW
11205static ushort __init
11206AscWriteEEPWord(PortAddr iop_base, uchar addr, ushort word_val)
1da177e4 11207{
27c868c2
MW
11208 ushort read_wval;
11209
11210 read_wval = AscReadEEPWord(iop_base, addr);
11211 if (read_wval != word_val) {
11212 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_ABLE);
11213 AscWaitEEPRead();
11214 AscWriteEEPDataReg(iop_base, word_val);
11215 AscWaitEEPRead();
11216 AscWriteEEPCmdReg(iop_base,
11217 (uchar)((uchar)ASC_EEP_CMD_WRITE | addr));
11218 AscWaitEEPWrite();
11219 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
11220 AscWaitEEPRead();
11221 return (AscReadEEPWord(iop_base, addr));
11222 }
11223 return (read_wval);
1da177e4
LT
11224}
11225
27c868c2
MW
11226static ushort __init
11227AscGetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
1da177e4 11228{
27c868c2
MW
11229 ushort wval;
11230 ushort sum;
11231 ushort *wbuf;
11232 int cfg_beg;
11233 int cfg_end;
11234 int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
11235 int s_addr;
11236
11237 wbuf = (ushort *)cfg_buf;
11238 sum = 0;
11239 /* Read two config words; Byte-swapping done by AscReadEEPWord(). */
11240 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
11241 *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr);
11242 sum += *wbuf;
11243 }
11244 if (bus_type & ASC_IS_VL) {
11245 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
11246 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
11247 } else {
11248 cfg_beg = ASC_EEP_DVC_CFG_BEG;
11249 cfg_end = ASC_EEP_MAX_DVC_ADDR;
11250 }
11251 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
11252 wval = AscReadEEPWord(iop_base, (uchar)s_addr);
11253 if (s_addr <= uchar_end_in_config) {
11254 /*
11255 * Swap all char fields - must unswap bytes already swapped
11256 * by AscReadEEPWord().
11257 */
11258 *wbuf = le16_to_cpu(wval);
11259 } else {
11260 /* Don't swap word field at the end - cntl field. */
11261 *wbuf = wval;
11262 }
11263 sum += wval; /* Checksum treats all EEPROM data as words. */
11264 }
11265 /*
11266 * Read the checksum word which will be compared against 'sum'
11267 * by the caller. Word field already swapped.
11268 */
11269 *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr);
11270 return (sum);
1da177e4
LT
11271}
11272
27c868c2
MW
11273static int __init
11274AscSetEEPConfigOnce(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
1da177e4 11275{
27c868c2
MW
11276 int n_error;
11277 ushort *wbuf;
11278 ushort word;
11279 ushort sum;
11280 int s_addr;
11281 int cfg_beg;
11282 int cfg_end;
11283 int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
11284
11285 wbuf = (ushort *)cfg_buf;
11286 n_error = 0;
11287 sum = 0;
11288 /* Write two config words; AscWriteEEPWord() will swap bytes. */
11289 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
11290 sum += *wbuf;
11291 if (*wbuf != AscWriteEEPWord(iop_base, (uchar)s_addr, *wbuf)) {
11292 n_error++;
11293 }
11294 }
11295 if (bus_type & ASC_IS_VL) {
11296 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
11297 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
11298 } else {
11299 cfg_beg = ASC_EEP_DVC_CFG_BEG;
11300 cfg_end = ASC_EEP_MAX_DVC_ADDR;
11301 }
11302 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
11303 if (s_addr <= uchar_end_in_config) {
11304 /*
11305 * This is a char field. Swap char fields before they are
11306 * swapped again by AscWriteEEPWord().
11307 */
11308 word = cpu_to_le16(*wbuf);
11309 if (word !=
11310 AscWriteEEPWord(iop_base, (uchar)s_addr, word)) {
11311 n_error++;
11312 }
11313 } else {
11314 /* Don't swap word field at the end - cntl field. */
11315 if (*wbuf !=
11316 AscWriteEEPWord(iop_base, (uchar)s_addr, *wbuf)) {
11317 n_error++;
11318 }
11319 }
11320 sum += *wbuf; /* Checksum calculated from word values. */
11321 }
11322 /* Write checksum word. It will be swapped by AscWriteEEPWord(). */
11323 *wbuf = sum;
11324 if (sum != AscWriteEEPWord(iop_base, (uchar)s_addr, sum)) {
11325 n_error++;
11326 }
1da177e4 11327
27c868c2
MW
11328 /* Read EEPROM back again. */
11329 wbuf = (ushort *)cfg_buf;
11330 /*
11331 * Read two config words; Byte-swapping done by AscReadEEPWord().
11332 */
11333 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
11334 if (*wbuf != AscReadEEPWord(iop_base, (uchar)s_addr)) {
11335 n_error++;
11336 }
11337 }
11338 if (bus_type & ASC_IS_VL) {
11339 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
11340 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
11341 } else {
11342 cfg_beg = ASC_EEP_DVC_CFG_BEG;
11343 cfg_end = ASC_EEP_MAX_DVC_ADDR;
11344 }
11345 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
11346 if (s_addr <= uchar_end_in_config) {
11347 /*
11348 * Swap all char fields. Must unswap bytes already swapped
11349 * by AscReadEEPWord().
11350 */
11351 word =
11352 le16_to_cpu(AscReadEEPWord
11353 (iop_base, (uchar)s_addr));
11354 } else {
11355 /* Don't swap word field at the end - cntl field. */
11356 word = AscReadEEPWord(iop_base, (uchar)s_addr);
11357 }
11358 if (*wbuf != word) {
11359 n_error++;
11360 }
11361 }
11362 /* Read checksum; Byte swapping not needed. */
11363 if (AscReadEEPWord(iop_base, (uchar)s_addr) != sum) {
11364 n_error++;
11365 }
11366 return (n_error);
1da177e4
LT
11367}
11368
27c868c2
MW
11369static int __init
11370AscSetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
1da177e4 11371{
27c868c2
MW
11372 int retry;
11373 int n_error;
11374
11375 retry = 0;
11376 while (TRUE) {
11377 if ((n_error = AscSetEEPConfigOnce(iop_base, cfg_buf,
11378 bus_type)) == 0) {
11379 break;
11380 }
11381 if (++retry > ASC_EEP_MAX_RETRY) {
11382 break;
11383 }
11384 }
11385 return (n_error);
1da177e4
LT
11386}
11387
27c868c2
MW
11388static void
11389AscAsyncFix(ASC_DVC_VAR *asc_dvc, uchar tid_no, ASC_SCSI_INQUIRY *inq)
1da177e4 11390{
27c868c2
MW
11391 uchar dvc_type;
11392 ASC_SCSI_BIT_ID_TYPE tid_bits;
11393
11394 dvc_type = ASC_INQ_DVC_TYPE(inq);
11395 tid_bits = ASC_TIX_TO_TARGET_ID(tid_no);
11396
11397 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ASYN_USE_SYN) {
11398 if (!(asc_dvc->init_sdtr & tid_bits)) {
11399 if ((dvc_type == TYPE_ROM) &&
11400 (AscCompareString((uchar *)inq->vendor_id,
11401 (uchar *)"HP ", 3) == 0)) {
11402 asc_dvc->pci_fix_asyn_xfer_always |= tid_bits;
11403 }
11404 asc_dvc->pci_fix_asyn_xfer |= tid_bits;
11405 if ((dvc_type == TYPE_PROCESSOR) ||
11406 (dvc_type == TYPE_SCANNER) ||
11407 (dvc_type == TYPE_ROM) || (dvc_type == TYPE_TAPE)) {
11408 asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
11409 }
11410
11411 if (asc_dvc->pci_fix_asyn_xfer & tid_bits) {
11412 AscSetRunChipSynRegAtID(asc_dvc->iop_base,
11413 tid_no,
11414 ASYN_SDTR_DATA_FIX_PCI_REV_AB);
11415 }
11416 }
11417 }
11418 return;
1da177e4
LT
11419}
11420
27c868c2 11421static int AscTagQueuingSafe(ASC_SCSI_INQUIRY *inq)
1da177e4 11422{
27c868c2
MW
11423 if ((inq->add_len >= 32) &&
11424 (AscCompareString((uchar *)inq->vendor_id,
11425 (uchar *)"QUANTUM XP34301", 15) == 0) &&
11426 (AscCompareString((uchar *)inq->product_rev_level,
11427 (uchar *)"1071", 4) == 0)) {
11428 return 0;
11429 }
11430 return 1;
1da177e4
LT
11431}
11432
27c868c2
MW
11433static void
11434AscInquiryHandling(ASC_DVC_VAR *asc_dvc, uchar tid_no, ASC_SCSI_INQUIRY *inq)
1da177e4 11435{
27c868c2
MW
11436 ASC_SCSI_BIT_ID_TYPE tid_bit = ASC_TIX_TO_TARGET_ID(tid_no);
11437 ASC_SCSI_BIT_ID_TYPE orig_init_sdtr, orig_use_tagged_qng;
11438
11439 orig_init_sdtr = asc_dvc->init_sdtr;
11440 orig_use_tagged_qng = asc_dvc->use_tagged_qng;
11441
11442 asc_dvc->init_sdtr &= ~tid_bit;
11443 asc_dvc->cfg->can_tagged_qng &= ~tid_bit;
11444 asc_dvc->use_tagged_qng &= ~tid_bit;
11445
11446 if (ASC_INQ_RESPONSE_FMT(inq) >= 2 || ASC_INQ_ANSI_VER(inq) >= 2) {
11447 if ((asc_dvc->cfg->sdtr_enable & tid_bit) && ASC_INQ_SYNC(inq)) {
11448 asc_dvc->init_sdtr |= tid_bit;
11449 }
11450 if ((asc_dvc->cfg->cmd_qng_enabled & tid_bit) &&
11451 ASC_INQ_CMD_QUEUE(inq)) {
11452 if (AscTagQueuingSafe(inq)) {
11453 asc_dvc->use_tagged_qng |= tid_bit;
11454 asc_dvc->cfg->can_tagged_qng |= tid_bit;
11455 }
11456 }
11457 }
11458 if (orig_use_tagged_qng != asc_dvc->use_tagged_qng) {
11459 AscWriteLramByte(asc_dvc->iop_base, ASCV_DISC_ENABLE_B,
11460 asc_dvc->cfg->disc_enable);
11461 AscWriteLramByte(asc_dvc->iop_base, ASCV_USE_TAGGED_QNG_B,
11462 asc_dvc->use_tagged_qng);
11463 AscWriteLramByte(asc_dvc->iop_base, ASCV_CAN_TAGGED_QNG_B,
11464 asc_dvc->cfg->can_tagged_qng);
11465
11466 asc_dvc->max_dvc_qng[tid_no] =
11467 asc_dvc->cfg->max_tag_qng[tid_no];
11468 AscWriteLramByte(asc_dvc->iop_base,
11469 (ushort)(ASCV_MAX_DVC_QNG_BEG + tid_no),
11470 asc_dvc->max_dvc_qng[tid_no]);
11471 }
11472 if (orig_init_sdtr != asc_dvc->init_sdtr) {
11473 AscAsyncFix(asc_dvc, tid_no, inq);
11474 }
11475 return;
1da177e4
LT
11476}
11477
27c868c2 11478static int AscCompareString(uchar *str1, uchar *str2, int len)
1da177e4 11479{
27c868c2
MW
11480 int i;
11481 int diff;
1da177e4 11482
27c868c2
MW
11483 for (i = 0; i < len; i++) {
11484 diff = (int)(str1[i] - str2[i]);
11485 if (diff != 0)
11486 return (diff);
11487 }
11488 return (0);
1da177e4
LT
11489}
11490
27c868c2 11491static uchar AscReadLramByte(PortAddr iop_base, ushort addr)
1da177e4 11492{
27c868c2
MW
11493 uchar byte_data;
11494 ushort word_data;
11495
11496 if (isodd_word(addr)) {
11497 AscSetChipLramAddr(iop_base, addr - 1);
11498 word_data = AscGetChipLramData(iop_base);
11499 byte_data = (uchar)((word_data >> 8) & 0xFF);
11500 } else {
11501 AscSetChipLramAddr(iop_base, addr);
11502 word_data = AscGetChipLramData(iop_base);
11503 byte_data = (uchar)(word_data & 0xFF);
11504 }
11505 return (byte_data);
1da177e4 11506}
27c868c2
MW
11507
11508static ushort AscReadLramWord(PortAddr iop_base, ushort addr)
1da177e4 11509{
27c868c2 11510 ushort word_data;
1da177e4 11511
27c868c2
MW
11512 AscSetChipLramAddr(iop_base, addr);
11513 word_data = AscGetChipLramData(iop_base);
11514 return (word_data);
1da177e4
LT
11515}
11516
11517#if CC_VERY_LONG_SG_LIST
27c868c2 11518static ASC_DCNT AscReadLramDWord(PortAddr iop_base, ushort addr)
1da177e4 11519{
27c868c2
MW
11520 ushort val_low, val_high;
11521 ASC_DCNT dword_data;
11522
11523 AscSetChipLramAddr(iop_base, addr);
11524 val_low = AscGetChipLramData(iop_base);
11525 val_high = AscGetChipLramData(iop_base);
11526 dword_data = ((ASC_DCNT) val_high << 16) | (ASC_DCNT) val_low;
11527 return (dword_data);
1da177e4
LT
11528}
11529#endif /* CC_VERY_LONG_SG_LIST */
11530
27c868c2 11531static void AscWriteLramWord(PortAddr iop_base, ushort addr, ushort word_val)
1da177e4 11532{
27c868c2
MW
11533 AscSetChipLramAddr(iop_base, addr);
11534 AscSetChipLramData(iop_base, word_val);
11535 return;
1da177e4
LT
11536}
11537
27c868c2 11538static void AscWriteLramByte(PortAddr iop_base, ushort addr, uchar byte_val)
1da177e4 11539{
27c868c2
MW
11540 ushort word_data;
11541
11542 if (isodd_word(addr)) {
11543 addr--;
11544 word_data = AscReadLramWord(iop_base, addr);
11545 word_data &= 0x00FF;
11546 word_data |= (((ushort)byte_val << 8) & 0xFF00);
11547 } else {
11548 word_data = AscReadLramWord(iop_base, addr);
11549 word_data &= 0xFF00;
11550 word_data |= ((ushort)byte_val & 0x00FF);
11551 }
11552 AscWriteLramWord(iop_base, addr, word_data);
11553 return;
1da177e4
LT
11554}
11555
11556/*
11557 * Copy 2 bytes to LRAM.
11558 *
11559 * The source data is assumed to be in little-endian order in memory
11560 * and is maintained in little-endian order when written to LRAM.
11561 */
27c868c2
MW
11562static void
11563AscMemWordCopyPtrToLram(PortAddr iop_base,
11564 ushort s_addr, uchar *s_buffer, int words)
1da177e4 11565{
27c868c2
MW
11566 int i;
11567
11568 AscSetChipLramAddr(iop_base, s_addr);
11569 for (i = 0; i < 2 * words; i += 2) {
11570 /*
11571 * On a little-endian system the second argument below
11572 * produces a little-endian ushort which is written to
11573 * LRAM in little-endian order. On a big-endian system
11574 * the second argument produces a big-endian ushort which
11575 * is "transparently" byte-swapped by outpw() and written
11576 * in little-endian order to LRAM.
11577 */
11578 outpw(iop_base + IOP_RAM_DATA,
11579 ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]);
11580 }
11581 return;
1da177e4
LT
11582}
11583
11584/*
11585 * Copy 4 bytes to LRAM.
11586 *
11587 * The source data is assumed to be in little-endian order in memory
11588 * and is maintained in little-endian order when writen to LRAM.
11589 */
27c868c2
MW
11590static void
11591AscMemDWordCopyPtrToLram(PortAddr iop_base,
11592 ushort s_addr, uchar *s_buffer, int dwords)
1da177e4 11593{
27c868c2
MW
11594 int i;
11595
11596 AscSetChipLramAddr(iop_base, s_addr);
11597 for (i = 0; i < 4 * dwords; i += 4) {
11598 outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]); /* LSW */
11599 outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 3] << 8) | s_buffer[i + 2]); /* MSW */
11600 }
11601 return;
1da177e4
LT
11602}
11603
11604/*
11605 * Copy 2 bytes from LRAM.
11606 *
11607 * The source data is assumed to be in little-endian order in LRAM
11608 * and is maintained in little-endian order when written to memory.
11609 */
27c868c2
MW
11610static void
11611AscMemWordCopyPtrFromLram(PortAddr iop_base,
11612 ushort s_addr, uchar *d_buffer, int words)
1da177e4 11613{
27c868c2
MW
11614 int i;
11615 ushort word;
11616
11617 AscSetChipLramAddr(iop_base, s_addr);
11618 for (i = 0; i < 2 * words; i += 2) {
11619 word = inpw(iop_base + IOP_RAM_DATA);
11620 d_buffer[i] = word & 0xff;
11621 d_buffer[i + 1] = (word >> 8) & 0xff;
11622 }
11623 return;
1da177e4
LT
11624}
11625
27c868c2 11626static ASC_DCNT AscMemSumLramWord(PortAddr iop_base, ushort s_addr, int words)
1da177e4 11627{
27c868c2
MW
11628 ASC_DCNT sum;
11629 int i;
1da177e4 11630
27c868c2
MW
11631 sum = 0L;
11632 for (i = 0; i < words; i++, s_addr += 2) {
11633 sum += AscReadLramWord(iop_base, s_addr);
11634 }
11635 return (sum);
1da177e4
LT
11636}
11637
27c868c2
MW
11638static void
11639AscMemWordSetLram(PortAddr iop_base, ushort s_addr, ushort set_wval, int words)
1da177e4 11640{
27c868c2 11641 int i;
1da177e4 11642
27c868c2
MW
11643 AscSetChipLramAddr(iop_base, s_addr);
11644 for (i = 0; i < words; i++) {
11645 AscSetChipLramData(iop_base, set_wval);
11646 }
11647 return;
1da177e4
LT
11648}
11649
1da177e4
LT
11650/*
11651 * --- Adv Library Functions
11652 */
11653
11654/* a_mcode.h */
11655
11656/* Microcode buffer is kept after initialization for error recovery. */
27c868c2
MW
11657static unsigned char _adv_asc3550_buf[] = {
11658 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0x16, 0x18, 0xe4, 0x00, 0xfc,
11659 0x01, 0x00, 0x48, 0xe4,
11660 0xbe, 0x18, 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00, 0x00, 0xfa, 0xff, 0xff,
11661 0x28, 0x0e, 0x9e, 0xe7,
11662 0xff, 0x00, 0x82, 0xe7, 0x00, 0xea, 0x00, 0xf6, 0x01, 0xe6, 0x09, 0xe7,
11663 0x55, 0xf0, 0x01, 0xf6,
11664 0x01, 0xfa, 0x08, 0x00, 0x03, 0x00, 0x04, 0x00, 0x18, 0xf4, 0x10, 0x00,
11665 0x00, 0xec, 0x85, 0xf0,
11666 0xbc, 0x00, 0xd5, 0xf0, 0x8e, 0x0c, 0x38, 0x54, 0x00, 0xe6, 0x1e, 0xf0,
11667 0x86, 0xf0, 0xb4, 0x00,
11668 0x98, 0x57, 0xd0, 0x01, 0x0c, 0x1c, 0x3e, 0x1c, 0x0c, 0x00, 0xbb, 0x00,
11669 0xaa, 0x18, 0x02, 0x80,
11670 0x32, 0xf0, 0x01, 0xfc, 0x88, 0x0c, 0xc6, 0x12, 0x02, 0x13, 0x18, 0x40,
11671 0x00, 0x57, 0x01, 0xea,
11672 0x3c, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12, 0x3e, 0x57, 0x00, 0x80,
11673 0x03, 0xe6, 0xb6, 0x00,
11674 0xc0, 0x00, 0x01, 0x01, 0x3e, 0x01, 0xda, 0x0f, 0x22, 0x10, 0x08, 0x12,
11675 0x02, 0x4a, 0xb9, 0x54,
11676 0x03, 0x58, 0x1b, 0x80, 0x30, 0xe4, 0x4b, 0xe4, 0x20, 0x00, 0x32, 0x00,
11677 0x3e, 0x00, 0x80, 0x00,
11678 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01,
11679 0x74, 0x01, 0x76, 0x01,
11680 0x78, 0x01, 0x62, 0x0a, 0x92, 0x0c, 0x2c, 0x10, 0x2e, 0x10, 0x06, 0x13,
11681 0x4c, 0x1c, 0xbb, 0x55,
11682 0x3c, 0x56, 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0, 0xb1, 0xf0,
11683 0x03, 0xf7, 0x06, 0xf7,
11684 0x03, 0xfc, 0x0f, 0x00, 0x40, 0x00, 0xbe, 0x00, 0x00, 0x01, 0xb0, 0x08,
11685 0x30, 0x13, 0x64, 0x15,
11686 0x32, 0x1c, 0x38, 0x1c, 0x4e, 0x1c, 0x10, 0x44, 0x02, 0x48, 0x00, 0x4c,
11687 0x04, 0xea, 0x5d, 0xf0,
11688 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00,
11689 0xcc, 0x00, 0x20, 0x01,
11690 0x4e, 0x01, 0x4e, 0x0b, 0x1e, 0x0e, 0x0c, 0x10, 0x0a, 0x12, 0x04, 0x13,
11691 0x40, 0x13, 0x30, 0x1c,
11692 0x00, 0x4e, 0xbd, 0x56, 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0,
11693 0x59, 0xf0, 0xa7, 0xf0,
11694 0xb8, 0xf0, 0x0e, 0xf7, 0x06, 0x00, 0x19, 0x00, 0x33, 0x00, 0x9b, 0x00,
11695 0xa4, 0x00, 0xb5, 0x00,
11696 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, 0xe7, 0x00, 0xde, 0x03, 0x56, 0x0a,
11697 0x14, 0x0e, 0x02, 0x10,
11698 0x04, 0x10, 0x0a, 0x10, 0x36, 0x10, 0x0a, 0x13, 0x12, 0x13, 0x52, 0x13,
11699 0x10, 0x15, 0x14, 0x15,
11700 0xac, 0x16, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x08, 0x44, 0x38, 0x44,
11701 0x91, 0x44, 0x0a, 0x45,
11702 0x48, 0x46, 0x01, 0x48, 0x68, 0x54, 0x83, 0x55, 0xb0, 0x57, 0x01, 0x58,
11703 0x83, 0x59, 0x05, 0xe6,
11704 0x0b, 0xf0, 0x0c, 0xf0, 0x5c, 0xf0, 0x4b, 0xf4, 0x04, 0xf8, 0x05, 0xf8,
11705 0x02, 0xfa, 0x03, 0xfa,
11706 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x1c, 0x00,
11707 0x9e, 0x00, 0xa8, 0x00,
11708 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00, 0x22, 0x01, 0x26, 0x01, 0x79, 0x01,
11709 0x7a, 0x01, 0xc0, 0x01,
11710 0xc2, 0x01, 0x7c, 0x02, 0x5a, 0x03, 0xea, 0x04, 0xe8, 0x07, 0x68, 0x08,
11711 0x69, 0x08, 0xba, 0x08,
11712 0xe9, 0x09, 0x06, 0x0b, 0x3a, 0x0e, 0x00, 0x10, 0x1a, 0x10, 0xed, 0x10,
11713 0xf1, 0x10, 0x06, 0x12,
11714 0x0c, 0x13, 0x16, 0x13, 0x1e, 0x13, 0x82, 0x13, 0x42, 0x14, 0xd6, 0x14,
11715 0x8a, 0x15, 0xc6, 0x17,
11716 0xd2, 0x17, 0x6b, 0x18, 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40,
11717 0x0e, 0x47, 0x48, 0x47,
11718 0x41, 0x48, 0x89, 0x48, 0x80, 0x4c, 0x00, 0x54, 0x44, 0x55, 0xe5, 0x55,
11719 0x14, 0x56, 0x77, 0x57,
11720 0xbf, 0x57, 0x40, 0x5c, 0x06, 0x80, 0x08, 0x90, 0x03, 0xa1, 0xfe, 0x9c,
11721 0xf0, 0x29, 0x02, 0xfe,
11722 0xb8, 0x0c, 0xff, 0x10, 0x00, 0x00, 0xd0, 0xfe, 0xcc, 0x18, 0x00, 0xcf,
11723 0xfe, 0x80, 0x01, 0xff,
11724 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
11725 0x00, 0xfe, 0x57, 0x24,
11726 0x00, 0xfe, 0x48, 0x00, 0x4f, 0xff, 0x04, 0x00, 0x00, 0x10, 0xff, 0x09,
11727 0x00, 0x00, 0xff, 0x08,
11728 0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10,
11729 0xff, 0xff, 0xff, 0x0f,
11730 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
11731 0xfe, 0x04, 0xf7, 0xcf,
11732 0x2a, 0x67, 0x0b, 0x01, 0xfe, 0xce, 0x0e, 0xfe, 0x04, 0xf7, 0xcf, 0x67,
11733 0x0b, 0x3c, 0x2a, 0xfe,
11734 0x3d, 0xf0, 0xfe, 0x02, 0x02, 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x91, 0xf0,
11735 0xfe, 0xf0, 0x01, 0xfe,
11736 0x90, 0xf0, 0xfe, 0xf0, 0x01, 0xfe, 0x8f, 0xf0, 0x9c, 0x05, 0x51, 0x3b,
11737 0x02, 0xfe, 0xd4, 0x0c,
11738 0x01, 0xfe, 0x44, 0x0d, 0xfe, 0xdd, 0x12, 0xfe, 0xfc, 0x10, 0xfe, 0x28,
11739 0x1c, 0x05, 0xfe, 0xa6,
11740 0x00, 0xfe, 0xd3, 0x12, 0x47, 0x18, 0xfe, 0xa6, 0x00, 0xb5, 0xfe, 0x48,
11741 0xf0, 0xfe, 0x86, 0x02,
11742 0xfe, 0x49, 0xf0, 0xfe, 0xa0, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xbe, 0x02,
11743 0xfe, 0x46, 0xf0, 0xfe,
11744 0x50, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x56, 0x02, 0xfe, 0x43, 0xf0, 0xfe,
11745 0x44, 0x02, 0xfe, 0x44,
11746 0xf0, 0xfe, 0x48, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x4c, 0x02, 0x17, 0x0b,
11747 0xa0, 0x17, 0x06, 0x18,
11748 0x96, 0x02, 0x29, 0xfe, 0x00, 0x1c, 0xde, 0xfe, 0x02, 0x1c, 0xdd, 0xfe,
11749 0x1e, 0x1c, 0xfe, 0xe9,
11750 0x10, 0x01, 0xfe, 0x20, 0x17, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc, 0xc7,
11751 0x0a, 0x6b, 0x01, 0x9e,
11752 0x02, 0x29, 0x14, 0x4d, 0x37, 0x97, 0x01, 0xfe, 0x64, 0x0f, 0x0a, 0x6b,
11753 0x01, 0x82, 0xfe, 0xbd,
11754 0x10, 0x0a, 0x6b, 0x01, 0x82, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe,
11755 0x58, 0x1c, 0x17, 0x06,
11756 0x18, 0x96, 0x2a, 0x25, 0x29, 0xfe, 0x3d, 0xf0, 0xfe, 0x02, 0x02, 0x21,
11757 0xfe, 0x94, 0x02, 0xfe,
11758 0x5a, 0x1c, 0xea, 0xfe, 0x14, 0x1c, 0x14, 0xfe, 0x30, 0x00, 0x37, 0x97,
11759 0x01, 0xfe, 0x54, 0x0f,
11760 0x17, 0x06, 0x18, 0x96, 0x02, 0xd0, 0x1e, 0x20, 0x07, 0x10, 0x34, 0xfe,
11761 0x69, 0x10, 0x17, 0x06,
11762 0x18, 0x96, 0xfe, 0x04, 0xec, 0x20, 0x46, 0x3d, 0x12, 0x20, 0xfe, 0x05,
11763 0xf6, 0xc7, 0x01, 0xfe,
11764 0x52, 0x16, 0x09, 0x4a, 0x4c, 0x35, 0x11, 0x2d, 0x3c, 0x8a, 0x01, 0xe6,
11765 0x02, 0x29, 0x0a, 0x40,
11766 0x01, 0x0e, 0x07, 0x00, 0x5d, 0x01, 0x6f, 0xfe, 0x18, 0x10, 0xfe, 0x41,
11767 0x58, 0x0a, 0x99, 0x01,
11768 0x0e, 0xfe, 0xc8, 0x54, 0x64, 0xfe, 0x0c, 0x03, 0x01, 0xe6, 0x02, 0x29,
11769 0x2a, 0x46, 0xfe, 0x02,
11770 0xe8, 0x27, 0xf8, 0xfe, 0x9e, 0x43, 0xf7, 0xfe, 0x27, 0xf0, 0xfe, 0xdc,
11771 0x01, 0xfe, 0x07, 0x4b,
11772 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x40, 0x1c, 0x25, 0xd2, 0xfe, 0x26, 0xf0,
11773 0xfe, 0x56, 0x03, 0xfe,
11774 0xa0, 0xf0, 0xfe, 0x44, 0x03, 0xfe, 0x11, 0xf0, 0x9c, 0xfe, 0xef, 0x10,
11775 0xfe, 0x9f, 0xf0, 0xfe,
11776 0x64, 0x03, 0xeb, 0x0f, 0xfe, 0x11, 0x00, 0x02, 0x5a, 0x2a, 0xfe, 0x48,
11777 0x1c, 0xeb, 0x09, 0x04,
11778 0x1d, 0xfe, 0x18, 0x13, 0x23, 0x1e, 0x98, 0xac, 0x12, 0x98, 0x0a, 0x40,
11779 0x01, 0x0e, 0xac, 0x75,
11780 0x01, 0xfe, 0xbc, 0x15, 0x11, 0xca, 0x25, 0xd2, 0xfe, 0x01, 0xf0, 0xd2,
11781 0xfe, 0x82, 0xf0, 0xfe,
11782 0x92, 0x03, 0xec, 0x11, 0xfe, 0xe4, 0x00, 0x65, 0xfe, 0xa4, 0x03, 0x25,
11783 0x32, 0x1f, 0xfe, 0xb4,
11784 0x03, 0x01, 0x43, 0xfe, 0x06, 0xf0, 0xfe, 0xc4, 0x03, 0x8d, 0x81, 0xfe,
11785 0x0a, 0xf0, 0xfe, 0x7a,
11786 0x06, 0x02, 0x22, 0x05, 0x6b, 0x28, 0x16, 0xfe, 0xf6, 0x04, 0x14, 0x2c,
11787 0x01, 0x33, 0x8f, 0xfe,
11788 0x66, 0x02, 0x02, 0xd1, 0xeb, 0x2a, 0x67, 0x1a, 0xfe, 0x67, 0x1b, 0xf8,
11789 0xf7, 0xfe, 0x48, 0x1c,
11790 0x70, 0x01, 0x6e, 0x87, 0x0a, 0x40, 0x01, 0x0e, 0x07, 0x00, 0x16, 0xd3,
11791 0x0a, 0xca, 0x01, 0x0e,
11792 0x74, 0x60, 0x59, 0x76, 0x27, 0x05, 0x6b, 0x28, 0xfe, 0x10, 0x12, 0x14,
11793 0x2c, 0x01, 0x33, 0x8f,
11794 0xfe, 0x66, 0x02, 0x02, 0xd1, 0xbc, 0x7d, 0xbd, 0x7f, 0x25, 0x22, 0x65,
11795 0xfe, 0x3c, 0x04, 0x1f,
11796 0xfe, 0x38, 0x04, 0x68, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e,
11797 0x12, 0x2b, 0xff, 0x02,
11798 0x00, 0x10, 0x01, 0x08, 0x1f, 0xfe, 0xe0, 0x04, 0x2b, 0x01, 0x08, 0x1f,
11799 0x22, 0x30, 0x2e, 0xd5,
11800 0xfe, 0x4c, 0x44, 0xfe, 0x4c, 0x12, 0x60, 0xfe, 0x44, 0x48, 0x13, 0x2c,
11801 0xfe, 0x4c, 0x54, 0x64,
11802 0xd3, 0x46, 0x76, 0x27, 0xfa, 0xef, 0xfe, 0x62, 0x13, 0x09, 0x04, 0x1d,
11803 0xfe, 0x2a, 0x13, 0x2f,
11804 0x07, 0x7e, 0xa5, 0xfe, 0x20, 0x10, 0x13, 0x2c, 0xfe, 0x4c, 0x54, 0x64,
11805 0xd3, 0xfa, 0xef, 0x86,
11806 0x09, 0x04, 0x1d, 0xfe, 0x08, 0x13, 0x2f, 0x07, 0x7e, 0x6e, 0x09, 0x04,
11807 0x1d, 0xfe, 0x1c, 0x12,
11808 0x14, 0x92, 0x09, 0x04, 0x06, 0x3b, 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe,
11809 0x70, 0x0c, 0x02, 0x22,
11810 0x2b, 0x11, 0xfe, 0xe6, 0x00, 0xfe, 0x1c, 0x90, 0xf9, 0x03, 0x14, 0x92,
11811 0x01, 0x33, 0x02, 0x29,
11812 0xfe, 0x42, 0x5b, 0x67, 0x1a, 0xfe, 0x46, 0x59, 0xf8, 0xf7, 0xfe, 0x87,
11813 0x80, 0xfe, 0x31, 0xe4,
11814 0x4f, 0x09, 0x04, 0x0b, 0xfe, 0x78, 0x13, 0xfe, 0x20, 0x80, 0x07, 0x1a,
11815 0xfe, 0x70, 0x12, 0x49,
11816 0x04, 0x06, 0xfe, 0x60, 0x13, 0x05, 0xfe, 0xa2, 0x00, 0x28, 0x16, 0xfe,
11817 0x80, 0x05, 0xfe, 0x31,
11818 0xe4, 0x6a, 0x49, 0x04, 0x0b, 0xfe, 0x4a, 0x13, 0x05, 0xfe, 0xa0, 0x00,
11819 0x28, 0xfe, 0x42, 0x12,
11820 0x5e, 0x01, 0x08, 0x25, 0x32, 0xf1, 0x01, 0x08, 0x26, 0xfe, 0x98, 0x05,
11821 0x11, 0xfe, 0xe3, 0x00,
11822 0x23, 0x49, 0xfe, 0x4a, 0xf0, 0xfe, 0x6a, 0x05, 0xfe, 0x49, 0xf0, 0xfe,
11823 0x64, 0x05, 0x83, 0x24,
11824 0xfe, 0x21, 0x00, 0xa1, 0x24, 0xfe, 0x22, 0x00, 0xa0, 0x24, 0x4c, 0xfe,
11825 0x09, 0x48, 0x01, 0x08,
11826 0x26, 0xfe, 0x98, 0x05, 0xfe, 0xe2, 0x08, 0x49, 0x04, 0xc5, 0x3b, 0x01,
11827 0x86, 0x24, 0x06, 0x12,
11828 0xcc, 0x37, 0xfe, 0x27, 0x01, 0x09, 0x04, 0x1d, 0xfe, 0x22, 0x12, 0x47,
11829 0x01, 0xa7, 0x14, 0x92,
11830 0x09, 0x04, 0x06, 0x3b, 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe, 0x70, 0x0c,
11831 0x02, 0x22, 0x05, 0xfe,
11832 0x9c, 0x00, 0x28, 0xfe, 0x3e, 0x12, 0x05, 0x50, 0x28, 0xfe, 0x36, 0x13,
11833 0x47, 0x01, 0xa7, 0x26,
11834 0xfe, 0x08, 0x06, 0x0a, 0x06, 0x49, 0x04, 0x19, 0xfe, 0x02, 0x12, 0x5f,
11835 0x01, 0xfe, 0xaa, 0x14,
11836 0x1f, 0xfe, 0xfe, 0x05, 0x11, 0x9a, 0x01, 0x43, 0x11, 0xfe, 0xe5, 0x00,
11837 0x05, 0x50, 0xb4, 0x0c,
11838 0x50, 0x05, 0xc6, 0x28, 0xfe, 0x62, 0x12, 0x05, 0x3f, 0x28, 0xfe, 0x5a,
11839 0x13, 0x01, 0xfe, 0x14,
11840 0x18, 0x01, 0xfe, 0x66, 0x18, 0xfe, 0x43, 0x48, 0xb7, 0x19, 0x13, 0x6c,
11841 0xff, 0x02, 0x00, 0x57,
11842 0x48, 0x8b, 0x1c, 0x3d, 0x85, 0xb7, 0x69, 0x47, 0x01, 0xa7, 0x26, 0xfe,
11843 0x72, 0x06, 0x49, 0x04,
11844 0x1b, 0xdf, 0x89, 0x0a, 0x4d, 0x01, 0xfe, 0xd8, 0x14, 0x1f, 0xfe, 0x68,
11845 0x06, 0x11, 0x9a, 0x01,
11846 0x43, 0x11, 0xfe, 0xe5, 0x00, 0x05, 0x3f, 0xb4, 0x0c, 0x3f, 0x17, 0x06,
11847 0x01, 0xa7, 0xec, 0x72,
11848 0x70, 0x01, 0x6e, 0x87, 0x11, 0xfe, 0xe2, 0x00, 0x01, 0x08, 0x25, 0x32,
11849 0xfe, 0x0a, 0xf0, 0xfe,
11850 0xa6, 0x06, 0x8c, 0xfe, 0x5c, 0x07, 0xfe, 0x06, 0xf0, 0xfe, 0x64, 0x07,
11851 0x8d, 0x81, 0x02, 0x22,
11852 0x09, 0x04, 0x0b, 0xfe, 0x2e, 0x12, 0x15, 0x1a, 0x01, 0x08, 0x15, 0x00,
11853 0x01, 0x08, 0x15, 0x00,
11854 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0xfe, 0x99, 0xa4, 0x01, 0x08, 0x15,
11855 0x00, 0x02, 0xfe, 0x32,
11856 0x08, 0x61, 0x04, 0x1b, 0xfe, 0x38, 0x12, 0x09, 0x04, 0x1b, 0x6e, 0x15,
11857 0xfe, 0x1b, 0x00, 0x01,
11858 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01,
11859 0x08, 0x15, 0x06, 0x01,
11860 0x08, 0x15, 0x00, 0x02, 0xd9, 0x66, 0x4c, 0xfe, 0x3a, 0x55, 0x5f, 0xfe,
11861 0x9a, 0x81, 0x4b, 0x1d,
11862 0xba, 0xfe, 0x32, 0x07, 0x0a, 0x1d, 0xfe, 0x09, 0x6f, 0xaf, 0xfe, 0xca,
11863 0x45, 0xfe, 0x32, 0x12,
11864 0x62, 0x2c, 0x85, 0x66, 0x7b, 0x01, 0x08, 0x25, 0x32, 0xfe, 0x0a, 0xf0,
11865 0xfe, 0x32, 0x07, 0x8d,
11866 0x81, 0x8c, 0xfe, 0x5c, 0x07, 0x02, 0x22, 0x01, 0x43, 0x02, 0xfe, 0x8a,
11867 0x06, 0x15, 0x19, 0x02,
11868 0xfe, 0x8a, 0x06, 0xfe, 0x9c, 0xf7, 0xd4, 0xfe, 0x2c, 0x90, 0xfe, 0xae,
11869 0x90, 0x77, 0xfe, 0xca,
11870 0x07, 0x0c, 0x54, 0x18, 0x55, 0x09, 0x4a, 0x6a, 0x35, 0x1e, 0x20, 0x07,
11871 0x10, 0xfe, 0x0e, 0x12,
11872 0x74, 0xfe, 0x80, 0x80, 0x37, 0x20, 0x63, 0x27, 0xfe, 0x06, 0x10, 0xfe,
11873 0x83, 0xe7, 0xc4, 0xa1,
11874 0xfe, 0x03, 0x40, 0x09, 0x4a, 0x4f, 0x35, 0x01, 0xa8, 0xad, 0xfe, 0x1f,
11875 0x40, 0x12, 0x58, 0x01,
11876 0xa5, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51, 0xfe, 0xc6,
11877 0x51, 0x83, 0xfb, 0xfe,
11878 0x8a, 0x90, 0x0c, 0x52, 0x18, 0x53, 0xfe, 0x0c, 0x90, 0xfe, 0x8e, 0x90,
11879 0xfe, 0x40, 0x50, 0xfe,
11880 0xc2, 0x50, 0x0c, 0x39, 0x18, 0x3a, 0xfe, 0x4a, 0x10, 0x09, 0x04, 0x6a,
11881 0xfe, 0x2a, 0x12, 0xfe,
11882 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0c, 0x54, 0x18, 0x55, 0x09, 0x04, 0x4f,
11883 0x85, 0x01, 0xa8, 0xfe,
11884 0x1f, 0x80, 0x12, 0x58, 0xfe, 0x44, 0x90, 0xfe, 0xc6, 0x90, 0x0c, 0x56,
11885 0x18, 0x57, 0xfb, 0xfe,
11886 0x8a, 0x90, 0x0c, 0x52, 0x18, 0x53, 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90,
11887 0x0c, 0x39, 0x18, 0x3a,
11888 0x0c, 0x38, 0x18, 0x4e, 0x09, 0x4a, 0x19, 0x35, 0x2a, 0x13, 0xfe, 0x4e,
11889 0x11, 0x65, 0xfe, 0x48,
11890 0x08, 0xfe, 0x9e, 0xf0, 0xfe, 0x5c, 0x08, 0xb1, 0x16, 0x32, 0x2a, 0x73,
11891 0xdd, 0xb8, 0xfe, 0x80,
11892 0x08, 0xb9, 0xfe, 0x9e, 0x08, 0x8c, 0xfe, 0x74, 0x08, 0xfe, 0x06, 0xf0,
11893 0xfe, 0x7a, 0x08, 0x8d,
11894 0x81, 0x02, 0x22, 0x01, 0x43, 0xfe, 0xc9, 0x10, 0x15, 0x19, 0xfe, 0xc9,
11895 0x10, 0x61, 0x04, 0x06,
11896 0xfe, 0x10, 0x12, 0x61, 0x04, 0x0b, 0x45, 0x09, 0x04, 0x0b, 0xfe, 0x68,
11897 0x12, 0xfe, 0x2e, 0x1c,
11898 0x02, 0xfe, 0x24, 0x0a, 0x61, 0x04, 0x06, 0x45, 0x61, 0x04, 0x0b, 0xfe,
11899 0x52, 0x12, 0xfe, 0x2c,
11900 0x1c, 0xfe, 0xaa, 0xf0, 0xfe, 0x1e, 0x09, 0xfe, 0xac, 0xf0, 0xfe, 0xbe,
11901 0x08, 0xfe, 0x8a, 0x10,
11902 0xaa, 0xfe, 0xf3, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0xca, 0x08, 0x02, 0xfe,
11903 0x24, 0x0a, 0xab, 0xfe,
11904 0xe7, 0x10, 0xfe, 0x2b, 0xf0, 0x9d, 0xe9, 0x1c, 0xfe, 0x00, 0xfe, 0xfe,
11905 0x1c, 0x12, 0xb5, 0xfe,
11906 0xd2, 0xf0, 0x9d, 0xfe, 0x76, 0x18, 0x1c, 0x1a, 0x16, 0x9d, 0x05, 0xcb,
11907 0x1c, 0x06, 0x16, 0x9d,
11908 0xb8, 0x6d, 0xb9, 0x6d, 0xaa, 0xab, 0xfe, 0xb1, 0x10, 0x70, 0x5e, 0x2b,
11909 0x14, 0x92, 0x01, 0x33,
11910 0x0f, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x5a, 0x0f, 0x7c, 0x02, 0x5a,
11911 0xfe, 0x74, 0x18, 0x1c,
11912 0xfe, 0x00, 0xf8, 0x16, 0x6d, 0x67, 0x1b, 0x01, 0xfe, 0x44, 0x0d, 0x3b,
11913 0x01, 0xe6, 0x1e, 0x27,
11914 0x74, 0x67, 0x1a, 0x02, 0x6d, 0x09, 0x04, 0x0b, 0x21, 0xfe, 0x06, 0x0a,
11915 0x09, 0x04, 0x6a, 0xfe,
11916 0x82, 0x12, 0x09, 0x04, 0x19, 0xfe, 0x66, 0x13, 0x1e, 0x58, 0xac, 0xfc,
11917 0xfe, 0x83, 0x80, 0xfe,
11918 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91, 0xfe, 0x86, 0x91, 0x63,
11919 0x27, 0xfe, 0x40, 0x59,
11920 0xfe, 0xc1, 0x59, 0x77, 0xd7, 0x05, 0x54, 0x31, 0x55, 0x0c, 0x7b, 0x18,
11921 0x7c, 0xbe, 0x54, 0xbf,
11922 0x55, 0x01, 0xa8, 0xad, 0x63, 0x27, 0x12, 0x58, 0xc0, 0x38, 0xc1, 0x4e,
11923 0x79, 0x56, 0x68, 0x57,
11924 0xf4, 0xf5, 0xfe, 0x04, 0xfa, 0x38, 0xfe, 0x05, 0xfa, 0x4e, 0x01, 0xa5,
11925 0xa2, 0x23, 0x0c, 0x7b,
11926 0x0c, 0x7c, 0x79, 0x56, 0x68, 0x57, 0xfe, 0x12, 0x10, 0x09, 0x04, 0x19,
11927 0x16, 0xd7, 0x79, 0x39,
11928 0x68, 0x3a, 0x09, 0x04, 0xfe, 0xf7, 0x00, 0x35, 0x05, 0x52, 0x31, 0x53,
11929 0xfe, 0x10, 0x58, 0xfe,
11930 0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x02, 0x6d, 0x09, 0x04,
11931 0x19, 0x16, 0xd7, 0x09,
11932 0x04, 0xfe, 0xf7, 0x00, 0x35, 0xfe, 0x3a, 0x55, 0xfe, 0x19, 0x81, 0x5f,
11933 0xfe, 0x10, 0x90, 0xfe,
11934 0x92, 0x90, 0xfe, 0xd7, 0x10, 0x2f, 0x07, 0x9b, 0x16, 0xfe, 0xc6, 0x08,
11935 0x11, 0x9b, 0x09, 0x04,
11936 0x0b, 0xfe, 0x14, 0x13, 0x05, 0x39, 0x31, 0x3a, 0x77, 0xfe, 0xc6, 0x08,
11937 0xfe, 0x0c, 0x58, 0xfe,
11938 0x8d, 0x58, 0x02, 0x6d, 0x23, 0x47, 0xfe, 0x19, 0x80, 0xde, 0x09, 0x04,
11939 0x0b, 0xfe, 0x1a, 0x12,
11940 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, 0xe9, 0xb5, 0xfe, 0xd1, 0xf0, 0xd9,
11941 0x14, 0x7a, 0x01, 0x33,
11942 0x0f, 0xfe, 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe, 0x6c, 0x19, 0xbe, 0x39,
11943 0xfe, 0xed, 0x19, 0xbf,
11944 0x3a, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xe9, 0x1c, 0xfe, 0x00, 0xff,
11945 0x34, 0xfe, 0x74, 0x10,
11946 0xb5, 0xfe, 0xd2, 0xf0, 0xfe, 0xb2, 0x0a, 0xfe, 0x76, 0x18, 0x1c, 0x1a,
11947 0x84, 0x05, 0xcb, 0x1c,
11948 0x06, 0xfe, 0x08, 0x13, 0x0f, 0xfe, 0x16, 0x00, 0x02, 0x5a, 0xfe, 0xd1,
11949 0xf0, 0xfe, 0xc4, 0x0a,
11950 0x14, 0x7a, 0x01, 0x33, 0x0f, 0xfe, 0x17, 0x00, 0xfe, 0x42, 0x10, 0xfe,
11951 0xce, 0xf0, 0xfe, 0xca,
11952 0x0a, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xd6, 0x0a, 0x0f, 0xfe,
11953 0x22, 0x00, 0x02, 0x5a,
11954 0xfe, 0xcb, 0xf0, 0xfe, 0xe2, 0x0a, 0x0f, 0xfe, 0x24, 0x00, 0x02, 0x5a,
11955 0xfe, 0xd0, 0xf0, 0xfe,
11956 0xec, 0x0a, 0x0f, 0x93, 0xdc, 0xfe, 0xcf, 0xf0, 0xfe, 0xf6, 0x0a, 0x0f,
11957 0x4c, 0xfe, 0x10, 0x10,
11958 0xfe, 0xcc, 0xf0, 0xd9, 0x61, 0x04, 0x19, 0x3b, 0x0f, 0xfe, 0x12, 0x00,
11959 0x2a, 0x13, 0xfe, 0x4e,
11960 0x11, 0x65, 0xfe, 0x0c, 0x0b, 0xfe, 0x9e, 0xf0, 0xfe, 0x20, 0x0b, 0xb1,
11961 0x16, 0x32, 0x2a, 0x73,
11962 0xdd, 0xb8, 0x22, 0xb9, 0x22, 0x2a, 0xec, 0x65, 0xfe, 0x2c, 0x0b, 0x25,
11963 0x32, 0x8c, 0xfe, 0x48,
11964 0x0b, 0x8d, 0x81, 0xb8, 0xd4, 0xb9, 0xd4, 0x02, 0x22, 0x01, 0x43, 0xfe,
11965 0xdb, 0x10, 0x11, 0xfe,
11966 0xe8, 0x00, 0xaa, 0xab, 0x70, 0xbc, 0x7d, 0xbd, 0x7f, 0xfe, 0x89, 0xf0,
11967 0x22, 0x30, 0x2e, 0xd8,
11968 0xbc, 0x7d, 0xbd, 0x7f, 0x01, 0x08, 0x1f, 0x22, 0x30, 0x2e, 0xd6, 0xb1,
11969 0x45, 0x0f, 0xfe, 0x42,
11970 0x00, 0x02, 0x5a, 0x78, 0x06, 0xfe, 0x81, 0x49, 0x16, 0xfe, 0x38, 0x0c,
11971 0x09, 0x04, 0x0b, 0xfe,
11972 0x44, 0x13, 0x0f, 0x00, 0x4b, 0x0b, 0xfe, 0x54, 0x12, 0x4b, 0xfe, 0x28,
11973 0x00, 0x21, 0xfe, 0xa6,
11974 0x0c, 0x0a, 0x40, 0x01, 0x0e, 0x07, 0x00, 0x5d, 0x3e, 0xfe, 0x28, 0x00,
11975 0xfe, 0xe2, 0x10, 0x01,
11976 0xe7, 0x01, 0xe8, 0x0a, 0x99, 0x01, 0xfe, 0x32, 0x0e, 0x59, 0x11, 0x2d,
11977 0x01, 0x6f, 0x02, 0x29,
11978 0x0f, 0xfe, 0x44, 0x00, 0x4b, 0x0b, 0xdf, 0x3e, 0x0b, 0xfe, 0xb4, 0x10,
11979 0x01, 0x86, 0x3e, 0x0b,
11980 0xfe, 0xaa, 0x10, 0x01, 0x86, 0xfe, 0x19, 0x82, 0xfe, 0x34, 0x46, 0xa3,
11981 0x3e, 0x0b, 0x0f, 0xfe,
11982 0x43, 0x00, 0xfe, 0x96, 0x10, 0x09, 0x4a, 0x0b, 0x35, 0x01, 0xe7, 0x01,
11983 0xe8, 0x59, 0x11, 0x2d,
11984 0x01, 0x6f, 0x67, 0x0b, 0x59, 0x3c, 0x8a, 0x02, 0xfe, 0x2a, 0x03, 0x09,
11985 0x04, 0x0b, 0x84, 0x3e,
11986 0x0b, 0x0f, 0x00, 0xfe, 0x5c, 0x10, 0x61, 0x04, 0x1b, 0xfe, 0x58, 0x12,
11987 0x09, 0x04, 0x1b, 0xfe,
11988 0x50, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x5c, 0x0c, 0xfe,
11989 0x1c, 0x1c, 0xfe, 0x9d,
11990 0xf0, 0xfe, 0x62, 0x0c, 0x09, 0x4a, 0x1b, 0x35, 0xfe, 0xa9, 0x10, 0x0f,
11991 0xfe, 0x15, 0x00, 0xfe,
11992 0x04, 0xe6, 0x0b, 0x5f, 0x5c, 0x0f, 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10,
11993 0x0f, 0xfe, 0x47, 0x00,
11994 0xa1, 0x0f, 0xfe, 0x41, 0x00, 0xa0, 0x0f, 0xfe, 0x24, 0x00, 0x87, 0xaa,
11995 0xab, 0x70, 0x05, 0x6b,
11996 0x28, 0x21, 0xd1, 0x5f, 0xfe, 0x04, 0xe6, 0x1b, 0xfe, 0x9d, 0x41, 0xfe,
11997 0x1c, 0x42, 0x59, 0x01,
11998 0xda, 0x02, 0x29, 0xea, 0x14, 0x0b, 0x37, 0x95, 0xa9, 0x14, 0xfe, 0x31,
11999 0x00, 0x37, 0x97, 0x01,
12000 0xfe, 0x54, 0x0f, 0x02, 0xd0, 0x3c, 0xfe, 0x06, 0xec, 0xc9, 0xee, 0x3e,
12001 0x1d, 0xfe, 0xce, 0x45,
12002 0x34, 0x3c, 0xfe, 0x06, 0xea, 0xc9, 0xfe, 0x47, 0x4b, 0x89, 0xfe, 0x75,
12003 0x57, 0x05, 0x51, 0xfe,
12004 0x98, 0x56, 0xfe, 0x38, 0x12, 0x0a, 0x42, 0x01, 0x0e, 0xfe, 0x44, 0x48,
12005 0x46, 0x09, 0x04, 0x1d,
12006 0xfe, 0x1a, 0x13, 0x0a, 0x40, 0x01, 0x0e, 0x47, 0xfe, 0x41, 0x58, 0x0a,
12007 0x99, 0x01, 0x0e, 0xfe,
12008 0x49, 0x54, 0x8e, 0xfe, 0x2a, 0x0d, 0x02, 0xfe, 0x2a, 0x03, 0x0a, 0x51,
12009 0xfe, 0xee, 0x14, 0xee,
12010 0x3e, 0x1d, 0xfe, 0xce, 0x45, 0x34, 0x3c, 0xfe, 0xce, 0x47, 0xfe, 0xad,
12011 0x13, 0x02, 0x29, 0x1e,
12012 0x20, 0x07, 0x10, 0xfe, 0x9e, 0x12, 0x23, 0x12, 0x4d, 0x12, 0x94, 0x12,
12013 0xce, 0x1e, 0x2d, 0x47,
12014 0x37, 0x2d, 0xb1, 0xe0, 0xfe, 0xbc, 0xf0, 0xfe, 0xec, 0x0d, 0x13, 0x06,
12015 0x12, 0x4d, 0x01, 0xfe,
12016 0xe2, 0x15, 0x05, 0xfe, 0x38, 0x01, 0x31, 0xfe, 0x3a, 0x01, 0x77, 0xfe,
12017 0xf0, 0x0d, 0xfe, 0x02,
12018 0xec, 0xce, 0x62, 0x00, 0x5d, 0xfe, 0x04, 0xec, 0x20, 0x46, 0xfe, 0x05,
12019 0xf6, 0xfe, 0x34, 0x01,
12020 0x01, 0xfe, 0x52, 0x16, 0xfb, 0xfe, 0x48, 0xf4, 0x0d, 0xfe, 0x18, 0x13,
12021 0xaf, 0xfe, 0x02, 0xea,
12022 0xce, 0x62, 0x7a, 0xfe, 0xc5, 0x13, 0x14, 0x1b, 0x37, 0x95, 0xa9, 0x5c,
12023 0x05, 0xfe, 0x38, 0x01,
12024 0x1c, 0xfe, 0xf0, 0xff, 0x0c, 0xfe, 0x60, 0x01, 0x05, 0xfe, 0x3a, 0x01,
12025 0x0c, 0xfe, 0x62, 0x01,
12026 0x3d, 0x12, 0x20, 0x24, 0x06, 0x12, 0x2d, 0x11, 0x2d, 0x8a, 0x13, 0x06,
12027 0x03, 0x23, 0x03, 0x1e,
12028 0x4d, 0xfe, 0xf7, 0x12, 0x1e, 0x94, 0xac, 0x12, 0x94, 0x07, 0x7a, 0xfe,
12029 0x71, 0x13, 0xfe, 0x24,
12030 0x1c, 0x14, 0x1a, 0x37, 0x95, 0xa9, 0xfe, 0xd9, 0x10, 0xb6, 0xfe, 0x03,
12031 0xdc, 0xfe, 0x73, 0x57,
12032 0xfe, 0x80, 0x5d, 0x03, 0xb6, 0xfe, 0x03, 0xdc, 0xfe, 0x5b, 0x57, 0xfe,
12033 0x80, 0x5d, 0x03, 0xfe,
12034 0x03, 0x57, 0xb6, 0x23, 0xfe, 0x00, 0xcc, 0x03, 0xfe, 0x03, 0x57, 0xb6,
12035 0x75, 0x03, 0x09, 0x04,
12036 0x4c, 0xfe, 0x22, 0x13, 0xfe, 0x1c, 0x80, 0x07, 0x06, 0xfe, 0x1a, 0x13,
12037 0xfe, 0x1e, 0x80, 0xe1,
12038 0xfe, 0x1d, 0x80, 0xa4, 0xfe, 0x0c, 0x90, 0xfe, 0x0e, 0x13, 0xfe, 0x0e,
12039 0x90, 0xa3, 0xfe, 0x3c,
12040 0x90, 0xfe, 0x30, 0xf4, 0x0b, 0xfe, 0x3c, 0x50, 0xa0, 0x01, 0xfe, 0x82,
12041 0x16, 0x2f, 0x07, 0x2d,
12042 0xe0, 0x01, 0xfe, 0xbc, 0x15, 0x09, 0x04, 0x1d, 0x45, 0x01, 0xe7, 0x01,
12043 0xe8, 0x11, 0xfe, 0xe9,
12044 0x00, 0x09, 0x04, 0x4c, 0xfe, 0x2c, 0x13, 0x01, 0xfe, 0x14, 0x16, 0xfe,
12045 0x1e, 0x1c, 0xfe, 0x14,
12046 0x90, 0xfe, 0x96, 0x90, 0x0c, 0xfe, 0x64, 0x01, 0x18, 0xfe, 0x66, 0x01,
12047 0x09, 0x04, 0x4f, 0xfe,
12048 0x12, 0x12, 0xfe, 0x03, 0x80, 0x74, 0xfe, 0x01, 0xec, 0x20, 0xfe, 0x80,
12049 0x40, 0x12, 0x20, 0x63,
12050 0x27, 0x11, 0xc8, 0x59, 0x1e, 0x20, 0xed, 0x76, 0x20, 0x03, 0xfe, 0x08,
12051 0x1c, 0x05, 0xfe, 0xac,
12052 0x00, 0xfe, 0x06, 0x58, 0x05, 0xfe, 0xae, 0x00, 0xfe, 0x07, 0x58, 0x05,
12053 0xfe, 0xb0, 0x00, 0xfe,
12054 0x08, 0x58, 0x05, 0xfe, 0xb2, 0x00, 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c,
12055 0x24, 0x69, 0x12, 0xc9,
12056 0x23, 0x0c, 0x50, 0x0c, 0x3f, 0x13, 0x40, 0x48, 0x5f, 0x17, 0x1d, 0xfe,
12057 0x90, 0x4d, 0xfe, 0x91,
12058 0x54, 0x21, 0xfe, 0x08, 0x0f, 0x3e, 0x10, 0x13, 0x42, 0x48, 0x17, 0x4c,
12059 0xfe, 0x90, 0x4d, 0xfe,
12060 0x91, 0x54, 0x21, 0xfe, 0x1e, 0x0f, 0x24, 0x10, 0x12, 0x20, 0x78, 0x2c,
12061 0x46, 0x1e, 0x20, 0xed,
12062 0x76, 0x20, 0x11, 0xc8, 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x32, 0x0f, 0xea,
12063 0x70, 0xfe, 0x14, 0x1c,
12064 0xfe, 0x10, 0x1c, 0xfe, 0x18, 0x1c, 0x03, 0x3c, 0xfe, 0x0c, 0x14, 0xee,
12065 0xfe, 0x07, 0xe6, 0x1d,
12066 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x03, 0x01, 0x86, 0x78, 0x2c, 0x46,
12067 0xfa, 0xef, 0xfe, 0x42,
12068 0x13, 0x2f, 0x07, 0x2d, 0xfe, 0x34, 0x13, 0x0a, 0x42, 0x01, 0x0e, 0xb0,
12069 0xfe, 0x36, 0x12, 0xf0,
12070 0xfe, 0x45, 0x48, 0x01, 0xe3, 0xfe, 0x00, 0xcc, 0xb0, 0xfe, 0xf3, 0x13,
12071 0x3d, 0x75, 0x07, 0x10,
12072 0xa3, 0x0a, 0x80, 0x01, 0x0e, 0xfe, 0x80, 0x5c, 0x01, 0x6f, 0xfe, 0x0e,
12073 0x10, 0x07, 0x7e, 0x45,
12074 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x6c, 0x0f, 0x03, 0xfe, 0x44, 0x58, 0x74,
12075 0xfe, 0x01, 0xec, 0x97,
12076 0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x1b, 0x76,
12077 0x27, 0x01, 0xda, 0xfe,
12078 0xdd, 0x10, 0x2a, 0xbc, 0x7d, 0xbd, 0x7f, 0x30, 0x2e, 0xd5, 0x07, 0x1b,
12079 0xfe, 0x48, 0x12, 0x07,
12080 0x0b, 0xfe, 0x56, 0x12, 0x07, 0x1a, 0xfe, 0x30, 0x12, 0x07, 0xc2, 0x16,
12081 0xfe, 0x3e, 0x11, 0x07,
12082 0xfe, 0x23, 0x00, 0x16, 0xfe, 0x4a, 0x11, 0x07, 0x06, 0x16, 0xfe, 0xa8,
12083 0x11, 0x07, 0x19, 0xfe,
12084 0x12, 0x12, 0x07, 0x00, 0x16, 0x22, 0x14, 0xc2, 0x01, 0x33, 0x9f, 0x2b,
12085 0x01, 0x08, 0x8c, 0x43,
12086 0x03, 0x2b, 0xfe, 0x62, 0x08, 0x0a, 0xca, 0x01, 0xfe, 0x32, 0x0e, 0x11,
12087 0x7e, 0x02, 0x29, 0x2b,
12088 0x2f, 0x07, 0x9b, 0xfe, 0xd9, 0x13, 0x79, 0x39, 0x68, 0x3a, 0x77, 0xfe,
12089 0xfc, 0x10, 0x09, 0x04,
12090 0x6a, 0xfe, 0x72, 0x12, 0xc0, 0x38, 0xc1, 0x4e, 0xf4, 0xf5, 0x8e, 0xfe,
12091 0xc6, 0x10, 0x1e, 0x58,
12092 0xfe, 0x26, 0x13, 0x05, 0x7b, 0x31, 0x7c, 0x77, 0xfe, 0x82, 0x0c, 0x0c,
12093 0x54, 0x18, 0x55, 0x23,
12094 0x0c, 0x7b, 0x0c, 0x7c, 0x01, 0xa8, 0x24, 0x69, 0x73, 0x12, 0x58, 0x01,
12095 0xa5, 0xc0, 0x38, 0xc1,
12096 0x4e, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x38, 0xfe,
12097 0x05, 0xfa, 0x4e, 0xfe,
12098 0x91, 0x10, 0x05, 0x56, 0x31, 0x57, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56,
12099 0x0c, 0x56, 0x18, 0x57,
12100 0x83, 0xc0, 0x38, 0xc1, 0x4e, 0xf4, 0xf5, 0x05, 0x52, 0x31, 0x53, 0xfe,
12101 0x00, 0x56, 0xfe, 0xa1,
12102 0x56, 0x0c, 0x52, 0x18, 0x53, 0x09, 0x04, 0x6a, 0xfe, 0x1e, 0x12, 0x1e,
12103 0x58, 0xfe, 0x1f, 0x40,
12104 0x05, 0x54, 0x31, 0x55, 0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x05, 0x56,
12105 0x31, 0x57, 0xfe, 0x44,
12106 0x50, 0xfe, 0xc6, 0x50, 0x05, 0x52, 0x31, 0x53, 0xfe, 0x08, 0x50, 0xfe,
12107 0x8a, 0x50, 0x05, 0x39,
12108 0x31, 0x3a, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x02, 0x5c, 0x24, 0x06,
12109 0x12, 0xcd, 0x02, 0x5b,
12110 0x2b, 0x01, 0x08, 0x1f, 0x44, 0x30, 0x2e, 0xd5, 0x07, 0x06, 0x21, 0x44,
12111 0x2f, 0x07, 0x9b, 0x21,
12112 0x5b, 0x01, 0x6e, 0x1c, 0x3d, 0x16, 0x44, 0x09, 0x04, 0x0b, 0xe2, 0x79,
12113 0x39, 0x68, 0x3a, 0xfe,
12114 0x0a, 0x55, 0x34, 0xfe, 0x8b, 0x55, 0xbe, 0x39, 0xbf, 0x3a, 0xfe, 0x0c,
12115 0x51, 0xfe, 0x8e, 0x51,
12116 0x02, 0x5b, 0xfe, 0x19, 0x81, 0xaf, 0xfe, 0x19, 0x41, 0x02, 0x5b, 0x2b,
12117 0x01, 0x08, 0x25, 0x32,
12118 0x1f, 0xa2, 0x30, 0x2e, 0xd8, 0x4b, 0x1a, 0xfe, 0xa6, 0x12, 0x4b, 0x0b,
12119 0x3b, 0x02, 0x44, 0x01,
12120 0x08, 0x25, 0x32, 0x1f, 0xa2, 0x30, 0x2e, 0xd6, 0x07, 0x1a, 0x21, 0x44,
12121 0x01, 0x08, 0x1f, 0xa2,
12122 0x30, 0x2e, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, 0x60, 0x05, 0xfe, 0x9c,
12123 0x00, 0x28, 0x84, 0x49,
12124 0x04, 0x19, 0x34, 0x9f, 0xfe, 0xbb, 0x45, 0x4b, 0x00, 0x45, 0x3e, 0x06,
12125 0x78, 0x3d, 0xfe, 0xda,
12126 0x14, 0x01, 0x6e, 0x87, 0xfe, 0x4b, 0x45, 0xe2, 0x2f, 0x07, 0x9a, 0xe1,
12127 0x05, 0xc6, 0x28, 0x84,
12128 0x05, 0x3f, 0x28, 0x34, 0x5e, 0x02, 0x5b, 0xfe, 0xc0, 0x5d, 0xfe, 0xf8,
12129 0x14, 0xfe, 0x03, 0x17,
12130 0x05, 0x50, 0xb4, 0x0c, 0x50, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01,
12131 0xfe, 0xaa, 0x14, 0x02,
12132 0x5c, 0x01, 0x08, 0x25, 0x32, 0x1f, 0x44, 0x30, 0x2e, 0xd6, 0x07, 0x06,
12133 0x21, 0x44, 0x01, 0xfe,
12134 0x8e, 0x13, 0xfe, 0x42, 0x58, 0xfe, 0x82, 0x14, 0xfe, 0xa4, 0x14, 0x87,
12135 0xfe, 0x4a, 0xf4, 0x0b,
12136 0x16, 0x44, 0xfe, 0x4a, 0xf4, 0x06, 0xfe, 0x0c, 0x12, 0x2f, 0x07, 0x9a,
12137 0x85, 0x02, 0x5b, 0x05,
12138 0x3f, 0xb4, 0x0c, 0x3f, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, 0xfe,
12139 0xd8, 0x14, 0x02, 0x5c,
12140 0x13, 0x06, 0x65, 0xfe, 0xca, 0x12, 0x26, 0xfe, 0xe0, 0x12, 0x72, 0xf1,
12141 0x01, 0x08, 0x23, 0x72,
12142 0x03, 0x8f, 0xfe, 0xdc, 0x12, 0x25, 0xfe, 0xdc, 0x12, 0x1f, 0xfe, 0xca,
12143 0x12, 0x5e, 0x2b, 0x01,
12144 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b,
12145 0x1c, 0xfe, 0xff, 0x7f,
12146 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00,
12147 0x57, 0x48, 0x8b, 0x1c,
12148 0x3d, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x13, 0x6c, 0xff, 0x02,
12149 0x00, 0x57, 0x48, 0x8b,
12150 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0xfe, 0x0b, 0x58,
12151 0x03, 0x0a, 0x50, 0x01,
12152 0x82, 0x0a, 0x3f, 0x01, 0x82, 0x03, 0xfc, 0x1c, 0x10, 0xff, 0x03, 0x00,
12153 0x54, 0xfe, 0x00, 0xf4,
12154 0x19, 0x48, 0xfe, 0x00, 0x7d, 0xfe, 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe,
12155 0x03, 0x7c, 0x63, 0x27,
12156 0x0c, 0x52, 0x18, 0x53, 0xbe, 0x56, 0xbf, 0x57, 0x03, 0xfe, 0x62, 0x08,
12157 0xfe, 0x82, 0x4a, 0xfe,
12158 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x74, 0x03, 0x01, 0xfe, 0x14, 0x18, 0xfe,
12159 0x42, 0x48, 0x5f, 0x60,
12160 0x89, 0x01, 0x08, 0x1f, 0xfe, 0xa2, 0x14, 0x30, 0x2e, 0xd8, 0x01, 0x08,
12161 0x1f, 0xfe, 0xa2, 0x14,
12162 0x30, 0x2e, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x05, 0xc6, 0x28, 0xfe,
12163 0xcc, 0x12, 0x49, 0x04,
12164 0x1b, 0xfe, 0xc4, 0x13, 0x23, 0x62, 0x1b, 0xe2, 0x4b, 0xc3, 0x64, 0xfe,
12165 0xe8, 0x13, 0x3b, 0x13,
12166 0x06, 0x17, 0xc3, 0x78, 0xdb, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55,
12167 0xa1, 0xff, 0x02, 0x83,
12168 0x55, 0x62, 0x1a, 0xa4, 0xbb, 0xfe, 0x30, 0x00, 0x8e, 0xe4, 0x17, 0x2c,
12169 0x13, 0x06, 0xfe, 0x56,
12170 0x10, 0x62, 0x0b, 0xe1, 0xbb, 0xfe, 0x64, 0x00, 0x8e, 0xe4, 0x0a, 0xfe,
12171 0x64, 0x00, 0x17, 0x93,
12172 0x13, 0x06, 0xfe, 0x28, 0x10, 0x62, 0x06, 0xfe, 0x60, 0x13, 0xbb, 0xfe,
12173 0xc8, 0x00, 0x8e, 0xe4,
12174 0x0a, 0xfe, 0xc8, 0x00, 0x17, 0x4d, 0x13, 0x06, 0x83, 0xbb, 0xfe, 0x90,
12175 0x01, 0xba, 0xfe, 0x4e,
12176 0x14, 0x89, 0xfe, 0x12, 0x10, 0xfe, 0x43, 0xf4, 0x94, 0xfe, 0x56, 0xf0,
12177 0xfe, 0x60, 0x14, 0xfe,
12178 0x04, 0xf4, 0x6c, 0xfe, 0x43, 0xf4, 0x93, 0xfe, 0xf3, 0x10, 0xf9, 0x01,
12179 0xfe, 0x22, 0x13, 0x1c,
12180 0x3d, 0xfe, 0x10, 0x13, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x69, 0xba,
12181 0xfe, 0x9c, 0x14, 0xb7,
12182 0x69, 0xfe, 0x1c, 0x10, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x19, 0xba,
12183 0xfe, 0x9c, 0x14, 0xb7,
12184 0x19, 0x83, 0x60, 0x23, 0xfe, 0x4d, 0xf4, 0x00, 0xdf, 0x89, 0x13, 0x06,
12185 0xfe, 0xb4, 0x56, 0xfe,
12186 0xc3, 0x58, 0x03, 0x60, 0x13, 0x0b, 0x03, 0x15, 0x06, 0x01, 0x08, 0x26,
12187 0xe5, 0x15, 0x0b, 0x01,
12188 0x08, 0x26, 0xe5, 0x15, 0x1a, 0x01, 0x08, 0x26, 0xe5, 0x72, 0xfe, 0x89,
12189 0x49, 0x01, 0x08, 0x03,
12190 0x15, 0x06, 0x01, 0x08, 0x26, 0xa6, 0x15, 0x1a, 0x01, 0x08, 0x26, 0xa6,
12191 0x15, 0x06, 0x01, 0x08,
12192 0x26, 0xa6, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x26, 0xa6, 0x72, 0xfe, 0x89,
12193 0x4a, 0x01, 0x08, 0x03,
12194 0x60, 0x03, 0x1e, 0xcc, 0x07, 0x06, 0xfe, 0x44, 0x13, 0xad, 0x12, 0xcc,
12195 0xfe, 0x49, 0xf4, 0x00,
12196 0x3b, 0x72, 0x9f, 0x5e, 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xf1, 0x01,
12197 0x08, 0x2f, 0x07, 0xfe,
12198 0xe3, 0x00, 0xfe, 0x20, 0x13, 0x1f, 0xfe, 0x5a, 0x15, 0x23, 0x12, 0xcd,
12199 0x01, 0x43, 0x1e, 0xcd,
12200 0x07, 0x06, 0x45, 0x09, 0x4a, 0x06, 0x35, 0x03, 0x0a, 0x42, 0x01, 0x0e,
12201 0xed, 0x88, 0x07, 0x10,
12202 0xa4, 0x0a, 0x80, 0x01, 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03, 0x0a,
12203 0x80, 0x01, 0x0e, 0x88,
12204 0xfe, 0x80, 0xe7, 0x10, 0x07, 0x10, 0x84, 0xfe, 0x45, 0x58, 0x01, 0xe3,
12205 0x88, 0x03, 0x0a, 0x42,
12206 0x01, 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03, 0x0a, 0x42, 0x01, 0x0e,
12207 0xfe, 0x80, 0x80, 0xf2,
12208 0xfe, 0x49, 0xe4, 0x10, 0xa4, 0x0a, 0x80, 0x01, 0x0e, 0xf2, 0x0a, 0x51,
12209 0x01, 0x82, 0x03, 0x17,
12210 0x10, 0x71, 0x66, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde,
12211 0xfe, 0x24, 0x1c, 0xfe,
12212 0x1d, 0xf7, 0x1d, 0x90, 0xfe, 0xf6, 0x15, 0x01, 0xfe, 0xfc, 0x16, 0xe0,
12213 0x91, 0x1d, 0x66, 0xfe,
12214 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x03, 0xae, 0x21, 0xfe, 0xe6, 0x15, 0xfe,
12215 0xda, 0x10, 0x17, 0x10,
12216 0x71, 0x05, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x19, 0xfe, 0x18, 0x58,
12217 0x05, 0xfe, 0x66, 0x01,
12218 0xfe, 0x19, 0x58, 0x91, 0x19, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4, 0x06,
12219 0xfe, 0x3c, 0x50, 0x66,
12220 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x19, 0x90, 0xfe,
12221 0x40, 0x16, 0xfe, 0xb6,
12222 0x14, 0x34, 0x03, 0xae, 0x21, 0xfe, 0x18, 0x16, 0xfe, 0x9c, 0x10, 0x17,
12223 0x10, 0x71, 0xfe, 0x83,
12224 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7, 0x38, 0x90,
12225 0xfe, 0x62, 0x16, 0xfe,
12226 0x94, 0x14, 0xfe, 0x10, 0x13, 0x91, 0x38, 0x66, 0x1b, 0xfe, 0xaf, 0x19,
12227 0xfe, 0x98, 0xe7, 0x00,
12228 0x03, 0xae, 0x21, 0xfe, 0x56, 0x16, 0xfe, 0x6c, 0x10, 0x17, 0x10, 0x71,
12229 0xfe, 0x30, 0xbc, 0xfe,
12230 0xb2, 0xbc, 0x91, 0xc5, 0x66, 0x1b, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7,
12231 0xc5, 0x90, 0xfe, 0x9a,
12232 0x16, 0xfe, 0x5c, 0x14, 0x34, 0x03, 0xae, 0x21, 0xfe, 0x86, 0x16, 0xfe,
12233 0x42, 0x10, 0xfe, 0x02,
12234 0xf6, 0x10, 0x71, 0xfe, 0x18, 0xfe, 0x54, 0xfe, 0x19, 0xfe, 0x55, 0xfc,
12235 0xfe, 0x1d, 0xf7, 0x4f,
12236 0x90, 0xfe, 0xc0, 0x16, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13, 0x91, 0x4f,
12237 0x47, 0xfe, 0x83, 0x58,
12238 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x10, 0xfe, 0x81, 0xe7, 0x10, 0x11,
12239 0xfe, 0xdd, 0x00, 0x63,
12240 0x27, 0x03, 0x63, 0x27, 0xfe, 0x12, 0x45, 0x21, 0xfe, 0xb0, 0x16, 0x14,
12241 0x06, 0x37, 0x95, 0xa9,
12242 0x02, 0x29, 0xfe, 0x39, 0xf0, 0xfe, 0x04, 0x17, 0x23, 0x03, 0xfe, 0x7e,
12243 0x18, 0x1c, 0x1a, 0x5d,
12244 0x13, 0x0d, 0x03, 0x71, 0x05, 0xcb, 0x1c, 0x06, 0xfe, 0xef, 0x12, 0xfe,
12245 0xe1, 0x10, 0x78, 0x2c,
12246 0x46, 0x2f, 0x07, 0x2d, 0xfe, 0x3c, 0x13, 0xfe, 0x82, 0x14, 0xfe, 0x42,
12247 0x13, 0x3c, 0x8a, 0x0a,
12248 0x42, 0x01, 0x0e, 0xb0, 0xfe, 0x3e, 0x12, 0xf0, 0xfe, 0x45, 0x48, 0x01,
12249 0xe3, 0xfe, 0x00, 0xcc,
12250 0xb0, 0xfe, 0xf3, 0x13, 0x3d, 0x75, 0x07, 0x10, 0xa3, 0x0a, 0x80, 0x01,
12251 0x0e, 0xf2, 0x01, 0x6f,
12252 0xfe, 0x16, 0x10, 0x07, 0x7e, 0x85, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12,
12253 0xf6, 0xfe, 0xd6, 0xf0,
12254 0xfe, 0x24, 0x17, 0x17, 0x0b, 0x03, 0xfe, 0x9c, 0xe7, 0x0b, 0x0f, 0xfe,
12255 0x15, 0x00, 0x59, 0x76,
12256 0x27, 0x01, 0xda, 0x17, 0x06, 0x03, 0x3c, 0x8a, 0x09, 0x4a, 0x1d, 0x35,
12257 0x11, 0x2d, 0x01, 0x6f,
12258 0x17, 0x06, 0x03, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x79, 0xc7, 0x68,
12259 0xc8, 0xfe, 0x48, 0x55,
12260 0x34, 0xfe, 0xc9, 0x55, 0x03, 0x1e, 0x98, 0x73, 0x12, 0x98, 0x03, 0x0a,
12261 0x99, 0x01, 0x0e, 0xf0,
12262 0x0a, 0x40, 0x01, 0x0e, 0xfe, 0x49, 0x44, 0x16, 0xfe, 0xf0, 0x17, 0x73,
12263 0x75, 0x03, 0x0a, 0x42,
12264 0x01, 0x0e, 0x07, 0x10, 0x45, 0x0a, 0x51, 0x01, 0x9e, 0x0a, 0x40, 0x01,
12265 0x0e, 0x73, 0x75, 0x03,
12266 0xfe, 0x4e, 0xe4, 0x1a, 0x64, 0xfe, 0x24, 0x18, 0x05, 0xfe, 0x90, 0x00,
12267 0xfe, 0x3a, 0x45, 0x5b,
12268 0xfe, 0x4e, 0xe4, 0xc2, 0x64, 0xfe, 0x36, 0x18, 0x05, 0xfe, 0x92, 0x00,
12269 0xfe, 0x02, 0xe6, 0x1b,
12270 0xdc, 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x64, 0xfe, 0x48, 0x18, 0x05,
12271 0xfe, 0x94, 0x00, 0xfe,
12272 0x02, 0xe6, 0x19, 0xfe, 0x08, 0x10, 0x05, 0xfe, 0x96, 0x00, 0xfe, 0x02,
12273 0xe6, 0x2c, 0xfe, 0x4e,
12274 0x45, 0xfe, 0x0c, 0x12, 0xaf, 0xff, 0x04, 0x68, 0x54, 0xde, 0x1c, 0x69,
12275 0x03, 0x07, 0x7a, 0xfe,
12276 0x5a, 0xf0, 0xfe, 0x74, 0x18, 0x24, 0xfe, 0x09, 0x00, 0xfe, 0x34, 0x10,
12277 0x07, 0x1b, 0xfe, 0x5a,
12278 0xf0, 0xfe, 0x82, 0x18, 0x24, 0xc3, 0xfe, 0x26, 0x10, 0x07, 0x1a, 0x5d,
12279 0x24, 0x2c, 0xdc, 0x07,
12280 0x0b, 0x5d, 0x24, 0x93, 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x5d, 0x24, 0x4d,
12281 0x9f, 0xad, 0x03, 0x14,
12282 0xfe, 0x09, 0x00, 0x01, 0x33, 0xfe, 0x04, 0xfe, 0x7d, 0x05, 0x7f, 0xf9,
12283 0x03, 0x25, 0xfe, 0xca,
12284 0x18, 0xfe, 0x14, 0xf0, 0x08, 0x65, 0xfe, 0xc6, 0x18, 0x03, 0xff, 0x1a,
12285 0x00, 0x00,
1da177e4
LT
12286};
12287
27c868c2
MW
12288static unsigned short _adv_asc3550_size = sizeof(_adv_asc3550_buf); /* 0x13AD */
12289static ADV_DCNT _adv_asc3550_chksum = 0x04D52DDDUL; /* Expanded little-endian checksum. */
1da177e4
LT
12290
12291/* Microcode buffer is kept after initialization for error recovery. */
27c868c2
MW
12292static unsigned char _adv_asc38C0800_buf[] = {
12293 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x16, 0x18, 0xe4,
12294 0x01, 0x00, 0x48, 0xe4,
12295 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00, 0xce, 0x19, 0x00, 0xfa, 0xff, 0xff,
12296 0x1c, 0x0f, 0x00, 0xf6,
12297 0x9e, 0xe7, 0xff, 0x00, 0x82, 0xe7, 0x00, 0xea, 0x01, 0xfa, 0x01, 0xe6,
12298 0x09, 0xe7, 0x55, 0xf0,
12299 0x01, 0xf6, 0x03, 0x00, 0x04, 0x00, 0x10, 0x00, 0x1e, 0xf0, 0x85, 0xf0,
12300 0x18, 0xf4, 0x08, 0x00,
12301 0xbc, 0x00, 0x38, 0x54, 0x00, 0xec, 0xd5, 0xf0, 0x82, 0x0d, 0x00, 0xe6,
12302 0x86, 0xf0, 0xb1, 0xf0,
12303 0x98, 0x57, 0x01, 0xfc, 0xb4, 0x00, 0xd4, 0x01, 0x0c, 0x1c, 0x3e, 0x1c,
12304 0x3c, 0x00, 0xbb, 0x00,
12305 0x00, 0x10, 0xba, 0x19, 0x02, 0x80, 0x32, 0xf0, 0x7c, 0x0d, 0x02, 0x13,
12306 0xba, 0x13, 0x18, 0x40,
12307 0x00, 0x57, 0x01, 0xea, 0x02, 0xfc, 0x03, 0xfc, 0x3e, 0x00, 0x6c, 0x01,
12308 0x6e, 0x01, 0x74, 0x01,
12309 0x76, 0x01, 0xb9, 0x54, 0x3e, 0x57, 0x00, 0x80, 0x03, 0xe6, 0xb6, 0x00,
12310 0xc0, 0x00, 0x01, 0x01,
12311 0x3e, 0x01, 0x7a, 0x01, 0xca, 0x08, 0xce, 0x10, 0x16, 0x11, 0x04, 0x12,
12312 0x08, 0x12, 0x02, 0x4a,
12313 0xbb, 0x55, 0x3c, 0x56, 0x03, 0x58, 0x1b, 0x80, 0x30, 0xe4, 0x4b, 0xe4,
12314 0x5d, 0xf0, 0x02, 0xfa,
12315 0x20, 0x00, 0x32, 0x00, 0x40, 0x00, 0x80, 0x00, 0x24, 0x01, 0x3c, 0x01,
12316 0x68, 0x01, 0x6a, 0x01,
12317 0x70, 0x01, 0x72, 0x01, 0x78, 0x01, 0x7c, 0x01, 0x62, 0x0a, 0x86, 0x0d,
12318 0x06, 0x13, 0x4c, 0x1c,
12319 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0, 0x03, 0xf7, 0x0c, 0x00,
12320 0x0f, 0x00, 0x47, 0x00,
12321 0xbe, 0x00, 0x00, 0x01, 0x20, 0x11, 0x5c, 0x16, 0x32, 0x1c, 0x38, 0x1c,
12322 0x4e, 0x1c, 0x10, 0x44,
12323 0x00, 0x4c, 0x04, 0xea, 0x5c, 0xf0, 0xa7, 0xf0, 0x04, 0xf6, 0x03, 0xfa,
12324 0x05, 0x00, 0x34, 0x00,
12325 0x36, 0x00, 0x98, 0x00, 0xcc, 0x00, 0x20, 0x01, 0x4e, 0x01, 0x4a, 0x0b,
12326 0x42, 0x0c, 0x12, 0x0f,
12327 0x0c, 0x10, 0x22, 0x11, 0x0a, 0x12, 0x04, 0x13, 0x30, 0x1c, 0x02, 0x48,
12328 0x00, 0x4e, 0x42, 0x54,
12329 0x44, 0x55, 0xbd, 0x56, 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0,
12330 0x59, 0xf0, 0xb8, 0xf0,
12331 0x4b, 0xf4, 0x06, 0xf7, 0x0e, 0xf7, 0x04, 0xfc, 0x05, 0xfc, 0x06, 0x00,
12332 0x19, 0x00, 0x33, 0x00,
12333 0x9b, 0x00, 0xa4, 0x00, 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00,
12334 0xe7, 0x00, 0xe2, 0x03,
12335 0x08, 0x0f, 0x02, 0x10, 0x04, 0x10, 0x0a, 0x10, 0x0a, 0x13, 0x0c, 0x13,
12336 0x12, 0x13, 0x24, 0x14,
12337 0x34, 0x14, 0x04, 0x16, 0x08, 0x16, 0xa4, 0x17, 0x20, 0x1c, 0x34, 0x1c,
12338 0x36, 0x1c, 0x08, 0x44,
12339 0x38, 0x44, 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46, 0x01, 0x48, 0x68, 0x54,
12340 0x3a, 0x55, 0x83, 0x55,
12341 0xe5, 0x55, 0xb0, 0x57, 0x01, 0x58, 0x83, 0x59, 0x05, 0xe6, 0x0b, 0xf0,
12342 0x0c, 0xf0, 0x04, 0xf8,
12343 0x05, 0xf8, 0x07, 0x00, 0x0a, 0x00, 0x1c, 0x00, 0x1e, 0x00, 0x9e, 0x00,
12344 0xa8, 0x00, 0xaa, 0x00,
12345 0xb9, 0x00, 0xe0, 0x00, 0x22, 0x01, 0x26, 0x01, 0x79, 0x01, 0x7e, 0x01,
12346 0xc4, 0x01, 0xc6, 0x01,
12347 0x80, 0x02, 0x5e, 0x03, 0xee, 0x04, 0x9a, 0x06, 0xf8, 0x07, 0x62, 0x08,
12348 0x68, 0x08, 0x69, 0x08,
12349 0xd6, 0x08, 0xe9, 0x09, 0xfa, 0x0b, 0x2e, 0x0f, 0x12, 0x10, 0x1a, 0x10,
12350 0xed, 0x10, 0xf1, 0x10,
12351 0x2a, 0x11, 0x06, 0x12, 0x0c, 0x12, 0x3e, 0x12, 0x10, 0x13, 0x16, 0x13,
12352 0x1e, 0x13, 0x46, 0x14,
12353 0x76, 0x14, 0x82, 0x14, 0x36, 0x15, 0xca, 0x15, 0x6b, 0x18, 0xbe, 0x18,
12354 0xca, 0x18, 0xe6, 0x19,
12355 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40, 0x0e, 0x47, 0xfe, 0x9c,
12356 0xf0, 0x2b, 0x02, 0xfe,
12357 0xac, 0x0d, 0xff, 0x10, 0x00, 0x00, 0xd7, 0xfe, 0xe8, 0x19, 0x00, 0xd6,
12358 0xfe, 0x84, 0x01, 0xff,
12359 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
12360 0x00, 0xfe, 0x57, 0x24,
12361 0x00, 0xfe, 0x4c, 0x00, 0x5b, 0xff, 0x04, 0x00, 0x00, 0x11, 0xff, 0x09,
12362 0x00, 0x00, 0xff, 0x08,
12363 0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10,
12364 0xff, 0xff, 0xff, 0x11,
12365 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
12366 0xfe, 0x04, 0xf7, 0xd6,
12367 0x2c, 0x99, 0x0a, 0x01, 0xfe, 0xc2, 0x0f, 0xfe, 0x04, 0xf7, 0xd6, 0x99,
12368 0x0a, 0x42, 0x2c, 0xfe,
12369 0x3d, 0xf0, 0xfe, 0x06, 0x02, 0xfe, 0x20, 0xf0, 0xa7, 0xfe, 0x91, 0xf0,
12370 0xfe, 0xf4, 0x01, 0xfe,
12371 0x90, 0xf0, 0xfe, 0xf4, 0x01, 0xfe, 0x8f, 0xf0, 0xa7, 0x03, 0x5d, 0x4d,
12372 0x02, 0xfe, 0xc8, 0x0d,
12373 0x01, 0xfe, 0x38, 0x0e, 0xfe, 0xdd, 0x12, 0xfe, 0xfc, 0x10, 0xfe, 0x28,
12374 0x1c, 0x03, 0xfe, 0xa6,
12375 0x00, 0xfe, 0xd3, 0x12, 0x41, 0x14, 0xfe, 0xa6, 0x00, 0xc2, 0xfe, 0x48,
12376 0xf0, 0xfe, 0x8a, 0x02,
12377 0xfe, 0x49, 0xf0, 0xfe, 0xa4, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc2, 0x02,
12378 0xfe, 0x46, 0xf0, 0xfe,
12379 0x54, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x5a, 0x02, 0xfe, 0x43, 0xf0, 0xfe,
12380 0x48, 0x02, 0xfe, 0x44,
12381 0xf0, 0xfe, 0x4c, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x50, 0x02, 0x18, 0x0a,
12382 0xaa, 0x18, 0x06, 0x14,
12383 0xa1, 0x02, 0x2b, 0xfe, 0x00, 0x1c, 0xe7, 0xfe, 0x02, 0x1c, 0xe6, 0xfe,
12384 0x1e, 0x1c, 0xfe, 0xe9,
12385 0x10, 0x01, 0xfe, 0x18, 0x18, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc, 0xce,
12386 0x09, 0x70, 0x01, 0xa8,
12387 0x02, 0x2b, 0x15, 0x59, 0x39, 0xa2, 0x01, 0xfe, 0x58, 0x10, 0x09, 0x70,
12388 0x01, 0x87, 0xfe, 0xbd,
12389 0x10, 0x09, 0x70, 0x01, 0x87, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe,
12390 0x58, 0x1c, 0x18, 0x06,
12391 0x14, 0xa1, 0x2c, 0x1c, 0x2b, 0xfe, 0x3d, 0xf0, 0xfe, 0x06, 0x02, 0x23,
12392 0xfe, 0x98, 0x02, 0xfe,
12393 0x5a, 0x1c, 0xf8, 0xfe, 0x14, 0x1c, 0x15, 0xfe, 0x30, 0x00, 0x39, 0xa2,
12394 0x01, 0xfe, 0x48, 0x10,
12395 0x18, 0x06, 0x14, 0xa1, 0x02, 0xd7, 0x22, 0x20, 0x07, 0x11, 0x35, 0xfe,
12396 0x69, 0x10, 0x18, 0x06,
12397 0x14, 0xa1, 0xfe, 0x04, 0xec, 0x20, 0x4f, 0x43, 0x13, 0x20, 0xfe, 0x05,
12398 0xf6, 0xce, 0x01, 0xfe,
12399 0x4a, 0x17, 0x08, 0x54, 0x58, 0x37, 0x12, 0x2f, 0x42, 0x92, 0x01, 0xfe,
12400 0x82, 0x16, 0x02, 0x2b,
12401 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66, 0x01, 0x73, 0xfe, 0x18, 0x10,
12402 0xfe, 0x41, 0x58, 0x09,
12403 0xa4, 0x01, 0x0e, 0xfe, 0xc8, 0x54, 0x6b, 0xfe, 0x10, 0x03, 0x01, 0xfe,
12404 0x82, 0x16, 0x02, 0x2b,
12405 0x2c, 0x4f, 0xfe, 0x02, 0xe8, 0x2a, 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43,
12406 0xfe, 0x77, 0x57, 0xfe,
12407 0x27, 0xf0, 0xfe, 0xe0, 0x01, 0xfe, 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xa7,
12408 0xfe, 0x40, 0x1c, 0x1c,
12409 0xd9, 0xfe, 0x26, 0xf0, 0xfe, 0x5a, 0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x48,
12410 0x03, 0xfe, 0x11, 0xf0,
12411 0xa7, 0xfe, 0xef, 0x10, 0xfe, 0x9f, 0xf0, 0xfe, 0x68, 0x03, 0xf9, 0x10,
12412 0xfe, 0x11, 0x00, 0x02,
12413 0x65, 0x2c, 0xfe, 0x48, 0x1c, 0xf9, 0x08, 0x05, 0x1b, 0xfe, 0x18, 0x13,
12414 0x21, 0x22, 0xa3, 0xb7,
12415 0x13, 0xa3, 0x09, 0x46, 0x01, 0x0e, 0xb7, 0x78, 0x01, 0xfe, 0xb4, 0x16,
12416 0x12, 0xd1, 0x1c, 0xd9,
12417 0xfe, 0x01, 0xf0, 0xd9, 0xfe, 0x82, 0xf0, 0xfe, 0x96, 0x03, 0xfa, 0x12,
12418 0xfe, 0xe4, 0x00, 0x27,
12419 0xfe, 0xa8, 0x03, 0x1c, 0x34, 0x1d, 0xfe, 0xb8, 0x03, 0x01, 0x4b, 0xfe,
12420 0x06, 0xf0, 0xfe, 0xc8,
12421 0x03, 0x95, 0x86, 0xfe, 0x0a, 0xf0, 0xfe, 0x8a, 0x06, 0x02, 0x24, 0x03,
12422 0x70, 0x28, 0x17, 0xfe,
12423 0xfa, 0x04, 0x15, 0x6d, 0x01, 0x36, 0x7b, 0xfe, 0x6a, 0x02, 0x02, 0xd8,
12424 0xf9, 0x2c, 0x99, 0x19,
12425 0xfe, 0x67, 0x1b, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x48, 0x1c,
12426 0x74, 0x01, 0xaf, 0x8c,
12427 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x17, 0xda, 0x09, 0xd1, 0x01, 0x0e,
12428 0x8d, 0x51, 0x64, 0x79,
12429 0x2a, 0x03, 0x70, 0x28, 0xfe, 0x10, 0x12, 0x15, 0x6d, 0x01, 0x36, 0x7b,
12430 0xfe, 0x6a, 0x02, 0x02,
12431 0xd8, 0xc7, 0x81, 0xc8, 0x83, 0x1c, 0x24, 0x27, 0xfe, 0x40, 0x04, 0x1d,
12432 0xfe, 0x3c, 0x04, 0x3b,
12433 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e, 0x12, 0x2d, 0xff, 0x02,
12434 0x00, 0x10, 0x01, 0x0b,
12435 0x1d, 0xfe, 0xe4, 0x04, 0x2d, 0x01, 0x0b, 0x1d, 0x24, 0x33, 0x31, 0xde,
12436 0xfe, 0x4c, 0x44, 0xfe,
12437 0x4c, 0x12, 0x51, 0xfe, 0x44, 0x48, 0x0f, 0x6f, 0xfe, 0x4c, 0x54, 0x6b,
12438 0xda, 0x4f, 0x79, 0x2a,
12439 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x62, 0x13, 0x08, 0x05, 0x1b,
12440 0xfe, 0x2a, 0x13, 0x32,
12441 0x07, 0x82, 0xfe, 0x52, 0x13, 0xfe, 0x20, 0x10, 0x0f, 0x6f, 0xfe, 0x4c,
12442 0x54, 0x6b, 0xda, 0xfe,
12443 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x40, 0x13, 0x08, 0x05, 0x1b, 0xfe,
12444 0x08, 0x13, 0x32, 0x07,
12445 0x82, 0xfe, 0x30, 0x13, 0x08, 0x05, 0x1b, 0xfe, 0x1c, 0x12, 0x15, 0x9d,
12446 0x08, 0x05, 0x06, 0x4d,
12447 0x15, 0xfe, 0x0d, 0x00, 0x01, 0x36, 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24,
12448 0x2d, 0x12, 0xfe, 0xe6,
12449 0x00, 0xfe, 0x1c, 0x90, 0xfe, 0x40, 0x5c, 0x04, 0x15, 0x9d, 0x01, 0x36,
12450 0x02, 0x2b, 0xfe, 0x42,
12451 0x5b, 0x99, 0x19, 0xfe, 0x46, 0x59, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57,
12452 0xfe, 0x87, 0x80, 0xfe,
12453 0x31, 0xe4, 0x5b, 0x08, 0x05, 0x0a, 0xfe, 0x84, 0x13, 0xfe, 0x20, 0x80,
12454 0x07, 0x19, 0xfe, 0x7c,
12455 0x12, 0x53, 0x05, 0x06, 0xfe, 0x6c, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x28,
12456 0x17, 0xfe, 0x90, 0x05,
12457 0xfe, 0x31, 0xe4, 0x5a, 0x53, 0x05, 0x0a, 0xfe, 0x56, 0x13, 0x03, 0xfe,
12458 0xa0, 0x00, 0x28, 0xfe,
12459 0x4e, 0x12, 0x67, 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x48, 0x05, 0x1c,
12460 0x34, 0xfe, 0x89, 0x48,
12461 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x56, 0x05, 0x26, 0xfe, 0xa8, 0x05,
12462 0x12, 0xfe, 0xe3, 0x00,
12463 0x21, 0x53, 0xfe, 0x4a, 0xf0, 0xfe, 0x76, 0x05, 0xfe, 0x49, 0xf0, 0xfe,
12464 0x70, 0x05, 0x88, 0x25,
12465 0xfe, 0x21, 0x00, 0xab, 0x25, 0xfe, 0x22, 0x00, 0xaa, 0x25, 0x58, 0xfe,
12466 0x09, 0x48, 0xff, 0x02,
12467 0x00, 0x10, 0x27, 0xfe, 0x86, 0x05, 0x26, 0xfe, 0xa8, 0x05, 0xfe, 0xe2,
12468 0x08, 0x53, 0x05, 0xcb,
12469 0x4d, 0x01, 0xb0, 0x25, 0x06, 0x13, 0xd3, 0x39, 0xfe, 0x27, 0x01, 0x08,
12470 0x05, 0x1b, 0xfe, 0x22,
12471 0x12, 0x41, 0x01, 0xb2, 0x15, 0x9d, 0x08, 0x05, 0x06, 0x4d, 0x15, 0xfe,
12472 0x0d, 0x00, 0x01, 0x36,
12473 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0xeb,
12474 0x03, 0x5c, 0x28, 0xfe,
12475 0x36, 0x13, 0x41, 0x01, 0xb2, 0x26, 0xfe, 0x18, 0x06, 0x09, 0x06, 0x53,
12476 0x05, 0x1f, 0xfe, 0x02,
12477 0x12, 0x50, 0x01, 0xfe, 0x9e, 0x15, 0x1d, 0xfe, 0x0e, 0x06, 0x12, 0xa5,
12478 0x01, 0x4b, 0x12, 0xfe,
12479 0xe5, 0x00, 0x03, 0x5c, 0xc1, 0x0c, 0x5c, 0x03, 0xcd, 0x28, 0xfe, 0x62,
12480 0x12, 0x03, 0x45, 0x28,
12481 0xfe, 0x5a, 0x13, 0x01, 0xfe, 0x0c, 0x19, 0x01, 0xfe, 0x76, 0x19, 0xfe,
12482 0x43, 0x48, 0xc4, 0xcc,
12483 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0x8b, 0xc4,
12484 0x6e, 0x41, 0x01, 0xb2,
12485 0x26, 0xfe, 0x82, 0x06, 0x53, 0x05, 0x1a, 0xe9, 0x91, 0x09, 0x59, 0x01,
12486 0xfe, 0xcc, 0x15, 0x1d,
12487 0xfe, 0x78, 0x06, 0x12, 0xa5, 0x01, 0x4b, 0x12, 0xfe, 0xe5, 0x00, 0x03,
12488 0x45, 0xc1, 0x0c, 0x45,
12489 0x18, 0x06, 0x01, 0xb2, 0xfa, 0x76, 0x74, 0x01, 0xaf, 0x8c, 0x12, 0xfe,
12490 0xe2, 0x00, 0x27, 0xdb,
12491 0x1c, 0x34, 0xfe, 0x0a, 0xf0, 0xfe, 0xb6, 0x06, 0x94, 0xfe, 0x6c, 0x07,
12492 0xfe, 0x06, 0xf0, 0xfe,
12493 0x74, 0x07, 0x95, 0x86, 0x02, 0x24, 0x08, 0x05, 0x0a, 0xfe, 0x2e, 0x12,
12494 0x16, 0x19, 0x01, 0x0b,
12495 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b,
12496 0xfe, 0x99, 0xa4, 0x01,
12497 0x0b, 0x16, 0x00, 0x02, 0xfe, 0x42, 0x08, 0x68, 0x05, 0x1a, 0xfe, 0x38,
12498 0x12, 0x08, 0x05, 0x1a,
12499 0xfe, 0x30, 0x13, 0x16, 0xfe, 0x1b, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01,
12500 0x0b, 0x16, 0x00, 0x01,
12501 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x06, 0x01, 0x0b, 0x16, 0x00, 0x02,
12502 0xe2, 0x6c, 0x58, 0xbe,
12503 0x50, 0xfe, 0x9a, 0x81, 0x55, 0x1b, 0x7a, 0xfe, 0x42, 0x07, 0x09, 0x1b,
12504 0xfe, 0x09, 0x6f, 0xba,
12505 0xfe, 0xca, 0x45, 0xfe, 0x32, 0x12, 0x69, 0x6d, 0x8b, 0x6c, 0x7f, 0x27,
12506 0xfe, 0x54, 0x07, 0x1c,
12507 0x34, 0xfe, 0x0a, 0xf0, 0xfe, 0x42, 0x07, 0x95, 0x86, 0x94, 0xfe, 0x6c,
12508 0x07, 0x02, 0x24, 0x01,
12509 0x4b, 0x02, 0xdb, 0x16, 0x1f, 0x02, 0xdb, 0xfe, 0x9c, 0xf7, 0xdc, 0xfe,
12510 0x2c, 0x90, 0xfe, 0xae,
12511 0x90, 0x56, 0xfe, 0xda, 0x07, 0x0c, 0x60, 0x14, 0x61, 0x08, 0x54, 0x5a,
12512 0x37, 0x22, 0x20, 0x07,
12513 0x11, 0xfe, 0x0e, 0x12, 0x8d, 0xfe, 0x80, 0x80, 0x39, 0x20, 0x6a, 0x2a,
12514 0xfe, 0x06, 0x10, 0xfe,
12515 0x83, 0xe7, 0xfe, 0x48, 0x00, 0xab, 0xfe, 0x03, 0x40, 0x08, 0x54, 0x5b,
12516 0x37, 0x01, 0xb3, 0xb8,
12517 0xfe, 0x1f, 0x40, 0x13, 0x62, 0x01, 0xef, 0xfe, 0x08, 0x50, 0xfe, 0x8a,
12518 0x50, 0xfe, 0x44, 0x51,
12519 0xfe, 0xc6, 0x51, 0x88, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90, 0x0c, 0x5e,
12520 0x14, 0x5f, 0xfe, 0x0c,
12521 0x90, 0xfe, 0x8e, 0x90, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x0c, 0x3d,
12522 0x14, 0x3e, 0xfe, 0x4a,
12523 0x10, 0x08, 0x05, 0x5a, 0xfe, 0x2a, 0x12, 0xfe, 0x2c, 0x90, 0xfe, 0xae,
12524 0x90, 0x0c, 0x60, 0x14,
12525 0x61, 0x08, 0x05, 0x5b, 0x8b, 0x01, 0xb3, 0xfe, 0x1f, 0x80, 0x13, 0x62,
12526 0xfe, 0x44, 0x90, 0xfe,
12527 0xc6, 0x90, 0x0c, 0x3f, 0x14, 0x40, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90,
12528 0x0c, 0x5e, 0x14, 0x5f,
12529 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90, 0x0c, 0x3d, 0x14, 0x3e, 0x0c, 0x2e,
12530 0x14, 0x3c, 0x21, 0x0c,
12531 0x49, 0x0c, 0x63, 0x08, 0x54, 0x1f, 0x37, 0x2c, 0x0f, 0xfe, 0x4e, 0x11,
12532 0x27, 0xdd, 0xfe, 0x9e,
12533 0xf0, 0xfe, 0x76, 0x08, 0xbc, 0x17, 0x34, 0x2c, 0x77, 0xe6, 0xc5, 0xfe,
12534 0x9a, 0x08, 0xc6, 0xfe,
12535 0xb8, 0x08, 0x94, 0xfe, 0x8e, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x94, 0x08,
12536 0x95, 0x86, 0x02, 0x24,
12537 0x01, 0x4b, 0xfe, 0xc9, 0x10, 0x16, 0x1f, 0xfe, 0xc9, 0x10, 0x68, 0x05,
12538 0x06, 0xfe, 0x10, 0x12,
12539 0x68, 0x05, 0x0a, 0x4e, 0x08, 0x05, 0x0a, 0xfe, 0x90, 0x12, 0xfe, 0x2e,
12540 0x1c, 0x02, 0xfe, 0x18,
12541 0x0b, 0x68, 0x05, 0x06, 0x4e, 0x68, 0x05, 0x0a, 0xfe, 0x7a, 0x12, 0xfe,
12542 0x2c, 0x1c, 0xfe, 0xaa,
12543 0xf0, 0xfe, 0xd2, 0x09, 0xfe, 0xac, 0xf0, 0xfe, 0x00, 0x09, 0x02, 0xfe,
12544 0xde, 0x09, 0xfe, 0xb7,
12545 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0x02, 0xf6, 0x1a, 0x50, 0xfe, 0x70, 0x18,
12546 0xfe, 0xf1, 0x18, 0xfe,
12547 0x40, 0x55, 0xfe, 0xe1, 0x55, 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0xfe,
12548 0x14, 0x59, 0xfe, 0x95,
12549 0x59, 0x1c, 0x85, 0xfe, 0x8c, 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0xac, 0xf0,
12550 0xfe, 0xf0, 0x08, 0xb5,
12551 0xfe, 0xcb, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0x0c, 0x09, 0x02, 0xfe, 0x18,
12552 0x0b, 0xb6, 0xfe, 0xbf,
12553 0x10, 0xfe, 0x2b, 0xf0, 0x85, 0xf4, 0x1e, 0xfe, 0x00, 0xfe, 0xfe, 0x1c,
12554 0x12, 0xc2, 0xfe, 0xd2,
12555 0xf0, 0x85, 0xfe, 0x76, 0x18, 0x1e, 0x19, 0x17, 0x85, 0x03, 0xd2, 0x1e,
12556 0x06, 0x17, 0x85, 0xc5,
12557 0x4a, 0xc6, 0x4a, 0xb5, 0xb6, 0xfe, 0x89, 0x10, 0x74, 0x67, 0x2d, 0x15,
12558 0x9d, 0x01, 0x36, 0x10,
12559 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x65, 0x10, 0x80, 0x02, 0x65, 0xfe,
12560 0x98, 0x80, 0xfe, 0x19,
12561 0xe4, 0x0a, 0xfe, 0x1a, 0x12, 0x51, 0xfe, 0x19, 0x82, 0xfe, 0x6c, 0x18,
12562 0xfe, 0x44, 0x54, 0xbe,
12563 0xfe, 0x19, 0x81, 0xfe, 0x74, 0x18, 0x8f, 0x90, 0x17, 0xfe, 0xce, 0x08,
12564 0x02, 0x4a, 0x08, 0x05,
12565 0x5a, 0xec, 0x03, 0x2e, 0x29, 0x3c, 0x0c, 0x3f, 0x14, 0x40, 0x9b, 0x2e,
12566 0x9c, 0x3c, 0xfe, 0x6c,
12567 0x18, 0xfe, 0xed, 0x18, 0xfe, 0x44, 0x54, 0xfe, 0xe5, 0x54, 0x3a, 0x3f,
12568 0x3b, 0x40, 0x03, 0x49,
12569 0x29, 0x63, 0x8f, 0xfe, 0xe3, 0x54, 0xfe, 0x74, 0x18, 0xfe, 0xf5, 0x18,
12570 0x8f, 0xfe, 0xe3, 0x54,
12571 0x90, 0xc0, 0x56, 0xfe, 0xce, 0x08, 0x02, 0x4a, 0xfe, 0x37, 0xf0, 0xfe,
12572 0xda, 0x09, 0xfe, 0x8b,
12573 0xf0, 0xfe, 0x60, 0x09, 0x02, 0x4a, 0x08, 0x05, 0x0a, 0x23, 0xfe, 0xfa,
12574 0x0a, 0x3a, 0x49, 0x3b,
12575 0x63, 0x56, 0xfe, 0x3e, 0x0a, 0x0f, 0xfe, 0xc0, 0x07, 0x41, 0x98, 0x00,
12576 0xad, 0xfe, 0x01, 0x59,
12577 0xfe, 0x52, 0xf0, 0xfe, 0x0c, 0x0a, 0x8f, 0x7a, 0xfe, 0x24, 0x0a, 0x3a,
12578 0x49, 0x8f, 0xfe, 0xe3,
12579 0x54, 0x57, 0x49, 0x7d, 0x63, 0xfe, 0x14, 0x58, 0xfe, 0x95, 0x58, 0x02,
12580 0x4a, 0x3a, 0x49, 0x3b,
12581 0x63, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0xbe, 0x57, 0x49, 0x57, 0x63,
12582 0x02, 0x4a, 0x08, 0x05,
12583 0x5a, 0xfe, 0x82, 0x12, 0x08, 0x05, 0x1f, 0xfe, 0x66, 0x13, 0x22, 0x62,
12584 0xb7, 0xfe, 0x03, 0xa1,
12585 0xfe, 0x83, 0x80, 0xfe, 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91,
12586 0xfe, 0x86, 0x91, 0x6a,
12587 0x2a, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x56, 0xe0, 0x03, 0x60, 0x29,
12588 0x61, 0x0c, 0x7f, 0x14,
12589 0x80, 0x57, 0x60, 0x7d, 0x61, 0x01, 0xb3, 0xb8, 0x6a, 0x2a, 0x13, 0x62,
12590 0x9b, 0x2e, 0x9c, 0x3c,
12591 0x3a, 0x3f, 0x3b, 0x40, 0x90, 0xc0, 0xfe, 0x04, 0xfa, 0x2e, 0xfe, 0x05,
12592 0xfa, 0x3c, 0x01, 0xef,
12593 0xfe, 0x36, 0x10, 0x21, 0x0c, 0x7f, 0x0c, 0x80, 0x3a, 0x3f, 0x3b, 0x40,
12594 0xe4, 0x08, 0x05, 0x1f,
12595 0x17, 0xe0, 0x3a, 0x3d, 0x3b, 0x3e, 0x08, 0x05, 0xfe, 0xf7, 0x00, 0x37,
12596 0x03, 0x5e, 0x29, 0x5f,
12597 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0x57, 0x49, 0x7d, 0x63, 0x02, 0xfe,
12598 0xf4, 0x09, 0x08, 0x05,
12599 0x1f, 0x17, 0xe0, 0x08, 0x05, 0xfe, 0xf7, 0x00, 0x37, 0xbe, 0xfe, 0x19,
12600 0x81, 0x50, 0xfe, 0x10,
12601 0x90, 0xfe, 0x92, 0x90, 0xfe, 0xd3, 0x10, 0x32, 0x07, 0xa6, 0x17, 0xfe,
12602 0x08, 0x09, 0x12, 0xa6,
12603 0x08, 0x05, 0x0a, 0xfe, 0x14, 0x13, 0x03, 0x3d, 0x29, 0x3e, 0x56, 0xfe,
12604 0x08, 0x09, 0xfe, 0x0c,
12605 0x58, 0xfe, 0x8d, 0x58, 0x02, 0x4a, 0x21, 0x41, 0xfe, 0x19, 0x80, 0xe7,
12606 0x08, 0x05, 0x0a, 0xfe,
12607 0x1a, 0x12, 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, 0xf4, 0xc2, 0xfe, 0xd1,
12608 0xf0, 0xe2, 0x15, 0x7e,
12609 0x01, 0x36, 0x10, 0xfe, 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe, 0x6c, 0x19,
12610 0x57, 0x3d, 0xfe, 0xed,
12611 0x19, 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xf4, 0x1e, 0xfe,
12612 0x00, 0xff, 0x35, 0xfe,
12613 0x74, 0x10, 0xc2, 0xfe, 0xd2, 0xf0, 0xfe, 0xa6, 0x0b, 0xfe, 0x76, 0x18,
12614 0x1e, 0x19, 0x8a, 0x03,
12615 0xd2, 0x1e, 0x06, 0xfe, 0x08, 0x13, 0x10, 0xfe, 0x16, 0x00, 0x02, 0x65,
12616 0xfe, 0xd1, 0xf0, 0xfe,
12617 0xb8, 0x0b, 0x15, 0x7e, 0x01, 0x36, 0x10, 0xfe, 0x17, 0x00, 0xfe, 0x42,
12618 0x10, 0xfe, 0xce, 0xf0,
12619 0xfe, 0xbe, 0x0b, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xca, 0x0b,
12620 0x10, 0xfe, 0x22, 0x00,
12621 0x02, 0x65, 0xfe, 0xcb, 0xf0, 0xfe, 0xd6, 0x0b, 0x10, 0xfe, 0x24, 0x00,
12622 0x02, 0x65, 0xfe, 0xd0,
12623 0xf0, 0xfe, 0xe0, 0x0b, 0x10, 0x9e, 0xe5, 0xfe, 0xcf, 0xf0, 0xfe, 0xea,
12624 0x0b, 0x10, 0x58, 0xfe,
12625 0x10, 0x10, 0xfe, 0xcc, 0xf0, 0xe2, 0x68, 0x05, 0x1f, 0x4d, 0x10, 0xfe,
12626 0x12, 0x00, 0x2c, 0x0f,
12627 0xfe, 0x4e, 0x11, 0x27, 0xfe, 0x00, 0x0c, 0xfe, 0x9e, 0xf0, 0xfe, 0x14,
12628 0x0c, 0xbc, 0x17, 0x34,
12629 0x2c, 0x77, 0xe6, 0xc5, 0x24, 0xc6, 0x24, 0x2c, 0xfa, 0x27, 0xfe, 0x20,
12630 0x0c, 0x1c, 0x34, 0x94,
12631 0xfe, 0x3c, 0x0c, 0x95, 0x86, 0xc5, 0xdc, 0xc6, 0xdc, 0x02, 0x24, 0x01,
12632 0x4b, 0xfe, 0xdb, 0x10,
12633 0x12, 0xfe, 0xe8, 0x00, 0xb5, 0xb6, 0x74, 0xc7, 0x81, 0xc8, 0x83, 0xfe,
12634 0x89, 0xf0, 0x24, 0x33,
12635 0x31, 0xe1, 0xc7, 0x81, 0xc8, 0x83, 0x27, 0xfe, 0x66, 0x0c, 0x1d, 0x24,
12636 0x33, 0x31, 0xdf, 0xbc,
12637 0x4e, 0x10, 0xfe, 0x42, 0x00, 0x02, 0x65, 0x7c, 0x06, 0xfe, 0x81, 0x49,
12638 0x17, 0xfe, 0x2c, 0x0d,
12639 0x08, 0x05, 0x0a, 0xfe, 0x44, 0x13, 0x10, 0x00, 0x55, 0x0a, 0xfe, 0x54,
12640 0x12, 0x55, 0xfe, 0x28,
12641 0x00, 0x23, 0xfe, 0x9a, 0x0d, 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66,
12642 0x44, 0xfe, 0x28, 0x00,
12643 0xfe, 0xe2, 0x10, 0x01, 0xf5, 0x01, 0xf6, 0x09, 0xa4, 0x01, 0xfe, 0x26,
12644 0x0f, 0x64, 0x12, 0x2f,
12645 0x01, 0x73, 0x02, 0x2b, 0x10, 0xfe, 0x44, 0x00, 0x55, 0x0a, 0xe9, 0x44,
12646 0x0a, 0xfe, 0xb4, 0x10,
12647 0x01, 0xb0, 0x44, 0x0a, 0xfe, 0xaa, 0x10, 0x01, 0xb0, 0xfe, 0x19, 0x82,
12648 0xfe, 0x34, 0x46, 0xac,
12649 0x44, 0x0a, 0x10, 0xfe, 0x43, 0x00, 0xfe, 0x96, 0x10, 0x08, 0x54, 0x0a,
12650 0x37, 0x01, 0xf5, 0x01,
12651 0xf6, 0x64, 0x12, 0x2f, 0x01, 0x73, 0x99, 0x0a, 0x64, 0x42, 0x92, 0x02,
12652 0xfe, 0x2e, 0x03, 0x08,
12653 0x05, 0x0a, 0x8a, 0x44, 0x0a, 0x10, 0x00, 0xfe, 0x5c, 0x10, 0x68, 0x05,
12654 0x1a, 0xfe, 0x58, 0x12,
12655 0x08, 0x05, 0x1a, 0xfe, 0x50, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0,
12656 0xfe, 0x50, 0x0d, 0xfe,
12657 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x56, 0x0d, 0x08, 0x54, 0x1a, 0x37,
12658 0xfe, 0xa9, 0x10, 0x10,
12659 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0a, 0x50, 0xfe, 0x2e, 0x10, 0x10,
12660 0xfe, 0x13, 0x00, 0xfe,
12661 0x10, 0x10, 0x10, 0x6f, 0xab, 0x10, 0xfe, 0x41, 0x00, 0xaa, 0x10, 0xfe,
12662 0x24, 0x00, 0x8c, 0xb5,
12663 0xb6, 0x74, 0x03, 0x70, 0x28, 0x23, 0xd8, 0x50, 0xfe, 0x04, 0xe6, 0x1a,
12664 0xfe, 0x9d, 0x41, 0xfe,
12665 0x1c, 0x42, 0x64, 0x01, 0xe3, 0x02, 0x2b, 0xf8, 0x15, 0x0a, 0x39, 0xa0,
12666 0xb4, 0x15, 0xfe, 0x31,
12667 0x00, 0x39, 0xa2, 0x01, 0xfe, 0x48, 0x10, 0x02, 0xd7, 0x42, 0xfe, 0x06,
12668 0xec, 0xd0, 0xfc, 0x44,
12669 0x1b, 0xfe, 0xce, 0x45, 0x35, 0x42, 0xfe, 0x06, 0xea, 0xd0, 0xfe, 0x47,
12670 0x4b, 0x91, 0xfe, 0x75,
12671 0x57, 0x03, 0x5d, 0xfe, 0x98, 0x56, 0xfe, 0x38, 0x12, 0x09, 0x48, 0x01,
12672 0x0e, 0xfe, 0x44, 0x48,
12673 0x4f, 0x08, 0x05, 0x1b, 0xfe, 0x1a, 0x13, 0x09, 0x46, 0x01, 0x0e, 0x41,
12674 0xfe, 0x41, 0x58, 0x09,
12675 0xa4, 0x01, 0x0e, 0xfe, 0x49, 0x54, 0x96, 0xfe, 0x1e, 0x0e, 0x02, 0xfe,
12676 0x2e, 0x03, 0x09, 0x5d,
12677 0xfe, 0xee, 0x14, 0xfc, 0x44, 0x1b, 0xfe, 0xce, 0x45, 0x35, 0x42, 0xfe,
12678 0xce, 0x47, 0xfe, 0xad,
12679 0x13, 0x02, 0x2b, 0x22, 0x20, 0x07, 0x11, 0xfe, 0x9e, 0x12, 0x21, 0x13,
12680 0x59, 0x13, 0x9f, 0x13,
12681 0xd5, 0x22, 0x2f, 0x41, 0x39, 0x2f, 0xbc, 0xad, 0xfe, 0xbc, 0xf0, 0xfe,
12682 0xe0, 0x0e, 0x0f, 0x06,
12683 0x13, 0x59, 0x01, 0xfe, 0xda, 0x16, 0x03, 0xfe, 0x38, 0x01, 0x29, 0xfe,
12684 0x3a, 0x01, 0x56, 0xfe,
12685 0xe4, 0x0e, 0xfe, 0x02, 0xec, 0xd5, 0x69, 0x00, 0x66, 0xfe, 0x04, 0xec,
12686 0x20, 0x4f, 0xfe, 0x05,
12687 0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x4a, 0x17, 0xfe, 0x08, 0x90, 0xfe,
12688 0x48, 0xf4, 0x0d, 0xfe,
12689 0x18, 0x13, 0xba, 0xfe, 0x02, 0xea, 0xd5, 0x69, 0x7e, 0xfe, 0xc5, 0x13,
12690 0x15, 0x1a, 0x39, 0xa0,
12691 0xb4, 0xfe, 0x2e, 0x10, 0x03, 0xfe, 0x38, 0x01, 0x1e, 0xfe, 0xf0, 0xff,
12692 0x0c, 0xfe, 0x60, 0x01,
12693 0x03, 0xfe, 0x3a, 0x01, 0x0c, 0xfe, 0x62, 0x01, 0x43, 0x13, 0x20, 0x25,
12694 0x06, 0x13, 0x2f, 0x12,
12695 0x2f, 0x92, 0x0f, 0x06, 0x04, 0x21, 0x04, 0x22, 0x59, 0xfe, 0xf7, 0x12,
12696 0x22, 0x9f, 0xb7, 0x13,
12697 0x9f, 0x07, 0x7e, 0xfe, 0x71, 0x13, 0xfe, 0x24, 0x1c, 0x15, 0x19, 0x39,
12698 0xa0, 0xb4, 0xfe, 0xd9,
12699 0x10, 0xc3, 0xfe, 0x03, 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x04,
12700 0xc3, 0xfe, 0x03, 0xdc,
12701 0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x04, 0xfe, 0x03, 0x57, 0xc3, 0x21,
12702 0xfe, 0x00, 0xcc, 0x04,
12703 0xfe, 0x03, 0x57, 0xc3, 0x78, 0x04, 0x08, 0x05, 0x58, 0xfe, 0x22, 0x13,
12704 0xfe, 0x1c, 0x80, 0x07,
12705 0x06, 0xfe, 0x1a, 0x13, 0xfe, 0x1e, 0x80, 0xed, 0xfe, 0x1d, 0x80, 0xae,
12706 0xfe, 0x0c, 0x90, 0xfe,
12707 0x0e, 0x13, 0xfe, 0x0e, 0x90, 0xac, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4,
12708 0x0a, 0xfe, 0x3c, 0x50,
12709 0xaa, 0x01, 0xfe, 0x7a, 0x17, 0x32, 0x07, 0x2f, 0xad, 0x01, 0xfe, 0xb4,
12710 0x16, 0x08, 0x05, 0x1b,
12711 0x4e, 0x01, 0xf5, 0x01, 0xf6, 0x12, 0xfe, 0xe9, 0x00, 0x08, 0x05, 0x58,
12712 0xfe, 0x2c, 0x13, 0x01,
12713 0xfe, 0x0c, 0x17, 0xfe, 0x1e, 0x1c, 0xfe, 0x14, 0x90, 0xfe, 0x96, 0x90,
12714 0x0c, 0xfe, 0x64, 0x01,
12715 0x14, 0xfe, 0x66, 0x01, 0x08, 0x05, 0x5b, 0xfe, 0x12, 0x12, 0xfe, 0x03,
12716 0x80, 0x8d, 0xfe, 0x01,
12717 0xec, 0x20, 0xfe, 0x80, 0x40, 0x13, 0x20, 0x6a, 0x2a, 0x12, 0xcf, 0x64,
12718 0x22, 0x20, 0xfb, 0x79,
12719 0x20, 0x04, 0xfe, 0x08, 0x1c, 0x03, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58,
12720 0x03, 0xfe, 0xae, 0x00,
12721
12722 0xfe, 0x07, 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58, 0x03, 0xfe,
12723 0xb2, 0x00, 0xfe, 0x09,
12724 0x58, 0xfe, 0x0a, 0x1c, 0x25, 0x6e, 0x13, 0xd0, 0x21, 0x0c, 0x5c, 0x0c,
12725 0x45, 0x0f, 0x46, 0x52,
12726 0x50, 0x18, 0x1b, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x23, 0xfe, 0xfc,
12727 0x0f, 0x44, 0x11, 0x0f,
12728 0x48, 0x52, 0x18, 0x58, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x23, 0xe4,
12729 0x25, 0x11, 0x13, 0x20,
12730 0x7c, 0x6f, 0x4f, 0x22, 0x20, 0xfb, 0x79, 0x20, 0x12, 0xcf, 0xfe, 0x14,
12731 0x56, 0xfe, 0xd6, 0xf0,
12732 0xfe, 0x26, 0x10, 0xf8, 0x74, 0xfe, 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe,
12733 0x18, 0x1c, 0x04, 0x42,
12734 0xfe, 0x0c, 0x14, 0xfc, 0xfe, 0x07, 0xe6, 0x1b, 0xfe, 0xce, 0x47, 0xfe,
12735 0xf5, 0x13, 0x04, 0x01,
12736 0xb0, 0x7c, 0x6f, 0x4f, 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42,
12737 0x13, 0x32, 0x07, 0x2f,
12738 0xfe, 0x34, 0x13, 0x09, 0x48, 0x01, 0x0e, 0xbb, 0xfe, 0x36, 0x12, 0xfe,
12739 0x41, 0x48, 0xfe, 0x45,
12740 0x48, 0x01, 0xf0, 0xfe, 0x00, 0xcc, 0xbb, 0xfe, 0xf3, 0x13, 0x43, 0x78,
12741 0x07, 0x11, 0xac, 0x09,
12742 0x84, 0x01, 0x0e, 0xfe, 0x80, 0x5c, 0x01, 0x73, 0xfe, 0x0e, 0x10, 0x07,
12743 0x82, 0x4e, 0xfe, 0x14,
12744 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x60, 0x10, 0x04, 0xfe, 0x44, 0x58, 0x8d,
12745 0xfe, 0x01, 0xec, 0xa2,
12746 0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x1a, 0x79,
12747 0x2a, 0x01, 0xe3, 0xfe,
12748 0xdd, 0x10, 0x2c, 0xc7, 0x81, 0xc8, 0x83, 0x33, 0x31, 0xde, 0x07, 0x1a,
12749 0xfe, 0x48, 0x12, 0x07,
12750 0x0a, 0xfe, 0x56, 0x12, 0x07, 0x19, 0xfe, 0x30, 0x12, 0x07, 0xc9, 0x17,
12751 0xfe, 0x32, 0x12, 0x07,
12752 0xfe, 0x23, 0x00, 0x17, 0xeb, 0x07, 0x06, 0x17, 0xfe, 0x9c, 0x12, 0x07,
12753 0x1f, 0xfe, 0x12, 0x12,
12754 0x07, 0x00, 0x17, 0x24, 0x15, 0xc9, 0x01, 0x36, 0xa9, 0x2d, 0x01, 0x0b,
12755 0x94, 0x4b, 0x04, 0x2d,
12756 0xdd, 0x09, 0xd1, 0x01, 0xfe, 0x26, 0x0f, 0x12, 0x82, 0x02, 0x2b, 0x2d,
12757 0x32, 0x07, 0xa6, 0xfe,
12758 0xd9, 0x13, 0x3a, 0x3d, 0x3b, 0x3e, 0x56, 0xfe, 0xf0, 0x11, 0x08, 0x05,
12759 0x5a, 0xfe, 0x72, 0x12,
12760 0x9b, 0x2e, 0x9c, 0x3c, 0x90, 0xc0, 0x96, 0xfe, 0xba, 0x11, 0x22, 0x62,
12761 0xfe, 0x26, 0x13, 0x03,
12762 0x7f, 0x29, 0x80, 0x56, 0xfe, 0x76, 0x0d, 0x0c, 0x60, 0x14, 0x61, 0x21,
12763 0x0c, 0x7f, 0x0c, 0x80,
12764 0x01, 0xb3, 0x25, 0x6e, 0x77, 0x13, 0x62, 0x01, 0xef, 0x9b, 0x2e, 0x9c,
12765 0x3c, 0xfe, 0x04, 0x55,
12766 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x2e, 0xfe, 0x05, 0xfa, 0x3c, 0xfe,
12767 0x91, 0x10, 0x03, 0x3f,
12768 0x29, 0x40, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56, 0x0c, 0x3f, 0x14, 0x40,
12769 0x88, 0x9b, 0x2e, 0x9c,
12770 0x3c, 0x90, 0xc0, 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x00, 0x56, 0xfe, 0xa1,
12771 0x56, 0x0c, 0x5e, 0x14,
12772 0x5f, 0x08, 0x05, 0x5a, 0xfe, 0x1e, 0x12, 0x22, 0x62, 0xfe, 0x1f, 0x40,
12773 0x03, 0x60, 0x29, 0x61,
12774 0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x03, 0x3f, 0x29, 0x40, 0xfe, 0x44,
12775 0x50, 0xfe, 0xc6, 0x50,
12776 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x03, 0x3d,
12777 0x29, 0x3e, 0xfe, 0x40,
12778 0x50, 0xfe, 0xc2, 0x50, 0x02, 0x89, 0x25, 0x06, 0x13, 0xd4, 0x02, 0x72,
12779 0x2d, 0x01, 0x0b, 0x1d,
12780 0x4c, 0x33, 0x31, 0xde, 0x07, 0x06, 0x23, 0x4c, 0x32, 0x07, 0xa6, 0x23,
12781 0x72, 0x01, 0xaf, 0x1e,
12782 0x43, 0x17, 0x4c, 0x08, 0x05, 0x0a, 0xee, 0x3a, 0x3d, 0x3b, 0x3e, 0xfe,
12783 0x0a, 0x55, 0x35, 0xfe,
12784 0x8b, 0x55, 0x57, 0x3d, 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51,
12785 0x02, 0x72, 0xfe, 0x19,
12786 0x81, 0xba, 0xfe, 0x19, 0x41, 0x02, 0x72, 0x2d, 0x01, 0x0b, 0x1c, 0x34,
12787 0x1d, 0xe8, 0x33, 0x31,
12788 0xe1, 0x55, 0x19, 0xfe, 0xa6, 0x12, 0x55, 0x0a, 0x4d, 0x02, 0x4c, 0x01,
12789 0x0b, 0x1c, 0x34, 0x1d,
12790 0xe8, 0x33, 0x31, 0xdf, 0x07, 0x19, 0x23, 0x4c, 0x01, 0x0b, 0x1d, 0xe8,
12791 0x33, 0x31, 0xfe, 0xe8,
12792 0x09, 0xfe, 0xc2, 0x49, 0x51, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0x8a, 0x53,
12793 0x05, 0x1f, 0x35, 0xa9,
12794 0xfe, 0xbb, 0x45, 0x55, 0x00, 0x4e, 0x44, 0x06, 0x7c, 0x43, 0xfe, 0xda,
12795 0x14, 0x01, 0xaf, 0x8c,
12796 0xfe, 0x4b, 0x45, 0xee, 0x32, 0x07, 0xa5, 0xed, 0x03, 0xcd, 0x28, 0x8a,
12797 0x03, 0x45, 0x28, 0x35,
12798 0x67, 0x02, 0x72, 0xfe, 0xc0, 0x5d, 0xfe, 0xf8, 0x14, 0xfe, 0x03, 0x17,
12799 0x03, 0x5c, 0xc1, 0x0c,
12800 0x5c, 0x67, 0x2d, 0x01, 0x0b, 0x26, 0x89, 0x01, 0xfe, 0x9e, 0x15, 0x02,
12801 0x89, 0x01, 0x0b, 0x1c,
12802 0x34, 0x1d, 0x4c, 0x33, 0x31, 0xdf, 0x07, 0x06, 0x23, 0x4c, 0x01, 0xf1,
12803 0xfe, 0x42, 0x58, 0xf1,
12804 0xfe, 0xa4, 0x14, 0x8c, 0xfe, 0x4a, 0xf4, 0x0a, 0x17, 0x4c, 0xfe, 0x4a,
12805 0xf4, 0x06, 0xea, 0x32,
12806 0x07, 0xa5, 0x8b, 0x02, 0x72, 0x03, 0x45, 0xc1, 0x0c, 0x45, 0x67, 0x2d,
12807 0x01, 0x0b, 0x26, 0x89,
12808 0x01, 0xfe, 0xcc, 0x15, 0x02, 0x89, 0x0f, 0x06, 0x27, 0xfe, 0xbe, 0x13,
12809 0x26, 0xfe, 0xd4, 0x13,
12810 0x76, 0xfe, 0x89, 0x48, 0x01, 0x0b, 0x21, 0x76, 0x04, 0x7b, 0xfe, 0xd0,
12811 0x13, 0x1c, 0xfe, 0xd0,
12812 0x13, 0x1d, 0xfe, 0xbe, 0x13, 0x67, 0x2d, 0x01, 0x0b, 0xfe, 0xd5, 0x10,
12813 0x0f, 0x71, 0xff, 0x02,
12814 0x00, 0x57, 0x52, 0x93, 0x1e, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe,
12815 0x00, 0x5c, 0x04, 0x0f,
12816 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0xfe, 0x30, 0x56,
12817 0xfe, 0x00, 0x5c, 0x04,
12818 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x04, 0x0f, 0x71, 0xff,
12819 0x02, 0x00, 0x57, 0x52,
12820 0x93, 0xfe, 0x0b, 0x58, 0x04, 0x09, 0x5c, 0x01, 0x87, 0x09, 0x45, 0x01,
12821 0x87, 0x04, 0xfe, 0x03,
12822 0xa1, 0x1e, 0x11, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4, 0x1f, 0x52,
12823 0xfe, 0x00, 0x7d, 0xfe,
12824 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c, 0x6a, 0x2a, 0x0c, 0x5e,
12825 0x14, 0x5f, 0x57, 0x3f,
12826 0x7d, 0x40, 0x04, 0xdd, 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83,
12827 0x5a, 0x8d, 0x04, 0x01,
12828 0xfe, 0x0c, 0x19, 0xfe, 0x42, 0x48, 0x50, 0x51, 0x91, 0x01, 0x0b, 0x1d,
12829 0xfe, 0x96, 0x15, 0x33,
12830 0x31, 0xe1, 0x01, 0x0b, 0x1d, 0xfe, 0x96, 0x15, 0x33, 0x31, 0xfe, 0xe8,
12831 0x0a, 0xfe, 0xc1, 0x59,
12832 0x03, 0xcd, 0x28, 0xfe, 0xcc, 0x12, 0x53, 0x05, 0x1a, 0xfe, 0xc4, 0x13,
12833 0x21, 0x69, 0x1a, 0xee,
12834 0x55, 0xca, 0x6b, 0xfe, 0xdc, 0x14, 0x4d, 0x0f, 0x06, 0x18, 0xca, 0x7c,
12835 0x30, 0xfe, 0x78, 0x10,
12836 0xff, 0x02, 0x83, 0x55, 0xab, 0xff, 0x02, 0x83, 0x55, 0x69, 0x19, 0xae,
12837 0x98, 0xfe, 0x30, 0x00,
12838 0x96, 0xf2, 0x18, 0x6d, 0x0f, 0x06, 0xfe, 0x56, 0x10, 0x69, 0x0a, 0xed,
12839 0x98, 0xfe, 0x64, 0x00,
12840 0x96, 0xf2, 0x09, 0xfe, 0x64, 0x00, 0x18, 0x9e, 0x0f, 0x06, 0xfe, 0x28,
12841 0x10, 0x69, 0x06, 0xfe,
12842 0x60, 0x13, 0x98, 0xfe, 0xc8, 0x00, 0x96, 0xf2, 0x09, 0xfe, 0xc8, 0x00,
12843 0x18, 0x59, 0x0f, 0x06,
12844 0x88, 0x98, 0xfe, 0x90, 0x01, 0x7a, 0xfe, 0x42, 0x15, 0x91, 0xe4, 0xfe,
12845 0x43, 0xf4, 0x9f, 0xfe,
12846 0x56, 0xf0, 0xfe, 0x54, 0x15, 0xfe, 0x04, 0xf4, 0x71, 0xfe, 0x43, 0xf4,
12847 0x9e, 0xfe, 0xf3, 0x10,
12848 0xfe, 0x40, 0x5c, 0x01, 0xfe, 0x16, 0x14, 0x1e, 0x43, 0xec, 0xfe, 0x00,
12849 0x17, 0xfe, 0x4d, 0xe4,
12850 0x6e, 0x7a, 0xfe, 0x90, 0x15, 0xc4, 0x6e, 0xfe, 0x1c, 0x10, 0xfe, 0x00,
12851 0x17, 0xfe, 0x4d, 0xe4,
12852 0xcc, 0x7a, 0xfe, 0x90, 0x15, 0xc4, 0xcc, 0x88, 0x51, 0x21, 0xfe, 0x4d,
12853 0xf4, 0x00, 0xe9, 0x91,
12854 0x0f, 0x06, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58, 0x04, 0x51, 0x0f, 0x0a,
12855 0x04, 0x16, 0x06, 0x01,
12856 0x0b, 0x26, 0xf3, 0x16, 0x0a, 0x01, 0x0b, 0x26, 0xf3, 0x16, 0x19, 0x01,
12857 0x0b, 0x26, 0xf3, 0x76,
12858 0xfe, 0x89, 0x49, 0x01, 0x0b, 0x04, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1,
12859 0x16, 0x19, 0x01, 0x0b,
12860 0x26, 0xb1, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1, 0xfe, 0x89, 0x49, 0x01,
12861 0x0b, 0x26, 0xb1, 0x76,
12862 0xfe, 0x89, 0x4a, 0x01, 0x0b, 0x04, 0x51, 0x04, 0x22, 0xd3, 0x07, 0x06,
12863 0xfe, 0x48, 0x13, 0xb8,
12864 0x13, 0xd3, 0xfe, 0x49, 0xf4, 0x00, 0x4d, 0x76, 0xa9, 0x67, 0xfe, 0x01,
12865 0xec, 0xfe, 0x27, 0x01,
12866 0xfe, 0x89, 0x48, 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x2e, 0x16, 0x32,
12867 0x07, 0xfe, 0xe3, 0x00,
12868 0xfe, 0x20, 0x13, 0x1d, 0xfe, 0x52, 0x16, 0x21, 0x13, 0xd4, 0x01, 0x4b,
12869 0x22, 0xd4, 0x07, 0x06,
12870 0x4e, 0x08, 0x54, 0x06, 0x37, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfb, 0x8e,
12871 0x07, 0x11, 0xae, 0x09,
12872 0x84, 0x01, 0x0e, 0x8e, 0x09, 0x5d, 0x01, 0xa8, 0x04, 0x09, 0x84, 0x01,
12873 0x0e, 0x8e, 0xfe, 0x80,
12874 0xe7, 0x11, 0x07, 0x11, 0x8a, 0xfe, 0x45, 0x58, 0x01, 0xf0, 0x8e, 0x04,
12875 0x09, 0x48, 0x01, 0x0e,
12876 0x8e, 0x09, 0x5d, 0x01, 0xa8, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfe, 0x80,
12877 0x80, 0xfe, 0x80, 0x4c,
12878 0xfe, 0x49, 0xe4, 0x11, 0xae, 0x09, 0x84, 0x01, 0x0e, 0xfe, 0x80, 0x4c,
12879 0x09, 0x5d, 0x01, 0x87,
12880 0x04, 0x18, 0x11, 0x75, 0x6c, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe,
12881 0x19, 0xde, 0xfe, 0x24,
12882 0x1c, 0xfe, 0x1d, 0xf7, 0x1b, 0x97, 0xfe, 0xee, 0x16, 0x01, 0xfe, 0xf4,
12883 0x17, 0xad, 0x9a, 0x1b,
12884 0x6c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x04, 0xb9, 0x23, 0xfe, 0xde,
12885 0x16, 0xfe, 0xda, 0x10,
12886 0x18, 0x11, 0x75, 0x03, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x1f, 0xfe,
12887 0x18, 0x58, 0x03, 0xfe,
12888 0x66, 0x01, 0xfe, 0x19, 0x58, 0x9a, 0x1f, 0xfe, 0x3c, 0x90, 0xfe, 0x30,
12889 0xf4, 0x06, 0xfe, 0x3c,
12890 0x50, 0x6c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x1f,
12891 0x97, 0xfe, 0x38, 0x17,
12892 0xfe, 0xb6, 0x14, 0x35, 0x04, 0xb9, 0x23, 0xfe, 0x10, 0x17, 0xfe, 0x9c,
12893 0x10, 0x18, 0x11, 0x75,
12894 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7,
12895 0x2e, 0x97, 0xfe, 0x5a,
12896 0x17, 0xfe, 0x94, 0x14, 0xec, 0x9a, 0x2e, 0x6c, 0x1a, 0xfe, 0xaf, 0x19,
12897 0xfe, 0x98, 0xe7, 0x00,
12898 0x04, 0xb9, 0x23, 0xfe, 0x4e, 0x17, 0xfe, 0x6c, 0x10, 0x18, 0x11, 0x75,
12899 0xfe, 0x30, 0xbc, 0xfe,
12900 0xb2, 0xbc, 0x9a, 0xcb, 0x6c, 0x1a, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7,
12901 0xcb, 0x97, 0xfe, 0x92,
12902 0x17, 0xfe, 0x5c, 0x14, 0x35, 0x04, 0xb9, 0x23, 0xfe, 0x7e, 0x17, 0xfe,
12903 0x42, 0x10, 0xfe, 0x02,
12904 0xf6, 0x11, 0x75, 0xfe, 0x18, 0xfe, 0x60, 0xfe, 0x19, 0xfe, 0x61, 0xfe,
12905 0x03, 0xa1, 0xfe, 0x1d,
12906 0xf7, 0x5b, 0x97, 0xfe, 0xb8, 0x17, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13,
12907 0x9a, 0x5b, 0x41, 0xfe,
12908 0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x11, 0xfe, 0x81, 0xe7,
12909 0x11, 0x12, 0xfe, 0xdd,
12910 0x00, 0x6a, 0x2a, 0x04, 0x6a, 0x2a, 0xfe, 0x12, 0x45, 0x23, 0xfe, 0xa8,
12911 0x17, 0x15, 0x06, 0x39,
12912 0xa0, 0xb4, 0x02, 0x2b, 0xfe, 0x39, 0xf0, 0xfe, 0xfc, 0x17, 0x21, 0x04,
12913 0xfe, 0x7e, 0x18, 0x1e,
12914 0x19, 0x66, 0x0f, 0x0d, 0x04, 0x75, 0x03, 0xd2, 0x1e, 0x06, 0xfe, 0xef,
12915 0x12, 0xfe, 0xe1, 0x10,
12916 0x7c, 0x6f, 0x4f, 0x32, 0x07, 0x2f, 0xfe, 0x3c, 0x13, 0xf1, 0xfe, 0x42,
12917 0x13, 0x42, 0x92, 0x09,
12918 0x48, 0x01, 0x0e, 0xbb, 0xeb, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01,
12919 0xf0, 0xfe, 0x00, 0xcc,
12920 0xbb, 0xfe, 0xf3, 0x13, 0x43, 0x78, 0x07, 0x11, 0xac, 0x09, 0x84, 0x01,
12921 0x0e, 0xfe, 0x80, 0x4c,
12922 0x01, 0x73, 0xfe, 0x16, 0x10, 0x07, 0x82, 0x8b, 0xfe, 0x40, 0x14, 0xfe,
12923 0x24, 0x12, 0xfe, 0x14,
12924 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x1c, 0x18, 0x18, 0x0a, 0x04, 0xfe, 0x9c,
12925 0xe7, 0x0a, 0x10, 0xfe,
12926 0x15, 0x00, 0x64, 0x79, 0x2a, 0x01, 0xe3, 0x18, 0x06, 0x04, 0x42, 0x92,
12927 0x08, 0x54, 0x1b, 0x37,
12928 0x12, 0x2f, 0x01, 0x73, 0x18, 0x06, 0x04, 0xfe, 0x38, 0x90, 0xfe, 0xba,
12929 0x90, 0x3a, 0xce, 0x3b,
12930 0xcf, 0xfe, 0x48, 0x55, 0x35, 0xfe, 0xc9, 0x55, 0x04, 0x22, 0xa3, 0x77,
12931 0x13, 0xa3, 0x04, 0x09,
12932 0xa4, 0x01, 0x0e, 0xfe, 0x41, 0x48, 0x09, 0x46, 0x01, 0x0e, 0xfe, 0x49,
12933 0x44, 0x17, 0xfe, 0xe8,
12934 0x18, 0x77, 0x78, 0x04, 0x09, 0x48, 0x01, 0x0e, 0x07, 0x11, 0x4e, 0x09,
12935 0x5d, 0x01, 0xa8, 0x09,
12936 0x46, 0x01, 0x0e, 0x77, 0x78, 0x04, 0xfe, 0x4e, 0xe4, 0x19, 0x6b, 0xfe,
12937 0x1c, 0x19, 0x03, 0xfe,
12938 0x90, 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xfe, 0x4e, 0xe4, 0xc9,
12939 0x6b, 0xfe, 0x2e, 0x19,
12940 0x03, 0xfe, 0x92, 0x00, 0xfe, 0x02, 0xe6, 0x1a, 0xe5, 0xfe, 0x4e, 0xe4,
12941 0xfe, 0x0b, 0x00, 0x6b,
12942 0xfe, 0x40, 0x19, 0x03, 0xfe, 0x94, 0x00, 0xfe, 0x02, 0xe6, 0x1f, 0xfe,
12943 0x08, 0x10, 0x03, 0xfe,
12944 0x96, 0x00, 0xfe, 0x02, 0xe6, 0x6d, 0xfe, 0x4e, 0x45, 0xea, 0xba, 0xff,
12945 0x04, 0x68, 0x54, 0xe7,
12946 0x1e, 0x6e, 0xfe, 0x08, 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c, 0xfe,
12947 0x1a, 0xf4, 0xfe, 0x00,
12948 0x04, 0xea, 0xfe, 0x48, 0xf4, 0x19, 0x7a, 0xfe, 0x74, 0x19, 0x0f, 0x19,
12949 0x04, 0x07, 0x7e, 0xfe,
12950 0x5a, 0xf0, 0xfe, 0x84, 0x19, 0x25, 0xfe, 0x09, 0x00, 0xfe, 0x34, 0x10,
12951 0x07, 0x1a, 0xfe, 0x5a,
12952 0xf0, 0xfe, 0x92, 0x19, 0x25, 0xca, 0xfe, 0x26, 0x10, 0x07, 0x19, 0x66,
12953 0x25, 0x6d, 0xe5, 0x07,
12954 0x0a, 0x66, 0x25, 0x9e, 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x66, 0x25, 0x59,
12955 0xa9, 0xb8, 0x04, 0x15,
12956 0xfe, 0x09, 0x00, 0x01, 0x36, 0xfe, 0x04, 0xfe, 0x81, 0x03, 0x83, 0xfe,
12957 0x40, 0x5c, 0x04, 0x1c,
12958 0xf7, 0xfe, 0x14, 0xf0, 0x0b, 0x27, 0xfe, 0xd6, 0x19, 0x1c, 0xf7, 0x7b,
12959 0xf7, 0xfe, 0x82, 0xf0,
12960 0xfe, 0xda, 0x19, 0x04, 0xff, 0xcc, 0x00, 0x00,
1da177e4
LT
12961};
12962
27c868c2
MW
12963static unsigned short _adv_asc38C0800_size = sizeof(_adv_asc38C0800_buf); /* 0x14E1 */
12964static ADV_DCNT _adv_asc38C0800_chksum = 0x050D3FD8UL; /* Expanded little-endian checksum. */
1da177e4
LT
12965
12966/* Microcode buffer is kept after initialization for error recovery. */
27c868c2
MW
12967static unsigned char _adv_asc38C1600_buf[] = {
12968 0x00, 0x00, 0x00, 0xf2, 0x00, 0x16, 0x00, 0xfc, 0x00, 0x10, 0x00, 0xf0,
12969 0x18, 0xe4, 0x01, 0x00,
12970 0x04, 0x1e, 0x48, 0xe4, 0x03, 0xf6, 0xf7, 0x13, 0x2e, 0x1e, 0x02, 0x00,
12971 0x07, 0x17, 0xc0, 0x5f,
12972 0x00, 0xfa, 0xff, 0xff, 0x04, 0x00, 0x00, 0xf6, 0x09, 0xe7, 0x82, 0xe7,
12973 0x85, 0xf0, 0x86, 0xf0,
12974 0x4e, 0x10, 0x9e, 0xe7, 0xff, 0x00, 0x55, 0xf0, 0x01, 0xf6, 0x03, 0x00,
12975 0x98, 0x57, 0x01, 0xe6,
12976 0x00, 0xea, 0x00, 0xec, 0x01, 0xfa, 0x18, 0xf4, 0x08, 0x00, 0xf0, 0x1d,
12977 0x38, 0x54, 0x32, 0xf0,
12978 0x10, 0x00, 0xc2, 0x0e, 0x1e, 0xf0, 0xd5, 0xf0, 0xbc, 0x00, 0x4b, 0xe4,
12979 0x00, 0xe6, 0xb1, 0xf0,
12980 0xb4, 0x00, 0x02, 0x13, 0x3e, 0x1c, 0xc8, 0x47, 0x3e, 0x00, 0xd8, 0x01,
12981 0x06, 0x13, 0x0c, 0x1c,
12982 0x5e, 0x1e, 0x00, 0x57, 0xc8, 0x57, 0x01, 0xfc, 0xbc, 0x0e, 0xa2, 0x12,
12983 0xb9, 0x54, 0x00, 0x80,
12984 0x62, 0x0a, 0x5a, 0x12, 0xc8, 0x15, 0x3e, 0x1e, 0x18, 0x40, 0xbd, 0x56,
12985 0x03, 0xe6, 0x01, 0xea,
12986 0x5c, 0xf0, 0x0f, 0x00, 0x20, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12,
12987 0x04, 0x13, 0xbb, 0x55,
12988 0x3c, 0x56, 0x3e, 0x57, 0x03, 0x58, 0x4a, 0xe4, 0x40, 0x00, 0xb6, 0x00,
12989 0xbb, 0x00, 0xc0, 0x00,
12990 0x00, 0x01, 0x01, 0x01, 0x3e, 0x01, 0x58, 0x0a, 0x44, 0x10, 0x0a, 0x12,
12991 0x4c, 0x1c, 0x4e, 0x1c,
12992 0x02, 0x4a, 0x30, 0xe4, 0x05, 0xe6, 0x0c, 0x00, 0x3c, 0x00, 0x80, 0x00,
12993 0x24, 0x01, 0x3c, 0x01,
12994 0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01, 0x74, 0x01, 0x76, 0x01,
12995 0x78, 0x01, 0x7c, 0x01,
12996 0xc6, 0x0e, 0x0c, 0x10, 0xac, 0x12, 0xae, 0x12, 0x16, 0x1a, 0x32, 0x1c,
12997 0x6e, 0x1e, 0x02, 0x48,
12998 0x3a, 0x55, 0xc9, 0x57, 0x02, 0xee, 0x5b, 0xf0, 0x03, 0xf7, 0x06, 0xf7,
12999 0x03, 0xfc, 0x06, 0x00,
13000 0x1e, 0x00, 0xbe, 0x00, 0xe1, 0x00, 0x0c, 0x12, 0x18, 0x1a, 0x70, 0x1a,
13001 0x30, 0x1c, 0x38, 0x1c,
13002 0x10, 0x44, 0x00, 0x4c, 0xb0, 0x57, 0x40, 0x5c, 0x4d, 0xe4, 0x04, 0xea,
13003 0x5d, 0xf0, 0xa7, 0xf0,
13004 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x09, 0x00, 0x19, 0x00, 0x32, 0x00,
13005 0x33, 0x00, 0x34, 0x00,
13006 0x36, 0x00, 0x98, 0x00, 0x9e, 0x00, 0xcc, 0x00, 0x20, 0x01, 0x4e, 0x01,
13007 0x79, 0x01, 0x3c, 0x09,
13008 0x68, 0x0d, 0x02, 0x10, 0x04, 0x10, 0x3a, 0x10, 0x08, 0x12, 0x0a, 0x13,
13009 0x40, 0x16, 0x50, 0x16,
13010 0x00, 0x17, 0x4a, 0x19, 0x00, 0x4e, 0x00, 0x54, 0x01, 0x58, 0x00, 0xdc,
13011 0x05, 0xf0, 0x09, 0xf0,
13012 0x59, 0xf0, 0xb8, 0xf0, 0x48, 0xf4, 0x0e, 0xf7, 0x0a, 0x00, 0x9b, 0x00,
13013 0x9c, 0x00, 0xa4, 0x00,
13014 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe7, 0x00, 0xf0, 0x03, 0x69, 0x08,
13015 0xe9, 0x09, 0x5c, 0x0c,
13016 0xb6, 0x12, 0xbc, 0x19, 0xd8, 0x1b, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c,
13017 0x42, 0x1d, 0x08, 0x44,
13018 0x38, 0x44, 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46, 0x89, 0x48, 0x68, 0x54,
13019 0x83, 0x55, 0x83, 0x59,
13020 0x31, 0xe4, 0x02, 0xe6, 0x07, 0xf0, 0x08, 0xf0, 0x0b, 0xf0, 0x0c, 0xf0,
13021 0x4b, 0xf4, 0x04, 0xf8,
13022 0x05, 0xf8, 0x02, 0xfa, 0x03, 0xfa, 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00,
13023 0xa8, 0x00, 0xaa, 0x00,
13024 0xb9, 0x00, 0xe0, 0x00, 0xe5, 0x00, 0x22, 0x01, 0x26, 0x01, 0x60, 0x01,
13025 0x7a, 0x01, 0x82, 0x01,
13026 0xc8, 0x01, 0xca, 0x01, 0x86, 0x02, 0x6a, 0x03, 0x18, 0x05, 0xb2, 0x07,
13027 0x68, 0x08, 0x10, 0x0d,
13028 0x06, 0x10, 0x0a, 0x10, 0x0e, 0x10, 0x12, 0x10, 0x60, 0x10, 0xed, 0x10,
13029 0xf3, 0x10, 0x06, 0x12,
13030 0x10, 0x12, 0x1e, 0x12, 0x0c, 0x13, 0x0e, 0x13, 0x10, 0x13, 0xfe, 0x9c,
13031 0xf0, 0x35, 0x05, 0xfe,
13032 0xec, 0x0e, 0xff, 0x10, 0x00, 0x00, 0xe9, 0xfe, 0x34, 0x1f, 0x00, 0xe8,
13033 0xfe, 0x88, 0x01, 0xff,
13034 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
13035 0x00, 0xfe, 0x57, 0x24,
13036 0x00, 0xfe, 0x4c, 0x00, 0x65, 0xff, 0x04, 0x00, 0x00, 0x1a, 0xff, 0x09,
13037 0x00, 0x00, 0xff, 0x08,
13038 0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10,
13039 0xff, 0xff, 0xff, 0x13,
13040 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
13041 0xfe, 0x04, 0xf7, 0xe8,
13042 0x37, 0x7d, 0x0d, 0x01, 0xfe, 0x4a, 0x11, 0xfe, 0x04, 0xf7, 0xe8, 0x7d,
13043 0x0d, 0x51, 0x37, 0xfe,
13044 0x3d, 0xf0, 0xfe, 0x0c, 0x02, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x91, 0xf0,
13045 0xfe, 0xf8, 0x01, 0xfe,
13046 0x90, 0xf0, 0xfe, 0xf8, 0x01, 0xfe, 0x8f, 0xf0, 0xbc, 0x03, 0x67, 0x4d,
13047 0x05, 0xfe, 0x08, 0x0f,
13048 0x01, 0xfe, 0x78, 0x0f, 0xfe, 0xdd, 0x12, 0x05, 0xfe, 0x0e, 0x03, 0xfe,
13049 0x28, 0x1c, 0x03, 0xfe,
13050 0xa6, 0x00, 0xfe, 0xd1, 0x12, 0x3e, 0x22, 0xfe, 0xa6, 0x00, 0xac, 0xfe,
13051 0x48, 0xf0, 0xfe, 0x90,
13052 0x02, 0xfe, 0x49, 0xf0, 0xfe, 0xaa, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc8,
13053 0x02, 0xfe, 0x46, 0xf0,
13054 0xfe, 0x5a, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x60, 0x02, 0xfe, 0x43, 0xf0,
13055 0xfe, 0x4e, 0x02, 0xfe,
13056 0x44, 0xf0, 0xfe, 0x52, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x56, 0x02, 0x1c,
13057 0x0d, 0xa2, 0x1c, 0x07,
13058 0x22, 0xb7, 0x05, 0x35, 0xfe, 0x00, 0x1c, 0xfe, 0xf1, 0x10, 0xfe, 0x02,
13059 0x1c, 0xf5, 0xfe, 0x1e,
13060 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0x5f, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc,
13061 0xde, 0x0a, 0x81, 0x01,
13062 0xa3, 0x05, 0x35, 0x1f, 0x95, 0x47, 0xb8, 0x01, 0xfe, 0xe4, 0x11, 0x0a,
13063 0x81, 0x01, 0x5c, 0xfe,
13064 0xbd, 0x10, 0x0a, 0x81, 0x01, 0x5c, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c,
13065 0xfe, 0x58, 0x1c, 0x1c,
13066 0x07, 0x22, 0xb7, 0x37, 0x2a, 0x35, 0xfe, 0x3d, 0xf0, 0xfe, 0x0c, 0x02,
13067 0x2b, 0xfe, 0x9e, 0x02,
13068 0xfe, 0x5a, 0x1c, 0xfe, 0x12, 0x1c, 0xfe, 0x14, 0x1c, 0x1f, 0xfe, 0x30,
13069 0x00, 0x47, 0xb8, 0x01,
13070 0xfe, 0xd4, 0x11, 0x1c, 0x07, 0x22, 0xb7, 0x05, 0xe9, 0x21, 0x2c, 0x09,
13071 0x1a, 0x31, 0xfe, 0x69,
13072 0x10, 0x1c, 0x07, 0x22, 0xb7, 0xfe, 0x04, 0xec, 0x2c, 0x60, 0x01, 0xfe,
13073 0x1e, 0x1e, 0x20, 0x2c,
13074 0xfe, 0x05, 0xf6, 0xde, 0x01, 0xfe, 0x62, 0x1b, 0x01, 0x0c, 0x61, 0x4a,
13075 0x44, 0x15, 0x56, 0x51,
13076 0x01, 0xfe, 0x9e, 0x1e, 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x0a, 0x57,
13077 0x01, 0x18, 0x09, 0x00,
13078 0x36, 0x01, 0x85, 0xfe, 0x18, 0x10, 0xfe, 0x41, 0x58, 0x0a, 0xba, 0x01,
13079 0x18, 0xfe, 0xc8, 0x54,
13080 0x7b, 0xfe, 0x1c, 0x03, 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x37, 0x60,
13081 0xfe, 0x02, 0xe8, 0x30,
13082 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, 0xfe, 0x77, 0x57, 0xfe, 0x27, 0xf0,
13083 0xfe, 0xe4, 0x01, 0xfe,
13084 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x40, 0x1c, 0x2a, 0xeb, 0xfe,
13085 0x26, 0xf0, 0xfe, 0x66,
13086 0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x54, 0x03, 0xfe, 0x11, 0xf0, 0xbc, 0xfe,
13087 0xef, 0x10, 0xfe, 0x9f,
13088 0xf0, 0xfe, 0x74, 0x03, 0xfe, 0x46, 0x1c, 0x19, 0xfe, 0x11, 0x00, 0x05,
13089 0x70, 0x37, 0xfe, 0x48,
13090 0x1c, 0xfe, 0x46, 0x1c, 0x01, 0x0c, 0x06, 0x28, 0xfe, 0x18, 0x13, 0x26,
13091 0x21, 0xb9, 0xc7, 0x20,
13092 0xb9, 0x0a, 0x57, 0x01, 0x18, 0xc7, 0x89, 0x01, 0xfe, 0xc8, 0x1a, 0x15,
13093 0xe1, 0x2a, 0xeb, 0xfe,
13094 0x01, 0xf0, 0xeb, 0xfe, 0x82, 0xf0, 0xfe, 0xa4, 0x03, 0xfe, 0x9c, 0x32,
13095 0x15, 0xfe, 0xe4, 0x00,
13096 0x2f, 0xfe, 0xb6, 0x03, 0x2a, 0x3c, 0x16, 0xfe, 0xc6, 0x03, 0x01, 0x41,
13097 0xfe, 0x06, 0xf0, 0xfe,
13098 0xd6, 0x03, 0xaf, 0xa0, 0xfe, 0x0a, 0xf0, 0xfe, 0xa2, 0x07, 0x05, 0x29,
13099 0x03, 0x81, 0x1e, 0x1b,
13100 0xfe, 0x24, 0x05, 0x1f, 0x63, 0x01, 0x42, 0x8f, 0xfe, 0x70, 0x02, 0x05,
13101 0xea, 0xfe, 0x46, 0x1c,
13102 0x37, 0x7d, 0x1d, 0xfe, 0x67, 0x1b, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57,
13103 0xfe, 0x48, 0x1c, 0x75,
13104 0x01, 0xa6, 0x86, 0x0a, 0x57, 0x01, 0x18, 0x09, 0x00, 0x1b, 0xec, 0x0a,
13105 0xe1, 0x01, 0x18, 0x77,
13106 0x50, 0x40, 0x8d, 0x30, 0x03, 0x81, 0x1e, 0xf8, 0x1f, 0x63, 0x01, 0x42,
13107 0x8f, 0xfe, 0x70, 0x02,
13108 0x05, 0xea, 0xd7, 0x99, 0xd8, 0x9c, 0x2a, 0x29, 0x2f, 0xfe, 0x4e, 0x04,
13109 0x16, 0xfe, 0x4a, 0x04,
13110 0x7e, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x54, 0x12, 0x32, 0xff,
13111 0x02, 0x00, 0x10, 0x01,
13112 0x08, 0x16, 0xfe, 0x02, 0x05, 0x32, 0x01, 0x08, 0x16, 0x29, 0x27, 0x25,
13113 0xee, 0xfe, 0x4c, 0x44,
13114 0xfe, 0x58, 0x12, 0x50, 0xfe, 0x44, 0x48, 0x13, 0x34, 0xfe, 0x4c, 0x54,
13115 0x7b, 0xec, 0x60, 0x8d,
13116 0x30, 0x01, 0xfe, 0x4e, 0x1e, 0xfe, 0x48, 0x47, 0xfe, 0x7c, 0x13, 0x01,
13117 0x0c, 0x06, 0x28, 0xfe,
13118 0x32, 0x13, 0x01, 0x43, 0x09, 0x9b, 0xfe, 0x68, 0x13, 0xfe, 0x26, 0x10,
13119 0x13, 0x34, 0xfe, 0x4c,
13120 0x54, 0x7b, 0xec, 0x01, 0xfe, 0x4e, 0x1e, 0xfe, 0x48, 0x47, 0xfe, 0x54,
13121 0x13, 0x01, 0x0c, 0x06,
13122 0x28, 0xa5, 0x01, 0x43, 0x09, 0x9b, 0xfe, 0x40, 0x13, 0x01, 0x0c, 0x06,
13123 0x28, 0xf9, 0x1f, 0x7f,
13124 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, 0x0d, 0x00, 0x01, 0x42, 0x8f,
13125 0xfe, 0xa4, 0x0e, 0x05,
13126 0x29, 0x32, 0x15, 0xfe, 0xe6, 0x00, 0x0f, 0xfe, 0x1c, 0x90, 0x04, 0xfe,
13127 0x9c, 0x93, 0x3a, 0x0b,
13128 0x0e, 0x8b, 0x02, 0x1f, 0x7f, 0x01, 0x42, 0x05, 0x35, 0xfe, 0x42, 0x5b,
13129 0x7d, 0x1d, 0xfe, 0x46,
13130 0x59, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0x0f, 0xfe, 0x87, 0x80, 0x04,
13131 0xfe, 0x87, 0x83, 0xfe,
13132 0xc9, 0x47, 0x0b, 0x0e, 0xd0, 0x65, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x98,
13133 0x13, 0x0f, 0xfe, 0x20,
13134 0x80, 0x04, 0xfe, 0xa0, 0x83, 0x33, 0x0b, 0x0e, 0x09, 0x1d, 0xfe, 0x84,
13135 0x12, 0x01, 0x38, 0x06,
13136 0x07, 0xfe, 0x70, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x1e, 0x1b, 0xfe, 0xda,
13137 0x05, 0xd0, 0x54, 0x01,
13138 0x38, 0x06, 0x0d, 0xfe, 0x58, 0x13, 0x03, 0xfe, 0xa0, 0x00, 0x1e, 0xfe,
13139 0x50, 0x12, 0x5e, 0xff,
13140 0x02, 0x00, 0x10, 0x2f, 0xfe, 0x90, 0x05, 0x2a, 0x3c, 0xcc, 0xff, 0x02,
13141 0x00, 0x10, 0x2f, 0xfe,
13142 0x9e, 0x05, 0x17, 0xfe, 0xf4, 0x05, 0x15, 0xfe, 0xe3, 0x00, 0x26, 0x01,
13143 0x38, 0xfe, 0x4a, 0xf0,
13144 0xfe, 0xc0, 0x05, 0xfe, 0x49, 0xf0, 0xfe, 0xba, 0x05, 0x71, 0x2e, 0xfe,
13145 0x21, 0x00, 0xf1, 0x2e,
13146 0xfe, 0x22, 0x00, 0xa2, 0x2e, 0x4a, 0xfe, 0x09, 0x48, 0xff, 0x02, 0x00,
13147 0x10, 0x2f, 0xfe, 0xd0,
13148 0x05, 0x17, 0xfe, 0xf4, 0x05, 0xfe, 0xe2, 0x08, 0x01, 0x38, 0x06, 0xfe,
13149 0x1c, 0x00, 0x4d, 0x01,
13150 0xa7, 0x2e, 0x07, 0x20, 0xe4, 0x47, 0xfe, 0x27, 0x01, 0x01, 0x0c, 0x06,
13151 0x28, 0xfe, 0x24, 0x12,
13152 0x3e, 0x01, 0x84, 0x1f, 0x7f, 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe,
13153 0x0d, 0x00, 0x01, 0x42,
13154 0x8f, 0xfe, 0xa4, 0x0e, 0x05, 0x29, 0x03, 0xe6, 0x1e, 0xfe, 0xca, 0x13,
13155 0x03, 0xb6, 0x1e, 0xfe,
13156 0x40, 0x12, 0x03, 0x66, 0x1e, 0xfe, 0x38, 0x13, 0x3e, 0x01, 0x84, 0x17,
13157 0xfe, 0x72, 0x06, 0x0a,
13158 0x07, 0x01, 0x38, 0x06, 0x24, 0xfe, 0x02, 0x12, 0x4f, 0x01, 0xfe, 0x56,
13159 0x19, 0x16, 0xfe, 0x68,
13160 0x06, 0x15, 0x82, 0x01, 0x41, 0x15, 0xe2, 0x03, 0x66, 0x8a, 0x10, 0x66,
13161 0x03, 0x9a, 0x1e, 0xfe,
13162 0x70, 0x12, 0x03, 0x55, 0x1e, 0xfe, 0x68, 0x13, 0x01, 0xc6, 0x09, 0x12,
13163 0x48, 0xfe, 0x92, 0x06,
13164 0x2e, 0x12, 0x01, 0xfe, 0xac, 0x1d, 0xfe, 0x43, 0x48, 0x62, 0x80, 0x13,
13165 0x58, 0xff, 0x02, 0x00,
13166 0x57, 0x52, 0xad, 0x23, 0x3f, 0x4e, 0x62, 0x49, 0x3e, 0x01, 0x84, 0x17,
13167 0xfe, 0xea, 0x06, 0x01,
13168 0x38, 0x06, 0x12, 0xf7, 0x45, 0x0a, 0x95, 0x01, 0xfe, 0x84, 0x19, 0x16,
13169 0xfe, 0xe0, 0x06, 0x15,
13170 0x82, 0x01, 0x41, 0x15, 0xe2, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x1c, 0x07,
13171 0x01, 0x84, 0xfe, 0xae,
13172 0x10, 0x03, 0x6f, 0x1e, 0xfe, 0x9e, 0x13, 0x3e, 0x01, 0x84, 0x03, 0x9a,
13173 0x1e, 0xfe, 0x1a, 0x12,
13174 0x01, 0x38, 0x06, 0x12, 0xfc, 0x01, 0xc6, 0x01, 0xfe, 0xac, 0x1d, 0xfe,
13175 0x43, 0x48, 0x62, 0x80,
13176 0xf0, 0x45, 0x0a, 0x95, 0x03, 0xb6, 0x1e, 0xf8, 0x01, 0x38, 0x06, 0x24,
13177 0x36, 0xfe, 0x02, 0xf6,
13178 0x07, 0x71, 0x78, 0x8c, 0x00, 0x4d, 0x62, 0x49, 0x3e, 0x2d, 0x93, 0x4e,
13179 0xd0, 0x0d, 0x17, 0xfe,
13180 0x9a, 0x07, 0x01, 0xfe, 0xc0, 0x19, 0x16, 0xfe, 0x90, 0x07, 0x26, 0x20,
13181 0x9e, 0x15, 0x82, 0x01,
13182 0x41, 0x15, 0xe2, 0x21, 0x9e, 0x09, 0x07, 0xfb, 0x03, 0xe6, 0xfe, 0x58,
13183 0x57, 0x10, 0xe6, 0x05,
13184 0xfe, 0x2a, 0x06, 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x1c, 0x07, 0x01, 0x84,
13185 0xfe, 0x9c, 0x32, 0x5f,
13186 0x75, 0x01, 0xa6, 0x86, 0x15, 0xfe, 0xe2, 0x00, 0x2f, 0xed, 0x2a, 0x3c,
13187 0xfe, 0x0a, 0xf0, 0xfe,
13188 0xce, 0x07, 0xae, 0xfe, 0x96, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x9e, 0x08,
13189 0xaf, 0xa0, 0x05, 0x29,
13190 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x2e, 0x12, 0x14, 0x1d, 0x01, 0x08, 0x14,
13191 0x00, 0x01, 0x08, 0x14,
13192 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0xfe, 0x99, 0xa4, 0x01, 0x08,
13193 0x14, 0x00, 0x05, 0xfe,
13194 0xc6, 0x09, 0x01, 0x76, 0x06, 0x12, 0xfe, 0x3a, 0x12, 0x01, 0x0c, 0x06,
13195 0x12, 0xfe, 0x30, 0x13,
13196 0x14, 0xfe, 0x1b, 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x00,
13197 0x01, 0x08, 0x14, 0x00,
13198 0x01, 0x08, 0x14, 0x07, 0x01, 0x08, 0x14, 0x00, 0x05, 0xef, 0x7c, 0x4a,
13199 0x78, 0x4f, 0x0f, 0xfe,
13200 0x9a, 0x81, 0x04, 0xfe, 0x9a, 0x83, 0xfe, 0xcb, 0x47, 0x0b, 0x0e, 0x2d,
13201 0x28, 0x48, 0xfe, 0x6c,
13202 0x08, 0x0a, 0x28, 0xfe, 0x09, 0x6f, 0xca, 0xfe, 0xca, 0x45, 0xfe, 0x32,
13203 0x12, 0x53, 0x63, 0x4e,
13204 0x7c, 0x97, 0x2f, 0xfe, 0x7e, 0x08, 0x2a, 0x3c, 0xfe, 0x0a, 0xf0, 0xfe,
13205 0x6c, 0x08, 0xaf, 0xa0,
13206 0xae, 0xfe, 0x96, 0x08, 0x05, 0x29, 0x01, 0x41, 0x05, 0xed, 0x14, 0x24,
13207 0x05, 0xed, 0xfe, 0x9c,
13208 0xf7, 0x9f, 0x01, 0xfe, 0xae, 0x1e, 0xfe, 0x18, 0x58, 0x01, 0xfe, 0xbe,
13209 0x1e, 0xfe, 0x99, 0x58,
13210 0xfe, 0x78, 0x18, 0xfe, 0xf9, 0x18, 0x8e, 0xfe, 0x16, 0x09, 0x10, 0x6a,
13211 0x22, 0x6b, 0x01, 0x0c,
13212 0x61, 0x54, 0x44, 0x21, 0x2c, 0x09, 0x1a, 0xf8, 0x77, 0x01, 0xfe, 0x7e,
13213 0x1e, 0x47, 0x2c, 0x7a,
13214 0x30, 0xf0, 0xfe, 0x83, 0xe7, 0xfe, 0x3f, 0x00, 0x71, 0xfe, 0x03, 0x40,
13215 0x01, 0x0c, 0x61, 0x65,
13216 0x44, 0x01, 0xc2, 0xc8, 0xfe, 0x1f, 0x40, 0x20, 0x6e, 0x01, 0xfe, 0x6a,
13217 0x16, 0xfe, 0x08, 0x50,
13218 0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51, 0xfe, 0xc6, 0x51, 0xfe, 0x10, 0x10,
13219 0x01, 0xfe, 0xce, 0x1e,
13220 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x01, 0xfe, 0xee, 0x1e,
13221 0x01, 0xfe, 0xfe, 0x1e,
13222 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x10, 0x4b, 0x22, 0x4c, 0xfe, 0x8a,
13223 0x10, 0x01, 0x0c, 0x06,
13224 0x54, 0xfe, 0x50, 0x12, 0x01, 0xfe, 0xae, 0x1e, 0x01, 0xfe, 0xbe, 0x1e,
13225 0x10, 0x6a, 0x22, 0x6b,
13226 0x01, 0x0c, 0x06, 0x65, 0x4e, 0x01, 0xc2, 0x0f, 0xfe, 0x1f, 0x80, 0x04,
13227 0xfe, 0x9f, 0x83, 0x33,
13228 0x0b, 0x0e, 0x20, 0x6e, 0x0f, 0xfe, 0x44, 0x90, 0x04, 0xfe, 0xc4, 0x93,
13229 0x3a, 0x0b, 0xfe, 0xc6,
13230 0x90, 0x04, 0xfe, 0xc6, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0x6c, 0x22, 0x6d,
13231 0x01, 0xfe, 0xce, 0x1e,
13232 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x0f, 0xfe, 0x40, 0x90,
13233 0x04, 0xfe, 0xc0, 0x93,
13234 0x3a, 0x0b, 0xfe, 0xc2, 0x90, 0x04, 0xfe, 0xc2, 0x93, 0x79, 0x0b, 0x0e,
13235 0x10, 0x4b, 0x22, 0x4c,
13236 0x10, 0x64, 0x22, 0x34, 0x01, 0x0c, 0x61, 0x24, 0x44, 0x37, 0x13, 0xfe,
13237 0x4e, 0x11, 0x2f, 0xfe,
13238 0xde, 0x09, 0xfe, 0x9e, 0xf0, 0xfe, 0xf2, 0x09, 0xfe, 0x01, 0x48, 0x1b,
13239 0x3c, 0x37, 0x88, 0xf5,
13240 0xd4, 0xfe, 0x1e, 0x0a, 0xd5, 0xfe, 0x42, 0x0a, 0xd2, 0xfe, 0x1e, 0x0a,
13241 0xd3, 0xfe, 0x42, 0x0a,
13242 0xae, 0xfe, 0x12, 0x0a, 0xfe, 0x06, 0xf0, 0xfe, 0x18, 0x0a, 0xaf, 0xa0,
13243 0x05, 0x29, 0x01, 0x41,
13244 0xfe, 0xc1, 0x10, 0x14, 0x24, 0xfe, 0xc1, 0x10, 0x01, 0x76, 0x06, 0x07,
13245 0xfe, 0x14, 0x12, 0x01,
13246 0x76, 0x06, 0x0d, 0x5d, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x74, 0x12, 0xfe,
13247 0x2e, 0x1c, 0x05, 0xfe,
13248 0x1a, 0x0c, 0x01, 0x76, 0x06, 0x07, 0x5d, 0x01, 0x76, 0x06, 0x0d, 0x41,
13249 0xfe, 0x2c, 0x1c, 0xfe,
13250 0xaa, 0xf0, 0xfe, 0xce, 0x0a, 0xfe, 0xac, 0xf0, 0xfe, 0x66, 0x0a, 0xfe,
13251 0x92, 0x10, 0xc4, 0xf6,
13252 0xfe, 0xad, 0xf0, 0xfe, 0x72, 0x0a, 0x05, 0xfe, 0x1a, 0x0c, 0xc5, 0xfe,
13253 0xe7, 0x10, 0xfe, 0x2b,
13254 0xf0, 0xbf, 0xfe, 0x6b, 0x18, 0x23, 0xfe, 0x00, 0xfe, 0xfe, 0x1c, 0x12,
13255 0xac, 0xfe, 0xd2, 0xf0,
13256 0xbf, 0xfe, 0x76, 0x18, 0x23, 0x1d, 0x1b, 0xbf, 0x03, 0xe3, 0x23, 0x07,
13257 0x1b, 0xbf, 0xd4, 0x5b,
13258 0xd5, 0x5b, 0xd2, 0x5b, 0xd3, 0x5b, 0xc4, 0xc5, 0xfe, 0xa9, 0x10, 0x75,
13259 0x5e, 0x32, 0x1f, 0x7f,
13260 0x01, 0x42, 0x19, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x70, 0x19, 0x98,
13261 0x05, 0x70, 0xfe, 0x74,
13262 0x18, 0x23, 0xfe, 0x00, 0xf8, 0x1b, 0x5b, 0x7d, 0x12, 0x01, 0xfe, 0x78,
13263 0x0f, 0x4d, 0x01, 0xfe,
13264 0x96, 0x1a, 0x21, 0x30, 0x77, 0x7d, 0x1d, 0x05, 0x5b, 0x01, 0x0c, 0x06,
13265 0x0d, 0x2b, 0xfe, 0xe2,
13266 0x0b, 0x01, 0x0c, 0x06, 0x54, 0xfe, 0xa6, 0x12, 0x01, 0x0c, 0x06, 0x24,
13267 0xfe, 0x88, 0x13, 0x21,
13268 0x6e, 0xc7, 0x01, 0xfe, 0x1e, 0x1f, 0x0f, 0xfe, 0x83, 0x80, 0x04, 0xfe,
13269 0x83, 0x83, 0xfe, 0xc9,
13270 0x47, 0x0b, 0x0e, 0xfe, 0xc8, 0x44, 0xfe, 0x42, 0x13, 0x0f, 0xfe, 0x04,
13271 0x91, 0x04, 0xfe, 0x84,
13272 0x93, 0xfe, 0xca, 0x57, 0x0b, 0xfe, 0x86, 0x91, 0x04, 0xfe, 0x86, 0x93,
13273 0xfe, 0xcb, 0x57, 0x0b,
13274 0x0e, 0x7a, 0x30, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x8e, 0x40, 0x03,
13275 0x6a, 0x3b, 0x6b, 0x10,
13276 0x97, 0x22, 0x98, 0xd9, 0x6a, 0xda, 0x6b, 0x01, 0xc2, 0xc8, 0x7a, 0x30,
13277 0x20, 0x6e, 0xdb, 0x64,
13278 0xdc, 0x34, 0x91, 0x6c, 0x7e, 0x6d, 0xfe, 0x44, 0x55, 0xfe, 0xe5, 0x55,
13279 0xfe, 0x04, 0xfa, 0x64,
13280 0xfe, 0x05, 0xfa, 0x34, 0x01, 0xfe, 0x6a, 0x16, 0xa3, 0x26, 0x10, 0x97,
13281 0x10, 0x98, 0x91, 0x6c,
13282 0x7e, 0x6d, 0xfe, 0x14, 0x10, 0x01, 0x0c, 0x06, 0x24, 0x1b, 0x40, 0x91,
13283 0x4b, 0x7e, 0x4c, 0x01,
13284 0x0c, 0x06, 0xfe, 0xf7, 0x00, 0x44, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x10,
13285 0x58, 0xfe, 0x91, 0x58,
13286 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x05, 0x5b, 0x01, 0x0c, 0x06, 0x24,
13287 0x1b, 0x40, 0x01, 0x0c,
13288 0x06, 0xfe, 0xf7, 0x00, 0x44, 0x78, 0x01, 0xfe, 0x8e, 0x1e, 0x4f, 0x0f,
13289 0xfe, 0x10, 0x90, 0x04,
13290 0xfe, 0x90, 0x93, 0x3a, 0x0b, 0xfe, 0x92, 0x90, 0x04, 0xfe, 0x92, 0x93,
13291 0x79, 0x0b, 0x0e, 0xfe,
13292 0xbd, 0x10, 0x01, 0x43, 0x09, 0xbb, 0x1b, 0xfe, 0x6e, 0x0a, 0x15, 0xbb,
13293 0x01, 0x0c, 0x06, 0x0d,
13294 0xfe, 0x14, 0x13, 0x03, 0x4b, 0x3b, 0x4c, 0x8e, 0xfe, 0x6e, 0x0a, 0xfe,
13295 0x0c, 0x58, 0xfe, 0x8d,
13296 0x58, 0x05, 0x5b, 0x26, 0x3e, 0x0f, 0xfe, 0x19, 0x80, 0x04, 0xfe, 0x99,
13297 0x83, 0x33, 0x0b, 0x0e,
13298 0xfe, 0xe5, 0x10, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1a, 0x12, 0xfe, 0x6c,
13299 0x19, 0xfe, 0x19, 0x41,
13300 0xfe, 0x6b, 0x18, 0xac, 0xfe, 0xd1, 0xf0, 0xef, 0x1f, 0x92, 0x01, 0x42,
13301 0x19, 0xfe, 0x44, 0x00,
13302 0xfe, 0x90, 0x10, 0xfe, 0x6c, 0x19, 0xd9, 0x4b, 0xfe, 0xed, 0x19, 0xda,
13303 0x4c, 0xfe, 0x0c, 0x51,
13304 0xfe, 0x8e, 0x51, 0xfe, 0x6b, 0x18, 0x23, 0xfe, 0x00, 0xff, 0x31, 0xfe,
13305 0x76, 0x10, 0xac, 0xfe,
13306 0xd2, 0xf0, 0xfe, 0xba, 0x0c, 0xfe, 0x76, 0x18, 0x23, 0x1d, 0x5d, 0x03,
13307 0xe3, 0x23, 0x07, 0xfe,
13308 0x08, 0x13, 0x19, 0xfe, 0x16, 0x00, 0x05, 0x70, 0xfe, 0xd1, 0xf0, 0xfe,
13309 0xcc, 0x0c, 0x1f, 0x92,
13310 0x01, 0x42, 0x19, 0xfe, 0x17, 0x00, 0x5c, 0xfe, 0xce, 0xf0, 0xfe, 0xd2,
13311 0x0c, 0xfe, 0x3e, 0x10,
13312 0xfe, 0xcd, 0xf0, 0xfe, 0xde, 0x0c, 0x19, 0xfe, 0x22, 0x00, 0x05, 0x70,
13313 0xfe, 0xcb, 0xf0, 0xfe,
13314 0xea, 0x0c, 0x19, 0xfe, 0x24, 0x00, 0x05, 0x70, 0xfe, 0xd0, 0xf0, 0xfe,
13315 0xf4, 0x0c, 0x19, 0x94,
13316 0xfe, 0x1c, 0x10, 0xfe, 0xcf, 0xf0, 0xfe, 0xfe, 0x0c, 0x19, 0x4a, 0xf3,
13317 0xfe, 0xcc, 0xf0, 0xef,
13318 0x01, 0x76, 0x06, 0x24, 0x4d, 0x19, 0xfe, 0x12, 0x00, 0x37, 0x13, 0xfe,
13319 0x4e, 0x11, 0x2f, 0xfe,
13320 0x16, 0x0d, 0xfe, 0x9e, 0xf0, 0xfe, 0x2a, 0x0d, 0xfe, 0x01, 0x48, 0x1b,
13321 0x3c, 0x37, 0x88, 0xf5,
13322 0xd4, 0x29, 0xd5, 0x29, 0xd2, 0x29, 0xd3, 0x29, 0x37, 0xfe, 0x9c, 0x32,
13323 0x2f, 0xfe, 0x3e, 0x0d,
13324 0x2a, 0x3c, 0xae, 0xfe, 0x62, 0x0d, 0xaf, 0xa0, 0xd4, 0x9f, 0xd5, 0x9f,
13325 0xd2, 0x9f, 0xd3, 0x9f,
13326 0x05, 0x29, 0x01, 0x41, 0xfe, 0xd3, 0x10, 0x15, 0xfe, 0xe8, 0x00, 0xc4,
13327 0xc5, 0x75, 0xd7, 0x99,
13328 0xd8, 0x9c, 0xfe, 0x89, 0xf0, 0x29, 0x27, 0x25, 0xbe, 0xd7, 0x99, 0xd8,
13329 0x9c, 0x2f, 0xfe, 0x8c,
13330 0x0d, 0x16, 0x29, 0x27, 0x25, 0xbd, 0xfe, 0x01, 0x48, 0xa4, 0x19, 0xfe,
13331 0x42, 0x00, 0x05, 0x70,
13332 0x90, 0x07, 0xfe, 0x81, 0x49, 0x1b, 0xfe, 0x64, 0x0e, 0x01, 0x0c, 0x06,
13333 0x0d, 0xfe, 0x44, 0x13,
13334 0x19, 0x00, 0x2d, 0x0d, 0xfe, 0x54, 0x12, 0x2d, 0xfe, 0x28, 0x00, 0x2b,
13335 0xfe, 0xda, 0x0e, 0x0a,
13336 0x57, 0x01, 0x18, 0x09, 0x00, 0x36, 0x46, 0xfe, 0x28, 0x00, 0xfe, 0xfa,
13337 0x10, 0x01, 0xfe, 0xf4,
13338 0x1c, 0x01, 0xfe, 0x00, 0x1d, 0x0a, 0xba, 0x01, 0xfe, 0x58, 0x10, 0x40,
13339 0x15, 0x56, 0x01, 0x85,
13340 0x05, 0x35, 0x19, 0xfe, 0x44, 0x00, 0x2d, 0x0d, 0xf7, 0x46, 0x0d, 0xfe,
13341 0xcc, 0x10, 0x01, 0xa7,
13342 0x46, 0x0d, 0xfe, 0xc2, 0x10, 0x01, 0xa7, 0x0f, 0xfe, 0x19, 0x82, 0x04,
13343 0xfe, 0x99, 0x83, 0xfe,
13344 0xcc, 0x47, 0x0b, 0x0e, 0xfe, 0x34, 0x46, 0xa5, 0x46, 0x0d, 0x19, 0xfe,
13345 0x43, 0x00, 0xfe, 0xa2,
13346 0x10, 0x01, 0x0c, 0x61, 0x0d, 0x44, 0x01, 0xfe, 0xf4, 0x1c, 0x01, 0xfe,
13347 0x00, 0x1d, 0x40, 0x15,
13348 0x56, 0x01, 0x85, 0x7d, 0x0d, 0x40, 0x51, 0x01, 0xfe, 0x9e, 0x1e, 0x05,
13349 0xfe, 0x3a, 0x03, 0x01,
13350 0x0c, 0x06, 0x0d, 0x5d, 0x46, 0x0d, 0x19, 0x00, 0xfe, 0x62, 0x10, 0x01,
13351 0x76, 0x06, 0x12, 0xfe,
13352 0x5c, 0x12, 0x01, 0x0c, 0x06, 0x12, 0xfe, 0x52, 0x13, 0xfe, 0x1c, 0x1c,
13353 0xfe, 0x9d, 0xf0, 0xfe,
13354 0x8e, 0x0e, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x94, 0x0e, 0x01,
13355 0x0c, 0x61, 0x12, 0x44,
13356 0xfe, 0x9f, 0x10, 0x19, 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0d, 0x4f,
13357 0xfe, 0x2e, 0x10, 0x19,
13358 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x19, 0xfe, 0x47, 0x00, 0xf1, 0x19,
13359 0xfe, 0x41, 0x00, 0xa2,
13360 0x19, 0xfe, 0x24, 0x00, 0x86, 0xc4, 0xc5, 0x75, 0x03, 0x81, 0x1e, 0x2b,
13361 0xea, 0x4f, 0xfe, 0x04,
13362 0xe6, 0x12, 0xfe, 0x9d, 0x41, 0xfe, 0x1c, 0x42, 0x40, 0x01, 0xf4, 0x05,
13363 0x35, 0xfe, 0x12, 0x1c,
13364 0x1f, 0x0d, 0x47, 0xb5, 0xc3, 0x1f, 0xfe, 0x31, 0x00, 0x47, 0xb8, 0x01,
13365 0xfe, 0xd4, 0x11, 0x05,
13366 0xe9, 0x51, 0xfe, 0x06, 0xec, 0xe0, 0xfe, 0x0e, 0x47, 0x46, 0x28, 0xfe,
13367 0xce, 0x45, 0x31, 0x51,
13368 0xfe, 0x06, 0xea, 0xe0, 0xfe, 0x47, 0x4b, 0x45, 0xfe, 0x75, 0x57, 0x03,
13369 0x67, 0xfe, 0x98, 0x56,
13370 0xfe, 0x38, 0x12, 0x0a, 0x5a, 0x01, 0x18, 0xfe, 0x44, 0x48, 0x60, 0x01,
13371 0x0c, 0x06, 0x28, 0xfe,
13372 0x18, 0x13, 0x0a, 0x57, 0x01, 0x18, 0x3e, 0xfe, 0x41, 0x58, 0x0a, 0xba,
13373 0xfe, 0xfa, 0x14, 0xfe,
13374 0x49, 0x54, 0xb0, 0xfe, 0x5e, 0x0f, 0x05, 0xfe, 0x3a, 0x03, 0x0a, 0x67,
13375 0xfe, 0xe0, 0x14, 0xfe,
13376 0x0e, 0x47, 0x46, 0x28, 0xfe, 0xce, 0x45, 0x31, 0x51, 0xfe, 0xce, 0x47,
13377 0xfe, 0xad, 0x13, 0x05,
13378 0x35, 0x21, 0x2c, 0x09, 0x1a, 0xfe, 0x98, 0x12, 0x26, 0x20, 0x96, 0x20,
13379 0xe7, 0xfe, 0x08, 0x1c,
13380 0xfe, 0x7c, 0x19, 0xfe, 0xfd, 0x19, 0xfe, 0x0a, 0x1c, 0x03, 0xe5, 0xfe,
13381 0x48, 0x55, 0xa5, 0x3b,
13382 0xfe, 0x62, 0x01, 0xfe, 0xc9, 0x55, 0x31, 0xfe, 0x74, 0x10, 0x01, 0xfe,
13383 0xf0, 0x1a, 0x03, 0xfe,
13384 0x38, 0x01, 0x3b, 0xfe, 0x3a, 0x01, 0x8e, 0xfe, 0x1e, 0x10, 0xfe, 0x02,
13385 0xec, 0xe7, 0x53, 0x00,
13386 0x36, 0xfe, 0x04, 0xec, 0x2c, 0x60, 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01,
13387 0x01, 0xfe, 0x62, 0x1b,
13388 0x01, 0xfe, 0xce, 0x1e, 0xb2, 0x11, 0xfe, 0x18, 0x13, 0xca, 0xfe, 0x02,
13389 0xea, 0xe7, 0x53, 0x92,
13390 0xfe, 0xc3, 0x13, 0x1f, 0x12, 0x47, 0xb5, 0xc3, 0xfe, 0x2a, 0x10, 0x03,
13391 0xfe, 0x38, 0x01, 0x23,
13392 0xfe, 0xf0, 0xff, 0x10, 0xe5, 0x03, 0xfe, 0x3a, 0x01, 0x10, 0xfe, 0x62,
13393 0x01, 0x01, 0xfe, 0x1e,
13394 0x1e, 0x20, 0x2c, 0x15, 0x56, 0x01, 0xfe, 0x9e, 0x1e, 0x13, 0x07, 0x02,
13395 0x26, 0x02, 0x21, 0x96,
13396 0xc7, 0x20, 0x96, 0x09, 0x92, 0xfe, 0x79, 0x13, 0x1f, 0x1d, 0x47, 0xb5,
13397 0xc3, 0xfe, 0xe1, 0x10,
13398 0xcf, 0xfe, 0x03, 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xcf,
13399 0xfe, 0x03, 0xdc, 0xfe,
13400 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xfe, 0x03, 0x57, 0xcf, 0x26, 0xfe,
13401 0x00, 0xcc, 0x02, 0xfe,
13402 0x03, 0x57, 0xcf, 0x89, 0x02, 0x01, 0x0c, 0x06, 0x4a, 0xfe, 0x4e, 0x13,
13403 0x0f, 0xfe, 0x1c, 0x80,
13404 0x04, 0xfe, 0x9c, 0x83, 0x33, 0x0b, 0x0e, 0x09, 0x07, 0xfe, 0x3a, 0x13,
13405 0x0f, 0xfe, 0x1e, 0x80,
13406 0x04, 0xfe, 0x9e, 0x83, 0x33, 0x0b, 0x0e, 0xfe, 0x2a, 0x13, 0x0f, 0xfe,
13407 0x1d, 0x80, 0x04, 0xfe,
13408 0x9d, 0x83, 0xfe, 0xf9, 0x13, 0x0e, 0xfe, 0x1c, 0x13, 0x01, 0xfe, 0xee,
13409 0x1e, 0xac, 0xfe, 0x14,
13410 0x13, 0x01, 0xfe, 0xfe, 0x1e, 0xfe, 0x81, 0x58, 0xfa, 0x01, 0xfe, 0x0e,
13411 0x1f, 0xfe, 0x30, 0xf4,
13412 0x0d, 0xfe, 0x3c, 0x50, 0xa2, 0x01, 0xfe, 0x92, 0x1b, 0x01, 0x43, 0x09,
13413 0x56, 0xfb, 0x01, 0xfe,
13414 0xc8, 0x1a, 0x01, 0x0c, 0x06, 0x28, 0xa4, 0x01, 0xfe, 0xf4, 0x1c, 0x01,
13415 0xfe, 0x00, 0x1d, 0x15,
13416 0xfe, 0xe9, 0x00, 0x01, 0x0c, 0x06, 0x4a, 0xfe, 0x4e, 0x13, 0x01, 0xfe,
13417 0x22, 0x1b, 0xfe, 0x1e,
13418 0x1c, 0x0f, 0xfe, 0x14, 0x90, 0x04, 0xfe, 0x94, 0x93, 0x3a, 0x0b, 0xfe,
13419 0x96, 0x90, 0x04, 0xfe,
13420 0x96, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0xfe, 0x64, 0x01, 0x22, 0xfe, 0x66,
13421 0x01, 0x01, 0x0c, 0x06,
13422 0x65, 0xf9, 0x0f, 0xfe, 0x03, 0x80, 0x04, 0xfe, 0x83, 0x83, 0x33, 0x0b,
13423 0x0e, 0x77, 0xfe, 0x01,
13424 0xec, 0x2c, 0xfe, 0x80, 0x40, 0x20, 0x2c, 0x7a, 0x30, 0x15, 0xdf, 0x40,
13425 0x21, 0x2c, 0xfe, 0x00,
13426 0x40, 0x8d, 0x2c, 0x02, 0xfe, 0x08, 0x1c, 0x03, 0xfe, 0xac, 0x00, 0xfe,
13427 0x06, 0x58, 0x03, 0xfe,
13428 0xae, 0x00, 0xfe, 0x07, 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58,
13429 0x03, 0xfe, 0xb2, 0x00,
13430 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c, 0x2e, 0x49, 0x20, 0xe0, 0x26, 0x10,
13431 0x66, 0x10, 0x55, 0x10,
13432 0x6f, 0x13, 0x57, 0x52, 0x4f, 0x1c, 0x28, 0xfe, 0x90, 0x4d, 0xfe, 0x91,
13433 0x54, 0x2b, 0xfe, 0x88,
13434 0x11, 0x46, 0x1a, 0x13, 0x5a, 0x52, 0x1c, 0x4a, 0xfe, 0x90, 0x4d, 0xfe,
13435 0x91, 0x54, 0x2b, 0xfe,
13436 0x9e, 0x11, 0x2e, 0x1a, 0x20, 0x2c, 0x90, 0x34, 0x60, 0x21, 0x2c, 0xfe,
13437 0x00, 0x40, 0x8d, 0x2c,
13438 0x15, 0xdf, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0xb2, 0x11, 0xfe,
13439 0x12, 0x1c, 0x75, 0xfe,
13440 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe, 0x18, 0x1c, 0x02, 0x51, 0xfe, 0x0c,
13441 0x14, 0xfe, 0x0e, 0x47,
13442 0xfe, 0x07, 0xe6, 0x28, 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x02, 0x01,
13443 0xa7, 0x90, 0x34, 0x60,
13444 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42, 0x13, 0xfe, 0x02, 0x80,
13445 0x09, 0x56, 0xfe, 0x34,
13446 0x13, 0x0a, 0x5a, 0x01, 0x18, 0xcb, 0xfe, 0x36, 0x12, 0xfe, 0x41, 0x48,
13447 0xfe, 0x45, 0x48, 0x01,
13448 0xfe, 0xb2, 0x16, 0xfe, 0x00, 0xcc, 0xcb, 0xfe, 0xf3, 0x13, 0x3f, 0x89,
13449 0x09, 0x1a, 0xa5, 0x0a,
13450 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x5c, 0x01, 0x85, 0xf2, 0x09, 0x9b, 0xa4,
13451 0xfe, 0x14, 0x56, 0xfe,
13452 0xd6, 0xf0, 0xfe, 0xec, 0x11, 0x02, 0xfe, 0x44, 0x58, 0x77, 0xfe, 0x01,
13453 0xec, 0xb8, 0xfe, 0x9e,
13454 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x12, 0x8d, 0x30, 0x01,
13455 0xf4, 0xfe, 0xdd, 0x10,
13456 0x37, 0xd7, 0x99, 0xd8, 0x9c, 0x27, 0x25, 0xee, 0x09, 0x12, 0xfe, 0x48,
13457 0x12, 0x09, 0x0d, 0xfe,
13458 0x56, 0x12, 0x09, 0x1d, 0xfe, 0x30, 0x12, 0x09, 0xdd, 0x1b, 0xfe, 0xc4,
13459 0x13, 0x09, 0xfe, 0x23,
13460 0x00, 0x1b, 0xfe, 0xd0, 0x13, 0x09, 0x07, 0x1b, 0xfe, 0x34, 0x14, 0x09,
13461 0x24, 0xfe, 0x12, 0x12,
13462 0x09, 0x00, 0x1b, 0x29, 0x1f, 0xdd, 0x01, 0x42, 0xa1, 0x32, 0x01, 0x08,
13463 0xae, 0x41, 0x02, 0x32,
13464 0xfe, 0x62, 0x08, 0x0a, 0xe1, 0x01, 0xfe, 0x58, 0x10, 0x15, 0x9b, 0x05,
13465 0x35, 0x32, 0x01, 0x43,
13466 0x09, 0xbb, 0xfe, 0xd7, 0x13, 0x91, 0x4b, 0x7e, 0x4c, 0x8e, 0xfe, 0x80,
13467 0x13, 0x01, 0x0c, 0x06,
13468 0x54, 0xfe, 0x72, 0x12, 0xdb, 0x64, 0xdc, 0x34, 0xfe, 0x44, 0x55, 0xfe,
13469 0xe5, 0x55, 0xb0, 0xfe,
13470 0x4a, 0x13, 0x21, 0x6e, 0xfe, 0x26, 0x13, 0x03, 0x97, 0x3b, 0x98, 0x8e,
13471 0xfe, 0xb6, 0x0e, 0x10,
13472 0x6a, 0x22, 0x6b, 0x26, 0x10, 0x97, 0x10, 0x98, 0x01, 0xc2, 0x2e, 0x49,
13473 0x88, 0x20, 0x6e, 0x01,
13474 0xfe, 0x6a, 0x16, 0xdb, 0x64, 0xdc, 0x34, 0xfe, 0x04, 0x55, 0xfe, 0xa5,
13475 0x55, 0xfe, 0x04, 0xfa,
13476 0x64, 0xfe, 0x05, 0xfa, 0x34, 0xfe, 0x8f, 0x10, 0x03, 0x6c, 0x3b, 0x6d,
13477 0xfe, 0x40, 0x56, 0xfe,
13478 0xe1, 0x56, 0x10, 0x6c, 0x22, 0x6d, 0x71, 0xdb, 0x64, 0xdc, 0x34, 0xfe,
13479 0x44, 0x55, 0xfe, 0xe5,
13480 0x55, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x00, 0x56, 0xfe, 0xa1, 0x56, 0x10,
13481 0x68, 0x22, 0x69, 0x01,
13482 0x0c, 0x06, 0x54, 0xf9, 0x21, 0x6e, 0xfe, 0x1f, 0x40, 0x03, 0x6a, 0x3b,
13483 0x6b, 0xfe, 0x2c, 0x50,
13484 0xfe, 0xae, 0x50, 0x03, 0x6c, 0x3b, 0x6d, 0xfe, 0x44, 0x50, 0xfe, 0xc6,
13485 0x50, 0x03, 0x68, 0x3b,
13486 0x69, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x03, 0x4b, 0x3b, 0x4c, 0xfe,
13487 0x40, 0x50, 0xfe, 0xc2,
13488 0x50, 0x05, 0x73, 0x2e, 0x07, 0x20, 0x9e, 0x05, 0x72, 0x32, 0x01, 0x08,
13489 0x16, 0x3d, 0x27, 0x25,
13490 0xee, 0x09, 0x07, 0x2b, 0x3d, 0x01, 0x43, 0x09, 0xbb, 0x2b, 0x72, 0x01,
13491 0xa6, 0x23, 0x3f, 0x1b,
13492 0x3d, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1e, 0x13, 0x91, 0x4b, 0x7e, 0x4c,
13493 0xfe, 0x0a, 0x55, 0x31,
13494 0xfe, 0x8b, 0x55, 0xd9, 0x4b, 0xda, 0x4c, 0xfe, 0x0c, 0x51, 0xfe, 0x8e,
13495 0x51, 0x05, 0x72, 0x01,
13496 0xfe, 0x8e, 0x1e, 0xca, 0xfe, 0x19, 0x41, 0x05, 0x72, 0x32, 0x01, 0x08,
13497 0x2a, 0x3c, 0x16, 0xc0,
13498 0x27, 0x25, 0xbe, 0x2d, 0x1d, 0xc0, 0x2d, 0x0d, 0x83, 0x2d, 0x7f, 0x1b,
13499 0xfe, 0x66, 0x15, 0x05,
13500 0x3d, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0xc0, 0x27, 0x25, 0xbd, 0x09, 0x1d,
13501 0x2b, 0x3d, 0x01, 0x08,
13502 0x16, 0xc0, 0x27, 0x25, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, 0x50, 0x03,
13503 0xb6, 0x1e, 0x83, 0x01,
13504 0x38, 0x06, 0x24, 0x31, 0xa1, 0xfe, 0xbb, 0x45, 0x2d, 0x00, 0xa4, 0x46,
13505 0x07, 0x90, 0x3f, 0x01,
13506 0xfe, 0xf8, 0x15, 0x01, 0xa6, 0x86, 0xfe, 0x4b, 0x45, 0xfe, 0x20, 0x13,
13507 0x01, 0x43, 0x09, 0x82,
13508 0xfe, 0x16, 0x13, 0x03, 0x9a, 0x1e, 0x5d, 0x03, 0x55, 0x1e, 0x31, 0x5e,
13509 0x05, 0x72, 0xfe, 0xc0,
13510 0x5d, 0x01, 0xa7, 0xfe, 0x03, 0x17, 0x03, 0x66, 0x8a, 0x10, 0x66, 0x5e,
13511 0x32, 0x01, 0x08, 0x17,
13512 0x73, 0x01, 0xfe, 0x56, 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16,
13513 0x3d, 0x27, 0x25, 0xbd,
13514 0x09, 0x07, 0x2b, 0x3d, 0x01, 0xfe, 0xbe, 0x16, 0xfe, 0x42, 0x58, 0xfe,
13515 0xe8, 0x14, 0x01, 0xa6,
13516 0x86, 0xfe, 0x4a, 0xf4, 0x0d, 0x1b, 0x3d, 0xfe, 0x4a, 0xf4, 0x07, 0xfe,
13517 0x0e, 0x12, 0x01, 0x43,
13518 0x09, 0x82, 0x4e, 0x05, 0x72, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x5e, 0x32,
13519 0x01, 0x08, 0x17, 0x73,
13520 0x01, 0xfe, 0x84, 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0x3d,
13521 0x27, 0x25, 0xbd, 0x09,
13522 0x12, 0x2b, 0x3d, 0x01, 0xfe, 0xe8, 0x17, 0x8b, 0xfe, 0xaa, 0x14, 0xfe,
13523 0xb6, 0x14, 0x86, 0xa8,
13524 0xb2, 0x0d, 0x1b, 0x3d, 0xb2, 0x07, 0xfe, 0x0e, 0x12, 0x01, 0x43, 0x09,
13525 0x82, 0x4e, 0x05, 0x72,
13526 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73, 0x01,
13527 0xfe, 0xc0, 0x19, 0x05,
13528 0x73, 0x13, 0x07, 0x2f, 0xfe, 0xcc, 0x15, 0x17, 0xfe, 0xe2, 0x15, 0x5f,
13529 0xcc, 0x01, 0x08, 0x26,
13530 0x5f, 0x02, 0x8f, 0xfe, 0xde, 0x15, 0x2a, 0xfe, 0xde, 0x15, 0x16, 0xfe,
13531 0xcc, 0x15, 0x5e, 0x32,
13532 0x01, 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52,
13533 0xad, 0x23, 0xfe, 0xff,
13534 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x02, 0x13, 0x58, 0xff, 0x02,
13535 0x00, 0x57, 0x52, 0xad,
13536 0x23, 0x3f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x02, 0x13, 0x58, 0xff,
13537 0x02, 0x00, 0x57, 0x52,
13538 0xad, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xfe, 0x00, 0x5e,
13539 0x02, 0x13, 0x58, 0xff,
13540 0x02, 0x00, 0x57, 0x52, 0xad, 0xfe, 0x0b, 0x58, 0x02, 0x0a, 0x66, 0x01,
13541 0x5c, 0x0a, 0x55, 0x01,
13542 0x5c, 0x0a, 0x6f, 0x01, 0x5c, 0x02, 0x01, 0xfe, 0x1e, 0x1f, 0x23, 0x1a,
13543 0xff, 0x03, 0x00, 0x54,
13544 0xfe, 0x00, 0xf4, 0x24, 0x52, 0x0f, 0xfe, 0x00, 0x7c, 0x04, 0xfe, 0x07,
13545 0x7c, 0x3a, 0x0b, 0x0e,
13546 0xfe, 0x00, 0x71, 0xfe, 0xf9, 0x18, 0xfe, 0x7a, 0x19, 0xfe, 0xfb, 0x19,
13547 0xfe, 0x1a, 0xf7, 0x00,
13548 0xfe, 0x1b, 0xf7, 0x00, 0x7a, 0x30, 0x10, 0x68, 0x22, 0x69, 0xd9, 0x6c,
13549 0xda, 0x6d, 0x02, 0xfe,
13550 0x62, 0x08, 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x77,
13551 0x02, 0x01, 0xc6, 0xfe,
13552 0x42, 0x48, 0x4f, 0x50, 0x45, 0x01, 0x08, 0x16, 0xfe, 0xe0, 0x17, 0x27,
13553 0x25, 0xbe, 0x01, 0x08,
13554 0x16, 0xfe, 0xe0, 0x17, 0x27, 0x25, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59,
13555 0x03, 0x9a, 0x1e, 0xfe,
13556 0xda, 0x12, 0x01, 0x38, 0x06, 0x12, 0xfe, 0xd0, 0x13, 0x26, 0x53, 0x12,
13557 0x48, 0xfe, 0x08, 0x17,
13558 0xd1, 0x12, 0x53, 0x12, 0xfe, 0x1e, 0x13, 0x2d, 0xb4, 0x7b, 0xfe, 0x26,
13559 0x17, 0x4d, 0x13, 0x07,
13560 0x1c, 0xb4, 0x90, 0x04, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xf1,
13561 0xff, 0x02, 0x83, 0x55,
13562 0x53, 0x1d, 0xfe, 0x12, 0x13, 0xd6, 0xfe, 0x30, 0x00, 0xb0, 0xfe, 0x80,
13563 0x17, 0x1c, 0x63, 0x13,
13564 0x07, 0xfe, 0x56, 0x10, 0x53, 0x0d, 0xfe, 0x16, 0x13, 0xd6, 0xfe, 0x64,
13565 0x00, 0xb0, 0xfe, 0x80,
13566 0x17, 0x0a, 0xfe, 0x64, 0x00, 0x1c, 0x94, 0x13, 0x07, 0xfe, 0x28, 0x10,
13567 0x53, 0x07, 0xfe, 0x60,
13568 0x13, 0xd6, 0xfe, 0xc8, 0x00, 0xb0, 0xfe, 0x80, 0x17, 0x0a, 0xfe, 0xc8,
13569 0x00, 0x1c, 0x95, 0x13,
13570 0x07, 0x71, 0xd6, 0xfe, 0x90, 0x01, 0x48, 0xfe, 0x8c, 0x17, 0x45, 0xf3,
13571 0xfe, 0x43, 0xf4, 0x96,
13572 0xfe, 0x56, 0xf0, 0xfe, 0x9e, 0x17, 0xfe, 0x04, 0xf4, 0x58, 0xfe, 0x43,
13573 0xf4, 0x94, 0xf6, 0x8b,
13574 0x01, 0xfe, 0x24, 0x16, 0x23, 0x3f, 0xfc, 0xa8, 0x8c, 0x49, 0x48, 0xfe,
13575 0xda, 0x17, 0x62, 0x49,
13576 0xfe, 0x1c, 0x10, 0xa8, 0x8c, 0x80, 0x48, 0xfe, 0xda, 0x17, 0x62, 0x80,
13577 0x71, 0x50, 0x26, 0xfe,
13578 0x4d, 0xf4, 0x00, 0xf7, 0x45, 0x13, 0x07, 0xfe, 0xb4, 0x56, 0xfe, 0xc3,
13579 0x58, 0x02, 0x50, 0x13,
13580 0x0d, 0x02, 0x50, 0x3e, 0x78, 0x4f, 0x45, 0x01, 0x08, 0x16, 0xa9, 0x27,
13581 0x25, 0xbe, 0xfe, 0x03,
13582 0xea, 0xfe, 0x7e, 0x01, 0x01, 0x08, 0x16, 0xa9, 0x27, 0x25, 0xfe, 0xe9,
13583 0x0a, 0x01, 0x08, 0x16,
13584 0xa9, 0x27, 0x25, 0xfe, 0xe9, 0x0a, 0xfe, 0x05, 0xea, 0xfe, 0x7f, 0x01,
13585 0x01, 0x08, 0x16, 0xa9,
13586 0x27, 0x25, 0xfe, 0x69, 0x09, 0xfe, 0x02, 0xea, 0xfe, 0x80, 0x01, 0x01,
13587 0x08, 0x16, 0xa9, 0x27,
13588 0x25, 0xfe, 0xe8, 0x08, 0x47, 0xfe, 0x81, 0x01, 0x03, 0xb6, 0x1e, 0x83,
13589 0x01, 0x38, 0x06, 0x24,
13590 0x31, 0xa2, 0x78, 0xf2, 0x53, 0x07, 0x36, 0xfe, 0x34, 0xf4, 0x3f, 0xa1,
13591 0x78, 0x03, 0x9a, 0x1e,
13592 0x83, 0x01, 0x38, 0x06, 0x12, 0x31, 0xf0, 0x4f, 0x45, 0xfe, 0x90, 0x10,
13593 0xfe, 0x40, 0x5a, 0x23,
13594 0x3f, 0xfb, 0x8c, 0x49, 0x48, 0xfe, 0xaa, 0x18, 0x62, 0x49, 0x71, 0x8c,
13595 0x80, 0x48, 0xfe, 0xaa,
13596 0x18, 0x62, 0x80, 0xfe, 0xb4, 0x56, 0xfe, 0x40, 0x5d, 0x01, 0xc6, 0x01,
13597 0xfe, 0xac, 0x1d, 0xfe,
13598 0x02, 0x17, 0xfe, 0xc8, 0x45, 0xfe, 0x5a, 0xf0, 0xfe, 0xc0, 0x18, 0xfe,
13599 0x43, 0x48, 0x2d, 0x93,
13600 0x36, 0xfe, 0x34, 0xf4, 0xfe, 0x00, 0x11, 0xfe, 0x40, 0x10, 0x2d, 0xb4,
13601 0x36, 0xfe, 0x34, 0xf4,
13602 0x04, 0xfe, 0x34, 0x10, 0x2d, 0xfe, 0x0b, 0x00, 0x36, 0x46, 0x63, 0xfe,
13603 0x28, 0x10, 0xfe, 0xc0,
13604 0x49, 0xff, 0x02, 0x00, 0x54, 0xb2, 0xfe, 0x90, 0x01, 0x48, 0xfe, 0xfa,
13605 0x18, 0x45, 0xfe, 0x1c,
13606 0xf4, 0x3f, 0xf3, 0xfe, 0x40, 0xf4, 0x96, 0xfe, 0x56, 0xf0, 0xfe, 0x0c,
13607 0x19, 0xfe, 0x04, 0xf4,
13608 0x58, 0xfe, 0x40, 0xf4, 0x94, 0xf6, 0x3e, 0x2d, 0x93, 0x4e, 0xd0, 0x0d,
13609 0x21, 0xfe, 0x7f, 0x01,
13610 0xfe, 0xc8, 0x46, 0xfe, 0x24, 0x13, 0x8c, 0x00, 0x5d, 0x26, 0x21, 0xfe,
13611 0x7e, 0x01, 0xfe, 0xc8,
13612 0x45, 0xfe, 0x14, 0x13, 0x21, 0xfe, 0x80, 0x01, 0xfe, 0x48, 0x45, 0xfa,
13613 0x21, 0xfe, 0x81, 0x01,
13614 0xfe, 0xc8, 0x44, 0x4e, 0x26, 0x02, 0x13, 0x07, 0x02, 0x78, 0x45, 0x50,
13615 0x13, 0x0d, 0x02, 0x14,
13616 0x07, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x14, 0x0d, 0x01, 0x08, 0x17,
13617 0xfe, 0x82, 0x19, 0x14,
13618 0x1d, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x5f, 0xfe, 0x89, 0x49, 0x01,
13619 0x08, 0x02, 0x14, 0x07,
13620 0x01, 0x08, 0x17, 0xc1, 0x14, 0x1d, 0x01, 0x08, 0x17, 0xc1, 0x14, 0x07,
13621 0x01, 0x08, 0x17, 0xc1,
13622 0xfe, 0x89, 0x49, 0x01, 0x08, 0x17, 0xc1, 0x5f, 0xfe, 0x89, 0x4a, 0x01,
13623 0x08, 0x02, 0x50, 0x02,
13624 0x14, 0x07, 0x01, 0x08, 0x17, 0x74, 0x14, 0x7f, 0x01, 0x08, 0x17, 0x74,
13625 0x14, 0x12, 0x01, 0x08,
13626 0x17, 0x74, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x17, 0x74, 0x14, 0x00, 0x01,
13627 0x08, 0x17, 0x74, 0xfe,
13628 0x89, 0x4a, 0x01, 0x08, 0x17, 0x74, 0xfe, 0x09, 0x49, 0x01, 0x08, 0x17,
13629 0x74, 0x5f, 0xcc, 0x01,
13630 0x08, 0x02, 0x21, 0xe4, 0x09, 0x07, 0xfe, 0x4c, 0x13, 0xc8, 0x20, 0xe4,
13631 0xfe, 0x49, 0xf4, 0x00,
13632 0x4d, 0x5f, 0xa1, 0x5e, 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xcc, 0xff,
13633 0x02, 0x00, 0x10, 0x2f,
13634 0xfe, 0x3e, 0x1a, 0x01, 0x43, 0x09, 0xfe, 0xe3, 0x00, 0xfe, 0x22, 0x13,
13635 0x16, 0xfe, 0x64, 0x1a,
13636 0x26, 0x20, 0x9e, 0x01, 0x41, 0x21, 0x9e, 0x09, 0x07, 0x5d, 0x01, 0x0c,
13637 0x61, 0x07, 0x44, 0x02,
13638 0x0a, 0x5a, 0x01, 0x18, 0xfe, 0x00, 0x40, 0xaa, 0x09, 0x1a, 0xfe, 0x12,
13639 0x13, 0x0a, 0x9d, 0x01,
13640 0x18, 0xaa, 0x0a, 0x67, 0x01, 0xa3, 0x02, 0x0a, 0x9d, 0x01, 0x18, 0xaa,
13641 0xfe, 0x80, 0xe7, 0x1a,
13642 0x09, 0x1a, 0x5d, 0xfe, 0x45, 0x58, 0x01, 0xfe, 0xb2, 0x16, 0xaa, 0x02,
13643 0x0a, 0x5a, 0x01, 0x18,
13644 0xaa, 0x0a, 0x67, 0x01, 0xa3, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x01, 0xfe,
13645 0x7e, 0x1e, 0xfe, 0x80,
13646 0x4c, 0xfe, 0x49, 0xe4, 0x1a, 0xfe, 0x12, 0x13, 0x0a, 0x9d, 0x01, 0x18,
13647 0xfe, 0x80, 0x4c, 0x0a,
13648 0x67, 0x01, 0x5c, 0x02, 0x1c, 0x1a, 0x87, 0x7c, 0xe5, 0xfe, 0x18, 0xdf,
13649 0xfe, 0x19, 0xde, 0xfe,
13650 0x24, 0x1c, 0xfe, 0x1d, 0xf7, 0x28, 0xb1, 0xfe, 0x04, 0x1b, 0x01, 0xfe,
13651 0x2a, 0x1c, 0xfa, 0xb3,
13652 0x28, 0x7c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x02, 0xc9, 0x2b, 0xfe,
13653 0xf4, 0x1a, 0xfe, 0xfa,
13654 0x10, 0x1c, 0x1a, 0x87, 0x03, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x24,
13655 0xfe, 0x18, 0x58, 0x03,
13656 0xfe, 0x66, 0x01, 0xfe, 0x19, 0x58, 0xb3, 0x24, 0x01, 0xfe, 0x0e, 0x1f,
13657 0xfe, 0x30, 0xf4, 0x07,
13658 0xfe, 0x3c, 0x50, 0x7c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c,
13659 0xf7, 0x24, 0xb1, 0xfe,
13660 0x50, 0x1b, 0xfe, 0xd4, 0x14, 0x31, 0x02, 0xc9, 0x2b, 0xfe, 0x26, 0x1b,
13661 0xfe, 0xba, 0x10, 0x1c,
13662 0x1a, 0x87, 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe,
13663 0x1d, 0xf7, 0x54, 0xb1,
13664 0xfe, 0x72, 0x1b, 0xfe, 0xb2, 0x14, 0xfc, 0xb3, 0x54, 0x7c, 0x12, 0xfe,
13665 0xaf, 0x19, 0xfe, 0x98,
13666 0xe7, 0x00, 0x02, 0xc9, 0x2b, 0xfe, 0x66, 0x1b, 0xfe, 0x8a, 0x10, 0x1c,
13667 0x1a, 0x87, 0x8b, 0x0f,
13668 0xfe, 0x30, 0x90, 0x04, 0xfe, 0xb0, 0x93, 0x3a, 0x0b, 0xfe, 0x18, 0x58,
13669 0xfe, 0x32, 0x90, 0x04,
13670 0xfe, 0xb2, 0x93, 0x3a, 0x0b, 0xfe, 0x19, 0x58, 0x0e, 0xa8, 0xb3, 0x4a,
13671 0x7c, 0x12, 0xfe, 0x0f,
13672 0x79, 0xfe, 0x1c, 0xf7, 0x4a, 0xb1, 0xfe, 0xc6, 0x1b, 0xfe, 0x5e, 0x14,
13673 0x31, 0x02, 0xc9, 0x2b,
13674 0xfe, 0x96, 0x1b, 0x5c, 0xfe, 0x02, 0xf6, 0x1a, 0x87, 0xfe, 0x18, 0xfe,
13675 0x6a, 0xfe, 0x19, 0xfe,
13676 0x6b, 0x01, 0xfe, 0x1e, 0x1f, 0xfe, 0x1d, 0xf7, 0x65, 0xb1, 0xfe, 0xee,
13677 0x1b, 0xfe, 0x36, 0x14,
13678 0xfe, 0x1c, 0x13, 0xb3, 0x65, 0x3e, 0xfe, 0x83, 0x58, 0xfe, 0xaf, 0x19,
13679 0xfe, 0x80, 0xe7, 0x1a,
13680 0xfe, 0x81, 0xe7, 0x1a, 0x15, 0xfe, 0xdd, 0x00, 0x7a, 0x30, 0x02, 0x7a,
13681 0x30, 0xfe, 0x12, 0x45,
13682 0x2b, 0xfe, 0xdc, 0x1b, 0x1f, 0x07, 0x47, 0xb5, 0xc3, 0x05, 0x35, 0xfe,
13683 0x39, 0xf0, 0x75, 0x26,
13684 0x02, 0xfe, 0x7e, 0x18, 0x23, 0x1d, 0x36, 0x13, 0x11, 0x02, 0x87, 0x03,
13685 0xe3, 0x23, 0x07, 0xfe,
13686 0xef, 0x12, 0xfe, 0xe1, 0x10, 0x90, 0x34, 0x60, 0xfe, 0x02, 0x80, 0x09,
13687 0x56, 0xfe, 0x3c, 0x13,
13688 0xfe, 0x82, 0x14, 0xfe, 0x42, 0x13, 0x51, 0xfe, 0x06, 0x83, 0x0a, 0x5a,
13689 0x01, 0x18, 0xcb, 0xfe,
13690 0x3e, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01, 0xfe, 0xb2, 0x16,
13691 0xfe, 0x00, 0xcc, 0xcb,
13692 0xfe, 0xf3, 0x13, 0x3f, 0x89, 0x09, 0x1a, 0xa5, 0x0a, 0x9d, 0x01, 0x18,
13693 0xfe, 0x80, 0x4c, 0x01,
13694 0x85, 0xfe, 0x16, 0x10, 0x09, 0x9b, 0x4e, 0xfe, 0x40, 0x14, 0xfe, 0x24,
13695 0x12, 0xfe, 0x14, 0x56,
13696 0xfe, 0xd6, 0xf0, 0xfe, 0x52, 0x1c, 0x1c, 0x0d, 0x02, 0xfe, 0x9c, 0xe7,
13697 0x0d, 0x19, 0xfe, 0x15,
13698 0x00, 0x40, 0x8d, 0x30, 0x01, 0xf4, 0x1c, 0x07, 0x02, 0x51, 0xfe, 0x06,
13699 0x83, 0xfe, 0x18, 0x80,
13700 0x61, 0x28, 0x44, 0x15, 0x56, 0x01, 0x85, 0x1c, 0x07, 0x02, 0xfe, 0x38,
13701 0x90, 0xfe, 0xba, 0x90,
13702 0x91, 0xde, 0x7e, 0xdf, 0xfe, 0x48, 0x55, 0x31, 0xfe, 0xc9, 0x55, 0x02,
13703 0x21, 0xb9, 0x88, 0x20,
13704 0xb9, 0x02, 0x0a, 0xba, 0x01, 0x18, 0xfe, 0x41, 0x48, 0x0a, 0x57, 0x01,
13705 0x18, 0xfe, 0x49, 0x44,
13706 0x1b, 0xfe, 0x1e, 0x1d, 0x88, 0x89, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x09,
13707 0x1a, 0xa4, 0x0a, 0x67,
13708 0x01, 0xa3, 0x0a, 0x57, 0x01, 0x18, 0x88, 0x89, 0x02, 0xfe, 0x4e, 0xe4,
13709 0x1d, 0x7b, 0xfe, 0x52,
13710 0x1d, 0x03, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xfe,
13711 0x4e, 0xe4, 0xdd, 0x7b,
13712 0xfe, 0x64, 0x1d, 0x03, 0xfe, 0x92, 0x00, 0xd1, 0x12, 0xfe, 0x1a, 0x10,
13713 0xfe, 0x4e, 0xe4, 0xfe,
13714 0x0b, 0x00, 0x7b, 0xfe, 0x76, 0x1d, 0x03, 0xfe, 0x94, 0x00, 0xd1, 0x24,
13715 0xfe, 0x08, 0x10, 0x03,
13716 0xfe, 0x96, 0x00, 0xd1, 0x63, 0xfe, 0x4e, 0x45, 0x83, 0xca, 0xff, 0x04,
13717 0x68, 0x54, 0xfe, 0xf1,
13718 0x10, 0x23, 0x49, 0xfe, 0x08, 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c,
13719 0xfe, 0x1a, 0xf4, 0xfe,
13720 0x00, 0x04, 0x83, 0xb2, 0x1d, 0x48, 0xfe, 0xaa, 0x1d, 0x13, 0x1d, 0x02,
13721 0x09, 0x92, 0xfe, 0x5a,
13722 0xf0, 0xfe, 0xba, 0x1d, 0x2e, 0x93, 0xfe, 0x34, 0x10, 0x09, 0x12, 0xfe,
13723 0x5a, 0xf0, 0xfe, 0xc8,
13724 0x1d, 0x2e, 0xb4, 0xfe, 0x26, 0x10, 0x09, 0x1d, 0x36, 0x2e, 0x63, 0xfe,
13725 0x1a, 0x10, 0x09, 0x0d,
13726 0x36, 0x2e, 0x94, 0xf2, 0x09, 0x07, 0x36, 0x2e, 0x95, 0xa1, 0xc8, 0x02,
13727 0x1f, 0x93, 0x01, 0x42,
13728 0xfe, 0x04, 0xfe, 0x99, 0x03, 0x9c, 0x8b, 0x02, 0x2a, 0xfe, 0x1c, 0x1e,
13729 0xfe, 0x14, 0xf0, 0x08,
13730 0x2f, 0xfe, 0x0c, 0x1e, 0x2a, 0xfe, 0x1c, 0x1e, 0x8f, 0xfe, 0x1c, 0x1e,
13731 0xfe, 0x82, 0xf0, 0xfe,
13732 0x10, 0x1e, 0x02, 0x0f, 0x3f, 0x04, 0xfe, 0x80, 0x83, 0x33, 0x0b, 0x0e,
13733 0x02, 0x0f, 0xfe, 0x18,
13734 0x80, 0x04, 0xfe, 0x98, 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x02,
13735 0x80, 0x04, 0xfe, 0x82,
13736 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06, 0x80, 0x04, 0xfe, 0x86,
13737 0x83, 0x33, 0x0b, 0x0e,
13738 0x02, 0x0f, 0xfe, 0x1b, 0x80, 0x04, 0xfe, 0x9b, 0x83, 0x33, 0x0b, 0x0e,
13739 0x02, 0x0f, 0xfe, 0x04,
13740 0x80, 0x04, 0xfe, 0x84, 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x80,
13741 0x80, 0x04, 0xfe, 0x80,
13742 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x19, 0x81, 0x04,
13743 0xfe, 0x99, 0x83, 0xfe,
13744 0xca, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06, 0x83, 0x04, 0xfe, 0x86,
13745 0x83, 0xfe, 0xce, 0x47,
13746 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x2c, 0x90, 0x04, 0xfe, 0xac, 0x93, 0x3a,
13747 0x0b, 0x0e, 0x02, 0x0f,
13748 0xfe, 0xae, 0x90, 0x04, 0xfe, 0xae, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
13749 0xfe, 0x08, 0x90, 0x04,
13750 0xfe, 0x88, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x8a, 0x90, 0x04,
13751 0xfe, 0x8a, 0x93, 0x79,
13752 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x0c, 0x90, 0x04, 0xfe, 0x8c, 0x93, 0x3a,
13753 0x0b, 0x0e, 0x02, 0x0f,
13754 0xfe, 0x8e, 0x90, 0x04, 0xfe, 0x8e, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
13755 0xfe, 0x3c, 0x90, 0x04,
13756 0xfe, 0xbc, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x8b, 0x0f, 0xfe, 0x03, 0x80,
13757 0x04, 0xfe, 0x83, 0x83,
13758 0x33, 0x0b, 0x77, 0x0e, 0xa8, 0x02, 0xff, 0x66, 0x00, 0x00,
1da177e4
LT
13759};
13760
27c868c2
MW
13761static unsigned short _adv_asc38C1600_size = sizeof(_adv_asc38C1600_buf); /* 0x1673 */
13762static ADV_DCNT _adv_asc38C1600_chksum = 0x0604EF77UL; /* Expanded little-endian checksum. */
1da177e4
LT
13763
13764/* a_init.c */
13765/*
13766 * EEPROM Configuration.
13767 *
13768 * All drivers should use this structure to set the default EEPROM
13769 * configuration. The BIOS now uses this structure when it is built.
13770 * Additional structure information can be found in a_condor.h where
13771 * the structure is defined.
13772 *
13773 * The *_Field_IsChar structs are needed to correct for endianness.
13774 * These values are read from the board 16 bits at a time directly
13775 * into the structs. Because some fields are char, the values will be
13776 * in the wrong order. The *_Field_IsChar tells when to flip the
13777 * bytes. Data read and written to PCI memory is automatically swapped
13778 * on big-endian platforms so char fields read as words are actually being
13779 * unswapped on big-endian platforms.
13780 */
27c868c2
MW
13781static ADVEEP_3550_CONFIG Default_3550_EEPROM_Config __initdata = {
13782 ADV_EEPROM_BIOS_ENABLE, /* cfg_lsw */
13783 0x0000, /* cfg_msw */
13784 0xFFFF, /* disc_enable */
13785 0xFFFF, /* wdtr_able */
13786 0xFFFF, /* sdtr_able */
13787 0xFFFF, /* start_motor */
13788 0xFFFF, /* tagqng_able */
13789 0xFFFF, /* bios_scan */
13790 0, /* scam_tolerant */
13791 7, /* adapter_scsi_id */
13792 0, /* bios_boot_delay */
13793 3, /* scsi_reset_delay */
13794 0, /* bios_id_lun */
13795 0, /* termination */
13796 0, /* reserved1 */
13797 0xFFE7, /* bios_ctrl */
13798 0xFFFF, /* ultra_able */
13799 0, /* reserved2 */
13800 ASC_DEF_MAX_HOST_QNG, /* max_host_qng */
13801 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
13802 0, /* dvc_cntl */
13803 0, /* bug_fix */
13804 0, /* serial_number_word1 */
13805 0, /* serial_number_word2 */
13806 0, /* serial_number_word3 */
13807 0, /* check_sum */
13808 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
13809 , /* oem_name[16] */
13810 0, /* dvc_err_code */
13811 0, /* adv_err_code */
13812 0, /* adv_err_addr */
13813 0, /* saved_dvc_err_code */
13814 0, /* saved_adv_err_code */
13815 0, /* saved_adv_err_addr */
13816 0 /* num_of_err */
1da177e4
LT
13817};
13818
27c868c2
MW
13819static ADVEEP_3550_CONFIG ADVEEP_3550_Config_Field_IsChar __initdata = {
13820 0, /* cfg_lsw */
13821 0, /* cfg_msw */
13822 0, /* -disc_enable */
13823 0, /* wdtr_able */
13824 0, /* sdtr_able */
13825 0, /* start_motor */
13826 0, /* tagqng_able */
13827 0, /* bios_scan */
13828 0, /* scam_tolerant */
13829 1, /* adapter_scsi_id */
13830 1, /* bios_boot_delay */
13831 1, /* scsi_reset_delay */
13832 1, /* bios_id_lun */
13833 1, /* termination */
13834 1, /* reserved1 */
13835 0, /* bios_ctrl */
13836 0, /* ultra_able */
13837 0, /* reserved2 */
13838 1, /* max_host_qng */
13839 1, /* max_dvc_qng */
13840 0, /* dvc_cntl */
13841 0, /* bug_fix */
13842 0, /* serial_number_word1 */
13843 0, /* serial_number_word2 */
13844 0, /* serial_number_word3 */
13845 0, /* check_sum */
13846 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
13847 , /* oem_name[16] */
13848 0, /* dvc_err_code */
13849 0, /* adv_err_code */
13850 0, /* adv_err_addr */
13851 0, /* saved_dvc_err_code */
13852 0, /* saved_adv_err_code */
13853 0, /* saved_adv_err_addr */
13854 0 /* num_of_err */
1da177e4
LT
13855};
13856
27c868c2
MW
13857static ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config __initdata = {
13858 ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
13859 0x0000, /* 01 cfg_msw */
13860 0xFFFF, /* 02 disc_enable */
13861 0xFFFF, /* 03 wdtr_able */
13862 0x4444, /* 04 sdtr_speed1 */
13863 0xFFFF, /* 05 start_motor */
13864 0xFFFF, /* 06 tagqng_able */
13865 0xFFFF, /* 07 bios_scan */
13866 0, /* 08 scam_tolerant */
13867 7, /* 09 adapter_scsi_id */
13868 0, /* bios_boot_delay */
13869 3, /* 10 scsi_reset_delay */
13870 0, /* bios_id_lun */
13871 0, /* 11 termination_se */
13872 0, /* termination_lvd */
13873 0xFFE7, /* 12 bios_ctrl */
13874 0x4444, /* 13 sdtr_speed2 */
13875 0x4444, /* 14 sdtr_speed3 */
13876 ASC_DEF_MAX_HOST_QNG, /* 15 max_host_qng */
13877 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
13878 0, /* 16 dvc_cntl */
13879 0x4444, /* 17 sdtr_speed4 */
13880 0, /* 18 serial_number_word1 */
13881 0, /* 19 serial_number_word2 */
13882 0, /* 20 serial_number_word3 */
13883 0, /* 21 check_sum */
13884 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
13885 , /* 22-29 oem_name[16] */
13886 0, /* 30 dvc_err_code */
13887 0, /* 31 adv_err_code */
13888 0, /* 32 adv_err_addr */
13889 0, /* 33 saved_dvc_err_code */
13890 0, /* 34 saved_adv_err_code */
13891 0, /* 35 saved_adv_err_addr */
13892 0, /* 36 reserved */
13893 0, /* 37 reserved */
13894 0, /* 38 reserved */
13895 0, /* 39 reserved */
13896 0, /* 40 reserved */
13897 0, /* 41 reserved */
13898 0, /* 42 reserved */
13899 0, /* 43 reserved */
13900 0, /* 44 reserved */
13901 0, /* 45 reserved */
13902 0, /* 46 reserved */
13903 0, /* 47 reserved */
13904 0, /* 48 reserved */
13905 0, /* 49 reserved */
13906 0, /* 50 reserved */
13907 0, /* 51 reserved */
13908 0, /* 52 reserved */
13909 0, /* 53 reserved */
13910 0, /* 54 reserved */
13911 0, /* 55 reserved */
13912 0, /* 56 cisptr_lsw */
13913 0, /* 57 cisprt_msw */
13914 PCI_VENDOR_ID_ASP, /* 58 subsysvid */
13915 PCI_DEVICE_ID_38C0800_REV1, /* 59 subsysid */
13916 0, /* 60 reserved */
13917 0, /* 61 reserved */
13918 0, /* 62 reserved */
13919 0 /* 63 reserved */
1da177e4
LT
13920};
13921
27c868c2
MW
13922static ADVEEP_38C0800_CONFIG ADVEEP_38C0800_Config_Field_IsChar __initdata = {
13923 0, /* 00 cfg_lsw */
13924 0, /* 01 cfg_msw */
13925 0, /* 02 disc_enable */
13926 0, /* 03 wdtr_able */
13927 0, /* 04 sdtr_speed1 */
13928 0, /* 05 start_motor */
13929 0, /* 06 tagqng_able */
13930 0, /* 07 bios_scan */
13931 0, /* 08 scam_tolerant */
13932 1, /* 09 adapter_scsi_id */
13933 1, /* bios_boot_delay */
13934 1, /* 10 scsi_reset_delay */
13935 1, /* bios_id_lun */
13936 1, /* 11 termination_se */
13937 1, /* termination_lvd */
13938 0, /* 12 bios_ctrl */
13939 0, /* 13 sdtr_speed2 */
13940 0, /* 14 sdtr_speed3 */
13941 1, /* 15 max_host_qng */
13942 1, /* max_dvc_qng */
13943 0, /* 16 dvc_cntl */
13944 0, /* 17 sdtr_speed4 */
13945 0, /* 18 serial_number_word1 */
13946 0, /* 19 serial_number_word2 */
13947 0, /* 20 serial_number_word3 */
13948 0, /* 21 check_sum */
13949 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
13950 , /* 22-29 oem_name[16] */
13951 0, /* 30 dvc_err_code */
13952 0, /* 31 adv_err_code */
13953 0, /* 32 adv_err_addr */
13954 0, /* 33 saved_dvc_err_code */
13955 0, /* 34 saved_adv_err_code */
13956 0, /* 35 saved_adv_err_addr */
13957 0, /* 36 reserved */
13958 0, /* 37 reserved */
13959 0, /* 38 reserved */
13960 0, /* 39 reserved */
13961 0, /* 40 reserved */
13962 0, /* 41 reserved */
13963 0, /* 42 reserved */
13964 0, /* 43 reserved */
13965 0, /* 44 reserved */
13966 0, /* 45 reserved */
13967 0, /* 46 reserved */
13968 0, /* 47 reserved */
13969 0, /* 48 reserved */
13970 0, /* 49 reserved */
13971 0, /* 50 reserved */
13972 0, /* 51 reserved */
13973 0, /* 52 reserved */
13974 0, /* 53 reserved */
13975 0, /* 54 reserved */
13976 0, /* 55 reserved */
13977 0, /* 56 cisptr_lsw */
13978 0, /* 57 cisprt_msw */
13979 0, /* 58 subsysvid */
13980 0, /* 59 subsysid */
13981 0, /* 60 reserved */
13982 0, /* 61 reserved */
13983 0, /* 62 reserved */
13984 0 /* 63 reserved */
1da177e4
LT
13985};
13986
27c868c2
MW
13987static ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config __initdata = {
13988 ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
13989 0x0000, /* 01 cfg_msw */
13990 0xFFFF, /* 02 disc_enable */
13991 0xFFFF, /* 03 wdtr_able */
13992 0x5555, /* 04 sdtr_speed1 */
13993 0xFFFF, /* 05 start_motor */
13994 0xFFFF, /* 06 tagqng_able */
13995 0xFFFF, /* 07 bios_scan */
13996 0, /* 08 scam_tolerant */
13997 7, /* 09 adapter_scsi_id */
13998 0, /* bios_boot_delay */
13999 3, /* 10 scsi_reset_delay */
14000 0, /* bios_id_lun */
14001 0, /* 11 termination_se */
14002 0, /* termination_lvd */
14003 0xFFE7, /* 12 bios_ctrl */
14004 0x5555, /* 13 sdtr_speed2 */
14005 0x5555, /* 14 sdtr_speed3 */
14006 ASC_DEF_MAX_HOST_QNG, /* 15 max_host_qng */
14007 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
14008 0, /* 16 dvc_cntl */
14009 0x5555, /* 17 sdtr_speed4 */
14010 0, /* 18 serial_number_word1 */
14011 0, /* 19 serial_number_word2 */
14012 0, /* 20 serial_number_word3 */
14013 0, /* 21 check_sum */
14014 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
14015 , /* 22-29 oem_name[16] */
14016 0, /* 30 dvc_err_code */
14017 0, /* 31 adv_err_code */
14018 0, /* 32 adv_err_addr */
14019 0, /* 33 saved_dvc_err_code */
14020 0, /* 34 saved_adv_err_code */
14021 0, /* 35 saved_adv_err_addr */
14022 0, /* 36 reserved */
14023 0, /* 37 reserved */
14024 0, /* 38 reserved */
14025 0, /* 39 reserved */
14026 0, /* 40 reserved */
14027 0, /* 41 reserved */
14028 0, /* 42 reserved */
14029 0, /* 43 reserved */
14030 0, /* 44 reserved */
14031 0, /* 45 reserved */
14032 0, /* 46 reserved */
14033 0, /* 47 reserved */
14034 0, /* 48 reserved */
14035 0, /* 49 reserved */
14036 0, /* 50 reserved */
14037 0, /* 51 reserved */
14038 0, /* 52 reserved */
14039 0, /* 53 reserved */
14040 0, /* 54 reserved */
14041 0, /* 55 reserved */
14042 0, /* 56 cisptr_lsw */
14043 0, /* 57 cisprt_msw */
14044 PCI_VENDOR_ID_ASP, /* 58 subsysvid */
14045 PCI_DEVICE_ID_38C1600_REV1, /* 59 subsysid */
14046 0, /* 60 reserved */
14047 0, /* 61 reserved */
14048 0, /* 62 reserved */
14049 0 /* 63 reserved */
1da177e4
LT
14050};
14051
27c868c2
MW
14052static ADVEEP_38C1600_CONFIG ADVEEP_38C1600_Config_Field_IsChar __initdata = {
14053 0, /* 00 cfg_lsw */
14054 0, /* 01 cfg_msw */
14055 0, /* 02 disc_enable */
14056 0, /* 03 wdtr_able */
14057 0, /* 04 sdtr_speed1 */
14058 0, /* 05 start_motor */
14059 0, /* 06 tagqng_able */
14060 0, /* 07 bios_scan */
14061 0, /* 08 scam_tolerant */
14062 1, /* 09 adapter_scsi_id */
14063 1, /* bios_boot_delay */
14064 1, /* 10 scsi_reset_delay */
14065 1, /* bios_id_lun */
14066 1, /* 11 termination_se */
14067 1, /* termination_lvd */
14068 0, /* 12 bios_ctrl */
14069 0, /* 13 sdtr_speed2 */
14070 0, /* 14 sdtr_speed3 */
14071 1, /* 15 max_host_qng */
14072 1, /* max_dvc_qng */
14073 0, /* 16 dvc_cntl */
14074 0, /* 17 sdtr_speed4 */
14075 0, /* 18 serial_number_word1 */
14076 0, /* 19 serial_number_word2 */
14077 0, /* 20 serial_number_word3 */
14078 0, /* 21 check_sum */
14079 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
14080 , /* 22-29 oem_name[16] */
14081 0, /* 30 dvc_err_code */
14082 0, /* 31 adv_err_code */
14083 0, /* 32 adv_err_addr */
14084 0, /* 33 saved_dvc_err_code */
14085 0, /* 34 saved_adv_err_code */
14086 0, /* 35 saved_adv_err_addr */
14087 0, /* 36 reserved */
14088 0, /* 37 reserved */
14089 0, /* 38 reserved */
14090 0, /* 39 reserved */
14091 0, /* 40 reserved */
14092 0, /* 41 reserved */
14093 0, /* 42 reserved */
14094 0, /* 43 reserved */
14095 0, /* 44 reserved */
14096 0, /* 45 reserved */
14097 0, /* 46 reserved */
14098 0, /* 47 reserved */
14099 0, /* 48 reserved */
14100 0, /* 49 reserved */
14101 0, /* 50 reserved */
14102 0, /* 51 reserved */
14103 0, /* 52 reserved */
14104 0, /* 53 reserved */
14105 0, /* 54 reserved */
14106 0, /* 55 reserved */
14107 0, /* 56 cisptr_lsw */
14108 0, /* 57 cisprt_msw */
14109 0, /* 58 subsysvid */
14110 0, /* 59 subsysid */
14111 0, /* 60 reserved */
14112 0, /* 61 reserved */
14113 0, /* 62 reserved */
14114 0 /* 63 reserved */
1da177e4
LT
14115};
14116
14117/*
14118 * Initialize the ADV_DVC_VAR structure.
14119 *
14120 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
14121 *
14122 * For a non-fatal error return a warning code. If there are no warnings
14123 * then 0 is returned.
14124 */
27c868c2 14125static int __init AdvInitGetConfig(ADV_DVC_VAR *asc_dvc)
1da177e4 14126{
27c868c2
MW
14127 ushort warn_code;
14128 AdvPortAddr iop_base;
14129 uchar pci_cmd_reg;
14130 int status;
14131
14132 warn_code = 0;
14133 asc_dvc->err_code = 0;
14134 iop_base = asc_dvc->iop_base;
14135
14136 /*
14137 * PCI Command Register
14138 *
14139 * Note: AscPCICmdRegBits_BusMastering definition (0x0007) includes
14140 * I/O Space Control, Memory Space Control and Bus Master Control bits.
14141 */
14142
14143 if (((pci_cmd_reg = DvcAdvReadPCIConfigByte(asc_dvc,
14144 AscPCIConfigCommandRegister))
14145 & AscPCICmdRegBits_BusMastering)
14146 != AscPCICmdRegBits_BusMastering) {
14147 pci_cmd_reg |= AscPCICmdRegBits_BusMastering;
14148
14149 DvcAdvWritePCIConfigByte(asc_dvc,
14150 AscPCIConfigCommandRegister,
14151 pci_cmd_reg);
14152
14153 if (((DvcAdvReadPCIConfigByte
14154 (asc_dvc, AscPCIConfigCommandRegister))
14155 & AscPCICmdRegBits_BusMastering)
14156 != AscPCICmdRegBits_BusMastering) {
14157 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
14158 }
14159 }
1da177e4 14160
27c868c2
MW
14161 /*
14162 * PCI Latency Timer
14163 *
14164 * If the "latency timer" register is 0x20 or above, then we don't need
14165 * to change it. Otherwise, set it to 0x20 (i.e. set it to 0x20 if it
14166 * comes up less than 0x20).
14167 */
14168 if (DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer) < 0x20) {
14169 DvcAdvWritePCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer,
14170 0x20);
14171 if (DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer) <
14172 0x20) {
14173 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
14174 }
14175 }
1da177e4 14176
27c868c2
MW
14177 /*
14178 * Save the state of the PCI Configuration Command Register
14179 * "Parity Error Response Control" Bit. If the bit is clear (0),
14180 * in AdvInitAsc3550/38C0800Driver() tell the microcode to ignore
14181 * DMA parity errors.
14182 */
14183 asc_dvc->cfg->control_flag = 0;
14184 if (((DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigCommandRegister)
14185 & AscPCICmdRegBits_ParErrRespCtrl)) == 0) {
14186 asc_dvc->cfg->control_flag |= CONTROL_FLAG_IGNORE_PERR;
14187 }
1da177e4 14188
27c868c2
MW
14189 asc_dvc->cfg->lib_version = (ADV_LIB_VERSION_MAJOR << 8) |
14190 ADV_LIB_VERSION_MINOR;
14191 asc_dvc->cfg->chip_version =
14192 AdvGetChipVersion(iop_base, asc_dvc->bus_type);
14193
14194 ASC_DBG2(1, "AdvInitGetConfig: iopb_chip_id_1: 0x%x 0x%x\n",
14195 (ushort)AdvReadByteRegister(iop_base, IOPB_CHIP_ID_1),
14196 (ushort)ADV_CHIP_ID_BYTE);
14197
14198 ASC_DBG2(1, "AdvInitGetConfig: iopw_chip_id_0: 0x%x 0x%x\n",
14199 (ushort)AdvReadWordRegister(iop_base, IOPW_CHIP_ID_0),
14200 (ushort)ADV_CHIP_ID_WORD);
14201
14202 /*
14203 * Reset the chip to start and allow register writes.
14204 */
14205 if (AdvFindSignature(iop_base) == 0) {
14206 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
14207 return ADV_ERROR;
14208 } else {
14209 /*
14210 * The caller must set 'chip_type' to a valid setting.
14211 */
14212 if (asc_dvc->chip_type != ADV_CHIP_ASC3550 &&
14213 asc_dvc->chip_type != ADV_CHIP_ASC38C0800 &&
14214 asc_dvc->chip_type != ADV_CHIP_ASC38C1600) {
14215 asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE;
14216 return ADV_ERROR;
14217 }
1da177e4 14218
27c868c2
MW
14219 /*
14220 * Reset Chip.
14221 */
14222 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
14223 ADV_CTRL_REG_CMD_RESET);
14224 DvcSleepMilliSecond(100);
14225 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
14226 ADV_CTRL_REG_CMD_WR_IO_REG);
14227
14228 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
14229 if ((status =
14230 AdvInitFrom38C1600EEP(asc_dvc)) == ADV_ERROR) {
14231 return ADV_ERROR;
14232 }
14233 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
14234 if ((status =
14235 AdvInitFrom38C0800EEP(asc_dvc)) == ADV_ERROR) {
14236 return ADV_ERROR;
14237 }
14238 } else {
14239 if ((status = AdvInitFrom3550EEP(asc_dvc)) == ADV_ERROR) {
14240 return ADV_ERROR;
14241 }
14242 }
14243 warn_code |= status;
14244 }
1da177e4 14245
27c868c2 14246 return warn_code;
1da177e4
LT
14247}
14248
14249/*
14250 * Initialize the ASC-3550.
14251 *
14252 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
14253 *
14254 * For a non-fatal error return a warning code. If there are no warnings
14255 * then 0 is returned.
14256 *
14257 * Needed after initialization for error recovery.
14258 */
27c868c2 14259static int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
1da177e4 14260{
27c868c2
MW
14261 AdvPortAddr iop_base;
14262 ushort warn_code;
14263 ADV_DCNT sum;
14264 int begin_addr;
14265 int end_addr;
14266 ushort code_sum;
14267 int word;
14268 int j;
14269 int adv_asc3550_expanded_size;
14270 ADV_CARR_T *carrp;
14271 ADV_DCNT contig_len;
14272 ADV_SDCNT buf_size;
14273 ADV_PADDR carr_paddr;
14274 int i;
14275 ushort scsi_cfg1;
14276 uchar tid;
14277 ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */
14278 ushort wdtr_able = 0, sdtr_able, tagqng_able;
14279 uchar max_cmd[ADV_MAX_TID + 1];
14280
14281 /* If there is already an error, don't continue. */
14282 if (asc_dvc->err_code != 0) {
14283 return ADV_ERROR;
14284 }
1da177e4 14285
27c868c2
MW
14286 /*
14287 * The caller must set 'chip_type' to ADV_CHIP_ASC3550.
14288 */
14289 if (asc_dvc->chip_type != ADV_CHIP_ASC3550) {
14290 asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE;
14291 return ADV_ERROR;
14292 }
1da177e4 14293
27c868c2
MW
14294 warn_code = 0;
14295 iop_base = asc_dvc->iop_base;
14296
14297 /*
14298 * Save the RISC memory BIOS region before writing the microcode.
14299 * The BIOS may already be loaded and using its RISC LRAM region
14300 * so its region must be saved and restored.
14301 *
14302 * Note: This code makes the assumption, which is currently true,
14303 * that a chip reset does not clear RISC LRAM.
14304 */
14305 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
14306 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
14307 bios_mem[i]);
14308 }
1da177e4 14309
27c868c2
MW
14310 /*
14311 * Save current per TID negotiated values.
14312 */
14313 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] == 0x55AA) {
14314 ushort bios_version, major, minor;
14315
14316 bios_version =
14317 bios_mem[(ASC_MC_BIOS_VERSION - ASC_MC_BIOSMEM) / 2];
14318 major = (bios_version >> 12) & 0xF;
14319 minor = (bios_version >> 8) & 0xF;
14320 if (major < 3 || (major == 3 && minor == 1)) {
14321 /* BIOS 3.1 and earlier location of 'wdtr_able' variable. */
14322 AdvReadWordLram(iop_base, 0x120, wdtr_able);
14323 } else {
14324 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
14325 }
14326 }
14327 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
14328 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
14329 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
14330 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
14331 max_cmd[tid]);
14332 }
1da177e4 14333
27c868c2
MW
14334 /*
14335 * Load the Microcode
14336 *
14337 * Write the microcode image to RISC memory starting at address 0.
14338 */
14339 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
14340 /* Assume the following compressed format of the microcode buffer:
14341 *
14342 * 254 word (508 byte) table indexed by byte code followed
14343 * by the following byte codes:
14344 *
14345 * 1-Byte Code:
14346 * 00: Emit word 0 in table.
14347 * 01: Emit word 1 in table.
14348 * .
14349 * FD: Emit word 253 in table.
14350 *
14351 * Multi-Byte Code:
14352 * FE WW WW: (3 byte code) Word to emit is the next word WW WW.
14353 * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
14354 */
14355 word = 0;
14356 for (i = 253 * 2; i < _adv_asc3550_size; i++) {
14357 if (_adv_asc3550_buf[i] == 0xff) {
14358 for (j = 0; j < _adv_asc3550_buf[i + 1]; j++) {
14359 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14360 _adv_asc3550_buf
14361 [i +
14362 3] << 8) |
14363 _adv_asc3550_buf
14364 [i + 2]));
14365 word++;
14366 }
14367 i += 3;
14368 } else if (_adv_asc3550_buf[i] == 0xfe) {
14369 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14370 _adv_asc3550_buf[i +
14371 2]
14372 << 8) |
14373 _adv_asc3550_buf[i +
14374 1]));
14375 i += 2;
14376 word++;
14377 } else {
14378 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14379 _adv_asc3550_buf[(_adv_asc3550_buf[i] * 2) + 1] << 8) | _adv_asc3550_buf[_adv_asc3550_buf[i] * 2]));
14380 word++;
14381 }
14382 }
1da177e4 14383
27c868c2
MW
14384 /*
14385 * Set 'word' for later use to clear the rest of memory and save
14386 * the expanded mcode size.
14387 */
14388 word *= 2;
14389 adv_asc3550_expanded_size = word;
14390
14391 /*
14392 * Clear the rest of ASC-3550 Internal RAM (8KB).
14393 */
14394 for (; word < ADV_3550_MEMSIZE; word += 2) {
14395 AdvWriteWordAutoIncLram(iop_base, 0);
14396 }
1da177e4 14397
27c868c2
MW
14398 /*
14399 * Verify the microcode checksum.
14400 */
14401 sum = 0;
14402 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
1da177e4 14403
27c868c2
MW
14404 for (word = 0; word < adv_asc3550_expanded_size; word += 2) {
14405 sum += AdvReadWordAutoIncLram(iop_base);
14406 }
1da177e4 14407
27c868c2
MW
14408 if (sum != _adv_asc3550_chksum) {
14409 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
14410 return ADV_ERROR;
14411 }
1da177e4 14412
27c868c2
MW
14413 /*
14414 * Restore the RISC memory BIOS region.
14415 */
14416 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
14417 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
14418 bios_mem[i]);
14419 }
1da177e4 14420
27c868c2
MW
14421 /*
14422 * Calculate and write the microcode code checksum to the microcode
14423 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
14424 */
14425 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
14426 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
14427 code_sum = 0;
14428 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
14429 for (word = begin_addr; word < end_addr; word += 2) {
14430 code_sum += AdvReadWordAutoIncLram(iop_base);
14431 }
14432 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
14433
14434 /*
14435 * Read and save microcode version and date.
14436 */
14437 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
14438 asc_dvc->cfg->mcode_date);
14439 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
14440 asc_dvc->cfg->mcode_version);
14441
14442 /*
14443 * Set the chip type to indicate the ASC3550.
14444 */
14445 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC3550);
14446
14447 /*
14448 * If the PCI Configuration Command Register "Parity Error Response
14449 * Control" Bit was clear (0), then set the microcode variable
14450 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
14451 * to ignore DMA parity errors.
14452 */
14453 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
14454 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
14455 word |= CONTROL_FLAG_IGNORE_PERR;
14456 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
14457 }
1da177e4 14458
27c868c2
MW
14459 /*
14460 * For ASC-3550, setting the START_CTL_EMFU [3:2] bits sets a FIFO
14461 * threshold of 128 bytes. This register is only accessible to the host.
14462 */
14463 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
14464 START_CTL_EMFU | READ_CMD_MRM);
14465
14466 /*
14467 * Microcode operating variables for WDTR, SDTR, and command tag
14468 * queuing will be set in AdvInquiryHandling() based on what a
14469 * device reports it is capable of in Inquiry byte 7.
14470 *
14471 * If SCSI Bus Resets have been disabled, then directly set
14472 * SDTR and WDTR from the EEPROM configuration. This will allow
14473 * the BIOS and warm boot to work without a SCSI bus hang on
14474 * the Inquiry caused by host and target mismatched DTR values.
14475 * Without the SCSI Bus Reset, before an Inquiry a device can't
14476 * be assumed to be in Asynchronous, Narrow mode.
14477 */
14478 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
14479 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
14480 asc_dvc->wdtr_able);
14481 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
14482 asc_dvc->sdtr_able);
14483 }
1da177e4 14484
27c868c2
MW
14485 /*
14486 * Set microcode operating variables for SDTR_SPEED1, SDTR_SPEED2,
14487 * SDTR_SPEED3, and SDTR_SPEED4 based on the ULTRA EEPROM per TID
14488 * bitmask. These values determine the maximum SDTR speed negotiated
14489 * with a device.
14490 *
14491 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
14492 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
14493 * without determining here whether the device supports SDTR.
14494 *
14495 * 4-bit speed SDTR speed name
14496 * =========== ===============
14497 * 0000b (0x0) SDTR disabled
14498 * 0001b (0x1) 5 Mhz
14499 * 0010b (0x2) 10 Mhz
14500 * 0011b (0x3) 20 Mhz (Ultra)
14501 * 0100b (0x4) 40 Mhz (LVD/Ultra2)
14502 * 0101b (0x5) 80 Mhz (LVD2/Ultra3)
14503 * 0110b (0x6) Undefined
14504 * .
14505 * 1111b (0xF) Undefined
14506 */
14507 word = 0;
14508 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
14509 if (ADV_TID_TO_TIDMASK(tid) & asc_dvc->ultra_able) {
14510 /* Set Ultra speed for TID 'tid'. */
14511 word |= (0x3 << (4 * (tid % 4)));
14512 } else {
14513 /* Set Fast speed for TID 'tid'. */
14514 word |= (0x2 << (4 * (tid % 4)));
14515 }
14516 if (tid == 3) { /* Check if done with sdtr_speed1. */
14517 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, word);
14518 word = 0;
14519 } else if (tid == 7) { /* Check if done with sdtr_speed2. */
14520 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, word);
14521 word = 0;
14522 } else if (tid == 11) { /* Check if done with sdtr_speed3. */
14523 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, word);
14524 word = 0;
14525 } else if (tid == 15) { /* Check if done with sdtr_speed4. */
14526 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, word);
14527 /* End of loop. */
14528 }
14529 }
1da177e4 14530
27c868c2
MW
14531 /*
14532 * Set microcode operating variable for the disconnect per TID bitmask.
14533 */
14534 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
14535 asc_dvc->cfg->disc_enable);
14536
14537 /*
14538 * Set SCSI_CFG0 Microcode Default Value.
14539 *
14540 * The microcode will set the SCSI_CFG0 register using this value
14541 * after it is started below.
14542 */
14543 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
14544 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
14545 asc_dvc->chip_scsi_id);
14546
14547 /*
14548 * Determine SCSI_CFG1 Microcode Default Value.
14549 *
14550 * The microcode will set the SCSI_CFG1 register using this value
14551 * after it is started below.
14552 */
14553
14554 /* Read current SCSI_CFG1 Register value. */
14555 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
14556
14557 /*
14558 * If all three connectors are in use, return an error.
14559 */
14560 if ((scsi_cfg1 & CABLE_ILLEGAL_A) == 0 ||
14561 (scsi_cfg1 & CABLE_ILLEGAL_B) == 0) {
14562 asc_dvc->err_code |= ASC_IERR_ILLEGAL_CONNECTION;
14563 return ADV_ERROR;
14564 }
1da177e4 14565
27c868c2
MW
14566 /*
14567 * If the internal narrow cable is reversed all of the SCSI_CTRL
14568 * register signals will be set. Check for and return an error if
14569 * this condition is found.
14570 */
14571 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
14572 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
14573 return ADV_ERROR;
14574 }
1da177e4 14575
27c868c2
MW
14576 /*
14577 * If this is a differential board and a single-ended device
14578 * is attached to one of the connectors, return an error.
14579 */
14580 if ((scsi_cfg1 & DIFF_MODE) && (scsi_cfg1 & DIFF_SENSE) == 0) {
14581 asc_dvc->err_code |= ASC_IERR_SINGLE_END_DEVICE;
14582 return ADV_ERROR;
14583 }
1da177e4 14584
27c868c2
MW
14585 /*
14586 * If automatic termination control is enabled, then set the
14587 * termination value based on a table listed in a_condor.h.
14588 *
14589 * If manual termination was specified with an EEPROM setting
14590 * then 'termination' was set-up in AdvInitFrom3550EEPROM() and
14591 * is ready to be 'ored' into SCSI_CFG1.
14592 */
14593 if (asc_dvc->cfg->termination == 0) {
14594 /*
14595 * The software always controls termination by setting TERM_CTL_SEL.
14596 * If TERM_CTL_SEL were set to 0, the hardware would set termination.
14597 */
14598 asc_dvc->cfg->termination |= TERM_CTL_SEL;
14599
14600 switch (scsi_cfg1 & CABLE_DETECT) {
14601 /* TERM_CTL_H: on, TERM_CTL_L: on */
14602 case 0x3:
14603 case 0x7:
14604 case 0xB:
14605 case 0xD:
14606 case 0xE:
14607 case 0xF:
14608 asc_dvc->cfg->termination |= (TERM_CTL_H | TERM_CTL_L);
14609 break;
14610
14611 /* TERM_CTL_H: on, TERM_CTL_L: off */
14612 case 0x1:
14613 case 0x5:
14614 case 0x9:
14615 case 0xA:
14616 case 0xC:
14617 asc_dvc->cfg->termination |= TERM_CTL_H;
14618 break;
14619
14620 /* TERM_CTL_H: off, TERM_CTL_L: off */
14621 case 0x2:
14622 case 0x6:
14623 break;
14624 }
14625 }
1da177e4 14626
27c868c2
MW
14627 /*
14628 * Clear any set TERM_CTL_H and TERM_CTL_L bits.
14629 */
14630 scsi_cfg1 &= ~TERM_CTL;
14631
14632 /*
14633 * Invert the TERM_CTL_H and TERM_CTL_L bits and then
14634 * set 'scsi_cfg1'. The TERM_POL bit does not need to be
14635 * referenced, because the hardware internally inverts
14636 * the Termination High and Low bits if TERM_POL is set.
14637 */
14638 scsi_cfg1 |= (TERM_CTL_SEL | (~asc_dvc->cfg->termination & TERM_CTL));
14639
14640 /*
14641 * Set SCSI_CFG1 Microcode Default Value
14642 *
14643 * Set filter value and possibly modified termination control
14644 * bits in the Microcode SCSI_CFG1 Register Value.
14645 *
14646 * The microcode will set the SCSI_CFG1 register using this value
14647 * after it is started below.
14648 */
14649 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1,
14650 FLTR_DISABLE | scsi_cfg1);
14651
14652 /*
14653 * Set MEM_CFG Microcode Default Value
14654 *
14655 * The microcode will set the MEM_CFG register using this value
14656 * after it is started below.
14657 *
14658 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
14659 * are defined.
14660 *
14661 * ASC-3550 has 8KB internal memory.
14662 */
14663 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
14664 BIOS_EN | RAM_SZ_8KB);
14665
14666 /*
14667 * Set SEL_MASK Microcode Default Value
14668 *
14669 * The microcode will set the SEL_MASK register using this value
14670 * after it is started below.
14671 */
14672 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
14673 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
14674
14675 /*
14676 * Build carrier freelist.
14677 *
14678 * Driver must have already allocated memory and set 'carrier_buf'.
14679 */
14680 ASC_ASSERT(asc_dvc->carrier_buf != NULL);
14681
14682 carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
14683 asc_dvc->carr_freelist = NULL;
14684 if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf) {
14685 buf_size = ADV_CARRIER_BUFSIZE;
14686 } else {
14687 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
14688 }
1da177e4 14689
27c868c2
MW
14690 do {
14691 /*
14692 * Get physical address of the carrier 'carrp'.
14693 */
14694 contig_len = sizeof(ADV_CARR_T);
14695 carr_paddr =
14696 cpu_to_le32(DvcGetPhyAddr
14697 (asc_dvc, NULL, (uchar *)carrp,
14698 (ADV_SDCNT *)&contig_len,
14699 ADV_IS_CARRIER_FLAG));
1da177e4 14700
27c868c2 14701 buf_size -= sizeof(ADV_CARR_T);
1da177e4 14702
27c868c2
MW
14703 /*
14704 * If the current carrier is not physically contiguous, then
14705 * maybe there was a page crossing. Try the next carrier aligned
14706 * start address.
14707 */
14708 if (contig_len < sizeof(ADV_CARR_T)) {
14709 carrp++;
14710 continue;
14711 }
14712
14713 carrp->carr_pa = carr_paddr;
14714 carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
1da177e4 14715
27c868c2
MW
14716 /*
14717 * Insert the carrier at the beginning of the freelist.
14718 */
14719 carrp->next_vpa =
14720 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
14721 asc_dvc->carr_freelist = carrp;
1da177e4 14722
27c868c2
MW
14723 carrp++;
14724 }
14725 while (buf_size > 0);
1da177e4 14726
27c868c2
MW
14727 /*
14728 * Set-up the Host->RISC Initiator Command Queue (ICQ).
14729 */
1da177e4 14730
27c868c2
MW
14731 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
14732 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
14733 return ADV_ERROR;
14734 }
14735 asc_dvc->carr_freelist = (ADV_CARR_T *)
14736 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
14737
14738 /*
14739 * The first command issued will be placed in the stopper carrier.
14740 */
14741 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
14742
14743 /*
14744 * Set RISC ICQ physical address start value.
14745 */
14746 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
14747
14748 /*
14749 * Set-up the RISC->Host Initiator Response Queue (IRQ).
14750 */
14751 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
14752 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
14753 return ADV_ERROR;
14754 }
14755 asc_dvc->carr_freelist = (ADV_CARR_T *)
14756 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
14757
14758 /*
14759 * The first command completed by the RISC will be placed in
14760 * the stopper.
14761 *
14762 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
14763 * completed the RISC will set the ASC_RQ_STOPPER bit.
14764 */
14765 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
14766
14767 /*
14768 * Set RISC IRQ physical address start value.
14769 */
14770 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
14771 asc_dvc->carr_pending_cnt = 0;
14772
14773 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
14774 (ADV_INTR_ENABLE_HOST_INTR |
14775 ADV_INTR_ENABLE_GLOBAL_INTR));
14776
14777 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
14778 AdvWriteWordRegister(iop_base, IOPW_PC, word);
14779
14780 /* finally, finally, gentlemen, start your engine */
14781 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
14782
14783 /*
14784 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
14785 * Resets should be performed. The RISC has to be running
14786 * to issue a SCSI Bus Reset.
14787 */
14788 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
14789 /*
14790 * If the BIOS Signature is present in memory, restore the
14791 * BIOS Handshake Configuration Table and do not perform
14792 * a SCSI Bus Reset.
14793 */
14794 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
14795 0x55AA) {
14796 /*
14797 * Restore per TID negotiated values.
14798 */
14799 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
14800 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
14801 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
14802 tagqng_able);
14803 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
14804 AdvWriteByteLram(iop_base,
14805 ASC_MC_NUMBER_OF_MAX_CMD + tid,
14806 max_cmd[tid]);
14807 }
14808 } else {
14809 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
14810 warn_code = ASC_WARN_BUSRESET_ERROR;
14811 }
14812 }
14813 }
1da177e4 14814
27c868c2
MW
14815 return warn_code;
14816}
1da177e4 14817
27c868c2
MW
14818/*
14819 * Initialize the ASC-38C0800.
14820 *
14821 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
14822 *
14823 * For a non-fatal error return a warning code. If there are no warnings
14824 * then 0 is returned.
14825 *
14826 * Needed after initialization for error recovery.
14827 */
14828static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc)
14829{
14830 AdvPortAddr iop_base;
14831 ushort warn_code;
14832 ADV_DCNT sum;
14833 int begin_addr;
14834 int end_addr;
14835 ushort code_sum;
14836 int word;
14837 int j;
14838 int adv_asc38C0800_expanded_size;
14839 ADV_CARR_T *carrp;
14840 ADV_DCNT contig_len;
14841 ADV_SDCNT buf_size;
14842 ADV_PADDR carr_paddr;
14843 int i;
14844 ushort scsi_cfg1;
14845 uchar byte;
14846 uchar tid;
14847 ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */
14848 ushort wdtr_able, sdtr_able, tagqng_able;
14849 uchar max_cmd[ADV_MAX_TID + 1];
14850
14851 /* If there is already an error, don't continue. */
14852 if (asc_dvc->err_code != 0) {
14853 return ADV_ERROR;
14854 }
1da177e4 14855
27c868c2
MW
14856 /*
14857 * The caller must set 'chip_type' to ADV_CHIP_ASC38C0800.
14858 */
14859 if (asc_dvc->chip_type != ADV_CHIP_ASC38C0800) {
14860 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
14861 return ADV_ERROR;
14862 }
1da177e4 14863
27c868c2
MW
14864 warn_code = 0;
14865 iop_base = asc_dvc->iop_base;
14866
14867 /*
14868 * Save the RISC memory BIOS region before writing the microcode.
14869 * The BIOS may already be loaded and using its RISC LRAM region
14870 * so its region must be saved and restored.
14871 *
14872 * Note: This code makes the assumption, which is currently true,
14873 * that a chip reset does not clear RISC LRAM.
14874 */
14875 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
14876 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
14877 bios_mem[i]);
14878 }
1da177e4 14879
27c868c2
MW
14880 /*
14881 * Save current per TID negotiated values.
14882 */
14883 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
14884 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
14885 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
14886 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
14887 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
14888 max_cmd[tid]);
14889 }
1da177e4 14890
27c868c2
MW
14891 /*
14892 * RAM BIST (RAM Built-In Self Test)
14893 *
14894 * Address : I/O base + offset 0x38h register (byte).
14895 * Function: Bit 7-6(RW) : RAM mode
14896 * Normal Mode : 0x00
14897 * Pre-test Mode : 0x40
14898 * RAM Test Mode : 0x80
14899 * Bit 5 : unused
14900 * Bit 4(RO) : Done bit
14901 * Bit 3-0(RO) : Status
14902 * Host Error : 0x08
14903 * Int_RAM Error : 0x04
14904 * RISC Error : 0x02
14905 * SCSI Error : 0x01
14906 * No Error : 0x00
14907 *
14908 * Note: RAM BIST code should be put right here, before loading the
14909 * microcode and after saving the RISC memory BIOS region.
14910 */
14911
14912 /*
14913 * LRAM Pre-test
14914 *
14915 * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
14916 * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
14917 * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
14918 * to NORMAL_MODE, return an error too.
14919 */
14920 for (i = 0; i < 2; i++) {
14921 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
14922 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
14923 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
14924 if ((byte & RAM_TEST_DONE) == 0
14925 || (byte & 0x0F) != PRE_TEST_VALUE) {
14926 asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
14927 return ADV_ERROR;
14928 }
14929
14930 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
14931 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
14932 if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
14933 != NORMAL_VALUE) {
14934 asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
14935 return ADV_ERROR;
14936 }
14937 }
1da177e4 14938
27c868c2
MW
14939 /*
14940 * LRAM Test - It takes about 1.5 ms to run through the test.
14941 *
14942 * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
14943 * If Done bit not set or Status not 0, save register byte, set the
14944 * err_code, and return an error.
14945 */
14946 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
14947 DvcSleepMilliSecond(10); /* Wait for 10ms before checking status. */
14948
14949 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
14950 if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) {
14951 /* Get here if Done bit not set or Status not 0. */
14952 asc_dvc->bist_err_code = byte; /* for BIOS display message */
14953 asc_dvc->err_code |= ASC_IERR_BIST_RAM_TEST;
14954 return ADV_ERROR;
14955 }
1da177e4 14956
27c868c2
MW
14957 /* We need to reset back to normal mode after LRAM test passes. */
14958 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
14959
14960 /*
14961 * Load the Microcode
14962 *
14963 * Write the microcode image to RISC memory starting at address 0.
14964 *
14965 */
14966 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
14967
14968 /* Assume the following compressed format of the microcode buffer:
14969 *
14970 * 254 word (508 byte) table indexed by byte code followed
14971 * by the following byte codes:
14972 *
14973 * 1-Byte Code:
14974 * 00: Emit word 0 in table.
14975 * 01: Emit word 1 in table.
14976 * .
14977 * FD: Emit word 253 in table.
14978 *
14979 * Multi-Byte Code:
14980 * FE WW WW: (3 byte code) Word to emit is the next word WW WW.
14981 * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
14982 */
14983 word = 0;
14984 for (i = 253 * 2; i < _adv_asc38C0800_size; i++) {
14985 if (_adv_asc38C0800_buf[i] == 0xff) {
14986 for (j = 0; j < _adv_asc38C0800_buf[i + 1]; j++) {
14987 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14988 _adv_asc38C0800_buf
14989 [i +
14990 3] << 8) |
14991 _adv_asc38C0800_buf
14992 [i + 2]));
14993 word++;
14994 }
14995 i += 3;
14996 } else if (_adv_asc38C0800_buf[i] == 0xfe) {
14997 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14998 _adv_asc38C0800_buf
14999 [i +
15000 2] << 8) |
15001 _adv_asc38C0800_buf[i
15002 +
15003 1]));
15004 i += 2;
15005 word++;
15006 } else {
15007 AdvWriteWordAutoIncLram(iop_base, (((ushort)
15008 _adv_asc38C0800_buf[(_adv_asc38C0800_buf[i] * 2) + 1] << 8) | _adv_asc38C0800_buf[_adv_asc38C0800_buf[i] * 2]));
15009 word++;
15010 }
15011 }
1da177e4 15012
27c868c2
MW
15013 /*
15014 * Set 'word' for later use to clear the rest of memory and save
15015 * the expanded mcode size.
15016 */
15017 word *= 2;
15018 adv_asc38C0800_expanded_size = word;
15019
15020 /*
15021 * Clear the rest of ASC-38C0800 Internal RAM (16KB).
15022 */
15023 for (; word < ADV_38C0800_MEMSIZE; word += 2) {
15024 AdvWriteWordAutoIncLram(iop_base, 0);
15025 }
1da177e4 15026
27c868c2
MW
15027 /*
15028 * Verify the microcode checksum.
15029 */
15030 sum = 0;
15031 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
1da177e4 15032
27c868c2
MW
15033 for (word = 0; word < adv_asc38C0800_expanded_size; word += 2) {
15034 sum += AdvReadWordAutoIncLram(iop_base);
15035 }
15036 ASC_DBG2(1, "AdvInitAsc38C0800Driver: word %d, i %d\n", word, i);
1da177e4 15037
27c868c2
MW
15038 ASC_DBG2(1,
15039 "AdvInitAsc38C0800Driver: sum 0x%lx, _adv_asc38C0800_chksum 0x%lx\n",
15040 (ulong)sum, (ulong)_adv_asc38C0800_chksum);
1da177e4 15041
27c868c2
MW
15042 if (sum != _adv_asc38C0800_chksum) {
15043 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
15044 return ADV_ERROR;
15045 }
1da177e4 15046
27c868c2
MW
15047 /*
15048 * Restore the RISC memory BIOS region.
15049 */
15050 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
15051 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
15052 bios_mem[i]);
15053 }
1da177e4 15054
27c868c2
MW
15055 /*
15056 * Calculate and write the microcode code checksum to the microcode
15057 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
15058 */
15059 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
15060 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
15061 code_sum = 0;
15062 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
15063 for (word = begin_addr; word < end_addr; word += 2) {
15064 code_sum += AdvReadWordAutoIncLram(iop_base);
15065 }
15066 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
15067
15068 /*
15069 * Read microcode version and date.
15070 */
15071 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
15072 asc_dvc->cfg->mcode_date);
15073 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
15074 asc_dvc->cfg->mcode_version);
15075
15076 /*
15077 * Set the chip type to indicate the ASC38C0800.
15078 */
15079 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C0800);
15080
15081 /*
15082 * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
15083 * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
15084 * cable detection and then we are able to read C_DET[3:0].
15085 *
15086 * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
15087 * Microcode Default Value' section below.
15088 */
15089 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
15090 AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1,
15091 scsi_cfg1 | DIS_TERM_DRV);
15092
15093 /*
15094 * If the PCI Configuration Command Register "Parity Error Response
15095 * Control" Bit was clear (0), then set the microcode variable
15096 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
15097 * to ignore DMA parity errors.
15098 */
15099 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
15100 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15101 word |= CONTROL_FLAG_IGNORE_PERR;
15102 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15103 }
1da177e4 15104
27c868c2
MW
15105 /*
15106 * For ASC-38C0800, set FIFO_THRESH_80B [6:4] bits and START_CTL_TH [3:2]
15107 * bits for the default FIFO threshold.
15108 *
15109 * Note: ASC-38C0800 FIFO threshold has been changed to 256 bytes.
15110 *
15111 * For DMA Errata #4 set the BC_THRESH_ENB bit.
15112 */
15113 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
15114 BC_THRESH_ENB | FIFO_THRESH_80B | START_CTL_TH |
15115 READ_CMD_MRM);
15116
15117 /*
15118 * Microcode operating variables for WDTR, SDTR, and command tag
15119 * queuing will be set in AdvInquiryHandling() based on what a
15120 * device reports it is capable of in Inquiry byte 7.
15121 *
15122 * If SCSI Bus Resets have been disabled, then directly set
15123 * SDTR and WDTR from the EEPROM configuration. This will allow
15124 * the BIOS and warm boot to work without a SCSI bus hang on
15125 * the Inquiry caused by host and target mismatched DTR values.
15126 * Without the SCSI Bus Reset, before an Inquiry a device can't
15127 * be assumed to be in Asynchronous, Narrow mode.
15128 */
15129 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
15130 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
15131 asc_dvc->wdtr_able);
15132 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
15133 asc_dvc->sdtr_able);
15134 }
1da177e4 15135
27c868c2
MW
15136 /*
15137 * Set microcode operating variables for DISC and SDTR_SPEED1,
15138 * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
15139 * configuration values.
15140 *
15141 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
15142 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
15143 * without determining here whether the device supports SDTR.
15144 */
15145 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
15146 asc_dvc->cfg->disc_enable);
15147 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
15148 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
15149 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
15150 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
15151
15152 /*
15153 * Set SCSI_CFG0 Microcode Default Value.
15154 *
15155 * The microcode will set the SCSI_CFG0 register using this value
15156 * after it is started below.
15157 */
15158 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
15159 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
15160 asc_dvc->chip_scsi_id);
15161
15162 /*
15163 * Determine SCSI_CFG1 Microcode Default Value.
15164 *
15165 * The microcode will set the SCSI_CFG1 register using this value
15166 * after it is started below.
15167 */
15168
15169 /* Read current SCSI_CFG1 Register value. */
15170 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
15171
15172 /*
15173 * If the internal narrow cable is reversed all of the SCSI_CTRL
15174 * register signals will be set. Check for and return an error if
15175 * this condition is found.
15176 */
15177 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
15178 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
15179 return ADV_ERROR;
15180 }
1da177e4 15181
27c868c2
MW
15182 /*
15183 * All kind of combinations of devices attached to one of four connectors
15184 * are acceptable except HVD device attached. For example, LVD device can
15185 * be attached to SE connector while SE device attached to LVD connector.
15186 * If LVD device attached to SE connector, it only runs up to Ultra speed.
15187 *
15188 * If an HVD device is attached to one of LVD connectors, return an error.
15189 * However, there is no way to detect HVD device attached to SE connectors.
15190 */
15191 if (scsi_cfg1 & HVD) {
15192 asc_dvc->err_code |= ASC_IERR_HVD_DEVICE;
15193 return ADV_ERROR;
15194 }
1da177e4 15195
27c868c2
MW
15196 /*
15197 * If either SE or LVD automatic termination control is enabled, then
15198 * set the termination value based on a table listed in a_condor.h.
15199 *
15200 * If manual termination was specified with an EEPROM setting then
15201 * 'termination' was set-up in AdvInitFrom38C0800EEPROM() and is ready to
15202 * be 'ored' into SCSI_CFG1.
15203 */
15204 if ((asc_dvc->cfg->termination & TERM_SE) == 0) {
15205 /* SE automatic termination control is enabled. */
15206 switch (scsi_cfg1 & C_DET_SE) {
15207 /* TERM_SE_HI: on, TERM_SE_LO: on */
15208 case 0x1:
15209 case 0x2:
15210 case 0x3:
15211 asc_dvc->cfg->termination |= TERM_SE;
15212 break;
15213
15214 /* TERM_SE_HI: on, TERM_SE_LO: off */
15215 case 0x0:
15216 asc_dvc->cfg->termination |= TERM_SE_HI;
15217 break;
15218 }
15219 }
15220
15221 if ((asc_dvc->cfg->termination & TERM_LVD) == 0) {
15222 /* LVD automatic termination control is enabled. */
15223 switch (scsi_cfg1 & C_DET_LVD) {
15224 /* TERM_LVD_HI: on, TERM_LVD_LO: on */
15225 case 0x4:
15226 case 0x8:
15227 case 0xC:
15228 asc_dvc->cfg->termination |= TERM_LVD;
15229 break;
15230
15231 /* TERM_LVD_HI: off, TERM_LVD_LO: off */
15232 case 0x0:
15233 break;
15234 }
15235 }
15236
15237 /*
15238 * Clear any set TERM_SE and TERM_LVD bits.
15239 */
15240 scsi_cfg1 &= (~TERM_SE & ~TERM_LVD);
15241
15242 /*
15243 * Invert the TERM_SE and TERM_LVD bits and then set 'scsi_cfg1'.
15244 */
15245 scsi_cfg1 |= (~asc_dvc->cfg->termination & 0xF0);
15246
15247 /*
15248 * Clear BIG_ENDIAN, DIS_TERM_DRV, Terminator Polarity and HVD/LVD/SE bits
15249 * and set possibly modified termination control bits in the Microcode
15250 * SCSI_CFG1 Register Value.
15251 */
15252 scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL & ~HVD_LVD_SE);
15253
15254 /*
15255 * Set SCSI_CFG1 Microcode Default Value
15256 *
15257 * Set possibly modified termination control and reset DIS_TERM_DRV
15258 * bits in the Microcode SCSI_CFG1 Register Value.
15259 *
15260 * The microcode will set the SCSI_CFG1 register using this value
15261 * after it is started below.
15262 */
15263 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
15264
15265 /*
15266 * Set MEM_CFG Microcode Default Value
15267 *
15268 * The microcode will set the MEM_CFG register using this value
15269 * after it is started below.
15270 *
15271 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
15272 * are defined.
15273 *
15274 * ASC-38C0800 has 16KB internal memory.
15275 */
15276 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
15277 BIOS_EN | RAM_SZ_16KB);
15278
15279 /*
15280 * Set SEL_MASK Microcode Default Value
15281 *
15282 * The microcode will set the SEL_MASK register using this value
15283 * after it is started below.
15284 */
15285 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
15286 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
15287
15288 /*
15289 * Build the carrier freelist.
15290 *
15291 * Driver must have already allocated memory and set 'carrier_buf'.
15292 */
15293 ASC_ASSERT(asc_dvc->carrier_buf != NULL);
15294
15295 carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
15296 asc_dvc->carr_freelist = NULL;
15297 if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf) {
15298 buf_size = ADV_CARRIER_BUFSIZE;
15299 } else {
15300 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
15301 }
15302
15303 do {
15304 /*
15305 * Get physical address for the carrier 'carrp'.
15306 */
15307 contig_len = sizeof(ADV_CARR_T);
15308 carr_paddr =
15309 cpu_to_le32(DvcGetPhyAddr
15310 (asc_dvc, NULL, (uchar *)carrp,
15311 (ADV_SDCNT *)&contig_len,
15312 ADV_IS_CARRIER_FLAG));
1da177e4 15313
27c868c2
MW
15314 buf_size -= sizeof(ADV_CARR_T);
15315
15316 /*
15317 * If the current carrier is not physically contiguous, then
15318 * maybe there was a page crossing. Try the next carrier aligned
15319 * start address.
15320 */
15321 if (contig_len < sizeof(ADV_CARR_T)) {
15322 carrp++;
15323 continue;
15324 }
15325
15326 carrp->carr_pa = carr_paddr;
15327 carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
15328
15329 /*
15330 * Insert the carrier at the beginning of the freelist.
15331 */
15332 carrp->next_vpa =
15333 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
15334 asc_dvc->carr_freelist = carrp;
15335
15336 carrp++;
15337 }
15338 while (buf_size > 0);
15339
15340 /*
15341 * Set-up the Host->RISC Initiator Command Queue (ICQ).
15342 */
15343
15344 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
15345 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15346 return ADV_ERROR;
15347 }
15348 asc_dvc->carr_freelist = (ADV_CARR_T *)
15349 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
15350
15351 /*
15352 * The first command issued will be placed in the stopper carrier.
15353 */
15354 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15355
15356 /*
15357 * Set RISC ICQ physical address start value.
15358 * carr_pa is LE, must be native before write
15359 */
15360 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, 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 * carr_pa is LE, must be native before write *
15385 */
15386 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
15387 asc_dvc->carr_pending_cnt = 0;
15388
15389 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
15390 (ADV_INTR_ENABLE_HOST_INTR |
15391 ADV_INTR_ENABLE_GLOBAL_INTR));
15392
15393 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
15394 AdvWriteWordRegister(iop_base, IOPW_PC, word);
15395
15396 /* finally, finally, gentlemen, start your engine */
15397 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
15398
15399 /*
15400 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
15401 * Resets should be performed. The RISC has to be running
15402 * to issue a SCSI Bus Reset.
15403 */
15404 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
15405 /*
15406 * If the BIOS Signature is present in memory, restore the
15407 * BIOS Handshake Configuration Table and do not perform
15408 * a SCSI Bus Reset.
15409 */
15410 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
15411 0x55AA) {
15412 /*
15413 * Restore per TID negotiated values.
15414 */
15415 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
15416 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
15417 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
15418 tagqng_able);
15419 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
15420 AdvWriteByteLram(iop_base,
15421 ASC_MC_NUMBER_OF_MAX_CMD + tid,
15422 max_cmd[tid]);
15423 }
15424 } else {
15425 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
15426 warn_code = ASC_WARN_BUSRESET_ERROR;
15427 }
15428 }
15429 }
15430
15431 return warn_code;
1da177e4
LT
15432}
15433
15434/*
27c868c2 15435 * Initialize the ASC-38C1600.
1da177e4 15436 *
27c868c2 15437 * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
1da177e4
LT
15438 *
15439 * For a non-fatal error return a warning code. If there are no warnings
15440 * then 0 is returned.
15441 *
15442 * Needed after initialization for error recovery.
15443 */
27c868c2 15444static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc)
1da177e4 15445{
27c868c2
MW
15446 AdvPortAddr iop_base;
15447 ushort warn_code;
15448 ADV_DCNT sum;
15449 int begin_addr;
15450 int end_addr;
15451 ushort code_sum;
15452 long word;
15453 int j;
15454 int adv_asc38C1600_expanded_size;
15455 ADV_CARR_T *carrp;
15456 ADV_DCNT contig_len;
15457 ADV_SDCNT buf_size;
15458 ADV_PADDR carr_paddr;
15459 int i;
15460 ushort scsi_cfg1;
15461 uchar byte;
15462 uchar tid;
15463 ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */
15464 ushort wdtr_able, sdtr_able, ppr_able, tagqng_able;
15465 uchar max_cmd[ASC_MAX_TID + 1];
15466
15467 /* If there is already an error, don't continue. */
15468 if (asc_dvc->err_code != 0) {
15469 return ADV_ERROR;
15470 }
1da177e4 15471
27c868c2
MW
15472 /*
15473 * The caller must set 'chip_type' to ADV_CHIP_ASC38C1600.
15474 */
15475 if (asc_dvc->chip_type != ADV_CHIP_ASC38C1600) {
15476 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
15477 return ADV_ERROR;
15478 }
1da177e4 15479
27c868c2
MW
15480 warn_code = 0;
15481 iop_base = asc_dvc->iop_base;
15482
15483 /*
15484 * Save the RISC memory BIOS region before writing the microcode.
15485 * The BIOS may already be loaded and using its RISC LRAM region
15486 * so its region must be saved and restored.
15487 *
15488 * Note: This code makes the assumption, which is currently true,
15489 * that a chip reset does not clear RISC LRAM.
15490 */
15491 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
15492 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
15493 bios_mem[i]);
15494 }
1da177e4 15495
27c868c2
MW
15496 /*
15497 * Save current per TID negotiated values.
15498 */
15499 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
15500 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
15501 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
15502 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
15503 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
15504 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
15505 max_cmd[tid]);
15506 }
1da177e4 15507
27c868c2
MW
15508 /*
15509 * RAM BIST (Built-In Self Test)
15510 *
15511 * Address : I/O base + offset 0x38h register (byte).
15512 * Function: Bit 7-6(RW) : RAM mode
15513 * Normal Mode : 0x00
15514 * Pre-test Mode : 0x40
15515 * RAM Test Mode : 0x80
15516 * Bit 5 : unused
15517 * Bit 4(RO) : Done bit
15518 * Bit 3-0(RO) : Status
15519 * Host Error : 0x08
15520 * Int_RAM Error : 0x04
15521 * RISC Error : 0x02
15522 * SCSI Error : 0x01
15523 * No Error : 0x00
15524 *
15525 * Note: RAM BIST code should be put right here, before loading the
15526 * microcode and after saving the RISC memory BIOS region.
15527 */
15528
15529 /*
15530 * LRAM Pre-test
15531 *
15532 * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
15533 * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
15534 * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
15535 * to NORMAL_MODE, return an error too.
15536 */
15537 for (i = 0; i < 2; i++) {
15538 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
15539 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
15540 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
15541 if ((byte & RAM_TEST_DONE) == 0
15542 || (byte & 0x0F) != PRE_TEST_VALUE) {
15543 asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
15544 return ADV_ERROR;
15545 }
15546
15547 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
15548 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
15549 if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
15550 != NORMAL_VALUE) {
15551 asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
15552 return ADV_ERROR;
15553 }
15554 }
1da177e4 15555
27c868c2
MW
15556 /*
15557 * LRAM Test - It takes about 1.5 ms to run through the test.
15558 *
15559 * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
15560 * If Done bit not set or Status not 0, save register byte, set the
15561 * err_code, and return an error.
15562 */
15563 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
15564 DvcSleepMilliSecond(10); /* Wait for 10ms before checking status. */
15565
15566 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
15567 if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) {
15568 /* Get here if Done bit not set or Status not 0. */
15569 asc_dvc->bist_err_code = byte; /* for BIOS display message */
15570 asc_dvc->err_code |= ASC_IERR_BIST_RAM_TEST;
15571 return ADV_ERROR;
15572 }
1da177e4 15573
27c868c2
MW
15574 /* We need to reset back to normal mode after LRAM test passes. */
15575 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
15576
15577 /*
15578 * Load the Microcode
15579 *
15580 * Write the microcode image to RISC memory starting at address 0.
15581 *
15582 */
15583 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
15584
15585 /*
15586 * Assume the following compressed format of the microcode buffer:
15587 *
15588 * 254 word (508 byte) table indexed by byte code followed
15589 * by the following byte codes:
15590 *
15591 * 1-Byte Code:
15592 * 00: Emit word 0 in table.
15593 * 01: Emit word 1 in table.
15594 * .
15595 * FD: Emit word 253 in table.
15596 *
15597 * Multi-Byte Code:
15598 * FE WW WW: (3 byte code) Word to emit is the next word WW WW.
15599 * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
15600 */
15601 word = 0;
15602 for (i = 253 * 2; i < _adv_asc38C1600_size; i++) {
15603 if (_adv_asc38C1600_buf[i] == 0xff) {
15604 for (j = 0; j < _adv_asc38C1600_buf[i + 1]; j++) {
15605 AdvWriteWordAutoIncLram(iop_base, (((ushort)
15606 _adv_asc38C1600_buf
15607 [i +
15608 3] << 8) |
15609 _adv_asc38C1600_buf
15610 [i + 2]));
15611 word++;
15612 }
15613 i += 3;
15614 } else if (_adv_asc38C1600_buf[i] == 0xfe) {
15615 AdvWriteWordAutoIncLram(iop_base, (((ushort)
15616 _adv_asc38C1600_buf
15617 [i +
15618 2] << 8) |
15619 _adv_asc38C1600_buf[i
15620 +
15621 1]));
15622 i += 2;
15623 word++;
15624 } else {
15625 AdvWriteWordAutoIncLram(iop_base, (((ushort)
15626 _adv_asc38C1600_buf[(_adv_asc38C1600_buf[i] * 2) + 1] << 8) | _adv_asc38C1600_buf[_adv_asc38C1600_buf[i] * 2]));
15627 word++;
15628 }
15629 }
1da177e4 15630
27c868c2
MW
15631 /*
15632 * Set 'word' for later use to clear the rest of memory and save
15633 * the expanded mcode size.
15634 */
15635 word *= 2;
15636 adv_asc38C1600_expanded_size = word;
15637
15638 /*
15639 * Clear the rest of ASC-38C1600 Internal RAM (32KB).
15640 */
15641 for (; word < ADV_38C1600_MEMSIZE; word += 2) {
15642 AdvWriteWordAutoIncLram(iop_base, 0);
15643 }
1da177e4 15644
27c868c2
MW
15645 /*
15646 * Verify the microcode checksum.
15647 */
15648 sum = 0;
15649 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
1da177e4 15650
27c868c2
MW
15651 for (word = 0; word < adv_asc38C1600_expanded_size; word += 2) {
15652 sum += AdvReadWordAutoIncLram(iop_base);
15653 }
1da177e4 15654
27c868c2
MW
15655 if (sum != _adv_asc38C1600_chksum) {
15656 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
15657 return ADV_ERROR;
15658 }
1da177e4 15659
27c868c2
MW
15660 /*
15661 * Restore the RISC memory BIOS region.
15662 */
15663 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
15664 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
15665 bios_mem[i]);
15666 }
1da177e4 15667
27c868c2
MW
15668 /*
15669 * Calculate and write the microcode code checksum to the microcode
15670 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
15671 */
15672 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
15673 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
15674 code_sum = 0;
15675 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
15676 for (word = begin_addr; word < end_addr; word += 2) {
15677 code_sum += AdvReadWordAutoIncLram(iop_base);
15678 }
15679 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
15680
15681 /*
15682 * Read microcode version and date.
15683 */
15684 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
15685 asc_dvc->cfg->mcode_date);
15686 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
15687 asc_dvc->cfg->mcode_version);
15688
15689 /*
15690 * Set the chip type to indicate the ASC38C1600.
15691 */
15692 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C1600);
15693
15694 /*
15695 * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
15696 * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
15697 * cable detection and then we are able to read C_DET[3:0].
15698 *
15699 * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
15700 * Microcode Default Value' section below.
15701 */
15702 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
15703 AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1,
15704 scsi_cfg1 | DIS_TERM_DRV);
15705
15706 /*
15707 * If the PCI Configuration Command Register "Parity Error Response
15708 * Control" Bit was clear (0), then set the microcode variable
15709 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
15710 * to ignore DMA parity errors.
15711 */
15712 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
15713 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15714 word |= CONTROL_FLAG_IGNORE_PERR;
15715 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15716 }
1da177e4 15717
27c868c2
MW
15718 /*
15719 * If the BIOS control flag AIPP (Asynchronous Information
15720 * Phase Protection) disable bit is not set, then set the firmware
15721 * 'control_flag' CONTROL_FLAG_ENABLE_AIPP bit to enable
15722 * AIPP checking and encoding.
15723 */
15724 if ((asc_dvc->bios_ctrl & BIOS_CTRL_AIPP_DIS) == 0) {
15725 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15726 word |= CONTROL_FLAG_ENABLE_AIPP;
15727 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15728 }
1da177e4 15729
27c868c2
MW
15730 /*
15731 * For ASC-38C1600 use DMA_CFG0 default values: FIFO_THRESH_80B [6:4],
15732 * and START_CTL_TH [3:2].
15733 */
15734 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
15735 FIFO_THRESH_80B | START_CTL_TH | READ_CMD_MRM);
15736
15737 /*
15738 * Microcode operating variables for WDTR, SDTR, and command tag
15739 * queuing will be set in AdvInquiryHandling() based on what a
15740 * device reports it is capable of in Inquiry byte 7.
15741 *
15742 * If SCSI Bus Resets have been disabled, then directly set
15743 * SDTR and WDTR from the EEPROM configuration. This will allow
15744 * the BIOS and warm boot to work without a SCSI bus hang on
15745 * the Inquiry caused by host and target mismatched DTR values.
15746 * Without the SCSI Bus Reset, before an Inquiry a device can't
15747 * be assumed to be in Asynchronous, Narrow mode.
15748 */
15749 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
15750 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
15751 asc_dvc->wdtr_able);
15752 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
15753 asc_dvc->sdtr_able);
15754 }
1da177e4 15755
27c868c2
MW
15756 /*
15757 * Set microcode operating variables for DISC and SDTR_SPEED1,
15758 * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
15759 * configuration values.
15760 *
15761 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
15762 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
15763 * without determining here whether the device supports SDTR.
15764 */
15765 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
15766 asc_dvc->cfg->disc_enable);
15767 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
15768 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
15769 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
15770 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
15771
15772 /*
15773 * Set SCSI_CFG0 Microcode Default Value.
15774 *
15775 * The microcode will set the SCSI_CFG0 register using this value
15776 * after it is started below.
15777 */
15778 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
15779 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
15780 asc_dvc->chip_scsi_id);
15781
15782 /*
15783 * Calculate SCSI_CFG1 Microcode Default Value.
15784 *
15785 * The microcode will set the SCSI_CFG1 register using this value
15786 * after it is started below.
15787 *
15788 * Each ASC-38C1600 function has only two cable detect bits.
15789 * The bus mode override bits are in IOPB_SOFT_OVER_WR.
15790 */
15791 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
15792
15793 /*
15794 * If the cable is reversed all of the SCSI_CTRL register signals
15795 * will be set. Check for and return an error if this condition is
15796 * found.
15797 */
15798 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
15799 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
15800 return ADV_ERROR;
15801 }
1da177e4 15802
27c868c2
MW
15803 /*
15804 * Each ASC-38C1600 function has two connectors. Only an HVD device
15805 * can not be connected to either connector. An LVD device or SE device
15806 * may be connected to either connecor. If an SE device is connected,
15807 * then at most Ultra speed (20 Mhz) can be used on both connectors.
15808 *
15809 * If an HVD device is attached, return an error.
15810 */
15811 if (scsi_cfg1 & HVD) {
15812 asc_dvc->err_code |= ASC_IERR_HVD_DEVICE;
15813 return ADV_ERROR;
15814 }
1da177e4 15815
27c868c2
MW
15816 /*
15817 * Each function in the ASC-38C1600 uses only the SE cable detect and
15818 * termination because there are two connectors for each function. Each
15819 * function may use either LVD or SE mode. Corresponding the SE automatic
15820 * termination control EEPROM bits are used for each function. Each
15821 * function has its own EEPROM. If SE automatic control is enabled for
15822 * the function, then set the termination value based on a table listed
15823 * in a_condor.h.
15824 *
15825 * If manual termination is specified in the EEPROM for the function,
15826 * then 'termination' was set-up in AscInitFrom38C1600EEPROM() and is
15827 * ready to be 'ored' into SCSI_CFG1.
15828 */
15829 if ((asc_dvc->cfg->termination & TERM_SE) == 0) {
15830 /* SE automatic termination control is enabled. */
15831 switch (scsi_cfg1 & C_DET_SE) {
15832 /* TERM_SE_HI: on, TERM_SE_LO: on */
15833 case 0x1:
15834 case 0x2:
15835 case 0x3:
15836 asc_dvc->cfg->termination |= TERM_SE;
15837 break;
15838
15839 case 0x0:
15840 if (ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info) == 0) {
15841 /* Function 0 - TERM_SE_HI: off, TERM_SE_LO: off */
15842 } else {
15843 /* Function 1 - TERM_SE_HI: on, TERM_SE_LO: off */
15844 asc_dvc->cfg->termination |= TERM_SE_HI;
15845 }
15846 break;
15847 }
15848 }
1da177e4 15849
27c868c2
MW
15850 /*
15851 * Clear any set TERM_SE bits.
15852 */
15853 scsi_cfg1 &= ~TERM_SE;
15854
15855 /*
15856 * Invert the TERM_SE bits and then set 'scsi_cfg1'.
15857 */
15858 scsi_cfg1 |= (~asc_dvc->cfg->termination & TERM_SE);
15859
15860 /*
15861 * Clear Big Endian and Terminator Polarity bits and set possibly
15862 * modified termination control bits in the Microcode SCSI_CFG1
15863 * Register Value.
15864 *
15865 * Big Endian bit is not used even on big endian machines.
15866 */
15867 scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL);
15868
15869 /*
15870 * Set SCSI_CFG1 Microcode Default Value
15871 *
15872 * Set possibly modified termination control bits in the Microcode
15873 * SCSI_CFG1 Register Value.
15874 *
15875 * The microcode will set the SCSI_CFG1 register using this value
15876 * after it is started below.
15877 */
15878 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
15879
15880 /*
15881 * Set MEM_CFG Microcode Default Value
15882 *
15883 * The microcode will set the MEM_CFG register using this value
15884 * after it is started below.
15885 *
15886 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
15887 * are defined.
15888 *
15889 * ASC-38C1600 has 32KB internal memory.
15890 *
15891 * XXX - Since ASC38C1600 Rev.3 has a Local RAM failure issue, we come
15892 * out a special 16K Adv Library and Microcode version. After the issue
15893 * resolved, we should turn back to the 32K support. Both a_condor.h and
15894 * mcode.sas files also need to be updated.
15895 *
15896 * AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
15897 * BIOS_EN | RAM_SZ_32KB);
15898 */
15899 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
15900 BIOS_EN | RAM_SZ_16KB);
15901
15902 /*
15903 * Set SEL_MASK Microcode Default Value
15904 *
15905 * The microcode will set the SEL_MASK register using this value
15906 * after it is started below.
15907 */
15908 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
15909 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
15910
15911 /*
15912 * Build the carrier freelist.
15913 *
15914 * Driver must have already allocated memory and set 'carrier_buf'.
15915 */
15916
15917 ASC_ASSERT(asc_dvc->carrier_buf != NULL);
15918
15919 carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
15920 asc_dvc->carr_freelist = NULL;
15921 if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf) {
15922 buf_size = ADV_CARRIER_BUFSIZE;
15923 } else {
15924 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
15925 }
1da177e4 15926
27c868c2
MW
15927 do {
15928 /*
15929 * Get physical address for the carrier 'carrp'.
15930 */
15931 contig_len = sizeof(ADV_CARR_T);
15932 carr_paddr =
15933 cpu_to_le32(DvcGetPhyAddr
15934 (asc_dvc, NULL, (uchar *)carrp,
15935 (ADV_SDCNT *)&contig_len,
15936 ADV_IS_CARRIER_FLAG));
1da177e4 15937
27c868c2 15938 buf_size -= sizeof(ADV_CARR_T);
1da177e4 15939
27c868c2
MW
15940 /*
15941 * If the current carrier is not physically contiguous, then
15942 * maybe there was a page crossing. Try the next carrier aligned
15943 * start address.
15944 */
15945 if (contig_len < sizeof(ADV_CARR_T)) {
15946 carrp++;
15947 continue;
15948 }
15949
15950 carrp->carr_pa = carr_paddr;
15951 carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
1da177e4 15952
27c868c2
MW
15953 /*
15954 * Insert the carrier at the beginning of the freelist.
15955 */
15956 carrp->next_vpa =
15957 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
15958 asc_dvc->carr_freelist = carrp;
1da177e4 15959
27c868c2
MW
15960 carrp++;
15961 }
15962 while (buf_size > 0);
15963
15964 /*
15965 * Set-up the Host->RISC Initiator Command Queue (ICQ).
15966 */
15967 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
15968 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15969 return ADV_ERROR;
15970 }
15971 asc_dvc->carr_freelist = (ADV_CARR_T *)
15972 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
15973
15974 /*
15975 * The first command issued will be placed in the stopper carrier.
15976 */
15977 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15978
15979 /*
15980 * Set RISC ICQ physical address start value. Initialize the
15981 * COMMA register to the same value otherwise the RISC will
15982 * prematurely detect a command is available.
15983 */
15984 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
15985 AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
15986 le32_to_cpu(asc_dvc->icq_sp->carr_pa));
15987
15988 /*
15989 * Set-up the RISC->Host Initiator Response Queue (IRQ).
15990 */
15991 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
15992 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15993 return ADV_ERROR;
15994 }
15995 asc_dvc->carr_freelist = (ADV_CARR_T *)
15996 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
15997
15998 /*
15999 * The first command completed by the RISC will be placed in
16000 * the stopper.
16001 *
16002 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
16003 * completed the RISC will set the ASC_RQ_STOPPER bit.
16004 */
16005 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
16006
16007 /*
16008 * Set RISC IRQ physical address start value.
16009 */
16010 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
16011 asc_dvc->carr_pending_cnt = 0;
16012
16013 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
16014 (ADV_INTR_ENABLE_HOST_INTR |
16015 ADV_INTR_ENABLE_GLOBAL_INTR));
16016 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
16017 AdvWriteWordRegister(iop_base, IOPW_PC, word);
16018
16019 /* finally, finally, gentlemen, start your engine */
16020 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
16021
16022 /*
16023 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
16024 * Resets should be performed. The RISC has to be running
16025 * to issue a SCSI Bus Reset.
16026 */
16027 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
16028 /*
16029 * If the BIOS Signature is present in memory, restore the
16030 * per TID microcode operating variables.
16031 */
16032 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
16033 0x55AA) {
16034 /*
16035 * Restore per TID negotiated values.
16036 */
16037 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
16038 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
16039 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
16040 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
16041 tagqng_able);
16042 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
16043 AdvWriteByteLram(iop_base,
16044 ASC_MC_NUMBER_OF_MAX_CMD + tid,
16045 max_cmd[tid]);
16046 }
16047 } else {
16048 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
16049 warn_code = ASC_WARN_BUSRESET_ERROR;
16050 }
16051 }
16052 }
1da177e4 16053
27c868c2
MW
16054 return warn_code;
16055}
1da177e4 16056
27c868c2
MW
16057/*
16058 * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
16059 * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
16060 * all of this is done.
16061 *
16062 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
16063 *
16064 * For a non-fatal error return a warning code. If there are no warnings
16065 * then 0 is returned.
16066 *
16067 * Note: Chip is stopped on entry.
16068 */
16069static int __init AdvInitFrom3550EEP(ADV_DVC_VAR *asc_dvc)
16070{
16071 AdvPortAddr iop_base;
16072 ushort warn_code;
16073 ADVEEP_3550_CONFIG eep_config;
16074 int i;
1da177e4 16075
27c868c2 16076 iop_base = asc_dvc->iop_base;
1da177e4 16077
27c868c2 16078 warn_code = 0;
1da177e4 16079
27c868c2
MW
16080 /*
16081 * Read the board's EEPROM configuration.
16082 *
16083 * Set default values if a bad checksum is found.
16084 */
16085 if (AdvGet3550EEPConfig(iop_base, &eep_config) != eep_config.check_sum) {
16086 warn_code |= ASC_WARN_EEPROM_CHKSUM;
1da177e4 16087
27c868c2
MW
16088 /*
16089 * Set EEPROM default values.
16090 */
16091 for (i = 0; i < sizeof(ADVEEP_3550_CONFIG); i++) {
16092 *((uchar *)&eep_config + i) =
16093 *((uchar *)&Default_3550_EEPROM_Config + i);
16094 }
1da177e4 16095
27c868c2
MW
16096 /*
16097 * Assume the 6 byte board serial number that was read
16098 * from EEPROM is correct even if the EEPROM checksum
16099 * failed.
16100 */
16101 eep_config.serial_number_word3 =
16102 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
1da177e4 16103
27c868c2
MW
16104 eep_config.serial_number_word2 =
16105 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
1da177e4 16106
27c868c2
MW
16107 eep_config.serial_number_word1 =
16108 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
1da177e4 16109
27c868c2
MW
16110 AdvSet3550EEPConfig(iop_base, &eep_config);
16111 }
16112 /*
16113 * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
16114 * EEPROM configuration that was read.
16115 *
16116 * This is the mapping of EEPROM fields to Adv Library fields.
16117 */
16118 asc_dvc->wdtr_able = eep_config.wdtr_able;
16119 asc_dvc->sdtr_able = eep_config.sdtr_able;
16120 asc_dvc->ultra_able = eep_config.ultra_able;
16121 asc_dvc->tagqng_able = eep_config.tagqng_able;
16122 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
16123 asc_dvc->max_host_qng = eep_config.max_host_qng;
16124 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16125 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
16126 asc_dvc->start_motor = eep_config.start_motor;
16127 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
16128 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
16129 asc_dvc->no_scam = eep_config.scam_tolerant;
16130 asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
16131 asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
16132 asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
16133
16134 /*
16135 * Set the host maximum queuing (max. 253, min. 16) and the per device
16136 * maximum queuing (max. 63, min. 4).
16137 */
16138 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
16139 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16140 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
16141 /* If the value is zero, assume it is uninitialized. */
16142 if (eep_config.max_host_qng == 0) {
16143 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16144 } else {
16145 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
16146 }
16147 }
1da177e4 16148
27c868c2
MW
16149 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
16150 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16151 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
16152 /* If the value is zero, assume it is uninitialized. */
16153 if (eep_config.max_dvc_qng == 0) {
16154 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16155 } else {
16156 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
16157 }
16158 }
1da177e4 16159
27c868c2
MW
16160 /*
16161 * If 'max_dvc_qng' is greater than 'max_host_qng', then
16162 * set 'max_dvc_qng' to 'max_host_qng'.
16163 */
16164 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
16165 eep_config.max_dvc_qng = eep_config.max_host_qng;
16166 }
1da177e4 16167
27c868c2
MW
16168 /*
16169 * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
16170 * values based on possibly adjusted EEPROM values.
16171 */
16172 asc_dvc->max_host_qng = eep_config.max_host_qng;
16173 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16174
16175 /*
16176 * If the EEPROM 'termination' field is set to automatic (0), then set
16177 * the ADV_DVC_CFG 'termination' field to automatic also.
16178 *
16179 * If the termination is specified with a non-zero 'termination'
16180 * value check that a legal value is set and set the ADV_DVC_CFG
16181 * 'termination' field appropriately.
16182 */
16183 if (eep_config.termination == 0) {
16184 asc_dvc->cfg->termination = 0; /* auto termination */
16185 } else {
16186 /* Enable manual control with low off / high off. */
16187 if (eep_config.termination == 1) {
16188 asc_dvc->cfg->termination = TERM_CTL_SEL;
16189
16190 /* Enable manual control with low off / high on. */
16191 } else if (eep_config.termination == 2) {
16192 asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H;
16193
16194 /* Enable manual control with low on / high on. */
16195 } else if (eep_config.termination == 3) {
16196 asc_dvc->cfg->termination =
16197 TERM_CTL_SEL | TERM_CTL_H | TERM_CTL_L;
16198 } else {
16199 /*
16200 * The EEPROM 'termination' field contains a bad value. Use
16201 * automatic termination instead.
16202 */
16203 asc_dvc->cfg->termination = 0;
16204 warn_code |= ASC_WARN_EEPROM_TERMINATION;
16205 }
16206 }
1da177e4 16207
27c868c2
MW
16208 return warn_code;
16209}
1da177e4 16210
27c868c2
MW
16211/*
16212 * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
16213 * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
16214 * all of this is done.
16215 *
16216 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
16217 *
16218 * For a non-fatal error return a warning code. If there are no warnings
16219 * then 0 is returned.
16220 *
16221 * Note: Chip is stopped on entry.
16222 */
16223static int __init AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_dvc)
16224{
16225 AdvPortAddr iop_base;
16226 ushort warn_code;
16227 ADVEEP_38C0800_CONFIG eep_config;
16228 int i;
16229 uchar tid, termination;
16230 ushort sdtr_speed = 0;
16231
16232 iop_base = asc_dvc->iop_base;
16233
16234 warn_code = 0;
16235
16236 /*
16237 * Read the board's EEPROM configuration.
16238 *
16239 * Set default values if a bad checksum is found.
16240 */
16241 if (AdvGet38C0800EEPConfig(iop_base, &eep_config) !=
16242 eep_config.check_sum) {
16243 warn_code |= ASC_WARN_EEPROM_CHKSUM;
1da177e4 16244
27c868c2
MW
16245 /*
16246 * Set EEPROM default values.
16247 */
16248 for (i = 0; i < sizeof(ADVEEP_38C0800_CONFIG); i++) {
16249 *((uchar *)&eep_config + i) =
16250 *((uchar *)&Default_38C0800_EEPROM_Config + i);
16251 }
1da177e4 16252
27c868c2
MW
16253 /*
16254 * Assume the 6 byte board serial number that was read
16255 * from EEPROM is correct even if the EEPROM checksum
16256 * failed.
16257 */
16258 eep_config.serial_number_word3 =
16259 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
1da177e4 16260
27c868c2
MW
16261 eep_config.serial_number_word2 =
16262 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
1da177e4 16263
27c868c2
MW
16264 eep_config.serial_number_word1 =
16265 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
1da177e4 16266
27c868c2
MW
16267 AdvSet38C0800EEPConfig(iop_base, &eep_config);
16268 }
16269 /*
16270 * Set ADV_DVC_VAR and ADV_DVC_CFG variables from the
16271 * EEPROM configuration that was read.
16272 *
16273 * This is the mapping of EEPROM fields to Adv Library fields.
16274 */
16275 asc_dvc->wdtr_able = eep_config.wdtr_able;
16276 asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
16277 asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
16278 asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
16279 asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
16280 asc_dvc->tagqng_able = eep_config.tagqng_able;
16281 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
16282 asc_dvc->max_host_qng = eep_config.max_host_qng;
16283 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16284 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
16285 asc_dvc->start_motor = eep_config.start_motor;
16286 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
16287 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
16288 asc_dvc->no_scam = eep_config.scam_tolerant;
16289 asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
16290 asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
16291 asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
16292
16293 /*
16294 * For every Target ID if any of its 'sdtr_speed[1234]' bits
16295 * are set, then set an 'sdtr_able' bit for it.
16296 */
16297 asc_dvc->sdtr_able = 0;
16298 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
16299 if (tid == 0) {
16300 sdtr_speed = asc_dvc->sdtr_speed1;
16301 } else if (tid == 4) {
16302 sdtr_speed = asc_dvc->sdtr_speed2;
16303 } else if (tid == 8) {
16304 sdtr_speed = asc_dvc->sdtr_speed3;
16305 } else if (tid == 12) {
16306 sdtr_speed = asc_dvc->sdtr_speed4;
16307 }
16308 if (sdtr_speed & ADV_MAX_TID) {
16309 asc_dvc->sdtr_able |= (1 << tid);
16310 }
16311 sdtr_speed >>= 4;
16312 }
1da177e4 16313
27c868c2
MW
16314 /*
16315 * Set the host maximum queuing (max. 253, min. 16) and the per device
16316 * maximum queuing (max. 63, min. 4).
16317 */
16318 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
16319 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16320 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
16321 /* If the value is zero, assume it is uninitialized. */
16322 if (eep_config.max_host_qng == 0) {
16323 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16324 } else {
16325 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
16326 }
16327 }
1da177e4 16328
27c868c2
MW
16329 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
16330 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16331 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
16332 /* If the value is zero, assume it is uninitialized. */
16333 if (eep_config.max_dvc_qng == 0) {
16334 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16335 } else {
16336 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
16337 }
16338 }
1da177e4 16339
27c868c2
MW
16340 /*
16341 * If 'max_dvc_qng' is greater than 'max_host_qng', then
16342 * set 'max_dvc_qng' to 'max_host_qng'.
16343 */
16344 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
16345 eep_config.max_dvc_qng = eep_config.max_host_qng;
16346 }
1da177e4 16347
27c868c2
MW
16348 /*
16349 * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
16350 * values based on possibly adjusted EEPROM values.
16351 */
16352 asc_dvc->max_host_qng = eep_config.max_host_qng;
16353 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16354
16355 /*
16356 * If the EEPROM 'termination' field is set to automatic (0), then set
16357 * the ADV_DVC_CFG 'termination' field to automatic also.
16358 *
16359 * If the termination is specified with a non-zero 'termination'
16360 * value check that a legal value is set and set the ADV_DVC_CFG
16361 * 'termination' field appropriately.
16362 */
16363 if (eep_config.termination_se == 0) {
16364 termination = 0; /* auto termination for SE */
16365 } else {
16366 /* Enable manual control with low off / high off. */
16367 if (eep_config.termination_se == 1) {
16368 termination = 0;
16369
16370 /* Enable manual control with low off / high on. */
16371 } else if (eep_config.termination_se == 2) {
16372 termination = TERM_SE_HI;
16373
16374 /* Enable manual control with low on / high on. */
16375 } else if (eep_config.termination_se == 3) {
16376 termination = TERM_SE;
16377 } else {
16378 /*
16379 * The EEPROM 'termination_se' field contains a bad value.
16380 * Use automatic termination instead.
16381 */
16382 termination = 0;
16383 warn_code |= ASC_WARN_EEPROM_TERMINATION;
16384 }
16385 }
1da177e4 16386
27c868c2
MW
16387 if (eep_config.termination_lvd == 0) {
16388 asc_dvc->cfg->termination = termination; /* auto termination for LVD */
16389 } else {
16390 /* Enable manual control with low off / high off. */
16391 if (eep_config.termination_lvd == 1) {
16392 asc_dvc->cfg->termination = termination;
16393
16394 /* Enable manual control with low off / high on. */
16395 } else if (eep_config.termination_lvd == 2) {
16396 asc_dvc->cfg->termination = termination | TERM_LVD_HI;
16397
16398 /* Enable manual control with low on / high on. */
16399 } else if (eep_config.termination_lvd == 3) {
16400 asc_dvc->cfg->termination = termination | TERM_LVD;
16401 } else {
16402 /*
16403 * The EEPROM 'termination_lvd' field contains a bad value.
16404 * Use automatic termination instead.
16405 */
16406 asc_dvc->cfg->termination = termination;
16407 warn_code |= ASC_WARN_EEPROM_TERMINATION;
16408 }
16409 }
1da177e4 16410
27c868c2 16411 return warn_code;
1da177e4
LT
16412}
16413
16414/*
27c868c2
MW
16415 * Read the board's EEPROM configuration. Set fields in ASC_DVC_VAR and
16416 * ASC_DVC_CFG based on the EEPROM settings. The chip is stopped while
16417 * all of this is done.
1da177e4
LT
16418 *
16419 * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
16420 *
16421 * For a non-fatal error return a warning code. If there are no warnings
16422 * then 0 is returned.
16423 *
27c868c2 16424 * Note: Chip is stopped on entry.
1da177e4 16425 */
27c868c2 16426static int __init AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc)
1da177e4 16427{
27c868c2
MW
16428 AdvPortAddr iop_base;
16429 ushort warn_code;
16430 ADVEEP_38C1600_CONFIG eep_config;
16431 int i;
16432 uchar tid, termination;
16433 ushort sdtr_speed = 0;
16434
16435 iop_base = asc_dvc->iop_base;
16436
16437 warn_code = 0;
16438
16439 /*
16440 * Read the board's EEPROM configuration.
16441 *
16442 * Set default values if a bad checksum is found.
16443 */
16444 if (AdvGet38C1600EEPConfig(iop_base, &eep_config) !=
16445 eep_config.check_sum) {
16446 warn_code |= ASC_WARN_EEPROM_CHKSUM;
1da177e4 16447
27c868c2
MW
16448 /*
16449 * Set EEPROM default values.
16450 */
16451 for (i = 0; i < sizeof(ADVEEP_38C1600_CONFIG); i++) {
16452 if (i == 1
16453 && ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info) !=
16454 0) {
16455 /*
16456 * Set Function 1 EEPROM Word 0 MSB
16457 *
16458 * Clear the BIOS_ENABLE (bit 14) and INTAB (bit 11)
16459 * EEPROM bits.
16460 *
16461 * Disable Bit 14 (BIOS_ENABLE) to fix SPARC Ultra 60 and
16462 * old Mac system booting problem. The Expansion ROM must
16463 * be disabled in Function 1 for these systems.
16464 *
16465 */
16466 *((uchar *)&eep_config + i) =
16467 ((*
16468 ((uchar *)&Default_38C1600_EEPROM_Config
16469 +
16470 i)) &
16471 (~
16472 (((ADV_EEPROM_BIOS_ENABLE |
16473 ADV_EEPROM_INTAB) >> 8) & 0xFF)));
16474
16475 /*
16476 * Set the INTAB (bit 11) if the GPIO 0 input indicates
16477 * the Function 1 interrupt line is wired to INTA.
16478 *
16479 * Set/Clear Bit 11 (INTAB) from the GPIO bit 0 input:
16480 * 1 - Function 1 interrupt line wired to INT A.
16481 * 0 - Function 1 interrupt line wired to INT B.
16482 *
16483 * Note: Adapter boards always have Function 0 wired to INTA.
16484 * Put all 5 GPIO bits in input mode and then read
16485 * their input values.
16486 */
16487 AdvWriteByteRegister(iop_base, IOPB_GPIO_CNTL,
16488 0);
16489 if (AdvReadByteRegister
16490 (iop_base, IOPB_GPIO_DATA) & 0x01) {
16491 /* Function 1 interrupt wired to INTA; Set EEPROM bit. */
16492 *((uchar *)&eep_config + i) |=
16493 ((ADV_EEPROM_INTAB >> 8) & 0xFF);
16494 }
16495 } else {
16496 *((uchar *)&eep_config + i) =
16497 *((uchar *)&Default_38C1600_EEPROM_Config
16498 + i);
16499 }
16500 }
1da177e4 16501
27c868c2
MW
16502 /*
16503 * Assume the 6 byte board serial number that was read
16504 * from EEPROM is correct even if the EEPROM checksum
16505 * failed.
16506 */
16507 eep_config.serial_number_word3 =
16508 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
1da177e4 16509
27c868c2
MW
16510 eep_config.serial_number_word2 =
16511 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
1da177e4 16512
27c868c2
MW
16513 eep_config.serial_number_word1 =
16514 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
1da177e4 16515
27c868c2
MW
16516 AdvSet38C1600EEPConfig(iop_base, &eep_config);
16517 }
1da177e4 16518
27c868c2
MW
16519 /*
16520 * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
16521 * EEPROM configuration that was read.
16522 *
16523 * This is the mapping of EEPROM fields to Adv Library fields.
16524 */
16525 asc_dvc->wdtr_able = eep_config.wdtr_able;
16526 asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
16527 asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
16528 asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
16529 asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
16530 asc_dvc->ppr_able = 0;
16531 asc_dvc->tagqng_able = eep_config.tagqng_able;
16532 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
16533 asc_dvc->max_host_qng = eep_config.max_host_qng;
16534 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16535 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ASC_MAX_TID);
16536 asc_dvc->start_motor = eep_config.start_motor;
16537 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
16538 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
16539 asc_dvc->no_scam = eep_config.scam_tolerant;
16540
16541 /*
16542 * For every Target ID if any of its 'sdtr_speed[1234]' bits
16543 * are set, then set an 'sdtr_able' bit for it.
16544 */
16545 asc_dvc->sdtr_able = 0;
16546 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
16547 if (tid == 0) {
16548 sdtr_speed = asc_dvc->sdtr_speed1;
16549 } else if (tid == 4) {
16550 sdtr_speed = asc_dvc->sdtr_speed2;
16551 } else if (tid == 8) {
16552 sdtr_speed = asc_dvc->sdtr_speed3;
16553 } else if (tid == 12) {
16554 sdtr_speed = asc_dvc->sdtr_speed4;
16555 }
16556 if (sdtr_speed & ASC_MAX_TID) {
16557 asc_dvc->sdtr_able |= (1 << tid);
16558 }
16559 sdtr_speed >>= 4;
16560 }
1da177e4 16561
27c868c2
MW
16562 /*
16563 * Set the host maximum queuing (max. 253, min. 16) and the per device
16564 * maximum queuing (max. 63, min. 4).
16565 */
16566 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
16567 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16568 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
16569 /* If the value is zero, assume it is uninitialized. */
16570 if (eep_config.max_host_qng == 0) {
16571 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16572 } else {
16573 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
16574 }
16575 }
1da177e4 16576
27c868c2
MW
16577 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
16578 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16579 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
16580 /* If the value is zero, assume it is uninitialized. */
16581 if (eep_config.max_dvc_qng == 0) {
16582 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16583 } else {
16584 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
16585 }
16586 }
1da177e4 16587
27c868c2
MW
16588 /*
16589 * If 'max_dvc_qng' is greater than 'max_host_qng', then
16590 * set 'max_dvc_qng' to 'max_host_qng'.
16591 */
16592 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
16593 eep_config.max_dvc_qng = eep_config.max_host_qng;
16594 }
1da177e4 16595
27c868c2
MW
16596 /*
16597 * Set ASC_DVC_VAR 'max_host_qng' and ASC_DVC_VAR 'max_dvc_qng'
16598 * values based on possibly adjusted EEPROM values.
16599 */
16600 asc_dvc->max_host_qng = eep_config.max_host_qng;
16601 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16602
16603 /*
16604 * If the EEPROM 'termination' field is set to automatic (0), then set
16605 * the ASC_DVC_CFG 'termination' field to automatic also.
16606 *
16607 * If the termination is specified with a non-zero 'termination'
16608 * value check that a legal value is set and set the ASC_DVC_CFG
16609 * 'termination' field appropriately.
16610 */
16611 if (eep_config.termination_se == 0) {
16612 termination = 0; /* auto termination for SE */
16613 } else {
16614 /* Enable manual control with low off / high off. */
16615 if (eep_config.termination_se == 1) {
16616 termination = 0;
16617
16618 /* Enable manual control with low off / high on. */
16619 } else if (eep_config.termination_se == 2) {
16620 termination = TERM_SE_HI;
16621
16622 /* Enable manual control with low on / high on. */
16623 } else if (eep_config.termination_se == 3) {
16624 termination = TERM_SE;
16625 } else {
16626 /*
16627 * The EEPROM 'termination_se' field contains a bad value.
16628 * Use automatic termination instead.
16629 */
16630 termination = 0;
16631 warn_code |= ASC_WARN_EEPROM_TERMINATION;
16632 }
16633 }
1da177e4 16634
27c868c2
MW
16635 if (eep_config.termination_lvd == 0) {
16636 asc_dvc->cfg->termination = termination; /* auto termination for LVD */
16637 } else {
16638 /* Enable manual control with low off / high off. */
16639 if (eep_config.termination_lvd == 1) {
16640 asc_dvc->cfg->termination = termination;
16641
16642 /* Enable manual control with low off / high on. */
16643 } else if (eep_config.termination_lvd == 2) {
16644 asc_dvc->cfg->termination = termination | TERM_LVD_HI;
16645
16646 /* Enable manual control with low on / high on. */
16647 } else if (eep_config.termination_lvd == 3) {
16648 asc_dvc->cfg->termination = termination | TERM_LVD;
16649 } else {
16650 /*
16651 * The EEPROM 'termination_lvd' field contains a bad value.
16652 * Use automatic termination instead.
16653 */
16654 asc_dvc->cfg->termination = termination;
16655 warn_code |= ASC_WARN_EEPROM_TERMINATION;
16656 }
16657 }
1da177e4 16658
27c868c2 16659 return warn_code;
1da177e4
LT
16660}
16661
16662/*
16663 * Read EEPROM configuration into the specified buffer.
16664 *
16665 * Return a checksum based on the EEPROM configuration read.
16666 */
27c868c2 16667static ushort __init
1da177e4
LT
16668AdvGet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
16669{
27c868c2
MW
16670 ushort wval, chksum;
16671 ushort *wbuf;
16672 int eep_addr;
16673 ushort *charfields;
16674
16675 charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar;
16676 wbuf = (ushort *)cfg_buf;
16677 chksum = 0;
16678
16679 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
16680 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
16681 wval = AdvReadEEPWord(iop_base, eep_addr);
16682 chksum += wval; /* Checksum is calculated from word values. */
16683 if (*charfields++) {
16684 *wbuf = le16_to_cpu(wval);
16685 } else {
16686 *wbuf = wval;
16687 }
16688 }
16689 /* Read checksum word. */
16690 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16691 wbuf++;
16692 charfields++;
16693
16694 /* Read rest of EEPROM not covered by the checksum. */
16695 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
16696 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
16697 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16698 if (*charfields++) {
16699 *wbuf = le16_to_cpu(*wbuf);
16700 }
16701 }
16702 return chksum;
1da177e4
LT
16703}
16704
16705/*
16706 * Read EEPROM configuration into the specified buffer.
16707 *
16708 * Return a checksum based on the EEPROM configuration read.
16709 */
27c868c2
MW
16710static ushort __init
16711AdvGet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf)
1da177e4 16712{
27c868c2
MW
16713 ushort wval, chksum;
16714 ushort *wbuf;
16715 int eep_addr;
16716 ushort *charfields;
16717
16718 charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar;
16719 wbuf = (ushort *)cfg_buf;
16720 chksum = 0;
16721
16722 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
16723 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
16724 wval = AdvReadEEPWord(iop_base, eep_addr);
16725 chksum += wval; /* Checksum is calculated from word values. */
16726 if (*charfields++) {
16727 *wbuf = le16_to_cpu(wval);
16728 } else {
16729 *wbuf = wval;
16730 }
16731 }
16732 /* Read checksum word. */
16733 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16734 wbuf++;
16735 charfields++;
16736
16737 /* Read rest of EEPROM not covered by the checksum. */
16738 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
16739 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
16740 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16741 if (*charfields++) {
16742 *wbuf = le16_to_cpu(*wbuf);
16743 }
16744 }
16745 return chksum;
1da177e4
LT
16746}
16747
16748/*
16749 * Read EEPROM configuration into the specified buffer.
16750 *
16751 * Return a checksum based on the EEPROM configuration read.
16752 */
27c868c2
MW
16753static ushort __init
16754AdvGet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf)
1da177e4 16755{
27c868c2
MW
16756 ushort wval, chksum;
16757 ushort *wbuf;
16758 int eep_addr;
16759 ushort *charfields;
16760
16761 charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar;
16762 wbuf = (ushort *)cfg_buf;
16763 chksum = 0;
16764
16765 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
16766 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
16767 wval = AdvReadEEPWord(iop_base, eep_addr);
16768 chksum += wval; /* Checksum is calculated from word values. */
16769 if (*charfields++) {
16770 *wbuf = le16_to_cpu(wval);
16771 } else {
16772 *wbuf = wval;
16773 }
16774 }
16775 /* Read checksum word. */
16776 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16777 wbuf++;
16778 charfields++;
16779
16780 /* Read rest of EEPROM not covered by the checksum. */
16781 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
16782 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
16783 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16784 if (*charfields++) {
16785 *wbuf = le16_to_cpu(*wbuf);
16786 }
16787 }
16788 return chksum;
1da177e4
LT
16789}
16790
16791/*
16792 * Read the EEPROM from specified location
16793 */
27c868c2 16794static ushort __init AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr)
1da177e4 16795{
27c868c2
MW
16796 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16797 ASC_EEP_CMD_READ | eep_word_addr);
16798 AdvWaitEEPCmd(iop_base);
16799 return AdvReadWordRegister(iop_base, IOPW_EE_DATA);
1da177e4
LT
16800}
16801
16802/*
16803 * Wait for EEPROM command to complete
16804 */
27c868c2 16805static void __init AdvWaitEEPCmd(AdvPortAddr iop_base)
1da177e4 16806{
27c868c2
MW
16807 int eep_delay_ms;
16808
16809 for (eep_delay_ms = 0; eep_delay_ms < ADV_EEP_DELAY_MS; eep_delay_ms++) {
16810 if (AdvReadWordRegister(iop_base, IOPW_EE_CMD) &
16811 ASC_EEP_CMD_DONE) {
16812 break;
16813 }
16814 DvcSleepMilliSecond(1);
16815 }
16816 if ((AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE) ==
16817 0) {
16818 ASC_ASSERT(0);
16819 }
16820 return;
1da177e4
LT
16821}
16822
16823/*
16824 * Write the EEPROM from 'cfg_buf'.
16825 */
c836043e 16826void __init
1da177e4
LT
16827AdvSet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
16828{
27c868c2
MW
16829 ushort *wbuf;
16830 ushort addr, chksum;
16831 ushort *charfields;
16832
16833 wbuf = (ushort *)cfg_buf;
16834 charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar;
16835 chksum = 0;
16836
16837 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
16838 AdvWaitEEPCmd(iop_base);
16839
16840 /*
16841 * Write EEPROM from word 0 to word 20.
16842 */
16843 for (addr = ADV_EEP_DVC_CFG_BEGIN;
16844 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
16845 ushort word;
16846
16847 if (*charfields++) {
16848 word = cpu_to_le16(*wbuf);
16849 } else {
16850 word = *wbuf;
16851 }
16852 chksum += *wbuf; /* Checksum is calculated from word values. */
16853 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16854 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16855 ASC_EEP_CMD_WRITE | addr);
16856 AdvWaitEEPCmd(iop_base);
16857 DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
16858 }
1da177e4 16859
27c868c2
MW
16860 /*
16861 * Write EEPROM checksum at word 21.
16862 */
16863 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
16864 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
16865 AdvWaitEEPCmd(iop_base);
16866 wbuf++;
16867 charfields++;
16868
16869 /*
16870 * Write EEPROM OEM name at words 22 to 29.
16871 */
16872 for (addr = ADV_EEP_DVC_CTL_BEGIN;
16873 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
16874 ushort word;
16875
16876 if (*charfields++) {
16877 word = cpu_to_le16(*wbuf);
16878 } else {
16879 word = *wbuf;
16880 }
16881 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16882 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16883 ASC_EEP_CMD_WRITE | addr);
16884 AdvWaitEEPCmd(iop_base);
16885 }
16886 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
16887 AdvWaitEEPCmd(iop_base);
16888 return;
1da177e4
LT
16889}
16890
16891/*
16892 * Write the EEPROM from 'cfg_buf'.
16893 */
c836043e 16894void __init
27c868c2 16895AdvSet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf)
1da177e4 16896{
27c868c2
MW
16897 ushort *wbuf;
16898 ushort *charfields;
16899 ushort addr, chksum;
16900
16901 wbuf = (ushort *)cfg_buf;
16902 charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar;
16903 chksum = 0;
16904
16905 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
16906 AdvWaitEEPCmd(iop_base);
16907
16908 /*
16909 * Write EEPROM from word 0 to word 20.
16910 */
16911 for (addr = ADV_EEP_DVC_CFG_BEGIN;
16912 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
16913 ushort word;
16914
16915 if (*charfields++) {
16916 word = cpu_to_le16(*wbuf);
16917 } else {
16918 word = *wbuf;
16919 }
16920 chksum += *wbuf; /* Checksum is calculated from word values. */
16921 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16922 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16923 ASC_EEP_CMD_WRITE | addr);
16924 AdvWaitEEPCmd(iop_base);
16925 DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
16926 }
1da177e4 16927
27c868c2
MW
16928 /*
16929 * Write EEPROM checksum at word 21.
16930 */
16931 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
16932 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
16933 AdvWaitEEPCmd(iop_base);
16934 wbuf++;
16935 charfields++;
16936
16937 /*
16938 * Write EEPROM OEM name at words 22 to 29.
16939 */
16940 for (addr = ADV_EEP_DVC_CTL_BEGIN;
16941 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
16942 ushort word;
16943
16944 if (*charfields++) {
16945 word = cpu_to_le16(*wbuf);
16946 } else {
16947 word = *wbuf;
16948 }
16949 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16950 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16951 ASC_EEP_CMD_WRITE | addr);
16952 AdvWaitEEPCmd(iop_base);
16953 }
16954 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
16955 AdvWaitEEPCmd(iop_base);
16956 return;
1da177e4
LT
16957}
16958
16959/*
16960 * Write the EEPROM from 'cfg_buf'.
16961 */
c836043e 16962void __init
27c868c2 16963AdvSet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf)
1da177e4 16964{
27c868c2
MW
16965 ushort *wbuf;
16966 ushort *charfields;
16967 ushort addr, chksum;
16968
16969 wbuf = (ushort *)cfg_buf;
16970 charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar;
16971 chksum = 0;
16972
16973 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
16974 AdvWaitEEPCmd(iop_base);
16975
16976 /*
16977 * Write EEPROM from word 0 to word 20.
16978 */
16979 for (addr = ADV_EEP_DVC_CFG_BEGIN;
16980 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
16981 ushort word;
16982
16983 if (*charfields++) {
16984 word = cpu_to_le16(*wbuf);
16985 } else {
16986 word = *wbuf;
16987 }
16988 chksum += *wbuf; /* Checksum is calculated from word values. */
16989 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16990 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16991 ASC_EEP_CMD_WRITE | addr);
16992 AdvWaitEEPCmd(iop_base);
16993 DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
16994 }
1da177e4 16995
27c868c2
MW
16996 /*
16997 * Write EEPROM checksum at word 21.
16998 */
16999 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
17000 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17001 AdvWaitEEPCmd(iop_base);
17002 wbuf++;
17003 charfields++;
17004
17005 /*
17006 * Write EEPROM OEM name at words 22 to 29.
17007 */
17008 for (addr = ADV_EEP_DVC_CTL_BEGIN;
17009 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
17010 ushort word;
17011
17012 if (*charfields++) {
17013 word = cpu_to_le16(*wbuf);
17014 } else {
17015 word = *wbuf;
17016 }
17017 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
17018 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
17019 ASC_EEP_CMD_WRITE | addr);
17020 AdvWaitEEPCmd(iop_base);
17021 }
17022 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
17023 AdvWaitEEPCmd(iop_base);
17024 return;
1da177e4
LT
17025}
17026
17027/* a_advlib.c */
17028/*
17029 * AdvExeScsiQueue() - Send a request to the RISC microcode program.
17030 *
17031 * Allocate a carrier structure, point the carrier to the ADV_SCSI_REQ_Q,
17032 * add the carrier to the ICQ (Initiator Command Queue), and tickle the
17033 * RISC to notify it a new command is ready to be executed.
17034 *
17035 * If 'done_status' is not set to QD_DO_RETRY, then 'error_retry' will be
17036 * set to SCSI_MAX_RETRY.
17037 *
17038 * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the microcode
17039 * for DMA addresses or math operations are byte swapped to little-endian
17040 * order.
17041 *
17042 * Return:
17043 * ADV_SUCCESS(1) - The request was successfully queued.
17044 * ADV_BUSY(0) - Resource unavailable; Retry again after pending
17045 * request completes.
17046 * ADV_ERROR(-1) - Invalid ADV_SCSI_REQ_Q request structure
17047 * host IC error.
17048 */
27c868c2 17049static int AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq)
1da177e4 17050{
27c868c2
MW
17051 ulong last_int_level;
17052 AdvPortAddr iop_base;
17053 ADV_DCNT req_size;
17054 ADV_PADDR req_paddr;
17055 ADV_CARR_T *new_carrp;
17056
17057 ASC_ASSERT(scsiq != NULL); /* 'scsiq' should never be NULL. */
17058
17059 /*
17060 * The ADV_SCSI_REQ_Q 'target_id' field should never exceed ADV_MAX_TID.
17061 */
17062 if (scsiq->target_id > ADV_MAX_TID) {
17063 scsiq->host_status = QHSTA_M_INVALID_DEVICE;
17064 scsiq->done_status = QD_WITH_ERROR;
17065 return ADV_ERROR;
17066 }
1da177e4 17067
27c868c2 17068 iop_base = asc_dvc->iop_base;
1da177e4 17069
27c868c2 17070 last_int_level = DvcEnterCritical();
1da177e4 17071
27c868c2
MW
17072 /*
17073 * Allocate a carrier ensuring at least one carrier always
17074 * remains on the freelist and initialize fields.
17075 */
17076 if ((new_carrp = asc_dvc->carr_freelist) == NULL) {
17077 DvcLeaveCritical(last_int_level);
17078 return ADV_BUSY;
17079 }
17080 asc_dvc->carr_freelist = (ADV_CARR_T *)
17081 ADV_U32_TO_VADDR(le32_to_cpu(new_carrp->next_vpa));
17082 asc_dvc->carr_pending_cnt++;
17083
17084 /*
17085 * Set the carrier to be a stopper by setting 'next_vpa'
17086 * to the stopper value. The current stopper will be changed
17087 * below to point to the new stopper.
17088 */
17089 new_carrp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
17090
17091 /*
17092 * Clear the ADV_SCSI_REQ_Q done flag.
17093 */
17094 scsiq->a_flag &= ~ADV_SCSIQ_DONE;
17095
17096 req_size = sizeof(ADV_SCSI_REQ_Q);
17097 req_paddr = DvcGetPhyAddr(asc_dvc, scsiq, (uchar *)scsiq,
17098 (ADV_SDCNT *)&req_size, ADV_IS_SCSIQ_FLAG);
17099
17100 ASC_ASSERT(ADV_32BALIGN(req_paddr) == req_paddr);
17101 ASC_ASSERT(req_size >= sizeof(ADV_SCSI_REQ_Q));
17102
17103 /* Wait for assertion before making little-endian */
17104 req_paddr = cpu_to_le32(req_paddr);
17105
17106 /* Save virtual and physical address of ADV_SCSI_REQ_Q and carrier. */
17107 scsiq->scsiq_ptr = cpu_to_le32(ADV_VADDR_TO_U32(scsiq));
17108 scsiq->scsiq_rptr = req_paddr;
17109
17110 scsiq->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->icq_sp));
17111 /*
17112 * Every ADV_CARR_T.carr_pa is byte swapped to little-endian
17113 * order during initialization.
17114 */
17115 scsiq->carr_pa = asc_dvc->icq_sp->carr_pa;
17116
17117 /*
17118 * Use the current stopper to send the ADV_SCSI_REQ_Q command to
17119 * the microcode. The newly allocated stopper will become the new
17120 * stopper.
17121 */
17122 asc_dvc->icq_sp->areq_vpa = req_paddr;
17123
17124 /*
17125 * Set the 'next_vpa' pointer for the old stopper to be the
17126 * physical address of the new stopper. The RISC can only
17127 * follow physical addresses.
17128 */
17129 asc_dvc->icq_sp->next_vpa = new_carrp->carr_pa;
17130
17131 /*
17132 * Set the host adapter stopper pointer to point to the new carrier.
17133 */
17134 asc_dvc->icq_sp = new_carrp;
17135
17136 if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
17137 asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
17138 /*
17139 * Tickle the RISC to tell it to read its Command Queue Head pointer.
17140 */
17141 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_A);
17142 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
17143 /*
17144 * Clear the tickle value. In the ASC-3550 the RISC flag
17145 * command 'clr_tickle_a' does not work unless the host
17146 * value is cleared.
17147 */
17148 AdvWriteByteRegister(iop_base, IOPB_TICKLE,
17149 ADV_TICKLE_NOP);
17150 }
17151 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
17152 /*
17153 * Notify the RISC a carrier is ready by writing the physical
17154 * address of the new carrier stopper to the COMMA register.
17155 */
17156 AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
17157 le32_to_cpu(new_carrp->carr_pa));
17158 }
1da177e4 17159
27c868c2 17160 DvcLeaveCritical(last_int_level);
1da177e4 17161
27c868c2 17162 return ADV_SUCCESS;
1da177e4
LT
17163}
17164
17165/*
17166 * Reset SCSI Bus and purge all outstanding requests.
17167 *
17168 * Return Value:
17169 * ADV_TRUE(1) - All requests are purged and SCSI Bus is reset.
17170 * ADV_FALSE(0) - Microcode command failed.
17171 * ADV_ERROR(-1) - Microcode command timed-out. Microcode or IC
17172 * may be hung which requires driver recovery.
17173 */
27c868c2 17174static int AdvResetSB(ADV_DVC_VAR *asc_dvc)
1da177e4 17175{
27c868c2
MW
17176 int status;
17177
17178 /*
17179 * Send the SCSI Bus Reset idle start idle command which asserts
17180 * the SCSI Bus Reset signal.
17181 */
17182 status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_START, 0L);
17183 if (status != ADV_TRUE) {
17184 return status;
17185 }
1da177e4 17186
27c868c2
MW
17187 /*
17188 * Delay for the specified SCSI Bus Reset hold time.
17189 *
17190 * The hold time delay is done on the host because the RISC has no
17191 * microsecond accurate timer.
17192 */
17193 DvcDelayMicroSecond(asc_dvc, (ushort)ASC_SCSI_RESET_HOLD_TIME_US);
17194
17195 /*
17196 * Send the SCSI Bus Reset end idle command which de-asserts
17197 * the SCSI Bus Reset signal and purges any pending requests.
17198 */
17199 status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_END, 0L);
17200 if (status != ADV_TRUE) {
17201 return status;
17202 }
17203
17204 DvcSleepMilliSecond((ADV_DCNT)asc_dvc->scsi_reset_wait * 1000);
1da177e4 17205
27c868c2 17206 return status;
1da177e4
LT
17207}
17208
17209/*
17210 * Reset chip and SCSI Bus.
17211 *
17212 * Return Value:
17213 * ADV_TRUE(1) - Chip re-initialization and SCSI Bus Reset successful.
17214 * ADV_FALSE(0) - Chip re-initialization and SCSI Bus Reset failure.
17215 */
27c868c2 17216static int AdvResetChipAndSB(ADV_DVC_VAR *asc_dvc)
1da177e4 17217{
27c868c2
MW
17218 int status;
17219 ushort wdtr_able, sdtr_able, tagqng_able;
17220 ushort ppr_able = 0;
17221 uchar tid, max_cmd[ADV_MAX_TID + 1];
17222 AdvPortAddr iop_base;
17223 ushort bios_sig;
17224
17225 iop_base = asc_dvc->iop_base;
17226
17227 /*
17228 * Save current per TID negotiated values.
17229 */
17230 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
17231 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
17232 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
17233 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
17234 }
17235 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
17236 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
17237 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
17238 max_cmd[tid]);
17239 }
1da177e4 17240
27c868c2
MW
17241 /*
17242 * Force the AdvInitAsc3550/38C0800Driver() function to
17243 * perform a SCSI Bus Reset by clearing the BIOS signature word.
17244 * The initialization functions assumes a SCSI Bus Reset is not
17245 * needed if the BIOS signature word is present.
17246 */
17247 AdvReadWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
17248 AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, 0);
17249
17250 /*
17251 * Stop chip and reset it.
17252 */
17253 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_STOP);
17254 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_RESET);
17255 DvcSleepMilliSecond(100);
17256 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
17257 ADV_CTRL_REG_CMD_WR_IO_REG);
17258
17259 /*
17260 * Reset Adv Library error code, if any, and try
17261 * re-initializing the chip.
17262 */
17263 asc_dvc->err_code = 0;
17264 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
17265 status = AdvInitAsc38C1600Driver(asc_dvc);
17266 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
17267 status = AdvInitAsc38C0800Driver(asc_dvc);
17268 } else {
17269 status = AdvInitAsc3550Driver(asc_dvc);
17270 }
1da177e4 17271
27c868c2
MW
17272 /* Translate initialization return value to status value. */
17273 if (status == 0) {
17274 status = ADV_TRUE;
17275 } else {
17276 status = ADV_FALSE;
17277 }
1da177e4 17278
27c868c2
MW
17279 /*
17280 * Restore the BIOS signature word.
17281 */
17282 AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
17283
17284 /*
17285 * Restore per TID negotiated values.
17286 */
17287 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
17288 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
17289 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
17290 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
17291 }
17292 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
17293 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
17294 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
17295 max_cmd[tid]);
17296 }
1da177e4 17297
27c868c2 17298 return status;
1da177e4
LT
17299}
17300
17301/*
17302 * Adv Library Interrupt Service Routine
17303 *
17304 * This function is called by a driver's interrupt service routine.
17305 * The function disables and re-enables interrupts.
17306 *
17307 * When a microcode idle command is completed, the ADV_DVC_VAR
17308 * 'idle_cmd_done' field is set to ADV_TRUE.
17309 *
17310 * Note: AdvISR() can be called when interrupts are disabled or even
17311 * when there is no hardware interrupt condition present. It will
17312 * always check for completed idle commands and microcode requests.
17313 * This is an important feature that shouldn't be changed because it
17314 * allows commands to be completed from polling mode loops.
17315 *
17316 * Return:
17317 * ADV_TRUE(1) - interrupt was pending
17318 * ADV_FALSE(0) - no interrupt was pending
17319 */
27c868c2 17320static int AdvISR(ADV_DVC_VAR *asc_dvc)
1da177e4 17321{
27c868c2
MW
17322 AdvPortAddr iop_base;
17323 uchar int_stat;
17324 ushort target_bit;
17325 ADV_CARR_T *free_carrp;
17326 ADV_VADDR irq_next_vpa;
17327 int flags;
17328 ADV_SCSI_REQ_Q *scsiq;
1da177e4 17329
27c868c2 17330 flags = DvcEnterCritical();
1da177e4 17331
27c868c2
MW
17332 iop_base = asc_dvc->iop_base;
17333
17334 /* Reading the register clears the interrupt. */
17335 int_stat = AdvReadByteRegister(iop_base, IOPB_INTR_STATUS_REG);
17336
17337 if ((int_stat & (ADV_INTR_STATUS_INTRA | ADV_INTR_STATUS_INTRB |
17338 ADV_INTR_STATUS_INTRC)) == 0) {
17339 DvcLeaveCritical(flags);
17340 return ADV_FALSE;
17341 }
17342
17343 /*
17344 * Notify the driver of an asynchronous microcode condition by
17345 * calling the ADV_DVC_VAR.async_callback function. The function
17346 * is passed the microcode ASC_MC_INTRB_CODE byte value.
17347 */
17348 if (int_stat & ADV_INTR_STATUS_INTRB) {
17349 uchar intrb_code;
17350
17351 AdvReadByteLram(iop_base, ASC_MC_INTRB_CODE, intrb_code);
17352
17353 if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
17354 asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
17355 if (intrb_code == ADV_ASYNC_CARRIER_READY_FAILURE &&
17356 asc_dvc->carr_pending_cnt != 0) {
17357 AdvWriteByteRegister(iop_base, IOPB_TICKLE,
17358 ADV_TICKLE_A);
17359 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
17360 AdvWriteByteRegister(iop_base,
17361 IOPB_TICKLE,
17362 ADV_TICKLE_NOP);
17363 }
17364 }
17365 }
17366
17367 if (asc_dvc->async_callback != 0) {
17368 (*asc_dvc->async_callback) (asc_dvc, intrb_code);
17369 }
17370 }
17371
17372 /*
17373 * Check if the IRQ stopper carrier contains a completed request.
17374 */
17375 while (((irq_next_vpa =
17376 le32_to_cpu(asc_dvc->irq_sp->next_vpa)) & ASC_RQ_DONE) != 0) {
17377 /*
17378 * Get a pointer to the newly completed ADV_SCSI_REQ_Q structure.
17379 * The RISC will have set 'areq_vpa' to a virtual address.
17380 *
17381 * The firmware will have copied the ASC_SCSI_REQ_Q.scsiq_ptr
17382 * field to the carrier ADV_CARR_T.areq_vpa field. The conversion
17383 * below complements the conversion of ASC_SCSI_REQ_Q.scsiq_ptr'
17384 * in AdvExeScsiQueue().
17385 */
17386 scsiq = (ADV_SCSI_REQ_Q *)
17387 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->areq_vpa));
17388
17389 /*
17390 * Request finished with good status and the queue was not
17391 * DMAed to host memory by the firmware. Set all status fields
17392 * to indicate good status.
17393 */
17394 if ((irq_next_vpa & ASC_RQ_GOOD) != 0) {
17395 scsiq->done_status = QD_NO_ERROR;
17396 scsiq->host_status = scsiq->scsi_status = 0;
17397 scsiq->data_cnt = 0L;
17398 }
17399
17400 /*
17401 * Advance the stopper pointer to the next carrier
17402 * ignoring the lower four bits. Free the previous
17403 * stopper carrier.
17404 */
17405 free_carrp = asc_dvc->irq_sp;
17406 asc_dvc->irq_sp = (ADV_CARR_T *)
17407 ADV_U32_TO_VADDR(ASC_GET_CARRP(irq_next_vpa));
17408
17409 free_carrp->next_vpa =
17410 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
17411 asc_dvc->carr_freelist = free_carrp;
17412 asc_dvc->carr_pending_cnt--;
17413
17414 ASC_ASSERT(scsiq != NULL);
17415 target_bit = ADV_TID_TO_TIDMASK(scsiq->target_id);
17416
17417 /*
17418 * Clear request microcode control flag.
17419 */
17420 scsiq->cntl = 0;
17421
17422 /*
17423 * If the command that completed was a SCSI INQUIRY and
17424 * LUN 0 was sent the command, then process the INQUIRY
17425 * command information for the device.
17426 *
17427 * Note: If data returned were either VPD or CmdDt data,
17428 * don't process the INQUIRY command information for
17429 * the device, otherwise may erroneously set *_able bits.
17430 */
17431 if (scsiq->done_status == QD_NO_ERROR &&
17432 scsiq->cdb[0] == INQUIRY &&
17433 scsiq->target_lun == 0 &&
17434 (scsiq->cdb[1] & ADV_INQ_RTN_VPD_AND_CMDDT)
17435 == ADV_INQ_RTN_STD_INQUIRY_DATA) {
17436 AdvInquiryHandling(asc_dvc, scsiq);
17437 }
17438
17439 /*
17440 * Notify the driver of the completed request by passing
17441 * the ADV_SCSI_REQ_Q pointer to its callback function.
17442 */
17443 scsiq->a_flag |= ADV_SCSIQ_DONE;
17444 (*asc_dvc->isr_callback) (asc_dvc, scsiq);
17445 /*
17446 * Note: After the driver callback function is called, 'scsiq'
17447 * can no longer be referenced.
17448 *
17449 * Fall through and continue processing other completed
17450 * requests...
17451 */
17452
17453 /*
17454 * Disable interrupts again in case the driver inadvertently
17455 * enabled interrupts in its callback function.
17456 *
17457 * The DvcEnterCritical() return value is ignored, because
17458 * the 'flags' saved when AdvISR() was first entered will be
17459 * used to restore the interrupt flag on exit.
17460 */
17461 (void)DvcEnterCritical();
17462 }
17463 DvcLeaveCritical(flags);
17464 return ADV_TRUE;
1da177e4
LT
17465}
17466
17467/*
17468 * Send an idle command to the chip and wait for completion.
17469 *
17470 * Command completion is polled for once per microsecond.
17471 *
17472 * The function can be called from anywhere including an interrupt handler.
17473 * But the function is not re-entrant, so it uses the DvcEnter/LeaveCritical()
17474 * functions to prevent reentrancy.
17475 *
17476 * Return Values:
17477 * ADV_TRUE - command completed successfully
17478 * ADV_FALSE - command failed
17479 * ADV_ERROR - command timed out
17480 */
27c868c2 17481static int
1da177e4 17482AdvSendIdleCmd(ADV_DVC_VAR *asc_dvc,
27c868c2 17483 ushort idle_cmd, ADV_DCNT idle_cmd_parameter)
1da177e4 17484{
27c868c2
MW
17485 ulong last_int_level;
17486 int result;
17487 ADV_DCNT i, j;
17488 AdvPortAddr iop_base;
17489
17490 last_int_level = DvcEnterCritical();
17491
17492 iop_base = asc_dvc->iop_base;
17493
17494 /*
17495 * Clear the idle command status which is set by the microcode
17496 * to a non-zero value to indicate when the command is completed.
17497 * The non-zero result is one of the IDLE_CMD_STATUS_* values
17498 * defined in a_advlib.h.
17499 */
17500 AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS, (ushort)0);
17501
17502 /*
17503 * Write the idle command value after the idle command parameter
17504 * has been written to avoid a race condition. If the order is not
17505 * followed, the microcode may process the idle command before the
17506 * parameters have been written to LRAM.
17507 */
17508 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IDLE_CMD_PARAMETER,
17509 cpu_to_le32(idle_cmd_parameter));
17510 AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD, idle_cmd);
17511
17512 /*
17513 * Tickle the RISC to tell it to process the idle command.
17514 */
17515 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_B);
17516 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
17517 /*
17518 * Clear the tickle value. In the ASC-3550 the RISC flag
17519 * command 'clr_tickle_b' does not work unless the host
17520 * value is cleared.
17521 */
17522 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
17523 }
1da177e4 17524
27c868c2
MW
17525 /* Wait for up to 100 millisecond for the idle command to timeout. */
17526 for (i = 0; i < SCSI_WAIT_100_MSEC; i++) {
17527 /* Poll once each microsecond for command completion. */
17528 for (j = 0; j < SCSI_US_PER_MSEC; j++) {
17529 AdvReadWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS,
17530 result);
17531 if (result != 0) {
17532 DvcLeaveCritical(last_int_level);
17533 return result;
17534 }
17535 DvcDelayMicroSecond(asc_dvc, (ushort)1);
17536 }
17537 }
1da177e4 17538
27c868c2
MW
17539 ASC_ASSERT(0); /* The idle command should never timeout. */
17540 DvcLeaveCritical(last_int_level);
17541 return ADV_ERROR;
1da177e4
LT
17542}
17543
17544/*
17545 * Inquiry Information Byte 7 Handling
17546 *
17547 * Handle SCSI Inquiry Command information for a device by setting
17548 * microcode operating variables that affect WDTR, SDTR, and Tag
17549 * Queuing.
17550 */
27c868c2 17551static void AdvInquiryHandling(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq)
1da177e4 17552{
27c868c2
MW
17553 AdvPortAddr iop_base;
17554 uchar tid;
17555 ADV_SCSI_INQUIRY *inq;
17556 ushort tidmask;
17557 ushort cfg_word;
17558
17559 /*
17560 * AdvInquiryHandling() requires up to INQUIRY information Byte 7
17561 * to be available.
17562 *
17563 * If less than 8 bytes of INQUIRY information were requested or less
17564 * than 8 bytes were transferred, then return. cdb[4] is the request
17565 * length and the ADV_SCSI_REQ_Q 'data_cnt' field is set by the
17566 * microcode to the transfer residual count.
17567 */
17568
17569 if (scsiq->cdb[4] < 8 ||
17570 (scsiq->cdb[4] - le32_to_cpu(scsiq->data_cnt)) < 8) {
17571 return;
17572 }
1da177e4 17573
27c868c2
MW
17574 iop_base = asc_dvc->iop_base;
17575 tid = scsiq->target_id;
17576
17577 inq = (ADV_SCSI_INQUIRY *) scsiq->vdata_addr;
1da177e4 17578
27c868c2
MW
17579 /*
17580 * WDTR, SDTR, and Tag Queuing cannot be enabled for old devices.
17581 */
17582 if (ADV_INQ_RESPONSE_FMT(inq) < 2 && ADV_INQ_ANSI_VER(inq) < 2) {
17583 return;
17584 } else {
17585 /*
17586 * INQUIRY Byte 7 Handling
17587 *
17588 * Use a device's INQUIRY byte 7 to determine whether it
17589 * supports WDTR, SDTR, and Tag Queuing. If the feature
17590 * is enabled in the EEPROM and the device supports the
17591 * feature, then enable it in the microcode.
17592 */
1da177e4 17593
27c868c2 17594 tidmask = ADV_TID_TO_TIDMASK(tid);
1da177e4 17595
27c868c2
MW
17596 /*
17597 * Wide Transfers
17598 *
17599 * If the EEPROM enabled WDTR for the device and the device
17600 * supports wide bus (16 bit) transfers, then turn on the
17601 * device's 'wdtr_able' bit and write the new value to the
17602 * microcode.
17603 */
17604 if ((asc_dvc->wdtr_able & tidmask) && ADV_INQ_WIDE16(inq)) {
17605 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
17606 if ((cfg_word & tidmask) == 0) {
17607 cfg_word |= tidmask;
17608 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
17609 cfg_word);
17610
17611 /*
17612 * Clear the microcode "SDTR negotiation" and "WDTR
17613 * negotiation" done indicators for the target to cause
17614 * it to negotiate with the new setting set above.
17615 * WDTR when accepted causes the target to enter
17616 * asynchronous mode, so SDTR must be negotiated.
17617 */
17618 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE,
17619 cfg_word);
17620 cfg_word &= ~tidmask;
17621 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE,
17622 cfg_word);
17623 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE,
17624 cfg_word);
17625 cfg_word &= ~tidmask;
17626 AdvWriteWordLram(iop_base, ASC_MC_WDTR_DONE,
17627 cfg_word);
17628 }
17629 }
17630
17631 /*
17632 * Synchronous Transfers
17633 *
17634 * If the EEPROM enabled SDTR for the device and the device
17635 * supports synchronous transfers, then turn on the device's
17636 * 'sdtr_able' bit. Write the new value to the microcode.
17637 */
17638 if ((asc_dvc->sdtr_able & tidmask) && ADV_INQ_SYNC(inq)) {
17639 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
17640 if ((cfg_word & tidmask) == 0) {
17641 cfg_word |= tidmask;
17642 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
17643 cfg_word);
17644
17645 /*
17646 * Clear the microcode "SDTR negotiation" done indicator
17647 * for the target to cause it to negotiate with the new
17648 * setting set above.
17649 */
17650 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE,
17651 cfg_word);
17652 cfg_word &= ~tidmask;
17653 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE,
17654 cfg_word);
17655 }
17656 }
17657 /*
17658 * If the Inquiry data included enough space for the SPI-3
17659 * Clocking field, then check if DT mode is supported.
17660 */
17661 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600 &&
17662 (scsiq->cdb[4] >= 57 ||
17663 (scsiq->cdb[4] - le32_to_cpu(scsiq->data_cnt)) >= 57)) {
17664 /*
17665 * PPR (Parallel Protocol Request) Capable
17666 *
17667 * If the device supports DT mode, then it must be PPR capable.
17668 * The PPR message will be used in place of the SDTR and WDTR
17669 * messages to negotiate synchronous speed and offset, transfer
17670 * width, and protocol options.
17671 */
17672 if (ADV_INQ_CLOCKING(inq) & ADV_INQ_CLOCKING_DT_ONLY) {
17673 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE,
17674 asc_dvc->ppr_able);
17675 asc_dvc->ppr_able |= tidmask;
17676 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE,
17677 asc_dvc->ppr_able);
17678 }
17679 }
17680
17681 /*
17682 * If the EEPROM enabled Tag Queuing for the device and the
17683 * device supports Tag Queueing, then turn on the device's
17684 * 'tagqng_enable' bit in the microcode and set the microcode
17685 * maximum command count to the ADV_DVC_VAR 'max_dvc_qng'
17686 * value.
17687 *
17688 * Tag Queuing is disabled for the BIOS which runs in polled
17689 * mode and would see no benefit from Tag Queuing. Also by
17690 * disabling Tag Queuing in the BIOS devices with Tag Queuing
17691 * bugs will at least work with the BIOS.
17692 */
17693 if ((asc_dvc->tagqng_able & tidmask) && ADV_INQ_CMD_QUEUE(inq)) {
17694 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
17695 cfg_word |= tidmask;
17696 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
17697 cfg_word);
17698
17699 AdvWriteByteLram(iop_base,
17700 ASC_MC_NUMBER_OF_MAX_CMD + tid,
17701 asc_dvc->max_dvc_qng);
17702 }
17703 }
1da177e4 17704}
27c868c2 17705
27c868c2
MW
17706static struct Scsi_Host *__devinit
17707advansys_board_found(int iop, struct device *dev, int bus_type)
17708{
17709 struct Scsi_Host *shost;
17710 struct pci_dev *pdev = bus_type == ASC_IS_PCI ? to_pci_dev(dev) : NULL;
17711 asc_board_t *boardp;
17712 ASC_DVC_VAR *asc_dvc_varp = NULL;
17713 ADV_DVC_VAR *adv_dvc_varp = NULL;
17714 adv_sgblk_t *sgp = NULL;
074c8fe4 17715 int share_irq;
27c868c2
MW
17716 int iolen = 0;
17717 ADV_PADDR pci_memory_address;
17718 int warn_code, err_code;
17719 int ret;
17720
17721 /*
17722 * Adapter found.
17723 *
17724 * Register the adapter, get its configuration, and
17725 * initialize it.
17726 */
17727 ASC_DBG(2, "advansys_board_found: scsi_register()\n");
17728 shost = scsi_register(&driver_template, sizeof(asc_board_t));
17729
17730 if (!shost)
17731 return NULL;
17732
17733 /* Save a pointer to the Scsi_Host of each board found. */
17734 asc_host[asc_board_count++] = shost;
17735
17736 /* Initialize private per board data */
17737 boardp = ASC_BOARDP(shost);
17738 memset(boardp, 0, sizeof(asc_board_t));
17739 boardp->id = asc_board_count - 1;
17740
17741 /* Initialize spinlock. */
17742 spin_lock_init(&boardp->lock);
17743
17744 /*
17745 * Handle both narrow and wide boards.
17746 *
17747 * If a Wide board was detected, set the board structure
17748 * wide board flag. Set-up the board structure based on
17749 * the board type.
17750 */
17751#ifdef CONFIG_PCI
17752 if (bus_type == ASC_IS_PCI &&
17753 (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW ||
17754 pdev->device == PCI_DEVICE_ID_38C0800_REV1 ||
17755 pdev->device == PCI_DEVICE_ID_38C1600_REV1)) {
17756 boardp->flags |= ASC_IS_WIDE_BOARD;
17757 }
17758#endif /* CONFIG_PCI */
17759
17760 if (ASC_NARROW_BOARD(boardp)) {
17761 ASC_DBG(1, "advansys_board_found: narrow board\n");
17762 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
17763 asc_dvc_varp->bus_type = bus_type;
17764 asc_dvc_varp->drv_ptr = boardp;
17765 asc_dvc_varp->cfg = &boardp->dvc_cfg.asc_dvc_cfg;
17766 asc_dvc_varp->cfg->overrun_buf = &overrun_buf[0];
17767 asc_dvc_varp->iop_base = iop;
17768 asc_dvc_varp->isr_callback = asc_isr_callback;
17769 } else {
17770 ASC_DBG(1, "advansys_board_found: wide board\n");
17771 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
17772 adv_dvc_varp->drv_ptr = boardp;
17773 adv_dvc_varp->cfg = &boardp->dvc_cfg.adv_dvc_cfg;
17774 adv_dvc_varp->isr_callback = adv_isr_callback;
17775 adv_dvc_varp->async_callback = adv_async_callback;
17776#ifdef CONFIG_PCI
17777 if (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW) {
17778 ASC_DBG(1, "advansys_board_found: ASC-3550\n");
17779 adv_dvc_varp->chip_type = ADV_CHIP_ASC3550;
17780 } else if (pdev->device == PCI_DEVICE_ID_38C0800_REV1) {
17781 ASC_DBG(1, "advansys_board_found: ASC-38C0800\n");
17782 adv_dvc_varp->chip_type = ADV_CHIP_ASC38C0800;
17783 } else {
17784 ASC_DBG(1, "advansys_board_found: ASC-38C1600\n");
17785 adv_dvc_varp->chip_type = ADV_CHIP_ASC38C1600;
17786 }
17787#endif /* CONFIG_PCI */
17788
17789 /*
17790 * Map the board's registers into virtual memory for
17791 * PCI slave access. Only memory accesses are used to
17792 * access the board's registers.
17793 *
17794 * Note: The PCI register base address is not always
17795 * page aligned, but the address passed to ioremap()
17796 * must be page aligned. It is guaranteed that the
17797 * PCI register base address will not cross a page
17798 * boundary.
17799 */
17800 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
17801 iolen = ADV_3550_IOLEN;
17802 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
17803 iolen = ADV_38C0800_IOLEN;
17804 } else {
17805 iolen = ADV_38C1600_IOLEN;
17806 }
17807#ifdef CONFIG_PCI
17808 pci_memory_address = pci_resource_start(pdev, 1);
17809 ASC_DBG1(1,
17810 "advansys_board_found: pci_memory_address: 0x%lx\n",
17811 (ulong)pci_memory_address);
17812 if ((boardp->ioremap_addr =
17813 ioremap(pci_memory_address & PAGE_MASK, PAGE_SIZE)) == 0) {
17814 ASC_PRINT3
17815 ("advansys_board_found: board %d: ioremap(%x, %d) returned NULL\n",
17816 boardp->id, pci_memory_address, iolen);
17817 scsi_unregister(shost);
17818 asc_board_count--;
17819 return NULL;
17820 }
17821 ASC_DBG1(1,
17822 "advansys_board_found: ioremap_addr: 0x%lx\n",
17823 (ulong)boardp->ioremap_addr);
17824 adv_dvc_varp->iop_base = (AdvPortAddr)
17825 (boardp->ioremap_addr +
17826 (pci_memory_address - (pci_memory_address & PAGE_MASK)));
17827 ASC_DBG1(1,
17828 "advansys_board_found: iop_base: 0x%lx\n",
17829 adv_dvc_varp->iop_base);
17830#endif /* CONFIG_PCI */
17831
17832 /*
17833 * Even though it isn't used to access wide boards, other
17834 * than for the debug line below, save I/O Port address so
17835 * that it can be reported.
17836 */
17837 boardp->ioport = iop;
17838
17839 ASC_DBG2(1,
17840 "advansys_board_found: iopb_chip_id_1 0x%x, iopw_chip_id_0 0x%x\n",
17841 (ushort)inp(iop + 1), (ushort)inpw(iop));
17842 }
17843
17844#ifdef CONFIG_PROC_FS
17845 /*
17846 * Allocate buffer for printing information from
17847 * /proc/scsi/advansys/[0...].
17848 */
17849 if ((boardp->prtbuf = kmalloc(ASC_PRTBUF_SIZE, GFP_ATOMIC)) == NULL) {
17850 ASC_PRINT3
17851 ("advansys_board_found: board %d: kmalloc(%d, %d) returned NULL\n",
17852 boardp->id, ASC_PRTBUF_SIZE, GFP_ATOMIC);
17853 scsi_unregister(shost);
17854 asc_board_count--;
17855 return NULL;
17856 }
17857#endif /* CONFIG_PROC_FS */
17858
17859 if (ASC_NARROW_BOARD(boardp)) {
17860 asc_dvc_varp->cfg->dev = dev;
17861 /*
17862 * Set the board bus type and PCI IRQ before
17863 * calling AscInitGetConfig().
17864 */
17865 switch (asc_dvc_varp->bus_type) {
17866#ifdef CONFIG_ISA
17867 case ASC_IS_ISA:
17868 shost->unchecked_isa_dma = TRUE;
074c8fe4 17869 share_irq = 0;
27c868c2
MW
17870 break;
17871 case ASC_IS_VL:
17872 shost->unchecked_isa_dma = FALSE;
074c8fe4 17873 share_irq = 0;
27c868c2
MW
17874 break;
17875 case ASC_IS_EISA:
17876 shost->unchecked_isa_dma = FALSE;
074c8fe4 17877 share_irq = IRQF_SHARED;
27c868c2
MW
17878 break;
17879#endif /* CONFIG_ISA */
17880#ifdef CONFIG_PCI
17881 case ASC_IS_PCI:
17882 shost->irq = asc_dvc_varp->irq_no = pdev->irq;
17883 asc_dvc_varp->cfg->pci_slot_info =
17884 ASC_PCI_MKID(pdev->bus->number,
17885 PCI_SLOT(pdev->devfn),
17886 PCI_FUNC(pdev->devfn));
17887 shost->unchecked_isa_dma = FALSE;
074c8fe4 17888 share_irq = IRQF_SHARED;
27c868c2
MW
17889 break;
17890#endif /* CONFIG_PCI */
17891 default:
17892 ASC_PRINT2
17893 ("advansys_board_found: board %d: unknown adapter type: %d\n",
17894 boardp->id, asc_dvc_varp->bus_type);
17895 shost->unchecked_isa_dma = TRUE;
074c8fe4 17896 share_irq = 0;
27c868c2
MW
17897 break;
17898 }
17899 } else {
17900 adv_dvc_varp->cfg->dev = dev;
17901 /*
17902 * For Wide boards set PCI information before calling
17903 * AdvInitGetConfig().
17904 */
17905#ifdef CONFIG_PCI
17906 shost->irq = adv_dvc_varp->irq_no = pdev->irq;
17907 adv_dvc_varp->cfg->pci_slot_info =
17908 ASC_PCI_MKID(pdev->bus->number,
17909 PCI_SLOT(pdev->devfn),
17910 PCI_FUNC(pdev->devfn));
17911 shost->unchecked_isa_dma = FALSE;
074c8fe4 17912 share_irq = IRQF_SHARED;
27c868c2
MW
17913#endif /* CONFIG_PCI */
17914 }
17915
17916 /*
17917 * Read the board configuration.
17918 */
17919 if (ASC_NARROW_BOARD(boardp)) {
17920 /*
17921 * NOTE: AscInitGetConfig() may change the board's
17922 * bus_type value. The bus_type value should no
17923 * longer be used. If the bus_type field must be
17924 * referenced only use the bit-wise AND operator "&".
17925 */
17926 ASC_DBG(2, "advansys_board_found: AscInitGetConfig()\n");
17927 switch (ret = AscInitGetConfig(asc_dvc_varp)) {
17928 case 0: /* No error */
17929 break;
17930 case ASC_WARN_IO_PORT_ROTATE:
17931 ASC_PRINT1
17932 ("AscInitGetConfig: board %d: I/O port address modified\n",
17933 boardp->id);
17934 break;
17935 case ASC_WARN_AUTO_CONFIG:
17936 ASC_PRINT1
17937 ("AscInitGetConfig: board %d: I/O port increment switch enabled\n",
17938 boardp->id);
17939 break;
17940 case ASC_WARN_EEPROM_CHKSUM:
17941 ASC_PRINT1
17942 ("AscInitGetConfig: board %d: EEPROM checksum error\n",
17943 boardp->id);
17944 break;
17945 case ASC_WARN_IRQ_MODIFIED:
17946 ASC_PRINT1
17947 ("AscInitGetConfig: board %d: IRQ modified\n",
17948 boardp->id);
17949 break;
17950 case ASC_WARN_CMD_QNG_CONFLICT:
17951 ASC_PRINT1
17952 ("AscInitGetConfig: board %d: tag queuing enabled w/o disconnects\n",
17953 boardp->id);
17954 break;
17955 default:
17956 ASC_PRINT2
17957 ("AscInitGetConfig: board %d: unknown warning: 0x%x\n",
17958 boardp->id, ret);
17959 break;
17960 }
17961 if ((err_code = asc_dvc_varp->err_code) != 0) {
17962 ASC_PRINT3
17963 ("AscInitGetConfig: board %d error: init_state 0x%x, err_code 0x%x\n",
17964 boardp->id,
17965 asc_dvc_varp->init_state, asc_dvc_varp->err_code);
17966 }
17967 } else {
17968 ASC_DBG(2, "advansys_board_found: AdvInitGetConfig()\n");
17969 if ((ret = AdvInitGetConfig(adv_dvc_varp)) != 0) {
17970 ASC_PRINT2
17971 ("AdvInitGetConfig: board %d: warning: 0x%x\n",
17972 boardp->id, ret);
17973 }
17974 if ((err_code = adv_dvc_varp->err_code) != 0) {
17975 ASC_PRINT2
17976 ("AdvInitGetConfig: board %d error: err_code 0x%x\n",
17977 boardp->id, adv_dvc_varp->err_code);
17978 }
17979 }
17980
17981 if (err_code != 0) {
17982#ifdef CONFIG_PROC_FS
17983 kfree(boardp->prtbuf);
17984#endif /* CONFIG_PROC_FS */
17985 scsi_unregister(shost);
17986 asc_board_count--;
17987 return NULL;
17988 }
17989
17990 /*
17991 * Save the EEPROM configuration so that it can be displayed
17992 * from /proc/scsi/advansys/[0...].
17993 */
17994 if (ASC_NARROW_BOARD(boardp)) {
17995
17996 ASCEEP_CONFIG *ep;
17997
17998 /*
17999 * Set the adapter's target id bit in the 'init_tidmask' field.
18000 */
18001 boardp->init_tidmask |=
18002 ADV_TID_TO_TIDMASK(asc_dvc_varp->cfg->chip_scsi_id);
18003
18004 /*
18005 * Save EEPROM settings for the board.
18006 */
18007 ep = &boardp->eep_config.asc_eep;
18008
18009 ep->init_sdtr = asc_dvc_varp->cfg->sdtr_enable;
18010 ep->disc_enable = asc_dvc_varp->cfg->disc_enable;
18011 ep->use_cmd_qng = asc_dvc_varp->cfg->cmd_qng_enabled;
18012 ASC_EEP_SET_DMA_SPD(ep, asc_dvc_varp->cfg->isa_dma_speed);
18013 ep->start_motor = asc_dvc_varp->start_motor;
18014 ep->cntl = asc_dvc_varp->dvc_cntl;
18015 ep->no_scam = asc_dvc_varp->no_scam;
18016 ep->max_total_qng = asc_dvc_varp->max_total_qng;
18017 ASC_EEP_SET_CHIP_ID(ep, asc_dvc_varp->cfg->chip_scsi_id);
18018 /* 'max_tag_qng' is set to the same value for every device. */
18019 ep->max_tag_qng = asc_dvc_varp->cfg->max_tag_qng[0];
18020 ep->adapter_info[0] = asc_dvc_varp->cfg->adapter_info[0];
18021 ep->adapter_info[1] = asc_dvc_varp->cfg->adapter_info[1];
18022 ep->adapter_info[2] = asc_dvc_varp->cfg->adapter_info[2];
18023 ep->adapter_info[3] = asc_dvc_varp->cfg->adapter_info[3];
18024 ep->adapter_info[4] = asc_dvc_varp->cfg->adapter_info[4];
18025 ep->adapter_info[5] = asc_dvc_varp->cfg->adapter_info[5];
18026
18027 /*
18028 * Modify board configuration.
18029 */
18030 ASC_DBG(2, "advansys_board_found: AscInitSetConfig()\n");
18031 switch (ret = AscInitSetConfig(asc_dvc_varp)) {
18032 case 0: /* No error. */
18033 break;
18034 case ASC_WARN_IO_PORT_ROTATE:
18035 ASC_PRINT1
18036 ("AscInitSetConfig: board %d: I/O port address modified\n",
18037 boardp->id);
18038 break;
18039 case ASC_WARN_AUTO_CONFIG:
18040 ASC_PRINT1
18041 ("AscInitSetConfig: board %d: I/O port increment switch enabled\n",
18042 boardp->id);
18043 break;
18044 case ASC_WARN_EEPROM_CHKSUM:
18045 ASC_PRINT1
18046 ("AscInitSetConfig: board %d: EEPROM checksum error\n",
18047 boardp->id);
18048 break;
18049 case ASC_WARN_IRQ_MODIFIED:
18050 ASC_PRINT1
18051 ("AscInitSetConfig: board %d: IRQ modified\n",
18052 boardp->id);
18053 break;
18054 case ASC_WARN_CMD_QNG_CONFLICT:
18055 ASC_PRINT1
18056 ("AscInitSetConfig: board %d: tag queuing w/o disconnects\n",
18057 boardp->id);
18058 break;
18059 default:
18060 ASC_PRINT2
18061 ("AscInitSetConfig: board %d: unknown warning: 0x%x\n",
18062 boardp->id, ret);
18063 break;
18064 }
18065 if (asc_dvc_varp->err_code != 0) {
18066 ASC_PRINT3
18067 ("AscInitSetConfig: board %d error: init_state 0x%x, err_code 0x%x\n",
18068 boardp->id,
18069 asc_dvc_varp->init_state, asc_dvc_varp->err_code);
18070#ifdef CONFIG_PROC_FS
18071 kfree(boardp->prtbuf);
18072#endif /* CONFIG_PROC_FS */
18073 scsi_unregister(shost);
18074 asc_board_count--;
18075 return NULL;
18076 }
18077
18078 /*
18079 * Finish initializing the 'Scsi_Host' structure.
18080 */
18081 /* AscInitSetConfig() will set the IRQ for non-PCI boards. */
18082 if ((asc_dvc_varp->bus_type & ASC_IS_PCI) == 0) {
18083 shost->irq = asc_dvc_varp->irq_no;
18084 }
18085 } else {
18086 ADVEEP_3550_CONFIG *ep_3550;
18087 ADVEEP_38C0800_CONFIG *ep_38C0800;
18088 ADVEEP_38C1600_CONFIG *ep_38C1600;
18089
18090 /*
18091 * Save Wide EEP Configuration Information.
18092 */
18093 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
18094 ep_3550 = &boardp->eep_config.adv_3550_eep;
18095
18096 ep_3550->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
18097 ep_3550->max_host_qng = adv_dvc_varp->max_host_qng;
18098 ep_3550->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
18099 ep_3550->termination = adv_dvc_varp->cfg->termination;
18100 ep_3550->disc_enable = adv_dvc_varp->cfg->disc_enable;
18101 ep_3550->bios_ctrl = adv_dvc_varp->bios_ctrl;
18102 ep_3550->wdtr_able = adv_dvc_varp->wdtr_able;
18103 ep_3550->sdtr_able = adv_dvc_varp->sdtr_able;
18104 ep_3550->ultra_able = adv_dvc_varp->ultra_able;
18105 ep_3550->tagqng_able = adv_dvc_varp->tagqng_able;
18106 ep_3550->start_motor = adv_dvc_varp->start_motor;
18107 ep_3550->scsi_reset_delay =
18108 adv_dvc_varp->scsi_reset_wait;
18109 ep_3550->serial_number_word1 =
18110 adv_dvc_varp->cfg->serial1;
18111 ep_3550->serial_number_word2 =
18112 adv_dvc_varp->cfg->serial2;
18113 ep_3550->serial_number_word3 =
18114 adv_dvc_varp->cfg->serial3;
18115 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
18116 ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
18117
18118 ep_38C0800->adapter_scsi_id =
18119 adv_dvc_varp->chip_scsi_id;
18120 ep_38C0800->max_host_qng = adv_dvc_varp->max_host_qng;
18121 ep_38C0800->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
18122 ep_38C0800->termination_lvd =
18123 adv_dvc_varp->cfg->termination;
18124 ep_38C0800->disc_enable =
18125 adv_dvc_varp->cfg->disc_enable;
18126 ep_38C0800->bios_ctrl = adv_dvc_varp->bios_ctrl;
18127 ep_38C0800->wdtr_able = adv_dvc_varp->wdtr_able;
18128 ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
18129 ep_38C0800->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
18130 ep_38C0800->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
18131 ep_38C0800->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
18132 ep_38C0800->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
18133 ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
18134 ep_38C0800->start_motor = adv_dvc_varp->start_motor;
18135 ep_38C0800->scsi_reset_delay =
18136 adv_dvc_varp->scsi_reset_wait;
18137 ep_38C0800->serial_number_word1 =
18138 adv_dvc_varp->cfg->serial1;
18139 ep_38C0800->serial_number_word2 =
18140 adv_dvc_varp->cfg->serial2;
18141 ep_38C0800->serial_number_word3 =
18142 adv_dvc_varp->cfg->serial3;
18143 } else {
18144 ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
18145
18146 ep_38C1600->adapter_scsi_id =
18147 adv_dvc_varp->chip_scsi_id;
18148 ep_38C1600->max_host_qng = adv_dvc_varp->max_host_qng;
18149 ep_38C1600->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
18150 ep_38C1600->termination_lvd =
18151 adv_dvc_varp->cfg->termination;
18152 ep_38C1600->disc_enable =
18153 adv_dvc_varp->cfg->disc_enable;
18154 ep_38C1600->bios_ctrl = adv_dvc_varp->bios_ctrl;
18155 ep_38C1600->wdtr_able = adv_dvc_varp->wdtr_able;
18156 ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
18157 ep_38C1600->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
18158 ep_38C1600->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
18159 ep_38C1600->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
18160 ep_38C1600->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
18161 ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
18162 ep_38C1600->start_motor = adv_dvc_varp->start_motor;
18163 ep_38C1600->scsi_reset_delay =
18164 adv_dvc_varp->scsi_reset_wait;
18165 ep_38C1600->serial_number_word1 =
18166 adv_dvc_varp->cfg->serial1;
18167 ep_38C1600->serial_number_word2 =
18168 adv_dvc_varp->cfg->serial2;
18169 ep_38C1600->serial_number_word3 =
18170 adv_dvc_varp->cfg->serial3;
18171 }
18172
18173 /*
18174 * Set the adapter's target id bit in the 'init_tidmask' field.
18175 */
18176 boardp->init_tidmask |=
18177 ADV_TID_TO_TIDMASK(adv_dvc_varp->chip_scsi_id);
18178
18179 /*
18180 * Finish initializing the 'Scsi_Host' structure.
18181 */
18182 shost->irq = adv_dvc_varp->irq_no;
18183 }
18184
18185 /*
18186 * Channels are numbered beginning with 0. For AdvanSys one host
18187 * structure supports one channel. Multi-channel boards have a
18188 * separate host structure for each channel.
18189 */
18190 shost->max_channel = 0;
18191 if (ASC_NARROW_BOARD(boardp)) {
18192 shost->max_id = ASC_MAX_TID + 1;
18193 shost->max_lun = ASC_MAX_LUN + 1;
18194
18195 shost->io_port = asc_dvc_varp->iop_base;
18196 boardp->asc_n_io_port = ASC_IOADR_GAP;
18197 shost->this_id = asc_dvc_varp->cfg->chip_scsi_id;
18198
18199 /* Set maximum number of queues the adapter can handle. */
18200 shost->can_queue = asc_dvc_varp->max_total_qng;
18201 } else {
18202 shost->max_id = ADV_MAX_TID + 1;
18203 shost->max_lun = ADV_MAX_LUN + 1;
18204
18205 /*
18206 * Save the I/O Port address and length even though
18207 * I/O ports are not used to access Wide boards.
18208 * Instead the Wide boards are accessed with
18209 * PCI Memory Mapped I/O.
18210 */
18211 shost->io_port = iop;
18212 boardp->asc_n_io_port = iolen;
18213
18214 shost->this_id = adv_dvc_varp->chip_scsi_id;
18215
18216 /* Set maximum number of queues the adapter can handle. */
18217 shost->can_queue = adv_dvc_varp->max_host_qng;
18218 }
18219
18220 /*
18221 * 'n_io_port' currently is one byte.
18222 *
18223 * Set a value to 'n_io_port', but never referenced it because
18224 * it may be truncated.
18225 */
18226 shost->n_io_port = boardp->asc_n_io_port <= 255 ?
18227 boardp->asc_n_io_port : 255;
18228
18229 /*
18230 * Following v1.3.89, 'cmd_per_lun' is no longer needed
18231 * and should be set to zero.
18232 *
18233 * But because of a bug introduced in v1.3.89 if the driver is
18234 * compiled as a module and 'cmd_per_lun' is zero, the Mid-Level
18235 * SCSI function 'allocate_device' will panic. To allow the driver
18236 * to work as a module in these kernels set 'cmd_per_lun' to 1.
18237 *
18238 * Note: This is wrong. cmd_per_lun should be set to the depth
18239 * you want on untagged devices always.
18240 #ifdef MODULE
18241 */
18242 shost->cmd_per_lun = 1;
18243/* #else
18244 shost->cmd_per_lun = 0;
18245#endif */
18246
18247 /*
18248 * Set the maximum number of scatter-gather elements the
18249 * adapter can handle.
18250 */
18251 if (ASC_NARROW_BOARD(boardp)) {
18252 /*
18253 * Allow two commands with 'sg_tablesize' scatter-gather
18254 * elements to be executed simultaneously. This value is
18255 * the theoretical hardware limit. It may be decreased
18256 * below.
18257 */
18258 shost->sg_tablesize =
18259 (((asc_dvc_varp->max_total_qng - 2) / 2) *
18260 ASC_SG_LIST_PER_Q) + 1;
18261 } else {
18262 shost->sg_tablesize = ADV_MAX_SG_LIST;
18263 }
18264
18265 /*
18266 * The value of 'sg_tablesize' can not exceed the SCSI
18267 * mid-level driver definition of SG_ALL. SG_ALL also
18268 * must not be exceeded, because it is used to define the
18269 * size of the scatter-gather table in 'struct asc_sg_head'.
18270 */
18271 if (shost->sg_tablesize > SG_ALL) {
18272 shost->sg_tablesize = SG_ALL;
18273 }
18274
18275 ASC_DBG1(1, "advansys_board_found: sg_tablesize: %d\n", shost->sg_tablesize);
18276
18277 /* BIOS start address. */
18278 if (ASC_NARROW_BOARD(boardp)) {
18279 shost->base = ((ulong)
18280 AscGetChipBiosAddress(asc_dvc_varp->
18281 iop_base,
18282 asc_dvc_varp->bus_type));
18283 } else {
18284 /*
18285 * Fill-in BIOS board variables. The Wide BIOS saves
18286 * information in LRAM that is used by the driver.
18287 */
18288 AdvReadWordLram(adv_dvc_varp->iop_base,
18289 BIOS_SIGNATURE, boardp->bios_signature);
18290 AdvReadWordLram(adv_dvc_varp->iop_base,
18291 BIOS_VERSION, boardp->bios_version);
18292 AdvReadWordLram(adv_dvc_varp->iop_base,
18293 BIOS_CODESEG, boardp->bios_codeseg);
18294 AdvReadWordLram(adv_dvc_varp->iop_base,
18295 BIOS_CODELEN, boardp->bios_codelen);
18296
18297 ASC_DBG2(1,
18298 "advansys_board_found: bios_signature 0x%x, bios_version 0x%x\n",
18299 boardp->bios_signature, boardp->bios_version);
18300
18301 ASC_DBG2(1,
18302 "advansys_board_found: bios_codeseg 0x%x, bios_codelen 0x%x\n",
18303 boardp->bios_codeseg, boardp->bios_codelen);
18304
18305 /*
18306 * If the BIOS saved a valid signature, then fill in
18307 * the BIOS code segment base address.
18308 */
18309 if (boardp->bios_signature == 0x55AA) {
18310 /*
18311 * Convert x86 realmode code segment to a linear
18312 * address by shifting left 4.
18313 */
18314 shost->base = ((ulong)boardp->bios_codeseg << 4);
18315 } else {
18316 shost->base = 0;
18317 }
18318 }
18319
18320 /*
18321 * Register Board Resources - I/O Port, DMA, IRQ
18322 */
18323
18324 /*
18325 * Register I/O port range.
18326 *
18327 * For Wide boards the I/O ports are not used to access
18328 * the board, but request the region anyway.
18329 *
18330 * 'shost->n_io_port' is not referenced, because it may be truncated.
18331 */
18332 ASC_DBG2(2,
18333 "advansys_board_found: request_region port 0x%lx, len 0x%x\n",
18334 (ulong)shost->io_port, boardp->asc_n_io_port);
18335 if (request_region(shost->io_port, boardp->asc_n_io_port,
18336 "advansys") == NULL) {
18337 ASC_PRINT3
18338 ("advansys_board_found: board %d: request_region() failed, port 0x%lx, len 0x%x\n",
18339 boardp->id, (ulong)shost->io_port, boardp->asc_n_io_port);
18340#ifdef CONFIG_PROC_FS
18341 kfree(boardp->prtbuf);
18342#endif /* CONFIG_PROC_FS */
18343 scsi_unregister(shost);
18344 asc_board_count--;
18345 return NULL;
18346 }
18347
18348 /* Register DMA Channel for Narrow boards. */
18349 shost->dma_channel = NO_ISA_DMA; /* Default to no ISA DMA. */
18350#ifdef CONFIG_ISA
18351 if (ASC_NARROW_BOARD(boardp)) {
18352 /* Register DMA channel for ISA bus. */
18353 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
18354 shost->dma_channel = asc_dvc_varp->cfg->isa_dma_channel;
18355 if ((ret =
18356 request_dma(shost->dma_channel, "advansys")) != 0) {
18357 ASC_PRINT3
18358 ("advansys_board_found: board %d: request_dma() %d failed %d\n",
18359 boardp->id, shost->dma_channel, ret);
18360 release_region(shost->io_port,
18361 boardp->asc_n_io_port);
18362#ifdef CONFIG_PROC_FS
18363 kfree(boardp->prtbuf);
18364#endif /* CONFIG_PROC_FS */
18365 scsi_unregister(shost);
18366 asc_board_count--;
18367 return NULL;
18368 }
18369 AscEnableIsaDma(shost->dma_channel);
18370 }
18371 }
18372#endif /* CONFIG_ISA */
18373
18374 /* Register IRQ Number. */
18375 ASC_DBG1(2, "advansys_board_found: request_irq() %d\n", shost->irq);
074c8fe4
MW
18376
18377 ret = request_irq(shost->irq, advansys_interrupt, share_irq,
18378 "advansys", shost);
18379
18380 if (ret) {
27c868c2
MW
18381 if (ret == -EBUSY) {
18382 ASC_PRINT2
18383 ("advansys_board_found: board %d: request_irq(): IRQ 0x%x already in use.\n",
18384 boardp->id, shost->irq);
18385 } else if (ret == -EINVAL) {
18386 ASC_PRINT2
18387 ("advansys_board_found: board %d: request_irq(): IRQ 0x%x not valid.\n",
18388 boardp->id, shost->irq);
18389 } else {
18390 ASC_PRINT3
18391 ("advansys_board_found: board %d: request_irq(): IRQ 0x%x failed with %d\n",
18392 boardp->id, shost->irq, ret);
18393 }
18394 release_region(shost->io_port, boardp->asc_n_io_port);
18395 iounmap(boardp->ioremap_addr);
18396 if (shost->dma_channel != NO_ISA_DMA) {
18397 free_dma(shost->dma_channel);
18398 }
18399#ifdef CONFIG_PROC_FS
18400 kfree(boardp->prtbuf);
18401#endif /* CONFIG_PROC_FS */
18402 scsi_unregister(shost);
18403 asc_board_count--;
18404 return NULL;
18405 }
18406
18407 /*
18408 * Initialize board RISC chip and enable interrupts.
18409 */
18410 if (ASC_NARROW_BOARD(boardp)) {
18411 ASC_DBG(2, "advansys_board_found: AscInitAsc1000Driver()\n");
18412 warn_code = AscInitAsc1000Driver(asc_dvc_varp);
18413 err_code = asc_dvc_varp->err_code;
18414
18415 if (warn_code || err_code) {
18416 ASC_PRINT4
18417 ("advansys_board_found: board %d error: init_state 0x%x, warn 0x%x, error 0x%x\n",
18418 boardp->id,
18419 asc_dvc_varp->init_state, warn_code, err_code);
18420 }
18421 } else {
18422 ADV_CARR_T *carrp;
18423 int req_cnt = 0;
18424 adv_req_t *reqp = NULL;
18425 int sg_cnt = 0;
18426
18427 /*
18428 * Allocate buffer carrier structures. The total size
18429 * is about 4 KB, so allocate all at once.
18430 */
18431 carrp = (ADV_CARR_T *) kmalloc(ADV_CARRIER_BUFSIZE, GFP_ATOMIC);
18432 ASC_DBG1(1, "advansys_board_found: carrp 0x%lx\n", (ulong)carrp);
18433
18434 if (carrp == NULL) {
18435 goto kmalloc_error;
18436 }
18437
18438 /*
18439 * Allocate up to 'max_host_qng' request structures for
18440 * the Wide board. The total size is about 16 KB, so
18441 * allocate all at once. If the allocation fails decrement
18442 * and try again.
18443 */
18444 for (req_cnt = adv_dvc_varp->max_host_qng;
18445 req_cnt > 0; req_cnt--) {
18446
18447 reqp = (adv_req_t *)
18448 kmalloc(sizeof(adv_req_t) * req_cnt, GFP_ATOMIC);
18449
18450 ASC_DBG3(1,
18451 "advansys_board_found: reqp 0x%lx, req_cnt %d, bytes %lu\n",
18452 (ulong)reqp, req_cnt,
18453 (ulong)sizeof(adv_req_t) * req_cnt);
18454
18455 if (reqp != NULL) {
18456 break;
18457 }
18458 }
18459 if (reqp == NULL) {
18460 goto kmalloc_error;
18461 }
18462
18463 /*
18464 * Allocate up to ADV_TOT_SG_BLOCK request structures for
18465 * the Wide board. Each structure is about 136 bytes.
18466 */
18467 boardp->adv_sgblkp = NULL;
18468 for (sg_cnt = 0; sg_cnt < ADV_TOT_SG_BLOCK; sg_cnt++) {
18469
18470 sgp = (adv_sgblk_t *)
18471 kmalloc(sizeof(adv_sgblk_t), GFP_ATOMIC);
18472
18473 if (sgp == NULL) {
18474 break;
18475 }
18476
18477 sgp->next_sgblkp = boardp->adv_sgblkp;
18478 boardp->adv_sgblkp = sgp;
18479
18480 }
18481 ASC_DBG3(1,
18482 "advansys_board_found: sg_cnt %d * %u = %u bytes\n",
18483 sg_cnt, sizeof(adv_sgblk_t),
18484 (unsigned)(sizeof(adv_sgblk_t) * sg_cnt));
18485
18486 /*
18487 * If no request structures or scatter-gather structures could
18488 * be allocated, then return an error. Otherwise continue with
18489 * initialization.
18490 */
18491 kmalloc_error:
18492 if (carrp == NULL) {
18493 ASC_PRINT1
18494 ("advansys_board_found: board %d error: failed to kmalloc() carrier buffer.\n",
18495 boardp->id);
18496 err_code = ADV_ERROR;
18497 } else if (reqp == NULL) {
18498 kfree(carrp);
18499 ASC_PRINT1
18500 ("advansys_board_found: board %d error: failed to kmalloc() adv_req_t buffer.\n",
18501 boardp->id);
18502 err_code = ADV_ERROR;
18503 } else if (boardp->adv_sgblkp == NULL) {
18504 kfree(carrp);
18505 kfree(reqp);
18506 ASC_PRINT1
18507 ("advansys_board_found: board %d error: failed to kmalloc() adv_sgblk_t buffers.\n",
18508 boardp->id);
18509 err_code = ADV_ERROR;
18510 } else {
18511
18512 /* Save carrier buffer pointer. */
18513 boardp->orig_carrp = carrp;
18514
18515 /*
18516 * Save original pointer for kfree() in case the
18517 * driver is built as a module and can be unloaded.
18518 */
18519 boardp->orig_reqp = reqp;
18520
18521 adv_dvc_varp->carrier_buf = carrp;
18522
18523 /*
18524 * Point 'adv_reqp' to the request structures and
18525 * link them together.
18526 */
18527 req_cnt--;
18528 reqp[req_cnt].next_reqp = NULL;
18529 for (; req_cnt > 0; req_cnt--) {
18530 reqp[req_cnt - 1].next_reqp = &reqp[req_cnt];
18531 }
18532 boardp->adv_reqp = &reqp[0];
18533
18534 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
18535 ASC_DBG(2,
18536 "advansys_board_found: AdvInitAsc3550Driver()\n");
18537 warn_code = AdvInitAsc3550Driver(adv_dvc_varp);
18538 } else if (adv_dvc_varp->chip_type ==
18539 ADV_CHIP_ASC38C0800) {
18540 ASC_DBG(2,
18541 "advansys_board_found: AdvInitAsc38C0800Driver()\n");
18542 warn_code =
18543 AdvInitAsc38C0800Driver(adv_dvc_varp);
18544 } else {
18545 ASC_DBG(2,
18546 "advansys_board_found: AdvInitAsc38C1600Driver()\n");
18547 warn_code =
18548 AdvInitAsc38C1600Driver(adv_dvc_varp);
18549 }
18550 err_code = adv_dvc_varp->err_code;
18551
18552 if (warn_code || err_code) {
18553 ASC_PRINT3
18554 ("advansys_board_found: board %d error: warn 0x%x, error 0x%x\n",
18555 boardp->id, warn_code, err_code);
18556 }
18557 }
18558 }
18559
18560 if (err_code != 0) {
18561 release_region(shost->io_port, boardp->asc_n_io_port);
18562 if (ASC_WIDE_BOARD(boardp)) {
18563 iounmap(boardp->ioremap_addr);
18564 kfree(boardp->orig_carrp);
18565 boardp->orig_carrp = NULL;
18566 if (boardp->orig_reqp) {
18567 kfree(boardp->orig_reqp);
18568 boardp->orig_reqp = boardp->adv_reqp = NULL;
18569 }
18570 while ((sgp = boardp->adv_sgblkp) != NULL) {
18571 boardp->adv_sgblkp = sgp->next_sgblkp;
18572 kfree(sgp);
18573 }
18574 }
18575 if (shost->dma_channel != NO_ISA_DMA) {
18576 free_dma(shost->dma_channel);
18577 }
18578#ifdef CONFIG_PROC_FS
18579 kfree(boardp->prtbuf);
18580#endif /* CONFIG_PROC_FS */
074c8fe4 18581 free_irq(shost->irq, shost);
27c868c2
MW
18582 scsi_unregister(shost);
18583 asc_board_count--;
18584 return NULL;
18585 }
18586 ASC_DBG_PRT_SCSI_HOST(2, shost);
18587
18588 return shost;
18589}
18590
18591/*
18592 * advansys_detect()
18593 *
18594 * Detect function for AdvanSys adapters.
18595 *
18596 * Argument is a pointer to the host driver's scsi_hosts entry.
18597 *
18598 * Return number of adapters found.
18599 *
18600 * Note: Because this function is called during system initialization
18601 * it must not call SCSI mid-level functions including scsi_malloc()
18602 * and scsi_free().
18603 */
18604static int __init advansys_detect(struct scsi_host_template *tpnt)
18605{
18606 static int detect_called = ASC_FALSE;
18607 int iop;
18608 int bus;
18609 int ioport = 0;
18610 struct device *dev = NULL;
18611#ifdef CONFIG_PCI
18612 int pci_init_search = 0;
18613 struct pci_dev *pci_devicep[ASC_NUM_BOARD_SUPPORTED];
18614 int pci_card_cnt_max = 0;
18615 int pci_card_cnt = 0;
18616 struct pci_dev *pdev = NULL;
18617 int pci_device_id_cnt = 0;
18618 unsigned int pci_device_id[ASC_PCI_DEVICE_ID_CNT] = {
18619 PCI_DEVICE_ID_ASP_1200A,
18620 PCI_DEVICE_ID_ASP_ABP940,
18621 PCI_DEVICE_ID_ASP_ABP940U,
18622 PCI_DEVICE_ID_ASP_ABP940UW,
18623 PCI_DEVICE_ID_38C0800_REV1,
18624 PCI_DEVICE_ID_38C1600_REV1
18625 };
18626#endif /* CONFIG_PCI */
18627
18628 if (detect_called == ASC_FALSE) {
18629 detect_called = ASC_TRUE;
18630 } else {
18631 printk
18632 ("AdvanSys SCSI: advansys_detect() multiple calls ignored\n");
18633 return 0;
18634 }
18635
18636 ASC_DBG(1, "advansys_detect: begin\n");
18637
18638 asc_board_count = 0;
18639
18640 /*
18641 * If I/O port probing has been modified, then verify and
18642 * clean-up the 'asc_ioport' list.
18643 */
18644 if (asc_iopflag == ASC_TRUE) {
18645 for (ioport = 0; ioport < ASC_NUM_IOPORT_PROBE; ioport++) {
18646 ASC_DBG2(1, "advansys_detect: asc_ioport[%d] 0x%x\n",
18647 ioport, asc_ioport[ioport]);
18648 if (asc_ioport[ioport] != 0) {
18649 for (iop = 0; iop < ASC_IOADR_TABLE_MAX_IX;
18650 iop++) {
18651 if (_asc_def_iop_base[iop] ==
18652 asc_ioport[ioport]) {
18653 break;
18654 }
18655 }
18656 if (iop == ASC_IOADR_TABLE_MAX_IX) {
18657 printk
18658 ("AdvanSys SCSI: specified I/O Port 0x%X is invalid\n",
18659 asc_ioport[ioport]);
18660 asc_ioport[ioport] = 0;
18661 }
18662 }
18663 }
18664 ioport = 0;
18665 }
18666
18667 for (bus = 0; bus < ASC_NUM_BUS; bus++) {
18668
18669 ASC_DBG2(1, "advansys_detect: bus search type %d (%s)\n",
18670 bus, asc_bus_name[bus]);
18671 iop = 0;
18672
18673 while (asc_board_count < ASC_NUM_BOARD_SUPPORTED) {
18674
18675 ASC_DBG1(2, "advansys_detect: asc_board_count %d\n",
18676 asc_board_count);
18677
18678 switch (asc_bus[bus]) {
18679 case ASC_IS_ISA:
18680 case ASC_IS_VL:
18681#ifdef CONFIG_ISA
18682 if (asc_iopflag == ASC_FALSE) {
18683 iop =
18684 AscSearchIOPortAddr(iop,
18685 asc_bus[bus]);
18686 } else {
18687 /*
18688 * ISA and VL I/O port scanning has either been
18689 * eliminated or limited to selected ports on
18690 * the LILO command line, /etc/lilo.conf, or
18691 * by setting variables when the module was loaded.
18692 */
18693 ASC_DBG(1,
18694 "advansys_detect: I/O port scanning modified\n");
18695 ioport_try_again:
18696 iop = 0;
18697 for (; ioport < ASC_NUM_IOPORT_PROBE;
18698 ioport++) {
18699 if ((iop =
18700 asc_ioport[ioport]) != 0) {
18701 break;
18702 }
18703 }
18704 if (iop) {
18705 ASC_DBG1(1,
18706 "advansys_detect: probing I/O port 0x%x...\n",
18707 iop);
18708 if (!request_region
18709 (iop, ASC_IOADR_GAP,
18710 "advansys")) {
18711 printk
18712 ("AdvanSys SCSI: specified I/O Port 0x%X is busy\n",
18713 iop);
18714 /* Don't try this I/O port twice. */
18715 asc_ioport[ioport] = 0;
18716 goto ioport_try_again;
18717 } else if (AscFindSignature(iop)
18718 == ASC_FALSE) {
18719 printk
18720 ("AdvanSys SCSI: specified I/O Port 0x%X has no adapter\n",
18721 iop);
18722 /* Don't try this I/O port twice. */
18723 release_region(iop,
18724 ASC_IOADR_GAP);
18725 asc_ioport[ioport] = 0;
18726 goto ioport_try_again;
18727 } else {
18728 /*
18729 * If this isn't an ISA board, then it must be
18730 * a VL board. If currently looking an ISA
18731 * board is being looked for then try for
18732 * another ISA board in 'asc_ioport'.
18733 */
18734 if (asc_bus[bus] ==
18735 ASC_IS_ISA
18736 &&
18737 (AscGetChipVersion
18738 (iop,
18739 ASC_IS_ISA) &
18740 ASC_CHIP_VER_ISA_BIT)
18741 == 0) {
18742 /*
18743 * Don't clear 'asc_ioport[ioport]'. Try
18744 * this board again for VL. Increment
18745 * 'ioport' past this board.
18746 */
18747 ioport++;
18748 release_region
18749 (iop,
18750 ASC_IOADR_GAP);
18751 goto ioport_try_again;
18752 }
18753 }
18754 /*
18755 * This board appears good, don't try the I/O port
18756 * again by clearing its value. Increment 'ioport'
18757 * for the next iteration.
18758 */
18759 asc_ioport[ioport++] = 0;
18760 }
18761 }
18762#endif /* CONFIG_ISA */
18763 break;
18764
18765 case ASC_IS_EISA:
18766#ifdef CONFIG_ISA
18767 iop = AscSearchIOPortAddr(iop, asc_bus[bus]);
18768#endif /* CONFIG_ISA */
18769 break;
18770
18771 case ASC_IS_PCI:
18772#ifdef CONFIG_PCI
18773 if (pci_init_search == 0) {
18774 int i, j;
18775
18776 pci_init_search = 1;
18777
18778 /* Find all PCI cards. */
18779 while (pci_device_id_cnt <
18780 ASC_PCI_DEVICE_ID_CNT) {
18781 if ((pdev =
18782 pci_find_device
18783 (PCI_VENDOR_ID_ASP,
18784 pci_device_id
18785 [pci_device_id_cnt],
18786 pdev)) == NULL) {
18787 pci_device_id_cnt++;
18788 } else {
18789 if (pci_enable_device
18790 (pdev) == 0) {
18791 pci_devicep
18792 [pci_card_cnt_max++]
18793 = pdev;
18794 }
18795 }
18796 }
18797
18798 /*
18799 * Sort PCI cards in ascending order by PCI Bus, Slot,
18800 * and Device Number.
18801 */
18802 for (i = 0; i < pci_card_cnt_max - 1;
18803 i++) {
18804 for (j = i + 1;
18805 j < pci_card_cnt_max;
18806 j++) {
18807 if ((pci_devicep[j]->
18808 bus->number <
18809 pci_devicep[i]->
18810 bus->number)
18811 ||
18812 ((pci_devicep[j]->
18813 bus->number ==
18814 pci_devicep[i]->
18815 bus->number)
18816 &&
18817 (pci_devicep[j]->
18818 devfn <
18819 pci_devicep[i]->
18820 devfn))) {
18821 pdev =
18822 pci_devicep
18823 [i];
18824 pci_devicep[i] =
18825 pci_devicep
18826 [j];
18827 pci_devicep[j] =
18828 pdev;
18829 }
18830 }
18831 }
18832
18833 pci_card_cnt = 0;
18834 } else {
18835 pci_card_cnt++;
18836 }
18837
18838 if (pci_card_cnt == pci_card_cnt_max) {
18839 iop = 0;
18840 } else {
18841 pdev = pci_devicep[pci_card_cnt];
18842
18843 ASC_DBG2(2,
18844 "advansys_detect: devfn %d, bus number %d\n",
18845 pdev->devfn,
18846 pdev->bus->number);
18847 iop = pci_resource_start(pdev, 0);
18848 ASC_DBG2(1,
18849 "advansys_detect: vendorID %X, deviceID %X\n",
18850 pdev->vendor,
18851 pdev->device);
18852 ASC_DBG2(2,
18853 "advansys_detect: iop %X, irqLine %d\n",
18854 iop, pdev->irq);
18855 }
18856 if (pdev)
18857 dev = &pdev->dev;
18858
18859#endif /* CONFIG_PCI */
18860 break;
18861
18862 default:
18863 ASC_PRINT1
18864 ("advansys_detect: unknown bus type: %d\n",
18865 asc_bus[bus]);
18866 break;
18867 }
18868 ASC_DBG1(1, "advansys_detect: iop 0x%x\n", iop);
18869
18870 /*
18871 * Adapter not found, try next bus type.
18872 */
18873 if (iop == 0) {
18874 break;
18875 }
18876
18877 advansys_board_found(iop, dev, asc_bus[bus]);
18878 }
18879 }
18880
18881 ASC_DBG1(1, "advansys_detect: done: asc_board_count %d\n",
18882 asc_board_count);
18883 return asc_board_count;
18884}
18885
18886/*
18887 * advansys_release()
18888 *
18889 * Release resources allocated for a single AdvanSys adapter.
18890 */
18891static int advansys_release(struct Scsi_Host *shost)
18892{
18893 asc_board_t *boardp;
18894
18895 ASC_DBG(1, "advansys_release: begin\n");
18896 boardp = ASC_BOARDP(shost);
074c8fe4 18897 free_irq(shost->irq, shost);
27c868c2
MW
18898 if (shost->dma_channel != NO_ISA_DMA) {
18899 ASC_DBG(1, "advansys_release: free_dma()\n");
18900 free_dma(shost->dma_channel);
18901 }
18902 release_region(shost->io_port, boardp->asc_n_io_port);
18903 if (ASC_WIDE_BOARD(boardp)) {
18904 adv_sgblk_t *sgp = NULL;
18905
18906 iounmap(boardp->ioremap_addr);
18907 kfree(boardp->orig_carrp);
18908 boardp->orig_carrp = NULL;
18909 if (boardp->orig_reqp) {
18910 kfree(boardp->orig_reqp);
18911 boardp->orig_reqp = boardp->adv_reqp = NULL;
18912 }
18913 while ((sgp = boardp->adv_sgblkp) != NULL) {
18914 boardp->adv_sgblkp = sgp->next_sgblkp;
18915 kfree(sgp);
18916 }
18917 }
18918#ifdef CONFIG_PROC_FS
18919 ASC_ASSERT(boardp->prtbuf != NULL);
18920 kfree(boardp->prtbuf);
18921#endif /* CONFIG_PROC_FS */
18922 scsi_unregister(shost);
18923 ASC_DBG(1, "advansys_release: end\n");
18924 return 0;
18925}
18926
d8dafd8c 18927#ifdef CONFIG_PCI
2672ea86
DJ
18928/* PCI Devices supported by this driver */
18929static struct pci_device_id advansys_pci_tbl[] __devinitdata = {
27c868c2
MW
18930 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_1200A,
18931 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
18932 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940,
18933 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
18934 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940U,
18935 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
18936 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940UW,
18937 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
18938 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C0800_REV1,
18939 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
18940 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C1600_REV1,
18941 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
18942 {}
2672ea86 18943};
27c868c2 18944
2672ea86 18945MODULE_DEVICE_TABLE(pci, advansys_pci_tbl);
d8dafd8c 18946#endif /* CONFIG_PCI */
8c6af9e1
MW
18947
18948MODULE_LICENSE("GPL");