Ok. I didn't make 2.4.0 in 2000. Tough. I tried, but we had some
[davej-history.git] / drivers / scsi / advansys.c
blob69fec6b1499c51f231c0cf0ba14a527e76e47ed3
1 /* $Id: advansys.c,v 1.69 1999/11/29 18:37:53 bobf Exp bobf $ */
2 #define ASC_VERSION "3.2M" /* AdvanSys Driver Version */
4 /*
5 * advansys.c - Linux Host Driver for AdvanSys SCSI Adapters
6 *
7 * Copyright (c) 1995-1999 Advanced System Products, Inc.
8 * All Rights Reserved.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that redistributions of source
12 * code retain the above copyright notice and this comment without
13 * modification.
15 * There is an AdvanSys Linux WWW page at:
16 * http://www.advansys.com/linux.html
18 * The latest version of the AdvanSys driver is available at:
19 * ftp://ftp.advansys.com/pub/linux/linux.tgz
21 * Please send questions, comments, bug reports to:
22 * linux@advansys.com
27 Documentation for the AdvanSys Driver
29 A. Linux Kernel Testing
30 B. Adapters Supported by this Driver
31 C. Linux v1.2.X - Directions for Adding the AdvanSys Driver
32 D. Linux v1.3.1 - v1.3.57 - Directions for Adding the AdvanSys Driver
33 E. Linux v1.3.58 and Newer - Upgrading the AdvanSys Driver
34 F. Source Comments
35 G. Driver Compile Time Options and Debugging
36 H. Driver LILO Option
37 I. Release History
38 J. Known Problems/Fix List
39 K. Credits
40 L. AdvanSys Contact Information
42 A. Linux Kernel Testing
44 This driver has been tested in the following Linux kernels: v1.2.13,
45 v1.3.57, v2.0.38, v2.2.13, and v2.3.28. These kernel versions are major
46 releases of Linux or the latest Linux kernel versions available when
47 this version of the driver was released. The driver should also work
48 in earlier versions of the Linux kernel. Beginning with v1.3.58 the
49 AdvanSys driver is included with all Linux kernels. Please refer to
50 sections C, D, and E for instructions on adding or upgrading the
51 AdvanSys driver. The driver is supported for x86 and alpha systems.
53 B. Adapters Supported by this Driver
55 AdvanSys (Advanced System Products, Inc.) manufactures the following
56 RISC-based, Bus-Mastering, Fast (10 Mhz) and Ultra (20 Mhz) Narrow
57 (8-bit transfer) SCSI Host Adapters for the ISA, EISA, VL, and PCI
58 buses and RISC-based, Bus-Mastering, Ultra (20 Mhz) Wide (16-bit
59 transfer) SCSI Host Adapters for the PCI bus.
61 The CDB counts below indicate the number of SCSI CDB (Command
62 Descriptor Block) requests that can be stored in the RISC chip
63 cache and board LRAM. A CDB is a single SCSI command. The driver
64 detect routine will display the number of CDBs available for each
65 adapter detected. The number of CDBs used by the driver can be
66 lowered in the BIOS by changing the 'Host Queue Size' adapter setting.
68 Connectivity Products:
69 ABP510/5150 - Bus-Master ISA (240 CDB)
70 ABP5140 - Bus-Master ISA PnP (16 CDB)
71 ABP5142 - Bus-Master ISA PnP with floppy (16 CDB)
72 ABP902/3902 - Bus-Master PCI (16 CDB)
73 ABP3905 - Bus-Master PCI (16 CDB)
74 ABP915 - Bus-Master PCI (16 CDB)
75 ABP920 - Bus-Master PCI (16 CDB)
76 ABP3922 - Bus-Master PCI (16 CDB)
77 ABP3925 - Bus-Master PCI (16 CDB)
78 ABP930 - Bus-Master PCI (16 CDB)
79 ABP930U - Bus-Master PCI Ultra (16 CDB)
80 ABP930UA - Bus-Master PCI Ultra (16 CDB)
81 ABP960 - Bus-Master PCI MAC/PC (16 CDB)
82 ABP960U - Bus-Master PCI MAC/PC Ultra (16 CDB)
84 Single Channel Products:
85 ABP542 - Bus-Master ISA with floppy (240 CDB)
86 ABP742 - Bus-Master EISA (240 CDB)
87 ABP842 - Bus-Master VL (240 CDB)
88 ABP940 - Bus-Master PCI (240 CDB)
89 ABP940U - Bus-Master PCI Ultra (240 CDB)
90 ABP940UA/3940UA - Bus-Master PCI Ultra (240 CDB)
91 ABP970 - Bus-Master PCI MAC/PC (240 CDB)
92 ABP970U - Bus-Master PCI MAC/PC Ultra (240 CDB)
93 ABP3960UA - Bus-Master PCI MAC/PC Ultra (240 CDB)
94 ABP940UW/3940UW - Bus-Master PCI Ultra-Wide (253 CDB)
95 ABP970UW - Bus-Master PCI MAC/PC Ultra-Wide (253 CDB)
96 ABP3940U2W - Bus-Master PCI LVD/Ultra2-Wide (253 CDB)
98 Multi-Channel Products:
99 ABP752 - Dual Channel Bus-Master EISA (240 CDB Per Channel)
100 ABP852 - Dual Channel Bus-Master VL (240 CDB Per Channel)
101 ABP950 - Dual Channel Bus-Master PCI (240 CDB Per Channel)
102 ABP950UW - Dual Channel Bus-Master PCI Ultra-Wide (253 CDB Per Channel)
103 ABP980 - Four Channel Bus-Master PCI (240 CDB Per Channel)
104 ABP980U - Four Channel Bus-Master PCI Ultra (240 CDB Per Channel)
105 ABP980UA/3980UA - Four Channel Bus-Master PCI Ultra (16 CDB Per Chan.)
106 ABP3950U2W - Bus-Master PCI LVD/Ultra2-Wide and Ultra-Wide (253 CDB)
108 C. Linux v1.2.X - Directions for Adding the AdvanSys Driver
110 These directions apply to v1.2.13. For versions that follow v1.2.13.
111 but precede v1.3.57 some of the changes for Linux v1.3.X listed
112 below may need to be modified or included. A patch is available
113 for v1.2.13 from the AdvanSys WWW and FTP sites.
115 There are two source files: advansys.h and advansys.c. Copy
116 both of these files to the directory /usr/src/linux/drivers/scsi.
118 1. Add the following line to /usr/src/linux/arch/i386/config.in
119 after "comment 'SCSI low-level drivers'":
121 bool 'AdvanSys SCSI support' CONFIG_SCSI_ADVANSYS y
123 2. Add the following lines to /usr/src/linux/drivers/scsi/hosts.c
124 after "#include "hosts.h"":
126 #ifdef CONFIG_SCSI_ADVANSYS
127 #include "advansys.h"
128 #endif
130 and after "static Scsi_Host_Template builtin_scsi_hosts[] =":
132 #ifdef CONFIG_SCSI_ADVANSYS
133 ADVANSYS,
134 #endif
136 3. Add the following lines to /usr/src/linux/drivers/scsi/Makefile:
138 ifdef CONFIG_SCSI_ADVANSYS
139 SCSI_SRCS := $(SCSI_SRCS) advansys.c
140 SCSI_OBJS := $(SCSI_OBJS) advansys.o
141 else
142 SCSI_MODULE_OBJS := $(SCSI_MODULE_OBJS) advansys.o
143 endif
145 4. (Optional) If you would like to enable the LILO command line
146 and /etc/lilo.conf 'advansys' option, make the following changes.
147 This option can be used to disable I/O port scanning or to limit
148 I/O port scanning to specific addresses. Refer to the 'Driver
149 LILO Option' section below. Add the following lines to
150 /usr/src/linux/init/main.c in the prototype section:
152 extern void advansys_setup(char *str, int *ints);
154 and add the following lines to the bootsetups[] array.
156 #ifdef CONFIG_SCSI_ADVANSYS
157 { "advansys=", advansys_setup },
158 #endif
160 5. If you have the HP 4020i CD-R driver and Linux v1.2.X you should
161 add a fix to the CD-ROM target driver. This fix will allow
162 you to mount CDs with the iso9660 file system. Linux v1.3.X
163 already has this fix. In the file /usr/src/linux/drivers/scsi/sr.c
164 and function get_sectorsize() after the line:
166 if(scsi_CDs[i].sector_size == 0) scsi_CDs[i].sector_size = 2048;
168 add the following line:
170 if(scsi_CDs[i].sector_size == 2340) scsi_CDs[i].sector_size = 2048;
172 6. In the directory /usr/src/linux run 'make config' to configure
173 the AdvanSys driver, then run 'make vmlinux' or 'make zlilo' to
174 make the kernel. If the AdvanSys driver is not configured, then
175 a loadable module can be built by running 'make modules' and
176 'make modules_install'. Use 'insmod' and 'rmmod' to install
177 and remove advansys.o.
179 D. Linux v1.3.1 - v1.3.57 - Directions for Adding the AdvanSys Driver
181 These directions apply to v1.3.57. For versions that precede v1.3.57
182 some of these changes may need to be modified or eliminated. A patch
183 is available for v1.3.57 from the AdvanSys WWW and FTP sites.
184 Beginning with v1.3.58 this driver is included with the Linux
185 distribution eliminating the need for making any changes.
187 There are two source files: advansys.h and advansys.c. Copy
188 both of these files to the directory /usr/src/linux/drivers/scsi.
190 1. Add the following line to /usr/src/linux/drivers/scsi/Config.in
191 after "comment 'SCSI low-level drivers'":
193 dep_tristate 'AdvanSys SCSI support' CONFIG_SCSI_ADVANSYS $CONFIG_SCSI
195 2. Add the following lines to /usr/src/linux/drivers/scsi/hosts.c
196 after "#include "hosts.h"":
198 #ifdef CONFIG_SCSI_ADVANSYS
199 #include "advansys.h"
200 #endif
202 and after "static Scsi_Host_Template builtin_scsi_hosts[] =":
204 #ifdef CONFIG_SCSI_ADVANSYS
205 ADVANSYS,
206 #endif
208 3. Add the following lines to /usr/src/linux/drivers/scsi/Makefile:
210 ifeq ($(CONFIG_SCSI_ADVANSYS),y)
211 L_OBJS += advansys.o
212 else
213 ifeq ($(CONFIG_SCSI_ADVANSYS),m)
214 M_OBJS += advansys.o
215 endif
216 endif
218 4. Add the following line to /usr/src/linux/include/linux/proc_fs.h
219 in the enum scsi_directory_inos array:
221 PROC_SCSI_ADVANSYS,
223 5. (Optional) If you would like to enable the LILO command line
224 and /etc/lilo.conf 'advansys' option, make the following changes.
225 This option can be used to disable I/O port scanning or to limit
226 I/O port scanning to specific addresses. Refer to the 'Driver
227 LILO Option' section below. Add the following lines to
228 /usr/src/linux/init/main.c in the prototype section:
230 extern void advansys_setup(char *str, int *ints);
232 and add the following lines to the bootsetups[] array.
234 #ifdef CONFIG_SCSI_ADVANSYS
235 { "advansys=", advansys_setup },
236 #endif
238 6. In the directory /usr/src/linux run 'make config' to configure
239 the AdvanSys driver, then run 'make vmlinux' or 'make zlilo' to
240 make the kernel. If the AdvanSys driver is not configured, then
241 a loadable module can be built by running 'make modules' and
242 'make modules_install'. Use 'insmod' and 'rmmod' to install
243 and remove advansys.o.
245 E. Linux v1.3.58 and Newer - Upgrading the AdvanSys Driver
247 To upgrade the AdvanSys driver in a Linux v1.3.58 and newer
248 kernel, first check the version of the current driver. The
249 version is defined by the manifest constant ASC_VERSION at
250 the beginning of advansys.c. The new driver should have a
251 ASC_VERSION value greater than the current version. To install
252 the new driver rename advansys.c and advansys.h in the Linux
253 kernel source tree drivers/scsi directory to different names
254 or save them to a different directory in case you want to revert
255 to the old version of the driver. After the old driver is saved
256 copy the new advansys.c and advansys.h to drivers/scsi, rebuild
257 the kernel, and install the new kernel. No other changes are needed.
259 F. Source Comments
261 1. Use tab stops set to 4 for the source files. For vi use 'se tabstops=4'.
263 2. This driver should be maintained in multiple files. But to make
264 it easier to include with Linux and to follow Linux conventions,
265 the whole driver is maintained in the source files advansys.h and
266 advansys.c. In this file logical sections of the driver begin with
267 a comment that contains '---'. The following are the logical sections
268 of the driver below.
270 --- Linux Version
271 --- Linux Include Files
272 --- Driver Options
273 --- Debugging Header
274 --- Asc Library Constants and Macros
275 --- Adv Library Constants and Macros
276 --- Driver Constants and Macros
277 --- Driver Structures
278 --- Driver Data
279 --- Driver Function Prototypes
280 --- Linux 'Scsi_Host_Template' and advansys_setup() Functions
281 --- Loadable Driver Support
282 --- Miscellaneous Driver Functions
283 --- Functions Required by the Asc Library
284 --- Functions Required by the Adv Library
285 --- Tracing and Debugging Functions
286 --- Asc Library Functions
287 --- Adv Library Functions
289 3. The string 'XXX' is used to flag code that needs to be re-written
290 or that contains a problem that needs to be addressed.
292 4. I have stripped comments from and reformatted the source for the
293 Asc Library and Adv Library to reduce the size of this file. This
294 source can be found under the following headings. The Asc Library
295 is used to support Narrow Boards. The Adv Library is used to
296 support Wide Boards.
298 --- Asc Library Constants and Macros
299 --- Adv Library Constants and Macros
300 --- Asc Library Functions
301 --- Adv Library Functions
303 G. Driver Compile Time Options and Debugging
305 In this source file the following constants can be defined. They are
306 defined in the source below. Both of these options are enabled by
307 default.
309 1. ADVANSYS_ASSERT - Enable driver assertions (Def: Enabled)
311 Enabling this option adds assertion logic statements to the
312 driver. If an assertion fails a message will be displayed to
313 the console, but the system will continue to operate. Any
314 assertions encountered should be reported to the person
315 responsible for the driver. Assertion statements may proactively
316 detect problems with the driver and facilitate fixing these
317 problems. Enabling assertions will add a small overhead to the
318 execution of the driver.
320 2. ADVANSYS_DEBUG - Enable driver debugging (Def: Disabled)
322 Enabling this option adds tracing functions to the driver and
323 the ability to set a driver tracing level at boot time. This
324 option will also export symbols not required outside the driver to
325 the kernel name space. This option is very useful for debugging
326 the driver, but it will add to the size of the driver execution
327 image and add overhead to the execution of the driver.
329 The amount of debugging output can be controlled with the global
330 variable 'asc_dbglvl'. The higher the number the more output. By
331 default the debug level is 0.
333 If the driver is loaded at boot time and the LILO Driver Option
334 is included in the system, the debug level can be changed by
335 specifying a 5th (ASC_NUM_IOPORT_PROBE + 1) I/O Port. The
336 first three hex digits of the pseudo I/O Port must be set to
337 'deb' and the fourth hex digit specifies the debug level: 0 - F.
338 The following command line will look for an adapter at 0x330
339 and set the debug level to 2.
341 linux advansys=0x330,0,0,0,0xdeb2
343 If the driver is built as a loadable module this variable can be
344 defined when the driver is loaded. The following insmod command
345 will set the debug level to one.
347 insmod advansys.o asc_dbglvl=1
349 Debugging Message Levels:
350 0: Errors Only
351 1: High-Level Tracing
352 2-N: Verbose Tracing
354 I don't know the approved way for turning on printk()s to the
355 console. Here's a program I use to do this. Debug output is
356 logged in /var/adm/messages.
358 main()
360 syscall(103, 7, 0, 0);
363 I found that increasing LOG_BUF_LEN to 40960 in kernel/printk.c
364 prevents most level 1 debug messages from being lost.
366 3. ADVANSYS_STATS - Enable statistics (Def: Enabled >= v1.3.0)
368 Enabling this option adds statistics collection and display
369 through /proc to the driver. The information is useful for
370 monitoring driver and device performance. It will add to the
371 size of the driver execution image and add minor overhead to
372 the execution of the driver.
374 Statistics are maintained on a per adapter basis. Driver entry
375 point call counts and transfer size counts are maintained.
376 Statistics are only available for kernels greater than or equal
377 to v1.3.0 with the CONFIG_PROC_FS (/proc) file system configured.
379 AdvanSys SCSI adapter files have the following path name format:
381 /proc/scsi/advansys/[0-(ASC_NUM_BOARD_SUPPORTED-1)]
383 This information can be displayed with cat. For example:
385 cat /proc/scsi/advansys/0
387 When ADVANSYS_STATS is not defined the AdvanSys /proc files only
388 contain adapter and device configuration information.
390 H. Driver LILO Option
392 If init/main.c is modified as described in the 'Directions for Adding
393 the AdvanSys Driver to Linux' section (B.4.) above, the driver will
394 recognize the 'advansys' LILO command line and /etc/lilo.conf option.
395 This option can be used to either disable I/O port scanning or to limit
396 scanning to 1 - 4 I/O ports. Regardless of the option setting EISA and
397 PCI boards will still be searched for and detected. This option only
398 affects searching for ISA and VL boards.
400 Examples:
401 1. Eliminate I/O port scanning:
402 boot: linux advansys=
404 boot: linux advansys=0x0
405 2. Limit I/O port scanning to one I/O port:
406 boot: linux advansys=0x110
407 3. Limit I/O port scanning to four I/O ports:
408 boot: linux advansys=0x110,0x210,0x230,0x330
410 For a loadable module the same effect can be achieved by setting
411 the 'asc_iopflag' variable and 'asc_ioport' array when loading
412 the driver, e.g.
414 insmod advansys.o asc_iopflag=1 asc_ioport=0x110,0x330
416 If ADVANSYS_DEBUG is defined a 5th (ASC_NUM_IOPORT_PROBE + 1)
417 I/O Port may be added to specify the driver debug level. Refer to
418 the 'Driver Compile Time Options and Debugging' section above for
419 more information.
421 I. Release History
423 BETA-1.0 (12/23/95):
424 First Release
426 BETA-1.1 (12/28/95):
427 1. Prevent advansys_detect() from being called twice.
428 2. Add LILO 0xdeb[0-f] option to set 'asc_dbglvl'.
430 1.2 (1/12/96):
431 1. Prevent re-entrancy in the interrupt handler which
432 resulted in the driver hanging Linux.
433 2. Fix problem that prevented ABP-940 cards from being
434 recognized on some PCI motherboards.
435 3. Add support for the ABP-5140 PnP ISA card.
436 4. Fix check condition return status.
437 5. Add conditionally compiled code for Linux v1.3.X.
439 1.3 (2/23/96):
440 1. Fix problem in advansys_biosparam() that resulted in the
441 wrong drive geometry being returned for drives > 1GB with
442 extended translation enabled.
443 2. Add additional tracing during device initialization.
444 3. Change code that only applies to ISA PnP adapter.
445 4. Eliminate 'make dep' warning.
446 5. Try to fix problem with handling resets by increasing their
447 timeout value.
449 1.4 (5/8/96):
450 1. Change definitions to eliminate conflicts with other subsystems.
451 2. Add versioning code for the shared interrupt changes.
452 3. Eliminate problem in asc_rmqueue() with iterating after removing
453 a request.
454 4. Remove reset request loop problem from the "Known Problems or
455 Issues" section. This problem was isolated and fixed in the
456 mid-level SCSI driver.
458 1.5 (8/8/96):
459 1. Add support for ABP-940U (PCI Ultra) adapter.
460 2. Add support for IRQ sharing by setting the SA_SHIRQ flag for
461 request_irq and supplying a dev_id pointer to both request_irq()
462 and free_irq().
463 3. In AscSearchIOPortAddr11() restore a call to check_region() which
464 should be used before I/O port probing.
465 4. Fix bug in asc_prt_hex() which resulted in the displaying
466 the wrong data.
467 5. Incorporate miscellaneous Asc Library bug fixes and new microcode.
468 6. Change driver versioning to be specific to each Linux sub-level.
469 7. Change statistics gathering to be per adapter instead of global
470 to the driver.
471 8. Add more information and statistics to the adapter /proc file:
472 /proc/scsi/advansys[0...].
473 9. Remove 'cmd_per_lun' from the "Known Problems or Issues" list.
474 This problem has been addressed with the SCSI mid-level changes
475 made in v1.3.89. The advansys_select_queue_depths() function
476 was added for the v1.3.89 changes.
478 1.6 (9/10/96):
479 1. Incorporate miscellaneous Asc Library bug fixes and new microcode.
481 1.7 (9/25/96):
482 1. Enable clustering and optimize the setting of the maximum number
483 of scatter gather elements for any particular board. Clustering
484 increases CPU utilization, but results in a relatively larger
485 increase in I/O throughput.
486 2. Improve the performance of the request queuing functions by
487 adding a last pointer to the queue structure.
488 3. Correct problems with reset and abort request handling that
489 could have hung or crashed Linux.
490 4. Add more information to the adapter /proc file:
491 /proc/scsi/advansys[0...].
492 5. Remove the request timeout issue form the driver issues list.
493 6. Miscellaneous documentation additions and changes.
495 1.8 (10/4/96):
496 1. Make changes to handle the new v2.1.0 kernel memory mapping
497 in which a kernel virtual address may not be equivalent to its
498 bus or DMA memory address.
499 2. Change abort and reset request handling to make it yet even
500 more robust.
501 3. Try to mitigate request starvation by sending ordered requests
502 to heavily loaded, tag queuing enabled devices.
503 4. Maintain statistics on request response time.
504 5. Add request response time statistics and other information to
505 the adapter /proc file: /proc/scsi/advansys[0...].
507 1.9 (10/21/96):
508 1. Add conditionally compiled code (ASC_QUEUE_FLOW_CONTROL) to
509 make use of mid-level SCSI driver device queue depth flow
510 control mechanism. This will eliminate aborts caused by a
511 device being unable to keep up with requests and eliminate
512 repeat busy or QUEUE FULL status returned by a device.
513 2. Incorporate miscellaneous Asc Library bug fixes.
514 3. To allow the driver to work in kernels with broken module
515 support set 'cmd_per_lun' if the driver is compiled as a
516 module. This change affects kernels v1.3.89 to present.
517 4. Remove PCI BIOS address from the driver banner. The PCI BIOS
518 is relocated by the motherboard BIOS and its new address can
519 not be determined by the driver.
520 5. Add mid-level SCSI queue depth information to the adapter
521 /proc file: /proc/scsi/advansys[0...].
523 2.0 (11/14/96):
524 1. Change allocation of global structures used for device
525 initialization to guarantee they are in DMA-able memory.
526 Previously when the driver was loaded as a module these
527 structures might not have been in DMA-able memory, causing
528 device initialization to fail.
530 2.1 (12/30/96):
531 1. In advansys_reset(), if the request is a synchronous reset
532 request, even if the request serial number has changed, then
533 complete the request.
534 2. Add Asc Library bug fixes including new microcode.
535 3. Clear inquiry buffer before using it.
536 4. Correct ifdef typo.
538 2.2 (1/15/97):
539 1. Add Asc Library bug fixes including new microcode.
540 2. Add synchronous data transfer rate information to the
541 adapter /proc file: /proc/scsi/advansys[0...].
542 3. Change ADVANSYS_DEBUG to be disabled by default. This
543 will reduce the size of the driver image, eliminate execution
544 overhead, and remove unneeded symbols from the kernel symbol
545 space that were previously added by the driver.
546 4. Add new compile-time option ADVANSYS_ASSERT for assertion
547 code that used to be defined within ADVANSYS_DEBUG. This
548 option is enabled by default.
550 2.8 (5/26/97):
551 1. Change version number to 2.8 to synchronize the Linux driver
552 version numbering with other AdvanSys drivers.
553 2. Reformat source files without tabs to present the same view
554 of the file to everyone regardless of the editor tab setting
555 being used.
556 3. Add Asc Library bug fixes.
558 3.1A (1/8/98):
559 1. Change version number to 3.1 to indicate that support for
560 Ultra-Wide adapters (ABP-940UW) is included in this release.
561 2. Add Asc Library (Narrow Board) bug fixes.
562 3. Report an underrun condition with the host status byte set
563 to DID_UNDERRUN. Currently DID_UNDERRUN is defined to 0 which
564 causes the underrun condition to be ignored. When Linux defines
565 its own DID_UNDERRUN the constant defined in this file can be
566 removed.
567 4. Add patch to AscWaitTixISRDone().
568 5. Add support for up to 16 different AdvanSys host adapter SCSI
569 channels in one system. This allows four cards with four channels
570 to be used in one system.
572 3.1B (1/9/98):
573 1. Handle that PCI register base addresses are not always page
574 aligned even though ioremap() requires that the address argument
575 be page aligned.
577 3.1C (1/10/98):
578 1. Update latest BIOS version checked for from the /proc file.
579 2. Don't set microcode SDTR variable at initialization. Instead
580 wait until device capabilities have been detected from an Inquiry
581 command.
583 3.1D (1/21/98):
584 1. Improve performance when the driver is compiled as module by
585 allowing up to 64 scatter-gather elements instead of 8.
587 3.1E (5/1/98):
588 1. Set time delay in AscWaitTixISRDone() to 1000 ms.
589 2. Include SMP locking changes.
590 3. For v2.1.93 and newer kernels use CONFIG_PCI and new PCI BIOS
591 access functions.
592 4. Update board serial number printing.
593 5. Try allocating an IRQ both with and without the SA_INTERRUPT
594 flag set to allow IRQ sharing with drivers that do not set
595 the SA_INTERRUPT flag. Also display a more descriptive error
596 message if request_irq() fails.
597 6. Update to latest Asc and Adv Libraries.
599 3.2A (7/22/99):
600 1. Update Adv Library to 4.16 which includes support for
601 the ASC38C0800 (Ultra2/LVD) IC.
603 3.2B (8/23/99):
604 1. Correct PCI compile time option for v2.1.93 and greater
605 kernels, advansys_info() string, and debug compile time
606 option.
607 2. Correct DvcSleepMilliSecond() for v2.1.0 and greater
608 kernels. This caused an LVD detection/BIST problem problem
609 among other things.
610 3. Sort PCI cards by PCI Bus, Slot, Function ascending order
611 to be consistent with the BIOS.
612 4. Update to Asc Library S121 and Adv Library 5.2.
614 3.2C (8/24/99):
615 1. Correct PCI card detection bug introduced in 3.2B that
616 prevented PCI cards from being detected in kernels older
617 than v2.1.93.
619 3.2D (8/26/99):
620 1. Correct /proc device synchronous speed information display.
621 Also when re-negotiation is pending for a target device
622 note this condition with an * and footnote.
623 2. Correct initialization problem with Ultra-Wide cards that
624 have a pre-3.2 BIOS. A microcode variable changed locations
625 in 3.2 and greater BIOSes which caused WDTR to be attempted
626 erroneously with drives that don't support WDTR.
628 3.2E (8/30/99):
629 1. Fix compile error caused by v2.3.13 PCI structure change.
630 2. Remove field from ASCEEP_CONFIG that resulted in an EEPROM
631 checksum error for ISA cards.
632 3. Remove ASC_QUEUE_FLOW_CONTROL conditional code. The mid-level
633 SCSI changes that it depended on were never included in Linux.
635 3.2F (9/3/99):
636 1. Handle new initial function code added in v2.3.16 for all
637 driver versions.
639 3.2G (9/8/99):
640 1. Fix PCI board detection in v2.3.13 and greater kernels.
641 2. Fix comiple errors in v2.3.X with debugging enabled.
643 3.2H (9/13/99):
644 1. Add 64-bit address, long support for Alpha and UltraSPARC.
645 The driver has been verified to work on an Alpha system.
646 2. Add partial byte order handling support for Power PC and
647 other big-endian platforms. This support has not yet been
648 completed or verified.
649 3. For wide boards replace block zeroing of request and
650 scatter-gather structures with individual field initialization
651 to improve performance.
652 4. Correct and clarify ROM BIOS version detection.
654 3.2I (10/8/99):
655 1. Update to Adv Library 5.4.
656 2. Add v2.3.19 underrun reporting to asc_isr_callback() and
657 adv_isr_callback(). Remove DID_UNDERRUN constant and other
658 no longer needed code that previously documented the lack
659 of underrun handling.
661 3.2J (10/14/99):
662 1. Eliminate compile errors for v2.0 and earlier kernels.
664 3.2K (11/15/99):
665 1. Correct debug compile error in asc_prt_adv_scsi_req_q().
666 2. Update Adv Library to 5.5.
667 3. Add ifdef handling for /proc changes added in v2.3.28.
668 4. Increase Wide board scatter-gather list maximum length to
669 255 when the driver is compiled into the kernel.
671 3.2L (11/18/99):
672 1. Fix bug in adv_get_sglist() that caused an assertion failure
673 at line 7475. The reqp->sgblkp pointer must be initialized
674 to NULL in adv_get_sglist().
676 3.2M (11/29/99):
677 1. Really fix bug in adv_get_sglist().
678 2. Incorporate v2.3.29 changes into driver.
680 J. Known Problems/Fix List (XXX)
682 1. Need to add memory mapping workaround. Test the memory mapping.
683 If it doesn't work revert to I/O port access. Can a test be done
684 safely?
685 2. Handle an interrupt not working. Keep an interrupt counter in
686 the interrupt handler. In the timeout function if the interrupt
687 has not occurred then print a message and run in polled mode.
688 3. Allow bus type scanning order to be changed.
689 4. Need to add support for target mode commands, cf. CAM XPT.
690 5 Need to add support for new Linux SCSI error handling method.
691 6. Need to fix sti/cli code in Asc Library.
692 7. Need to fix abort code in Adv Library.
693 8. Reduce io_request_lock hold time.
695 K. Credits
697 Nathan Hartwell <mage@cdc3.cdc.net> provided the directions and
698 basis for the Linux v1.3.X changes which were included in the
699 1.2 release.
701 Thomas E Zerucha <zerucha@shell.portal.com> pointed out a bug
702 in advansys_biosparam() which was fixed in the 1.3 release.
704 Erik Ratcliffe <erik@caldera.com> has done testing of the
705 AdvanSys driver in the Caldera releases.
707 Rik van Riel <H.H.vanRiel@fys.ruu.nl> provided a patch to
708 AscWaitTixISRDone() which he found necessary to make the
709 driver work with a SCSI-1 disk.
711 Mark Moran <mmoran@mmoran.com> has helped test Ultra-Wide
712 support in the 3.1A driver.
714 Doug Gilbert <dgilbert@interlog.com> has made changes and
715 suggestions to improve the driver and done testing.
717 Ken Mort <ken@mort.net> reported a DEBUG compile bug fixed
718 in 3.2K.
720 L. AdvanSys Contact Information
722 Mail: Advanced System Products, Inc.
723 1150 Ringwood Court
724 San Jose, CA 95131
725 Operator/Sales: 1-408-383-9400
726 FAX: 1-408-383-9612
727 Tech Support: 1-408-467-2930
728 Tech Support E-Mail: support@advansys.com
729 FTP Site: ftp.advansys.com (login: anonymous)
730 Web Site: http://www.advansys.com
736 * --- Linux Version
739 /* Convert Linux Version, Patch-level, Sub-level to LINUX_VERSION_CODE. */
740 #define ASC_LINUX_VERSION(V, P, S) (((V) * 65536) + ((P) * 256) + (S))
742 #ifndef LINUX_VERSION_CODE
743 #include <linux/version.h>
744 #endif /* LINUX_VERSION_CODE */
748 * --- Linux Include Files
751 #include <linux/config.h>
752 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
753 #ifdef MODULE
754 #include <linux/module.h>
755 #endif /* MODULE */
756 #endif /* version >= v1.3.0 */
757 #include <linux/string.h>
758 #include <linux/sched.h>
759 #include <linux/kernel.h>
760 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,0)
761 #include <linux/head.h>
762 #endif /* verions < v2.1.0 */
763 #include <linux/types.h>
764 #include <linux/ioport.h>
765 #include <linux/delay.h>
766 #include <linux/malloc.h>
767 #include <linux/mm.h>
768 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
769 #include <linux/proc_fs.h>
770 #endif /* version >= v1.3.0 */
771 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(2,1,23)
772 #include <linux/init.h>
773 #endif /* version >= v2.1.23 */
774 #include <asm/io.h>
775 #include <asm/system.h>
776 #include <asm/dma.h>
777 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0)
778 #include "../block/blk.h"
779 #else /* version >= v1.3.0 */
780 #include <linux/blk.h>
781 #include <linux/stat.h>
782 #endif /* version >= v1.3.0 */
783 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(2,3,18)
784 #include <linux/spinlock.h>
785 #elif LINUX_VERSION_CODE >= ASC_LINUX_VERSION(2,1,95)
786 #include <asm/spinlock.h>
787 #endif /* version >= 2.1.95 */
788 #include "scsi.h"
789 #include "hosts.h"
790 #include "sd.h"
791 #include "advansys.h"
792 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(2,1,93)
793 #ifdef CONFIG_PCI
794 #include <linux/pci.h>
795 #endif /* CONFIG_PCI */
796 #else /* version < v2.1.93 */
798 * For earlier than v2.1.93 the driver has its own PCI configuration.
799 * If PCI is not needed in a kernel before v2.1.93 this define can be
800 * turned-off to make the driver object smaller.
802 #define ASC_CONFIG_PCI
803 #endif /* version < v2.1.93 */
805 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,0)
806 #define cpu_to_le16(word) (word)
807 #define le16_to_cpu(word) (word)
808 #define cpu_to_le32(dword) (dword)
809 #define le32_to_cpu(dword) (dword)
810 #endif /* version < v2.1.0 */
814 * --- Driver Options
817 /* Enable driver assertions. */
818 #define ADVANSYS_ASSERT
820 /* Enable driver tracing. */
821 /* #define ADVANSYS_DEBUG */
824 * Because of no /proc to display them, statistics are disabled
825 * for versions prior to v1.3.0.
827 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0)
828 #undef ADVANSYS_STATS /* Disable statistics */
829 #else /* version >= v1.3.0 */
830 #define ADVANSYS_STATS /* Enable statistics. */
831 #endif /* version >= v1.3.0 */
835 * --- Debugging Header
838 #ifdef ADVANSYS_DEBUG
839 #define STATIC
840 #else /* ADVANSYS_DEBUG */
841 #define STATIC static
842 #endif /* ADVANSYS_DEBUG */
846 * --- Asc Library Constants and Macros
849 #define ASC_LIB_VERSION_MAJOR 1
850 #define ASC_LIB_VERSION_MINOR 24
851 #define ASC_LIB_SERIAL_NUMBER 121
854 * Portable Data Types
856 * Any instance where a 32-bit long or pointer type is assumed
857 * for precision or HW defined structures, the following define
858 * types must be used. In Linux the char, short, and int types
859 * are all consistent at 8, 16, and 32 bits respectively. Pointers
860 * and long types are 64 bits on Alpha and UltraSPARC.
862 #define ASC_PADDR __u32 /* Physical/Bus address data type. */
863 #define ASC_VADDR __u32 /* Virtual address data type. */
864 #define ASC_DCNT __u32 /* Unsigned Data count type. */
865 #define ASC_SDCNT __s32 /* Signed Data count type. */
868 * These macros are used to convert a virtual address to a
869 * 32-bit value. This currently can be used on Linux Alpha
870 * which uses 64-bit virtual address but a 32-bit bus address.
871 * This is likely to break in the future, but doing this now
872 * will give us time to change the HW and FW to handle 64-bit
873 * addresses.
875 #define ASC_VADDR_TO_U32 virt_to_bus
876 #define ASC_U32_TO_VADDR bus_to_virt
878 typedef unsigned char uchar;
880 #ifndef NULL
881 #define NULL (0)
882 #endif
883 #ifndef TRUE
884 #define TRUE (1)
885 #endif
886 #ifndef FALSE
887 #define FALSE (0)
888 #endif
890 #define EOF (-1)
891 #define ERR (-1)
892 #define UW_ERR (uint)(0xFFFF)
893 #define isodd_word(val) ((((uint)val) & (uint)0x0001) != 0)
894 #define AscPCIConfigVendorIDRegister 0x0000
895 #define AscPCIConfigDeviceIDRegister 0x0002
896 #define AscPCIConfigCommandRegister 0x0004
897 #define AscPCIConfigStatusRegister 0x0006
898 #define AscPCIConfigRevisionIDRegister 0x0008
899 #define AscPCIConfigCacheSize 0x000C
900 #define AscPCIConfigLatencyTimer 0x000D
901 #define AscPCIIOBaseRegister 0x0010
902 #define AscPCICmdRegBits_IOMemBusMaster 0x0007
903 #define ASC_PCI_ID2BUS(id) ((id) & 0xFF)
904 #define ASC_PCI_ID2DEV(id) (((id) >> 11) & 0x1F)
905 #define ASC_PCI_ID2FUNC(id) (((id) >> 8) & 0x7)
906 #define ASC_PCI_MKID(bus, dev, func) ((((dev) & 0x1F) << 11) | (((func) & 0x7) << 8) | ((bus) & 0xFF))
907 #define ASC_PCI_VENDORID 0x10CD
908 #define ASC_PCI_DEVICEID_1200A 0x1100
909 #define ASC_PCI_DEVICEID_1200B 0x1200
910 #define ASC_PCI_DEVICEID_ULTRA 0x1300
911 #define ASC_PCI_REVISION_3150 0x02
912 #define ASC_PCI_REVISION_3050 0x03
914 #define ASC_DVCLIB_CALL_DONE (1)
915 #define ASC_DVCLIB_CALL_FAILED (0)
916 #define ASC_DVCLIB_CALL_ERROR (-1)
919 * Enable CC_VERY_LONG_SG_LIST to support up to 64K element SG lists.
920 * The SRB structure will have to be changed and the ASC_SRB2SCSIQ()
921 * macro re-defined to be able to obtain a ASC_SCSI_Q pointer from the
922 * SRB structure.
924 #define CC_VERY_LONG_SG_LIST 0
925 #define ASC_SRB2SCSIQ(srb_ptr) (srb_ptr)
927 #define PortAddr unsigned short /* port address size */
928 #define inp(port) inb(port)
929 #define inpw(port) inw(port)
930 #define inpl(port) inl(port)
931 #define outp(port, byte) outb((byte), (port))
932 #define outpw(port, word) outw((word), (port))
933 #define outpl(port, dword) outl((dword), (port))
934 #define ASC_MAX_SG_QUEUE 7
935 #define ASC_MAX_SG_LIST 255
937 #define ASC_CS_TYPE unsigned short
939 #define ASC_IS_ISA (0x0001)
940 #define ASC_IS_ISAPNP (0x0081)
941 #define ASC_IS_EISA (0x0002)
942 #define ASC_IS_PCI (0x0004)
943 #define ASC_IS_PCI_ULTRA (0x0104)
944 #define ASC_IS_PCMCIA (0x0008)
945 #define ASC_IS_MCA (0x0020)
946 #define ASC_IS_VL (0x0040)
947 #define ASC_ISA_PNP_PORT_ADDR (0x279)
948 #define ASC_ISA_PNP_PORT_WRITE (ASC_ISA_PNP_PORT_ADDR+0x800)
949 #define ASC_IS_WIDESCSI_16 (0x0100)
950 #define ASC_IS_WIDESCSI_32 (0x0200)
951 #define ASC_IS_BIG_ENDIAN (0x8000)
952 #define ASC_CHIP_MIN_VER_VL (0x01)
953 #define ASC_CHIP_MAX_VER_VL (0x07)
954 #define ASC_CHIP_MIN_VER_PCI (0x09)
955 #define ASC_CHIP_MAX_VER_PCI (0x0F)
956 #define ASC_CHIP_VER_PCI_BIT (0x08)
957 #define ASC_CHIP_MIN_VER_ISA (0x11)
958 #define ASC_CHIP_MIN_VER_ISA_PNP (0x21)
959 #define ASC_CHIP_MAX_VER_ISA (0x27)
960 #define ASC_CHIP_VER_ISA_BIT (0x30)
961 #define ASC_CHIP_VER_ISAPNP_BIT (0x20)
962 #define ASC_CHIP_VER_ASYN_BUG (0x21)
963 #define ASC_CHIP_VER_PCI 0x08
964 #define ASC_CHIP_VER_PCI_ULTRA_3150 (ASC_CHIP_VER_PCI | 0x02)
965 #define ASC_CHIP_VER_PCI_ULTRA_3050 (ASC_CHIP_VER_PCI | 0x03)
966 #define ASC_CHIP_MIN_VER_EISA (0x41)
967 #define ASC_CHIP_MAX_VER_EISA (0x47)
968 #define ASC_CHIP_VER_EISA_BIT (0x40)
969 #define ASC_CHIP_LATEST_VER_EISA ((ASC_CHIP_MIN_VER_EISA - 1) + 3)
970 #define ASC_MAX_LIB_SUPPORTED_ISA_CHIP_VER 0x21
971 #define ASC_MAX_LIB_SUPPORTED_PCI_CHIP_VER 0x0A
972 #define ASC_MAX_VL_DMA_ADDR (0x07FFFFFFL)
973 #define ASC_MAX_VL_DMA_COUNT (0x07FFFFFFL)
974 #define ASC_MAX_PCI_DMA_ADDR (0xFFFFFFFFL)
975 #define ASC_MAX_PCI_DMA_COUNT (0xFFFFFFFFL)
976 #define ASC_MAX_ISA_DMA_ADDR (0x00FFFFFFL)
977 #define ASC_MAX_ISA_DMA_COUNT (0x00FFFFFFL)
978 #define ASC_MAX_EISA_DMA_ADDR (0x07FFFFFFL)
979 #define ASC_MAX_EISA_DMA_COUNT (0x07FFFFFFL)
980 #ifndef inpw_noswap
981 #define inpw_noswap(port) inpw(port)
982 #endif
983 #ifndef outpw_noswap
984 #define outpw_noswap(port, data) outpw(port, data)
985 #endif
986 #define ASC_SCSI_ID_BITS 3
987 #define ASC_SCSI_TIX_TYPE uchar
988 #define ASC_ALL_DEVICE_BIT_SET 0xFF
989 #define ASC_SCSI_BIT_ID_TYPE uchar
990 #define ASC_MAX_TID 7
991 #define ASC_MAX_LUN 7
992 #define ASC_SCSI_WIDTH_BIT_SET 0xFF
993 #define ASC_MAX_SENSE_LEN 32
994 #define ASC_MIN_SENSE_LEN 14
995 #define ASC_MAX_CDB_LEN 12
996 #define ASC_SCSI_RESET_HOLD_TIME_US 60
997 #define SCSICMD_TestUnitReady 0x00
998 #define SCSICMD_Rewind 0x01
999 #define SCSICMD_Rezero 0x01
1000 #define SCSICMD_RequestSense 0x03
1001 #define SCSICMD_Format 0x04
1002 #define SCSICMD_FormatUnit 0x04
1003 #define SCSICMD_Read6 0x08
1004 #define SCSICMD_Write6 0x0A
1005 #define SCSICMD_Seek6 0x0B
1006 #define SCSICMD_Inquiry 0x12
1007 #define SCSICMD_Verify6 0x13
1008 #define SCSICMD_ModeSelect6 0x15
1009 #define SCSICMD_ModeSense6 0x1A
1010 #define SCSICMD_StartStopUnit 0x1B
1011 #define SCSICMD_LoadUnloadTape 0x1B
1012 #define SCSICMD_ReadCapacity 0x25
1013 #define SCSICMD_Read10 0x28
1014 #define SCSICMD_Write10 0x2A
1015 #define SCSICMD_Seek10 0x2B
1016 #define SCSICMD_Erase10 0x2C
1017 #define SCSICMD_WriteAndVerify10 0x2E
1018 #define SCSICMD_Verify10 0x2F
1019 #define SCSICMD_WriteBuffer 0x3B
1020 #define SCSICMD_ReadBuffer 0x3C
1021 #define SCSICMD_ReadLong 0x3E
1022 #define SCSICMD_WriteLong 0x3F
1023 #define SCSICMD_ReadTOC 0x43
1024 #define SCSICMD_ReadHeader 0x44
1025 #define SCSICMD_ModeSelect10 0x55
1026 #define SCSICMD_ModeSense10 0x5A
1027 #define SCSI_TYPE_DASD 0x00
1028 #define SCSI_TYPE_SASD 0x01
1029 #define SCSI_TYPE_PRN 0x02
1030 #define SCSI_TYPE_PROC 0x03
1031 #define SCSI_TYPE_WORM 0x04
1032 #define SCSI_TYPE_CDROM 0x05
1033 #define SCSI_TYPE_SCANNER 0x06
1034 #define SCSI_TYPE_OPTMEM 0x07
1035 #define SCSI_TYPE_MED_CHG 0x08
1036 #define SCSI_TYPE_COMM 0x09
1037 #define SCSI_TYPE_UNKNOWN 0x1F
1038 #define SCSI_TYPE_NO_DVC 0xFF
1039 #define INQ_CLOCKING_ST_ONLY 0x0
1040 #define INQ_CLOCKING_DT_ONLY 0x1
1041 #define INQ_CLOCKING_ST_AND_DT 0x3
1042 #define ASC_SCSIDIR_NOCHK 0x00
1043 #define ASC_SCSIDIR_T2H 0x08
1044 #define ASC_SCSIDIR_H2T 0x10
1045 #define ASC_SCSIDIR_NODATA 0x18
1046 #define SCSI_SENKEY_NO_SENSE 0x00
1047 #define SCSI_SENKEY_UNDEFINED 0x01
1048 #define SCSI_SENKEY_NOT_READY 0x02
1049 #define SCSI_SENKEY_MEDIUM_ERR 0x03
1050 #define SCSI_SENKEY_HW_ERR 0x04
1051 #define SCSI_SENKEY_ILLEGAL 0x05
1052 #define SCSI_SENKEY_ATTENTION 0x06
1053 #define SCSI_SENKEY_PROTECTED 0x07
1054 #define SCSI_SENKEY_BLANK 0x08
1055 #define SCSI_SENKEY_V_UNIQUE 0x09
1056 #define SCSI_SENKEY_CPY_ABORT 0x0A
1057 #define SCSI_SENKEY_ABORT 0x0B
1058 #define SCSI_SENKEY_EQUAL 0x0C
1059 #define SCSI_SENKEY_VOL_OVERFLOW 0x0D
1060 #define SCSI_SENKEY_MISCOMP 0x0E
1061 #define SCSI_SENKEY_RESERVED 0x0F
1062 #define SCSI_ASC_NOMEDIA 0x3A
1063 #define ASC_SRB_HOST(x) ((uchar)((uchar)(x) >> 4))
1064 #define ASC_SRB_TID(x) ((uchar)((uchar)(x) & (uchar)0x0F))
1065 #define ASC_SRB_LUN(x) ((uchar)((uint)(x) >> 13))
1066 #define PUT_CDB1(x) ((uchar)((uint)(x) >> 8))
1067 #define SS_GOOD 0x00
1068 #define SS_CHK_CONDITION 0x02
1069 #define SS_CONDITION_MET 0x04
1070 #define SS_TARGET_BUSY 0x08
1071 #define SS_INTERMID 0x10
1072 #define SS_INTERMID_COND_MET 0x14
1073 #define SS_RSERV_CONFLICT 0x18
1074 #define SS_CMD_TERMINATED 0x22
1075 #define SS_QUEUE_FULL 0x28
1076 #define MS_CMD_DONE 0x00
1077 #define MS_EXTEND 0x01
1078 #define MS_SDTR_LEN 0x03
1079 #define MS_SDTR_CODE 0x01
1080 #define MS_WDTR_LEN 0x02
1081 #define MS_WDTR_CODE 0x03
1082 #define MS_MDP_LEN 0x05
1083 #define MS_MDP_CODE 0x00
1084 #define M1_SAVE_DATA_PTR 0x02
1085 #define M1_RESTORE_PTRS 0x03
1086 #define M1_DISCONNECT 0x04
1087 #define M1_INIT_DETECTED_ERR 0x05
1088 #define M1_ABORT 0x06
1089 #define M1_MSG_REJECT 0x07
1090 #define M1_NO_OP 0x08
1091 #define M1_MSG_PARITY_ERR 0x09
1092 #define M1_LINK_CMD_DONE 0x0A
1093 #define M1_LINK_CMD_DONE_WFLAG 0x0B
1094 #define M1_BUS_DVC_RESET 0x0C
1095 #define M1_ABORT_TAG 0x0D
1096 #define M1_CLR_QUEUE 0x0E
1097 #define M1_INIT_RECOVERY 0x0F
1098 #define M1_RELEASE_RECOVERY 0x10
1099 #define M1_KILL_IO_PROC 0x11
1100 #define M2_QTAG_MSG_SIMPLE 0x20
1101 #define M2_QTAG_MSG_HEAD 0x21
1102 #define M2_QTAG_MSG_ORDERED 0x22
1103 #define M2_IGNORE_WIDE_RESIDUE 0x23
1105 typedef struct {
1106 uchar peri_dvc_type:5;
1107 uchar peri_qualifier:3;
1108 } ASC_SCSI_INQ0;
1110 typedef struct {
1111 uchar dvc_type_modifier:7;
1112 uchar rmb:1;
1113 } ASC_SCSI_INQ1;
1115 typedef struct {
1116 uchar ansi_apr_ver:3;
1117 uchar ecma_ver:3;
1118 uchar iso_ver:2;
1119 } ASC_SCSI_INQ2;
1121 typedef struct {
1122 uchar rsp_data_fmt:4;
1123 uchar res:2;
1124 uchar TemIOP:1;
1125 uchar aenc:1;
1126 } ASC_SCSI_INQ3;
1128 typedef struct {
1129 uchar StfRe:1;
1130 uchar CmdQue:1;
1131 uchar Reserved:1;
1132 uchar Linked:1;
1133 uchar Sync:1;
1134 uchar WBus16:1;
1135 uchar WBus32:1;
1136 uchar RelAdr:1;
1137 } ASC_SCSI_INQ7;
1139 typedef struct {
1140 ASC_SCSI_INQ0 byte0;
1141 ASC_SCSI_INQ1 byte1;
1142 ASC_SCSI_INQ2 byte2;
1143 ASC_SCSI_INQ3 byte3;
1144 uchar add_len;
1145 uchar res1;
1146 uchar res2;
1147 ASC_SCSI_INQ7 byte7;
1148 uchar vendor_id[8];
1149 uchar product_id[16];
1150 uchar product_rev_level[4];
1151 } ASC_SCSI_INQUIRY;
1153 typedef struct asc_req_sense {
1154 uchar err_code:7;
1155 uchar info_valid:1;
1156 uchar segment_no;
1157 uchar sense_key:4;
1158 uchar reserved_bit:1;
1159 uchar sense_ILI:1;
1160 uchar sense_EOM:1;
1161 uchar file_mark:1;
1162 uchar info1[4];
1163 uchar add_sense_len;
1164 uchar cmd_sp_info[4];
1165 uchar asc;
1166 uchar ascq;
1167 uchar fruc;
1168 uchar sks_byte0:7;
1169 uchar sks_valid:1;
1170 uchar sks_bytes[2];
1171 uchar notused[2];
1172 uchar ex_sense_code;
1173 uchar info2[4];
1174 } ASC_REQ_SENSE;
1176 #define ASC_SG_LIST_PER_Q 7
1177 #define QS_FREE 0x00
1178 #define QS_READY 0x01
1179 #define QS_DISC1 0x02
1180 #define QS_DISC2 0x04
1181 #define QS_BUSY 0x08
1182 #define QS_ABORTED 0x40
1183 #define QS_DONE 0x80
1184 #define QC_NO_CALLBACK 0x01
1185 #define QC_SG_SWAP_QUEUE 0x02
1186 #define QC_SG_HEAD 0x04
1187 #define QC_DATA_IN 0x08
1188 #define QC_DATA_OUT 0x10
1189 #define QC_URGENT 0x20
1190 #define QC_MSG_OUT 0x40
1191 #define QC_REQ_SENSE 0x80
1192 #define QCSG_SG_XFER_LIST 0x02
1193 #define QCSG_SG_XFER_MORE 0x04
1194 #define QCSG_SG_XFER_END 0x08
1195 #define QD_IN_PROGRESS 0x00
1196 #define QD_NO_ERROR 0x01
1197 #define QD_ABORTED_BY_HOST 0x02
1198 #define QD_WITH_ERROR 0x04
1199 #define QD_INVALID_REQUEST 0x80
1200 #define QD_INVALID_HOST_NUM 0x81
1201 #define QD_INVALID_DEVICE 0x82
1202 #define QD_ERR_INTERNAL 0xFF
1203 #define QHSTA_NO_ERROR 0x00
1204 #define QHSTA_M_SEL_TIMEOUT 0x11
1205 #define QHSTA_M_DATA_OVER_RUN 0x12
1206 #define QHSTA_M_DATA_UNDER_RUN 0x12
1207 #define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
1208 #define QHSTA_M_BAD_BUS_PHASE_SEQ 0x14
1209 #define QHSTA_D_QDONE_SG_LIST_CORRUPTED 0x21
1210 #define QHSTA_D_ASC_DVC_ERROR_CODE_SET 0x22
1211 #define QHSTA_D_HOST_ABORT_FAILED 0x23
1212 #define QHSTA_D_EXE_SCSI_Q_FAILED 0x24
1213 #define QHSTA_D_EXE_SCSI_Q_BUSY_TIMEOUT 0x25
1214 #define QHSTA_D_ASPI_NO_BUF_POOL 0x26
1215 #define QHSTA_M_WTM_TIMEOUT 0x41
1216 #define QHSTA_M_BAD_CMPL_STATUS_IN 0x42
1217 #define QHSTA_M_NO_AUTO_REQ_SENSE 0x43
1218 #define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
1219 #define QHSTA_M_TARGET_STATUS_BUSY 0x45
1220 #define QHSTA_M_BAD_TAG_CODE 0x46
1221 #define QHSTA_M_BAD_QUEUE_FULL_OR_BUSY 0x47
1222 #define QHSTA_M_HUNG_REQ_SCSI_BUS_RESET 0x48
1223 #define QHSTA_D_LRAM_CMP_ERROR 0x81
1224 #define QHSTA_M_MICRO_CODE_ERROR_HALT 0xA1
1225 #define ASC_FLAG_SCSIQ_REQ 0x01
1226 #define ASC_FLAG_BIOS_SCSIQ_REQ 0x02
1227 #define ASC_FLAG_BIOS_ASYNC_IO 0x04
1228 #define ASC_FLAG_SRB_LINEAR_ADDR 0x08
1229 #define ASC_FLAG_WIN16 0x10
1230 #define ASC_FLAG_WIN32 0x20
1231 #define ASC_FLAG_ISA_OVER_16MB 0x40
1232 #define ASC_FLAG_DOS_VM_CALLBACK 0x80
1233 #define ASC_TAG_FLAG_EXTRA_BYTES 0x10
1234 #define ASC_TAG_FLAG_DISABLE_DISCONNECT 0x04
1235 #define ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX 0x08
1236 #define ASC_TAG_FLAG_DISABLE_CHK_COND_INT_HOST 0x40
1237 #define ASC_SCSIQ_CPY_BEG 4
1238 #define ASC_SCSIQ_SGHD_CPY_BEG 2
1239 #define ASC_SCSIQ_B_FWD 0
1240 #define ASC_SCSIQ_B_BWD 1
1241 #define ASC_SCSIQ_B_STATUS 2
1242 #define ASC_SCSIQ_B_QNO 3
1243 #define ASC_SCSIQ_B_CNTL 4
1244 #define ASC_SCSIQ_B_SG_QUEUE_CNT 5
1245 #define ASC_SCSIQ_D_DATA_ADDR 8
1246 #define ASC_SCSIQ_D_DATA_CNT 12
1247 #define ASC_SCSIQ_B_SENSE_LEN 20
1248 #define ASC_SCSIQ_DONE_INFO_BEG 22
1249 #define ASC_SCSIQ_D_SRBPTR 22
1250 #define ASC_SCSIQ_B_TARGET_IX 26
1251 #define ASC_SCSIQ_B_CDB_LEN 28
1252 #define ASC_SCSIQ_B_TAG_CODE 29
1253 #define ASC_SCSIQ_W_VM_ID 30
1254 #define ASC_SCSIQ_DONE_STATUS 32
1255 #define ASC_SCSIQ_HOST_STATUS 33
1256 #define ASC_SCSIQ_SCSI_STATUS 34
1257 #define ASC_SCSIQ_CDB_BEG 36
1258 #define ASC_SCSIQ_DW_REMAIN_XFER_ADDR 56
1259 #define ASC_SCSIQ_DW_REMAIN_XFER_CNT 60
1260 #define ASC_SCSIQ_B_FIRST_SG_WK_QP 48
1261 #define ASC_SCSIQ_B_SG_WK_QP 49
1262 #define ASC_SCSIQ_B_SG_WK_IX 50
1263 #define ASC_SCSIQ_W_ALT_DC1 52
1264 #define ASC_SCSIQ_B_LIST_CNT 6
1265 #define ASC_SCSIQ_B_CUR_LIST_CNT 7
1266 #define ASC_SGQ_B_SG_CNTL 4
1267 #define ASC_SGQ_B_SG_HEAD_QP 5
1268 #define ASC_SGQ_B_SG_LIST_CNT 6
1269 #define ASC_SGQ_B_SG_CUR_LIST_CNT 7
1270 #define ASC_SGQ_LIST_BEG 8
1271 #define ASC_DEF_SCSI1_QNG 4
1272 #define ASC_MAX_SCSI1_QNG 4
1273 #define ASC_DEF_SCSI2_QNG 16
1274 #define ASC_MAX_SCSI2_QNG 32
1275 #define ASC_TAG_CODE_MASK 0x23
1276 #define ASC_STOP_REQ_RISC_STOP 0x01
1277 #define ASC_STOP_ACK_RISC_STOP 0x03
1278 #define ASC_STOP_CLEAN_UP_BUSY_Q 0x10
1279 #define ASC_STOP_CLEAN_UP_DISC_Q 0x20
1280 #define ASC_STOP_HOST_REQ_RISC_HALT 0x40
1281 #define ASC_TIDLUN_TO_IX(tid, lun) (ASC_SCSI_TIX_TYPE)((tid) + ((lun)<<ASC_SCSI_ID_BITS))
1282 #define ASC_TID_TO_TARGET_ID(tid) (ASC_SCSI_BIT_ID_TYPE)(0x01 << (tid))
1283 #define ASC_TIX_TO_TARGET_ID(tix) (0x01 << ((tix) & ASC_MAX_TID))
1284 #define ASC_TIX_TO_TID(tix) ((tix) & ASC_MAX_TID)
1285 #define ASC_TID_TO_TIX(tid) ((tid) & ASC_MAX_TID)
1286 #define ASC_TIX_TO_LUN(tix) (((tix) >> ASC_SCSI_ID_BITS) & ASC_MAX_LUN)
1287 #define ASC_QNO_TO_QADDR(q_no) ((ASC_QADR_BEG)+((int)(q_no) << 6))
1289 typedef struct asc_scisq_1 {
1290 uchar status;
1291 uchar q_no;
1292 uchar cntl;
1293 uchar sg_queue_cnt;
1294 uchar target_id;
1295 uchar target_lun;
1296 ASC_PADDR data_addr;
1297 ASC_DCNT data_cnt;
1298 ASC_PADDR sense_addr;
1299 uchar sense_len;
1300 uchar extra_bytes;
1301 } ASC_SCSIQ_1;
1303 typedef struct asc_scisq_2 {
1304 ASC_VADDR srb_ptr;
1305 uchar target_ix;
1306 uchar flag;
1307 uchar cdb_len;
1308 uchar tag_code;
1309 ushort vm_id;
1310 } ASC_SCSIQ_2;
1312 typedef struct asc_scsiq_3 {
1313 uchar done_stat;
1314 uchar host_stat;
1315 uchar scsi_stat;
1316 uchar scsi_msg;
1317 } ASC_SCSIQ_3;
1319 typedef struct asc_scsiq_4 {
1320 uchar cdb[ASC_MAX_CDB_LEN];
1321 uchar y_first_sg_list_qp;
1322 uchar y_working_sg_qp;
1323 uchar y_working_sg_ix;
1324 uchar y_res;
1325 ushort x_req_count;
1326 ushort x_reconnect_rtn;
1327 ASC_PADDR x_saved_data_addr;
1328 ASC_DCNT x_saved_data_cnt;
1329 } ASC_SCSIQ_4;
1331 typedef struct asc_q_done_info {
1332 ASC_SCSIQ_2 d2;
1333 ASC_SCSIQ_3 d3;
1334 uchar q_status;
1335 uchar q_no;
1336 uchar cntl;
1337 uchar sense_len;
1338 uchar extra_bytes;
1339 uchar res;
1340 ASC_DCNT remain_bytes;
1341 } ASC_QDONE_INFO;
1343 typedef struct asc_sg_list {
1344 ASC_PADDR addr;
1345 ASC_DCNT bytes;
1346 } ASC_SG_LIST;
1348 typedef struct asc_sg_head {
1349 ushort entry_cnt;
1350 ushort queue_cnt;
1351 ushort entry_to_copy;
1352 ushort res;
1353 ASC_SG_LIST sg_list[ASC_MAX_SG_LIST];
1354 } ASC_SG_HEAD;
1356 #define ASC_MIN_SG_LIST 2
1358 typedef struct asc_min_sg_head {
1359 ushort entry_cnt;
1360 ushort queue_cnt;
1361 ushort entry_to_copy;
1362 ushort res;
1363 ASC_SG_LIST sg_list[ASC_MIN_SG_LIST];
1364 } ASC_MIN_SG_HEAD;
1366 #define QCX_SORT (0x0001)
1367 #define QCX_COALEASE (0x0002)
1369 typedef struct asc_scsi_q {
1370 ASC_SCSIQ_1 q1;
1371 ASC_SCSIQ_2 q2;
1372 uchar *cdbptr;
1373 ASC_SG_HEAD *sg_head;
1374 ushort remain_sg_entry_cnt;
1375 ushort next_sg_index;
1376 } ASC_SCSI_Q;
1378 typedef struct asc_scsi_req_q {
1379 ASC_SCSIQ_1 r1;
1380 ASC_SCSIQ_2 r2;
1381 uchar *cdbptr;
1382 ASC_SG_HEAD *sg_head;
1383 uchar *sense_ptr;
1384 ASC_SCSIQ_3 r3;
1385 uchar cdb[ASC_MAX_CDB_LEN];
1386 uchar sense[ASC_MIN_SENSE_LEN];
1387 } ASC_SCSI_REQ_Q;
1389 typedef struct asc_scsi_bios_req_q {
1390 ASC_SCSIQ_1 r1;
1391 ASC_SCSIQ_2 r2;
1392 uchar *cdbptr;
1393 ASC_SG_HEAD *sg_head;
1394 uchar *sense_ptr;
1395 ASC_SCSIQ_3 r3;
1396 uchar cdb[ASC_MAX_CDB_LEN];
1397 uchar sense[ASC_MIN_SENSE_LEN];
1398 } ASC_SCSI_BIOS_REQ_Q;
1400 typedef struct asc_risc_q {
1401 uchar fwd;
1402 uchar bwd;
1403 ASC_SCSIQ_1 i1;
1404 ASC_SCSIQ_2 i2;
1405 ASC_SCSIQ_3 i3;
1406 ASC_SCSIQ_4 i4;
1407 } ASC_RISC_Q;
1409 typedef struct asc_sg_list_q {
1410 uchar seq_no;
1411 uchar q_no;
1412 uchar cntl;
1413 uchar sg_head_qp;
1414 uchar sg_list_cnt;
1415 uchar sg_cur_list_cnt;
1416 } ASC_SG_LIST_Q;
1418 typedef struct asc_risc_sg_list_q {
1419 uchar fwd;
1420 uchar bwd;
1421 ASC_SG_LIST_Q sg;
1422 ASC_SG_LIST sg_list[7];
1423 } ASC_RISC_SG_LIST_Q;
1425 #define ASC_EXE_SCSI_IO_MAX_IDLE_LOOP 0x1000000UL
1426 #define ASC_EXE_SCSI_IO_MAX_WAIT_LOOP 1024
1427 #define ASCQ_ERR_NO_ERROR 0
1428 #define ASCQ_ERR_IO_NOT_FOUND 1
1429 #define ASCQ_ERR_LOCAL_MEM 2
1430 #define ASCQ_ERR_CHKSUM 3
1431 #define ASCQ_ERR_START_CHIP 4
1432 #define ASCQ_ERR_INT_TARGET_ID 5
1433 #define ASCQ_ERR_INT_LOCAL_MEM 6
1434 #define ASCQ_ERR_HALT_RISC 7
1435 #define ASCQ_ERR_GET_ASPI_ENTRY 8
1436 #define ASCQ_ERR_CLOSE_ASPI 9
1437 #define ASCQ_ERR_HOST_INQUIRY 0x0A
1438 #define ASCQ_ERR_SAVED_SRB_BAD 0x0B
1439 #define ASCQ_ERR_QCNTL_SG_LIST 0x0C
1440 #define ASCQ_ERR_Q_STATUS 0x0D
1441 #define ASCQ_ERR_WR_SCSIQ 0x0E
1442 #define ASCQ_ERR_PC_ADDR 0x0F
1443 #define ASCQ_ERR_SYN_OFFSET 0x10
1444 #define ASCQ_ERR_SYN_XFER_TIME 0x11
1445 #define ASCQ_ERR_LOCK_DMA 0x12
1446 #define ASCQ_ERR_UNLOCK_DMA 0x13
1447 #define ASCQ_ERR_VDS_CHK_INSTALL 0x14
1448 #define ASCQ_ERR_MICRO_CODE_HALT 0x15
1449 #define ASCQ_ERR_SET_LRAM_ADDR 0x16
1450 #define ASCQ_ERR_CUR_QNG 0x17
1451 #define ASCQ_ERR_SG_Q_LINKS 0x18
1452 #define ASCQ_ERR_SCSIQ_PTR 0x19
1453 #define ASCQ_ERR_ISR_RE_ENTRY 0x1A
1454 #define ASCQ_ERR_CRITICAL_RE_ENTRY 0x1B
1455 #define ASCQ_ERR_ISR_ON_CRITICAL 0x1C
1456 #define ASCQ_ERR_SG_LIST_ODD_ADDRESS 0x1D
1457 #define ASCQ_ERR_XFER_ADDRESS_TOO_BIG 0x1E
1458 #define ASCQ_ERR_SCSIQ_NULL_PTR 0x1F
1459 #define ASCQ_ERR_SCSIQ_BAD_NEXT_PTR 0x20
1460 #define ASCQ_ERR_GET_NUM_OF_FREE_Q 0x21
1461 #define ASCQ_ERR_SEND_SCSI_Q 0x22
1462 #define ASCQ_ERR_HOST_REQ_RISC_HALT 0x23
1463 #define ASCQ_ERR_RESET_SDTR 0x24
1464 #define ASC_WARN_NO_ERROR 0x0000
1465 #define ASC_WARN_IO_PORT_ROTATE 0x0001
1466 #define ASC_WARN_EEPROM_CHKSUM 0x0002
1467 #define ASC_WARN_IRQ_MODIFIED 0x0004
1468 #define ASC_WARN_AUTO_CONFIG 0x0008
1469 #define ASC_WARN_CMD_QNG_CONFLICT 0x0010
1470 #define ASC_WARN_EEPROM_RECOVER 0x0020
1471 #define ASC_WARN_CFG_MSW_RECOVER 0x0040
1472 #define ASC_WARN_SET_PCI_CONFIG_SPACE 0x0080
1473 #define ASC_IERR_WRITE_EEPROM 0x0001
1474 #define ASC_IERR_MCODE_CHKSUM 0x0002
1475 #define ASC_IERR_SET_PC_ADDR 0x0004
1476 #define ASC_IERR_START_STOP_CHIP 0x0008
1477 #define ASC_IERR_IRQ_NO 0x0010
1478 #define ASC_IERR_SET_IRQ_NO 0x0020
1479 #define ASC_IERR_CHIP_VERSION 0x0040
1480 #define ASC_IERR_SET_SCSI_ID 0x0080
1481 #define ASC_IERR_GET_PHY_ADDR 0x0100
1482 #define ASC_IERR_BAD_SIGNATURE 0x0200
1483 #define ASC_IERR_NO_BUS_TYPE 0x0400
1484 #define ASC_IERR_SCAM 0x0800
1485 #define ASC_IERR_SET_SDTR 0x1000
1486 #define ASC_IERR_RW_LRAM 0x8000
1487 #define ASC_DEF_IRQ_NO 10
1488 #define ASC_MAX_IRQ_NO 15
1489 #define ASC_MIN_IRQ_NO 10
1490 #define ASC_MIN_REMAIN_Q (0x02)
1491 #define ASC_DEF_MAX_TOTAL_QNG (0xF0)
1492 #define ASC_MIN_TAG_Q_PER_DVC (0x04)
1493 #define ASC_DEF_TAG_Q_PER_DVC (0x04)
1494 #define ASC_MIN_FREE_Q ASC_MIN_REMAIN_Q
1495 #define ASC_MIN_TOTAL_QNG ((ASC_MAX_SG_QUEUE)+(ASC_MIN_FREE_Q))
1496 #define ASC_MAX_TOTAL_QNG 240
1497 #define ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG 16
1498 #define ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG 8
1499 #define ASC_MAX_PCI_INRAM_TOTAL_QNG 20
1500 #define ASC_MAX_INRAM_TAG_QNG 16
1501 #define ASC_IOADR_TABLE_MAX_IX 11
1502 #define ASC_IOADR_GAP 0x10
1503 #define ASC_SEARCH_IOP_GAP 0x10
1504 #define ASC_MIN_IOP_ADDR (PortAddr)0x0100
1505 #define ASC_MAX_IOP_ADDR (PortAddr)0x3F0
1506 #define ASC_IOADR_1 (PortAddr)0x0110
1507 #define ASC_IOADR_2 (PortAddr)0x0130
1508 #define ASC_IOADR_3 (PortAddr)0x0150
1509 #define ASC_IOADR_4 (PortAddr)0x0190
1510 #define ASC_IOADR_5 (PortAddr)0x0210
1511 #define ASC_IOADR_6 (PortAddr)0x0230
1512 #define ASC_IOADR_7 (PortAddr)0x0250
1513 #define ASC_IOADR_8 (PortAddr)0x0330
1514 #define ASC_IOADR_DEF ASC_IOADR_8
1515 #define ASC_LIB_SCSIQ_WK_SP 256
1516 #define ASC_MAX_SYN_XFER_NO 16
1517 #define ASC_SYN_MAX_OFFSET 0x0F
1518 #define ASC_DEF_SDTR_OFFSET 0x0F
1519 #define ASC_DEF_SDTR_INDEX 0x00
1520 #define ASC_SDTR_ULTRA_PCI_10MB_INDEX 0x02
1521 #define SYN_XFER_NS_0 25
1522 #define SYN_XFER_NS_1 30
1523 #define SYN_XFER_NS_2 35
1524 #define SYN_XFER_NS_3 40
1525 #define SYN_XFER_NS_4 50
1526 #define SYN_XFER_NS_5 60
1527 #define SYN_XFER_NS_6 70
1528 #define SYN_XFER_NS_7 85
1529 #define SYN_ULTRA_XFER_NS_0 12
1530 #define SYN_ULTRA_XFER_NS_1 19
1531 #define SYN_ULTRA_XFER_NS_2 25
1532 #define SYN_ULTRA_XFER_NS_3 32
1533 #define SYN_ULTRA_XFER_NS_4 38
1534 #define SYN_ULTRA_XFER_NS_5 44
1535 #define SYN_ULTRA_XFER_NS_6 50
1536 #define SYN_ULTRA_XFER_NS_7 57
1537 #define SYN_ULTRA_XFER_NS_8 63
1538 #define SYN_ULTRA_XFER_NS_9 69
1539 #define SYN_ULTRA_XFER_NS_10 75
1540 #define SYN_ULTRA_XFER_NS_11 82
1541 #define SYN_ULTRA_XFER_NS_12 88
1542 #define SYN_ULTRA_XFER_NS_13 94
1543 #define SYN_ULTRA_XFER_NS_14 100
1544 #define SYN_ULTRA_XFER_NS_15 107
1546 typedef struct ext_msg {
1547 uchar msg_type;
1548 uchar msg_len;
1549 uchar msg_req;
1550 union {
1551 struct {
1552 uchar sdtr_xfer_period;
1553 uchar sdtr_req_ack_offset;
1554 } sdtr;
1555 struct {
1556 uchar wdtr_width;
1557 } wdtr;
1558 struct {
1559 uchar mdp_b3;
1560 uchar mdp_b2;
1561 uchar mdp_b1;
1562 uchar mdp_b0;
1563 } mdp;
1564 } u_ext_msg;
1565 uchar res;
1566 } EXT_MSG;
1568 #define xfer_period u_ext_msg.sdtr.sdtr_xfer_period
1569 #define req_ack_offset u_ext_msg.sdtr.sdtr_req_ack_offset
1570 #define wdtr_width u_ext_msg.wdtr.wdtr_width
1571 #define mdp_b3 u_ext_msg.mdp_b3
1572 #define mdp_b2 u_ext_msg.mdp_b2
1573 #define mdp_b1 u_ext_msg.mdp_b1
1574 #define mdp_b0 u_ext_msg.mdp_b0
1576 typedef struct asc_dvc_cfg {
1577 ASC_SCSI_BIT_ID_TYPE can_tagged_qng;
1578 ASC_SCSI_BIT_ID_TYPE cmd_qng_enabled;
1579 ASC_SCSI_BIT_ID_TYPE disc_enable;
1580 ASC_SCSI_BIT_ID_TYPE sdtr_enable;
1581 uchar chip_scsi_id:4;
1582 uchar isa_dma_speed:4;
1583 uchar isa_dma_channel;
1584 uchar chip_version;
1585 ushort pci_device_id;
1586 ushort lib_serial_no;
1587 ushort lib_version;
1588 ushort mcode_date;
1589 ushort mcode_version;
1590 uchar max_tag_qng[ASC_MAX_TID + 1];
1591 uchar *overrun_buf;
1592 uchar sdtr_period_offset[ASC_MAX_TID + 1];
1593 ushort pci_slot_info;
1594 uchar adapter_info[6];
1595 } ASC_DVC_CFG;
1597 #define ASC_DEF_DVC_CNTL 0xFFFF
1598 #define ASC_DEF_CHIP_SCSI_ID 7
1599 #define ASC_DEF_ISA_DMA_SPEED 4
1600 #define ASC_INIT_STATE_NULL 0x0000
1601 #define ASC_INIT_STATE_BEG_GET_CFG 0x0001
1602 #define ASC_INIT_STATE_END_GET_CFG 0x0002
1603 #define ASC_INIT_STATE_BEG_SET_CFG 0x0004
1604 #define ASC_INIT_STATE_END_SET_CFG 0x0008
1605 #define ASC_INIT_STATE_BEG_LOAD_MC 0x0010
1606 #define ASC_INIT_STATE_END_LOAD_MC 0x0020
1607 #define ASC_INIT_STATE_BEG_INQUIRY 0x0040
1608 #define ASC_INIT_STATE_END_INQUIRY 0x0080
1609 #define ASC_INIT_RESET_SCSI_DONE 0x0100
1610 #define ASC_INIT_STATE_WITHOUT_EEP 0x8000
1611 #define ASC_PCI_DEVICE_ID_REV_A 0x1100
1612 #define ASC_PCI_DEVICE_ID_REV_B 0x1200
1613 #define ASC_BUG_FIX_IF_NOT_DWB 0x0001
1614 #define ASC_BUG_FIX_ASYN_USE_SYN 0x0002
1615 #define ASYN_SDTR_DATA_FIX_PCI_REV_AB 0x41
1616 #define ASC_MIN_TAGGED_CMD 7
1617 #define ASC_MAX_SCSI_RESET_WAIT 30
1619 struct asc_dvc_var; /* Forward Declaration. */
1621 typedef void (* ASC_ISR_CALLBACK)(struct asc_dvc_var *, ASC_QDONE_INFO *);
1622 typedef int (* ASC_EXE_CALLBACK)(struct asc_dvc_var *, ASC_SCSI_Q *);
1624 typedef struct asc_dvc_var {
1625 PortAddr iop_base;
1626 ushort err_code;
1627 ushort dvc_cntl;
1628 ushort bug_fix_cntl;
1629 ushort bus_type;
1630 ASC_ISR_CALLBACK isr_callback;
1631 ASC_EXE_CALLBACK exe_callback;
1632 ASC_SCSI_BIT_ID_TYPE init_sdtr;
1633 ASC_SCSI_BIT_ID_TYPE sdtr_done;
1634 ASC_SCSI_BIT_ID_TYPE use_tagged_qng;
1635 ASC_SCSI_BIT_ID_TYPE unit_not_ready;
1636 ASC_SCSI_BIT_ID_TYPE queue_full_or_busy;
1637 ASC_SCSI_BIT_ID_TYPE start_motor;
1638 uchar scsi_reset_wait;
1639 uchar chip_no;
1640 char is_in_int;
1641 uchar max_total_qng;
1642 uchar cur_total_qng;
1643 uchar in_critical_cnt;
1644 uchar irq_no;
1645 uchar last_q_shortage;
1646 ushort init_state;
1647 uchar cur_dvc_qng[ASC_MAX_TID + 1];
1648 uchar max_dvc_qng[ASC_MAX_TID + 1];
1649 ASC_SCSI_Q *scsiq_busy_head[ASC_MAX_TID + 1];
1650 ASC_SCSI_Q *scsiq_busy_tail[ASC_MAX_TID + 1];
1651 uchar sdtr_period_tbl[ASC_MAX_SYN_XFER_NO];
1652 ASC_DVC_CFG *cfg;
1653 ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer_always;
1654 char redo_scam;
1655 ushort res2;
1656 uchar dos_int13_table[ASC_MAX_TID + 1];
1657 ASC_DCNT max_dma_count;
1658 ASC_SCSI_BIT_ID_TYPE no_scam;
1659 ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer;
1660 uchar max_sdtr_index;
1661 uchar host_init_sdtr_index;
1662 struct asc_board *drv_ptr;
1663 ASC_DCNT uc_break;
1664 } ASC_DVC_VAR;
1666 typedef struct asc_dvc_inq_info {
1667 uchar type[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
1668 } ASC_DVC_INQ_INFO;
1670 typedef struct asc_cap_info {
1671 ASC_DCNT lba;
1672 ASC_DCNT blk_size;
1673 } ASC_CAP_INFO;
1675 typedef struct asc_cap_info_array {
1676 ASC_CAP_INFO cap_info[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
1677 } ASC_CAP_INFO_ARRAY;
1679 #define ASC_MCNTL_NO_SEL_TIMEOUT (ushort)0x0001
1680 #define ASC_MCNTL_NULL_TARGET (ushort)0x0002
1681 #define ASC_CNTL_INITIATOR (ushort)0x0001
1682 #define ASC_CNTL_BIOS_GT_1GB (ushort)0x0002
1683 #define ASC_CNTL_BIOS_GT_2_DISK (ushort)0x0004
1684 #define ASC_CNTL_BIOS_REMOVABLE (ushort)0x0008
1685 #define ASC_CNTL_NO_SCAM (ushort)0x0010
1686 #define ASC_CNTL_INT_MULTI_Q (ushort)0x0080
1687 #define ASC_CNTL_NO_LUN_SUPPORT (ushort)0x0040
1688 #define ASC_CNTL_NO_VERIFY_COPY (ushort)0x0100
1689 #define ASC_CNTL_RESET_SCSI (ushort)0x0200
1690 #define ASC_CNTL_INIT_INQUIRY (ushort)0x0400
1691 #define ASC_CNTL_INIT_VERBOSE (ushort)0x0800
1692 #define ASC_CNTL_SCSI_PARITY (ushort)0x1000
1693 #define ASC_CNTL_BURST_MODE (ushort)0x2000
1694 #define ASC_CNTL_SDTR_ENABLE_ULTRA (ushort)0x4000
1695 #define ASC_EEP_DVC_CFG_BEG_VL 2
1696 #define ASC_EEP_MAX_DVC_ADDR_VL 15
1697 #define ASC_EEP_DVC_CFG_BEG 32
1698 #define ASC_EEP_MAX_DVC_ADDR 45
1699 #define ASC_EEP_DEFINED_WORDS 10
1700 #define ASC_EEP_MAX_ADDR 63
1701 #define ASC_EEP_RES_WORDS 0
1702 #define ASC_EEP_MAX_RETRY 20
1703 #define ASC_MAX_INIT_BUSY_RETRY 8
1704 #define ASC_EEP_ISA_PNP_WSIZE 16
1706 typedef struct asceep_config {
1707 ushort cfg_lsw;
1708 ushort cfg_msw;
1709 uchar init_sdtr;
1710 uchar disc_enable;
1711 uchar use_cmd_qng;
1712 uchar start_motor;
1713 uchar max_total_qng;
1714 uchar max_tag_qng;
1715 uchar bios_scan;
1716 uchar power_up_wait;
1717 uchar no_scam;
1718 uchar chip_scsi_id:4;
1719 uchar isa_dma_speed:4;
1720 uchar dos_int13_table[ASC_MAX_TID + 1];
1721 uchar adapter_info[6];
1722 ushort cntl;
1723 ushort chksum;
1724 } ASCEEP_CONFIG;
1726 #define ASC_PCI_CFG_LSW_SCSI_PARITY 0x0800
1727 #define ASC_PCI_CFG_LSW_BURST_MODE 0x0080
1728 #define ASC_PCI_CFG_LSW_INTR_ABLE 0x0020
1730 #define ASC_EEP_CMD_READ 0x80
1731 #define ASC_EEP_CMD_WRITE 0x40
1732 #define ASC_EEP_CMD_WRITE_ABLE 0x30
1733 #define ASC_EEP_CMD_WRITE_DISABLE 0x00
1734 #define ASC_OVERRUN_BSIZE 0x00000048UL
1735 #define ASC_CTRL_BREAK_ONCE 0x0001
1736 #define ASC_CTRL_BREAK_STAY_IDLE 0x0002
1737 #define ASCV_MSGOUT_BEG 0x0000
1738 #define ASCV_MSGOUT_SDTR_PERIOD (ASCV_MSGOUT_BEG+3)
1739 #define ASCV_MSGOUT_SDTR_OFFSET (ASCV_MSGOUT_BEG+4)
1740 #define ASCV_BREAK_SAVED_CODE (ushort)0x0006
1741 #define ASCV_MSGIN_BEG (ASCV_MSGOUT_BEG+8)
1742 #define ASCV_MSGIN_SDTR_PERIOD (ASCV_MSGIN_BEG+3)
1743 #define ASCV_MSGIN_SDTR_OFFSET (ASCV_MSGIN_BEG+4)
1744 #define ASCV_SDTR_DATA_BEG (ASCV_MSGIN_BEG+8)
1745 #define ASCV_SDTR_DONE_BEG (ASCV_SDTR_DATA_BEG+8)
1746 #define ASCV_MAX_DVC_QNG_BEG (ushort)0x0020
1747 #define ASCV_BREAK_ADDR (ushort)0x0028
1748 #define ASCV_BREAK_NOTIFY_COUNT (ushort)0x002A
1749 #define ASCV_BREAK_CONTROL (ushort)0x002C
1750 #define ASCV_BREAK_HIT_COUNT (ushort)0x002E
1752 #define ASCV_ASCDVC_ERR_CODE_W (ushort)0x0030
1753 #define ASCV_MCODE_CHKSUM_W (ushort)0x0032
1754 #define ASCV_MCODE_SIZE_W (ushort)0x0034
1755 #define ASCV_STOP_CODE_B (ushort)0x0036
1756 #define ASCV_DVC_ERR_CODE_B (ushort)0x0037
1757 #define ASCV_OVERRUN_PADDR_D (ushort)0x0038
1758 #define ASCV_OVERRUN_BSIZE_D (ushort)0x003C
1759 #define ASCV_HALTCODE_W (ushort)0x0040
1760 #define ASCV_CHKSUM_W (ushort)0x0042
1761 #define ASCV_MC_DATE_W (ushort)0x0044
1762 #define ASCV_MC_VER_W (ushort)0x0046
1763 #define ASCV_NEXTRDY_B (ushort)0x0048
1764 #define ASCV_DONENEXT_B (ushort)0x0049
1765 #define ASCV_USE_TAGGED_QNG_B (ushort)0x004A
1766 #define ASCV_SCSIBUSY_B (ushort)0x004B
1767 #define ASCV_Q_DONE_IN_PROGRESS_B (ushort)0x004C
1768 #define ASCV_CURCDB_B (ushort)0x004D
1769 #define ASCV_RCLUN_B (ushort)0x004E
1770 #define ASCV_BUSY_QHEAD_B (ushort)0x004F
1771 #define ASCV_DISC1_QHEAD_B (ushort)0x0050
1772 #define ASCV_DISC_ENABLE_B (ushort)0x0052
1773 #define ASCV_CAN_TAGGED_QNG_B (ushort)0x0053
1774 #define ASCV_HOSTSCSI_ID_B (ushort)0x0055
1775 #define ASCV_MCODE_CNTL_B (ushort)0x0056
1776 #define ASCV_NULL_TARGET_B (ushort)0x0057
1777 #define ASCV_FREE_Q_HEAD_W (ushort)0x0058
1778 #define ASCV_DONE_Q_TAIL_W (ushort)0x005A
1779 #define ASCV_FREE_Q_HEAD_B (ushort)(ASCV_FREE_Q_HEAD_W+1)
1780 #define ASCV_DONE_Q_TAIL_B (ushort)(ASCV_DONE_Q_TAIL_W+1)
1781 #define ASCV_HOST_FLAG_B (ushort)0x005D
1782 #define ASCV_TOTAL_READY_Q_B (ushort)0x0064
1783 #define ASCV_VER_SERIAL_B (ushort)0x0065
1784 #define ASCV_HALTCODE_SAVED_W (ushort)0x0066
1785 #define ASCV_WTM_FLAG_B (ushort)0x0068
1786 #define ASCV_RISC_FLAG_B (ushort)0x006A
1787 #define ASCV_REQ_SG_LIST_QP (ushort)0x006B
1788 #define ASC_HOST_FLAG_IN_ISR 0x01
1789 #define ASC_HOST_FLAG_ACK_INT 0x02
1790 #define ASC_RISC_FLAG_GEN_INT 0x01
1791 #define ASC_RISC_FLAG_REQ_SG_LIST 0x02
1792 #define IOP_CTRL (0x0F)
1793 #define IOP_STATUS (0x0E)
1794 #define IOP_INT_ACK IOP_STATUS
1795 #define IOP_REG_IFC (0x0D)
1796 #define IOP_SYN_OFFSET (0x0B)
1797 #define IOP_EXTRA_CONTROL (0x0D)
1798 #define IOP_REG_PC (0x0C)
1799 #define IOP_RAM_ADDR (0x0A)
1800 #define IOP_RAM_DATA (0x08)
1801 #define IOP_EEP_DATA (0x06)
1802 #define IOP_EEP_CMD (0x07)
1803 #define IOP_VERSION (0x03)
1804 #define IOP_CONFIG_HIGH (0x04)
1805 #define IOP_CONFIG_LOW (0x02)
1806 #define IOP_SIG_BYTE (0x01)
1807 #define IOP_SIG_WORD (0x00)
1808 #define IOP_REG_DC1 (0x0E)
1809 #define IOP_REG_DC0 (0x0C)
1810 #define IOP_REG_SB (0x0B)
1811 #define IOP_REG_DA1 (0x0A)
1812 #define IOP_REG_DA0 (0x08)
1813 #define IOP_REG_SC (0x09)
1814 #define IOP_DMA_SPEED (0x07)
1815 #define IOP_REG_FLAG (0x07)
1816 #define IOP_FIFO_H (0x06)
1817 #define IOP_FIFO_L (0x04)
1818 #define IOP_REG_ID (0x05)
1819 #define IOP_REG_QP (0x03)
1820 #define IOP_REG_IH (0x02)
1821 #define IOP_REG_IX (0x01)
1822 #define IOP_REG_AX (0x00)
1823 #define IFC_REG_LOCK (0x00)
1824 #define IFC_REG_UNLOCK (0x09)
1825 #define IFC_WR_EN_FILTER (0x10)
1826 #define IFC_RD_NO_EEPROM (0x10)
1827 #define IFC_SLEW_RATE (0x20)
1828 #define IFC_ACT_NEG (0x40)
1829 #define IFC_INP_FILTER (0x80)
1830 #define IFC_INIT_DEFAULT (IFC_ACT_NEG | IFC_REG_UNLOCK)
1831 #define SC_SEL (uchar)(0x80)
1832 #define SC_BSY (uchar)(0x40)
1833 #define SC_ACK (uchar)(0x20)
1834 #define SC_REQ (uchar)(0x10)
1835 #define SC_ATN (uchar)(0x08)
1836 #define SC_IO (uchar)(0x04)
1837 #define SC_CD (uchar)(0x02)
1838 #define SC_MSG (uchar)(0x01)
1839 #define SEC_SCSI_CTL (uchar)(0x80)
1840 #define SEC_ACTIVE_NEGATE (uchar)(0x40)
1841 #define SEC_SLEW_RATE (uchar)(0x20)
1842 #define SEC_ENABLE_FILTER (uchar)(0x10)
1843 #define ASC_HALT_EXTMSG_IN (ushort)0x8000
1844 #define ASC_HALT_CHK_CONDITION (ushort)0x8100
1845 #define ASC_HALT_SS_QUEUE_FULL (ushort)0x8200
1846 #define ASC_HALT_DISABLE_ASYN_USE_SYN_FIX (ushort)0x8300
1847 #define ASC_HALT_ENABLE_ASYN_USE_SYN_FIX (ushort)0x8400
1848 #define ASC_HALT_SDTR_REJECTED (ushort)0x4000
1849 #define ASC_HALT_HOST_COPY_SG_LIST_TO_RISC ( ushort )0x2000
1850 #define ASC_MAX_QNO 0xF8
1851 #define ASC_DATA_SEC_BEG (ushort)0x0080
1852 #define ASC_DATA_SEC_END (ushort)0x0080
1853 #define ASC_CODE_SEC_BEG (ushort)0x0080
1854 #define ASC_CODE_SEC_END (ushort)0x0080
1855 #define ASC_QADR_BEG (0x4000)
1856 #define ASC_QADR_USED (ushort)(ASC_MAX_QNO * 64)
1857 #define ASC_QADR_END (ushort)0x7FFF
1858 #define ASC_QLAST_ADR (ushort)0x7FC0
1859 #define ASC_QBLK_SIZE 0x40
1860 #define ASC_BIOS_DATA_QBEG 0xF8
1861 #define ASC_MIN_ACTIVE_QNO 0x01
1862 #define ASC_QLINK_END 0xFF
1863 #define ASC_EEPROM_WORDS 0x10
1864 #define ASC_MAX_MGS_LEN 0x10
1865 #define ASC_BIOS_ADDR_DEF 0xDC00
1866 #define ASC_BIOS_SIZE 0x3800
1867 #define ASC_BIOS_RAM_OFF 0x3800
1868 #define ASC_BIOS_RAM_SIZE 0x800
1869 #define ASC_BIOS_MIN_ADDR 0xC000
1870 #define ASC_BIOS_MAX_ADDR 0xEC00
1871 #define ASC_BIOS_BANK_SIZE 0x0400
1872 #define ASC_MCODE_START_ADDR 0x0080
1873 #define ASC_CFG0_HOST_INT_ON 0x0020
1874 #define ASC_CFG0_BIOS_ON 0x0040
1875 #define ASC_CFG0_VERA_BURST_ON 0x0080
1876 #define ASC_CFG0_SCSI_PARITY_ON 0x0800
1877 #define ASC_CFG1_SCSI_TARGET_ON 0x0080
1878 #define ASC_CFG1_LRAM_8BITS_ON 0x0800
1879 #define ASC_CFG_MSW_CLR_MASK 0x3080
1880 #define CSW_TEST1 (ASC_CS_TYPE)0x8000
1881 #define CSW_AUTO_CONFIG (ASC_CS_TYPE)0x4000
1882 #define CSW_RESERVED1 (ASC_CS_TYPE)0x2000
1883 #define CSW_IRQ_WRITTEN (ASC_CS_TYPE)0x1000
1884 #define CSW_33MHZ_SELECTED (ASC_CS_TYPE)0x0800
1885 #define CSW_TEST2 (ASC_CS_TYPE)0x0400
1886 #define CSW_TEST3 (ASC_CS_TYPE)0x0200
1887 #define CSW_RESERVED2 (ASC_CS_TYPE)0x0100
1888 #define CSW_DMA_DONE (ASC_CS_TYPE)0x0080
1889 #define CSW_FIFO_RDY (ASC_CS_TYPE)0x0040
1890 #define CSW_EEP_READ_DONE (ASC_CS_TYPE)0x0020
1891 #define CSW_HALTED (ASC_CS_TYPE)0x0010
1892 #define CSW_SCSI_RESET_ACTIVE (ASC_CS_TYPE)0x0008
1893 #define CSW_PARITY_ERR (ASC_CS_TYPE)0x0004
1894 #define CSW_SCSI_RESET_LATCH (ASC_CS_TYPE)0x0002
1895 #define CSW_INT_PENDING (ASC_CS_TYPE)0x0001
1896 #define CIW_CLR_SCSI_RESET_INT (ASC_CS_TYPE)0x1000
1897 #define CIW_INT_ACK (ASC_CS_TYPE)0x0100
1898 #define CIW_TEST1 (ASC_CS_TYPE)0x0200
1899 #define CIW_TEST2 (ASC_CS_TYPE)0x0400
1900 #define CIW_SEL_33MHZ (ASC_CS_TYPE)0x0800
1901 #define CIW_IRQ_ACT (ASC_CS_TYPE)0x1000
1902 #define CC_CHIP_RESET (uchar)0x80
1903 #define CC_SCSI_RESET (uchar)0x40
1904 #define CC_HALT (uchar)0x20
1905 #define CC_SINGLE_STEP (uchar)0x10
1906 #define CC_DMA_ABLE (uchar)0x08
1907 #define CC_TEST (uchar)0x04
1908 #define CC_BANK_ONE (uchar)0x02
1909 #define CC_DIAG (uchar)0x01
1910 #define ASC_1000_ID0W 0x04C1
1911 #define ASC_1000_ID0W_FIX 0x00C1
1912 #define ASC_1000_ID1B 0x25
1913 #define ASC_EISA_BIG_IOP_GAP (0x1C30-0x0C50)
1914 #define ASC_EISA_SMALL_IOP_GAP (0x0020)
1915 #define ASC_EISA_MIN_IOP_ADDR (0x0C30)
1916 #define ASC_EISA_MAX_IOP_ADDR (0xFC50)
1917 #define ASC_EISA_REV_IOP_MASK (0x0C83)
1918 #define ASC_EISA_PID_IOP_MASK (0x0C80)
1919 #define ASC_EISA_CFG_IOP_MASK (0x0C86)
1920 #define ASC_GET_EISA_SLOT(iop) (PortAddr)((iop) & 0xF000)
1921 #define ASC_EISA_ID_740 0x01745004UL
1922 #define ASC_EISA_ID_750 0x01755004UL
1923 #define INS_HALTINT (ushort)0x6281
1924 #define INS_HALT (ushort)0x6280
1925 #define INS_SINT (ushort)0x6200
1926 #define INS_RFLAG_WTM (ushort)0x7380
1927 #define ASC_MC_SAVE_CODE_WSIZE 0x500
1928 #define ASC_MC_SAVE_DATA_WSIZE 0x40
1930 typedef struct asc_mc_saved {
1931 ushort data[ASC_MC_SAVE_DATA_WSIZE];
1932 ushort code[ASC_MC_SAVE_CODE_WSIZE];
1933 } ASC_MC_SAVED;
1935 #define AscGetQDoneInProgress(port) AscReadLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B)
1936 #define AscPutQDoneInProgress(port, val) AscWriteLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B, val)
1937 #define AscGetVarFreeQHead(port) AscReadLramWord((port), ASCV_FREE_Q_HEAD_W)
1938 #define AscGetVarDoneQTail(port) AscReadLramWord((port), ASCV_DONE_Q_TAIL_W)
1939 #define AscPutVarFreeQHead(port, val) AscWriteLramWord((port), ASCV_FREE_Q_HEAD_W, val)
1940 #define AscPutVarDoneQTail(port, val) AscWriteLramWord((port), ASCV_DONE_Q_TAIL_W, val)
1941 #define AscGetRiscVarFreeQHead(port) AscReadLramByte((port), ASCV_NEXTRDY_B)
1942 #define AscGetRiscVarDoneQTail(port) AscReadLramByte((port), ASCV_DONENEXT_B)
1943 #define AscPutRiscVarFreeQHead(port, val) AscWriteLramByte((port), ASCV_NEXTRDY_B, val)
1944 #define AscPutRiscVarDoneQTail(port, val) AscWriteLramByte((port), ASCV_DONENEXT_B, val)
1945 #define AscPutMCodeSDTRDoneAtID(port, id, data) AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id), (data));
1946 #define AscGetMCodeSDTRDoneAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id));
1947 #define AscPutMCodeInitSDTRAtID(port, id, data) AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id), data);
1948 #define AscGetMCodeInitSDTRAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id));
1949 #define AscSynIndexToPeriod(index) (uchar)(asc_dvc->sdtr_period_tbl[ (index) ])
1950 #define AscGetChipSignatureByte(port) (uchar)inp((port)+IOP_SIG_BYTE)
1951 #define AscGetChipSignatureWord(port) (ushort)inpw((port)+IOP_SIG_WORD)
1952 #define AscGetChipVerNo(port) (uchar)inp((port)+IOP_VERSION)
1953 #define AscGetChipCfgLsw(port) (ushort)inpw((port)+IOP_CONFIG_LOW)
1954 #define AscGetChipCfgMsw(port) (ushort)inpw((port)+IOP_CONFIG_HIGH)
1955 #define AscSetChipCfgLsw(port, data) outpw((port)+IOP_CONFIG_LOW, data)
1956 #define AscSetChipCfgMsw(port, data) outpw((port)+IOP_CONFIG_HIGH, data)
1957 #define AscGetChipEEPCmd(port) (uchar)inp((port)+IOP_EEP_CMD)
1958 #define AscSetChipEEPCmd(port, data) outp((port)+IOP_EEP_CMD, data)
1959 #define AscGetChipEEPData(port) (ushort)inpw((port)+IOP_EEP_DATA)
1960 #define AscSetChipEEPData(port, data) outpw((port)+IOP_EEP_DATA, data)
1961 #define AscGetChipLramAddr(port) (ushort)inpw((PortAddr)((port)+IOP_RAM_ADDR))
1962 #define AscSetChipLramAddr(port, addr) outpw((PortAddr)((port)+IOP_RAM_ADDR), addr)
1963 #define AscGetChipLramData(port) (ushort)inpw((port)+IOP_RAM_DATA)
1964 #define AscSetChipLramData(port, data) outpw((port)+IOP_RAM_DATA, data)
1965 #define AscGetChipLramDataNoSwap(port) (ushort)inpw_noswap((port)+IOP_RAM_DATA)
1966 #define AscSetChipLramDataNoSwap(port, data) outpw_noswap((port)+IOP_RAM_DATA, data)
1967 #define AscGetChipIFC(port) (uchar)inp((port)+IOP_REG_IFC)
1968 #define AscSetChipIFC(port, data) outp((port)+IOP_REG_IFC, data)
1969 #define AscGetChipStatus(port) (ASC_CS_TYPE)inpw((port)+IOP_STATUS)
1970 #define AscSetChipStatus(port, cs_val) outpw((port)+IOP_STATUS, cs_val)
1971 #define AscGetChipControl(port) (uchar)inp((port)+IOP_CTRL)
1972 #define AscSetChipControl(port, cc_val) outp((port)+IOP_CTRL, cc_val)
1973 #define AscGetChipSyn(port) (uchar)inp((port)+IOP_SYN_OFFSET)
1974 #define AscSetChipSyn(port, data) outp((port)+IOP_SYN_OFFSET, data)
1975 #define AscSetPCAddr(port, data) outpw((port)+IOP_REG_PC, data)
1976 #define AscGetPCAddr(port) (ushort)inpw((port)+IOP_REG_PC)
1977 #define AscIsIntPending(port) (AscGetChipStatus(port) & (CSW_INT_PENDING | CSW_SCSI_RESET_LATCH))
1978 #define AscGetChipScsiID(port) ((AscGetChipCfgLsw(port) >> 8) & ASC_MAX_TID)
1979 #define AscGetExtraControl(port) (uchar)inp((port)+IOP_EXTRA_CONTROL)
1980 #define AscSetExtraControl(port, data) outp((port)+IOP_EXTRA_CONTROL, data)
1981 #define AscReadChipAX(port) (ushort)inpw((port)+IOP_REG_AX)
1982 #define AscWriteChipAX(port, data) outpw((port)+IOP_REG_AX, data)
1983 #define AscReadChipIX(port) (uchar)inp((port)+IOP_REG_IX)
1984 #define AscWriteChipIX(port, data) outp((port)+IOP_REG_IX, data)
1985 #define AscReadChipIH(port) (ushort)inpw((port)+IOP_REG_IH)
1986 #define AscWriteChipIH(port, data) outpw((port)+IOP_REG_IH, data)
1987 #define AscReadChipQP(port) (uchar)inp((port)+IOP_REG_QP)
1988 #define AscWriteChipQP(port, data) outp((port)+IOP_REG_QP, data)
1989 #define AscReadChipFIFO_L(port) (ushort)inpw((port)+IOP_REG_FIFO_L)
1990 #define AscWriteChipFIFO_L(port, data) outpw((port)+IOP_REG_FIFO_L, data)
1991 #define AscReadChipFIFO_H(port) (ushort)inpw((port)+IOP_REG_FIFO_H)
1992 #define AscWriteChipFIFO_H(port, data) outpw((port)+IOP_REG_FIFO_H, data)
1993 #define AscReadChipDmaSpeed(port) (uchar)inp((port)+IOP_DMA_SPEED)
1994 #define AscWriteChipDmaSpeed(port, data) outp((port)+IOP_DMA_SPEED, data)
1995 #define AscReadChipDA0(port) (ushort)inpw((port)+IOP_REG_DA0)
1996 #define AscWriteChipDA0(port) outpw((port)+IOP_REG_DA0, data)
1997 #define AscReadChipDA1(port) (ushort)inpw((port)+IOP_REG_DA1)
1998 #define AscWriteChipDA1(port) outpw((port)+IOP_REG_DA1, data)
1999 #define AscReadChipDC0(port) (ushort)inpw((port)+IOP_REG_DC0)
2000 #define AscWriteChipDC0(port) outpw((port)+IOP_REG_DC0, data)
2001 #define AscReadChipDC1(port) (ushort)inpw((port)+IOP_REG_DC1)
2002 #define AscWriteChipDC1(port) outpw((port)+IOP_REG_DC1, data)
2003 #define AscReadChipDvcID(port) (uchar)inp((port)+IOP_REG_ID)
2004 #define AscWriteChipDvcID(port, data) outp((port)+IOP_REG_ID, data)
2006 STATIC int AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg);
2007 STATIC int AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg);
2008 STATIC void AscWaitEEPRead(void);
2009 STATIC void AscWaitEEPWrite(void);
2010 STATIC ushort AscReadEEPWord(PortAddr, uchar);
2011 STATIC ushort AscWriteEEPWord(PortAddr, uchar, ushort);
2012 STATIC ushort AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
2013 STATIC int AscSetEEPConfigOnce(PortAddr, ASCEEP_CONFIG *, ushort);
2014 STATIC int AscSetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
2015 STATIC int AscStartChip(PortAddr);
2016 STATIC int AscStopChip(PortAddr);
2017 STATIC void AscSetChipIH(PortAddr, ushort);
2018 STATIC int AscIsChipHalted(PortAddr);
2019 STATIC void AscAckInterrupt(PortAddr);
2020 STATIC void AscDisableInterrupt(PortAddr);
2021 STATIC void AscEnableInterrupt(PortAddr);
2022 STATIC void AscSetBank(PortAddr, uchar);
2023 STATIC int AscResetChipAndScsiBus(ASC_DVC_VAR *);
2024 STATIC ushort AscGetIsaDmaChannel(PortAddr);
2025 STATIC ushort AscSetIsaDmaChannel(PortAddr, ushort);
2026 STATIC uchar AscSetIsaDmaSpeed(PortAddr, uchar);
2027 STATIC uchar AscGetIsaDmaSpeed(PortAddr);
2028 STATIC uchar AscReadLramByte(PortAddr, ushort);
2029 STATIC ushort AscReadLramWord(PortAddr, ushort);
2030 STATIC ASC_DCNT AscReadLramDWord(PortAddr, ushort);
2031 STATIC void AscWriteLramWord(PortAddr, ushort, ushort);
2032 STATIC void AscWriteLramDWord(PortAddr, ushort, ASC_DCNT);
2033 STATIC void AscWriteLramByte(PortAddr, ushort, uchar);
2034 STATIC ASC_DCNT AscMemSumLramWord(PortAddr, ushort, int);
2035 STATIC void AscMemWordSetLram(PortAddr, ushort, ushort, int);
2036 STATIC void AscMemWordCopyToLram(PortAddr, ushort, ushort *, int);
2037 STATIC void AscMemDWordCopyToLram(PortAddr, ushort, ASC_DCNT *, int);
2038 STATIC void AscMemWordCopyFromLram(PortAddr, ushort, ushort *, int);
2039 STATIC ushort AscInitAscDvcVar(ASC_DVC_VAR *);
2040 STATIC ushort AscInitFromEEP(ASC_DVC_VAR *);
2041 STATIC ushort AscInitFromAscDvcVar(ASC_DVC_VAR *);
2042 STATIC ushort AscInitMicroCodeVar(ASC_DVC_VAR *);
2043 STATIC int AscTestExternalLram(ASC_DVC_VAR *);
2044 STATIC uchar AscMsgOutSDTR(ASC_DVC_VAR *, uchar, uchar);
2045 STATIC uchar AscCalSDTRData(ASC_DVC_VAR *, uchar, uchar);
2046 STATIC void AscSetChipSDTR(PortAddr, uchar, uchar);
2047 STATIC uchar AscGetSynPeriodIndex(ASC_DVC_VAR *, uchar);
2048 STATIC uchar AscAllocFreeQueue(PortAddr, uchar);
2049 STATIC uchar AscAllocMultipleFreeQueue(PortAddr, uchar, uchar);
2050 STATIC int AscRiscHaltedAbortSRB(ASC_DVC_VAR *, ASC_DCNT);
2051 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
2052 STATIC int AscRiscHaltedAbortTIX(ASC_DVC_VAR *, uchar);
2053 #endif /* version >= v1.3.89 */
2054 STATIC int AscHostReqRiscHalt(PortAddr);
2055 STATIC int AscStopQueueExe(PortAddr);
2056 STATIC int AscStartQueueExe(PortAddr);
2057 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
2058 STATIC int AscCleanUpDiscQueue(PortAddr);
2059 #endif /* version >= v1.3.89 */
2060 STATIC int AscCleanUpBusyQueue(PortAddr);
2061 STATIC int AscWaitTixISRDone(ASC_DVC_VAR *, uchar);
2062 STATIC int AscWaitISRDone(ASC_DVC_VAR *);
2063 STATIC ASC_PADDR AscGetOnePhyAddr(ASC_DVC_VAR *, uchar *,
2064 ASC_DCNT);
2065 STATIC int AscSendScsiQueue(ASC_DVC_VAR *,
2066 ASC_SCSI_Q * scsiq,
2067 uchar n_q_required);
2068 STATIC int AscPutReadyQueue(ASC_DVC_VAR *,
2069 ASC_SCSI_Q *, uchar);
2070 STATIC int AscPutReadySgListQueue(ASC_DVC_VAR *,
2071 ASC_SCSI_Q *, uchar);
2072 STATIC int AscSetChipSynRegAtID(PortAddr, uchar, uchar);
2073 STATIC int AscSetRunChipSynRegAtID(PortAddr, uchar, uchar);
2074 STATIC ushort AscInitLram(ASC_DVC_VAR *);
2075 STATIC int AscReInitLram(ASC_DVC_VAR *);
2076 STATIC ushort AscInitQLinkVar(ASC_DVC_VAR *);
2077 STATIC int AscSetLibErrorCode(ASC_DVC_VAR *, ushort);
2078 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
2079 STATIC int _AscWaitQDone(PortAddr, ASC_SCSI_Q *);
2080 #endif /* version >= v1.3.89 */
2081 STATIC int AscIsrChipHalted(ASC_DVC_VAR *);
2082 STATIC uchar _AscCopyLramScsiDoneQ(PortAddr, ushort,
2083 ASC_QDONE_INFO *, ASC_DCNT);
2084 STATIC int AscIsrQDone(ASC_DVC_VAR *);
2085 STATIC int AscCompareString(uchar *, uchar *, int);
2086 STATIC ushort AscGetEisaChipCfg(PortAddr);
2087 STATIC ASC_DCNT AscGetEisaProductID(PortAddr);
2088 STATIC PortAddr AscSearchIOPortAddrEISA(PortAddr);
2089 STATIC uchar AscGetChipScsiCtrl(PortAddr);
2090 STATIC uchar AscSetChipScsiID(PortAddr, uchar);
2091 STATIC uchar AscGetChipVersion(PortAddr, ushort);
2092 STATIC ushort AscGetChipBusType(PortAddr);
2093 STATIC ASC_DCNT AscLoadMicroCode(PortAddr, ushort, ushort *, ushort);
2094 STATIC int AscFindSignature(PortAddr);
2095 STATIC PortAddr AscSearchIOPortAddr11(PortAddr);
2096 STATIC void AscToggleIRQAct(PortAddr);
2097 STATIC void AscSetISAPNPWaitForKey(void);
2098 STATIC uchar AscGetChipIRQ(PortAddr, ushort);
2099 STATIC uchar AscSetChipIRQ(PortAddr, uchar, ushort);
2100 STATIC ushort AscGetChipBiosAddress(PortAddr, ushort);
2101 STATIC int DvcEnterCritical(void);
2102 STATIC void DvcLeaveCritical(int);
2103 STATIC void DvcInPortWords(PortAddr, ushort *, int);
2104 STATIC void DvcOutPortWords(PortAddr, ushort *, int);
2105 STATIC void DvcOutPortDWords(PortAddr, ASC_DCNT *, int);
2106 STATIC uchar DvcReadPCIConfigByte(ASC_DVC_VAR *, ushort);
2107 STATIC void DvcWritePCIConfigByte(ASC_DVC_VAR *,
2108 ushort, uchar);
2109 STATIC ushort AscGetChipBiosAddress(PortAddr, ushort);
2110 STATIC void DvcSleepMilliSecond(ASC_DCNT);
2111 STATIC void DvcDelayNanoSecond(ASC_DVC_VAR *, ASC_DCNT);
2112 STATIC ASC_DCNT DvcGetSGList(ASC_DVC_VAR *, uchar *,
2113 ASC_DCNT, ASC_SG_HEAD *);
2114 STATIC void DvcPutScsiQ(PortAddr, ushort, ushort *, int);
2115 STATIC void DvcGetQinfo(PortAddr, ushort, ushort *, int);
2116 STATIC PortAddr AscSearchIOPortAddr(PortAddr, ushort);
2117 STATIC ushort AscInitGetConfig(ASC_DVC_VAR *);
2118 STATIC ushort AscInitSetConfig(ASC_DVC_VAR *);
2119 STATIC ushort AscInitAsc1000Driver(ASC_DVC_VAR *);
2120 STATIC void AscAsyncFix(ASC_DVC_VAR *, uchar,
2121 ASC_SCSI_INQUIRY *);
2122 STATIC int AscTagQueuingSafe(ASC_SCSI_INQUIRY *);
2123 STATIC void AscInquiryHandling(ASC_DVC_VAR *,
2124 uchar, ASC_SCSI_INQUIRY *);
2125 STATIC int AscExeScsiQueue(ASC_DVC_VAR *, ASC_SCSI_Q *);
2126 STATIC int AscISR(ASC_DVC_VAR *);
2127 STATIC uint AscGetNumOfFreeQueue(ASC_DVC_VAR *, uchar,
2128 uchar);
2129 STATIC int AscSgListToQueue(int);
2130 STATIC int AscAbortSRB(ASC_DVC_VAR *, ASC_VADDR);
2131 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
2132 STATIC int AscResetDevice(ASC_DVC_VAR *, uchar);
2133 #endif /* version >= v1.3.89 */
2134 STATIC int AscResetSB(ASC_DVC_VAR *);
2135 STATIC void AscEnableIsaDma(uchar);
2136 STATIC ASC_DCNT AscGetMaxDmaCount(ushort);
2140 * --- Adv Library Constants and Macros
2143 #define ADV_LIB_VERSION_MAJOR 5
2144 #define ADV_LIB_VERSION_MINOR 5
2146 /* d_os_dep.h */
2147 #define ADV_OS_LINUX
2150 * Define Adv Library required special types.
2154 * Portable Data Types
2156 * Any instance where a 32-bit long or pointer type is assumed
2157 * for precision or HW defined structures, the following define
2158 * types must be used. In Linux the char, short, and int types
2159 * are all consistent at 8, 16, and 32 bits respectively. Pointers
2160 * and long types are 64 bits on Alpha and UltraSPARC.
2162 #define ADV_PADDR __u32 /* Physical address data type. */
2163 #define ADV_VADDR __u32 /* Virtual address data type. */
2164 #define ADV_DCNT __u32 /* Unsigned Data count type. */
2165 #define ADV_SDCNT __s32 /* Signed Data count type. */
2168 * These macros are used to convert a virtual address to a
2169 * 32-bit value. This currently can be used on Linux Alpha
2170 * which uses 64-bit virtual address but a 32-bit bus address.
2171 * This is likely to break in the future, but doing this now
2172 * will give us time to change the HW and FW to handle 64-bit
2173 * addresses.
2175 #define ADV_VADDR_TO_U32 virt_to_bus
2176 #define ADV_U32_TO_VADDR bus_to_virt
2178 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0)
2179 #define AdvPortAddr unsigned short /* I/O Port address size */
2180 #else /* version >= v1,3,0 */
2181 #define AdvPortAddr ulong /* Virtual memory address size */
2182 #endif /* version >= v1,3,0 */
2185 * Define Adv Library required memory access macros.
2187 #define ADV_MEM_READB(addr) readb(addr)
2188 #define ADV_MEM_READW(addr) readw(addr)
2189 #define ADV_MEM_WRITEB(addr, byte) writeb(byte, addr)
2190 #define ADV_MEM_WRITEW(addr, word) writew(word, addr)
2193 * The I/O memory mapping function names changed in 2.1.X.
2195 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,0)
2196 #define ioremap vremap
2197 #define iounmap vfree
2198 #endif /* version < v2.1.0 */
2200 #define ADV_CARRIER_COUNT (ASC_DEF_MAX_HOST_QNG + 15)
2203 * Define total number of simultaneous maximum element scatter-gather
2204 * request blocks per wide adapter. ASC_DEF_MAX_HOST_QNG (253) is the
2205 * maximum number of outstanding commands per wide host adapter. Each
2206 * command uses one or more ADV_SG_BLOCK each with 15 scatter-gather
2207 * elements. Allow each command to have at least one ADV_SG_BLOCK structure.
2208 * This allows about 15 commands to have the maximum 17 ADV_SG_BLOCK
2209 * structures or 255 scatter-gather elements.
2212 #define ADV_TOT_SG_BLOCK ASC_DEF_MAX_HOST_QNG
2215 * Define Adv Library required maximum number of scatter-gather
2216 * elements per request.
2218 #define ADV_MAX_SG_LIST 255
2220 /* Number of SG blocks needed. */
2221 #define ADV_NUM_SG_BLOCK \
2222 ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK)
2224 /* Total contiguous memory needed for SG blocks. */
2225 #define ADV_SG_TOTAL_MEM_SIZE \
2226 (sizeof(ADV_SG_BLOCK) * ADV_NUM_SG_BLOCK)
2228 #define ASC_PAGE_SIZE PAGE_SIZE
2230 #define ADV_NUM_PAGE_CROSSING \
2231 ((ADV_SG_TOTAL_MEM_SIZE + (ASC_PAGE_SIZE - 1))/ASC_PAGE_SIZE)
2233 /* a_condor.h */
2234 #define ADV_PCI_VENDOR_ID 0x10CD
2235 #define ADV_PCI_DEVICE_ID_REV_A 0x2300
2236 #define ADV_PCI_DEVID_38C0800_REV1 0x2500
2237 #define ADV_PCI_DEVID_38C1600_REV1 0x2700
2239 #define ASC_EEP_DVC_CFG_BEGIN (0x00)
2240 #define ASC_EEP_DVC_CFG_END (0x15)
2241 #define ASC_EEP_DVC_CTL_BEGIN (0x16) /* location of OEM name */
2242 #define ASC_EEP_MAX_WORD_ADDR (0x1E)
2244 #define ASC_EEP_DELAY_MS 100
2246 #define ADV_EEPROM_BIG_ENDIAN 0x8000 /* EEPROM Bit 15 */
2247 #define ADV_EEPROM_BIOS_ENABLE 0x4000 /* EEPROM Bit 14 */
2249 * For the ASC3550 Bit 13 is Termination Polarity control bit.
2250 * For later ICs Bit 13 controls whether the CIS (Card Information
2251 * Service Section) is loaded from EEPROM.
2253 #define ADV_EEPROM_TERM_POL 0x2000 /* EEPROM Bit 13 */
2254 #define ADV_EEPROM_CIS_LD 0x2000 /* EEPROM Bit 13 */
2256 typedef struct adveep_3550_config
2258 /* Word Offset, Description */
2260 ushort cfg_lsw; /* 00 power up initialization */
2261 /* bit 13 set - Term Polarity Control */
2262 /* bit 14 set - BIOS Enable */
2263 /* bit 15 set - Big Endian Mode */
2264 ushort cfg_msw; /* 01 unused */
2265 ushort disc_enable; /* 02 disconnect enable */
2266 ushort wdtr_able; /* 03 Wide DTR able */
2267 ushort sdtr_able; /* 04 Synchronous DTR able */
2268 ushort start_motor; /* 05 send start up motor */
2269 ushort tagqng_able; /* 06 tag queuing able */
2270 ushort bios_scan; /* 07 BIOS device control */
2271 ushort scam_tolerant; /* 08 no scam */
2273 uchar adapter_scsi_id; /* 09 Host Adapter ID */
2274 uchar bios_boot_delay; /* power up wait */
2276 uchar scsi_reset_delay; /* 10 reset delay */
2277 uchar bios_id_lun; /* first boot device scsi id & lun */
2278 /* high nibble is lun */
2279 /* low nibble is scsi id */
2281 uchar termination; /* 11 0 - automatic */
2282 /* 1 - low off / high off */
2283 /* 2 - low off / high on */
2284 /* 3 - low on / high on */
2285 /* There is no low on / high off */
2287 uchar reserved1; /* reserved byte (not used) */
2289 ushort bios_ctrl; /* 12 BIOS control bits */
2290 /* bit 0 set: BIOS don't act as initiator. */
2291 /* bit 1 set: BIOS > 1 GB support */
2292 /* bit 2 set: BIOS > 2 Disk Support */
2293 /* bit 3 set: BIOS don't support removables */
2294 /* bit 4 set: BIOS support bootable CD */
2295 /* bit 5 set: */
2296 /* bit 6 set: BIOS support multiple LUNs */
2297 /* bit 7 set: BIOS display of message */
2298 /* bit 8 set: */
2299 /* bit 9 set: Reset SCSI bus during init. */
2300 /* bit 10 set: */
2301 /* bit 11 set: No verbose initialization. */
2302 /* bit 12 set: SCSI parity enabled */
2303 /* bit 13 set: */
2304 /* bit 14 set: */
2305 /* bit 15 set: */
2306 ushort ultra_able; /* 13 ULTRA speed able */
2307 ushort reserved2; /* 14 reserved */
2308 uchar max_host_qng; /* 15 maximum host queuing */
2309 uchar max_dvc_qng; /* maximum per device queuing */
2310 ushort dvc_cntl; /* 16 control bit for driver */
2311 ushort bug_fix; /* 17 control bit for bug fix */
2312 ushort serial_number_word1; /* 18 Board serial number word 1 */
2313 ushort serial_number_word2; /* 19 Board serial number word 2 */
2314 ushort serial_number_word3; /* 20 Board serial number word 3 */
2315 ushort check_sum; /* 21 EEP check sum */
2316 uchar oem_name[16]; /* 22 OEM name */
2317 ushort dvc_err_code; /* 30 last device driver error code */
2318 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
2319 ushort adv_err_addr; /* 32 last uc error address */
2320 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
2321 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
2322 ushort saved_adv_err_addr; /* 35 saved last uc error address */
2323 ushort num_of_err; /* 36 number of error */
2324 } ADVEEP_3550_CONFIG;
2326 typedef struct adveep_38C0800_config
2328 /* Word Offset, Description */
2330 ushort cfg_lsw; /* 00 power up initialization */
2331 /* bit 13 set - Load CIS */
2332 /* bit 14 set - BIOS Enable */
2333 /* bit 15 set - Big Endian Mode */
2334 ushort cfg_msw; /* 01 unused */
2335 ushort disc_enable; /* 02 disconnect enable */
2336 ushort wdtr_able; /* 03 Wide DTR able */
2337 ushort sdtr_speed1; /* 04 SDTR Speed TID 0-3 */
2338 ushort start_motor; /* 05 send start up motor */
2339 ushort tagqng_able; /* 06 tag queuing able */
2340 ushort bios_scan; /* 07 BIOS device control */
2341 ushort scam_tolerant; /* 08 no scam */
2343 uchar adapter_scsi_id; /* 09 Host Adapter ID */
2344 uchar bios_boot_delay; /* power up wait */
2346 uchar scsi_reset_delay; /* 10 reset delay */
2347 uchar bios_id_lun; /* first boot device scsi id & lun */
2348 /* high nibble is lun */
2349 /* low nibble is scsi id */
2351 uchar termination_se; /* 11 0 - automatic */
2352 /* 1 - low off / high off */
2353 /* 2 - low off / high on */
2354 /* 3 - low on / high on */
2355 /* There is no low on / high off */
2357 uchar termination_lvd; /* 11 0 - automatic */
2358 /* 1 - low off / high off */
2359 /* 2 - low off / high on */
2360 /* 3 - low on / high on */
2361 /* There is no low on / high off */
2363 ushort bios_ctrl; /* 12 BIOS control bits */
2364 /* bit 0 set: BIOS don't act as initiator. */
2365 /* bit 1 set: BIOS > 1 GB support */
2366 /* bit 2 set: BIOS > 2 Disk Support */
2367 /* bit 3 set: BIOS don't support removables */
2368 /* bit 4 set: BIOS support bootable CD */
2369 /* bit 5 set: BIOS scan enabled */
2370 /* bit 6 set: BIOS support multiple LUNs */
2371 /* bit 7 set: BIOS display of message */
2372 /* bit 8 set: */
2373 /* bit 9 set: Reset SCSI bus during init. */
2374 /* bit 10 set: */
2375 /* bit 11 set: No verbose initialization. */
2376 /* bit 12 set: SCSI parity enabled */
2377 /* bit 13 set: */
2378 /* bit 14 set: */
2379 /* bit 15 set: */
2380 ushort sdtr_speed2; /* 13 SDTR speed TID 4-7 */
2381 ushort sdtr_speed3; /* 14 SDTR speed TID 8-11 */
2382 uchar max_host_qng; /* 15 maximum host queueing */
2383 uchar max_dvc_qng; /* maximum per device queuing */
2384 ushort dvc_cntl; /* 16 control bit for driver */
2385 ushort sdtr_speed4; /* 17 SDTR speed 4 TID 12-15 */
2386 ushort serial_number_word1; /* 18 Board serial number word 1 */
2387 ushort serial_number_word2; /* 19 Board serial number word 2 */
2388 ushort serial_number_word3; /* 20 Board serial number word 3 */
2389 ushort check_sum; /* 21 EEP check sum */
2390 uchar oem_name[16]; /* 22 OEM name */
2391 ushort dvc_err_code; /* 30 last device driver error code */
2392 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
2393 ushort adv_err_addr; /* 32 last uc error address */
2394 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
2395 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
2396 ushort saved_adv_err_addr; /* 35 saved last uc error address */
2397 ushort reserved36; /* 36 reserved */
2398 ushort reserved37; /* 37 reserved */
2399 ushort reserved38; /* 38 reserved */
2400 ushort reserved39; /* 39 reserved */
2401 ushort reserved40; /* 40 reserved */
2402 ushort reserved41; /* 41 reserved */
2403 ushort reserved42; /* 42 reserved */
2404 ushort reserved43; /* 43 reserved */
2405 ushort reserved44; /* 44 reserved */
2406 ushort reserved45; /* 45 reserved */
2407 ushort reserved46; /* 46 reserved */
2408 ushort reserved47; /* 47 reserved */
2409 ushort reserved48; /* 48 reserved */
2410 ushort reserved49; /* 49 reserved */
2411 ushort reserved50; /* 50 reserved */
2412 ushort reserved51; /* 51 reserved */
2413 ushort reserved52; /* 52 reserved */
2414 ushort reserved53; /* 53 reserved */
2415 ushort reserved54; /* 54 reserved */
2416 ushort reserved55; /* 55 reserved */
2417 ushort cisptr_lsw; /* 56 CIS PTR LSW */
2418 ushort cisprt_msw; /* 57 CIS PTR MSW */
2419 ushort subsysvid; /* 58 SubSystem Vendor ID */
2420 ushort subsysid; /* 59 SubSystem ID */
2421 ushort reserved60; /* 60 reserved */
2422 ushort reserved61; /* 61 reserved */
2423 ushort reserved62; /* 62 reserved */
2424 ushort reserved63; /* 63 reserved */
2425 } ADVEEP_38C0800_CONFIG;
2428 * EEPROM Commands
2430 #define ASC_EEP_CMD_DONE 0x0200
2431 #define ASC_EEP_CMD_DONE_ERR 0x0001
2433 /* cfg_word */
2434 #define EEP_CFG_WORD_BIG_ENDIAN 0x8000
2436 /* bios_ctrl */
2437 #define BIOS_CTRL_BIOS 0x0001
2438 #define BIOS_CTRL_EXTENDED_XLAT 0x0002
2439 #define BIOS_CTRL_GT_2_DISK 0x0004
2440 #define BIOS_CTRL_BIOS_REMOVABLE 0x0008
2441 #define BIOS_CTRL_BOOTABLE_CD 0x0010
2442 #define BIOS_CTRL_MULTIPLE_LUN 0x0040
2443 #define BIOS_CTRL_DISPLAY_MSG 0x0080
2444 #define BIOS_CTRL_NO_SCAM 0x0100
2445 #define BIOS_CTRL_RESET_SCSI_BUS 0x0200
2446 #define BIOS_CTRL_INIT_VERBOSE 0x0800
2447 #define BIOS_CTRL_SCSI_PARITY 0x1000
2449 #define ADV_3550_MEMSIZE 0x2000 /* 8 KB Internal Memory */
2450 #define ADV_3550_IOLEN 0x40 /* I/O Port Range in bytes */
2452 #define ADV_38C0800_MEMSIZE 0x4000 /* 16 KB Internal Memory */
2453 #define ADV_38C0800_IOLEN 0x100 /* I/O Port Range in bytes */
2455 #define ADV_38C1600_MEMSIZE 0x4000 /* 16 KB Internal Memory */
2456 #define ADV_38C1600_IOLEN 0x100 /* I/O Port Range 256 bytes */
2457 #define ADV_38C1600_MEMLEN 0x1000 /* Memory Range 4KB bytes */
2460 * Byte I/O register address from base of 'iop_base'.
2462 #define IOPB_INTR_STATUS_REG 0x00
2463 #define IOPB_CHIP_ID_1 0x01
2464 #define IOPB_INTR_ENABLES 0x02
2465 #define IOPB_CHIP_TYPE_REV 0x03
2466 #define IOPB_RES_ADDR_4 0x04
2467 #define IOPB_RES_ADDR_5 0x05
2468 #define IOPB_RAM_DATA 0x06
2469 #define IOPB_RES_ADDR_7 0x07
2470 #define IOPB_FLAG_REG 0x08
2471 #define IOPB_RES_ADDR_9 0x09
2472 #define IOPB_RISC_CSR 0x0A
2473 #define IOPB_RES_ADDR_B 0x0B
2474 #define IOPB_RES_ADDR_C 0x0C
2475 #define IOPB_RES_ADDR_D 0x0D
2476 #define IOPB_SOFT_OVER_WR 0x0E
2477 #define IOPB_RES_ADDR_F 0x0F
2478 #define IOPB_MEM_CFG 0x10
2479 #define IOPB_RES_ADDR_11 0x11
2480 #define IOPB_GPIO_DATA 0x12
2481 #define IOPB_RES_ADDR_13 0x13
2482 #define IOPB_FLASH_PAGE 0x14
2483 #define IOPB_RES_ADDR_15 0x15
2484 #define IOPB_GPIO_CNTL 0x16
2485 #define IOPB_RES_ADDR_17 0x17
2486 #define IOPB_FLASH_DATA 0x18
2487 #define IOPB_RES_ADDR_19 0x19
2488 #define IOPB_RES_ADDR_1A 0x1A
2489 #define IOPB_RES_ADDR_1B 0x1B
2490 #define IOPB_RES_ADDR_1C 0x1C
2491 #define IOPB_RES_ADDR_1D 0x1D
2492 #define IOPB_RES_ADDR_1E 0x1E
2493 #define IOPB_RES_ADDR_1F 0x1F
2494 #define IOPB_DMA_CFG0 0x20
2495 #define IOPB_DMA_CFG1 0x21
2496 #define IOPB_TICKLE 0x22
2497 #define IOPB_DMA_REG_WR 0x23
2498 #define IOPB_SDMA_STATUS 0x24
2499 #define IOPB_SCSI_BYTE_CNT 0x25
2500 #define IOPB_HOST_BYTE_CNT 0x26
2501 #define IOPB_BYTE_LEFT_TO_XFER 0x27
2502 #define IOPB_BYTE_TO_XFER_0 0x28
2503 #define IOPB_BYTE_TO_XFER_1 0x29
2504 #define IOPB_BYTE_TO_XFER_2 0x2A
2505 #define IOPB_BYTE_TO_XFER_3 0x2B
2506 #define IOPB_ACC_GRP 0x2C
2507 #define IOPB_RES_ADDR_2D 0x2D
2508 #define IOPB_DEV_ID 0x2E
2509 #define IOPB_RES_ADDR_2F 0x2F
2510 #define IOPB_SCSI_DATA 0x30
2511 #define IOPB_RES_ADDR_31 0x31
2512 #define IOPB_RES_ADDR_32 0x32
2513 #define IOPB_SCSI_DATA_HSHK 0x33
2514 #define IOPB_SCSI_CTRL 0x34
2515 #define IOPB_RES_ADDR_35 0x35
2516 #define IOPB_RES_ADDR_36 0x36
2517 #define IOPB_RES_ADDR_37 0x37
2518 #define IOPB_RAM_BIST 0x38
2519 #define IOPB_PLL_TEST 0x39
2520 #define IOPB_PCI_INT_CFG 0x3A
2521 #define IOPB_RES_ADDR_3B 0x3B
2522 #define IOPB_RFIFO_CNT 0x3C
2523 #define IOPB_RES_ADDR_3D 0x3D
2524 #define IOPB_RES_ADDR_3E 0x3E
2525 #define IOPB_RES_ADDR_3F 0x3F
2528 * Word I/O register address from base of 'iop_base'.
2530 #define IOPW_CHIP_ID_0 0x00 /* CID0 */
2531 #define IOPW_CTRL_REG 0x02 /* CC */
2532 #define IOPW_RAM_ADDR 0x04 /* LA */
2533 #define IOPW_RAM_DATA 0x06 /* LD */
2534 #define IOPW_RES_ADDR_08 0x08
2535 #define IOPW_RISC_CSR 0x0A /* CSR */
2536 #define IOPW_SCSI_CFG0 0x0C /* CFG0 */
2537 #define IOPW_SCSI_CFG1 0x0E /* CFG1 */
2538 #define IOPW_RES_ADDR_10 0x10
2539 #define IOPW_SEL_MASK 0x12 /* SM */
2540 #define IOPW_RES_ADDR_14 0x14
2541 #define IOPW_FLASH_ADDR 0x16 /* FA */
2542 #define IOPW_RES_ADDR_18 0x18
2543 #define IOPW_EE_CMD 0x1A /* EC */
2544 #define IOPW_EE_DATA 0x1C /* ED */
2545 #define IOPW_SFIFO_CNT 0x1E /* SFC */
2546 #define IOPW_RES_ADDR_20 0x20
2547 #define IOPW_Q_BASE 0x22 /* QB */
2548 #define IOPW_QP 0x24 /* QP */
2549 #define IOPW_IX 0x26 /* IX */
2550 #define IOPW_SP 0x28 /* SP */
2551 #define IOPW_PC 0x2A /* PC */
2552 #define IOPW_RES_ADDR_2C 0x2C
2553 #define IOPW_RES_ADDR_2E 0x2E
2554 #define IOPW_SCSI_DATA 0x30 /* SD */
2555 #define IOPW_SCSI_DATA_HSHK 0x32 /* SDH */
2556 #define IOPW_SCSI_CTRL 0x34 /* SC */
2557 #define IOPW_HSHK_CFG 0x36 /* HCFG */
2558 #define IOPW_SXFR_STATUS 0x36 /* SXS */
2559 #define IOPW_SXFR_CNTL 0x38 /* SXL */
2560 #define IOPW_SXFR_CNTH 0x3A /* SXH */
2561 #define IOPW_RES_ADDR_3C 0x3C
2562 #define IOPW_RFIFO_DATA 0x3E /* RFD */
2565 * Doubleword I/O register address from base of 'iop_base'.
2567 #define IOPDW_RES_ADDR_0 0x00
2568 #define IOPDW_RAM_DATA 0x04
2569 #define IOPDW_RES_ADDR_8 0x08
2570 #define IOPDW_RES_ADDR_C 0x0C
2571 #define IOPDW_RES_ADDR_10 0x10
2572 #define IOPDW_COMMA 0x14
2573 #define IOPDW_COMMB 0x18
2574 #define IOPDW_RES_ADDR_1C 0x1C
2575 #define IOPDW_SDMA_ADDR0 0x20
2576 #define IOPDW_SDMA_ADDR1 0x24
2577 #define IOPDW_SDMA_COUNT 0x28
2578 #define IOPDW_SDMA_ERROR 0x2C
2579 #define IOPDW_RDMA_ADDR0 0x30
2580 #define IOPDW_RDMA_ADDR1 0x34
2581 #define IOPDW_RDMA_COUNT 0x38
2582 #define IOPDW_RDMA_ERROR 0x3C
2584 #define ADV_CHIP_ID_BYTE 0x25
2585 #define ADV_CHIP_ID_WORD 0x04C1
2587 #define ADV_SC_SCSI_BUS_RESET 0x2000
2589 #define ADV_INTR_ENABLE_HOST_INTR 0x01
2590 #define ADV_INTR_ENABLE_SEL_INTR 0x02
2591 #define ADV_INTR_ENABLE_DPR_INTR 0x04
2592 #define ADV_INTR_ENABLE_RTA_INTR 0x08
2593 #define ADV_INTR_ENABLE_RMA_INTR 0x10
2594 #define ADV_INTR_ENABLE_RST_INTR 0x20
2595 #define ADV_INTR_ENABLE_DPE_INTR 0x40
2596 #define ADV_INTR_ENABLE_GLOBAL_INTR 0x80
2598 #define ADV_INTR_STATUS_INTRA 0x01
2599 #define ADV_INTR_STATUS_INTRB 0x02
2600 #define ADV_INTR_STATUS_INTRC 0x04
2602 #define ADV_RISC_CSR_STOP (0x0000)
2603 #define ADV_RISC_TEST_COND (0x2000)
2604 #define ADV_RISC_CSR_RUN (0x4000)
2605 #define ADV_RISC_CSR_SINGLE_STEP (0x8000)
2607 #define ADV_CTRL_REG_HOST_INTR 0x0100
2608 #define ADV_CTRL_REG_SEL_INTR 0x0200
2609 #define ADV_CTRL_REG_DPR_INTR 0x0400
2610 #define ADV_CTRL_REG_RTA_INTR 0x0800
2611 #define ADV_CTRL_REG_RMA_INTR 0x1000
2612 #define ADV_CTRL_REG_RES_BIT14 0x2000
2613 #define ADV_CTRL_REG_DPE_INTR 0x4000
2614 #define ADV_CTRL_REG_POWER_DONE 0x8000
2615 #define ADV_CTRL_REG_ANY_INTR 0xFF00
2617 #define ADV_CTRL_REG_CMD_RESET 0x00C6
2618 #define ADV_CTRL_REG_CMD_WR_IO_REG 0x00C5
2619 #define ADV_CTRL_REG_CMD_RD_IO_REG 0x00C4
2620 #define ADV_CTRL_REG_CMD_WR_PCI_CFG_SPACE 0x00C3
2621 #define ADV_CTRL_REG_CMD_RD_PCI_CFG_SPACE 0x00C2
2623 #define ADV_TICKLE_NOP 0x00
2624 #define ADV_TICKLE_A 0x01
2625 #define ADV_TICKLE_B 0x02
2626 #define ADV_TICKLE_C 0x03
2628 #define ADV_SCSI_CTRL_RSTOUT 0x2000
2630 #define AdvIsIntPending(port) \
2631 (AdvReadWordRegister(port, IOPW_CTRL_REG) & ADV_CTRL_REG_HOST_INTR)
2634 * SCSI_CFG0 Register bit definitions
2636 #define TIMER_MODEAB 0xC000 /* Watchdog, Second, and Select. Timer Ctrl. */
2637 #define PARITY_EN 0x2000 /* Enable SCSI Parity Error detection */
2638 #define EVEN_PARITY 0x1000 /* Select Even Parity */
2639 #define WD_LONG 0x0800 /* Watchdog Interval, 1: 57 min, 0: 13 sec */
2640 #define QUEUE_128 0x0400 /* Queue Size, 1: 128 byte, 0: 64 byte */
2641 #define PRIM_MODE 0x0100 /* Primitive SCSI mode */
2642 #define SCAM_EN 0x0080 /* Enable SCAM selection */
2643 #define SEL_TMO_LONG 0x0040 /* Sel/Resel Timeout, 1: 400 ms, 0: 1.6 ms */
2644 #define CFRM_ID 0x0020 /* SCAM id sel. confirm., 1: fast, 0: 6.4 ms */
2645 #define OUR_ID_EN 0x0010 /* Enable OUR_ID bits */
2646 #define OUR_ID 0x000F /* SCSI ID */
2649 * SCSI_CFG1 Register bit definitions
2651 #define BIG_ENDIAN 0x8000 /* Enable Big Endian Mode MIO:15, EEP:15 */
2652 #define TERM_POL 0x2000 /* Terminator Polarity Ctrl. MIO:13, EEP:13 */
2653 #define SLEW_RATE 0x1000 /* SCSI output buffer slew rate */
2654 #define FILTER_SEL 0x0C00 /* Filter Period Selection */
2655 #define FLTR_DISABLE 0x0000 /* Input Filtering Disabled */
2656 #define FLTR_11_TO_20NS 0x0800 /* Input Filtering 11ns to 20ns */
2657 #define FLTR_21_TO_39NS 0x0C00 /* Input Filtering 21ns to 39ns */
2658 #define ACTIVE_DBL 0x0200 /* Disable Active Negation */
2659 #define DIFF_MODE 0x0100 /* SCSI differential Mode (Read-Only) */
2660 #define DIFF_SENSE 0x0080 /* 1: No SE cables, 0: SE cable (Read-Only) */
2661 #define TERM_CTL_SEL 0x0040 /* Enable TERM_CTL_H and TERM_CTL_L */
2662 #define TERM_CTL 0x0030 /* External SCSI Termination Bits */
2663 #define TERM_CTL_H 0x0020 /* Enable External SCSI Upper Termination */
2664 #define TERM_CTL_L 0x0010 /* Enable External SCSI Lower Termination */
2665 #define CABLE_DETECT 0x000F /* External SCSI Cable Connection Status */
2668 * Addendum for ASC-38C0800 Chip
2670 #define DIS_TERM_DRV 0x4000 /* 1: Read c_det[3:0], 0: cannot read */
2671 #define HVD_LVD_SE 0x1C00 /* Device Detect Bits */
2672 #define HVD 0x1000 /* HVD Device Detect */
2673 #define LVD 0x0800 /* LVD Device Detect */
2674 #define SE 0x0400 /* SE Device Detect */
2675 #define TERM_LVD 0x00C0 /* LVD Termination Bits */
2676 #define TERM_LVD_HI 0x0080 /* Enable LVD Upper Termination */
2677 #define TERM_LVD_LO 0x0040 /* Enable LVD Lower Termination */
2678 #define TERM_SE 0x0030 /* SE Termination Bits */
2679 #define TERM_SE_HI 0x0020 /* Enable SE Upper Termination */
2680 #define TERM_SE_LO 0x0010 /* Enable SE Lower Termination */
2681 #define C_DET_LVD 0x000C /* LVD Cable Detect Bits */
2682 #define C_DET3 0x0008 /* Cable Detect for LVD External Wide */
2683 #define C_DET2 0x0004 /* Cable Detect for LVD Internal Wide */
2684 #define C_DET_SE 0x0003 /* SE Cable Detect Bits */
2685 #define C_DET1 0x0002 /* Cable Detect for SE Internal Wide */
2686 #define C_DET0 0x0001 /* Cable Detect for SE Internal Narrow */
2689 #define CABLE_ILLEGAL_A 0x7
2690 /* x 0 0 0 | on on | Illegal (all 3 connectors are used) */
2692 #define CABLE_ILLEGAL_B 0xB
2693 /* 0 x 0 0 | on on | Illegal (all 3 connectors are used) */
2696 * MEM_CFG Register bit definitions
2698 #define BIOS_EN 0x40 /* BIOS Enable MIO:14,EEP:14 */
2699 #define FAST_EE_CLK 0x20 /* Diagnostic Bit */
2700 #define RAM_SZ 0x1C /* Specify size of RAM to RISC */
2701 #define RAM_SZ_2KB 0x00 /* 2 KB */
2702 #define RAM_SZ_4KB 0x04 /* 4 KB */
2703 #define RAM_SZ_8KB 0x08 /* 8 KB */
2704 #define RAM_SZ_16KB 0x0C /* 16 KB */
2705 #define RAM_SZ_32KB 0x10 /* 32 KB */
2706 #define RAM_SZ_64KB 0x14 /* 64 KB */
2709 * DMA_CFG0 Register bit definitions
2711 * This register is only accessible to the host.
2713 #define BC_THRESH_ENB 0x80 /* PCI DMA Start Conditions */
2714 #define FIFO_THRESH 0x70 /* PCI DMA FIFO Threshold */
2715 #define FIFO_THRESH_16B 0x00 /* 16 bytes */
2716 #define FIFO_THRESH_32B 0x20 /* 32 bytes */
2717 #define FIFO_THRESH_48B 0x30 /* 48 bytes */
2718 #define FIFO_THRESH_64B 0x40 /* 64 bytes */
2719 #define FIFO_THRESH_80B 0x50 /* 80 bytes (default) */
2720 #define FIFO_THRESH_96B 0x60 /* 96 bytes */
2721 #define FIFO_THRESH_112B 0x70 /* 112 bytes */
2722 #define START_CTL 0x0C /* DMA start conditions */
2723 #define START_CTL_TH 0x00 /* Wait threshold level (default) */
2724 #define START_CTL_ID 0x04 /* Wait SDMA/SBUS idle */
2725 #define START_CTL_THID 0x08 /* Wait threshold and SDMA/SBUS idle */
2726 #define START_CTL_EMFU 0x0C /* Wait SDMA FIFO empty/full */
2727 #define READ_CMD 0x03 /* Memory Read Method */
2728 #define READ_CMD_MR 0x00 /* Memory Read */
2729 #define READ_CMD_MRL 0x02 /* Memory Read Long */
2730 #define READ_CMD_MRM 0x03 /* Memory Read Multiple (default) */
2733 * ASC-38C0800 RAM BIST Register bit definitions
2735 #define RAM_TEST_MODE 0x80
2736 #define PRE_TEST_MODE 0x40
2737 #define NORMAL_MODE 0x00
2738 #define RAM_TEST_DONE 0x10
2739 #define RAM_TEST_STATUS 0x0F
2740 #define RAM_TEST_HOST_ERROR 0x08
2741 #define RAM_TEST_INTRAM_ERROR 0x04
2742 #define RAM_TEST_RISC_ERROR 0x02
2743 #define RAM_TEST_SCSI_ERROR 0x01
2744 #define RAM_TEST_SUCCESS 0x00
2745 #define PRE_TEST_VALUE 0x05
2746 #define NORMAL_VALUE 0x00
2748 /* a_advlib.h */
2751 * Adv Library Status Definitions
2753 #define ADV_TRUE 1
2754 #define ADV_FALSE 0
2755 #define ADV_NOERROR 1
2756 #define ADV_SUCCESS 1
2757 #define ADV_BUSY 0
2758 #define ADV_ERROR (-1)
2762 * ASC_DVC_VAR 'warn_code' values
2764 #define ASC_WARN_BUSRESET_ERROR 0x0001 /* SCSI Bus Reset error */
2765 #define ASC_WARN_EEPROM_CHKSUM 0x0002 /* EEP check sum error */
2766 #define ASC_WARN_EEPROM_TERMINATION 0x0004 /* EEP termination bad field */
2767 #define ASC_WARN_SET_PCI_CONFIG_SPACE 0x0080 /* PCI config space set error */
2768 #define ASC_WARN_ERROR 0xFFFF /* ADV_ERROR return */
2770 #define ADV_MAX_TID 15 /* max. target identifier */
2771 #define ADV_MAX_LUN 7 /* max. logical unit number */
2775 * AscInitGetConfig() and AscInitAsc1000Driver() Definitions
2777 * Error code values are set in ASC_DVC_VAR 'err_code'.
2779 #define ASC_IERR_WRITE_EEPROM 0x0001 /* write EEPROM error */
2780 #define ASC_IERR_MCODE_CHKSUM 0x0002 /* micro code check sum error */
2781 #define ASC_IERR_NO_CARRIER 0x0004 /* No more carrier memory. */
2782 #define ASC_IERR_START_STOP_CHIP 0x0008 /* start/stop chip failed */
2783 #define ASC_IERR_CHIP_VERSION 0x0040 /* wrong chip version */
2784 #define ASC_IERR_SET_SCSI_ID 0x0080 /* set SCSI ID failed */
2785 #define ASC_IERR_HVD_DEVICE 0x0100 /* HVD attached to LVD connector. */
2786 #define ASC_IERR_BAD_SIGNATURE 0x0200 /* signature not found */
2787 #define ASC_IERR_ILLEGAL_CONNECTION 0x0400 /* Illegal cable connection */
2788 #define ASC_IERR_SINGLE_END_DEVICE 0x0800 /* Single-end used w/differential */
2789 #define ASC_IERR_REVERSED_CABLE 0x1000 /* Narrow flat cable reversed */
2790 #define ASC_IERR_BIST_PRE_TEST 0x2000 /* BIST pre-test error */
2791 #define ASC_IERR_BIST_RAM_TEST 0x4000 /* BIST RAM test error */
2792 #define ASC_IERR_BAD_CHIPTYPE 0x8000 /* Invalid 'chip_type' setting. */
2795 * Fixed locations of microcode operating variables.
2797 #define ASC_MC_CODE_BEGIN_ADDR 0x0028 /* microcode start address */
2798 #define ASC_MC_CODE_END_ADDR 0x002A /* microcode end address */
2799 #define ASC_MC_CODE_CHK_SUM 0x002C /* microcode code checksum */
2800 #define ASC_MC_VERSION_DATE 0x0038 /* microcode version */
2801 #define ASC_MC_VERSION_NUM 0x003A /* microcode number */
2802 #define ASC_MC_BIOSMEM 0x0040 /* BIOS RISC Memory Start */
2803 #define ASC_MC_BIOSLEN 0x0050 /* BIOS RISC Memory Length */
2804 #define ASC_MC_BIOS_SIGNATURE 0x0058 /* BIOS Signature 0x55AA */
2805 #define ASC_MC_BIOS_VERSION 0x005A /* BIOS Version (2 bytes) */
2806 #define ASC_MC_SDTR_SPEED1 0x0090 /* SDTR Speed for TID 0-3 */
2807 #define ASC_MC_SDTR_SPEED2 0x0092 /* SDTR Speed for TID 4-7 */
2808 #define ASC_MC_SDTR_SPEED3 0x0094 /* SDTR Speed for TID 8-11 */
2809 #define ASC_MC_SDTR_SPEED4 0x0096 /* SDTR Speed for TID 12-15 */
2810 #define ASC_MC_CHIP_TYPE 0x009A
2811 #define ASC_MC_INTRB_CODE 0x009B
2812 #define ASC_MC_WDTR_ABLE 0x009C
2813 #define ASC_MC_SDTR_ABLE 0x009E
2814 #define ASC_MC_TAGQNG_ABLE 0x00A0
2815 #define ASC_MC_DISC_ENABLE 0x00A2
2816 #define ASC_MC_IDLE_CMD_STATUS 0x00A4
2817 #define ASC_MC_IDLE_CMD 0x00A6
2818 #define ASC_MC_IDLE_CMD_PARAMETER 0x00A8
2819 #define ASC_MC_DEFAULT_SCSI_CFG0 0x00AC
2820 #define ASC_MC_DEFAULT_SCSI_CFG1 0x00AE
2821 #define ASC_MC_DEFAULT_MEM_CFG 0x00B0
2822 #define ASC_MC_DEFAULT_SEL_MASK 0x00B2
2823 #define ASC_MC_SDTR_DONE 0x00B6
2824 #define ASC_MC_NUMBER_OF_QUEUED_CMD 0x00C0
2825 #define ASC_MC_NUMBER_OF_MAX_CMD 0x00D0
2826 #define ASC_MC_DEVICE_HSHK_CFG_TABLE 0x0100
2827 #define ASC_MC_CONTROL_FLAG 0x0122 /* Microcode control flag. */
2828 #define ASC_MC_WDTR_DONE 0x0124
2829 #define ASC_MC_CAM_MODE_MASK 0x015E /* CAM mode TID bitmask. */
2830 #define ASC_MC_ICQ 0x0160
2831 #define ASC_MC_IRQ 0x0164
2834 * BIOS LRAM variable absolute offsets.
2836 #define BIOS_CODESEG 0x54
2837 #define BIOS_CODELEN 0x56
2838 #define BIOS_SIGNATURE 0x58
2839 #define BIOS_VERSION 0x5A
2842 * Microcode Control Flags
2844 * Flags set by the Adv Library in RISC variable 'control_flag' (0x122)
2845 * and handled by the microcode.
2847 #define CONTROL_FLAG_IGNORE_PERR 0x0001 /* Ignore DMA Parity Errors */
2850 * ASC_MC_DEVICE_HSHK_CFG_TABLE microcode table or HSHK_CFG register format
2852 #define HSHK_CFG_WIDE_XFR 0x8000
2853 #define HSHK_CFG_RATE 0x0F00
2854 #define HSHK_CFG_OFFSET 0x001F
2856 #define ASC_DEF_MAX_HOST_QNG 0xFD /* Max. number of host commands (253) */
2857 #define ASC_DEF_MIN_HOST_QNG 0x10 /* Min. number of host commands (16) */
2858 #define ASC_DEF_MAX_DVC_QNG 0x3F /* Max. number commands per device (63) */
2859 #define ASC_DEF_MIN_DVC_QNG 0x04 /* Min. number commands per device (4) */
2861 #define ASC_QC_DATA_CHECK 0x01 /* Require ASC_QC_DATA_OUT set or clear. */
2862 #define ASC_QC_DATA_OUT 0x02 /* Data out DMA transfer. */
2863 #define ASC_QC_START_MOTOR 0x04 /* Send auto-start motor before request. */
2864 #define ASC_QC_NO_OVERRUN 0x08 /* Don't report overrun. */
2865 #define ASC_QC_FREEZE_TIDQ 0x10 /* Freeze TID queue after request. XXX TBD */
2867 #define ASC_QSC_NO_DISC 0x01 /* Don't allow disconnect for request. */
2868 #define ASC_QSC_NO_TAGMSG 0x02 /* Don't allow tag queuing for request. */
2869 #define ASC_QSC_NO_SYNC 0x04 /* Don't use Synch. transfer on request. */
2870 #define ASC_QSC_NO_WIDE 0x08 /* Don't use Wide transfer on request. */
2871 #define ASC_QSC_REDO_DTR 0x10 /* Renegotiate WDTR/SDTR before request. */
2873 * Note: If a Tag Message is to be sent and neither ASC_QSC_HEAD_TAG or
2874 * ASC_QSC_ORDERED_TAG is set, then a Simple Tag Message (0x20) is used.
2876 #define ASC_QSC_HEAD_TAG 0x40 /* Use Head Tag Message (0x21). */
2877 #define ASC_QSC_ORDERED_TAG 0x80 /* Use Ordered Tag Message (0x22). */
2879 typedef struct adv_carr_t
2881 ADV_VADDR carr_va; /* Carrier Virtual Address */
2882 ADV_PADDR carr_pa; /* Carrier Physical Address */
2883 ADV_VADDR areq_vpa; /* ASC_SCSI_REQ_Q Virtual or Physical Address */
2885 * next_vpa [31:4] Carrier Virtual or Physical Next Pointer
2887 * next_vpa [3:1] Reserved Bits
2888 * next_vpa [0] Done Flag set in Response Queue.
2890 ADV_VADDR next_vpa;
2891 } ADV_CARR_T;
2894 * Mask used to eliminate low 4 bits of carrier 'next_vpa' field.
2896 #define ASC_NEXT_VPA_MASK 0xFFFFFFF0
2898 #define ASC_RQ_DONE 0x00000001
2899 #define ASC_CQ_STOPPER 0x00000000
2901 #define ASC_GET_CARRP(carrp) ((carrp) & ASC_NEXT_VPA_MASK)
2903 #define ADV_PAGE_SIZE 4096 /* Assume 4KB page size. */
2905 #define ADV_CARRIER_NUM_PAGE_CROSSING \
2906 (((ADV_CARRIER_COUNT * sizeof(ADV_CARR_T)) + \
2907 (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
2909 #define ADV_CARRIER_BUFSIZE \
2910 ((ADV_CARRIER_COUNT + ADV_CARRIER_NUM_PAGE_CROSSING) * sizeof(ADV_CARR_T))
2913 * ASC_SCSI_REQ_Q 'a_flag' definitions
2915 * The Adv Library should limit use to the lower nibble (4 bits) of
2916 * a_flag. Drivers are free to use the upper nibble (4 bits) of a_flag.
2918 #define ADV_POLL_REQUEST 0x01 /* poll for request completion */
2919 #define ADV_SCSIQ_DONE 0x02 /* request done */
2920 #define ADV_DONT_RETRY 0x08 /* don't do retry */
2922 #define ADV_CHIP_ASC3550 0x01 /* Ultra-Wide IC */
2923 #define ADV_CHIP_ASC38C0800 0x02 /* Ultra2-Wide/LVD IC */
2924 #define ADV_CHIP_ASC38C1600 0x03 /* Ultra3-Wide/LVD2 IC */
2927 * Adapter temporary configuration structure
2929 * This structure can be discarded after initialization. Don't add
2930 * fields here needed after initialization.
2932 * Field naming convention:
2934 * *_enable indicates the field enables or disables a feature. The
2935 * value of the field is never reset.
2937 typedef struct adv_dvc_cfg {
2938 ushort disc_enable; /* enable disconnection */
2939 uchar chip_version; /* chip version */
2940 uchar termination; /* Term. Ctrl. bits 6-5 of SCSI_CFG1 register */
2941 ushort pci_device_id; /* PCI device code number */
2942 ushort lib_version; /* Adv Library version number */
2943 ushort control_flag; /* Microcode Control Flag */
2944 ushort mcode_date; /* Microcode date */
2945 ushort mcode_version; /* Microcode version */
2946 ushort pci_slot_info; /* high byte device/function number */
2947 /* bits 7-3 device num., bits 2-0 function num. */
2948 /* low byte bus num. */
2949 ushort serial1; /* EEPROM serial number word 1 */
2950 ushort serial2; /* EEPROM serial number word 2 */
2951 ushort serial3; /* EEPROM serial number word 3 */
2952 } ADV_DVC_CFG;
2954 struct adv_dvc_var;
2955 struct adv_scsi_req_q;
2957 typedef void (* ADV_ISR_CALLBACK)
2958 (struct adv_dvc_var *, struct adv_scsi_req_q *);
2960 typedef void (* ADV_ASYNC_CALLBACK)
2961 (struct adv_dvc_var *, uchar);
2964 * Adapter operation variable structure.
2966 * One structure is required per host adapter.
2968 * Field naming convention:
2970 * *_able indicates both whether a feature should be enabled or disabled
2971 * and whether a device isi capable of the feature. At initialization
2972 * this field may be set, but later if a device is found to be incapable
2973 * of the feature, the field is cleared.
2975 typedef struct adv_dvc_var {
2976 AdvPortAddr iop_base; /* I/O port address */
2977 ushort err_code; /* fatal error code */
2978 ushort bios_ctrl; /* BIOS control word, EEPROM word 12 */
2979 ADV_ISR_CALLBACK isr_callback;
2980 ADV_ASYNC_CALLBACK async_callback;
2981 ushort wdtr_able; /* try WDTR for a device */
2982 ushort sdtr_able; /* try SDTR for a device */
2983 ushort ultra_able; /* try SDTR Ultra speed for a device */
2984 ushort sdtr_speed1; /* EEPROM SDTR Speed for TID 0-3 */
2985 ushort sdtr_speed2; /* EEPROM SDTR Speed for TID 4-7 */
2986 ushort sdtr_speed3; /* EEPROM SDTR Speed for TID 8-11 */
2987 ushort sdtr_speed4; /* EEPROM SDTR Speed for TID 12-15 */
2988 ushort tagqng_able; /* try tagged queuing with a device */
2989 uchar max_dvc_qng; /* maximum number of tagged commands per device */
2990 ushort start_motor; /* start motor command allowed */
2991 uchar scsi_reset_wait; /* delay in seconds after scsi bus reset */
2992 uchar chip_no; /* should be assigned by caller */
2993 uchar max_host_qng; /* maximum number of Q'ed command allowed */
2994 uchar irq_no; /* IRQ number */
2995 ushort no_scam; /* scam_tolerant of EEPROM */
2996 struct asc_board *drv_ptr; /* driver pointer to private structure */
2997 uchar chip_scsi_id; /* chip SCSI target ID */
2998 uchar chip_type;
2999 uchar bist_err_code;
3000 ADV_CARR_T *carrier_buf;
3001 ADV_CARR_T *carr_freelist; /* Carrier free list. */
3002 ADV_CARR_T *icq_sp; /* Initiator command queue stopper pointer. */
3003 ADV_CARR_T *irq_sp; /* Initiator response queue stopper pointer. */
3004 ushort carr_pending_cnt; /* Count of pending carriers. */
3006 * Note: The following fields will not be used after initialization. The
3007 * driver may discard the buffer after initialization is done.
3009 ADV_DVC_CFG *cfg; /* temporary configuration structure */
3010 } ADV_DVC_VAR;
3012 #define NO_OF_SG_PER_BLOCK 15
3014 typedef struct asc_sg_block {
3015 uchar reserved1;
3016 uchar reserved2;
3017 uchar reserved3;
3018 uchar sg_cnt; /* Valid entries in block. */
3019 ADV_PADDR sg_ptr; /* Pointer to next sg block. */
3020 struct {
3021 ADV_PADDR sg_addr; /* SG element address. */
3022 ADV_DCNT sg_count; /* SG element count. */
3023 } sg_list[NO_OF_SG_PER_BLOCK];
3024 } ADV_SG_BLOCK;
3027 * ADV_SCSI_REQ_Q - microcode request structure
3029 * All fields in this structure up to byte 60 are used by the microcode.
3030 * The microcode makes assumptions about the size and ordering of fields
3031 * in this structure. Do not change the structure definition here without
3032 * coordinating the change with the microcode.
3034 typedef struct adv_scsi_req_q {
3035 uchar cntl; /* Ucode flags and state (ASC_MC_QC_*). */
3036 uchar target_cmd;
3037 uchar target_id; /* Device target identifier. */
3038 uchar target_lun; /* Device target logical unit number. */
3039 ADV_PADDR data_addr; /* Data buffer physical address. */
3040 ADV_DCNT data_cnt; /* Data count. Ucode sets to residual. */
3041 ADV_PADDR sense_addr;
3042 ADV_PADDR carr_pa;
3043 uchar mflag;
3044 uchar sense_len;
3045 uchar cdb_len; /* SCSI CDB length. */
3046 uchar scsi_cntl;
3047 uchar done_status; /* Completion status. */
3048 uchar scsi_status; /* SCSI status byte. */
3049 uchar host_status; /* Ucode host status. */
3050 uchar sg_working_ix;
3051 uchar cdb[12]; /* SCSI command block. */
3052 ADV_PADDR sg_real_addr; /* SG list physical address. */
3053 ADV_PADDR scsiq_rptr;
3054 ADV_DCNT sg_working_data_cnt;
3055 ADV_VADDR scsiq_ptr;
3056 ADV_VADDR carr_va;
3058 * End of microcode structure - 60 bytes. The rest of the structure
3059 * is used by the Adv Library and ignored by the microcode.
3061 ADV_VADDR srb_ptr;
3062 ADV_SG_BLOCK *sg_list_ptr; /* SG list virtual address. */
3063 char *vdata_addr; /* Data buffer virtual address. */
3064 uchar a_flag;
3065 } ADV_SCSI_REQ_Q;
3068 * Microcode idle loop commands
3070 #define IDLE_CMD_COMPLETED 0
3071 #define IDLE_CMD_STOP_CHIP 0x0001
3072 #define IDLE_CMD_STOP_CHIP_SEND_INT 0x0002
3073 #define IDLE_CMD_SEND_INT 0x0004
3074 #define IDLE_CMD_ABORT 0x0008
3075 #define IDLE_CMD_DEVICE_RESET 0x0010
3076 #define IDLE_CMD_SCSI_RESET_START 0x0020 /* Assert SCSI Bus Reset */
3077 #define IDLE_CMD_SCSI_RESET_END 0x0040 /* Deassert SCSI Bus Reset */
3078 #define IDLE_CMD_SCSIREQ 0x0080
3080 #define IDLE_CMD_STATUS_SUCCESS 0x0001
3081 #define IDLE_CMD_STATUS_FAILURE 0x0002
3084 * AdvSendIdleCmd() flag definitions.
3086 #define ADV_NOWAIT 0x01
3089 * Wait loop time out values.
3091 #define SCSI_WAIT_10_SEC 10UL /* 10 seconds */
3092 #define SCSI_WAIT_100_MSEC 100UL /* 100 milliseconds */
3093 #define SCSI_US_PER_MSEC 1000 /* microseconds per millisecond */
3094 #define SCSI_MS_PER_SEC 1000UL /* milliseconds per second */
3095 #define SCSI_MAX_RETRY 10 /* retry count */
3097 #define ADV_ASYNC_RDMA_FAILURE 0x01 /* Fatal RDMA failure. */
3098 #define ADV_ASYNC_SCSI_BUS_RESET_DET 0x02 /* Detected SCSI Bus Reset. */
3099 #define ADV_ASYNC_CARRIER_READY_FAILURE 0x03 /* Carrier Ready failure. */
3101 #define ADV_HOST_SCSI_BUS_RESET 0x80 /* Host Initiated SCSI Bus Reset. */
3104 * Device drivers must define the following functions.
3106 STATIC int DvcEnterCritical(void);
3107 STATIC void DvcLeaveCritical(int);
3108 STATIC void DvcSleepMilliSecond(ADV_DCNT);
3109 STATIC uchar DvcAdvReadPCIConfigByte(ADV_DVC_VAR *, ushort);
3110 STATIC void DvcAdvWritePCIConfigByte(ADV_DVC_VAR *, ushort, uchar);
3111 STATIC ADV_PADDR DvcGetPhyAddr(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *,
3112 uchar *, ASC_SDCNT *, int);
3113 STATIC void DvcDelayMicroSecond(ADV_DVC_VAR *, ushort);
3116 * Adv Library functions available to drivers.
3118 STATIC int AdvExeScsiQueue(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
3119 STATIC int AdvISR(ADV_DVC_VAR *);
3120 STATIC int AdvInitGetConfig(ADV_DVC_VAR *);
3121 STATIC int AdvInitAsc3550Driver(ADV_DVC_VAR *);
3122 STATIC int AdvInitAsc38C0800Driver(ADV_DVC_VAR *);
3123 STATIC int AdvResetChipAndSB(ADV_DVC_VAR *);
3124 STATIC int AdvResetSB(ADV_DVC_VAR *asc_dvc);
3127 * Internal Adv Library functions.
3129 STATIC int AdvSendIdleCmd(ADV_DVC_VAR *, ushort, ADV_DCNT);
3130 STATIC void AdvInquiryHandling(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
3131 STATIC int AdvInitFrom3550EEP(ADV_DVC_VAR *);
3132 STATIC int AdvInitFrom38C0800EEP(ADV_DVC_VAR *);
3133 STATIC ushort AdvGet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *);
3134 STATIC void AdvSet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *);
3135 STATIC ushort AdvGet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *);
3136 STATIC void AdvSet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *);
3137 STATIC void AdvWaitEEPCmd(AdvPortAddr);
3138 STATIC ushort AdvReadEEPWord(AdvPortAddr, int);
3141 * PCI Bus Definitions
3143 #define AscPCICmdRegBits_BusMastering 0x0007
3144 #define AscPCICmdRegBits_ParErrRespCtrl 0x0040
3146 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0)
3148 /* Read byte from a register. */
3149 #define AdvReadByteRegister(iop_base, reg_off) \
3150 (inp((iop_base) + (reg_off)))
3152 /* Write byte to a register. */
3153 #define AdvWriteByteRegister(iop_base, reg_off, byte) \
3154 (outp((iop_base) + (reg_off), (byte)))
3156 /* Read word (2 bytes) from a register. */
3157 #define AdvReadWordRegister(iop_base, reg_off) \
3158 (le16_to_cpu(inpw((iop_base) + (reg_off))))
3160 /* Write word (2 bytes) to a register. */
3161 #define AdvWriteWordRegister(iop_base, reg_off, word) \
3162 (outpw((iop_base) + (reg_off), cpu_to_le16(word)))
3164 /* Read byte from LRAM. */
3165 #define AdvReadByteLram(iop_base, addr, byte) \
3166 do { \
3167 outpw((iop_base) + IOPW_RAM_ADDR, (addr)); \
3168 (byte) = inp((iop_base) + IOPB_RAM_DATA); \
3169 } while (0)
3171 /* Write byte to LRAM. */
3172 #define AdvWriteByteLram(iop_base, addr, byte) \
3173 (outpw((iop_base) + IOPW_RAM_ADDR, (addr)), \
3174 outp((iop_base) + IOPB_RAM_DATA, (byte)))
3176 /* Read word (2 bytes) from LRAM. */
3177 #define AdvReadWordLram(iop_base, addr, word) \
3178 do { \
3179 outpw((iop_base) + IOPW_RAM_ADDR, (addr)); \
3180 (word) = le16_to_cpu(inpw((iop_base) + IOPW_RAM_DATA)); \
3181 } while (0)
3183 /* Write word (2 bytes) to LRAM. */
3184 #define AdvWriteWordLram(iop_base, addr, word) \
3185 (outpw((iop_base) + IOPW_RAM_ADDR, (addr)), \
3186 outpw((iop_base) + IOPW_RAM_DATA, cpu_to_le16(word)))
3188 /* Write double word (4 bytes) to LRAM */
3189 /* Because of unspecified C language ordering don't use auto-increment. */
3190 #define AdvWriteDWordLram(iop_base, addr, dword) \
3191 ((outpw((iop_base) + IOPW_RAM_ADDR, (addr)), \
3192 outpw((iop_base) + IOPW_RAM_DATA, \
3193 cpu_to_le16((ushort) ((dword) & 0xFFFF)))), \
3194 (outpw((iop_base) + IOPW_RAM_ADDR, (addr) + 2), \
3195 outpw((iop_base) + IOPW_RAM_DATA, \
3196 cpu_to_le16((ushort) ((dword >> 16) & 0xFFFF)))))
3198 /* Read word (2 bytes) from LRAM assuming that the address is already set. */
3199 #define AdvReadWordAutoIncLram(iop_base) \
3200 (le16_to_cpu(inpw((iop_base) + IOPW_RAM_DATA)))
3202 /* Write word (2 bytes) to LRAM assuming that the address is already set. */
3203 #define AdvWriteWordAutoIncLram(iop_base, word) \
3204 (outpw((iop_base) + IOPW_RAM_DATA, cpu_to_le16(word)))
3206 #else /* version >= v1,3,0 */
3208 /* Read byte from a register. */
3209 #define AdvReadByteRegister(iop_base, reg_off) \
3210 (ADV_MEM_READB((iop_base) + (reg_off)))
3212 /* Write byte to a register. */
3213 #define AdvWriteByteRegister(iop_base, reg_off, byte) \
3214 (ADV_MEM_WRITEB((iop_base) + (reg_off), (byte)))
3216 /* Read word (2 bytes) from a register. */
3217 #define AdvReadWordRegister(iop_base, reg_off) \
3218 le16_to_cpu(ADV_MEM_READW((iop_base) + (reg_off)))
3220 /* Write word (2 bytes) to a register. */
3221 #define AdvWriteWordRegister(iop_base, reg_off, word) \
3222 (ADV_MEM_WRITEW((iop_base) + (reg_off), cpu_to_le16(word)))
3224 /* Read byte from LRAM. */
3225 #define AdvReadByteLram(iop_base, addr, byte) \
3226 do { \
3227 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
3228 (byte) = ADV_MEM_READB((iop_base) + IOPB_RAM_DATA); \
3229 } while (0)
3231 /* Write byte to LRAM. */
3232 #define AdvWriteByteLram(iop_base, addr, byte) \
3233 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3234 ADV_MEM_WRITEB((iop_base) + IOPB_RAM_DATA, (byte)))
3236 /* Read word (2 bytes) from LRAM. */
3237 #define AdvReadWordLram(iop_base, addr, word) \
3238 do { \
3239 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
3240 (word) = le16_to_cpu(ADV_MEM_READW((iop_base) + IOPW_RAM_DATA)); \
3241 } while (0)
3243 /* Write word (2 bytes) to LRAM. */
3244 #define AdvWriteWordLram(iop_base, addr, word) \
3245 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3246 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, cpu_to_le16(word)))
3248 /* Write double word (4 bytes) to LRAM */
3249 /* Because of unspecified C language ordering don't use auto-increment. */
3250 #define AdvWriteDWordLram(iop_base, addr, dword) \
3251 ((ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3252 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
3253 cpu_to_le16((ushort) ((dword) & 0xFFFF)))), \
3254 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr) + 2), \
3255 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
3256 cpu_to_le16((ushort) ((dword >> 16) & 0xFFFF)))))
3258 /* Read word (2 bytes) from LRAM assuming that the address is already set. */
3259 #define AdvReadWordAutoIncLram(iop_base) \
3260 le16_to_cpu(ADV_MEM_READW((iop_base) + IOPW_RAM_DATA))
3262 /* Write word (2 bytes) to LRAM assuming that the address is already set. */
3263 #define AdvWriteWordAutoIncLram(iop_base, word) \
3264 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, cpu_to_le16(word)))
3266 #endif /* version >= v1,3,0 */
3269 * Define macro to check for Condor signature.
3271 * Evaluate to ADV_TRUE if a Condor chip is found the specified port
3272 * address 'iop_base'. Otherwise evalue to ADV_FALSE.
3274 #define AdvFindSignature(iop_base) \
3275 (((AdvReadByteRegister((iop_base), IOPB_CHIP_ID_1) == \
3276 ADV_CHIP_ID_BYTE) && \
3277 (AdvReadWordRegister((iop_base), IOPW_CHIP_ID_0) == \
3278 ADV_CHIP_ID_WORD)) ? ADV_TRUE : ADV_FALSE)
3281 * Define macro to Return the version number of the chip at 'iop_base'.
3283 * The second parameter 'bus_type' is currently unused.
3285 #define AdvGetChipVersion(iop_base, bus_type) \
3286 AdvReadByteRegister((iop_base), IOPB_CHIP_TYPE_REV)
3289 * Abort an SRB in the chip's RISC Memory. The 'srb_ptr' argument must
3290 * match the ASC_SCSI_REQ_Q 'srb_ptr' field.
3292 * If the request has not yet been sent to the device it will simply be
3293 * aborted from RISC memory. If the request is disconnected it will be
3294 * aborted on reselection by sending an Abort Message to the target ID.
3296 * Return value:
3297 * ADV_TRUE(1) - Queue was successfully aborted.
3298 * ADV_FALSE(0) - Queue was not found on the active queue list.
3300 #define AdvAbortQueue(asc_dvc, scsiq) \
3301 AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_ABORT, \
3302 (ADV_DCNT) (scsiq))
3305 * Send a Bus Device Reset Message to the specified target ID.
3307 * All outstanding commands will be purged if sending the
3308 * Bus Device Reset Message is successful.
3310 * Return Value:
3311 * ADV_TRUE(1) - All requests on the target are purged.
3312 * ADV_FALSE(0) - Couldn't issue Bus Device Reset Message; Requests
3313 * are not purged.
3315 #define AdvResetDevice(asc_dvc, target_id) \
3316 AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_DEVICE_RESET, \
3317 (ADV_DCNT) (target_id))
3320 * SCSI Wide Type definition.
3322 #define ADV_SCSI_BIT_ID_TYPE ushort
3325 * AdvInitScsiTarget() 'cntl_flag' options.
3327 #define ADV_SCAN_LUN 0x01
3328 #define ADV_CAPINFO_NOLUN 0x02
3331 * Convert target id to target id bit mask.
3333 #define ADV_TID_TO_TIDMASK(tid) (0x01 << ((tid) & ADV_MAX_TID))
3336 * ASC_SCSI_REQ_Q 'done_status' and 'host_status' return values.
3339 #define QD_NO_STATUS 0x00 /* Request not completed yet. */
3340 #define QD_NO_ERROR 0x01
3341 #define QD_ABORTED_BY_HOST 0x02
3342 #define QD_WITH_ERROR 0x04
3344 #define QHSTA_NO_ERROR 0x00
3345 #define QHSTA_M_SEL_TIMEOUT 0x11
3346 #define QHSTA_M_DATA_OVER_RUN 0x12
3347 #define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
3348 #define QHSTA_M_QUEUE_ABORTED 0x15
3349 #define QHSTA_M_SXFR_SDMA_ERR 0x16 /* SXFR_STATUS SCSI DMA Error */
3350 #define QHSTA_M_SXFR_SXFR_PERR 0x17 /* SXFR_STATUS SCSI Bus Parity Error */
3351 #define QHSTA_M_RDMA_PERR 0x18 /* RISC PCI DMA parity error */
3352 #define QHSTA_M_SXFR_OFF_UFLW 0x19 /* SXFR_STATUS Offset Underflow */
3353 #define QHSTA_M_SXFR_OFF_OFLW 0x20 /* SXFR_STATUS Offset Overflow */
3354 #define QHSTA_M_SXFR_WD_TMO 0x21 /* SXFR_STATUS Watchdog Timeout */
3355 #define QHSTA_M_SXFR_DESELECTED 0x22 /* SXFR_STATUS Deselected */
3356 /* Note: QHSTA_M_SXFR_XFR_OFLW is identical to QHSTA_M_DATA_OVER_RUN. */
3357 #define QHSTA_M_SXFR_XFR_OFLW 0x12 /* SXFR_STATUS Transfer Overflow */
3358 #define QHSTA_M_SXFR_XFR_PH_ERR 0x24 /* SXFR_STATUS Transfer Phase Error */
3359 #define QHSTA_M_SXFR_UNKNOWN_ERROR 0x25 /* SXFR_STATUS Unknown Error */
3360 #define QHSTA_M_SCSI_BUS_RESET 0x30 /* Request aborted from SBR */
3361 #define QHSTA_M_SCSI_BUS_RESET_UNSOL 0x31 /* Request aborted from unsol. SBR */
3362 #define QHSTA_M_BUS_DEVICE_RESET 0x32 /* Request aborted from BDR */
3363 #define QHSTA_M_DIRECTION_ERR 0x35 /* Data Phase mismatch */
3364 #define QHSTA_M_DIRECTION_ERR_HUNG 0x36 /* Data Phase mismatch and bus hang */
3365 #define QHSTA_M_WTM_TIMEOUT 0x41
3366 #define QHSTA_M_BAD_CMPL_STATUS_IN 0x42
3367 #define QHSTA_M_NO_AUTO_REQ_SENSE 0x43
3368 #define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
3369 #define QHSTA_M_INVALID_DEVICE 0x45 /* Bad target ID */
3370 #define QHSTA_M_FROZEN_TIDQ 0x46 /* TID Queue frozen. */
3371 #define QHSTA_M_SGBACKUP_ERROR 0x47 /* Scatter-Gather backup error */
3375 * Default EEPROM Configuration structure defined in a_init.c.
3377 extern ADVEEP_3550_CONFIG Default_3550_EEPROM_Config;
3378 extern ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config;
3381 * DvcGetPhyAddr() flag arguments
3383 #define ADV_IS_SCSIQ_FLAG 0x01 /* 'addr' is ASC_SCSI_REQ_Q pointer */
3384 #define ADV_ASCGETSGLIST_VADDR 0x02 /* 'addr' is AscGetSGList() virtual addr */
3385 #define ADV_IS_SENSE_FLAG 0x04 /* 'addr' is sense virtual pointer */
3386 #define ADV_IS_DATA_FLAG 0x08 /* 'addr' is data virtual pointer */
3387 #define ADV_IS_SGLIST_FLAG 0x10 /* 'addr' is sglist virtual pointer */
3388 #define ADV_IS_CARRIER_FLAG 0x20 /* 'addr' is ADV_CARR_T pointer */
3390 /* Return the address that is aligned at the next doubleword >= to 'addr'. */
3391 #define ADV_DWALIGN(addr) (((ulong) (addr) + 0x3) & ~0x3)
3392 #define ADV_16BALIGN(addr) (((ulong) (addr) + 0xF) & ~0xF)
3395 * Total contiguous memory needed for driver SG blocks.
3397 * ADV_MAX_SG_LIST must be defined by a driver. It is the maximum
3398 * number of scatter-gather elements the driver supports in a
3399 * single request.
3402 #ifndef ADV_MAX_SG_LIST
3403 Forced Error: Driver must define ADV_MAX_SG_LIST.
3404 #endif /* ADV_MAX_SG_LIST */
3406 #define ADV_SG_LIST_MAX_BYTE_SIZE \
3407 (sizeof(ADV_SG_BLOCK) * \
3408 ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK))
3410 typedef struct {
3411 uchar peri_dvc_type : 5; /* peripheral device type */
3412 uchar peri_qualifier : 3; /* peripheral qualifier */
3413 uchar dvc_type_modifier : 7; /* device type modifier (for SCSI I) */
3414 uchar rmb : 1; /* RMB - removable medium bit */
3415 uchar ansi_apr_ver : 3; /* ANSI approved version */
3416 uchar ecma_ver : 3; /* ECMA version */
3417 uchar iso_ver : 2; /* ISO version */
3418 uchar rsp_data_fmt : 4; /* response data format */
3419 /* 0 SCSI 1 */
3420 /* 1 CCS */
3421 /* 2 SCSI-2 */
3422 /* 3-F reserved */
3423 uchar res1 : 2; /* reserved */
3424 uchar TemIOP : 1; /* terminate I/O process bit (see 5.6.22) */
3425 uchar aenc : 1; /* asynch. event notification (processor) */
3426 uchar add_len; /* additional length */
3427 uchar res2; /* reserved */
3428 uchar res3; /* reserved */
3429 uchar StfRe : 1; /* soft reset implemented */
3430 uchar CmdQue : 1; /* command queuing */
3431 uchar res4 : 1; /* reserved */
3432 uchar Linked : 1; /* linked command for this logical unit */
3433 uchar Sync : 1; /* synchronous data transfer */
3434 uchar WBus16 : 1; /* wide bus 16 bit data transfer */
3435 uchar WBus32 : 1; /* wide bus 32 bit data transfer */
3436 uchar RelAdr : 1; /* relative addressing mode */
3437 uchar vendor_id[8]; /* vendor identification */
3438 uchar product_id[16]; /* product identification */
3439 uchar product_rev_level[4]; /* product revision level */
3440 uchar vendor_specific[20]; /* vendor specific */
3441 uchar IUS : 1; /* information unit supported */
3442 uchar QAS : 1; /* quick arbitrate supported */
3443 uchar Clocking : 2; /* clocking field */
3444 uchar res5 : 4; /* reserved */
3445 uchar res6; /* reserved */
3446 } ADV_SCSI_INQUIRY; /* 58 bytes */
3450 * --- Driver Constants and Macros
3453 #define ASC_NUM_BOARD_SUPPORTED 16
3454 #define ASC_NUM_IOPORT_PROBE 4
3455 #define ASC_NUM_BUS 4
3457 /* Reference Scsi_Host hostdata */
3458 #define ASC_BOARDP(host) ((asc_board_t *) &((host)->hostdata))
3460 /* asc_board_t flags */
3461 #define ASC_HOST_IN_RESET 0x01
3462 #define ASC_HOST_IN_ABORT 0x02
3463 #define ASC_IS_WIDE_BOARD 0x04 /* AdvanSys Wide Board */
3464 #define ASC_SELECT_QUEUE_DEPTHS 0x08
3466 #define ASC_NARROW_BOARD(boardp) (((boardp)->flags & ASC_IS_WIDE_BOARD) == 0)
3467 #define ASC_WIDE_BOARD(boardp) ((boardp)->flags & ASC_IS_WIDE_BOARD)
3469 #define NO_ISA_DMA 0xff /* No ISA DMA Channel Used */
3472 * If the Linux kernel version supports freeing initialization code
3473 * and data after loading, define macros for this purpose. These macros
3474 * are not used when the driver is built as a module, cf. linux/init.h.
3476 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,23)
3477 #define ASC_INITFUNC(type, func) type func
3478 #define ASC_INITDATA
3479 #define ASC_INIT
3480 #else /* version >= v2.1.23 */
3481 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,3,16)
3482 #define ASC_INITFUNC(type, func) __initfunc(type func)
3483 #else /* version >= v2.3.16 */
3484 #define ASC_INITFUNC(type, func) type __init func
3485 #endif /* version >= v2.3.16 */
3486 #define ASC_INITDATA __initdata
3487 #define ASC_INIT __init
3488 #endif /* version >= v2.1.23 */
3490 #define ASC_INFO_SIZE 128 /* advansys_info() line size */
3492 /* /proc/scsi/advansys/[0...] related definitions */
3493 #define ASC_PRTBUF_SIZE 2048
3494 #define ASC_PRTLINE_SIZE 160
3496 #define ASC_PRT_NEXT() \
3497 if (cp) { \
3498 totlen += len; \
3499 leftlen -= len; \
3500 if (leftlen == 0) { \
3501 return totlen; \
3503 cp += len; \
3506 #define ASC_MIN(a, b) (((a) < (b)) ? (a) : (b))
3508 /* Asc Library return codes */
3509 #define ASC_TRUE 1
3510 #define ASC_FALSE 0
3511 #define ASC_NOERROR 1
3512 #define ASC_BUSY 0
3513 #define ASC_ERROR (-1)
3515 /* Scsi_Cmnd function return codes */
3516 #define STATUS_BYTE(byte) (byte)
3517 #define MSG_BYTE(byte) ((byte) << 8)
3518 #define HOST_BYTE(byte) ((byte) << 16)
3519 #define DRIVER_BYTE(byte) ((byte) << 24)
3522 * The following definitions and macros are OS independent interfaces to
3523 * the queue functions:
3524 * REQ - SCSI request structure
3525 * REQP - pointer to SCSI request structure
3526 * REQPTID(reqp) - reqp's target id
3527 * REQPNEXT(reqp) - reqp's next pointer
3528 * REQPNEXTP(reqp) - pointer to reqp's next pointer
3529 * REQPTIME(reqp) - reqp's time stamp value
3530 * REQTIMESTAMP() - system time stamp value
3532 typedef Scsi_Cmnd REQ, *REQP;
3533 #define REQPNEXT(reqp) ((REQP) ((reqp)->host_scribble))
3534 #define REQPNEXTP(reqp) ((REQP *) &((reqp)->host_scribble))
3535 #define REQPTID(reqp) ((reqp)->target)
3536 #define REQPTIME(reqp) ((reqp)->SCp.this_residual)
3537 #define REQTIMESTAMP() (jiffies)
3539 #define REQTIMESTAT(function, ascq, reqp, tid) \
3542 * If the request time stamp is less than the system time stamp, then \
3543 * maybe the system time stamp wrapped. Set the request time to zero.\
3544 */ \
3545 if (REQPTIME(reqp) <= REQTIMESTAMP()) { \
3546 REQPTIME(reqp) = REQTIMESTAMP() - REQPTIME(reqp); \
3547 } else { \
3548 /* Indicate an error occurred with the assertion. */ \
3549 ASC_ASSERT(REQPTIME(reqp) <= REQTIMESTAMP()); \
3550 REQPTIME(reqp) = 0; \
3552 /* Handle first minimum time case without external initialization. */ \
3553 if (((ascq)->q_tot_cnt[tid] == 1) || \
3554 (REQPTIME(reqp) < (ascq)->q_min_tim[tid])) { \
3555 (ascq)->q_min_tim[tid] = REQPTIME(reqp); \
3556 ASC_DBG3(1, "%s: new q_min_tim[%d] %u\n", \
3557 (function), (tid), (ascq)->q_min_tim[tid]); \
3559 if (REQPTIME(reqp) > (ascq)->q_max_tim[tid]) { \
3560 (ascq)->q_max_tim[tid] = REQPTIME(reqp); \
3561 ASC_DBG3(1, "%s: new q_max_tim[%d] %u\n", \
3562 (function), tid, (ascq)->q_max_tim[tid]); \
3564 (ascq)->q_tot_tim[tid] += REQPTIME(reqp); \
3565 /* Reset the time stamp field. */ \
3566 REQPTIME(reqp) = 0; \
3569 /* asc_enqueue() flags */
3570 #define ASC_FRONT 1
3571 #define ASC_BACK 2
3573 /* asc_dequeue_list() argument */
3574 #define ASC_TID_ALL (-1)
3576 /* Return non-zero, if the queue is empty. */
3577 #define ASC_QUEUE_EMPTY(ascq) ((ascq)->q_tidmask == 0)
3579 /* PCI configuration declarations */
3581 #define PCI_BASE_CLASS_PREDEFINED 0x00
3582 #define PCI_BASE_CLASS_MASS_STORAGE 0x01
3583 #define PCI_BASE_CLASS_NETWORK 0x02
3584 #define PCI_BASE_CLASS_DISPLAY 0x03
3585 #define PCI_BASE_CLASS_MULTIMEDIA 0x04
3586 #define PCI_BASE_CLASS_MEMORY_CONTROLLER 0x05
3587 #define PCI_BASE_CLASS_BRIDGE_DEVICE 0x06
3589 /* MASS STORAGE */
3590 #define PCI_SUB_CLASS_SCSI_CONTROLLER 0x00
3591 #define PCI_SUB_CLASS_IDE_CONTROLLER 0x01
3592 #define PCI_SUB_CLASS_FLOPPY_DISK_CONTROLLER 0x02
3593 #define PCI_SUB_CLASS_IPI_BUS_CONTROLLER 0x03
3594 #define PCI_SUB_CLASS_OTHER_MASS_CONTROLLER 0x80
3596 /* NETWORK CONTROLLER */
3597 #define PCI_SUB_CLASS_ETHERNET_CONTROLLER 0x00
3598 #define PCI_SUB_CLASS_TOKEN_RING_CONTROLLER 0x01
3599 #define PCI_SUB_CLASS_FDDI_CONTROLLER 0x02
3600 #define PCI_SUB_CLASS_OTHER_NETWORK_CONTROLLER 0x80
3602 /* DISPLAY CONTROLLER */
3603 #define PCI_SUB_CLASS_VGA_CONTROLLER 0x00
3604 #define PCI_SUB_CLASS_XGA_CONTROLLER 0x01
3605 #define PCI_SUB_CLASS_OTHER_DISPLAY_CONTROLLER 0x80
3607 /* MULTIMEDIA CONTROLLER */
3608 #define PCI_SUB_CLASS_VIDEO_DEVICE 0x00
3609 #define PCI_SUB_CLASS_AUDIO_DEVICE 0x01
3610 #define PCI_SUB_CLASS_OTHER_MULTIMEDIA_DEVICE 0x80
3612 /* MEMORY CONTROLLER */
3613 #define PCI_SUB_CLASS_RAM_CONTROLLER 0x00
3614 #define PCI_SUB_CLASS_FLASH_CONTROLLER 0x01
3615 #define PCI_SUB_CLASS_OTHER_MEMORY_CONTROLLER 0x80
3617 /* BRIDGE CONTROLLER */
3618 #define PCI_SUB_CLASS_HOST_BRIDGE_CONTROLLER 0x00
3619 #define PCI_SUB_CLASS_ISA_BRIDGE_CONTROLLER 0x01
3620 #define PCI_SUB_CLASS_EISA_BRIDGE_CONTROLLER 0x02
3621 #define PCI_SUB_CLASS_MC_BRIDGE_CONTROLLER 0x03
3622 #define PCI_SUB_CLASS_PCI_TO_PCI_BRIDGE_CONTROLLER 0x04
3623 #define PCI_SUB_CLASS_PCMCIA_BRIDGE_CONTROLLER 0x05
3624 #define PCI_SUB_CLASS_OTHER_BRIDGE_CONTROLLER 0x80
3626 #define PCI_MAX_SLOT 0x1F
3627 #define PCI_MAX_BUS 0xFF
3628 #define PCI_IOADDRESS_MASK 0xFFFE
3629 #define ASC_PCI_VENDORID 0x10CD
3630 #define ASC_PCI_DEVICE_ID_CNT 5 /* PCI Device ID count. */
3631 #define ASC_PCI_DEVICE_ID_1100 0x1100
3632 #define ASC_PCI_DEVICE_ID_1200 0x1200
3633 #define ASC_PCI_DEVICE_ID_1300 0x1300
3634 #define ASC_PCI_DEVICE_ID_2300 0x2300 /* ASC-3550 */
3635 #define ASC_PCI_DEVICE_ID_2500 0x2500 /* ASC-38C0800 */
3637 /* PCI IO Port Addresses to generate special cycle */
3639 #define PCI_CONFIG_ADDRESS_MECH1 0x0CF8
3640 #define PCI_CONFIG_DATA_MECH1 0x0CFC
3642 #define PCI_CONFIG_FORWARD_REGISTER 0x0CFA /* 0=type 0; 1=type 1; */
3644 #define PCI_CONFIG_BUS_NUMBER_MASK 0x00FF0000
3645 #define PCI_CONFIG_DEVICE_FUNCTION_MASK 0x0000FF00
3646 #define PCI_CONFIG_REGISTER_NUMBER_MASK 0x000000F8
3648 #define PCI_DEVICE_FOUND 0x0000
3649 #define PCI_DEVICE_NOT_FOUND 0xffff
3651 #define SUBCLASS_OFFSET 0x0A
3652 #define CLASSCODE_OFFSET 0x0B
3653 #define VENDORID_OFFSET 0x00
3654 #define DEVICEID_OFFSET 0x02
3656 #ifndef ADVANSYS_STATS
3657 #define ASC_STATS(shp, counter)
3658 #define ASC_STATS_ADD(shp, counter, count)
3659 #else /* ADVANSYS_STATS */
3660 #define ASC_STATS(shp, counter) \
3661 (ASC_BOARDP(shp)->asc_stats.counter++)
3663 #define ASC_STATS_ADD(shp, counter, count) \
3664 (ASC_BOARDP(shp)->asc_stats.counter += (count))
3665 #endif /* ADVANSYS_STATS */
3667 #define ASC_CEILING(val, unit) (((val) + ((unit) - 1))/(unit))
3669 /* If the result wraps when calculating tenths, return 0. */
3670 #define ASC_TENTHS(num, den) \
3671 (((10 * ((num)/(den))) > (((num) * 10)/(den))) ? \
3672 0 : ((((num) * 10)/(den)) - (10 * ((num)/(den)))))
3675 * Display a message to the console.
3677 #define ASC_PRINT(s) \
3679 printk("advansys: "); \
3680 printk(s); \
3683 #define ASC_PRINT1(s, a1) \
3685 printk("advansys: "); \
3686 printk((s), (a1)); \
3689 #define ASC_PRINT2(s, a1, a2) \
3691 printk("advansys: "); \
3692 printk((s), (a1), (a2)); \
3695 #define ASC_PRINT3(s, a1, a2, a3) \
3697 printk("advansys: "); \
3698 printk((s), (a1), (a2), (a3)); \
3701 #define ASC_PRINT4(s, a1, a2, a3, a4) \
3703 printk("advansys: "); \
3704 printk((s), (a1), (a2), (a3), (a4)); \
3708 #ifndef ADVANSYS_DEBUG
3710 #define ASC_DBG(lvl, s)
3711 #define ASC_DBG1(lvl, s, a1)
3712 #define ASC_DBG2(lvl, s, a1, a2)
3713 #define ASC_DBG3(lvl, s, a1, a2, a3)
3714 #define ASC_DBG4(lvl, s, a1, a2, a3, a4)
3715 #define ASC_DBG_PRT_SCSI_HOST(lvl, s)
3716 #define ASC_DBG_PRT_SCSI_CMND(lvl, s)
3717 #define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp)
3718 #define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
3719 #define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone)
3720 #define ADV_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
3721 #define ASC_DBG_PRT_HEX(lvl, name, start, length)
3722 #define ASC_DBG_PRT_CDB(lvl, cdb, len)
3723 #define ASC_DBG_PRT_SENSE(lvl, sense, len)
3724 #define ASC_DBG_PRT_INQUIRY(lvl, inq, len)
3726 #else /* ADVANSYS_DEBUG */
3729 * Debugging Message Levels:
3730 * 0: Errors Only
3731 * 1: High-Level Tracing
3732 * 2-N: Verbose Tracing
3735 #define ASC_DBG(lvl, s) \
3737 if (asc_dbglvl >= (lvl)) { \
3738 printk(s); \
3742 #define ASC_DBG1(lvl, s, a1) \
3744 if (asc_dbglvl >= (lvl)) { \
3745 printk((s), (a1)); \
3749 #define ASC_DBG2(lvl, s, a1, a2) \
3751 if (asc_dbglvl >= (lvl)) { \
3752 printk((s), (a1), (a2)); \
3756 #define ASC_DBG3(lvl, s, a1, a2, a3) \
3758 if (asc_dbglvl >= (lvl)) { \
3759 printk((s), (a1), (a2), (a3)); \
3763 #define ASC_DBG4(lvl, s, a1, a2, a3, a4) \
3765 if (asc_dbglvl >= (lvl)) { \
3766 printk((s), (a1), (a2), (a3), (a4)); \
3770 #define ASC_DBG_PRT_SCSI_HOST(lvl, s) \
3772 if (asc_dbglvl >= (lvl)) { \
3773 asc_prt_scsi_host(s); \
3777 #define ASC_DBG_PRT_SCSI_CMND(lvl, s) \
3779 if (asc_dbglvl >= (lvl)) { \
3780 asc_prt_scsi_cmnd(s); \
3784 #define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp) \
3786 if (asc_dbglvl >= (lvl)) { \
3787 asc_prt_asc_scsi_q(scsiqp); \
3791 #define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone) \
3793 if (asc_dbglvl >= (lvl)) { \
3794 asc_prt_asc_qdone_info(qdone); \
3798 #define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp) \
3800 if (asc_dbglvl >= (lvl)) { \
3801 asc_prt_adv_scsi_req_q(scsiqp); \
3805 #define ASC_DBG_PRT_HEX(lvl, name, start, length) \
3807 if (asc_dbglvl >= (lvl)) { \
3808 asc_prt_hex((name), (start), (length)); \
3812 #define ASC_DBG_PRT_CDB(lvl, cdb, len) \
3813 ASC_DBG_PRT_HEX((lvl), "CDB", (uchar *) (cdb), (len));
3815 #define ASC_DBG_PRT_SENSE(lvl, sense, len) \
3816 ASC_DBG_PRT_HEX((lvl), "SENSE", (uchar *) (sense), (len));
3818 #define ASC_DBG_PRT_INQUIRY(lvl, inq, len) \
3819 ASC_DBG_PRT_HEX((lvl), "INQUIRY", (uchar *) (inq), (len));
3820 #endif /* ADVANSYS_DEBUG */
3822 #ifndef ADVANSYS_ASSERT
3823 #define ASC_ASSERT(a)
3824 #else /* ADVANSYS_ASSERT */
3826 #define ASC_ASSERT(a) \
3828 if (!(a)) { \
3829 printk("ASC_ASSERT() Failure: file %s, line %d\n", \
3830 __FILE__, __LINE__); \
3834 #endif /* ADVANSYS_ASSERT */
3838 * --- Driver Structures
3841 #ifdef ADVANSYS_STATS
3843 /* Per board statistics structure */
3844 struct asc_stats {
3845 /* Driver Entrypoint Statistics */
3846 ADV_DCNT command; /* # calls to advansys_command() */
3847 ADV_DCNT queuecommand; /* # calls to advansys_queuecommand() */
3848 ADV_DCNT abort; /* # calls to advansys_abort() */
3849 ADV_DCNT reset; /* # calls to advansys_reset() */
3850 ADV_DCNT biosparam; /* # calls to advansys_biosparam() */
3851 ADV_DCNT interrupt; /* # advansys_interrupt() calls */
3852 ADV_DCNT callback; /* # calls to asc/adv_isr_callback() */
3853 ADV_DCNT done; /* # calls to request's scsi_done function */
3854 ADV_DCNT build_error; /* # asc/adv_build_req() ASC_ERROR returns. */
3855 ADV_DCNT adv_build_noreq; /* # adv_build_req() adv_req_t alloc. fail. */
3856 ADV_DCNT adv_build_nosg; /* # adv_build_req() adv_sgblk_t alloc. fail. */
3857 /* AscExeScsiQueue()/AdvExeScsiQueue() Statistics */
3858 ADV_DCNT exe_noerror; /* # ASC_NOERROR returns. */
3859 ADV_DCNT exe_busy; /* # ASC_BUSY returns. */
3860 ADV_DCNT exe_error; /* # ASC_ERROR returns. */
3861 ADV_DCNT exe_unknown; /* # unknown returns. */
3862 /* Data Transfer Statistics */
3863 ADV_DCNT cont_cnt; /* # non-scatter-gather I/O requests received */
3864 ADV_DCNT cont_xfer; /* # contiguous transfer 512-bytes */
3865 ADV_DCNT sg_cnt; /* # scatter-gather I/O requests received */
3866 ADV_DCNT sg_elem; /* # scatter-gather elements */
3867 ADV_DCNT sg_xfer; /* # scatter-gather transfer 512-bytes */
3869 #endif /* ADVANSYS_STATS */
3872 * Request queuing structure
3874 typedef struct asc_queue {
3875 ADV_SCSI_BIT_ID_TYPE q_tidmask; /* queue mask */
3876 REQP q_first[ADV_MAX_TID+1]; /* first queued request */
3877 REQP q_last[ADV_MAX_TID+1]; /* last queued request */
3878 #ifdef ADVANSYS_STATS
3879 short q_cur_cnt[ADV_MAX_TID+1]; /* current queue count */
3880 short q_max_cnt[ADV_MAX_TID+1]; /* maximum queue count */
3881 ADV_DCNT q_tot_cnt[ADV_MAX_TID+1]; /* total enqueue count */
3882 ADV_DCNT q_tot_tim[ADV_MAX_TID+1]; /* total time queued */
3883 ushort q_max_tim[ADV_MAX_TID+1]; /* maximum time queued */
3884 ushort q_min_tim[ADV_MAX_TID+1]; /* minimum time queued */
3885 #endif /* ADVANSYS_STATS */
3886 } asc_queue_t;
3889 * Adv Library Request Structures
3891 * The following two structures are used to process Wide Board requests.
3893 * The ADV_SCSI_REQ_Q structure in adv_req_t is passed to the Adv Library
3894 * and microcode with the ADV_SCSI_REQ_Q field 'srb_ptr' pointing to the
3895 * adv_req_t. The adv_req_t structure 'cmndp' field in turn points to the
3896 * Mid-Level SCSI request structure.
3898 * Zero or more ADV_SG_BLOCK are used with each ADV_SCSI_REQ_Q. Each
3899 * ADV_SG_BLOCK structure holds 15 scatter-gather elements. Under Linux
3900 * up to 255 scatter-gather elements may be used per request or
3901 * ADV_SCSI_REQ_Q.
3903 typedef struct adv_sgblk {
3904 ADV_SG_BLOCK sg_block; /* Sgblock structure. */
3905 uchar align2[4]; /* Sgblock structure padding. */
3906 struct adv_sgblk *next_sgblkp; /* Next scatter-gather structure. */
3907 } adv_sgblk_t;
3909 typedef struct adv_req {
3910 ADV_SCSI_REQ_Q scsi_req_q; /* Adv Library request structure. */
3911 uchar align1[4]; /* Request structure padding. */
3912 Scsi_Cmnd *cmndp; /* Mid-Level SCSI command pointer. */
3913 adv_sgblk_t *sgblkp; /* Adv Library scatter-gather pointer. */
3914 struct adv_req *next_reqp; /* Next Request Structure. */
3915 } adv_req_t;
3918 * Structure allocated for each board.
3920 * This structure is allocated by scsi_register() at the end
3921 * of the 'Scsi_Host' structure starting at the 'hostdata'
3922 * field. It is guaranteed to be allocated from DMA-able memory.
3924 typedef struct asc_board {
3925 int id; /* Board Id */
3926 uint flags; /* Board flags */
3927 union {
3928 ASC_DVC_VAR asc_dvc_var; /* Narrow board */
3929 ADV_DVC_VAR adv_dvc_var; /* Wide board */
3930 } dvc_var;
3931 union {
3932 ASC_DVC_CFG asc_dvc_cfg; /* Narrow board */
3933 ADV_DVC_CFG adv_dvc_cfg; /* Wide board */
3934 } dvc_cfg;
3935 asc_queue_t active; /* Active command queue */
3936 asc_queue_t waiting; /* Waiting command queue */
3937 asc_queue_t done; /* Done command queue */
3938 ADV_SCSI_BIT_ID_TYPE init_tidmask; /* Target init./valid mask */
3939 Scsi_Device *device[ADV_MAX_TID+1]; /* Mid-Level Scsi Device */
3940 ushort reqcnt[ADV_MAX_TID+1]; /* Starvation request count */
3941 ADV_SCSI_BIT_ID_TYPE queue_full; /* Queue full mask */
3942 ushort queue_full_cnt[ADV_MAX_TID+1]; /* Queue full count */
3943 union {
3944 ASCEEP_CONFIG asc_eep; /* Narrow EEPROM config. */
3945 ADVEEP_3550_CONFIG adv_3550_eep; /* 3550 EEPROM config. */
3946 ADVEEP_38C0800_CONFIG adv_38C0800_eep; /* 38C0800 EEPROM config. */
3947 } eep_config;
3948 ulong last_reset; /* Saved last reset time */
3949 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
3950 /* /proc/scsi/advansys/[0...] */
3951 char *prtbuf; /* Statistics Print Buffer */
3952 #endif /* version >= v1.3.0 */
3953 #ifdef ADVANSYS_STATS
3954 struct asc_stats asc_stats; /* Board statistics */
3955 #endif /* ADVANSYS_STATS */
3957 * The following fields are used only for Narrow Boards.
3959 /* The following three structures must be in DMA-able memory. */
3960 ASC_SCSI_REQ_Q scsireqq;
3961 ASC_CAP_INFO cap_info;
3962 ASC_SCSI_INQUIRY inquiry;
3963 uchar sdtr_data[ASC_MAX_TID+1]; /* SDTR information */
3965 * The following fields are used only for Wide Boards.
3967 void *ioremap_addr; /* I/O Memory remap address. */
3968 ushort ioport; /* I/O Port address. */
3969 ADV_CARR_T *orig_carrp; /* ADV_CARR_T memory block. */
3970 adv_req_t *orig_reqp; /* adv_req_t memory block. */
3971 adv_req_t *adv_reqp; /* Request structures. */
3972 adv_sgblk_t *adv_sgblkp; /* Scatter-gather structures. */
3973 ushort bios_signature; /* BIOS Signature. */
3974 ushort bios_version; /* BIOS Version. */
3975 ushort bios_codeseg; /* BIOS Code Segment. */
3976 ushort bios_codelen; /* BIOS Code Segment Length. */
3977 } asc_board_t;
3980 * PCI configuration structures
3982 typedef struct _PCI_DATA_
3984 uchar type;
3985 uchar bus;
3986 uchar slot;
3987 uchar func;
3988 uchar offset;
3989 } PCI_DATA;
3991 typedef struct _PCI_DEVICE_
3993 ushort vendorID;
3994 ushort deviceID;
3995 ushort slotNumber;
3996 ushort slotFound;
3997 uchar busNumber;
3998 uchar maxBusNumber;
3999 uchar devFunc;
4000 ushort startSlot;
4001 ushort endSlot;
4002 uchar bridge;
4003 uchar type;
4004 } PCI_DEVICE;
4006 typedef struct _PCI_CONFIG_SPACE_
4008 ushort vendorID;
4009 ushort deviceID;
4010 ushort command;
4011 ushort status;
4012 uchar revision;
4013 uchar classCode[3];
4014 uchar cacheSize;
4015 uchar latencyTimer;
4016 uchar headerType;
4017 uchar bist;
4018 ADV_PADDR baseAddress[6];
4019 ushort reserved[4];
4020 ADV_PADDR optionRomAddr;
4021 ushort reserved2[4];
4022 uchar irqLine;
4023 uchar irqPin;
4024 uchar minGnt;
4025 uchar maxLatency;
4026 } PCI_CONFIG_SPACE;
4030 * --- Driver Data
4033 /* Note: All driver global data should be initialized. */
4035 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,3,28) && \
4036 LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
4037 struct proc_dir_entry proc_scsi_advansys =
4039 PROC_SCSI_ADVANSYS, /* unsigned short low_ino */
4040 8, /* unsigned short namelen */
4041 "advansys", /* const char *name */
4042 S_IFDIR | S_IRUGO | S_IXUGO, /* mode_t mode */
4043 2 /* nlink_t nlink */
4045 #endif /* v2.3.28 > version >= v1.3.0 */
4047 /* Number of boards detected in system. */
4048 STATIC int asc_board_count = 0;
4049 STATIC struct Scsi_Host *asc_host[ASC_NUM_BOARD_SUPPORTED] = { 0 };
4051 /* Overrun buffer shared between all boards. */
4052 STATIC uchar overrun_buf[ASC_OVERRUN_BSIZE] = { 0 };
4055 * Global structures required to issue a command.
4057 STATIC ASC_SCSI_Q asc_scsi_q = { { 0 } };
4058 STATIC ASC_SG_HEAD asc_sg_head = { 0 };
4060 /* List of supported bus types. */
4061 STATIC ushort asc_bus[ASC_NUM_BUS] ASC_INITDATA = {
4062 ASC_IS_ISA,
4063 ASC_IS_VL,
4064 ASC_IS_EISA,
4065 ASC_IS_PCI,
4068 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
4069 #ifdef ASC_CONFIG_PCI
4070 STATIC int pci_scan_method ASC_INITDATA = -1;
4071 #endif /* ASC_CONFIG_PCI */
4072 #endif /* version < v2.1.93 */
4075 * Used with the LILO 'advansys' option to eliminate or
4076 * limit I/O port probing at boot time, cf. advansys_setup().
4078 STATIC int asc_iopflag = ASC_FALSE;
4079 STATIC int asc_ioport[ASC_NUM_IOPORT_PROBE] = { 0, 0, 0, 0 };
4081 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0)
4083 * In kernels earlier than v1.3.0, kmalloc() does not work
4084 * during driver initialization. Therefore statically declare
4085 * 16 elements of each structure. v1.3.0 kernels will probably
4086 * not need any more than this number.
4088 uchar adv_carr_buf[20 * sizeof(ADV_CARR_T)] = { 0 };
4089 uchar adv_req_buf[16 * sizeof(adv_req_t)] = { 0 };
4090 #define ADV_SGBLK_BUF_CNT 32
4091 uchar adv_sgblk_buf[ADV_SGBLK_BUF_CNT * sizeof(adv_sgblk_t)] = { 0 };
4092 #endif /* version >= v1,3,0 */
4094 #ifdef ADVANSYS_DEBUG
4095 STATIC char *
4096 asc_bus_name[ASC_NUM_BUS] = {
4097 "ASC_IS_ISA",
4098 "ASC_IS_VL",
4099 "ASC_IS_EISA",
4100 "ASC_IS_PCI",
4103 STATIC int asc_dbglvl = 2;
4104 #endif /* ADVANSYS_DEBUG */
4106 /* Declaration for Asc Library internal data referenced by driver. */
4107 STATIC PortAddr _asc_def_iop_base[];
4111 * --- Driver Function Prototypes
4113 * advansys.h contains function prototypes for functions global to Linux.
4116 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
4117 STATIC int asc_proc_copy(off_t, off_t, char *, int , char *, int);
4118 #endif /* version >= v1.3.0 */
4119 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,70)
4120 STATIC void advansys_interrupt(int, struct pt_regs *);
4121 #else /* version >= v1.3.70 */
4122 STATIC void advansys_interrupt(int, void *, struct pt_regs *);
4123 #endif /* version >= v1.3.70 */
4124 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
4125 STATIC void advansys_select_queue_depths(struct Scsi_Host *,
4126 Scsi_Device *);
4127 #endif /* version >= v1.3.89 */
4128 STATIC void advansys_command_done(Scsi_Cmnd *);
4129 STATIC void asc_scsi_done_list(Scsi_Cmnd *);
4130 STATIC int asc_execute_scsi_cmnd(Scsi_Cmnd *);
4131 STATIC int asc_build_req(asc_board_t *, Scsi_Cmnd *);
4132 STATIC int adv_build_req(asc_board_t *, Scsi_Cmnd *, ADV_SCSI_REQ_Q **);
4133 STATIC int adv_get_sglist(asc_board_t *, adv_req_t *, Scsi_Cmnd *);
4134 STATIC void asc_isr_callback(ASC_DVC_VAR *, ASC_QDONE_INFO *);
4135 STATIC void adv_isr_callback(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
4136 STATIC void adv_async_callback(ADV_DVC_VAR *, uchar);
4137 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
4138 #ifdef ASC_CONFIG_PCI
4139 STATIC int asc_srch_pci_dev(PCI_DEVICE *);
4140 STATIC uchar asc_scan_method(void);
4141 STATIC int asc_pci_find_dev(PCI_DEVICE *);
4142 STATIC void asc_get_pci_cfg(PCI_DEVICE *, PCI_CONFIG_SPACE *);
4143 STATIC ushort asc_get_cfg_word(PCI_DATA *);
4144 STATIC uchar asc_get_cfg_byte(PCI_DATA *);
4145 STATIC void asc_put_cfg_byte(PCI_DATA *, uchar);
4146 #endif /* ASC_CONFIG_PCI */
4147 #endif /* version < v2.1.93 */
4148 STATIC void asc_enqueue(asc_queue_t *, REQP, int);
4149 STATIC REQP asc_dequeue(asc_queue_t *, int);
4150 STATIC REQP asc_dequeue_list(asc_queue_t *, REQP *, int);
4151 STATIC int asc_rmqueue(asc_queue_t *, REQP);
4152 STATIC int asc_isqueued(asc_queue_t *, REQP);
4153 STATIC void asc_execute_queue(asc_queue_t *);
4154 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
4155 STATIC int asc_prt_board_devices(struct Scsi_Host *, char *, int);
4156 STATIC int asc_prt_adv_bios(struct Scsi_Host *, char *, int);
4157 STATIC int asc_get_eeprom_string(ushort *serialnum, uchar *cp);
4158 STATIC int asc_prt_asc_board_eeprom(struct Scsi_Host *, char *, int);
4159 STATIC int asc_prt_adv_board_eeprom(struct Scsi_Host *, char *, int);
4160 STATIC int asc_prt_driver_conf(struct Scsi_Host *, char *, int);
4161 STATIC int asc_prt_asc_board_info(struct Scsi_Host *, char *, int);
4162 STATIC int asc_prt_adv_board_info(struct Scsi_Host *, char *, int);
4163 STATIC int asc_prt_line(char *, int, char *fmt, ...);
4164 #endif /* version >= v1.3.0 */
4166 /* Declaration for Asc Library internal functions referenced by driver. */
4167 STATIC int AscFindSignature(PortAddr);
4168 STATIC ushort AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
4170 #ifdef ADVANSYS_STATS
4171 STATIC int asc_prt_board_stats(struct Scsi_Host *, char *, int);
4172 #endif /* ADVANSYS_STATS */
4174 #ifdef ADVANSYS_DEBUG
4175 STATIC void asc_prt_scsi_host(struct Scsi_Host *);
4176 STATIC void asc_prt_scsi_cmnd(Scsi_Cmnd *);
4177 STATIC void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *);
4178 STATIC void asc_prt_asc_dvc_var(ASC_DVC_VAR *);
4179 STATIC void asc_prt_asc_scsi_q(ASC_SCSI_Q *);
4180 STATIC void asc_prt_asc_qdone_info(ASC_QDONE_INFO *);
4181 STATIC void asc_prt_adv_dvc_cfg(ADV_DVC_CFG *);
4182 STATIC void asc_prt_adv_dvc_var(ADV_DVC_VAR *);
4183 STATIC void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *);
4184 STATIC void asc_prt_adv_sgblock(int, ADV_SG_BLOCK *);
4185 STATIC void asc_prt_hex(char *f, uchar *, int);
4186 #endif /* ADVANSYS_DEBUG */
4188 #ifdef ADVANSYS_ASSERT
4189 STATIC int advansys_interrupts_enabled(void);
4190 #endif /* ADVANSYS_ASSERT */
4194 * --- Linux 'Scsi_Host_Template' and advansys_setup() Functions
4197 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
4199 * advansys_proc_info() - /proc/scsi/advansys/[0-(ASC_NUM_BOARD_SUPPORTED-1)]
4201 * *buffer: I/O buffer
4202 * **start: if inout == FALSE pointer into buffer where user read should start
4203 * offset: current offset into a /proc/scsi/advansys/[0...] file
4204 * length: length of buffer
4205 * hostno: Scsi_Host host_no
4206 * inout: TRUE - user is writing; FALSE - user is reading
4208 * Return the number of bytes read from or written to a
4209 * /proc/scsi/advansys/[0...] file.
4211 * Note: This function uses the per board buffer 'prtbuf' which is
4212 * allocated when the board is initialized in advansys_detect(). The
4213 * buffer is ASC_PRTBUF_SIZE bytes. The function asc_proc_copy() is
4214 * used to write to the buffer. The way asc_proc_copy() is written
4215 * if 'prtbuf' is too small it will not be overwritten. Instead the
4216 * user just won't get all the available statistics.
4219 advansys_proc_info(char *buffer, char **start, off_t offset, int length,
4220 int hostno, int inout)
4222 #ifdef CONFIG_PROC_FS
4223 struct Scsi_Host *shp;
4224 asc_board_t *boardp;
4225 int i;
4226 char *cp;
4227 int cplen;
4228 int cnt;
4229 int totcnt;
4230 int leftlen;
4231 char *curbuf;
4232 off_t advoffset;
4233 Scsi_Device *scd;
4235 ASC_DBG(1, "advansys_proc_info: begin\n");
4238 * User write not supported.
4240 if (inout == TRUE) {
4241 return(-ENOSYS);
4245 * User read of /proc/scsi/advansys/[0...] file.
4248 /* Find the specified board. */
4249 for (i = 0; i < asc_board_count; i++) {
4250 if (asc_host[i]->host_no == hostno) {
4251 break;
4254 if (i == asc_board_count) {
4255 return(-ENOENT);
4258 shp = asc_host[i];
4259 boardp = ASC_BOARDP(shp);
4261 /* Copy read data starting at the beginning of the buffer. */
4262 *start = buffer;
4263 curbuf = buffer;
4264 advoffset = 0;
4265 totcnt = 0;
4266 leftlen = length;
4269 * Get board configuration information.
4271 * advansys_info() returns the board string from its own static buffer.
4273 cp = (char *) advansys_info(shp);
4274 strcat(cp, "\n");
4275 cplen = strlen(cp);
4276 /* Copy board information. */
4277 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4278 totcnt += cnt;
4279 leftlen -= cnt;
4280 if (leftlen == 0) {
4281 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4282 return totcnt;
4284 advoffset += cplen;
4285 curbuf += cnt;
4288 * Display Wide Board BIOS Information.
4290 if (ASC_WIDE_BOARD(boardp)) {
4291 cp = boardp->prtbuf;
4292 cplen = asc_prt_adv_bios(shp, cp, ASC_PRTBUF_SIZE);
4293 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4294 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4295 totcnt += cnt;
4296 leftlen -= cnt;
4297 if (leftlen == 0) {
4298 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4299 return totcnt;
4301 advoffset += cplen;
4302 curbuf += cnt;
4306 * Display driver information for each device attached to the board.
4308 cp = boardp->prtbuf;
4309 cplen = asc_prt_board_devices(shp, cp, ASC_PRTBUF_SIZE);
4310 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4311 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4312 totcnt += cnt;
4313 leftlen -= cnt;
4314 if (leftlen == 0) {
4315 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4316 return totcnt;
4318 advoffset += cplen;
4319 curbuf += cnt;
4322 * Display target driver information for each device attached
4323 * to the board.
4325 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,75)
4326 for (scd = scsi_devices; scd; scd = scd->next)
4327 #else /* version >= v2.1.75 */
4328 for (scd = shp->host_queue; scd; scd = scd->next)
4329 #endif /* version >= v2.1.75 */
4331 if (scd->host == shp) {
4332 cp = boardp->prtbuf;
4334 * Note: If proc_print_scsidevice() writes more than
4335 * ASC_PRTBUF_SIZE bytes, it will overrun 'prtbuf'.
4337 proc_print_scsidevice(scd, cp, &cplen, 0);
4338 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4339 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4340 totcnt += cnt;
4341 leftlen -= cnt;
4342 if (leftlen == 0) {
4343 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4344 return totcnt;
4346 advoffset += cplen;
4347 curbuf += cnt;
4352 * Display EEPROM configuration for the board.
4354 cp = boardp->prtbuf;
4355 if (ASC_NARROW_BOARD(boardp)) {
4356 cplen = asc_prt_asc_board_eeprom(shp, cp, ASC_PRTBUF_SIZE);
4357 } else {
4358 cplen = asc_prt_adv_board_eeprom(shp, cp, ASC_PRTBUF_SIZE);
4360 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4361 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4362 totcnt += cnt;
4363 leftlen -= cnt;
4364 if (leftlen == 0) {
4365 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4366 return totcnt;
4368 advoffset += cplen;
4369 curbuf += cnt;
4372 * Display driver configuration and information for the board.
4374 cp = boardp->prtbuf;
4375 cplen = asc_prt_driver_conf(shp, cp, ASC_PRTBUF_SIZE);
4376 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4377 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4378 totcnt += cnt;
4379 leftlen -= cnt;
4380 if (leftlen == 0) {
4381 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4382 return totcnt;
4384 advoffset += cplen;
4385 curbuf += cnt;
4387 #ifdef ADVANSYS_STATS
4389 * Display driver statistics for the board.
4391 cp = boardp->prtbuf;
4392 cplen = asc_prt_board_stats(shp, cp, ASC_PRTBUF_SIZE);
4393 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4394 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4395 totcnt += cnt;
4396 leftlen -= cnt;
4397 if (leftlen == 0) {
4398 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4399 return totcnt;
4401 advoffset += cplen;
4402 curbuf += cnt;
4403 #endif /* ADVANSYS_STATS */
4406 * Display Asc Library dynamic configuration information
4407 * for the board.
4409 cp = boardp->prtbuf;
4410 if (ASC_NARROW_BOARD(boardp)) {
4411 cplen = asc_prt_asc_board_info(shp, cp, ASC_PRTBUF_SIZE);
4412 } else {
4413 cplen = asc_prt_adv_board_info(shp, cp, ASC_PRTBUF_SIZE);
4415 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4416 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4417 totcnt += cnt;
4418 leftlen -= cnt;
4419 if (leftlen == 0) {
4420 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4421 return totcnt;
4423 advoffset += cplen;
4424 curbuf += cnt;
4426 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4428 return totcnt;
4429 #else /* CONFIG_PROC_FS */
4430 return 0;
4431 #endif /* CONFIG_PROC_FS */
4433 #endif /* version >= v1.3.0 */
4436 * advansys_detect()
4438 * Detect function for AdvanSys adapters.
4440 * Argument is a pointer to the host driver's scsi_hosts entry.
4442 * Return number of adapters found.
4444 * Note: Because this function is called during system initialization
4445 * it must not call SCSI mid-level functions including scsi_malloc()
4446 * and scsi_free().
4448 ASC_INITFUNC(
4449 int,
4450 advansys_detect(Scsi_Host_Template *tpnt)
4453 static int detect_called = ASC_FALSE;
4454 int iop;
4455 int bus;
4456 struct Scsi_Host *shp = NULL;
4457 asc_board_t *boardp = NULL;
4458 ASC_DVC_VAR *asc_dvc_varp = NULL;
4459 ADV_DVC_VAR *adv_dvc_varp = NULL;
4460 adv_sgblk_t *sgp = NULL;
4461 int ioport = 0;
4462 int share_irq = FALSE;
4463 int iolen = 0;
4464 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
4465 #ifdef ASC_CONFIG_PCI
4466 int pci_init_search = 0;
4467 PCI_DEVICE pci_device[ASC_NUM_BOARD_SUPPORTED];
4468 int pci_card_cnt_max = 0;
4469 int pci_card_cnt = 0;
4470 PCI_DEVICE pciDevice;
4471 PCI_CONFIG_SPACE pciConfig;
4472 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
4473 ADV_PADDR pci_memory_address;
4474 #endif /* version >= v1,3,0 */
4475 #endif /* ASC_CONFIG_PCI */
4476 #else /* version >= v2.1.93 */
4477 #ifdef CONFIG_PCI
4478 int pci_init_search = 0;
4479 struct pci_dev *pci_devicep[ASC_NUM_BOARD_SUPPORTED];
4480 int pci_card_cnt_max = 0;
4481 int pci_card_cnt = 0;
4482 struct pci_dev *pci_devp = NULL;
4483 int pci_device_id_cnt = 0;
4484 unsigned int pci_device_id[ASC_PCI_DEVICE_ID_CNT] = {
4485 ASC_PCI_DEVICE_ID_1100,
4486 ASC_PCI_DEVICE_ID_1200,
4487 ASC_PCI_DEVICE_ID_1300,
4488 ASC_PCI_DEVICE_ID_2300,
4489 ASC_PCI_DEVICE_ID_2500
4491 ADV_PADDR pci_memory_address;
4492 #endif /* CONFIG_PCI */
4493 #endif /* version >= v2.1.93 */
4494 int warn_code, err_code;
4495 int ret;
4497 if (detect_called == ASC_FALSE) {
4498 detect_called = ASC_TRUE;
4499 } else {
4500 printk("AdvanSys SCSI: advansys_detect() multiple calls ignored\n");
4501 return 0;
4504 ASC_DBG(1, "advansys_detect: begin\n");
4506 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(2,3,28)
4507 tpnt->proc_name = "advansys";
4508 #elif LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
4509 tpnt->proc_dir = &proc_scsi_advansys;
4510 #endif /* version >= v1.3.0 */
4512 asc_board_count = 0;
4515 * If I/O port probing has been modified, then verify and
4516 * clean-up the 'asc_ioport' list.
4518 if (asc_iopflag == ASC_TRUE) {
4519 for (ioport = 0; ioport < ASC_NUM_IOPORT_PROBE; ioport++) {
4520 ASC_DBG2(1, "advansys_detect: asc_ioport[%d] %x\n",
4521 ioport, asc_ioport[ioport]);
4522 if (asc_ioport[ioport] != 0) {
4523 for (iop = 0; iop < ASC_IOADR_TABLE_MAX_IX; iop++) {
4524 if (_asc_def_iop_base[iop] == asc_ioport[ioport]) {
4525 break;
4528 if (iop == ASC_IOADR_TABLE_MAX_IX) {
4529 printk(
4530 "AdvanSys SCSI: specified I/O Port 0x%X is invalid\n",
4531 asc_ioport[ioport]);
4532 asc_ioport[ioport] = 0;
4536 ioport = 0;
4539 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
4540 #ifdef ASC_CONFIG_PCI
4541 memset(&pciDevice, 0, sizeof(PCI_DEVICE));
4542 memset(&pciConfig, 0, sizeof(PCI_CONFIG_SPACE));
4543 pciDevice.maxBusNumber = PCI_MAX_BUS;
4544 pciDevice.endSlot = PCI_MAX_SLOT;
4545 #endif /* ASC_CONFIG_PCI */
4546 #endif /* version < v2.1.93 */
4548 for (bus = 0; bus < ASC_NUM_BUS; bus++) {
4550 ASC_DBG2(1, "advansys_detect: bus search type %d (%s)\n",
4551 bus, asc_bus_name[bus]);
4552 iop = 0;
4554 while (asc_board_count < ASC_NUM_BOARD_SUPPORTED) {
4556 ASC_DBG1(2, "advansys_detect: asc_board_count %d\n",
4557 asc_board_count);
4559 switch (asc_bus[bus]) {
4560 case ASC_IS_ISA:
4561 case ASC_IS_VL:
4562 if (asc_iopflag == ASC_FALSE) {
4563 iop = AscSearchIOPortAddr(iop, asc_bus[bus]);
4564 } else {
4566 * ISA and VL I/O port scanning has either been
4567 * eliminated or limited to selected ports on
4568 * the LILO command line, /etc/lilo.conf, or
4569 * by setting variables when the module was loaded.
4571 ASC_DBG(1, "advansys_detect: I/O port scanning modified\n");
4572 ioport_try_again:
4573 iop = 0;
4574 for (; ioport < ASC_NUM_IOPORT_PROBE; ioport++) {
4575 if ((iop = asc_ioport[ioport]) != 0) {
4576 break;
4579 if (iop) {
4580 ASC_DBG1(1, "advansys_detect: probing I/O port %x...\n",
4581 iop);
4582 if (check_region(iop, ASC_IOADR_GAP) != 0) {
4583 printk(
4584 "AdvanSys SCSI: specified I/O Port 0x%X is busy\n", iop);
4585 /* Don't try this I/O port twice. */
4586 asc_ioport[ioport] = 0;
4587 goto ioport_try_again;
4588 } else if (AscFindSignature(iop) == ASC_FALSE) {
4589 printk(
4590 "AdvanSys SCSI: specified I/O Port 0x%X has no adapter\n", iop);
4591 /* Don't try this I/O port twice. */
4592 asc_ioport[ioport] = 0;
4593 goto ioport_try_again;
4594 } else {
4596 * If this isn't an ISA board, then it must be
4597 * a VL board. If currently looking an ISA
4598 * board is being looked for then try for
4599 * another ISA board in 'asc_ioport'.
4601 if (asc_bus[bus] == ASC_IS_ISA &&
4602 (AscGetChipVersion(iop, ASC_IS_ISA) &
4603 ASC_CHIP_VER_ISA_BIT) == 0) {
4605 * Don't clear 'asc_ioport[ioport]'. Try
4606 * this board again for VL. Increment
4607 * 'ioport' past this board.
4609 ioport++;
4610 goto ioport_try_again;
4614 * This board appears good, don't try the I/O port
4615 * again by clearing its value. Increment 'ioport'
4616 * for the next iteration.
4618 asc_ioport[ioport++] = 0;
4621 break;
4623 case ASC_IS_EISA:
4624 iop = AscSearchIOPortAddr(iop, asc_bus[bus]);
4625 break;
4627 case ASC_IS_PCI:
4628 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
4629 #ifdef ASC_CONFIG_PCI
4630 if (pci_init_search == 0) {
4631 int i, j;
4633 pci_init_search = 1;
4635 /* Find all PCI cards. */
4636 while (asc_srch_pci_dev(&pciDevice) == PCI_DEVICE_FOUND) {
4637 pci_device[pci_card_cnt_max++] = pciDevice;
4641 * Sort PCI cards in ascending order by PCI Bus, Slot,
4642 * and Device Number.
4644 for (i = 0; i < pci_card_cnt_max - 1; i++)
4646 for (j = i + 1; j < pci_card_cnt_max; j++) {
4647 if ((pci_device[j].busNumber <
4648 pci_device[i].busNumber) ||
4649 ((pci_device[j].busNumber ==
4650 pci_device[i].busNumber) &&
4651 (pci_device[j].slotNumber <
4652 pci_device[i].slotNumber)) ||
4653 ((pci_device[j].busNumber ==
4654 pci_device[i].busNumber) &&
4655 (pci_device[j].slotNumber ==
4656 pci_device[i].slotNumber) &&
4657 (pci_device[j].devFunc <
4658 pci_device[i].devFunc))) {
4659 pciDevice = pci_device[i];
4660 pci_device[i] = pci_device[j];
4661 pci_device[j] = pciDevice;
4666 pci_card_cnt = 0;
4667 } else {
4668 pci_card_cnt++;
4671 if (pci_card_cnt == pci_card_cnt_max) {
4672 iop = 0;
4673 } else {
4674 pciDevice = pci_device[pci_card_cnt];
4675 ASC_DBG2(2,
4676 "advansys_detect: slotFound %d, busNumber %d\n",
4677 pciDevice.slotFound, pciDevice.busNumber);
4678 asc_get_pci_cfg(&pciDevice, &pciConfig);
4679 iop = pciConfig.baseAddress[0] & PCI_IOADDRESS_MASK;
4680 ASC_DBG2(1,
4681 "advansys_detect: vendorID %X, deviceID %X\n",
4682 pciConfig.vendorID, pciConfig.deviceID);
4683 ASC_DBG2(2, "advansys_detect: iop %X, irqLine %d\n",
4684 iop, pciConfig.irqLine);
4686 break;
4687 #endif /* ASC_CONFIG_PCI */
4688 #else /* version >= v2.1.93 */
4689 #ifdef CONFIG_PCI
4690 if (pci_init_search == 0) {
4691 int i, j;
4693 pci_init_search = 1;
4695 /* Find all PCI cards. */
4696 while (pci_device_id_cnt < ASC_PCI_DEVICE_ID_CNT) {
4697 if ((pci_devp = pci_find_device(ASC_PCI_VENDORID,
4698 pci_device_id[pci_device_id_cnt], pci_devp)) ==
4699 NULL) {
4700 pci_device_id_cnt++;
4701 } else {
4702 if (pci_enable_device(pci_devp) == 0)
4703 pci_devicep[pci_card_cnt_max++] = pci_devp;
4708 * Sort PCI cards in ascending order by PCI Bus, Slot,
4709 * and Device Number.
4711 for (i = 0; i < pci_card_cnt_max - 1; i++)
4713 for (j = i + 1; j < pci_card_cnt_max; j++) {
4714 if ((pci_devicep[j]->bus->number <
4715 pci_devicep[i]->bus->number) ||
4716 ((pci_devicep[j]->bus->number ==
4717 pci_devicep[i]->bus->number) &&
4718 (pci_devicep[j]->devfn <
4719 pci_devicep[i]->devfn))) {
4720 pci_devp = pci_devicep[i];
4721 pci_devicep[i] = pci_devicep[j];
4722 pci_devicep[j] = pci_devp;
4727 pci_card_cnt = 0;
4728 } else {
4729 pci_card_cnt++;
4732 if (pci_card_cnt == pci_card_cnt_max) {
4733 iop = 0;
4734 } else {
4735 pci_devp = pci_devicep[pci_card_cnt];
4737 ASC_DBG2(2,
4738 "advansys_detect: devfn %d, bus number %d\n",
4739 pci_devp->devfn, pci_devp->bus->number);
4740 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,3,13)
4741 iop = pci_devp->base_address[0] & PCI_IOADDRESS_MASK;
4742 #else /* version >= v2.3.13 */
4743 iop = pci_resource_start(pci_devp, 0);
4744 #endif /* version >= v2.3.13 */
4745 ASC_DBG2(1,
4746 "advansys_detect: vendorID %X, deviceID %X\n",
4747 pci_devp->vendor, pci_devp->device);
4748 ASC_DBG2(2, "advansys_detect: iop %X, irqLine %d\n",
4749 iop, pci_devp->irq);
4751 #endif /* CONFIG_PCI */
4752 #endif /* version >= v2.1.93 */
4753 break;
4755 default:
4756 ASC_PRINT1("advansys_detect: unknown bus type: %d\n",
4757 asc_bus[bus]);
4758 break;
4760 ASC_DBG1(1, "advansys_detect: iop %x\n", iop);
4763 * Adapter not found, try next bus type.
4765 if (iop == 0) {
4766 break;
4770 * Adapter found.
4772 * Register the adapter, get its configuration, and
4773 * initialize it.
4775 ASC_DBG(2, "advansys_detect: scsi_register()\n");
4776 shp = scsi_register(tpnt, sizeof(asc_board_t));
4778 if(shp==NULL)
4779 continue;
4781 /* Save a pointer to the Scsi_host of each board found. */
4782 asc_host[asc_board_count++] = shp;
4784 /* Initialize private per board data */
4785 boardp = ASC_BOARDP(shp);
4786 memset(boardp, 0, sizeof(asc_board_t));
4787 boardp->id = asc_board_count - 1;
4790 * Handle both narrow and wide boards.
4792 * If a Wide board was detected, set the board structure
4793 * wide board flag. Set-up the board structure based on
4794 * the board type.
4796 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
4797 #ifdef ASC_CONFIG_PCI
4798 if (asc_bus[bus] == ASC_IS_PCI &&
4799 (pciConfig.deviceID == ASC_PCI_DEVICE_ID_2300 ||
4800 pciConfig.deviceID == ASC_PCI_DEVICE_ID_2500))
4802 boardp->flags |= ASC_IS_WIDE_BOARD;
4804 #endif /* ASC_CONFIG_PCI */
4805 #else /* version >= v2.1.93 */
4806 #ifdef CONFIG_PCI
4807 if (asc_bus[bus] == ASC_IS_PCI &&
4808 (pci_devp->device == ASC_PCI_DEVICE_ID_2300 ||
4809 pci_devp->device == ASC_PCI_DEVICE_ID_2500))
4811 boardp->flags |= ASC_IS_WIDE_BOARD;
4813 #endif /* CONFIG_PCI */
4814 #endif /* version >= v2.1.93 */
4816 if (ASC_NARROW_BOARD(boardp)) {
4817 ASC_DBG(1, "advansys_detect: narrow board\n");
4818 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
4819 asc_dvc_varp->bus_type = asc_bus[bus];
4820 asc_dvc_varp->drv_ptr = boardp;
4821 asc_dvc_varp->cfg = &boardp->dvc_cfg.asc_dvc_cfg;
4822 asc_dvc_varp->cfg->overrun_buf = &overrun_buf[0];
4823 asc_dvc_varp->iop_base = iop;
4824 asc_dvc_varp->isr_callback = asc_isr_callback;
4825 } else {
4826 ASC_DBG(1, "advansys_detect: wide board\n");
4827 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
4828 adv_dvc_varp->drv_ptr = boardp;
4829 adv_dvc_varp->cfg = &boardp->dvc_cfg.adv_dvc_cfg;
4830 adv_dvc_varp->isr_callback = adv_isr_callback;
4831 adv_dvc_varp->async_callback = adv_async_callback;
4833 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
4834 #ifdef ASC_CONFIG_PCI
4835 if (pciConfig.deviceID == ASC_PCI_DEVICE_ID_2300)
4837 ASC_DBG(1, "advansys_detect: ASC-3550\n");
4838 adv_dvc_varp->chip_type = ADV_CHIP_ASC3550;
4839 } else
4841 ASC_DBG(1, "advansys_detect: ASC-38C0800\n");
4842 adv_dvc_varp->chip_type = ADV_CHIP_ASC38C0800;
4844 #endif /* ASC_CONFIG_PCI */
4845 #else /* version >= v2.1.93 */
4846 #ifdef CONFIG_PCI
4847 if (pci_devp->device == ASC_PCI_DEVICE_ID_2300)
4849 ASC_DBG(1, "advansys_detect: ASC-3550\n");
4850 adv_dvc_varp->chip_type = ADV_CHIP_ASC3550;
4851 } else
4853 ASC_DBG(1, "advansys_detect: ASC-38C0800\n");
4854 adv_dvc_varp->chip_type = ADV_CHIP_ASC38C0800;
4856 #endif /* CONFIG_PCI */
4857 #endif /* version >= v2.1.93 */
4859 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0)
4860 adv_dvc_varp->iop_base = iop;
4861 #else /* version >= v1,3,0 */
4863 * Map the board's registers into virtual memory for
4864 * PCI slave access. Only memory accesses are used to
4865 * access the board's registers.
4867 * Note: The PCI register base address is not always
4868 * page aligned, but the address passed to ioremap()
4869 * must be page aligned. It is guaranteed that the
4870 * PCI register base address will not cross a page
4871 * boundary.
4873 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
4875 iolen = ADV_3550_IOLEN;
4876 } else {
4877 iolen = ADV_38C0800_IOLEN;
4879 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
4880 #ifdef ASC_CONFIG_PCI
4881 pci_memory_address = pciConfig.baseAddress[1];
4882 ASC_DBG1(1, "advansys_detect: pci_memory_address: %lu\n",
4883 (ulong) pci_memory_address);
4884 if ((boardp->ioremap_addr =
4885 ioremap(pci_memory_address & PAGE_MASK,
4886 PAGE_SIZE)) == 0) {
4887 ASC_PRINT3(
4888 "advansys_detect: board %d: ioremap(%lu, %x) returned NULL\n",
4889 boardp->id, (ulong) pci_memory_address, iolen);
4890 scsi_unregister(shp);
4891 asc_board_count--;
4892 continue;
4894 ASC_DBG1(1, "advansys_detect: ioremap_addr: %lx\n",
4895 (ulong) boardp->ioremap_addr);
4896 adv_dvc_varp->iop_base = (AdvPortAddr)
4897 (boardp->ioremap_addr +
4898 (pci_memory_address - (pci_memory_address & PAGE_MASK)));
4899 ASC_DBG1(1, "advansys_detect: iop_base: %lx\n",
4900 adv_dvc_varp->iop_base);
4901 #endif /* ASC_CONFIG_PCI */
4902 #else /* version >= v2.1.93 */
4903 #ifdef CONFIG_PCI
4904 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,3,13)
4905 pci_memory_address = pci_devp->base_address[1];
4906 #else /* version >= v2.3.13 */
4907 pci_memory_address = pci_resource_start(pci_devp, 1);
4908 #endif /* version >= v2.3.13 */
4909 ASC_DBG1(1, "advansys_detect: pci_memory_address: %x\n",
4910 pci_memory_address);
4911 if ((boardp->ioremap_addr =
4912 ioremap(pci_memory_address & PAGE_MASK,
4913 PAGE_SIZE)) == 0) {
4914 ASC_PRINT3(
4915 "advansys_detect: board %d: ioremap(%x, %d) returned NULL\n",
4916 boardp->id, pci_memory_address, iolen);
4917 scsi_unregister(shp);
4918 asc_board_count--;
4919 continue;
4921 ASC_DBG1(1, "advansys_detect: ioremap_addr: %lx\n",
4922 (ulong) boardp->ioremap_addr);
4923 adv_dvc_varp->iop_base = (AdvPortAddr)
4924 (boardp->ioremap_addr +
4925 (pci_memory_address - (pci_memory_address & PAGE_MASK)));
4926 ASC_DBG1(1, "advansys_detect: iop_base: %lx\n",
4927 adv_dvc_varp->iop_base);
4928 #endif /* CONFIG_PCI */
4929 #endif /* version >= v2.1.93 */
4930 #endif /* version >= v1,3,0 */
4933 * Even though it isn't used to access the board in
4934 * kernels greater than or equal to v1.3.0, save
4935 * the I/O Port address so that it can be reported and
4936 * displayed.
4938 boardp->ioport = iop;
4940 ASC_DBG2(1,
4941 "advansys_detect: iopb_chip_id_1 %x, iopw_chip_id_0 %x\n",
4942 (ushort) inp(iop + 1), (ushort) inpw(iop));
4945 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
4947 * Allocate buffer for printing information from
4948 * /proc/scsi/advansys/[0...].
4950 if ((boardp->prtbuf =
4951 kmalloc(ASC_PRTBUF_SIZE, GFP_ATOMIC)) == NULL) {
4952 ASC_PRINT3(
4953 "advansys_detect: board %d: kmalloc(%d, %d) returned NULL\n",
4954 boardp->id, ASC_PRTBUF_SIZE, GFP_ATOMIC);
4955 scsi_unregister(shp);
4956 asc_board_count--;
4957 continue;
4959 #endif /* version >= v1.3.0 */
4961 if (ASC_NARROW_BOARD(boardp)) {
4963 * Set the board bus type and PCI IRQ before
4964 * calling AscInitGetConfig().
4966 switch (asc_dvc_varp->bus_type) {
4967 case ASC_IS_ISA:
4968 shp->unchecked_isa_dma = TRUE;
4969 share_irq = FALSE;
4970 break;
4971 case ASC_IS_VL:
4972 shp->unchecked_isa_dma = FALSE;
4973 share_irq = FALSE;
4974 break;
4975 case ASC_IS_EISA:
4976 shp->unchecked_isa_dma = FALSE;
4977 share_irq = TRUE;
4978 break;
4979 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
4980 #ifdef ASC_CONFIG_PCI
4981 case ASC_IS_PCI:
4982 shp->irq = asc_dvc_varp->irq_no = pciConfig.irqLine;
4983 asc_dvc_varp->cfg->pci_device_id = pciConfig.deviceID;
4984 asc_dvc_varp->cfg->pci_slot_info =
4985 ASC_PCI_MKID(pciDevice.busNumber,
4986 pciDevice.slotFound,
4987 pciDevice.devFunc);
4988 shp->unchecked_isa_dma = FALSE;
4989 share_irq = TRUE;
4990 break;
4991 #endif /* ASC_CONFIG_PCI */
4992 #else /* version >= v2.1.93 */
4993 #ifdef CONFIG_PCI
4994 case ASC_IS_PCI:
4995 shp->irq = asc_dvc_varp->irq_no = pci_devp->irq;
4996 asc_dvc_varp->cfg->pci_device_id = pci_devp->device;
4997 asc_dvc_varp->cfg->pci_slot_info =
4998 ASC_PCI_MKID(pci_devp->bus->number,
4999 PCI_SLOT(pci_devp->devfn),
5000 PCI_FUNC(pci_devp->devfn));
5001 shp->unchecked_isa_dma = FALSE;
5002 share_irq = TRUE;
5003 break;
5004 #endif /* CONFIG_PCI */
5005 #endif /* version >= v2.1.93 */
5006 default:
5007 ASC_PRINT2(
5008 "advansys_detect: board %d: unknown adapter type: %d\n",
5009 boardp->id, asc_dvc_varp->bus_type);
5010 shp->unchecked_isa_dma = TRUE;
5011 share_irq = FALSE;
5012 break;
5014 } else {
5016 * For Wide boards set PCI information before calling
5017 * AdvInitGetConfig().
5019 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
5020 #ifdef ASC_CONFIG_PCI
5021 shp->irq = adv_dvc_varp->irq_no = pciConfig.irqLine;
5022 adv_dvc_varp->cfg->pci_device_id = pciConfig.deviceID;
5023 adv_dvc_varp->cfg->pci_slot_info =
5024 ASC_PCI_MKID(pciDevice.busNumber,
5025 pciDevice.slotFound,
5026 pciDevice.devFunc);
5027 shp->unchecked_isa_dma = FALSE;
5028 share_irq = TRUE;
5029 #endif /* ASC_CONFIG_PCI */
5030 #else /* version >= v2.1.93 */
5031 #ifdef CONFIG_PCI
5032 shp->irq = adv_dvc_varp->irq_no = pci_devp->irq;
5033 adv_dvc_varp->cfg->pci_device_id = pci_devp->device;
5034 adv_dvc_varp->cfg->pci_slot_info =
5035 ASC_PCI_MKID(pci_devp->bus->number,
5036 PCI_SLOT(pci_devp->devfn),
5037 PCI_FUNC(pci_devp->devfn));
5038 shp->unchecked_isa_dma = FALSE;
5039 share_irq = TRUE;
5040 #endif /* CONFIG_PCI */
5041 #endif /* version >= v2.1.93 */
5045 * Read the board configuration.
5047 if (ASC_NARROW_BOARD(boardp)) {
5049 * NOTE: AscInitGetConfig() may change the board's
5050 * bus_type value. The asc_bus[bus] value should no
5051 * longer be used. If the bus_type field must be
5052 * referenced only use the bit-wise AND operator "&".
5054 ASC_DBG(2, "advansys_detect: AscInitGetConfig()\n");
5055 switch(ret = AscInitGetConfig(asc_dvc_varp)) {
5056 case 0: /* No error */
5057 break;
5058 case ASC_WARN_IO_PORT_ROTATE:
5059 ASC_PRINT1(
5060 "AscInitGetConfig: board %d: I/O port address modified\n",
5061 boardp->id);
5062 break;
5063 case ASC_WARN_AUTO_CONFIG:
5064 ASC_PRINT1(
5065 "AscInitGetConfig: board %d: I/O port increment switch enabled\n",
5066 boardp->id);
5067 break;
5068 case ASC_WARN_EEPROM_CHKSUM:
5069 ASC_PRINT1(
5070 "AscInitGetConfig: board %d: EEPROM checksum error\n",
5071 boardp->id);
5072 break;
5073 case ASC_WARN_IRQ_MODIFIED:
5074 ASC_PRINT1(
5075 "AscInitGetConfig: board %d: IRQ modified\n",
5076 boardp->id);
5077 break;
5078 case ASC_WARN_CMD_QNG_CONFLICT:
5079 ASC_PRINT1(
5080 "AscInitGetConfig: board %d: tag queuing enabled w/o disconnects\n",
5081 boardp->id);
5082 break;
5083 default:
5084 ASC_PRINT2(
5085 "AscInitGetConfig: board %d: unknown warning: %x\n",
5086 boardp->id, ret);
5087 break;
5089 if ((err_code = asc_dvc_varp->err_code) != 0) {
5090 ASC_PRINT3(
5091 "AscInitGetConfig: board %d error: init_state %x, err_code %x\n",
5092 boardp->id, asc_dvc_varp->init_state,
5093 asc_dvc_varp->err_code);
5095 } else {
5096 ASC_DBG(2, "advansys_detect: AdvInitGetConfig()\n");
5097 if ((ret = AdvInitGetConfig(adv_dvc_varp)) != 0) {
5098 ASC_PRINT2("AdvInitGetConfig: board %d: warning: %x\n",
5099 boardp->id, ret);
5101 if ((err_code = adv_dvc_varp->err_code) != 0) {
5102 ASC_PRINT2(
5103 "AdvInitGetConfig: board %d error: err_code %x\n",
5104 boardp->id, adv_dvc_varp->err_code);
5108 if (err_code != 0) {
5109 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
5110 kfree(boardp->prtbuf);
5111 #endif /* version >= v1.3.0 */
5112 scsi_unregister(shp);
5113 asc_board_count--;
5114 continue;
5118 * Save the EEPROM configuration so that it can be displayed
5119 * from /proc/scsi/advansys/[0...].
5121 if (ASC_NARROW_BOARD(boardp)) {
5123 ASCEEP_CONFIG *ep;
5126 * Set the adapter's target id bit in the 'init_tidmask' field.
5128 boardp->init_tidmask |=
5129 ADV_TID_TO_TIDMASK(asc_dvc_varp->cfg->chip_scsi_id);
5132 * Save EEPROM settings for the board.
5134 ep = &boardp->eep_config.asc_eep;
5136 ep->init_sdtr = asc_dvc_varp->cfg->sdtr_enable;
5137 ep->disc_enable = asc_dvc_varp->cfg->disc_enable;
5138 ep->use_cmd_qng = asc_dvc_varp->cfg->cmd_qng_enabled;
5139 ep->isa_dma_speed = asc_dvc_varp->cfg->isa_dma_speed;
5140 ep->start_motor = asc_dvc_varp->start_motor;
5141 ep->cntl = asc_dvc_varp->dvc_cntl;
5142 ep->no_scam = asc_dvc_varp->no_scam;
5143 ep->max_total_qng = asc_dvc_varp->max_total_qng;
5144 ep->chip_scsi_id = asc_dvc_varp->cfg->chip_scsi_id;
5145 /* 'max_tag_qng' is set to the same value for every device. */
5146 ep->max_tag_qng = asc_dvc_varp->cfg->max_tag_qng[0];
5147 ep->adapter_info[0] = asc_dvc_varp->cfg->adapter_info[0];
5148 ep->adapter_info[1] = asc_dvc_varp->cfg->adapter_info[1];
5149 ep->adapter_info[2] = asc_dvc_varp->cfg->adapter_info[2];
5150 ep->adapter_info[3] = asc_dvc_varp->cfg->adapter_info[3];
5151 ep->adapter_info[4] = asc_dvc_varp->cfg->adapter_info[4];
5152 ep->adapter_info[5] = asc_dvc_varp->cfg->adapter_info[5];
5153 ep->adapter_info[6] = asc_dvc_varp->cfg->adapter_info[6];
5156 * Modify board configuration.
5158 ASC_DBG(2, "advansys_detect: AscInitSetConfig()\n");
5159 switch (ret = AscInitSetConfig(asc_dvc_varp)) {
5160 case 0: /* No error. */
5161 break;
5162 case ASC_WARN_IO_PORT_ROTATE:
5163 ASC_PRINT1(
5164 "AscInitSetConfig: board %d: I/O port address modified\n",
5165 boardp->id);
5166 break;
5167 case ASC_WARN_AUTO_CONFIG:
5168 ASC_PRINT1(
5169 "AscInitSetConfig: board %d: I/O port increment switch enabled\n",
5170 boardp->id);
5171 break;
5172 case ASC_WARN_EEPROM_CHKSUM:
5173 ASC_PRINT1(
5174 "AscInitSetConfig: board %d: EEPROM checksum error\n",
5175 boardp->id);
5176 break;
5177 case ASC_WARN_IRQ_MODIFIED:
5178 ASC_PRINT1(
5179 "AscInitSetConfig: board %d: IRQ modified\n",
5180 boardp->id);
5181 break;
5182 case ASC_WARN_CMD_QNG_CONFLICT:
5183 ASC_PRINT1(
5184 "AscInitSetConfig: board %d: tag queuing w/o disconnects\n",
5185 boardp->id);
5186 break;
5187 default:
5188 ASC_PRINT2(
5189 "AscInitSetConfig: board %d: unknown warning: %x\n",
5190 boardp->id, ret);
5191 break;
5193 if (asc_dvc_varp->err_code != 0) {
5194 ASC_PRINT3(
5195 "AscInitSetConfig: board %d error: init_state %x, err_code %x\n",
5196 boardp->id, asc_dvc_varp->init_state,
5197 asc_dvc_varp->err_code);
5198 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
5199 kfree(boardp->prtbuf);
5200 #endif /* version >= v1.3.0 */
5201 scsi_unregister(shp);
5202 asc_board_count--;
5203 continue;
5207 * Finish initializing the 'Scsi_Host' structure.
5209 /* AscInitSetConfig() will set the IRQ for non-PCI boards. */
5210 if ((asc_dvc_varp->bus_type & ASC_IS_PCI) == 0) {
5211 shp->irq = asc_dvc_varp->irq_no;
5213 } else {
5214 ADVEEP_3550_CONFIG *ep_3550;
5215 ADVEEP_38C0800_CONFIG *ep_38C0800;
5218 * Save Wide EEP Configuration Information.
5220 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
5222 ep_3550 = &boardp->eep_config.adv_3550_eep;
5224 ep_3550->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
5225 ep_3550->max_host_qng = adv_dvc_varp->max_host_qng;
5226 ep_3550->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
5227 ep_3550->termination = adv_dvc_varp->cfg->termination;
5228 ep_3550->disc_enable = adv_dvc_varp->cfg->disc_enable;
5229 ep_3550->bios_ctrl = adv_dvc_varp->bios_ctrl;
5230 ep_3550->wdtr_able = adv_dvc_varp->wdtr_able;
5231 ep_3550->sdtr_able = adv_dvc_varp->sdtr_able;
5232 ep_3550->ultra_able = adv_dvc_varp->ultra_able;
5233 ep_3550->tagqng_able = adv_dvc_varp->tagqng_able;
5234 ep_3550->start_motor = adv_dvc_varp->start_motor;
5235 ep_3550->scsi_reset_delay = adv_dvc_varp->scsi_reset_wait;
5236 ep_3550->serial_number_word1 =
5237 adv_dvc_varp->cfg->serial1;
5238 ep_3550->serial_number_word2 =
5239 adv_dvc_varp->cfg->serial2;
5240 ep_3550->serial_number_word3 =
5241 adv_dvc_varp->cfg->serial3;
5242 } else
5244 ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
5246 ep_38C0800->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
5247 ep_38C0800->max_host_qng = adv_dvc_varp->max_host_qng;
5248 ep_38C0800->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
5249 ep_38C0800->termination_lvd =
5250 adv_dvc_varp->cfg->termination;
5251 ep_38C0800->disc_enable = adv_dvc_varp->cfg->disc_enable;
5252 ep_38C0800->bios_ctrl = adv_dvc_varp->bios_ctrl;
5253 ep_38C0800->wdtr_able = adv_dvc_varp->wdtr_able;
5254 ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
5255 ep_38C0800->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
5256 ep_38C0800->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
5257 ep_38C0800->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
5258 ep_38C0800->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
5259 ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
5260 ep_38C0800->start_motor = adv_dvc_varp->start_motor;
5261 ep_38C0800->scsi_reset_delay =
5262 adv_dvc_varp->scsi_reset_wait;
5263 ep_38C0800->serial_number_word1 =
5264 adv_dvc_varp->cfg->serial1;
5265 ep_38C0800->serial_number_word2 =
5266 adv_dvc_varp->cfg->serial2;
5267 ep_38C0800->serial_number_word3 =
5268 adv_dvc_varp->cfg->serial3;
5272 * Set the adapter's target id bit in the 'init_tidmask' field.
5274 boardp->init_tidmask |=
5275 ADV_TID_TO_TIDMASK(adv_dvc_varp->chip_scsi_id);
5278 * Finish initializing the 'Scsi_Host' structure.
5280 shp->irq = adv_dvc_varp->irq_no;
5283 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
5285 * Channels are numbered beginning with 0. For AdvanSys One host
5286 * structure supports one channel. Multi-channel boards have a
5287 * separate host structure for each channel.
5289 shp->max_channel = 0;
5290 #endif /* version >= v1.3.89 */
5291 if (ASC_NARROW_BOARD(boardp)) {
5292 shp->max_id = ASC_MAX_TID + 1;
5293 shp->max_lun = ASC_MAX_LUN + 1;
5295 shp->io_port = asc_dvc_varp->iop_base;
5296 shp->n_io_port = ASC_IOADR_GAP;
5297 shp->this_id = asc_dvc_varp->cfg->chip_scsi_id;
5299 /* Set maximum number of queues the adapter can handle. */
5300 shp->can_queue = asc_dvc_varp->max_total_qng;
5301 } else {
5302 shp->max_id = ADV_MAX_TID + 1;
5303 shp->max_lun = ADV_MAX_LUN + 1;
5306 * Save the I/O Port address and length even though the
5307 * in v1.3.0 and greater kernels the region is not used
5308 * by a Wide board. Instead the board is accessed with
5309 * Memory Mapped I/O.
5311 shp->io_port = iop;
5312 shp->n_io_port = iolen;
5314 shp->this_id = adv_dvc_varp->chip_scsi_id;
5316 /* Set maximum number of queues the adapter can handle. */
5317 shp->can_queue = adv_dvc_varp->max_host_qng;
5320 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,89)
5322 * In old kernels without tag queuing support and with memory
5323 * allocation problems set a conservative 'cmd_per_lun' value.
5325 #ifdef MODULE
5326 shp->cmd_per_lun = 1;
5327 #else /* MODULE */
5328 shp->cmd_per_lun = 4;
5329 #endif /* MODULE */
5330 ASC_DBG1(1, "advansys_detect: cmd_per_lun: %d\n", shp->cmd_per_lun);
5331 #else /* version >= v1.3.89 */
5333 * Following v1.3.89, 'cmd_per_lun' is no longer needed
5334 * and should be set to zero.
5336 * But because of a bug introduced in v1.3.89 if the driver is
5337 * compiled as a module and 'cmd_per_lun' is zero, the Mid-Level
5338 * SCSI function 'allocate_device' will panic. To allow the driver
5339 * to work as a module in these kernels set 'cmd_per_lun' to 1.
5341 #ifdef MODULE
5342 shp->cmd_per_lun = 1;
5343 #else /* MODULE */
5344 shp->cmd_per_lun = 0;
5345 #endif /* MODULE */
5347 * Use the host 'select_queue_depths' function to determine
5348 * the number of commands to queue per device.
5350 shp->select_queue_depths = advansys_select_queue_depths;
5351 #endif /* version >= v1.3.89 */
5354 * Set the maximum number of scatter-gather elements the
5355 * adapter can handle.
5357 if (ASC_NARROW_BOARD(boardp)) {
5359 * Allow two commands with 'sg_tablesize' scatter-gather
5360 * elements to be executed simultaneously. This value is
5361 * the theoretical hardware limit. It may be decreased
5362 * below.
5364 shp->sg_tablesize =
5365 (((asc_dvc_varp->max_total_qng - 2) / 2) *
5366 ASC_SG_LIST_PER_Q) + 1;
5367 } else {
5368 shp->sg_tablesize = ADV_MAX_SG_LIST;
5371 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
5372 #ifdef MODULE
5374 * If the driver is compiled as a module, set a limit on the
5375 * 'sg_tablesize' value to prevent memory allocation failures.
5376 * Memory allocation errors are more likely to occur at module
5377 * load time, then at driver initialization time.
5379 if (shp->sg_tablesize > 64) {
5380 shp->sg_tablesize = 64;
5382 #endif /* MODULE */
5383 #endif /* version < v2.0.0 */
5386 * The value of 'sg_tablesize' can not exceed the SCSI
5387 * mid-level driver definition of SG_ALL. SG_ALL also
5388 * must not be exceeded, because it is used to define the
5389 * size of the scatter-gather table in 'struct asc_sg_head'.
5391 if (shp->sg_tablesize > SG_ALL) {
5392 shp->sg_tablesize = SG_ALL;
5395 ASC_DBG1(1, "advansys_detect: sg_tablesize: %d\n",
5396 shp->sg_tablesize);
5398 /* BIOS start address. */
5399 if (ASC_NARROW_BOARD(boardp)) {
5400 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(2,3,29)
5401 shp->base =
5402 #else /* version >= v2.3.29 */
5403 shp->base = (char *)
5404 #endif /* version < v2.3.29 */
5405 ((ulong) AscGetChipBiosAddress(
5406 asc_dvc_varp->iop_base,
5407 asc_dvc_varp->bus_type));
5408 } else {
5410 * Fill-in BIOS board variables. The Wide BIOS saves
5411 * information in LRAM that is used by the driver.
5413 AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_SIGNATURE,
5414 boardp->bios_signature);
5415 AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_VERSION,
5416 boardp->bios_version);
5417 AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_CODESEG,
5418 boardp->bios_codeseg);
5419 AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_CODELEN,
5420 boardp->bios_codelen);
5422 ASC_DBG2(1,
5423 "advansys_detect: bios_signature %x, bios_version %x\n",
5424 boardp->bios_signature, boardp->bios_version);
5426 ASC_DBG2(1,
5427 "advansys_detect: bios_codeseg %x, bios_codelen %x\n",
5428 boardp->bios_codeseg, boardp->bios_codelen);
5431 * If the BIOS saved a valid signature, then fill in
5432 * the BIOS code segment base address.
5434 if (boardp->bios_signature == 0x55AA) {
5436 * Convert x86 realmode code segment to a linear
5437 * address by shifting left 4.
5439 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(2,3,29)
5440 shp->base =
5441 #else /* version >= v2.3.29 */
5442 shp->base = (char *)
5443 #endif /* version < v2.3.29 */
5444 ((ulong) boardp->bios_codeseg << 4);
5445 } else {
5446 shp->base = 0;
5451 * Register Board Resources - I/O Port, DMA, IRQ
5454 /* Register I/O port range. */
5455 ASC_DBG(2, "advansys_detect: request_region()\n");
5456 request_region(shp->io_port, shp->n_io_port, "advansys");
5458 /* Register DMA Channel for Narrow boards. */
5459 shp->dma_channel = NO_ISA_DMA; /* Default to no ISA DMA. */
5460 if (ASC_NARROW_BOARD(boardp)) {
5461 /* Register DMA channel for ISA bus. */
5462 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
5463 shp->dma_channel = asc_dvc_varp->cfg->isa_dma_channel;
5464 if ((ret =
5465 request_dma(shp->dma_channel, "advansys")) != 0) {
5466 ASC_PRINT3(
5467 "advansys_detect: board %d: request_dma() %d failed %d\n",
5468 boardp->id, shp->dma_channel, ret);
5469 release_region(shp->io_port, shp->n_io_port);
5470 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
5471 kfree(boardp->prtbuf);
5472 #endif /* version >= v1.3.0 */
5473 scsi_unregister(shp);
5474 asc_board_count--;
5475 continue;
5477 AscEnableIsaDma(shp->dma_channel);
5481 /* Register IRQ Number. */
5482 ASC_DBG1(2, "advansys_detect: request_irq() %d\n", shp->irq);
5483 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,70)
5484 if ((ret = request_irq(shp->irq, advansys_interrupt,
5485 SA_INTERRUPT, "advansys")) != 0)
5486 #else /* version >= v1.3.70 */
5488 * If request_irq() fails with the SA_INTERRUPT flag set,
5489 * then try again without the SA_INTERRUPT flag set. This
5490 * allows IRQ sharing to work even with other drivers that
5491 * do not set the SA_INTERRUPT flag.
5493 * If SA_INTERRUPT is not set, then interrupts are enabled
5494 * before the driver interrupt function is called.
5496 if (((ret = request_irq(shp->irq, advansys_interrupt,
5497 SA_INTERRUPT | (share_irq == TRUE ? SA_SHIRQ : 0),
5498 "advansys", boardp)) != 0) &&
5499 ((ret = request_irq(shp->irq, advansys_interrupt,
5500 (share_irq == TRUE ? SA_SHIRQ : 0),
5501 "advansys", boardp)) != 0))
5502 #endif /* version >= v1.3.70 */
5504 if (ret == -EBUSY) {
5505 ASC_PRINT2(
5506 "advansys_detect: board %d: request_irq(): IRQ %d already in use.\n",
5507 boardp->id, shp->irq);
5508 } else if (ret == -EINVAL) {
5509 ASC_PRINT2(
5510 "advansys_detect: board %d: request_irq(): IRQ %d not valid.\n",
5511 boardp->id, shp->irq);
5512 } else {
5513 ASC_PRINT3(
5514 "advansys_detect: board %d: request_irq(): IRQ %d failed with %d\n",
5515 boardp->id, shp->irq, ret);
5517 release_region(shp->io_port, shp->n_io_port);
5518 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
5519 iounmap(boardp->ioremap_addr);
5520 #endif /* version >= v1,3,0 */
5521 if (shp->dma_channel != NO_ISA_DMA) {
5522 free_dma(shp->dma_channel);
5524 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
5525 kfree(boardp->prtbuf);
5526 #endif /* version >= v1.3.0 */
5527 scsi_unregister(shp);
5528 asc_board_count--;
5529 continue;
5533 * Initialize board RISC chip and enable interrupts.
5535 if (ASC_NARROW_BOARD(boardp)) {
5536 ASC_DBG(2, "advansys_detect: AscInitAsc1000Driver()\n");
5537 warn_code = AscInitAsc1000Driver(asc_dvc_varp);
5538 err_code = asc_dvc_varp->err_code;
5540 if (warn_code || err_code) {
5541 ASC_PRINT4(
5542 "AscInitAsc1000Driver: board %d: error: init_state %x, warn %x error %x\n",
5543 boardp->id, asc_dvc_varp->init_state,
5544 warn_code, err_code);
5546 } else {
5547 ADV_CARR_T *carrp;
5548 int req_cnt;
5549 adv_req_t *reqp = NULL;
5550 int sg_cnt = 0;
5552 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0)
5553 carrp = (ADV_CARR_T *) &adv_carr_buf[0];
5554 req_cnt = sizeof(adv_req_buf)/sizeof(adv_req_t);
5555 sg_cnt = sizeof(adv_sgblk_buf)/sizeof(adv_sgblk_t);
5556 reqp = (adv_req_t *) &adv_req_buf[0];
5557 boardp->adv_sgblkp = NULL;
5558 for (sg_cnt = 0; sg_cnt < ADV_SGBLK_BUF_CNT; sg_cnt++) {
5559 sgp = (adv_sgblk_t *) &adv_sgblk_buf[sg_cnt];
5560 sgp->next_sgblkp = boardp->adv_sgblkp;
5561 boardp->adv_sgblkp = sgp;
5563 #else /* version >= v1.3.0 */
5565 * Allocate buffer carrier structures. The total size
5566 * is about 4 KB, so allocate all at once.
5568 carrp =
5569 (ADV_CARR_T *) kmalloc(ADV_CARRIER_BUFSIZE, GFP_ATOMIC);
5570 ASC_DBG1(1, "advansys_detect: carrp %lx\n", (ulong) carrp);
5572 if (carrp == NULL) {
5573 goto kmalloc_error;
5577 * Allocate up to 'max_host_qng' request structures for
5578 * the Wide board. The total size is about 16 KB, so
5579 * allocate all at once. If the allocation fails decrement
5580 * and try again.
5582 for (req_cnt = adv_dvc_varp->max_host_qng;
5583 req_cnt > 0; req_cnt--) {
5585 reqp = (adv_req_t *)
5586 kmalloc(sizeof(adv_req_t) * req_cnt, GFP_ATOMIC);
5588 ASC_DBG3(1,
5589 "advansys_detect: reqp %lx, req_cnt %d, bytes %lu\n",
5590 (ulong) reqp, req_cnt,
5591 (ulong) sizeof(adv_req_t) * req_cnt);
5593 if (reqp != NULL) {
5594 break;
5597 if (reqp == NULL)
5599 goto kmalloc_error;
5603 * Allocate up to ADV_TOT_SG_BLOCK request structures for
5604 * the Wide board. Each structure is about 136 bytes.
5606 boardp->adv_sgblkp = NULL;
5607 for (sg_cnt = 0; sg_cnt < ADV_TOT_SG_BLOCK; sg_cnt++) {
5609 sgp = (adv_sgblk_t *)
5610 kmalloc(sizeof(adv_sgblk_t), GFP_ATOMIC);
5612 if (sgp == NULL) {
5613 break;
5616 sgp->next_sgblkp = boardp->adv_sgblkp;
5617 boardp->adv_sgblkp = sgp;
5620 ASC_DBG3(1,
5621 "advansys_detect: sg_cnt %d * %u = %u bytes\n",
5622 sg_cnt, sizeof(adv_sgblk_t),
5623 (unsigned) (sizeof(adv_sgblk_t) * sg_cnt));
5626 * If no request structures or scatter-gather structures could
5627 * be allocated, then return an error. Otherwise continue with
5628 * initialization.
5630 kmalloc_error:
5631 if (carrp == NULL)
5633 ASC_PRINT1(
5634 "advansys_detect: board %d: error: failed to kmalloc() carrier buffer.\n",
5635 boardp->id);
5636 err_code = ADV_ERROR;
5637 } else if (reqp == NULL) {
5638 kfree(carrp);
5639 ASC_PRINT1(
5640 "advansys_detect: board %d: error: failed to kmalloc() adv_req_t buffer.\n",
5641 boardp->id);
5642 err_code = ADV_ERROR;
5643 } else if (boardp->adv_sgblkp == NULL) {
5644 kfree(carrp);
5645 kfree(reqp);
5646 ASC_PRINT1(
5647 "advansys_detect: board %d: error: failed to kmalloc() adv_sgblk_t buffers.\n",
5648 boardp->id);
5649 err_code = ADV_ERROR;
5650 } else {
5652 /* Save carrier buffer pointer. */
5653 boardp->orig_carrp = carrp;
5656 * Save original pointer for kfree() in case the
5657 * driver is built as a module and can be unloaded.
5659 boardp->orig_reqp = reqp;
5660 #endif /* version >= v1.3.0 */
5662 adv_dvc_varp->carrier_buf = carrp;
5665 * Point 'adv_reqp' to the request structures and
5666 * link them together.
5668 req_cnt--;
5669 reqp[req_cnt].next_reqp = NULL;
5670 for (; req_cnt > 0; req_cnt--) {
5671 reqp[req_cnt - 1].next_reqp = &reqp[req_cnt];
5673 boardp->adv_reqp = &reqp[0];
5675 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
5677 ASC_DBG(2,
5678 "advansys_detect: AdvInitAsc3550Driver()\n");
5679 warn_code = AdvInitAsc3550Driver(adv_dvc_varp);
5680 } else {
5681 ASC_DBG(2,
5682 "advansys_detect: AdvInitAsc38C0800Driver()\n");
5683 warn_code = AdvInitAsc38C0800Driver(adv_dvc_varp);
5685 err_code = adv_dvc_varp->err_code;
5687 if (warn_code || err_code) {
5688 ASC_PRINT3(
5689 "AdvInitAsc3550/38C0800Driver: board %d: error: warn %x, error %x\n",
5690 boardp->id, warn_code, err_code);
5692 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
5694 #endif /* version >= v1,3,0 */
5697 if (err_code != 0) {
5698 release_region(shp->io_port, shp->n_io_port);
5699 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
5700 if (ASC_WIDE_BOARD(boardp)) {
5701 iounmap(boardp->ioremap_addr);
5702 if (boardp->orig_carrp) {
5703 kfree(boardp->orig_carrp);
5704 boardp->orig_carrp = NULL;
5706 if (boardp->orig_reqp) {
5707 kfree(boardp->orig_reqp);
5708 boardp->orig_reqp = boardp->adv_reqp = NULL;
5710 while ((sgp = boardp->adv_sgblkp) != NULL)
5712 boardp->adv_sgblkp = sgp->next_sgblkp;
5713 kfree(sgp);
5716 #endif /* version >= v1,3,0 */
5717 if (shp->dma_channel != NO_ISA_DMA) {
5718 free_dma(shp->dma_channel);
5720 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
5721 kfree(boardp->prtbuf);
5722 #endif /* version >= v1.3.0 */
5723 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,70)
5724 free_irq(shp->irq);
5725 #else /* version >= v1.3.70 */
5726 free_irq(shp->irq, boardp);
5727 #endif /* version >= v1.3.70 */
5728 scsi_unregister(shp);
5729 asc_board_count--;
5730 continue;
5732 ASC_DBG_PRT_SCSI_HOST(2, shp);
5735 ASC_DBG1(1, "advansys_detect: done: asc_board_count %d\n", asc_board_count);
5736 return asc_board_count;
5740 * advansys_release()
5742 * Release resources allocated for a single AdvanSys adapter.
5745 advansys_release(struct Scsi_Host *shp)
5747 asc_board_t *boardp;
5749 ASC_DBG(1, "advansys_release: begin\n");
5750 boardp = ASC_BOARDP(shp);
5751 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,70)
5752 free_irq(shp->irq);
5753 #else /* version >= v1.3.70 */
5754 free_irq(shp->irq, boardp);
5755 #endif /* version >= v1.3.70 */
5756 if (shp->dma_channel != NO_ISA_DMA) {
5757 ASC_DBG(1, "advansys_release: free_dma()\n");
5758 free_dma(shp->dma_channel);
5760 release_region(shp->io_port, shp->n_io_port);
5761 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
5762 if (ASC_WIDE_BOARD(boardp)) {
5763 adv_sgblk_t *sgp = NULL;
5765 iounmap(boardp->ioremap_addr);
5766 if (boardp->orig_carrp) {
5767 kfree(boardp->orig_carrp);
5768 boardp->orig_carrp = NULL;
5770 if (boardp->orig_reqp) {
5771 kfree(boardp->orig_reqp);
5772 boardp->orig_reqp = boardp->adv_reqp = NULL;
5774 while ((sgp = boardp->adv_sgblkp) != NULL)
5776 boardp->adv_sgblkp = sgp->next_sgblkp;
5777 kfree(sgp);
5780 ASC_ASSERT(boardp->prtbuf != NULL);
5781 kfree(boardp->prtbuf);
5782 #endif /* version >= v1.3.0 */
5783 scsi_unregister(shp);
5784 ASC_DBG(1, "advansys_release: end\n");
5785 return 0;
5789 * advansys_info()
5791 * Return suitable for printing on the console with the argument
5792 * adapter's configuration information.
5794 * Note: The information line should not exceed ASC_INFO_SIZE bytes,
5795 * otherwise the static 'info' array will be overrun.
5797 const char *
5798 advansys_info(struct Scsi_Host *shp)
5800 static char info[ASC_INFO_SIZE];
5801 asc_board_t *boardp;
5802 ASC_DVC_VAR *asc_dvc_varp;
5803 ADV_DVC_VAR *adv_dvc_varp;
5804 char *busname;
5805 int iolen;
5806 char *widename = NULL;
5808 boardp = ASC_BOARDP(shp);
5809 if (ASC_NARROW_BOARD(boardp)) {
5810 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
5811 ASC_DBG(1, "advansys_info: begin\n");
5812 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
5813 if ((asc_dvc_varp->bus_type & ASC_IS_ISAPNP) == ASC_IS_ISAPNP) {
5814 busname = "ISA PnP";
5815 } else {
5816 busname = "ISA";
5818 sprintf(info,
5819 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,92)
5820 "AdvanSys SCSI %s: %s %u CDB: BIOS %lX, IO %lX/%X, IRQ %u, DMA %u",
5821 #else /* version >= v2.1.92 */
5822 "AdvanSys SCSI %s: %s %u CDB: BIOS %lX, IO %lX/%X, IRQ %u, DMA %u",
5823 #endif /* version >= v2.1.92 */
5824 ASC_VERSION, busname, asc_dvc_varp->max_total_qng,
5825 (ulong) shp->base,
5826 (ulong) shp->io_port, shp->n_io_port - 1,
5827 shp->irq, shp->dma_channel);
5828 } else if (asc_dvc_varp->bus_type & ASC_IS_PCI) {
5829 if ((asc_dvc_varp->bus_type & ASC_IS_PCI_ULTRA)
5830 == ASC_IS_PCI_ULTRA) {
5831 busname = "PCI Ultra";
5832 } else {
5833 busname = "PCI";
5835 sprintf(info,
5836 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,92)
5837 "AdvanSys SCSI %s: %s %u CDB: IO %X/%X, IRQ %u",
5838 #else /* version >= v2.1.92 */
5839 "AdvanSys SCSI %s: %s %u CDB: IO %lX/%X, IRQ %u",
5840 #endif /* version >= v2.1.92 */
5841 ASC_VERSION, busname, asc_dvc_varp->max_total_qng,
5842 shp->io_port, shp->n_io_port - 1, shp->irq);
5843 } else {
5844 if (asc_dvc_varp->bus_type & ASC_IS_VL) {
5845 busname = "VL";
5846 } else if (asc_dvc_varp->bus_type & ASC_IS_EISA) {
5847 busname = "EISA";
5848 } else {
5849 busname = "?";
5850 ASC_PRINT2(
5851 "advansys_info: board %d: unknown bus type %d\n",
5852 boardp->id, asc_dvc_varp->bus_type);
5854 sprintf(info,
5855 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,92)
5856 "AdvanSys SCSI %s: %s %u CDB: BIOS %lX, IO %X/%X, IRQ %u",
5857 #else /* version >= v2.1.92 */
5858 "AdvanSys SCSI %s: %s %u CDB: BIOS %lX, IO %lX/%X, IRQ %u",
5859 #endif /* version >= v2.1.92 */
5860 ASC_VERSION, busname, asc_dvc_varp->max_total_qng,
5861 (ulong) shp->base, shp->io_port - 1,
5862 shp->n_io_port, shp->irq);
5864 } else {
5866 * Wide Adapter Information
5868 * Memory-mapped I/O is used instead of I/O space to access
5869 * the adapter, but display the I/O Port range. The Memory
5870 * I/O address is displayed through the driver /proc file.
5872 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
5873 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
5875 iolen = ADV_3550_IOLEN;
5876 widename = "Ultra-Wide";
5877 } else {
5878 iolen = ADV_38C0800_IOLEN;
5879 widename = "Ultra2-Wide";
5881 if (boardp->bios_signature == 0x55AA) {
5882 sprintf(info,
5883 "AdvanSys SCSI %s: PCI %s: BIOS %X/%X, IO %X/%X, IRQ %u",
5884 ASC_VERSION,
5885 widename,
5886 boardp->bios_codeseg << 4,
5887 boardp->bios_codelen > 0 ?
5888 (boardp->bios_codelen << 9) - 1 : 0,
5889 (unsigned) boardp->ioport, iolen - 1,
5890 shp->irq);
5891 } else {
5892 sprintf(info,
5893 "AdvanSys SCSI %s: PCI %s: IO %X/%X, IRQ %u",
5894 ASC_VERSION,
5895 widename,
5896 (unsigned) boardp->ioport,
5897 (iolen - 1),
5898 shp->irq);
5901 ASC_ASSERT(strlen(info) < ASC_INFO_SIZE);
5902 ASC_DBG(1, "advansys_info: end\n");
5903 return info;
5907 * advansys_command() - polled I/O entrypoint.
5909 * Apparently host drivers shouldn't return until the command
5910 * is finished.
5912 * Note: This is an old interface that is no longer used by the SCSI
5913 * mid-level driver. The new interface, advansys_queuecommand(),
5914 * currently handles all requests.
5917 advansys_command(Scsi_Cmnd *scp)
5919 ASC_DBG1(1, "advansys_command: scp %lx\n", (ulong) scp);
5920 ASC_STATS(scp->host, command);
5921 scp->SCp.Status = 0; /* Set to a known state */
5922 advansys_queuecommand(scp, advansys_command_done);
5923 while (scp->SCp.Status == 0) {
5924 continue;
5926 ASC_DBG1(1, "advansys_command: result %x\n", scp->result);
5927 return scp->result;
5931 * advansys_queuecommand() - interrupt-driven I/O entrypoint.
5933 * This function always returns 0. Command return status is saved
5934 * in the 'scp' result field.
5937 advansys_queuecommand(Scsi_Cmnd *scp, void (*done)(Scsi_Cmnd *))
5939 struct Scsi_Host *shp;
5940 asc_board_t *boardp;
5941 int flags;
5942 Scsi_Cmnd *done_scp;
5944 shp = scp->host;
5945 boardp = ASC_BOARDP(shp);
5946 ASC_STATS(shp, queuecommand);
5949 * Disable interrupts to preserve request ordering and provide
5950 * mutually exclusive access to global structures used to initiate
5951 * a request.
5953 save_flags(flags);
5954 cli();
5957 * Block new commands while handling a reset or abort request.
5959 if (boardp->flags & (ASC_HOST_IN_RESET | ASC_HOST_IN_ABORT)) {
5960 if (boardp->flags & ASC_HOST_IN_RESET) {
5961 ASC_DBG1(1,
5962 "advansys_queuecommand: scp %lx blocked for reset request\n",
5963 (ulong) scp);
5964 scp->result = HOST_BYTE(DID_RESET);
5965 } else {
5966 ASC_DBG1(1,
5967 "advansys_queuecommand: scp %lx blocked for abort request\n",
5968 (ulong) scp);
5969 scp->result = HOST_BYTE(DID_ABORT);
5973 * Add blocked requests to the board's 'done' queue. The queued
5974 * requests will be completed at the end of the abort or reset
5975 * handling.
5977 asc_enqueue(&boardp->done, scp, ASC_BACK);
5978 restore_flags(flags);
5979 return 0;
5983 * Attempt to execute any waiting commands for the board.
5985 if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
5986 ASC_DBG(1,
5987 "advansys_queuecommand: before asc_execute_queue() waiting\n");
5988 asc_execute_queue(&boardp->waiting);
5992 * Save the function pointer to Linux mid-level 'done' function
5993 * and attempt to execute the command.
5995 * If ASC_ERROR is returned the request has been added to the
5996 * board's 'active' queue and will be completed by the interrupt
5997 * handler.
5999 * If ASC_BUSY is returned add the request to the board's per
6000 * target waiting list.
6002 * If an error occurred, the request will have been placed on the
6003 * board's 'done' queue and must be completed before returning.
6005 scp->scsi_done = done;
6006 switch (asc_execute_scsi_cmnd(scp)) {
6007 case ASC_NOERROR:
6008 break;
6009 case ASC_BUSY:
6010 asc_enqueue(&boardp->waiting, scp, ASC_BACK);
6011 break;
6012 case ASC_ERROR:
6013 default:
6014 done_scp = asc_dequeue_list(&boardp->done, NULL, ASC_TID_ALL);
6015 /* Interrupts could be enabled here. */
6016 asc_scsi_done_list(done_scp);
6017 break;
6020 restore_flags(flags);
6021 return 0;
6025 * advansys_abort()
6027 * Abort the command specified by 'scp'.
6030 advansys_abort(Scsi_Cmnd *scp)
6032 struct Scsi_Host *shp;
6033 asc_board_t *boardp;
6034 ASC_DVC_VAR *asc_dvc_varp;
6035 ADV_DVC_VAR *adv_dvc_varp;
6036 int flags;
6037 int do_scsi_done;
6038 int scp_found;
6039 Scsi_Cmnd *done_scp = NULL;
6040 int ret;
6042 /* Save current flags and disable interrupts. */
6043 save_flags(flags);
6044 cli();
6046 ASC_DBG1(1, "advansys_abort: scp %lx\n", (ulong) scp);
6048 #ifdef ADVANSYS_STATS
6049 if (scp->host != NULL) {
6050 ASC_STATS(scp->host, abort);
6052 #endif /* ADVANSYS_STATS */
6054 #ifdef ADVANSYS_ASSERT
6055 do_scsi_done = ASC_ERROR;
6056 scp_found = ASC_ERROR;
6057 ret = ASC_ERROR;
6058 #endif /* ADVANSYS_ASSERT */
6060 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
6061 if (scp->serial_number != scp->serial_number_at_timeout) {
6062 ASC_PRINT1(
6063 "advansys_abort: timeout serial number changed for request %lx\n",
6064 (ulong) scp);
6065 do_scsi_done = ASC_FALSE;
6066 scp_found = ASC_FALSE;
6067 ret = SCSI_ABORT_NOT_RUNNING;
6068 } else
6069 #endif /* version >= v1.3.89 */
6070 if ((shp = scp->host) == NULL) {
6071 scp->result = HOST_BYTE(DID_ERROR);
6072 do_scsi_done = ASC_TRUE;
6073 scp_found = ASC_FALSE;
6074 ret = SCSI_ABORT_ERROR;
6075 } else if ((boardp = ASC_BOARDP(shp))->flags &
6076 (ASC_HOST_IN_RESET | ASC_HOST_IN_ABORT)) {
6077 ASC_PRINT2(
6078 "advansys_abort: board %d: Nested host reset or abort, flags 0x%x\n",
6079 boardp->id, boardp->flags);
6080 do_scsi_done = ASC_TRUE;
6081 if ((asc_rmqueue(&boardp->active, scp) == ASC_TRUE) ||
6082 (asc_rmqueue(&boardp->waiting, scp) == ASC_TRUE)) {
6083 scp_found = ASC_TRUE;
6084 } else {
6085 scp_found = ASC_FALSE;
6087 scp->result = HOST_BYTE(DID_ERROR);
6088 ret = SCSI_ABORT_ERROR;
6089 } else {
6090 /* Set abort flag to avoid nested reset or abort requests. */
6091 boardp->flags |= ASC_HOST_IN_ABORT;
6093 do_scsi_done = ASC_TRUE;
6094 if (asc_rmqueue(&boardp->waiting, scp) == ASC_TRUE) {
6096 * If asc_rmqueue() found the command on the waiting
6097 * queue, it had not been sent to the device. After
6098 * the queue is removed, no other handling is required.
6100 ASC_DBG1(1, "advansys_abort: scp %lx found on waiting queue\n",
6101 (ulong) scp);
6102 scp_found = ASC_TRUE;
6103 scp->result = HOST_BYTE(DID_ABORT);
6104 ret = SCSI_ABORT_SUCCESS;
6105 } else if (asc_isqueued(&boardp->active, scp) == ASC_TRUE) {
6107 * If asc_isqueued() found the command on the active
6108 * queue, it has been sent to the device. The command
6109 * will be returned through the interrupt handler after
6110 * it has been aborted.
6113 if (ASC_NARROW_BOARD(boardp)) {
6115 * Narrow Board
6117 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
6118 scp->result = HOST_BYTE(DID_ABORT);
6120 /* sti(); XXX */ /* Enable interrupts for AscAbortSRB(). */
6121 ASC_DBG1(1, "advansys_abort: before AscAbortSRB(), scp %lx\n",
6122 (ulong) scp);
6123 /* XXX */
6124 switch (AscAbortSRB(asc_dvc_varp, ASC_VADDR_TO_U32(scp))) {
6125 case ASC_TRUE:
6126 /* asc_isr_callback() will be called */
6127 ASC_DBG(1, "advansys_abort: AscAbortSRB() TRUE\n");
6128 ret = SCSI_ABORT_PENDING;
6129 break;
6130 case ASC_FALSE:
6131 /* Request has apparently already completed. */
6132 ASC_DBG(1, "advansys_abort: AscAbortSRB() FALSE\n");
6133 ret = SCSI_ABORT_NOT_RUNNING;
6134 break;
6135 case ASC_ERROR:
6136 default:
6137 ASC_DBG(1, "advansys_abort: AscAbortSRB() ERROR\n");
6138 ret = SCSI_ABORT_ERROR;
6139 break;
6141 cli();
6142 } else {
6144 * Wide Board
6146 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
6147 scp->result = HOST_BYTE(DID_ABORT);
6149 ASC_DBG1(1,
6150 "advansys_abort: before AdvAbortQueue(), scp %lx\n",
6151 (ulong) scp);
6152 #if 0 /* XXX */
6153 switch (AdvAbortQueue(adv_dvc_varp, (ADV_VADDR) XXX)) {
6154 case ASC_TRUE:
6155 /* asc_isr_callback() will be called */
6156 ASC_DBG(1, "advansys_abort: AdvAbortQueue() TRUE\n");
6157 ret = SCSI_ABORT_PENDING;
6158 break;
6159 case ASC_FALSE:
6160 /* Request has apparently already completed. */
6161 ASC_DBG(1, "advansys_abort: AdvAbortQueue() FALSE\n");
6162 ret = SCSI_ABORT_NOT_RUNNING;
6163 break;
6164 case ASC_ERROR:
6165 default:
6166 ASC_DBG(1, "advansys_abort: AdvAbortQueue() ERROR\n");
6167 ret = SCSI_ABORT_ERROR;
6168 break;
6171 * Ensure all requests completed by the microcode have
6172 * been processed by calling AdvISR().
6174 (void) AdvISR(adv_dvc_varp);
6175 #else /* XXX */
6176 (void) AdvResetChipAndSB(adv_dvc_varp);
6177 ret = SCSI_ABORT_SUCCESS;
6178 #endif /* XXX */
6182 * The request will either still be on the active queue
6183 * or have been added to the board's done queue.
6185 if (asc_rmqueue(&boardp->active, scp) == ASC_TRUE) {
6186 scp->result = HOST_BYTE(DID_ABORT);
6187 scp_found = ASC_TRUE;
6188 } else {
6189 scp_found = asc_rmqueue(&boardp->done, scp);
6190 ASC_ASSERT(scp_found == ASC_TRUE);
6192 } else {
6194 * The command was not found on the active or waiting queues.
6196 do_scsi_done = ASC_TRUE;
6197 scp_found = ASC_FALSE;
6198 ret = SCSI_ABORT_NOT_RUNNING;
6201 /* Clear abort flag. */
6202 boardp->flags &= ~ASC_HOST_IN_ABORT;
6205 * Because the ASC_HOST_IN_ABORT flag causes both
6206 * 'advansys_interrupt' and 'asc_isr_callback' to
6207 * queue requests to the board's 'done' queue and
6208 * prevents waiting commands from being executed,
6209 * these queued requests must be handled here.
6211 done_scp = asc_dequeue_list(&boardp->done, NULL, ASC_TID_ALL);
6214 * Start any waiting commands for the board.
6216 if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
6217 ASC_DBG(1, "advansys_interrupt: before asc_execute_queue()\n");
6218 asc_execute_queue(&boardp->waiting);
6222 /* Interrupts could be enabled here. */
6225 * Complete the request to be aborted, unless it has been
6226 * restarted as detected above, even if it was not found on
6227 * the device active or waiting queues.
6229 ASC_ASSERT(do_scsi_done != ASC_ERROR);
6230 ASC_ASSERT(scp_found != ASC_ERROR);
6231 if (do_scsi_done == ASC_TRUE) {
6232 if (scp->scsi_done == NULL) {
6233 ASC_PRINT1(
6234 "advansys_abort: aborted request scsi_done() is NULL, %lx\n",
6235 (ulong) scp);
6236 } else {
6237 if (scp_found == ASC_FALSE) {
6238 ASC_PRINT1(
6239 "advansys_abort: abort request not active or waiting, completing anyway %lx\n",
6240 (ulong) scp);
6242 ASC_STATS(scp->host, done);
6243 scp->scsi_done(scp);
6248 * It is possible for the request done function to re-enable
6249 * interrupts without confusing the driver. But here interrupts
6250 * aren't enabled until all requests have been completed.
6252 if (done_scp != NULL) {
6253 asc_scsi_done_list(done_scp);
6256 ASC_DBG1(1, "advansys_abort: ret %d\n", ret);
6258 /* Re-enable interrupts, if they were enabled on entry. */
6259 restore_flags(flags);
6261 ASC_ASSERT(ret != ASC_ERROR);
6262 return ret;
6266 * advansys_reset()
6268 * Reset the device associated with the command 'scp'.
6271 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,89)
6272 advansys_reset(Scsi_Cmnd *scp)
6273 #else /* version >= v1.3.89 */
6274 advansys_reset(Scsi_Cmnd *scp, unsigned int reset_flags)
6275 #endif /* version >= v1.3.89 */
6277 struct Scsi_Host *shp;
6278 asc_board_t *boardp;
6279 ASC_DVC_VAR *asc_dvc_varp;
6280 ADV_DVC_VAR *adv_dvc_varp;
6281 int flags;
6282 Scsi_Cmnd *done_scp = NULL, *last_scp = NULL;
6283 Scsi_Cmnd *tscp, *new_last_scp;
6284 int do_scsi_done;
6285 int scp_found;
6286 int status;
6287 int target;
6288 int ret;
6289 int device_reset = ASC_FALSE;
6291 /* Save current flags and disable interrupts. */
6292 save_flags(flags);
6293 cli();
6295 ASC_DBG1(1, "advansys_reset: %lx\n", (ulong) scp);
6297 #ifdef ADVANSYS_STATS
6298 if (scp->host != NULL) {
6299 ASC_STATS(scp->host, reset);
6301 #endif /* ADVANSYS_STATS */
6303 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
6304 if ((reset_flags & SCSI_RESET_ASYNCHRONOUS) &&
6305 (scp->serial_number != scp->serial_number_at_timeout)) {
6306 ASC_PRINT1(
6307 "advansys_reset: timeout serial number changed for request %lx\n",
6308 (ulong) scp);
6309 do_scsi_done = ASC_FALSE;
6310 scp_found = ASC_FALSE;
6311 ret = SCSI_RESET_NOT_RUNNING;
6312 } else
6313 #endif /* version >= v1.3.89 */
6314 if ((shp = scp->host) == NULL) {
6315 scp->result = HOST_BYTE(DID_ERROR);
6316 do_scsi_done = ASC_TRUE;
6317 scp_found = ASC_FALSE;
6318 ret = SCSI_RESET_ERROR;
6319 } else if ((boardp = ASC_BOARDP(shp))->flags &
6320 (ASC_HOST_IN_RESET | ASC_HOST_IN_ABORT)) {
6321 ASC_PRINT2(
6322 "advansys_reset: board %d: Nested host reset or abort, flags 0x%x\n",
6323 boardp->id, boardp->flags);
6324 do_scsi_done = ASC_TRUE;
6325 if ((asc_rmqueue(&boardp->active, scp) == ASC_TRUE) ||
6326 (asc_rmqueue(&boardp->waiting, scp) == ASC_TRUE)) {
6327 scp_found = ASC_TRUE;
6328 } else {
6329 scp_found = ASC_FALSE;
6331 scp->result = HOST_BYTE(DID_ERROR);
6332 ret = SCSI_RESET_ERROR;
6333 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(2,1,0)
6334 } else if (time_after_eq(jiffies, boardp->last_reset) &&
6335 time_before(jiffies, boardp->last_reset + (10 * HZ))) {
6336 #else /* version < v2.1.0 */
6337 } else if (jiffies >= boardp->last_reset &&
6338 jiffies < (boardp->last_reset + (10 * HZ))) {
6339 #endif /* version < v2.1.0 */
6341 * Don't allow a reset to be attempted within 10 seconds
6342 * of the last reset.
6344 * If 'jiffies' wrapping occurs, the reset request will go
6345 * through, because a wrapped 'jiffies' would not pass the
6346 * test above.
6348 ASC_DBG(1,
6349 "advansys_reset: reset within 10 sec of last reset ignored\n");
6350 do_scsi_done = ASC_TRUE;
6351 if ((asc_rmqueue(&boardp->active, scp) == ASC_TRUE) ||
6352 (asc_rmqueue(&boardp->waiting, scp) == ASC_TRUE)) {
6353 scp_found = ASC_TRUE;
6354 } else {
6355 scp_found = ASC_FALSE;
6357 scp->result = HOST_BYTE(DID_ERROR);
6358 ret = SCSI_RESET_ERROR;
6359 } else {
6360 do_scsi_done = ASC_TRUE;
6362 /* Set reset flag to avoid nested reset or abort requests. */
6363 boardp->flags |= ASC_HOST_IN_RESET;
6366 * If the request is on the target waiting or active queue
6367 * or the board done queue, then remove it and note that it
6368 * was found.
6370 if (asc_rmqueue(&boardp->active, scp) == ASC_TRUE) {
6371 ASC_DBG(1, "advansys_reset: active scp_found = TRUE\n");
6372 scp_found = ASC_TRUE;
6373 } else if (asc_rmqueue(&boardp->waiting, scp) == ASC_TRUE) {
6374 ASC_DBG(1, "advansys_reset: waiting scp_found = TRUE\n");
6375 scp_found = ASC_TRUE;
6376 } else if (asc_rmqueue(&boardp->done, scp) == ASC_TRUE) {
6377 scp_found = ASC_TRUE;
6378 } else {
6379 scp_found = ASC_FALSE;
6383 if (ASC_NARROW_BOARD(boardp)) {
6385 * Narrow Board
6387 * If the suggest reset bus flags are set, then reset the bus.
6388 * Otherwise only reset the device.
6390 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
6391 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
6392 if (reset_flags &
6393 (SCSI_RESET_SUGGEST_BUS_RESET |
6394 SCSI_RESET_SUGGEST_HOST_RESET)) {
6395 #endif /* version >= v1.3.89 */
6398 * Reset the target's SCSI bus.
6400 ASC_DBG(1, "advansys_reset: before AscResetSB()\n");
6401 /* sti(); XXX */ /* Enable interrupts for AscResetSB(). */
6402 status = AscResetSB(asc_dvc_varp);
6403 /* cli(); XXX */
6404 switch (status) {
6405 case ASC_TRUE:
6406 ASC_DBG(1, "advansys_reset: AscResetSB() success\n");
6407 ret = SCSI_RESET_SUCCESS;
6408 break;
6409 case ASC_ERROR:
6410 default:
6411 ASC_DBG(1, "advansys_reset: AscResetSB() failed\n");
6412 ret = SCSI_RESET_ERROR;
6413 break;
6416 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
6417 } else {
6419 * Reset the specified device. If the device reset fails,
6420 * then reset the SCSI bus.
6423 ASC_DBG1(1,
6424 "advansys_reset: before AscResetDevice(), target %d\n",
6425 scp->target);
6426 /* sti(); XXX */ /* Enable interrupts for AscResetDevice(). */
6427 status = AscResetDevice(asc_dvc_varp, scp->target);
6428 /* cli(); XXX */
6430 switch (status) {
6431 case ASC_TRUE:
6432 ASC_DBG(1, "advansys_reset: AscResetDevice() success\n");
6433 device_reset = ASC_TRUE;
6434 ret = SCSI_RESET_SUCCESS;
6435 break;
6436 case ASC_ERROR:
6437 default:
6438 ASC_DBG(1,
6439 "advansys_reset: AscResetDevice() failed; Calling AscResetSB()\n");
6440 /* sti(); XXX */ /* Enable interrupts for AscResetSB(). */
6441 status = AscResetSB(asc_dvc_varp);
6442 /* cli(); XXX */
6443 switch (status) {
6444 case ASC_TRUE:
6445 ASC_DBG(1, "advansys_reset: AscResetSB() TRUE\n");
6446 ret = SCSI_RESET_SUCCESS;
6447 break;
6448 case ASC_ERROR:
6449 default:
6450 ASC_DBG(1, "advansys_reset: AscResetSB() ERROR\n");
6451 ret = SCSI_RESET_ERROR;
6452 break;
6454 break;
6457 #endif /* version >= v1.3.89 */
6458 } else {
6460 * Wide Board
6462 * If the suggest reset bus flags are set, then reset the bus.
6463 * Otherwise only reset the device.
6465 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
6466 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
6467 if (reset_flags &
6468 (SCSI_RESET_SUGGEST_BUS_RESET |
6469 SCSI_RESET_SUGGEST_HOST_RESET)) {
6470 #endif /* version >= v1.3.89 */
6473 * Reset the target's SCSI bus.
6475 ASC_DBG(1, "advansys_reset: before AdvResetChipAndSB()\n");
6476 switch (AdvResetChipAndSB(adv_dvc_varp)) {
6477 case ASC_TRUE:
6478 ASC_DBG(1,
6479 "advansys_reset: AdvResetChipAndSB() success\n");
6480 ret = SCSI_RESET_SUCCESS;
6481 break;
6482 case ASC_FALSE:
6483 default:
6484 ASC_DBG(1, "advansys_reset: AdvResetChipAndSB() failed\n");
6485 ret = SCSI_RESET_ERROR;
6486 break;
6489 * Ensure all requests completed by the microcode have
6490 * been processed by calling AdvISR().
6492 (void) AdvISR(adv_dvc_varp);
6493 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
6494 } else {
6496 * Reset the specified device. If the device reset fails,
6497 * then reset the SCSI bus.
6500 ASC_DBG1(1,
6501 "advansys_reset: before AdvResetDevice(), target %d\n",
6502 scp->target);
6504 switch (AdvResetDevice(adv_dvc_varp, scp->target)) {
6505 case ASC_TRUE:
6506 ASC_DBG(1, "advansys_reset: AdvResetDevice() success\n");
6507 device_reset = ASC_TRUE;
6508 ret = SCSI_RESET_SUCCESS;
6509 break;
6510 case ASC_FALSE:
6511 default:
6512 ASC_DBG(1,
6513 "advansys_reset: AdvResetDevice() failed; Calling AdvResetChipAndSB()\n");
6515 switch (AdvResetChipAndSB(adv_dvc_varp)) {
6516 case ASC_TRUE:
6517 ASC_DBG(1,
6518 "advansys_reset: AdvResetChipAndSB() TRUE\n");
6519 ret = SCSI_RESET_SUCCESS;
6520 break;
6521 case ASC_FALSE:
6522 default:
6523 ASC_DBG(1,
6524 "advansys_reset: AdvResetChipAndSB() ERROR\n");
6525 ret = SCSI_RESET_ERROR;
6526 break;
6528 break;
6531 * Ensure all requests completed by the microcode have
6532 * been processed by calling AdvISR().
6534 (void) AdvISR(adv_dvc_varp);
6536 #endif /* version >= v1.3.89 */
6540 * Because the ASC_HOST_IN_RESET flag causes both
6541 * 'advansys_interrupt' and 'asc_isr_callback' to
6542 * queue requests to the board's 'done' queue and
6543 * prevents waiting commands from being executed,
6544 * these queued requests must be handled here.
6546 done_scp = asc_dequeue_list(&boardp->done, &last_scp,
6547 ASC_TID_ALL);
6550 * If a device reset was performed dequeue all waiting
6551 * and active requests for the device and set the request
6552 * status to DID_RESET.
6554 * If a SCSI bus reset was performed dequeue all waiting
6555 * and active requests for all devices and set the request
6556 * status to DID_RESET.
6558 if (device_reset == ASC_TRUE) {
6559 target = scp->target;
6560 } else {
6561 target = ASC_TID_ALL;
6565 * Add active requests to 'done_scp' and set the request status
6566 * to DID_RESET.
6568 if (done_scp == NULL) {
6569 done_scp = asc_dequeue_list(&boardp->active, &last_scp, target);
6570 for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) {
6571 tscp->result = HOST_BYTE(DID_RESET);
6573 } else {
6574 ASC_ASSERT(last_scp != NULL);
6575 REQPNEXT(last_scp) = asc_dequeue_list(&boardp->active,
6576 &new_last_scp, target);
6577 if (new_last_scp != NULL) {
6578 ASC_ASSERT(REQPNEXT(last_scp) != NULL);
6579 for (tscp = REQPNEXT(last_scp); tscp; tscp = REQPNEXT(tscp)) {
6580 tscp->result = HOST_BYTE(DID_RESET);
6582 last_scp = new_last_scp;
6587 * Add waiting requests to 'done_scp' and set the request status
6588 * to DID_RESET.
6590 if (done_scp == NULL) {
6591 done_scp = asc_dequeue_list(&boardp->waiting, &last_scp, target);
6592 for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) {
6593 tscp->result = HOST_BYTE(DID_RESET);
6595 } else {
6596 ASC_ASSERT(last_scp != NULL);
6597 REQPNEXT(last_scp) = asc_dequeue_list(&boardp->waiting,
6598 &new_last_scp, target);
6599 if (new_last_scp != NULL) {
6600 ASC_ASSERT(REQPNEXT(last_scp) != NULL);
6601 for (tscp = REQPNEXT(last_scp); tscp; tscp = REQPNEXT(tscp)) {
6602 tscp->result = HOST_BYTE(DID_RESET);
6604 last_scp = new_last_scp;
6608 /* Save the time of the most recently completed reset. */
6609 boardp->last_reset = jiffies;
6611 /* Clear reset flag. */
6612 boardp->flags &= ~ASC_HOST_IN_RESET;
6615 * Start any waiting commands for the board.
6617 if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
6618 ASC_DBG(1, "advansys_interrupt: before asc_execute_queue()\n");
6619 asc_execute_queue(&boardp->waiting);
6621 ret = SCSI_RESET_SUCCESS;
6624 /* Interrupts could be enabled here. */
6626 ASC_ASSERT(do_scsi_done != ASC_ERROR);
6627 ASC_ASSERT(scp_found != ASC_ERROR);
6628 if (do_scsi_done == ASC_TRUE) {
6629 if (scp->scsi_done == NULL) {
6630 ASC_PRINT1(
6631 "advansys_reset: reset request scsi_done() is NULL, %lx\n",
6632 (ulong) scp);
6633 } else {
6634 if (scp_found == ASC_FALSE) {
6635 ASC_PRINT1(
6636 "advansys_reset: reset request not active or waiting, completing anyway %lx\n",
6637 (ulong) scp);
6639 ASC_STATS(scp->host, done);
6640 scp->scsi_done(scp);
6645 * It is possible for the request done function to re-enable
6646 * interrupts without confusing the driver. But here interrupts
6647 * aren't enabled until requests have been completed.
6649 if (done_scp != NULL) {
6650 asc_scsi_done_list(done_scp);
6653 ASC_DBG1(1, "advansys_reset: ret %d\n", ret);
6655 /* Re-enable interrupts, if they were enabled on entry. */
6656 restore_flags(flags);
6658 ASC_ASSERT(ret != ASC_ERROR);
6659 return ret;
6663 * advansys_biosparam()
6665 * Translate disk drive geometry if the "BIOS greater than 1 GB"
6666 * support is enabled for a drive.
6668 * ip (information pointer) is an int array with the following definition:
6669 * ip[0]: heads
6670 * ip[1]: sectors
6671 * ip[2]: cylinders
6674 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0)
6675 advansys_biosparam(Disk *dp, int dep, int ip[])
6676 #else /* version >= v1.3.0 */
6677 advansys_biosparam(Disk *dp, kdev_t dep, int ip[])
6678 #endif /* version >= v1.3.0 */
6680 asc_board_t *boardp;
6682 ASC_DBG(1, "advansys_biosparam: begin\n");
6683 ASC_STATS(dp->device->host, biosparam);
6684 boardp = ASC_BOARDP(dp->device->host);
6685 if (ASC_NARROW_BOARD(boardp)) {
6686 if ((boardp->dvc_var.asc_dvc_var.dvc_cntl &
6687 ASC_CNTL_BIOS_GT_1GB) && dp->capacity > 0x200000) {
6688 ip[0] = 255;
6689 ip[1] = 63;
6690 } else {
6691 ip[0] = 64;
6692 ip[1] = 32;
6694 } else {
6695 if ((boardp->dvc_var.adv_dvc_var.bios_ctrl &
6696 BIOS_CTRL_EXTENDED_XLAT) && dp->capacity > 0x200000) {
6697 ip[0] = 255;
6698 ip[1] = 63;
6699 } else {
6700 ip[0] = 64;
6701 ip[1] = 32;
6704 ip[2] = dp->capacity / (ip[0] * ip[1]);
6705 ASC_DBG(1, "advansys_biosparam: end\n");
6706 return 0;
6710 * advansys_setup()
6712 * This function is called from init/main.c at boot time.
6713 * It it passed LILO parameters that can be set from the
6714 * LILO command line or in /etc/lilo.conf.
6716 * It is used by the AdvanSys driver to either disable I/O
6717 * port scanning or to limit scanning to 1 - 4 I/O ports.
6718 * Regardless of the option setting EISA and PCI boards
6719 * will still be searched for and detected. This option
6720 * only affects searching for ISA and VL boards.
6722 * If ADVANSYS_DEBUG is defined the driver debug level may
6723 * be set using the 5th (ASC_NUM_IOPORT_PROBE + 1) I/O Port.
6725 * Examples:
6726 * 1. Eliminate I/O port scanning:
6727 * boot: linux advansys=
6728 * or
6729 * boot: linux advansys=0x0
6730 * 2. Limit I/O port scanning to one I/O port:
6731 * boot: linux advansys=0x110
6732 * 3. Limit I/O port scanning to four I/O ports:
6733 * boot: linux advansys=0x110,0x210,0x230,0x330
6734 * 4. If ADVANSYS_DEBUG, limit I/O port scanning to four I/O ports and
6735 * set the driver debug level to 2.
6736 * boot: linux advansys=0x110,0x210,0x230,0x330,0xdeb2
6738 * ints[0] - number of arguments
6739 * ints[1] - first argument
6740 * ints[2] - second argument
6741 * ...
6743 ASC_INITFUNC(
6744 void,
6745 advansys_setup(char *str, int *ints)
6748 int i;
6750 if (asc_iopflag == ASC_TRUE) {
6751 printk("AdvanSys SCSI: 'advansys' LILO option may appear only once\n");
6752 return;
6755 asc_iopflag = ASC_TRUE;
6757 if (ints[0] > ASC_NUM_IOPORT_PROBE) {
6758 #ifdef ADVANSYS_DEBUG
6759 if ((ints[0] == ASC_NUM_IOPORT_PROBE + 1) &&
6760 (ints[ASC_NUM_IOPORT_PROBE + 1] >> 4 == 0xdeb)) {
6761 asc_dbglvl = ints[ASC_NUM_IOPORT_PROBE + 1] & 0xf;
6762 } else {
6763 #endif /* ADVANSYS_DEBUG */
6764 printk("AdvanSys SCSI: only %d I/O ports accepted\n",
6765 ASC_NUM_IOPORT_PROBE);
6766 #ifdef ADVANSYS_DEBUG
6768 #endif /* ADVANSYS_DEBUG */
6771 #ifdef ADVANSYS_DEBUG
6772 ASC_DBG1(1, "advansys_setup: ints[0] %d\n", ints[0]);
6773 for (i = 1; i < ints[0]; i++) {
6774 ASC_DBG2(1, " ints[%d] %x", i, ints[i]);
6776 ASC_DBG(1, "\n");
6777 #endif /* ADVANSYS_DEBUG */
6779 for (i = 1; i <= ints[0] && i <= ASC_NUM_IOPORT_PROBE; i++) {
6780 asc_ioport[i-1] = ints[i];
6781 ASC_DBG2(1, "advansys_setup: asc_ioport[%d] %x\n",
6782 i - 1, asc_ioport[i-1]);
6788 * --- Loadable Driver Support
6791 static Scsi_Host_Template driver_template = ADVANSYS;
6792 # include "scsi_module.c"
6796 * --- Miscellaneous Driver Functions
6800 * First-level interrupt handler.
6802 * For versions > v1.3.70, 'dev_id' is a pointer to the interrupting
6803 * adapter's asc_board_t. Because all boards are currently checked
6804 * for interrupts on each interrupt, 'dev_id' is not referenced. 'dev_id'
6805 * could be used to identify an interrupt passed to the AdvanSys driver,
6806 * which is for a device sharing an interrupt with an AdvanSys adapter.
6808 STATIC void
6809 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,70)
6810 advansys_interrupt(int irq, struct pt_regs *regs)
6811 #else /* version >= v1.3.70 */
6812 advansys_interrupt(int irq, void *dev_id, struct pt_regs *regs)
6813 #endif /* version >= v1.3.70 */
6815 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,95)
6816 int flags;
6817 #else /* version >= v2.1.95 */
6818 unsigned long flags;
6819 #endif /* version >= v2.1.95 */
6820 int i;
6821 asc_board_t *boardp;
6822 Scsi_Cmnd *done_scp = NULL, *last_scp = NULL;
6823 Scsi_Cmnd *new_last_scp;
6825 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,95)
6826 /* Disable interrupts, if they aren't already disabled. */
6827 save_flags(flags);
6828 cli();
6829 #else /* version >= v2.1.95 */
6831 * Disable interrupts, if they aren't already disabled and acquire
6832 * the I/O spinlock.
6834 spin_lock_irqsave(&io_request_lock, flags);
6835 #endif /* version >= v2.1.95 */
6837 ASC_DBG(1, "advansys_interrupt: begin\n");
6840 * Check for interrupts on all boards.
6841 * AscISR() will call asc_isr_callback().
6843 for (i = 0; i < asc_board_count; i++) {
6844 boardp = ASC_BOARDP(asc_host[i]);
6845 ASC_DBG2(2, "advansys_interrupt: i %d, boardp %lx\n",
6846 i, (ulong) boardp)
6847 if (ASC_NARROW_BOARD(boardp)) {
6849 * Narrow Board
6851 if (AscIsIntPending(asc_host[i]->io_port)) {
6852 ASC_STATS(asc_host[i], interrupt);
6853 ASC_DBG(1, "advansys_interrupt: before AscISR()\n");
6854 AscISR(&boardp->dvc_var.asc_dvc_var);
6856 } else {
6858 * Wide Board
6860 ASC_DBG(1, "advansys_interrupt: before AdvISR()\n");
6861 if (AdvISR(&boardp->dvc_var.adv_dvc_var)) {
6862 ASC_STATS(asc_host[i], interrupt);
6867 * Start waiting requests and create a list of completed requests.
6869 * If a reset or abort request is being performed for the board,
6870 * the reset or abort handler will complete pending requests after
6871 * it has completed.
6873 if ((boardp->flags & (ASC_HOST_IN_RESET | ASC_HOST_IN_ABORT)) == 0) {
6874 ASC_DBG2(1, "advansys_interrupt: done_scp %lx, last_scp %lx\n",
6875 (ulong) done_scp, (ulong) last_scp);
6877 /* Start any waiting commands for the board. */
6878 if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
6879 ASC_DBG(1, "advansys_interrupt: before asc_execute_queue()\n");
6880 asc_execute_queue(&boardp->waiting);
6884 * Add to the list of requests that must be completed.
6886 * 'done_scp' will always be NULL on the first iteration
6887 * of this loop. 'last_scp' is set at the same time as
6888 * 'done_scp'.
6890 if (done_scp == NULL) {
6891 done_scp = asc_dequeue_list(&boardp->done, &last_scp,
6892 ASC_TID_ALL);
6893 } else {
6894 ASC_ASSERT(last_scp != NULL);
6895 REQPNEXT(last_scp) = asc_dequeue_list(&boardp->done,
6896 &new_last_scp, ASC_TID_ALL);
6897 if (new_last_scp != NULL) {
6898 ASC_ASSERT(REQPNEXT(last_scp) != NULL);
6899 last_scp = new_last_scp;
6905 /* Interrupts could be enabled here. */
6908 * It is possible for the request done function to re-enable
6909 * interrupts without confusing the driver. But here the
6910 * original flags aren't restored until all requests have been
6911 * completed.
6913 asc_scsi_done_list(done_scp);
6915 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,95)
6917 * Restore the original flags which will enable interrupts
6918 * if and only if they were enabled on entry.
6920 restore_flags(flags);
6921 #else /* version >= v2.1.95 */
6923 * Release the I/O spinlock and restore the original flags
6924 * which will enable interrupts if and only if they were
6925 * enabled on entry.
6927 spin_unlock_irqrestore(&io_request_lock, flags);
6928 #endif /* version >= v2.1.95 */
6930 ASC_DBG(1, "advansys_interrupt: end\n");
6931 return;
6934 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
6936 * Set the number of commands to queue per device for the
6937 * specified host adapter.
6939 STATIC void
6940 advansys_select_queue_depths(struct Scsi_Host *shp, Scsi_Device *devicelist)
6942 Scsi_Device *device;
6943 asc_board_t *boardp;
6945 boardp = ASC_BOARDP(shp);
6946 boardp->flags |= ASC_SELECT_QUEUE_DEPTHS;
6947 for (device = devicelist; device != NULL; device = device->next) {
6948 if (device->host != shp) {
6949 continue;
6952 * Save a pointer to the device and set its initial/maximum
6953 * queue depth.
6955 boardp->device[device->id] = device;
6956 if (ASC_NARROW_BOARD(boardp)) {
6957 device->queue_depth =
6958 boardp->dvc_var.asc_dvc_var.max_dvc_qng[device->id];
6959 } else {
6960 device->queue_depth =
6961 boardp->dvc_var.adv_dvc_var.max_dvc_qng;
6963 ASC_DBG3(1, "advansys_select_queue_depths: shp %lx, id %d, depth %d\n",
6964 (ulong) shp, device->id, device->queue_depth);
6967 #endif /* version >= v1.3.89 */
6970 * Function used only with polled I/O requests that are initiated by
6971 * advansys_command().
6973 STATIC void
6974 advansys_command_done(Scsi_Cmnd *scp)
6976 ASC_DBG1(1, "advansys_command_done: scp %lx\n", (ulong) scp);
6977 scp->SCp.Status = 1;
6981 * Complete all requests on the singly linked list pointed
6982 * to by 'scp'.
6984 * Interrupts can be enabled on entry.
6986 STATIC void
6987 asc_scsi_done_list(Scsi_Cmnd *scp)
6989 Scsi_Cmnd *tscp;
6991 ASC_DBG(2, "asc_scsi_done_list: begin\n");
6992 while (scp != NULL) {
6993 ASC_DBG1(3, "asc_scsi_done_list: scp %lx\n", (ulong) scp);
6994 tscp = REQPNEXT(scp);
6995 REQPNEXT(scp) = NULL;
6996 ASC_STATS(scp->host, done);
6997 ASC_ASSERT(scp->scsi_done != NULL);
6998 scp->scsi_done(scp);
6999 scp = tscp;
7001 ASC_DBG(2, "asc_scsi_done_list: done\n");
7002 return;
7006 * Execute a single 'Scsi_Cmnd'.
7008 * The function 'done' is called when the request has been completed.
7010 * Scsi_Cmnd:
7012 * host - board controlling device
7013 * device - device to send command
7014 * target - target of device
7015 * lun - lun of device
7016 * cmd_len - length of SCSI CDB
7017 * cmnd - buffer for SCSI 8, 10, or 12 byte CDB
7018 * use_sg - if non-zero indicates scatter-gather request with use_sg elements
7020 * if (use_sg == 0) {
7021 * request_buffer - buffer address for request
7022 * request_bufflen - length of request buffer
7023 * } else {
7024 * request_buffer - pointer to scatterlist structure
7027 * sense_buffer - sense command buffer
7029 * result (4 bytes of an int):
7030 * Byte Meaning
7031 * 0 SCSI Status Byte Code
7032 * 1 SCSI One Byte Message Code
7033 * 2 Host Error Code
7034 * 3 Mid-Level Error Code
7036 * host driver fields:
7037 * SCp - Scsi_Pointer used for command processing status
7038 * scsi_done - used to save caller's done function
7039 * host_scribble - used for pointer to another Scsi_Cmnd
7041 * If this function returns ASC_NOERROR or ASC_ERROR the request
7042 * has been enqueued on the board's 'done' queue and must be
7043 * completed by the caller.
7045 * If ASC_BUSY is returned the request must be enqueued by the
7046 * caller and re-tried later.
7048 STATIC int
7049 asc_execute_scsi_cmnd(Scsi_Cmnd *scp)
7051 asc_board_t *boardp;
7052 ASC_DVC_VAR *asc_dvc_varp;
7053 ADV_DVC_VAR *adv_dvc_varp;
7054 ADV_SCSI_REQ_Q *adv_scsiqp;
7055 Scsi_Device *device;
7056 int ret;
7058 ASC_ASSERT(advansys_interrupts_enabled() == ASC_FALSE);
7059 ASC_DBG2(1, "asc_execute_scsi_cmnd: scp %lx, done %lx\n",
7060 (ulong) scp, (ulong) scp->scsi_done);
7062 boardp = ASC_BOARDP(scp->host);
7063 device = boardp->device[scp->target];
7065 if (ASC_NARROW_BOARD(boardp)) {
7067 * Build and execute Narrow Board request.
7070 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
7073 * Build Asc Library request structure using the
7074 * global structures 'asc_scsi_req' and 'asc_sg_head'.
7076 * asc_build_req() can not return ASC_BUSY.
7078 if (asc_build_req(boardp, scp) == ASC_ERROR) {
7079 ASC_STATS(scp->host, build_error);
7080 return ASC_ERROR;
7084 * Execute the command. If there is no error, add the command
7085 * to the active queue.
7087 switch (ret = AscExeScsiQueue(asc_dvc_varp, &asc_scsi_q)) {
7088 case ASC_NOERROR:
7089 ASC_STATS(scp->host, exe_noerror);
7091 * Increment monotonically increasing per device successful
7092 * request counter. Wrapping doesn't matter.
7094 boardp->reqcnt[scp->target]++;
7096 asc_enqueue(&boardp->active, scp, ASC_BACK);
7097 ASC_DBG(1,
7098 "asc_execute_scsi_cmnd: AscExeScsiQueue(), ASC_NOERROR\n");
7099 break;
7100 case ASC_BUSY:
7101 /* Caller must enqueue request and retry later. */
7102 ASC_STATS(scp->host, exe_busy);
7103 break;
7104 case ASC_ERROR:
7105 ASC_PRINT2(
7106 "asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() ASC_ERROR, err_code %x\n",
7107 boardp->id, asc_dvc_varp->err_code);
7108 ASC_STATS(scp->host, exe_error);
7109 scp->result = HOST_BYTE(DID_ERROR);
7110 asc_enqueue(&boardp->done, scp, ASC_BACK);
7111 break;
7112 default:
7113 ASC_PRINT2(
7114 "asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() unknown, err_code %x\n",
7115 boardp->id, asc_dvc_varp->err_code);
7116 ASC_STATS(scp->host, exe_unknown);
7117 scp->result = HOST_BYTE(DID_ERROR);
7118 asc_enqueue(&boardp->done, scp, ASC_BACK);
7119 break;
7121 } else {
7123 * Build and execute Wide Board request.
7125 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
7128 * Build and get a pointer to an Adv Library request structure.
7130 * If the request is successfully built then send it below,
7131 * otherwise return with an error.
7133 switch (adv_build_req(boardp, scp, &adv_scsiqp)) {
7134 case ASC_NOERROR:
7135 ASC_DBG(3, "asc_execute_scsi_cmnd: adv_build_req ASC_NOERROR\n");
7136 break;
7137 case ASC_BUSY:
7138 ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req ASC_BUSY\n");
7139 return ASC_BUSY;
7140 case ASC_ERROR:
7141 default:
7142 ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req ASC_ERROR\n");
7143 ASC_STATS(scp->host, build_error);
7144 return ASC_ERROR;
7148 * Execute the command. If there is no error, add the command
7149 * to the active queue.
7151 switch (ret = AdvExeScsiQueue(adv_dvc_varp, adv_scsiqp)) {
7152 case ASC_NOERROR:
7153 ASC_STATS(scp->host, exe_noerror);
7155 * Increment monotonically increasing per device successful
7156 * request counter. Wrapping doesn't matter.
7158 boardp->reqcnt[scp->target]++;
7159 asc_enqueue(&boardp->active, scp, ASC_BACK);
7160 ASC_DBG(1,
7161 "asc_execute_scsi_cmnd: AdvExeScsiQueue(), ASC_NOERROR\n");
7162 break;
7163 case ASC_BUSY:
7164 /* Caller must enqueue request and retry later. */
7165 ASC_STATS(scp->host, exe_busy);
7166 break;
7167 case ASC_ERROR:
7168 ASC_PRINT2(
7169 "asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() ASC_ERROR, err_code %x\n",
7170 boardp->id, adv_dvc_varp->err_code);
7171 ASC_STATS(scp->host, exe_error);
7172 scp->result = HOST_BYTE(DID_ERROR);
7173 asc_enqueue(&boardp->done, scp, ASC_BACK);
7174 break;
7175 default:
7176 ASC_PRINT2(
7177 "asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() unknown, err_code %x\n",
7178 boardp->id, adv_dvc_varp->err_code);
7179 ASC_STATS(scp->host, exe_unknown);
7180 scp->result = HOST_BYTE(DID_ERROR);
7181 asc_enqueue(&boardp->done, scp, ASC_BACK);
7182 break;
7186 ASC_DBG(1, "asc_execute_scsi_cmnd: end\n");
7187 ASC_ASSERT(advansys_interrupts_enabled() == ASC_FALSE);
7188 return ret;
7192 * Build a request structure for the Asc Library (Narrow Board).
7194 * The global structures 'asc_scsi_q' and 'asc_sg_head' are
7195 * used to build the request.
7197 * If an error occurs, then return ASC_ERROR.
7199 STATIC int
7200 asc_build_req(asc_board_t *boardp, Scsi_Cmnd *scp)
7203 * Mutually exclusive access is required to 'asc_scsi_q' and
7204 * 'asc_sg_head' until after the request is started.
7206 memset(&asc_scsi_q, 0, sizeof(ASC_SCSI_Q));
7209 * Point the ASC_SCSI_Q to the 'Scsi_Cmnd'.
7211 asc_scsi_q.q2.srb_ptr = ASC_VADDR_TO_U32(scp);
7214 * Build the ASC_SCSI_Q request.
7216 ASC_ASSERT(scp->cmd_len <= ASC_MAX_CDB_LEN);
7217 if (scp->cmd_len > ASC_MAX_CDB_LEN) {
7218 scp->cmd_len = ASC_MAX_CDB_LEN;
7220 asc_scsi_q.cdbptr = &scp->cmnd[0];
7221 asc_scsi_q.q2.cdb_len = scp->cmd_len;
7222 asc_scsi_q.q1.target_id = ASC_TID_TO_TARGET_ID(scp->target);
7223 asc_scsi_q.q1.target_lun = scp->lun;
7224 asc_scsi_q.q2.target_ix = ASC_TIDLUN_TO_IX(scp->target, scp->lun);
7225 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
7226 asc_scsi_q.q1.sense_addr = (ADV_PADDR) &scp->sense_buffer[0];
7227 #else /* version >= v2.0.0 */
7228 asc_scsi_q.q1.sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
7229 #endif /* version >= v2.0.0 */
7230 asc_scsi_q.q1.sense_len = sizeof(scp->sense_buffer);
7233 * If there are any outstanding requests for the current target,
7234 * then every 255th request send an ORDERED request. This heuristic
7235 * tries to retain the benefit of request sorting while preventing
7236 * request starvation. 255 is the max number of tags or pending commands
7237 * a device may have outstanding.
7239 * The request count is incremented below for every successfully
7240 * started request.
7243 if ((boardp->dvc_var.asc_dvc_var.cur_dvc_qng[scp->target] > 0) &&
7244 (boardp->reqcnt[scp->target] % 255) == 0) {
7245 asc_scsi_q.q2.tag_code = M2_QTAG_MSG_ORDERED;
7246 } else {
7247 asc_scsi_q.q2.tag_code = M2_QTAG_MSG_SIMPLE;
7251 * Build ASC_SCSI_Q for a contiguous buffer or a scatter-gather
7252 * buffer command.
7254 if (scp->use_sg == 0) {
7256 * CDB request of single contiguous buffer.
7258 ASC_STATS(scp->host, cont_cnt);
7259 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
7260 asc_scsi_q.q1.data_addr = (ADV_PADDR) scp->request_buffer;
7261 #else /* version >= v2.0.0 */
7262 asc_scsi_q.q1.data_addr =
7263 cpu_to_le32(virt_to_bus(scp->request_buffer));
7264 #endif /* version >= v2.0.0 */
7265 asc_scsi_q.q1.data_cnt = scp->request_bufflen;
7266 ASC_STATS_ADD(scp->host, cont_xfer,
7267 ASC_CEILING(scp->request_bufflen, 512));
7268 asc_scsi_q.q1.sg_queue_cnt = 0;
7269 asc_scsi_q.sg_head = NULL;
7270 } else {
7272 * CDB scatter-gather request list.
7274 int sgcnt;
7275 struct scatterlist *slp;
7277 if (scp->use_sg > scp->host->sg_tablesize) {
7278 ASC_PRINT3(
7279 "asc_build_req: board %d: use_sg %d > sg_tablesize %d\n",
7280 boardp->id, scp->use_sg, scp->host->sg_tablesize);
7281 scp->result = HOST_BYTE(DID_ERROR);
7282 asc_enqueue(&boardp->done, scp, ASC_BACK);
7283 return ASC_ERROR;
7286 ASC_STATS(scp->host, sg_cnt);
7289 * Use global ASC_SG_HEAD structure and set the ASC_SCSI_Q
7290 * structure to point to it.
7292 memset(&asc_sg_head, 0, sizeof(ASC_SG_HEAD));
7294 asc_scsi_q.q1.cntl |= QC_SG_HEAD;
7295 asc_scsi_q.sg_head = &asc_sg_head;
7296 asc_scsi_q.q1.data_cnt = 0;
7297 asc_scsi_q.q1.data_addr = 0;
7298 asc_sg_head.entry_cnt = asc_scsi_q.q1.sg_queue_cnt = scp->use_sg;
7299 ASC_STATS_ADD(scp->host, sg_elem, asc_sg_head.entry_cnt);
7302 * Convert scatter-gather list into ASC_SG_HEAD list.
7304 slp = (struct scatterlist *) scp->request_buffer;
7305 for (sgcnt = 0; sgcnt < scp->use_sg; sgcnt++, slp++) {
7306 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
7307 asc_sg_head.sg_list[sgcnt].addr = (ADV_PADDR) slp->address;
7308 #else /* version >= v2.0.0 */
7309 asc_sg_head.sg_list[sgcnt].addr =
7310 cpu_to_le32(virt_to_bus(slp->address));
7311 #endif /* version >= v2.0.0 */
7312 asc_sg_head.sg_list[sgcnt].bytes = cpu_to_le32(slp->length);
7313 ASC_STATS_ADD(scp->host, sg_xfer, ASC_CEILING(slp->length, 512));
7317 ASC_DBG_PRT_ASC_SCSI_Q(2, &asc_scsi_q);
7318 ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
7320 return ASC_NOERROR;
7324 * Build a request structure for the Adv Library (Wide Board).
7326 * If an adv_req_t can not be allocated to issue the request,
7327 * then return ASC_BUSY. If an error occurs, then return ASC_ERROR.
7329 * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the
7330 * microcode for DMA addresses or math operations are byte swapped
7331 * to little-endian order.
7333 STATIC int
7334 adv_build_req(asc_board_t *boardp, Scsi_Cmnd *scp,
7335 ADV_SCSI_REQ_Q **adv_scsiqpp)
7337 adv_req_t *reqp;
7338 ADV_SCSI_REQ_Q *scsiqp;
7339 int i;
7340 int ret;
7343 * Allocate an adv_req_t structure from the board to execute
7344 * the command.
7346 if (boardp->adv_reqp == NULL) {
7347 ASC_DBG(1, "adv_build_req: no free adv_req_t\n");
7348 ASC_STATS(scp->host, adv_build_noreq);
7349 return ASC_BUSY;
7350 } else {
7351 reqp = boardp->adv_reqp;
7352 boardp->adv_reqp = reqp->next_reqp;
7353 reqp->next_reqp = NULL;
7357 * Get 4-byte aligned ADV_SCSI_REQ_Q and ADV_SG_BLOCK pointers.
7359 scsiqp = (ADV_SCSI_REQ_Q *) ADV_DWALIGN(&reqp->scsi_req_q);
7362 * Initialize the structure.
7364 scsiqp->cntl = scsiqp->scsi_cntl = scsiqp->done_status = 0;
7367 * Set the ADV_SCSI_REQ_Q 'srb_ptr' to point to the adv_req_t structure.
7369 scsiqp->srb_ptr = ASC_VADDR_TO_U32(reqp);
7372 * Set the adv_req_t 'cmndp' to point to the Scsi_Cmnd structure.
7374 reqp->cmndp = scp;
7377 * Build the ADV_SCSI_REQ_Q request.
7381 * Set CDB length and copy it to the request structure.
7383 ASC_ASSERT(scp->cmd_len <= ASC_MAX_CDB_LEN);
7384 if (scp->cmd_len > ASC_MAX_CDB_LEN) {
7385 scp->cmd_len = ASC_MAX_CDB_LEN;
7387 scsiqp->cdb_len = scp->cmd_len;
7388 for (i = 0; i < scp->cmd_len; i++) {
7389 scsiqp->cdb[i] = scp->cmnd[i];
7392 scsiqp->target_id = scp->target;
7393 scsiqp->target_lun = scp->lun;
7395 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
7396 scsiqp->sense_addr = (ADV_PADDR) &scp->sense_buffer[0];
7397 #else /* version >= v2.0.0 */
7398 scsiqp->sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
7399 #endif /* version >= v2.0.0 */
7400 scsiqp->sense_len = sizeof(scp->sense_buffer);
7403 * Build ADV_SCSI_REQ_Q for a contiguous buffer or a scatter-gather
7404 * buffer command.
7406 scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
7407 scsiqp->vdata_addr = scp->request_buffer;
7408 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
7409 scsiqp->data_addr = (ADV_PADDR) scp->request_buffer;
7410 #else /* version >= v2.0.0 */
7411 scsiqp->data_addr = cpu_to_le32(virt_to_bus(scp->request_buffer));
7412 #endif /* version >= v2.0.0 */
7414 if (scp->use_sg == 0) {
7416 * CDB request of single contiguous buffer.
7418 reqp->sgblkp = NULL;
7419 scsiqp->sg_list_ptr = NULL;
7420 scsiqp->sg_real_addr = 0;
7421 ASC_STATS(scp->host, cont_cnt);
7422 ASC_STATS_ADD(scp->host, cont_xfer,
7423 ASC_CEILING(scp->request_bufflen, 512));
7424 } else {
7426 * CDB scatter-gather request list.
7428 if (scp->use_sg > ADV_MAX_SG_LIST) {
7429 ASC_PRINT3(
7430 "adv_build_req: board %d: use_sg %d > ADV_MAX_SG_LIST %d\n",
7431 boardp->id, scp->use_sg, scp->host->sg_tablesize);
7432 scp->result = HOST_BYTE(DID_ERROR);
7433 asc_enqueue(&boardp->done, scp, ASC_BACK);
7436 * Free the 'adv_req_t' structure by adding it back to the
7437 * board free list.
7439 reqp->next_reqp = boardp->adv_reqp;
7440 boardp->adv_reqp = reqp;
7442 return ASC_ERROR;
7445 if ((ret = adv_get_sglist(boardp, reqp, scp)) != ADV_SUCCESS) {
7447 * Free the adv_req_t structure by adding it back to the
7448 * board free list.
7450 reqp->next_reqp = boardp->adv_reqp;
7451 boardp->adv_reqp = reqp;
7453 return ret;
7456 ASC_STATS(scp->host, sg_cnt);
7457 ASC_STATS_ADD(scp->host, sg_elem, scp->use_sg);
7460 ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
7461 ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
7463 *adv_scsiqpp = scsiqp;
7465 return ASC_NOERROR;
7469 * Build scatter-gather list for Adv Library (Wide Board).
7471 * Additional ADV_SG_BLOCK structures will need to be allocated
7472 * if the total number of scatter-gather elements exceeds
7473 * NO_OF_SG_PER_BLOCK (15). The ADV_SG_BLOCK structures are
7474 * assumed to be physically contiguous.
7476 * Return:
7477 * ADV_SUCCESS(1) - SG List successfully created
7478 * ADV_ERROR(-1) - SG List creation failed
7480 STATIC int
7481 adv_get_sglist(asc_board_t *boardp, adv_req_t *reqp, Scsi_Cmnd *scp)
7483 adv_sgblk_t *sgblkp;
7484 ADV_SCSI_REQ_Q *scsiqp;
7485 struct scatterlist *slp;
7486 int sg_elem_cnt;
7487 ADV_SG_BLOCK *sg_block, *prev_sg_block;
7488 ADV_PADDR sg_block_paddr;
7489 int i;
7491 scsiqp = (ADV_SCSI_REQ_Q *) ADV_DWALIGN(&reqp->scsi_req_q);
7492 slp = (struct scatterlist *) scp->request_buffer;
7493 sg_elem_cnt = scp->use_sg;
7494 prev_sg_block = NULL;
7495 reqp->sgblkp = NULL;
7500 * Allocate a 'adv_sgblk_t' structure from the board free
7501 * list. One 'adv_sgblk_t' structure holds NO_OF_SG_PER_BLOCK
7502 * (15) scatter-gather elements.
7504 if ((sgblkp = boardp->adv_sgblkp) == NULL) {
7505 ASC_DBG(1, "adv_get_sglist: no free adv_sgblk_t\n");
7506 ASC_STATS(scp->host, adv_build_nosg);
7509 * Allocation failed. Free 'adv_sgblk_t' structures already
7510 * allocated for the request.
7512 while ((sgblkp = reqp->sgblkp) != NULL)
7514 /* Remove 'sgblkp' from the request list. */
7515 reqp->sgblkp = sgblkp->next_sgblkp;
7517 /* Add 'sgblkp' to the board free list. */
7518 sgblkp->next_sgblkp = boardp->adv_sgblkp;
7519 boardp->adv_sgblkp = sgblkp;
7521 return ASC_BUSY;
7522 } else {
7523 /* Complete 'adv_sgblk_t' board allocation. */
7524 boardp->adv_sgblkp = sgblkp->next_sgblkp;
7525 sgblkp->next_sgblkp = NULL;
7528 * Get 4 byte aligned virtual and physical addresses for
7529 * the allocated ADV_SG_BLOCK structure.
7531 sg_block = (ADV_SG_BLOCK *) ADV_DWALIGN(&sgblkp->sg_block);
7532 sg_block_paddr =
7533 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
7534 (ADV_PADDR) sg_block;
7535 #else /* version >= v2.0.0 */
7536 virt_to_bus(sg_block);
7537 #endif /* version >= v2.0.0 */
7540 * Check if this is the first 'adv_sgblk_t' for the request.
7542 if (reqp->sgblkp == NULL)
7544 /* Request's first scatter-gather block. */
7545 reqp->sgblkp = sgblkp;
7548 * Set ADV_SCSI_REQ_T ADV_SG_BLOCK virtual and physical
7549 * address pointers.
7551 scsiqp->sg_list_ptr = sg_block;
7552 scsiqp->sg_real_addr = cpu_to_le32(sg_block_paddr);
7553 } else
7555 /* Request's second or later scatter-gather block. */
7556 sgblkp->next_sgblkp = reqp->sgblkp;
7557 reqp->sgblkp = sgblkp;
7560 * Point the previous ADV_SG_BLOCK structure to
7561 * the newly allocated ADV_SG_BLOCK structure.
7563 ASC_ASSERT(prev_sg_block != NULL);
7564 prev_sg_block->sg_ptr = cpu_to_le32(sg_block_paddr);
7568 for (i = 0; i < NO_OF_SG_PER_BLOCK; i++)
7570 sg_block->sg_list[i].sg_addr =
7571 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
7572 (ADV_PADDR) slp->address;
7573 #else /* version >= v2.0.0 */
7574 cpu_to_le32(virt_to_bus(slp->address));
7575 #endif /* version >= v2.0.0 */
7576 sg_block->sg_list[i].sg_count = cpu_to_le32(slp->length);
7577 ASC_STATS_ADD(scp->host, sg_xfer, ASC_CEILING(slp->length, 512));
7579 if (--sg_elem_cnt == 0)
7580 { /* Last ADV_SG_BLOCK and scatter-gather entry. */
7581 sg_block->sg_cnt = i + 1;
7582 sg_block->sg_ptr = 0L; /* Last ADV_SG_BLOCK in list. */
7583 return ADV_SUCCESS;
7585 slp++;
7587 sg_block->sg_cnt = NO_OF_SG_PER_BLOCK;
7588 prev_sg_block = sg_block;
7590 while (1);
7591 /* NOTREACHED */
7595 * asc_isr_callback() - Second Level Interrupt Handler called by AscISR().
7597 * Interrupt callback function for the Narrow SCSI Asc Library.
7599 STATIC void
7600 asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
7602 asc_board_t *boardp;
7603 Scsi_Cmnd *scp;
7604 struct Scsi_Host *shp;
7605 int i;
7607 ASC_ASSERT(advansys_interrupts_enabled() == ASC_FALSE);
7608 ASC_DBG2(1, "asc_isr_callback: asc_dvc_varp %lx, qdonep %lx\n",
7609 (ulong) asc_dvc_varp, (ulong) qdonep);
7610 ASC_DBG_PRT_ASC_QDONE_INFO(2, qdonep);
7613 * Get the Scsi_Cmnd structure and Scsi_Host structure for the
7614 * command that has been completed.
7616 scp = (Scsi_Cmnd *) ASC_U32_TO_VADDR(qdonep->d2.srb_ptr);
7617 ASC_DBG1(1, "asc_isr_callback: scp %lx\n", (ulong) scp);
7619 if (scp == NULL) {
7620 ASC_PRINT("asc_isr_callback: scp is NULL\n");
7621 return;
7623 ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
7626 * If the request's host pointer is not valid, display a
7627 * message and return.
7629 shp = scp->host;
7630 for (i = 0; i < asc_board_count; i++) {
7631 if (asc_host[i] == shp) {
7632 break;
7635 if (i == asc_board_count) {
7636 ASC_PRINT2(
7637 "asc_isr_callback: scp %lx has bad host pointer, host %lx\n",
7638 (ulong) scp, (ulong) shp);
7639 return;
7642 ASC_STATS(shp, callback);
7643 ASC_DBG1(1, "asc_isr_callback: shp %lx\n", (ulong) shp);
7646 * If the request isn't found on the active queue, it may
7647 * have been removed to handle a reset or abort request.
7648 * Display a message and return.
7650 boardp = ASC_BOARDP(shp);
7651 ASC_ASSERT(asc_dvc_varp == &boardp->dvc_var.asc_dvc_var);
7652 if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) {
7653 ASC_PRINT2(
7654 "asc_isr_callback: board %d: scp %lx not on active queue\n",
7655 boardp->id, (ulong) scp);
7656 return;
7660 * 'qdonep' contains the command's ending status.
7662 switch (qdonep->d3.done_stat) {
7663 case QD_NO_ERROR:
7664 ASC_DBG(2, "asc_isr_callback: QD_NO_ERROR\n");
7665 scp->result = 0;
7668 * If an INQUIRY command completed successfully, then call
7669 * the AscInquiryHandling() function to set-up the device.
7671 if (scp->cmnd[0] == SCSICMD_Inquiry && scp->lun == 0 &&
7672 (scp->request_bufflen - qdonep->remain_bytes) >= 8)
7674 AscInquiryHandling(asc_dvc_varp, scp->target & 0x7,
7675 (ASC_SCSI_INQUIRY *) scp->request_buffer);
7678 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(2,3,19)
7680 * Check for an underrun condition.
7682 * If there was no error and an underrun condition, then
7683 * then return the number of underrun bytes.
7685 if (scp->request_bufflen != 0 && qdonep->remain_bytes != 0 &&
7686 qdonep->remain_bytes <= scp->request_bufflen != 0) {
7687 ASC_DBG1(1, "asc_isr_callback: underrun condition %u bytes\n",
7688 (unsigned) qdonep->remain_bytes);
7689 scp->resid = qdonep->remain_bytes;
7691 #endif /* version >= v2.3.19 */
7692 break;
7694 case QD_WITH_ERROR:
7695 ASC_DBG(2, "asc_isr_callback: QD_WITH_ERROR\n");
7696 switch (qdonep->d3.host_stat) {
7697 case QHSTA_NO_ERROR:
7698 if (qdonep->d3.scsi_stat == SS_CHK_CONDITION) {
7699 ASC_DBG(2, "asc_isr_callback: SS_CHK_CONDITION\n");
7700 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
7701 sizeof(scp->sense_buffer));
7703 * Note: The 'status_byte()' macro used by target drivers
7704 * defined in scsi.h shifts the status byte returned by
7705 * host drivers right by 1 bit. This is why target drivers
7706 * also use right shifted status byte definitions. For
7707 * instance target drivers use CHECK_CONDITION, defined to
7708 * 0x1, instead of the SCSI defined check condition value
7709 * of 0x2. Host drivers are supposed to return the status
7710 * byte as it is defined by SCSI.
7712 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
7713 STATUS_BYTE(qdonep->d3.scsi_stat);
7714 } else {
7715 scp->result = STATUS_BYTE(qdonep->d3.scsi_stat);
7717 break;
7719 default:
7720 /* QHSTA error occurred */
7721 ASC_DBG1(1, "asc_isr_callback: host_stat %x\n",
7722 qdonep->d3.host_stat);
7723 scp->result = HOST_BYTE(DID_BAD_TARGET);
7724 break;
7726 break;
7728 case QD_ABORTED_BY_HOST:
7729 ASC_DBG(1, "asc_isr_callback: QD_ABORTED_BY_HOST\n");
7730 scp->result = HOST_BYTE(DID_ABORT) | MSG_BYTE(qdonep->d3.scsi_msg) |
7731 STATUS_BYTE(qdonep->d3.scsi_stat);
7732 break;
7734 default:
7735 ASC_DBG1(1, "asc_isr_callback: done_stat %x\n", qdonep->d3.done_stat);
7736 scp->result = HOST_BYTE(DID_ERROR) | MSG_BYTE(qdonep->d3.scsi_msg) |
7737 STATUS_BYTE(qdonep->d3.scsi_stat);
7738 break;
7742 * If the 'init_tidmask' bit isn't already set for the target and the
7743 * current request finished normally, then set the bit for the target
7744 * to indicate that a device is present.
7746 if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->target)) == 0 &&
7747 qdonep->d3.done_stat == QD_NO_ERROR &&
7748 qdonep->d3.host_stat == QHSTA_NO_ERROR) {
7749 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->target);
7753 * Because interrupts may be enabled by the 'Scsi_Cmnd' done
7754 * function, add the command to the end of the board's done queue.
7755 * The done function for the command will be called from
7756 * advansys_interrupt().
7758 asc_enqueue(&boardp->done, scp, ASC_BACK);
7760 return;
7764 * adv_isr_callback() - Second Level Interrupt Handler called by AdvISR().
7766 * Callback function for the Wide SCSI Adv Library.
7768 STATIC void
7769 adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp)
7771 asc_board_t *boardp;
7772 adv_req_t *reqp;
7773 adv_sgblk_t *sgblkp;
7774 Scsi_Cmnd *scp;
7775 struct Scsi_Host *shp;
7776 int i;
7778 ASC_ASSERT(advansys_interrupts_enabled() == ASC_FALSE);
7779 ASC_DBG2(1, "adv_isr_callback: adv_dvc_varp %lx, scsiqp %lx\n",
7780 (ulong) adv_dvc_varp, (ulong) scsiqp);
7781 ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
7784 * Get the adv_req_t structure for the command that has been
7785 * completed. The adv_req_t structure actually contains the
7786 * completed ADV_SCSI_REQ_Q structure.
7788 reqp = (adv_req_t *) ADV_U32_TO_VADDR(scsiqp->srb_ptr);
7789 ASC_DBG1(1, "adv_isr_callback: reqp %lx\n", (ulong) reqp);
7790 if (reqp == NULL) {
7791 ASC_PRINT("adv_isr_callback: reqp is NULL\n");
7792 return;
7796 * Get the Scsi_Cmnd structure and Scsi_Host structure for the
7797 * command that has been completed.
7799 * Note: The adv_req_t request structure and adv_sgblk_t structure,
7800 * if any, are dropped, because a board structure pointer can not be
7801 * determined.
7803 scp = reqp->cmndp;
7804 ASC_DBG1(1, "adv_isr_callback: scp %lx\n", (ulong) scp);
7805 if (scp == NULL) {
7806 ASC_PRINT("adv_isr_callback: scp is NULL; adv_req_t dropped.\n");
7807 return;
7809 ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
7812 * If the request's host pointer is not valid, display a message
7813 * and return.
7815 shp = scp->host;
7816 for (i = 0; i < asc_board_count; i++) {
7817 if (asc_host[i] == shp) {
7818 break;
7822 * Note: If the host structure is not found, the adv_req_t request
7823 * structure and adv_sgblk_t structure, if any, is dropped.
7825 if (i == asc_board_count) {
7826 ASC_PRINT2(
7827 "adv_isr_callback: scp %lx has bad host pointer, host %lx\n",
7828 (ulong) scp, (ulong) shp);
7829 return;
7832 ASC_STATS(shp, callback);
7833 ASC_DBG1(1, "adv_isr_callback: shp %lx\n", (ulong) shp);
7836 * If the request isn't found on the active queue, it may have been
7837 * removed to handle a reset or abort request. Display a message and
7838 * return.
7840 * Note: Because the structure may still be in use don't attempt
7841 * to free the adv_req_t and adv_sgblk_t, if any, structures.
7843 boardp = ASC_BOARDP(shp);
7844 ASC_ASSERT(adv_dvc_varp == &boardp->dvc_var.adv_dvc_var);
7845 if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) {
7846 ASC_PRINT2(
7847 "adv_isr_callback: board %d: scp %lx not on active queue\n",
7848 boardp->id, (ulong) scp);
7849 return;
7853 * 'done_status' contains the command's ending status.
7855 switch (scsiqp->done_status) {
7856 case QD_NO_ERROR:
7857 ASC_DBG(2, "adv_isr_callback: QD_NO_ERROR\n");
7858 scp->result = 0;
7860 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(2,3,19)
7862 * Check for an underrun condition.
7864 * If there was no error and an underrun condition, then
7865 * then return the number of underrun bytes.
7867 if (scp->request_bufflen != 0 && scsiqp->data_cnt != 0 &&
7868 scsiqp->data_cnt <= scp->request_bufflen) {
7869 ASC_DBG1(1, "adv_isr_callback: underrun condition %lu bytes\n",
7870 (ulong) scsiqp->data_cnt);
7871 scp->resid = scsiqp->data_cnt;
7873 #endif /* version >= v2.3.19 */
7874 break;
7876 case QD_WITH_ERROR:
7877 ASC_DBG(2, "adv_isr_callback: QD_WITH_ERROR\n");
7878 switch (scsiqp->host_status) {
7879 case QHSTA_NO_ERROR:
7880 if (scsiqp->scsi_status == SS_CHK_CONDITION) {
7881 ASC_DBG(2, "adv_isr_callback: SS_CHK_CONDITION\n");
7882 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
7883 sizeof(scp->sense_buffer));
7885 * Note: The 'status_byte()' macro used by target drivers
7886 * defined in scsi.h shifts the status byte returned by
7887 * host drivers right by 1 bit. This is why target drivers
7888 * also use right shifted status byte definitions. For
7889 * instance target drivers use CHECK_CONDITION, defined to
7890 * 0x1, instead of the SCSI defined check condition value
7891 * of 0x2. Host drivers are supposed to return the status
7892 * byte as it is defined by SCSI.
7894 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
7895 STATUS_BYTE(scsiqp->scsi_status);
7896 } else {
7897 scp->result = STATUS_BYTE(scsiqp->scsi_status);
7899 break;
7901 default:
7902 /* Some other QHSTA error occurred. */
7903 ASC_DBG1(1, "adv_isr_callback: host_status %x\n",
7904 scsiqp->host_status);
7905 scp->result = HOST_BYTE(DID_BAD_TARGET);
7906 break;
7908 break;
7910 case QD_ABORTED_BY_HOST:
7911 ASC_DBG(1, "adv_isr_callback: QD_ABORTED_BY_HOST\n");
7912 scp->result = HOST_BYTE(DID_ABORT) | STATUS_BYTE(scsiqp->scsi_status);
7913 break;
7915 default:
7916 ASC_DBG1(1, "adv_isr_callback: done_status %x\n", scsiqp->done_status);
7917 scp->result = HOST_BYTE(DID_ERROR) | STATUS_BYTE(scsiqp->scsi_status);
7918 break;
7922 * If the 'init_tidmask' bit isn't already set for the target and the
7923 * current request finished normally, then set the bit for the target
7924 * to indicate that a device is present.
7926 if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->target)) == 0 &&
7927 scsiqp->done_status == QD_NO_ERROR &&
7928 scsiqp->host_status == QHSTA_NO_ERROR) {
7929 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->target);
7933 * Because interrupts may be enabled by the 'Scsi_Cmnd' done
7934 * function, add the command to the end of the board's done queue.
7935 * The done function for the command will be called from
7936 * advansys_interrupt().
7938 asc_enqueue(&boardp->done, scp, ASC_BACK);
7941 * Free all 'adv_sgblk_t' structures allocated for the request.
7943 while ((sgblkp = reqp->sgblkp) != NULL)
7945 /* Remove 'sgblkp' from the request list. */
7946 reqp->sgblkp = sgblkp->next_sgblkp;
7948 /* Add 'sgblkp' to the board free list. */
7949 sgblkp->next_sgblkp = boardp->adv_sgblkp;
7950 boardp->adv_sgblkp = sgblkp;
7954 * Free the adv_req_t structure used with the command by adding
7955 * it back to the board free list.
7957 reqp->next_reqp = boardp->adv_reqp;
7958 boardp->adv_reqp = reqp;
7960 ASC_DBG(1, "adv_isr_callback: done\n");
7962 return;
7966 * adv_async_callback() - Adv Library asynchronous event callback function.
7968 STATIC void
7969 adv_async_callback(ADV_DVC_VAR *adv_dvc_varp, uchar code)
7971 switch (code)
7973 case ADV_ASYNC_SCSI_BUS_RESET_DET:
7975 * The firmware detected a SCSI Bus reset.
7977 ASC_DBG(0, "adv_async_callback: ADV_ASYNC_SCSI_BUS_RESET_DET\n");
7978 break;
7980 case ADV_ASYNC_RDMA_FAILURE:
7982 * Handle RDMA failure by resetting the SCSI Bus and
7983 * possibly the chip if it is unresponsive. Log the error
7984 * with a unique code.
7986 ASC_DBG(0, "adv_async_callback: ADV_ASYNC_RDMA_FAILURE\n");
7987 AdvResetChipAndSB(adv_dvc_varp);
7988 break;
7990 case ADV_HOST_SCSI_BUS_RESET:
7992 * Host generated SCSI bus reset occurred.
7994 ASC_DBG(0, "adv_async_callback: ADV_HOST_SCSI_BUS_RESET\n");
7995 break;
7997 default:
7998 ASC_DBG1(0, "DvcAsyncCallBack: unknown code 0x%x\n", code);
7999 break;
8003 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
8004 #ifdef ASC_CONFIG_PCI
8006 * Search for an AdvanSys PCI device in the PCI configuration space.
8008 ASC_INITFUNC(
8009 STATIC int,
8010 asc_srch_pci_dev(PCI_DEVICE *pciDevice)
8013 int ret = PCI_DEVICE_NOT_FOUND;
8015 ASC_DBG(2, "asc_srch_pci_dev: begin\n");
8017 if (pci_scan_method == -1) {
8018 pci_scan_method = asc_scan_method();
8020 pciDevice->type = pci_scan_method;
8021 ASC_DBG1(2, "asc_srch_pci_dev: type %d\n", pciDevice->type);
8023 ret = asc_pci_find_dev(pciDevice);
8024 ASC_DBG1(2, "asc_srch_pci_dev: asc_pci_find_dev() return %d\n", ret);
8025 if (ret == PCI_DEVICE_FOUND) {
8026 pciDevice->slotNumber = pciDevice->slotFound + 1;
8027 pciDevice->startSlot = pciDevice->slotFound + 1;
8028 } else {
8029 if (pciDevice->bridge > pciDevice->busNumber) {
8030 ASC_DBG2(2, "asc_srch_pci_dev: bridge %x, busNumber %x\n",
8031 pciDevice->bridge, pciDevice->busNumber);
8032 pciDevice->busNumber++;
8033 pciDevice->slotNumber = 0;
8034 pciDevice->startSlot = 0;
8035 pciDevice->endSlot = 0x0f;
8036 ret = asc_srch_pci_dev(pciDevice);
8037 ASC_DBG1(2, "asc_srch_pci_dev: recursive call return %d\n", ret);
8041 ASC_DBG1(2, "asc_srch_pci_dev: return %d\n", ret);
8042 return ret;
8046 * Determine the access method to be used for 'pciDevice'.
8048 ASC_INITFUNC(
8049 STATIC uchar,
8050 asc_scan_method(void)
8053 ushort data;
8054 PCI_DATA pciData;
8055 uchar type;
8056 uchar slot;
8058 ASC_DBG(2, "asc_scan_method: begin\n");
8059 memset(&pciData, 0, sizeof(pciData));
8060 for (type = 1; type < 3; type++) {
8061 pciData.type = type;
8062 for (slot = 0; slot < PCI_MAX_SLOT; slot++) {
8063 pciData.slot = slot;
8064 data = asc_get_cfg_word(&pciData);
8065 if ((data != 0xFFFF) && (data != 0x0000)) {
8066 ASC_DBG2(4, "asc_scan_method: data %x, type %d\n", data, type);
8067 return (type);
8071 ASC_DBG1(4, "asc_scan_method: type %d\n", type);
8072 return (type);
8076 * Check for an AdvanSys PCI device in 'pciDevice'.
8078 * Return PCI_DEVICE_FOUND if found, otherwise return PCI_DEVICE_NOT_FOUND.
8080 ASC_INITFUNC(
8081 STATIC int,
8082 asc_pci_find_dev(PCI_DEVICE *pciDevice)
8085 PCI_DATA pciData;
8086 ushort vendorid, deviceid;
8087 uchar classcode, subclass;
8088 uchar lslot;
8090 ASC_DBG(3, "asc_pci_find_dev: begin\n");
8091 pciData.type = pciDevice->type;
8092 pciData.bus = pciDevice->busNumber;
8093 pciData.func = pciDevice->devFunc;
8094 lslot = pciDevice->startSlot;
8095 for (; lslot < pciDevice->endSlot; lslot++) {
8096 pciData.slot = lslot;
8097 pciData.offset = VENDORID_OFFSET;
8098 vendorid = asc_get_cfg_word(&pciData);
8099 ASC_DBG1(3, "asc_pci_find_dev: vendorid %x\n", vendorid);
8100 if (vendorid != 0xffff) {
8101 pciData.offset = DEVICEID_OFFSET;
8102 deviceid = asc_get_cfg_word(&pciData);
8103 ASC_DBG1(3, "asc_pci_find_dev: deviceid %x\n", deviceid);
8104 if ((vendorid == ASC_PCI_VENDORID) &&
8105 ((deviceid == ASC_PCI_DEVICE_ID_1100) ||
8106 (deviceid == ASC_PCI_DEVICE_ID_1200) ||
8107 (deviceid == ASC_PCI_DEVICE_ID_1300) ||
8108 (deviceid == ASC_PCI_DEVICE_ID_2300) ||
8109 (deviceid == ASC_PCI_DEVICE_ID_2500))) {
8110 pciDevice->slotFound = lslot;
8111 ASC_DBG(3, "asc_pci_find_dev: PCI_DEVICE_FOUND\n");
8112 return PCI_DEVICE_FOUND;
8113 } else {
8114 pciData.offset = SUBCLASS_OFFSET;
8115 subclass = asc_get_cfg_byte(&pciData);
8116 pciData.offset = CLASSCODE_OFFSET;
8117 classcode = asc_get_cfg_byte(&pciData);
8118 if ((classcode & PCI_BASE_CLASS_BRIDGE_DEVICE) &&
8119 (subclass & PCI_SUB_CLASS_PCI_TO_PCI_BRIDGE_CONTROLLER)) {
8120 pciDevice->bridge++;
8122 ASC_DBG2(3, "asc_pci_find_dev: subclass %x, classcode %x\n",
8123 subclass, classcode);
8127 return PCI_DEVICE_NOT_FOUND;
8131 * Read PCI configuration data into 'pciConfig'.
8133 ASC_INITFUNC(
8134 STATIC void,
8135 asc_get_pci_cfg(PCI_DEVICE *pciDevice, PCI_CONFIG_SPACE *pciConfig)
8138 PCI_DATA pciData;
8139 uchar counter;
8140 uchar *localConfig;
8142 ASC_DBG1(4, "asc_get_pci_cfg: slotFound %d\n ",
8143 pciDevice->slotFound);
8145 pciData.type = pciDevice->type;
8146 pciData.bus = pciDevice->busNumber;
8147 pciData.slot = pciDevice->slotFound;
8148 pciData.func = pciDevice->devFunc;
8149 localConfig = (uchar *) pciConfig;
8151 for (counter = 0; counter < sizeof(PCI_CONFIG_SPACE); counter++) {
8152 pciData.offset = counter;
8153 *localConfig = asc_get_cfg_byte(&pciData);
8154 ASC_DBG1(4, "asc_get_pci_cfg: byte %x\n", *localConfig);
8155 localConfig++;
8157 ASC_DBG1(4, "asc_get_pci_cfg: counter %d\n", counter);
8161 * Read a word (16 bits) from the PCI configuration space.
8163 * The configuration mechanism is checked for the correct access method.
8165 ASC_INITFUNC(
8166 STATIC ushort,
8167 asc_get_cfg_word(PCI_DATA *pciData)
8170 ushort tmp;
8171 ADV_DCNT address;
8172 ADV_DCNT lbus = pciData->bus;
8173 ADV_DCNT lslot = pciData->slot;
8174 ADV_DCNT lfunc = pciData->func;
8175 uchar t2CFA, t2CF8;
8176 ADV_DCNT t1CF8, t1CFC;
8178 ASC_DBG4(4, "asc_get_cfg_word: type %d, bus %u, slot %u, func %u\n",
8179 pciData->type, (unsigned) lbus, (unsigned) lslot, (unsigned) lfunc);
8182 * Check type of configuration mechanism.
8184 if (pciData->type == 2) {
8186 * Save registers to be restored later.
8188 t2CFA = inp(0xCFA); /* save PCI bus register */
8189 t2CF8 = inp(0xCF8); /* save config space enable register */
8192 * Write the bus and enable registers.
8194 /* set for type 1 cycle, if needed */
8195 outp(0xCFA, pciData->bus);
8196 /* set the function number */
8197 outp(0xCF8, 0x10 | (pciData->func << 1));
8200 * Read the configuration space type 2 locations.
8202 tmp = (ushort) inpw(0xC000 | ((pciData->slot << 8) + pciData->offset));
8204 outp(0xCFA, t2CFA); /* save PCI bus register */
8205 outp(0xCF8, t2CF8); /* save config space enable register */
8206 } else {
8208 * Type 1 or 3 configuration mechanism.
8210 * Save the CONFIG_ADDRESS and CONFIG_DATA register values.
8212 t1CF8 = inpl(0xCF8);
8213 t1CFC = inpl(0xCFC);
8216 * enable <31>, bus = <23:16>, slot = <15:11>,
8217 * func = <10:8>, reg = <7:2>
8219 address = (ADV_DCNT) ((lbus << 16) | (lslot << 11) |
8220 (lfunc << 8) | (pciData->offset & 0xFC) | 0x80000000L);
8223 * Write out the address to CONFIG_ADDRESS.
8225 outpl(0xCF8, address);
8228 * Read in word from CONFIG_DATA.
8230 tmp = (ushort) ((inpl(0xCFC) >>
8231 ((pciData->offset & 2) * 8)) & 0xFFFF);
8234 * Restore registers.
8236 outpl(0xCF8, t1CF8);
8237 outpl(0xCFC, t1CFC);
8239 ASC_DBG1(4, "asc_get_cfg_word: config data: %x\n", tmp);
8240 return tmp;
8244 * Reads a byte from the PCI configuration space.
8246 * The configuration mechanism is checked for the correct access method.
8248 ASC_INITFUNC(
8249 STATIC uchar,
8250 asc_get_cfg_byte(PCI_DATA *pciData)
8253 uchar tmp;
8254 ADV_DCNT address;
8255 ADV_DCNT lbus = pciData->bus, lslot = pciData->slot, lfunc = pciData->func;
8256 ADV_DCNT t2CFA, t2CF8;
8257 ADV_DCNT t1CF8, t1CFC;
8259 ASC_DBG1(4, "asc_get_cfg_byte: type: %d\n", pciData->type);
8262 * Check type of configuration mechanism.
8264 if (pciData->type == 2) {
8266 * Save registers to be restored later.
8268 t2CFA = inp(0xCFA); /* save PCI bus register */
8269 t2CF8 = inp(0xCF8); /* save config space enable register */
8272 * Write the bus and enable registers.
8274 /* set for type 1 cycle, if needed */
8275 outp(0xCFA, pciData->bus);
8276 /* set the function number */
8277 outp(0xCF8, 0x10 | (pciData->func << 1));
8280 * Read configuration space type 2 locations.
8282 tmp = inp(0xC000 | ((pciData->slot << 8) + pciData->offset));
8285 * Restore registers.
8287 outp(0xCF8, t2CF8); /* restore the enable register */
8288 outp(0xCFA, t2CFA); /* restore PCI bus register */
8289 } else {
8291 * Type 1 or 3 configuration mechanism.
8293 * Save CONFIG_ADDRESS and CONFIG_DATA register values.
8295 t1CF8 = inpl(0xCF8);
8296 t1CFC = inpl(0xCFC);
8299 * enable <31>, bus = <23:16>, slot = <15:11>, func = <10:8>,
8300 * reg = <7:2>
8302 address = (ADV_DCNT) ((lbus << 16) | (lslot << 11) |
8303 (lfunc << 8) | (pciData->offset & 0xFC) | 0x80000000L);
8306 * Write out address to CONFIG_ADDRESS.
8308 outpl(0xCF8, address);
8311 * Read in word from CONFIG_DATA.
8313 tmp = (uchar) ((inpl(0xCFC) >> ((pciData->offset & 3) * 8)) & 0xFF);
8316 * Restore registers.
8318 outpl(0xCF8, t1CF8);
8319 outpl(0xCFC, t1CFC);
8321 ASC_DBG1(4, "asc_get_cfg_byte: config data: %x\n", tmp);
8322 return tmp;
8326 * Write a byte to the PCI configuration space.
8328 ASC_INITFUNC(
8329 STATIC void,
8330 asc_put_cfg_byte(PCI_DATA *pciData, uchar byte_data)
8333 ADV_DCNT tmpl;
8334 ADV_DCNT address;
8335 ADV_DCNT lbus = pciData->bus, lslot = pciData->slot, lfunc = pciData->func;
8336 uchar t2CFA, t2CF8;
8337 ADV_DCNT t1CF8, t1CFC;
8339 ASC_DBG2(4, "asc_put_cfg_byte: type: %d, byte_data %x\n",
8340 pciData->type, byte_data);
8343 * Check type of configuration mechanism.
8345 if (pciData->type == 2) {
8348 * Save registers to be restored later.
8350 t2CFA = inp(0xCFA); /* save PCI bus register */
8351 t2CF8 = inp(0xCF8); /* save config space enable register */
8354 * Write bus and enable registers.
8356 outp(0xCFA, pciData->bus);
8359 * Set the function number.
8361 outp(0xCF8, 0x10 | (pciData->func << 1));
8364 * Write the configuration space type 2 locations.
8366 outp(0xC000 | ((pciData->slot << 8) + pciData->offset), byte_data);
8369 * Restore registers.
8371 outp(0xCF8, t2CF8); /* restore the enable register */
8372 outp(0xCFA, t2CFA); /* restore PCI bus register */
8373 } else {
8376 * Type 1 or 3 configuration mechanism.
8378 * Save the CONFIG_ADDRESS and CONFIG_DATA register values.
8380 t1CF8 = inpl(0xCF8);
8381 t1CFC = inpl(0xCFC);
8384 * enable <31>, bus = <23:16>, slot = <15:11>, func = <10:8>,
8385 * reg = <7:2>
8387 address = (ADV_DCNT) ((lbus << 16) | (lslot << 11) | (lfunc << 8) |
8388 (pciData->offset & 0xFC) | 0x80000000L);
8390 * Write out address to CONFIG_ADDRESS.
8392 outpl(0xCF8, address);
8395 * Write double word to CONFIG_DATA preserving the bytes
8396 * in the double not written.
8398 tmpl = inpl(0xCFC) & ~(0xFF << ((pciData->offset & 3) * 8));
8399 outpl(0xCFC, tmpl | (byte_data << ((pciData->offset & 3) * 8)));
8402 * Restore registers.
8404 outpl(0xCF8, t1CF8);
8405 outpl(0xCFC, t1CFC);
8407 ASC_DBG(4, "asc_put_cfg_byte: end\n");
8409 #endif /* ASC_CONFIG_PCI */
8410 #endif /* version < v2.1.93 */
8413 * Add a 'REQP' to the end of specified queue. Set 'tidmask'
8414 * to indicate a command is queued for the device.
8416 * 'flag' may be either ASC_FRONT or ASC_BACK.
8418 * 'REQPNEXT(reqp)' returns reqp's next pointer.
8420 STATIC void
8421 asc_enqueue(asc_queue_t *ascq, REQP reqp, int flag)
8423 int tid;
8425 ASC_DBG3(3, "asc_enqueue: ascq %lx, reqp %lx, flag %d\n",
8426 (ulong) ascq, (ulong) reqp, flag);
8427 ASC_ASSERT(advansys_interrupts_enabled() == ASC_FALSE);
8428 ASC_ASSERT(reqp != NULL);
8429 ASC_ASSERT(flag == ASC_FRONT || flag == ASC_BACK);
8430 tid = REQPTID(reqp);
8431 ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
8432 if (flag == ASC_FRONT) {
8433 REQPNEXT(reqp) = ascq->q_first[tid];
8434 ascq->q_first[tid] = reqp;
8435 /* If the queue was empty, set the last pointer. */
8436 if (ascq->q_last[tid] == NULL) {
8437 ascq->q_last[tid] = reqp;
8439 } else { /* ASC_BACK */
8440 if (ascq->q_last[tid] != NULL) {
8441 REQPNEXT(ascq->q_last[tid]) = reqp;
8443 ascq->q_last[tid] = reqp;
8444 REQPNEXT(reqp) = NULL;
8445 /* If the queue was empty, set the first pointer. */
8446 if (ascq->q_first[tid] == NULL) {
8447 ascq->q_first[tid] = reqp;
8450 /* The queue has at least one entry, set its bit. */
8451 ascq->q_tidmask |= ADV_TID_TO_TIDMASK(tid);
8452 #ifdef ADVANSYS_STATS
8453 /* Maintain request queue statistics. */
8454 ascq->q_tot_cnt[tid]++;
8455 ascq->q_cur_cnt[tid]++;
8456 if (ascq->q_cur_cnt[tid] > ascq->q_max_cnt[tid]) {
8457 ascq->q_max_cnt[tid] = ascq->q_cur_cnt[tid];
8458 ASC_DBG2(2, "asc_enqueue: new q_max_cnt[%d] %d\n",
8459 tid, ascq->q_max_cnt[tid]);
8461 REQPTIME(reqp) = REQTIMESTAMP();
8462 #endif /* ADVANSYS_STATS */
8463 ASC_DBG1(3, "asc_enqueue: reqp %lx\n", (ulong) reqp);
8464 return;
8468 * Return first queued 'REQP' on the specified queue for
8469 * the specified target device. Clear the 'tidmask' bit for
8470 * the device if no more commands are left queued for it.
8472 * 'REQPNEXT(reqp)' returns reqp's next pointer.
8474 STATIC REQP
8475 asc_dequeue(asc_queue_t *ascq, int tid)
8477 REQP reqp;
8479 ASC_DBG2(3, "asc_dequeue: ascq %lx, tid %d\n", (ulong) ascq, tid);
8480 ASC_ASSERT(advansys_interrupts_enabled() == ASC_FALSE);
8481 ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
8482 if ((reqp = ascq->q_first[tid]) != NULL) {
8483 ASC_ASSERT(ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid));
8484 ascq->q_first[tid] = REQPNEXT(reqp);
8485 /* If the queue is empty, clear its bit and the last pointer. */
8486 if (ascq->q_first[tid] == NULL) {
8487 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
8488 ASC_ASSERT(ascq->q_last[tid] == reqp);
8489 ascq->q_last[tid] = NULL;
8491 #ifdef ADVANSYS_STATS
8492 /* Maintain request queue statistics. */
8493 ascq->q_cur_cnt[tid]--;
8494 ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0);
8495 REQTIMESTAT("asc_dequeue", ascq, reqp, tid);
8496 #endif /* ADVANSYS_STATS */
8498 ASC_DBG1(3, "asc_dequeue: reqp %lx\n", (ulong) reqp);
8499 return reqp;
8503 * Return a pointer to a singly linked list of all the requests queued
8504 * for 'tid' on the 'asc_queue_t' pointed to by 'ascq'.
8506 * If 'lastpp' is not NULL, '*lastpp' will be set to point to the
8507 * the last request returned in the singly linked list.
8509 * 'tid' should either be a valid target id or if it is ASC_TID_ALL,
8510 * then all queued requests are concatenated into one list and
8511 * returned.
8513 * Note: If 'lastpp' is used to append a new list to the end of
8514 * an old list, only change the old list last pointer if '*lastpp'
8515 * (or the function return value) is not NULL, i.e. use a temporary
8516 * variable for 'lastpp' and check its value after the function return
8517 * before assigning it to the list last pointer.
8519 * Unfortunately collecting queuing time statistics adds overhead to
8520 * the function that isn't inherent to the function's algorithm.
8522 STATIC REQP
8523 asc_dequeue_list(asc_queue_t *ascq, REQP *lastpp, int tid)
8525 REQP firstp, lastp;
8526 int i;
8528 ASC_DBG2(3, "asc_dequeue_list: ascq %lx, tid %d\n", (ulong) ascq, tid);
8529 ASC_ASSERT(advansys_interrupts_enabled() == ASC_FALSE);
8530 ASC_ASSERT((tid == ASC_TID_ALL) || (tid >= 0 && tid <= ADV_MAX_TID));
8533 * If 'tid' is not ASC_TID_ALL, return requests only for
8534 * the specified 'tid'. If 'tid' is ASC_TID_ALL, return all
8535 * requests for all tids.
8537 if (tid != ASC_TID_ALL) {
8538 /* Return all requests for the specified 'tid'. */
8539 if ((ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid)) == 0) {
8540 /* List is empty; Set first and last return pointers to NULL. */
8541 firstp = lastp = NULL;
8542 } else {
8543 firstp = ascq->q_first[tid];
8544 lastp = ascq->q_last[tid];
8545 ascq->q_first[tid] = ascq->q_last[tid] = NULL;
8546 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
8547 #ifdef ADVANSYS_STATS
8549 REQP reqp;
8550 ascq->q_cur_cnt[tid] = 0;
8551 for (reqp = firstp; reqp; reqp = REQPNEXT(reqp)) {
8552 REQTIMESTAT("asc_dequeue_list", ascq, reqp, tid);
8555 #endif /* ADVANSYS_STATS */
8557 } else {
8558 /* Return all requests for all tids. */
8559 firstp = lastp = NULL;
8560 for (i = 0; i <= ADV_MAX_TID; i++) {
8561 if (ascq->q_tidmask & ADV_TID_TO_TIDMASK(i)) {
8562 if (firstp == NULL) {
8563 firstp = ascq->q_first[i];
8564 lastp = ascq->q_last[i];
8565 } else {
8566 ASC_ASSERT(lastp != NULL);
8567 REQPNEXT(lastp) = ascq->q_first[i];
8568 lastp = ascq->q_last[i];
8570 ascq->q_first[i] = ascq->q_last[i] = NULL;
8571 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(i);
8572 #ifdef ADVANSYS_STATS
8573 ascq->q_cur_cnt[i] = 0;
8574 #endif /* ADVANSYS_STATS */
8577 #ifdef ADVANSYS_STATS
8579 REQP reqp;
8580 for (reqp = firstp; reqp; reqp = REQPNEXT(reqp)) {
8581 REQTIMESTAT("asc_dequeue_list", ascq, reqp, reqp->target);
8584 #endif /* ADVANSYS_STATS */
8586 if (lastpp) {
8587 *lastpp = lastp;
8589 ASC_DBG1(3, "asc_dequeue_list: firstp %lx\n", (ulong) firstp);
8590 return firstp;
8594 * Remove the specified 'REQP' from the specified queue for
8595 * the specified target device. Clear the 'tidmask' bit for the
8596 * device if no more commands are left queued for it.
8598 * 'REQPNEXT(reqp)' returns reqp's the next pointer.
8600 * Return ASC_TRUE if the command was found and removed,
8601 * otherwise return ASC_FALSE.
8603 STATIC int
8604 asc_rmqueue(asc_queue_t *ascq, REQP reqp)
8606 REQP currp, prevp;
8607 int tid;
8608 int ret = ASC_FALSE;
8610 ASC_DBG2(3, "asc_rmqueue: ascq %lx, reqp %lx\n",
8611 (ulong) ascq, (ulong) reqp);
8612 ASC_ASSERT(advansys_interrupts_enabled() == ASC_FALSE);
8613 ASC_ASSERT(reqp != NULL);
8615 tid = REQPTID(reqp);
8616 ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
8619 * Handle the common case of 'reqp' being the first
8620 * entry on the queue.
8622 if (reqp == ascq->q_first[tid]) {
8623 ret = ASC_TRUE;
8624 ascq->q_first[tid] = REQPNEXT(reqp);
8625 /* If the queue is now empty, clear its bit and the last pointer. */
8626 if (ascq->q_first[tid] == NULL) {
8627 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
8628 ASC_ASSERT(ascq->q_last[tid] == reqp);
8629 ascq->q_last[tid] = NULL;
8631 } else if (ascq->q_first[tid] != NULL) {
8632 ASC_ASSERT(ascq->q_last[tid] != NULL);
8634 * Because the case of 'reqp' being the first entry has been
8635 * handled above and it is known the queue is not empty, if
8636 * 'reqp' is found on the queue it is guaranteed the queue will
8637 * not become empty and that 'q_first[tid]' will not be changed.
8639 * Set 'prevp' to the first entry, 'currp' to the second entry,
8640 * and search for 'reqp'.
8642 for (prevp = ascq->q_first[tid], currp = REQPNEXT(prevp);
8643 currp; prevp = currp, currp = REQPNEXT(currp)) {
8644 if (currp == reqp) {
8645 ret = ASC_TRUE;
8646 REQPNEXT(prevp) = REQPNEXT(currp);
8647 REQPNEXT(reqp) = NULL;
8648 if (ascq->q_last[tid] == reqp) {
8649 ascq->q_last[tid] = prevp;
8651 break;
8655 #ifdef ADVANSYS_STATS
8656 /* Maintain request queue statistics. */
8657 if (ret == ASC_TRUE) {
8658 ascq->q_cur_cnt[tid]--;
8659 REQTIMESTAT("asc_rmqueue", ascq, reqp, tid);
8661 ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0);
8662 #endif /* ADVANSYS_STATS */
8663 ASC_DBG2(3, "asc_rmqueue: reqp %lx, ret %d\n", (ulong) reqp, ret);
8664 return ret;
8668 * If the specified 'REQP' is queued on the specified queue for
8669 * the specified target device, return ASC_TRUE.
8671 STATIC int
8672 asc_isqueued(asc_queue_t *ascq, REQP reqp)
8674 REQP treqp;
8675 int tid;
8676 int ret = ASC_FALSE;
8678 ASC_DBG2(3, "asc_isqueued: ascq %lx, reqp %lx\n",
8679 (ulong) ascq, (ulong) reqp);
8680 ASC_ASSERT(advansys_interrupts_enabled() == ASC_FALSE);
8681 ASC_ASSERT(reqp != NULL);
8683 tid = REQPTID(reqp);
8684 ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
8686 for (treqp = ascq->q_first[tid]; treqp; treqp = REQPNEXT(treqp)) {
8687 ASC_ASSERT(ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid));
8688 if (treqp == reqp) {
8689 ret = ASC_TRUE;
8690 break;
8693 ASC_DBG1(3, "asc_isqueued: ret %x\n", ret);
8694 return ret;
8698 * Execute as many queued requests as possible for the specified queue.
8700 * Calls asc_execute_scsi_cmnd() to execute a REQP/Scsi_Cmnd.
8702 STATIC void
8703 asc_execute_queue(asc_queue_t *ascq)
8705 ADV_SCSI_BIT_ID_TYPE scan_tidmask;
8706 REQP reqp;
8707 int i;
8709 ASC_DBG1(1, "asc_execute_queue: ascq %lx\n", (ulong) ascq);
8710 ASC_ASSERT(advansys_interrupts_enabled() == ASC_FALSE);
8712 * Execute queued commands for devices attached to
8713 * the current board in round-robin fashion.
8715 scan_tidmask = ascq->q_tidmask;
8716 do {
8717 for (i = 0; i <= ADV_MAX_TID; i++) {
8718 if (scan_tidmask & ADV_TID_TO_TIDMASK(i)) {
8719 if ((reqp = asc_dequeue(ascq, i)) == NULL) {
8720 scan_tidmask &= ~ADV_TID_TO_TIDMASK(i);
8721 } else if (asc_execute_scsi_cmnd((Scsi_Cmnd *) reqp)
8722 == ASC_BUSY) {
8723 scan_tidmask &= ~ADV_TID_TO_TIDMASK(i);
8724 /* Put the request back at front of the list. */
8725 asc_enqueue(ascq, reqp, ASC_FRONT);
8729 } while (scan_tidmask);
8730 return;
8733 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
8735 * asc_prt_board_devices()
8737 * Print driver information for devices attached to the board.
8739 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
8740 * cf. asc_prt_line().
8742 * Return the number of characters copied into 'cp'. No more than
8743 * 'cplen' characters will be copied to 'cp'.
8745 STATIC int
8746 asc_prt_board_devices(struct Scsi_Host *shp, char *cp, int cplen)
8748 asc_board_t *boardp;
8749 int leftlen;
8750 int totlen;
8751 int len;
8752 int chip_scsi_id;
8753 int i;
8755 boardp = ASC_BOARDP(shp);
8756 leftlen = cplen;
8757 totlen = len = 0;
8759 len = asc_prt_line(cp, leftlen,
8760 "\nDevice Information for AdvanSys SCSI Host %d:\n", shp->host_no);
8761 ASC_PRT_NEXT();
8763 if (ASC_NARROW_BOARD(boardp)) {
8764 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
8765 } else {
8766 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
8769 len = asc_prt_line(cp, leftlen, "Target IDs Detected:");
8770 ASC_PRT_NEXT();
8771 for (i = 0; i <= ADV_MAX_TID; i++) {
8772 if (boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) {
8773 len = asc_prt_line(cp, leftlen, " %X,", i);
8774 ASC_PRT_NEXT();
8777 len = asc_prt_line(cp, leftlen, " (%X=Host Adapter)\n", chip_scsi_id);
8778 ASC_PRT_NEXT();
8780 return totlen;
8784 * Display Wide Board BIOS Information.
8786 STATIC int
8787 asc_prt_adv_bios(struct Scsi_Host *shp, char *cp, int cplen)
8789 asc_board_t *boardp;
8790 int leftlen;
8791 int totlen;
8792 int len;
8793 ushort major, minor, letter;
8795 boardp = ASC_BOARDP(shp);
8796 leftlen = cplen;
8797 totlen = len = 0;
8799 len = asc_prt_line(cp, leftlen, "\nROM BIOS Version: ");
8800 ASC_PRT_NEXT();
8803 * If the BIOS saved a valid signature, then fill in
8804 * the BIOS code segment base address.
8806 if (boardp->bios_signature != 0x55AA) {
8807 len = asc_prt_line(cp, leftlen, "Disabled or Pre-3.1\n");
8808 ASC_PRT_NEXT();
8809 len = asc_prt_line(cp, leftlen,
8810 "BIOS either disabled or Pre-3.1. If it is pre-3.1, then a newer version\n");
8811 ASC_PRT_NEXT();
8812 len = asc_prt_line(cp, leftlen,
8813 "can be found at the AdvanSys FTP site: ftp://ftp.advansys.com/pub\n");
8814 ASC_PRT_NEXT();
8815 } else {
8816 major = (boardp->bios_version >> 12) & 0xF;
8817 minor = (boardp->bios_version >> 8) & 0xF;
8818 letter = (boardp->bios_version & 0xFF);
8820 len = asc_prt_line(cp, leftlen, "%d.%d%c\n",
8821 major, minor, letter >= 26 ? '?' : letter + 'A');
8822 ASC_PRT_NEXT();
8825 * Current available ROM BIOS release is 3.1I for UW
8826 * and 3.2I for U2W. This code doesn't differentiate
8827 * UW and U2W boards.
8829 if (major < 3 || (major <= 3 && minor < 1) ||
8830 (major <= 3 && minor <= 1 && letter < ('I'- 'A'))) {
8831 len = asc_prt_line(cp, leftlen,
8832 "Newer version of ROM BIOS is available at the AdvanSys FTP site:\n");
8833 ASC_PRT_NEXT();
8834 len = asc_prt_line(cp, leftlen,
8835 "ftp://ftp.advansys.com/pub\n");
8836 ASC_PRT_NEXT();
8840 return totlen;
8844 * Add serial number to information bar if signature AAh
8845 * is found in at bit 15-9 (7 bits) of word 1.
8847 * Serial Number consists fo 12 alpha-numeric digits.
8849 * 1 - Product type (A,B,C,D..) Word0: 15-13 (3 bits)
8850 * 2 - MFG Location (A,B,C,D..) Word0: 12-10 (3 bits)
8851 * 3-4 - Product ID (0-99) Word0: 9-0 (10 bits)
8852 * 5 - Product revision (A-J) Word0: " "
8854 * Signature Word1: 15-9 (7 bits)
8855 * 6 - Year (0-9) Word1: 8-6 (3 bits) & Word2: 15 (1 bit)
8856 * 7-8 - Week of the year (1-52) Word1: 5-0 (6 bits)
8858 * 9-12 - Serial Number (A001-Z999) Word2: 14-0 (15 bits)
8860 * Note 1: Only production cards will have a serial number.
8862 * Note 2: Signature is most significant 7 bits (0xFE).
8864 * Returns ASC_TRUE if serial number found, otherwise returns ASC_FALSE.
8866 STATIC int
8867 asc_get_eeprom_string(ushort *serialnum, uchar *cp)
8869 ushort w, num;
8871 if ((serialnum[1] & 0xFE00) != ((ushort) 0xAA << 8)) {
8872 return ASC_FALSE;
8873 } else {
8875 * First word - 6 digits.
8877 w = serialnum[0];
8879 /* Product type - 1st digit. */
8880 if ((*cp = 'A' + ((w & 0xE000) >> 13)) == 'H') {
8881 /* Product type is P=Prototype */
8882 *cp += 0x8;
8884 cp++;
8886 /* Manufacturing location - 2nd digit. */
8887 *cp++ = 'A' + ((w & 0x1C00) >> 10);
8889 /* Product ID - 3rd, 4th digits. */
8890 num = w & 0x3FF;
8891 *cp++ = '0' + (num / 100);
8892 num %= 100;
8893 *cp++ = '0' + (num / 10);
8895 /* Product revision - 5th digit. */
8896 *cp++ = 'A' + (num % 10);
8899 * Second word
8901 w = serialnum[1];
8904 * Year - 6th digit.
8906 * If bit 15 of third word is set, then the
8907 * last digit of the year is greater than 7.
8909 if (serialnum[2] & 0x8000) {
8910 *cp++ = '8' + ((w & 0x1C0) >> 6);
8911 } else {
8912 *cp++ = '0' + ((w & 0x1C0) >> 6);
8915 /* Week of year - 7th, 8th digits. */
8916 num = w & 0x003F;
8917 *cp++ = '0' + num / 10;
8918 num %= 10;
8919 *cp++ = '0' + num;
8922 * Third word
8924 w = serialnum[2] & 0x7FFF;
8926 /* Serial number - 9th digit. */
8927 *cp++ = 'A' + (w / 1000);
8929 /* 10th, 11th, 12th digits. */
8930 num = w % 1000;
8931 *cp++ = '0' + num / 100;
8932 num %= 100;
8933 *cp++ = '0' + num / 10;
8934 num %= 10;
8935 *cp++ = '0' + num;
8937 *cp = '\0'; /* Null Terminate the string. */
8938 return ASC_TRUE;
8943 * asc_prt_asc_board_eeprom()
8945 * Print board EEPROM configuration.
8947 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
8948 * cf. asc_prt_line().
8950 * Return the number of characters copied into 'cp'. No more than
8951 * 'cplen' characters will be copied to 'cp'.
8953 STATIC int
8954 asc_prt_asc_board_eeprom(struct Scsi_Host *shp, char *cp, int cplen)
8956 asc_board_t *boardp;
8957 ASC_DVC_VAR *asc_dvc_varp;
8958 int leftlen;
8959 int totlen;
8960 int len;
8961 ASCEEP_CONFIG *ep;
8962 int i;
8963 int isa_dma_speed[] = { 10, 8, 7, 6, 5, 4, 3, 2 };
8964 uchar serialstr[13];
8966 boardp = ASC_BOARDP(shp);
8967 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
8968 ep = &boardp->eep_config.asc_eep;
8970 leftlen = cplen;
8971 totlen = len = 0;
8973 len = asc_prt_line(cp, leftlen,
8974 "\nEEPROM Settings for AdvanSys SCSI Host %d:\n", shp->host_no);
8975 ASC_PRT_NEXT();
8977 if (asc_get_eeprom_string((ushort *) &ep->adapter_info[0], serialstr) ==
8978 ASC_TRUE) {
8979 len = asc_prt_line(cp, leftlen, " Serial Number: %s\n", serialstr);
8980 ASC_PRT_NEXT();
8981 } else {
8982 if (ep->adapter_info[5] == 0xBB) {
8983 len = asc_prt_line(cp, leftlen,
8984 " Default Settings Used for EEPROM-less Adapter.\n");
8985 ASC_PRT_NEXT();
8986 } else {
8987 len = asc_prt_line(cp, leftlen,
8988 " Serial Number Signature Not Present.\n");
8989 ASC_PRT_NEXT();
8993 len = asc_prt_line(cp, leftlen,
8994 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
8995 ep->chip_scsi_id, ep->max_total_qng, ep->max_tag_qng);
8996 ASC_PRT_NEXT();
8998 len = asc_prt_line(cp, leftlen,
8999 " cntl %x, no_scam %x\n",
9000 ep->cntl, ep->no_scam);
9001 ASC_PRT_NEXT();
9003 len = asc_prt_line(cp, leftlen,
9004 " Target ID: ");
9005 ASC_PRT_NEXT();
9006 for (i = 0; i <= ASC_MAX_TID; i++) {
9007 len = asc_prt_line(cp, leftlen, " %d", i);
9008 ASC_PRT_NEXT();
9010 len = asc_prt_line(cp, leftlen, "\n");
9011 ASC_PRT_NEXT();
9013 len = asc_prt_line(cp, leftlen,
9014 " Disconnects: ");
9015 ASC_PRT_NEXT();
9016 for (i = 0; i <= ASC_MAX_TID; i++) {
9017 len = asc_prt_line(cp, leftlen, " %c",
9018 (ep->disc_enable & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
9019 ASC_PRT_NEXT();
9021 len = asc_prt_line(cp, leftlen, "\n");
9022 ASC_PRT_NEXT();
9024 len = asc_prt_line(cp, leftlen,
9025 " Command Queuing: ");
9026 ASC_PRT_NEXT();
9027 for (i = 0; i <= ASC_MAX_TID; i++) {
9028 len = asc_prt_line(cp, leftlen, " %c",
9029 (ep->use_cmd_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
9030 ASC_PRT_NEXT();
9032 len = asc_prt_line(cp, leftlen, "\n");
9033 ASC_PRT_NEXT();
9035 len = asc_prt_line(cp, leftlen,
9036 " Start Motor: ");
9037 ASC_PRT_NEXT();
9038 for (i = 0; i <= ASC_MAX_TID; i++) {
9039 len = asc_prt_line(cp, leftlen, " %c",
9040 (ep->start_motor & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
9041 ASC_PRT_NEXT();
9043 len = asc_prt_line(cp, leftlen, "\n");
9044 ASC_PRT_NEXT();
9046 len = asc_prt_line(cp, leftlen,
9047 " Synchronous Transfer:");
9048 ASC_PRT_NEXT();
9049 for (i = 0; i <= ASC_MAX_TID; i++) {
9050 len = asc_prt_line(cp, leftlen, " %c",
9051 (ep->init_sdtr & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
9052 ASC_PRT_NEXT();
9054 len = asc_prt_line(cp, leftlen, "\n");
9055 ASC_PRT_NEXT();
9057 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
9058 len = asc_prt_line(cp, leftlen,
9059 " Host ISA DMA speed: %d MB/S\n",
9060 isa_dma_speed[ep->isa_dma_speed]);
9061 ASC_PRT_NEXT();
9064 return totlen;
9068 * asc_prt_adv_board_eeprom()
9070 * Print board EEPROM configuration.
9072 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
9073 * cf. asc_prt_line().
9075 * Return the number of characters copied into 'cp'. No more than
9076 * 'cplen' characters will be copied to 'cp'.
9078 STATIC int
9079 asc_prt_adv_board_eeprom(struct Scsi_Host *shp, char *cp, int cplen)
9081 asc_board_t *boardp;
9082 ADV_DVC_VAR *adv_dvc_varp;
9083 int leftlen;
9084 int totlen;
9085 int len;
9086 int i;
9087 char *termstr;
9088 uchar serialstr[13];
9089 ADVEEP_3550_CONFIG *ep_3550 = NULL;
9090 ADVEEP_38C0800_CONFIG *ep_38C0800 = NULL;
9091 ushort word;
9092 ushort *wordp;
9093 ushort sdtr_speed = 0;
9095 boardp = ASC_BOARDP(shp);
9096 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
9097 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
9099 ep_3550 = &boardp->eep_config.adv_3550_eep;
9100 } else
9102 ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
9105 leftlen = cplen;
9106 totlen = len = 0;
9108 len = asc_prt_line(cp, leftlen,
9109 "\nEEPROM Settings for AdvanSys SCSI Host %d:\n", shp->host_no);
9110 ASC_PRT_NEXT();
9112 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
9114 wordp = &ep_3550->serial_number_word1;
9115 } else
9117 wordp = &ep_38C0800->serial_number_word1;
9120 if (asc_get_eeprom_string(wordp, serialstr) == ASC_TRUE) {
9121 len = asc_prt_line(cp, leftlen, " Serial Number: %s\n", serialstr);
9122 ASC_PRT_NEXT();
9123 } else {
9124 len = asc_prt_line(cp, leftlen,
9125 " Serial Number Signature Not Present.\n");
9126 ASC_PRT_NEXT();
9129 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
9131 len = asc_prt_line(cp, leftlen,
9132 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
9133 ep_3550->adapter_scsi_id, ep_3550->max_host_qng,
9134 ep_3550->max_dvc_qng);
9135 ASC_PRT_NEXT();
9136 } else
9138 len = asc_prt_line(cp, leftlen,
9139 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
9140 ep_38C0800->adapter_scsi_id, ep_38C0800->max_host_qng,
9141 ep_38C0800->max_dvc_qng);
9142 ASC_PRT_NEXT();
9144 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
9146 word = ep_3550->termination;
9147 } else
9149 word = ep_38C0800->termination_lvd;
9151 switch (word) {
9152 case 1:
9153 termstr = "Low Off/High Off";
9154 break;
9155 case 2:
9156 termstr = "Low Off/High On";
9157 break;
9158 case 3:
9159 termstr = "Low On/High On";
9160 break;
9161 default:
9162 case 0:
9163 termstr = "Automatic";
9164 break;
9167 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
9169 len = asc_prt_line(cp, leftlen,
9170 " termination: %u (%s), bios_ctrl: %x\n",
9171 ep_3550->termination, termstr, ep_3550->bios_ctrl);
9172 ASC_PRT_NEXT();
9173 } else
9175 len = asc_prt_line(cp, leftlen,
9176 " termination: %u (%s), bios_ctrl: %x\n",
9177 ep_38C0800->termination_lvd, termstr, ep_38C0800->bios_ctrl);
9178 ASC_PRT_NEXT();
9181 len = asc_prt_line(cp, leftlen,
9182 " Target ID: ");
9183 ASC_PRT_NEXT();
9184 for (i = 0; i <= ADV_MAX_TID; i++) {
9185 len = asc_prt_line(cp, leftlen, " %X", i);
9186 ASC_PRT_NEXT();
9188 len = asc_prt_line(cp, leftlen, "\n");
9189 ASC_PRT_NEXT();
9191 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
9193 word = ep_3550->disc_enable;
9194 } else
9196 word = ep_38C0800->disc_enable;
9198 len = asc_prt_line(cp, leftlen,
9199 " Disconnects: ");
9200 ASC_PRT_NEXT();
9201 for (i = 0; i <= ADV_MAX_TID; i++) {
9202 len = asc_prt_line(cp, leftlen, " %c",
9203 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
9204 ASC_PRT_NEXT();
9206 len = asc_prt_line(cp, leftlen, "\n");
9207 ASC_PRT_NEXT();
9209 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
9211 word = ep_3550->tagqng_able;
9212 } else
9214 word = ep_38C0800->tagqng_able;
9216 len = asc_prt_line(cp, leftlen,
9217 " Command Queuing: ");
9218 ASC_PRT_NEXT();
9219 for (i = 0; i <= ADV_MAX_TID; i++) {
9220 len = asc_prt_line(cp, leftlen, " %c",
9221 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
9222 ASC_PRT_NEXT();
9224 len = asc_prt_line(cp, leftlen, "\n");
9225 ASC_PRT_NEXT();
9227 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
9229 word = ep_3550->start_motor;
9230 } else
9232 word = ep_38C0800->start_motor;
9234 len = asc_prt_line(cp, leftlen,
9235 " Start Motor: ");
9236 ASC_PRT_NEXT();
9237 for (i = 0; i <= ADV_MAX_TID; i++) {
9238 len = asc_prt_line(cp, leftlen, " %c",
9239 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
9240 ASC_PRT_NEXT();
9242 len = asc_prt_line(cp, leftlen, "\n");
9243 ASC_PRT_NEXT();
9245 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
9247 len = asc_prt_line(cp, leftlen,
9248 " Synchronous Transfer:");
9249 ASC_PRT_NEXT();
9250 for (i = 0; i <= ADV_MAX_TID; i++) {
9251 len = asc_prt_line(cp, leftlen, " %c",
9252 (ep_3550->sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
9253 ASC_PRT_NEXT();
9255 len = asc_prt_line(cp, leftlen, "\n");
9256 ASC_PRT_NEXT();
9259 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
9261 len = asc_prt_line(cp, leftlen,
9262 " Ultra Transfer: ");
9263 ASC_PRT_NEXT();
9264 for (i = 0; i <= ADV_MAX_TID; i++) {
9265 len = asc_prt_line(cp, leftlen, " %c",
9266 (ep_3550->ultra_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
9267 ASC_PRT_NEXT();
9269 len = asc_prt_line(cp, leftlen, "\n");
9270 ASC_PRT_NEXT();
9273 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
9275 word = ep_3550->wdtr_able;
9276 } else
9278 word = ep_38C0800->wdtr_able;
9280 len = asc_prt_line(cp, leftlen,
9281 " Wide Transfer: ");
9282 ASC_PRT_NEXT();
9283 for (i = 0; i <= ADV_MAX_TID; i++) {
9284 len = asc_prt_line(cp, leftlen, " %c",
9285 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
9286 ASC_PRT_NEXT();
9288 len = asc_prt_line(cp, leftlen, "\n");
9289 ASC_PRT_NEXT();
9291 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
9293 len = asc_prt_line(cp, leftlen,
9294 " Synchronous Transfer Speed (Mhz):\n ");
9295 ASC_PRT_NEXT();
9296 for (i = 0; i <= ADV_MAX_TID; i++) {
9297 char *speed_str;
9299 if (i == 0)
9301 sdtr_speed = adv_dvc_varp->sdtr_speed1;
9302 } else if (i == 4)
9304 sdtr_speed = adv_dvc_varp->sdtr_speed2;
9305 } else if (i == 8)
9307 sdtr_speed = adv_dvc_varp->sdtr_speed3;
9308 } else if (i == 12)
9310 sdtr_speed = adv_dvc_varp->sdtr_speed4;
9312 switch (sdtr_speed & ADV_MAX_TID)
9314 case 0: speed_str = "Off"; break;
9315 case 1: speed_str = " 5"; break;
9316 case 2: speed_str = " 10"; break;
9317 case 3: speed_str = " 20"; break;
9318 case 4: speed_str = " 40"; break;
9319 case 5: speed_str = " 80"; break;
9320 default: speed_str = "Unk"; break;
9322 len = asc_prt_line(cp, leftlen, "%X:%s ", i, speed_str);
9323 ASC_PRT_NEXT();
9324 if (i == 7)
9326 len = asc_prt_line(cp, leftlen, "\n ");
9327 ASC_PRT_NEXT();
9329 sdtr_speed >>= 4;
9331 len = asc_prt_line(cp, leftlen, "\n");
9332 ASC_PRT_NEXT();
9335 return totlen;
9339 * asc_prt_driver_conf()
9341 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
9342 * cf. asc_prt_line().
9344 * Return the number of characters copied into 'cp'. No more than
9345 * 'cplen' characters will be copied to 'cp'.
9347 STATIC int
9348 asc_prt_driver_conf(struct Scsi_Host *shp, char *cp, int cplen)
9350 asc_board_t *boardp;
9351 int leftlen;
9352 int totlen;
9353 int len;
9354 int chip_scsi_id;
9355 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
9356 int i;
9357 #endif /* version >= v1.3.89 */
9359 boardp = ASC_BOARDP(shp);
9361 leftlen = cplen;
9362 totlen = len = 0;
9364 len = asc_prt_line(cp, leftlen,
9365 "\nLinux Driver Configuration and Information for AdvanSys SCSI Host %d:\n",
9366 shp->host_no);
9367 ASC_PRT_NEXT();
9369 len = asc_prt_line(cp, leftlen,
9370 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,89)
9371 " host_busy %u, last_reset %u, max_id %u, max_lun %u\n",
9372 shp->host_busy, shp->last_reset, shp->max_id, shp->max_lun);
9373 #else /* version >= v1.3.89 */
9374 " host_busy %u, last_reset %u, max_id %u, max_lun %u, max_channel %u\n",
9375 shp->host_busy, shp->last_reset, shp->max_id, shp->max_lun,
9376 shp->max_channel);
9377 #endif /* version >= v1.3.89 */
9378 ASC_PRT_NEXT();
9380 len = asc_prt_line(cp, leftlen,
9381 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,57)
9382 " can_queue %d, this_id %d, sg_tablesize %u, cmd_per_lun %u\n",
9383 shp->can_queue, shp->this_id, shp->sg_tablesize, shp->cmd_per_lun);
9384 #else /* version >= v1.3.57 */
9385 " unique_id %d, can_queue %d, this_id %d, sg_tablesize %u, cmd_per_lun %u\n",
9386 shp->unique_id, shp->can_queue, shp->this_id, shp->sg_tablesize,
9387 shp->cmd_per_lun);
9388 #endif /* version >= v1.3.57 */
9389 ASC_PRT_NEXT();
9391 len = asc_prt_line(cp, leftlen,
9392 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,57)
9393 " unchecked_isa_dma %d, loaded_as_module %d\n",
9394 shp->unchecked_isa_dma, shp->loaded_as_module);
9395 #else /* version >= v1.3.57 */
9396 " unchecked_isa_dma %d, use_clustering %d, loaded_as_module %d\n",
9397 shp->unchecked_isa_dma, shp->use_clustering, shp->loaded_as_module);
9398 #endif /* version >= v1.3.57 */
9399 ASC_PRT_NEXT();
9401 len = asc_prt_line(cp, leftlen, " flags %x, last_reset %x, jiffies %x\n",
9402 boardp->flags, boardp->last_reset, jiffies);
9403 ASC_PRT_NEXT();
9405 if (ASC_NARROW_BOARD(boardp)) {
9406 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
9407 } else {
9408 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
9411 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
9412 if (boardp->flags & ASC_SELECT_QUEUE_DEPTHS) {
9413 len = asc_prt_line(cp, leftlen, " queue_depth:");
9414 ASC_PRT_NEXT();
9415 for (i = 0; i <= ADV_MAX_TID; i++) {
9416 if ((chip_scsi_id == i) ||
9417 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
9418 continue;
9420 if (boardp->device[i] == NULL) {
9421 continue;
9423 len = asc_prt_line(cp, leftlen, " %X:%d",
9424 i, boardp->device[i]->queue_depth);
9425 ASC_PRT_NEXT();
9427 len = asc_prt_line(cp, leftlen, "\n");
9428 ASC_PRT_NEXT();
9430 #endif /* version >= v1.3.89 */
9432 return totlen;
9436 * asc_prt_asc_board_info()
9438 * Print dynamic board configuration information.
9440 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
9441 * cf. asc_prt_line().
9443 * Return the number of characters copied into 'cp'. No more than
9444 * 'cplen' characters will be copied to 'cp'.
9446 STATIC int
9447 asc_prt_asc_board_info(struct Scsi_Host *shp, char *cp, int cplen)
9449 asc_board_t *boardp;
9450 int chip_scsi_id;
9451 int leftlen;
9452 int totlen;
9453 int len;
9454 ASC_DVC_VAR *v;
9455 ASC_DVC_CFG *c;
9456 int i;
9457 int renegotiate = 0;
9459 boardp = ASC_BOARDP(shp);
9460 v = &boardp->dvc_var.asc_dvc_var;
9461 c = &boardp->dvc_cfg.asc_dvc_cfg;
9462 chip_scsi_id = c->chip_scsi_id;
9464 leftlen = cplen;
9465 totlen = len = 0;
9467 len = asc_prt_line(cp, leftlen,
9468 "\nAsc Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
9469 shp->host_no);
9470 ASC_PRT_NEXT();
9472 len = asc_prt_line(cp, leftlen,
9473 " chip_version %u, lib_version %x, lib_serial_no %u, mcode_date %x\n",
9474 c->chip_version, c->lib_version, c->lib_serial_no, c->mcode_date);
9475 ASC_PRT_NEXT();
9477 len = asc_prt_line(cp, leftlen,
9478 " mcode_version %x, err_code %u\n",
9479 c->mcode_version, v->err_code);
9480 ASC_PRT_NEXT();
9482 /* Current number of commands waiting for the host. */
9483 len = asc_prt_line(cp, leftlen,
9484 " Total Command Pending: %d\n", v->cur_total_qng);
9485 ASC_PRT_NEXT();
9487 len = asc_prt_line(cp, leftlen,
9488 " Command Queuing:");
9489 ASC_PRT_NEXT();
9490 for (i = 0; i <= ASC_MAX_TID; i++) {
9491 if ((chip_scsi_id == i) ||
9492 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
9493 continue;
9495 len = asc_prt_line(cp, leftlen, " %X:%c",
9496 i, (v->use_tagged_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
9497 ASC_PRT_NEXT();
9499 len = asc_prt_line(cp, leftlen, "\n");
9500 ASC_PRT_NEXT();
9502 /* Current number of commands waiting for a device. */
9503 len = asc_prt_line(cp, leftlen,
9504 " Command Queue Pending:");
9505 ASC_PRT_NEXT();
9506 for (i = 0; i <= ASC_MAX_TID; i++) {
9507 if ((chip_scsi_id == i) ||
9508 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
9509 continue;
9511 len = asc_prt_line(cp, leftlen, " %X:%u", i, v->cur_dvc_qng[i]);
9512 ASC_PRT_NEXT();
9514 len = asc_prt_line(cp, leftlen, "\n");
9515 ASC_PRT_NEXT();
9517 /* Current limit on number of commands that can be sent to a device. */
9518 len = asc_prt_line(cp, leftlen,
9519 " Command Queue Limit:");
9520 ASC_PRT_NEXT();
9521 for (i = 0; i <= ASC_MAX_TID; i++) {
9522 if ((chip_scsi_id == i) ||
9523 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
9524 continue;
9526 len = asc_prt_line(cp, leftlen, " %X:%u", i, v->max_dvc_qng[i]);
9527 ASC_PRT_NEXT();
9529 len = asc_prt_line(cp, leftlen, "\n");
9530 ASC_PRT_NEXT();
9532 /* Indicate whether the device has returned queue full status. */
9533 len = asc_prt_line(cp, leftlen,
9534 " Command Queue Full:");
9535 ASC_PRT_NEXT();
9536 for (i = 0; i <= ASC_MAX_TID; i++) {
9537 if ((chip_scsi_id == i) ||
9538 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
9539 continue;
9541 if (boardp->queue_full & ADV_TID_TO_TIDMASK(i)) {
9542 len = asc_prt_line(cp, leftlen, " %X:Y-%d",
9543 i, boardp->queue_full_cnt[i]);
9544 } else {
9545 len = asc_prt_line(cp, leftlen, " %X:N", i);
9547 ASC_PRT_NEXT();
9549 len = asc_prt_line(cp, leftlen, "\n");
9550 ASC_PRT_NEXT();
9552 len = asc_prt_line(cp, leftlen,
9553 " Synchronous Transfer:");
9554 ASC_PRT_NEXT();
9555 for (i = 0; i <= ASC_MAX_TID; i++) {
9556 if ((chip_scsi_id == i) ||
9557 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
9558 continue;
9560 len = asc_prt_line(cp, leftlen, " %X:%c",
9561 i, (v->sdtr_done & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
9562 ASC_PRT_NEXT();
9564 len = asc_prt_line(cp, leftlen, "\n");
9565 ASC_PRT_NEXT();
9567 for (i = 0; i <= ASC_MAX_TID; i++) {
9568 uchar syn_period_ix;
9570 if ((chip_scsi_id == i) ||
9571 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
9572 ((v->init_sdtr & ADV_TID_TO_TIDMASK(i)) == 0)) {
9573 continue;
9576 len = asc_prt_line(cp, leftlen, " %X:", i);
9577 ASC_PRT_NEXT();
9579 if ((boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET) == 0)
9581 len = asc_prt_line(cp, leftlen, " Asynchronous");
9582 ASC_PRT_NEXT();
9583 } else
9585 syn_period_ix =
9586 (boardp->sdtr_data[i] >> 4) & (v->max_sdtr_index - 1);
9588 len = asc_prt_line(cp, leftlen,
9589 " Transfer Period Factor: %d (%d.%d Mhz),",
9590 v->sdtr_period_tbl[syn_period_ix],
9591 250 / v->sdtr_period_tbl[syn_period_ix],
9592 ASC_TENTHS(250, v->sdtr_period_tbl[syn_period_ix]));
9593 ASC_PRT_NEXT();
9595 len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
9596 boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET);
9597 ASC_PRT_NEXT();
9600 if ((v->sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
9601 len = asc_prt_line(cp, leftlen, "*\n");
9602 renegotiate = 1;
9603 } else
9605 len = asc_prt_line(cp, leftlen, "\n");
9607 ASC_PRT_NEXT();
9610 if (renegotiate)
9612 len = asc_prt_line(cp, leftlen,
9613 " * = Re-negotiation pending before next command.\n");
9614 ASC_PRT_NEXT();
9617 return totlen;
9621 * asc_prt_adv_board_info()
9623 * Print dynamic board configuration information.
9625 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
9626 * cf. asc_prt_line().
9628 * Return the number of characters copied into 'cp'. No more than
9629 * 'cplen' characters will be copied to 'cp'.
9631 STATIC int
9632 asc_prt_adv_board_info(struct Scsi_Host *shp, char *cp, int cplen)
9634 asc_board_t *boardp;
9635 int leftlen;
9636 int totlen;
9637 int len;
9638 int i;
9639 ADV_DVC_VAR *v;
9640 ADV_DVC_CFG *c;
9641 AdvPortAddr iop_base;
9642 ushort chip_scsi_id;
9643 ushort lramword;
9644 uchar lrambyte;
9645 ushort tagqng_able;
9646 ushort sdtr_able, wdtr_able;
9647 ushort wdtr_done, sdtr_done;
9648 ushort period = 0;
9649 int renegotiate = 0;
9651 boardp = ASC_BOARDP(shp);
9652 v = &boardp->dvc_var.adv_dvc_var;
9653 c = &boardp->dvc_cfg.adv_dvc_cfg;
9654 iop_base = v->iop_base;
9655 chip_scsi_id = v->chip_scsi_id;
9657 leftlen = cplen;
9658 totlen = len = 0;
9660 len = asc_prt_line(cp, leftlen,
9661 "\nAdv Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
9662 shp->host_no);
9663 ASC_PRT_NEXT();
9665 len = asc_prt_line(cp, leftlen,
9666 " iop_base %lx, cable_detect: %X, err_code %u\n",
9667 v->iop_base,
9668 AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1) & CABLE_DETECT,
9669 v->err_code);
9670 ASC_PRT_NEXT();
9672 len = asc_prt_line(cp, leftlen,
9673 " chip_version %u, lib_version %x, mcode_date %x, mcode_version %x\n",
9674 c->chip_version, c->lib_version, c->mcode_date, c->mcode_version);
9675 ASC_PRT_NEXT();
9677 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
9678 len = asc_prt_line(cp, leftlen,
9679 " Queuing Enabled:");
9680 ASC_PRT_NEXT();
9681 for (i = 0; i <= ADV_MAX_TID; i++) {
9682 if ((chip_scsi_id == i) ||
9683 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
9684 continue;
9687 len = asc_prt_line(cp, leftlen, " %X:%c",
9688 i, (tagqng_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
9689 ASC_PRT_NEXT();
9691 len = asc_prt_line(cp, leftlen, "\n");
9692 ASC_PRT_NEXT();
9694 len = asc_prt_line(cp, leftlen,
9695 " Queue Limit:");
9696 ASC_PRT_NEXT();
9697 for (i = 0; i <= ADV_MAX_TID; i++) {
9698 if ((chip_scsi_id == i) ||
9699 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
9700 continue;
9703 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + i, lrambyte);
9705 len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
9706 ASC_PRT_NEXT();
9708 len = asc_prt_line(cp, leftlen, "\n");
9709 ASC_PRT_NEXT();
9711 len = asc_prt_line(cp, leftlen,
9712 " Command Pending:");
9713 ASC_PRT_NEXT();
9714 for (i = 0; i <= ADV_MAX_TID; i++) {
9715 if ((chip_scsi_id == i) ||
9716 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
9717 continue;
9720 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_QUEUED_CMD + i, lrambyte);
9722 len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
9723 ASC_PRT_NEXT();
9725 len = asc_prt_line(cp, leftlen, "\n");
9726 ASC_PRT_NEXT();
9728 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
9729 len = asc_prt_line(cp, leftlen,
9730 " Wide Enabled:");
9731 ASC_PRT_NEXT();
9732 for (i = 0; i <= ADV_MAX_TID; i++) {
9733 if ((chip_scsi_id == i) ||
9734 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
9735 continue;
9738 len = asc_prt_line(cp, leftlen, " %X:%c",
9739 i, (wdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
9740 ASC_PRT_NEXT();
9742 len = asc_prt_line(cp, leftlen, "\n");
9743 ASC_PRT_NEXT();
9745 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, wdtr_done);
9746 len = asc_prt_line(cp, leftlen,
9747 " Transfer Bit Width:");
9748 ASC_PRT_NEXT();
9749 for (i = 0; i <= ADV_MAX_TID; i++) {
9750 if ((chip_scsi_id == i) ||
9751 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
9752 continue;
9755 AdvReadWordLram(iop_base, ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
9756 lramword);
9758 len = asc_prt_line(cp, leftlen, " %X:%d",
9759 i, (lramword & 0x8000) ? 16 : 8);
9760 ASC_PRT_NEXT();
9762 if ((wdtr_able & ADV_TID_TO_TIDMASK(i)) &&
9763 (wdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
9764 len = asc_prt_line(cp, leftlen, "*");
9765 ASC_PRT_NEXT();
9766 renegotiate = 1;
9769 len = asc_prt_line(cp, leftlen, "\n");
9770 ASC_PRT_NEXT();
9772 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
9773 len = asc_prt_line(cp, leftlen,
9774 " Synchronous Enabled:");
9775 ASC_PRT_NEXT();
9776 for (i = 0; i <= ADV_MAX_TID; i++) {
9777 if ((chip_scsi_id == i) ||
9778 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
9779 continue;
9782 len = asc_prt_line(cp, leftlen, " %X:%c",
9783 i, (sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
9784 ASC_PRT_NEXT();
9786 len = asc_prt_line(cp, leftlen, "\n");
9787 ASC_PRT_NEXT();
9789 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, sdtr_done);
9790 for (i = 0; i <= ADV_MAX_TID; i++) {
9792 AdvReadWordLram(iop_base, ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
9793 lramword);
9794 lramword &= ~0x8000;
9796 if ((chip_scsi_id == i) ||
9797 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
9798 ((sdtr_able & ADV_TID_TO_TIDMASK(i)) == 0)) {
9799 continue;
9802 len = asc_prt_line(cp, leftlen, " %X:", i);
9803 ASC_PRT_NEXT();
9805 if ((lramword & 0x1F) == 0) /* Check for REQ/ACK Offset 0. */
9807 len = asc_prt_line(cp, leftlen, " Asynchronous");
9808 ASC_PRT_NEXT();
9809 } else
9811 len = asc_prt_line(cp, leftlen, " Transfer Period Factor: ");
9812 ASC_PRT_NEXT();
9814 if ((lramword & 0x1F00) == 0x1100) /* 80 Mhz */
9816 len = asc_prt_line(cp, leftlen, "9 (80.0 Mhz),");
9817 ASC_PRT_NEXT();
9818 } else if ((lramword & 0x1F00) == 0x1000) /* 40 Mhz */
9820 len = asc_prt_line(cp, leftlen, "10 (40.0 Mhz),");
9821 ASC_PRT_NEXT();
9822 } else /* 20 Mhz or below. */
9824 period = (((lramword >> 8) * 25) + 50)/4;
9826 if (period == 0) /* Should never happen. */
9828 len = asc_prt_line(cp, leftlen, "%d (? Mhz), ");
9829 ASC_PRT_NEXT();
9830 } else
9832 len = asc_prt_line(cp, leftlen,
9833 "%d (%d.%d Mhz),",
9834 period, 250/period, ASC_TENTHS(250, period));
9835 ASC_PRT_NEXT();
9839 len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
9840 lramword & 0x1F);
9841 ASC_PRT_NEXT();
9844 if ((sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
9845 len = asc_prt_line(cp, leftlen, "*\n");
9846 renegotiate = 1;
9847 } else
9849 len = asc_prt_line(cp, leftlen, "\n");
9851 ASC_PRT_NEXT();
9854 if (renegotiate)
9856 len = asc_prt_line(cp, leftlen,
9857 " * = Re-negotiation pending before next command.\n");
9858 ASC_PRT_NEXT();
9861 return totlen;
9865 * asc_proc_copy()
9867 * Copy proc information to a read buffer taking into account the current
9868 * read offset in the file and the remaining space in the read buffer.
9870 STATIC int
9871 asc_proc_copy(off_t advoffset, off_t offset, char *curbuf, int leftlen,
9872 char *cp, int cplen)
9874 int cnt = 0;
9876 ASC_DBG3(2, "asc_proc_copy: offset %d, advoffset %d, cplen %d\n",
9877 (unsigned) offset, (unsigned) advoffset, cplen);
9878 if (offset <= advoffset) {
9879 /* Read offset below current offset, copy everything. */
9880 cnt = ASC_MIN(cplen, leftlen);
9881 ASC_DBG3(2, "asc_proc_copy: curbuf %lx, cp %lx, cnt %d\n",
9882 (ulong) curbuf, (ulong) cp, cnt);
9883 memcpy(curbuf, cp, cnt);
9884 } else if (offset < advoffset + cplen) {
9885 /* Read offset within current range, partial copy. */
9886 cnt = (advoffset + cplen) - offset;
9887 cp = (cp + cplen) - cnt;
9888 cnt = ASC_MIN(cnt, leftlen);
9889 ASC_DBG3(2, "asc_proc_copy: curbuf %lx, cp %lx, cnt %d\n",
9890 (ulong) curbuf, (ulong) cp, cnt);
9891 memcpy(curbuf, cp, cnt);
9893 return cnt;
9897 * asc_prt_line()
9899 * If 'cp' is NULL print to the console, otherwise print to a buffer.
9901 * Return 0 if printing to the console, otherwise return the number of
9902 * bytes written to the buffer.
9904 * Note: If any single line is greater than ASC_PRTLINE_SIZE bytes the stack
9905 * will be corrupted. 's[]' is defined to be ASC_PRTLINE_SIZE bytes.
9907 STATIC int
9908 asc_prt_line(char *buf, int buflen, char *fmt, ...)
9910 va_list args;
9911 int ret;
9912 char s[ASC_PRTLINE_SIZE];
9914 va_start(args, fmt);
9915 ret = vsprintf(s, fmt, args);
9916 ASC_ASSERT(ret < ASC_PRTLINE_SIZE);
9917 if (buf == NULL) {
9918 (void) printk(s);
9919 ret = 0;
9920 } else {
9921 ret = ASC_MIN(buflen, ret);
9922 memcpy(buf, s, ret);
9924 va_end(args);
9925 return ret;
9927 #endif /* version >= v1.3.0 */
9931 * --- Functions Required by the Asc Library
9935 * Delay for 'n' milliseconds. Don't use the 'jiffies'
9936 * global variable which is incremented once every 5 ms
9937 * from a timer interrupt, because this function may be
9938 * called when interrupts are disabled.
9940 STATIC void
9941 DvcSleepMilliSecond(ADV_DCNT n)
9943 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,0)
9944 ADV_DCNT i;
9945 #endif /* version < v2.1.0 */
9947 ASC_DBG1(4, "DvcSleepMilliSecond: %lu\n", (ulong) n);
9948 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(2,1,0)
9949 mdelay(n);
9950 #else /* version < v2.1.0 */
9951 for (i = 0; i < n; i++) {
9952 udelay(1000);
9954 #endif /* version < v2.1.0 */
9957 STATIC int
9958 DvcEnterCritical(void)
9960 int flags;
9962 save_flags(flags);
9963 cli();
9964 return flags;
9967 STATIC void
9968 DvcLeaveCritical(int flags)
9970 restore_flags(flags);
9973 STATIC ADV_DCNT
9974 DvcGetSGList(ASC_DVC_VAR *asc_dvc_sg, uchar *buf_addr, ADV_DCNT buf_len,
9975 ASC_SG_HEAD *asc_sg_head_ptr)
9977 ADV_DCNT buf_size;
9979 buf_size = buf_len;
9980 asc_sg_head_ptr->entry_cnt = 1;
9981 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
9982 asc_sg_head_ptr->sg_list[0].addr = (ADV_PADDR) buf_addr;
9983 #else /* version >= v2.0.0 */
9984 asc_sg_head_ptr->sg_list[0].addr = virt_to_bus(buf_addr);
9985 #endif /* version >= v2.0.0 */
9986 asc_sg_head_ptr->sg_list[0].bytes = buf_size;
9987 return buf_size;
9991 * void
9992 * DvcPutScsiQ(PortAddr iop_base, ushort s_addr, ushort *outbuf, int words)
9994 * Calling/Exit State:
9995 * none
9997 * Description:
9998 * Output an ASC_SCSI_Q structure to the chip
10000 STATIC void
10001 DvcPutScsiQ(PortAddr iop_base, ushort s_addr, ushort *outbuf, int words)
10003 int i;
10005 ASC_DBG_PRT_HEX(2, "DvcPutScsiQ", (uchar *) outbuf, 2 * words);
10006 AscSetChipLramAddr(iop_base, s_addr);
10007 for (i = 0; i < words; i++, outbuf++) {
10008 if (i == 2 || i == 10) {
10009 continue;
10011 AscSetChipLramDataNoSwap(iop_base, *outbuf);
10016 * void
10017 * DvcGetQinfo(PortAddr iop_base, ushort s_addr, ushort *inbuf, int words)
10019 * Calling/Exit State:
10020 * none
10022 * Description:
10023 * Input an ASC_QDONE_INFO structure from the chip
10025 STATIC void
10026 DvcGetQinfo(PortAddr iop_base, ushort s_addr, ushort *inbuf, int words)
10028 int i;
10030 AscSetChipLramAddr(iop_base, s_addr);
10031 for (i = 0; i < words; i++, inbuf++) {
10032 if (i == 5) {
10033 continue;
10035 *inbuf = AscGetChipLramDataNoSwap(iop_base);
10037 ASC_DBG_PRT_HEX(2, "DvcGetQinfo", (uchar *) inbuf, 2 * words);
10041 * void DvcOutPortWords(ushort iop_base, ushort &outbuf, int words)
10043 * Calling/Exit State:
10044 * none
10046 * Description:
10047 * output a buffer to an i/o port address
10049 STATIC void
10050 DvcOutPortWords(ushort iop_base, ushort *outbuf, int words)
10052 int i;
10054 for (i = 0; i < words; i++, outbuf++)
10055 outpw(iop_base, *outbuf);
10059 * void DvcInPortWords(ushort iop_base, ushort &outbuf, int words)
10061 * Calling/Exit State:
10062 * none
10064 * Description:
10065 * input a buffer from an i/o port address
10067 STATIC void
10068 DvcInPortWords(ushort iop_base, ushort *inbuf, int words)
10070 int i;
10072 for (i = 0; i < words; i++, inbuf++)
10073 *inbuf = inpw(iop_base);
10077 * void DvcOutPortDWords(PortAddr port, ADV_DCNT *pdw, int dwords)
10079 * Calling/Exit State:
10080 * none
10082 * Description:
10083 * output a buffer of 32-bit integers to an i/o port address in
10084 * 16 bit integer units
10086 STATIC void
10087 DvcOutPortDWords(PortAddr port, ADV_DCNT *pdw, int dwords)
10089 int i;
10090 int words;
10091 ushort *pw;
10093 pw = (ushort *) pdw;
10094 words = dwords << 1;
10095 for(i = 0; i < words; i++, pw++) {
10096 outpw(port, *pw);
10098 return;
10102 * Read a PCI configuration byte.
10104 ASC_INITFUNC(
10105 STATIC uchar,
10106 DvcReadPCIConfigByte(
10107 ASC_DVC_VAR *asc_dvc,
10108 ushort offset)
10111 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
10112 #ifdef ASC_CONFIG_PCI
10113 PCI_DATA pciData;
10115 pciData.bus = ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info);
10116 pciData.slot = ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info);
10117 pciData.func = ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info);
10118 pciData.offset = offset;
10119 pciData.type = pci_scan_method;
10120 return asc_get_cfg_byte(&pciData);
10121 #else /* ASC_CONFIG_PCI */
10122 return 0;
10123 #endif /* ASC_CONFIG_PCI */
10124 #else /* version >= v2.1.93 */
10125 #ifdef CONFIG_PCI
10126 uchar byte_data;
10127 pcibios_read_config_byte(ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info),
10128 PCI_DEVFN(ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info),
10129 ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info)),
10130 offset, &byte_data);
10131 return byte_data;
10132 #else /* CONFIG_PCI */
10133 return 0;
10134 #endif /* CONFIG_PCI */
10135 #endif /* version >= v2.1.93 */
10139 * Write a PCI configuration byte.
10141 ASC_INITFUNC(
10142 STATIC void,
10143 DvcWritePCIConfigByte(
10144 ASC_DVC_VAR *asc_dvc,
10145 ushort offset,
10146 uchar byte_data)
10149 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
10150 #ifdef ASC_CONFIG_PCI
10151 PCI_DATA pciData;
10153 pciData.bus = ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info);
10154 pciData.slot = ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info);
10155 pciData.func = ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info);
10156 pciData.offset = offset;
10157 pciData.type = pci_scan_method;
10158 asc_put_cfg_byte(&pciData, byte_data);
10159 #endif /* ASC_CONFIG_PCI */
10160 #else /* version >= v2.1.93 */
10161 #ifdef CONFIG_PCI
10162 pcibios_write_config_byte(ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info),
10163 PCI_DEVFN(ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info),
10164 ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info)),
10165 offset, byte_data);
10166 #endif /* CONFIG_PCI */
10167 #endif /* version >= v2.1.93 */
10171 * Return the BIOS address of the adapter at the specified
10172 * I/O port and with the specified bus type.
10174 ASC_INITFUNC(
10175 STATIC ushort,
10176 AscGetChipBiosAddress(
10177 PortAddr iop_base,
10178 ushort bus_type
10182 ushort cfg_lsw;
10183 ushort bios_addr;
10186 * The PCI BIOS is re-located by the motherboard BIOS. Because
10187 * of this the driver can not determine where a PCI BIOS is
10188 * loaded and executes.
10190 if (bus_type & ASC_IS_PCI)
10192 return(0);
10195 if((bus_type & ASC_IS_EISA) != 0)
10197 cfg_lsw = AscGetEisaChipCfg(iop_base);
10198 cfg_lsw &= 0x000F;
10199 bios_addr = (ushort)(ASC_BIOS_MIN_ADDR +
10200 (cfg_lsw * ASC_BIOS_BANK_SIZE));
10201 return(bios_addr);
10202 }/* if */
10204 cfg_lsw = AscGetChipCfgLsw(iop_base);
10207 * ISA PnP uses the top bit as the 32K BIOS flag
10209 if (bus_type == ASC_IS_ISAPNP)
10211 cfg_lsw &= 0x7FFF;
10212 }/* if */
10214 bios_addr = (ushort)(((cfg_lsw >> 12) * ASC_BIOS_BANK_SIZE) +
10215 ASC_BIOS_MIN_ADDR);
10216 return(bios_addr);
10221 * --- Functions Required by the Adv Library
10225 * DvcGetPhyAddr()
10227 * Return the physical address of 'vaddr' and set '*lenp' to the
10228 * number of physically contiguous bytes that follow 'vaddr'.
10229 * 'flag' indicates the type of structure whose physical address
10230 * is being translated.
10232 * Note: Because Linux currently doesn't page the kernel and all
10233 * kernel buffers are physically contiguous, leave '*lenp' unchanged.
10235 ADV_PADDR
10236 DvcGetPhyAddr(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq,
10237 uchar *vaddr, ADV_SDCNT *lenp, int flag)
10239 ADV_PADDR paddr;
10241 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
10242 paddr = (ADV_PADDR) vaddr;
10243 #else /* version >= v2.0.0 */
10244 paddr = virt_to_bus(vaddr);
10245 #endif /* version >= v2.0.0 */
10247 ASC_DBG4(4,
10248 "DvcGetPhyAddr: vaddr 0x%lx, lenp 0x%lx *lenp %lu, paddr 0x%lx\n",
10249 (ulong) vaddr, (ulong) lenp, (ulong) *((ulong *) lenp), (ulong) paddr);
10251 return paddr;
10255 * Read a PCI configuration byte.
10257 ASC_INITFUNC(
10258 STATIC uchar,
10259 DvcAdvReadPCIConfigByte(
10260 ADV_DVC_VAR *asc_dvc,
10261 ushort offset)
10264 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
10265 #ifdef ASC_CONFIG_PCI
10266 PCI_DATA pciData;
10268 pciData.bus = ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info);
10269 pciData.slot = ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info);
10270 pciData.func = ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info);
10271 pciData.offset = offset;
10272 pciData.type = pci_scan_method;
10273 return asc_get_cfg_byte(&pciData);
10274 #else /* ASC_CONFIG_PCI */
10275 return 0;
10276 #endif /* ASC_CONFIG_PCI */
10277 #else /* version >= v2.1.93 */
10278 #ifdef CONFIG_PCI
10279 uchar byte_data;
10280 pcibios_read_config_byte(ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info),
10281 PCI_DEVFN(ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info),
10282 ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info)),
10283 offset, &byte_data);
10284 return byte_data;
10285 #else /* CONFIG_PCI */
10286 return 0;
10287 #endif /* CONFIG_PCI */
10288 #endif /* version >= v2.1.93 */
10292 * Write a PCI configuration byte.
10294 ASC_INITFUNC(
10295 STATIC void,
10296 DvcAdvWritePCIConfigByte(
10297 ADV_DVC_VAR *asc_dvc,
10298 ushort offset,
10299 uchar byte_data)
10302 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
10303 #ifdef ASC_CONFIG_PCI
10304 PCI_DATA pciData;
10306 pciData.bus = ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info);
10307 pciData.slot = ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info);
10308 pciData.func = ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info);
10309 pciData.offset = offset;
10310 pciData.type = pci_scan_method;
10311 asc_put_cfg_byte(&pciData, byte_data);
10312 #endif /* ASC_CONFIG_PCI */
10313 #else /* version >= v2.1.93 */
10314 #ifdef CONFIG_PCI
10315 pcibios_write_config_byte(ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info),
10316 PCI_DEVFN(ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info),
10317 ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info)),
10318 offset, byte_data);
10319 #endif /* CONFIG_PCI */
10320 #endif /* version >= v2.1.93 */
10324 * --- Tracing and Debugging Functions
10327 #ifdef ADVANSYS_STATS
10329 * asc_prt_board_stats()
10331 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
10332 * cf. asc_prt_line().
10334 * Return the number of characters copied into 'cp'. No more than
10335 * 'cplen' characters will be copied to 'cp'.
10337 STATIC int
10338 asc_prt_board_stats(struct Scsi_Host *shp, char *cp, int cplen)
10340 int leftlen;
10341 int totlen;
10342 int len;
10343 struct asc_stats *s;
10344 int i;
10345 ushort chip_scsi_id;
10346 asc_board_t *boardp;
10347 asc_queue_t *active;
10348 asc_queue_t *waiting;
10350 leftlen = cplen;
10351 totlen = len = 0;
10353 boardp = ASC_BOARDP(shp);
10354 s = &boardp->asc_stats;
10356 len = asc_prt_line(cp, leftlen,
10357 "\nLinux Driver Statistics for AdvanSys SCSI Host %d:\n", shp->host_no);
10358 ASC_PRT_NEXT();
10360 len = asc_prt_line(cp, leftlen,
10361 " command %lu, queuecommand %lu, abort %lu, reset %lu, biosparam %lu\n",
10362 s->command, s->queuecommand, s->abort, s->reset, s->biosparam);
10363 ASC_PRT_NEXT();
10365 len = asc_prt_line(cp, leftlen,
10366 " interrupt %lu, callback %lu, done %lu\n",
10367 s->interrupt, s->callback, s->done);
10368 ASC_PRT_NEXT();
10370 len = asc_prt_line(cp, leftlen,
10371 " exe_noerror %lu, exe_busy %lu, exe_error %lu, exe_unknown %lu\n",
10372 s->exe_noerror, s->exe_busy, s->exe_error, s->exe_unknown);
10373 ASC_PRT_NEXT();
10375 if (ASC_NARROW_BOARD(boardp)) {
10376 len = asc_prt_line(cp, leftlen,
10377 " build_error %lu\n",
10378 s->build_error);
10379 } else {
10380 len = asc_prt_line(cp, leftlen,
10381 " build_error %lu, build_noreq %lu, build_nosg %lu\n",
10382 s->build_error, s->adv_build_noreq, s->adv_build_nosg);
10384 ASC_PRT_NEXT();
10387 * Display data transfer statistics.
10389 if (s->cont_cnt > 0) {
10390 len = asc_prt_line(cp, leftlen, " cont_cnt %lu, ", s->cont_cnt);
10391 ASC_PRT_NEXT();
10393 len = asc_prt_line(cp, leftlen, "cont_xfer %lu.%01lu kb ",
10394 s->cont_xfer/2,
10395 ASC_TENTHS(s->cont_xfer, 2));
10396 ASC_PRT_NEXT();
10398 /* Contiguous transfer average size */
10399 len = asc_prt_line(cp, leftlen, "avg_xfer %lu.%01lu kb\n",
10400 (s->cont_xfer/2)/s->cont_cnt,
10401 ASC_TENTHS((s->cont_xfer/2), s->cont_cnt));
10402 ASC_PRT_NEXT();
10405 if (s->sg_cnt > 0) {
10407 len = asc_prt_line(cp, leftlen, " sg_cnt %lu, sg_elem %lu, ",
10408 s->sg_cnt, s->sg_elem);
10409 ASC_PRT_NEXT();
10411 len = asc_prt_line(cp, leftlen, "sg_xfer %lu.%01lu kb\n",
10412 s->sg_xfer/2,
10413 ASC_TENTHS(s->sg_xfer, 2));
10414 ASC_PRT_NEXT();
10416 /* Scatter gather transfer statistics */
10417 len = asc_prt_line(cp, leftlen, " avg_num_elem %lu.%01lu, ",
10418 s->sg_elem/s->sg_cnt,
10419 ASC_TENTHS(s->sg_elem, s->sg_cnt));
10420 ASC_PRT_NEXT();
10422 len = asc_prt_line(cp, leftlen, "avg_elem_size %lu.%01lu kb, ",
10423 (s->sg_xfer/2)/s->sg_elem,
10424 ASC_TENTHS((s->sg_xfer/2), s->sg_elem));
10425 ASC_PRT_NEXT();
10427 len = asc_prt_line(cp, leftlen, "avg_xfer_size %lu.%01lu kb\n",
10428 (s->sg_xfer/2)/s->sg_cnt,
10429 ASC_TENTHS((s->sg_xfer/2), s->sg_cnt));
10430 ASC_PRT_NEXT();
10434 * Display request queuing statistics.
10436 len = asc_prt_line(cp, leftlen,
10437 " Active and Waiting Request Queues (Time Unit: %d HZ):\n", HZ);
10438 ASC_PRT_NEXT();
10440 active = &ASC_BOARDP(shp)->active;
10441 waiting = &ASC_BOARDP(shp)->waiting;
10443 if (ASC_NARROW_BOARD(boardp)) {
10444 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
10445 } else {
10446 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
10449 for (i = 0; i <= ADV_MAX_TID; i++) {
10451 if ((chip_scsi_id == i) ||
10452 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
10453 continue;
10456 if (active->q_tot_cnt[i] > 0 || waiting->q_tot_cnt[i] > 0) {
10457 len = asc_prt_line(cp, leftlen, " target %d\n", i);
10458 ASC_PRT_NEXT();
10460 len = asc_prt_line(cp, leftlen,
10461 " active: cnt [cur %d, max %d, tot %u], time [min %d, max %d, avg %lu.%01lu]\n",
10462 active->q_cur_cnt[i], active->q_max_cnt[i],
10463 active->q_tot_cnt[i],
10464 active->q_min_tim[i], active->q_max_tim[i],
10465 (active->q_tot_cnt[i] == 0) ? 0 :
10466 (active->q_tot_tim[i]/active->q_tot_cnt[i]),
10467 (active->q_tot_cnt[i] == 0) ? 0 :
10468 ASC_TENTHS(active->q_tot_tim[i], active->q_tot_cnt[i]));
10469 ASC_PRT_NEXT();
10471 len = asc_prt_line(cp, leftlen,
10472 " waiting: cnt [cur %d, max %d, tot %u], time [min %u, max %u, avg %lu.%01lu]\n",
10473 waiting->q_cur_cnt[i], waiting->q_max_cnt[i],
10474 waiting->q_tot_cnt[i],
10475 waiting->q_min_tim[i], waiting->q_max_tim[i],
10476 (waiting->q_tot_cnt[i] == 0) ? 0 :
10477 (waiting->q_tot_tim[i]/waiting->q_tot_cnt[i]),
10478 (waiting->q_tot_cnt[i] == 0) ? 0 :
10479 ASC_TENTHS(waiting->q_tot_tim[i], waiting->q_tot_cnt[i]));
10480 ASC_PRT_NEXT();
10484 return totlen;
10486 #endif /* ADVANSYS_STATS */
10488 #ifdef ADVANSYS_DEBUG
10490 * asc_prt_scsi_host()
10492 STATIC void
10493 asc_prt_scsi_host(struct Scsi_Host *s)
10495 asc_board_t *boardp;
10497 boardp = ASC_BOARDP(s);
10499 printk("Scsi_Host at addr %lx\n", (ulong) s);
10500 printk(
10501 " next %lx, extra_bytes %u, host_busy %u, host_no %d, last_reset %d,\n",
10502 (ulong) s->next, s->extra_bytes, s->host_busy, s->host_no,
10503 (unsigned) s->last_reset);
10505 printk(
10506 " host_queue %lx, hostt %lx, block %lx,\n",
10507 (ulong) s->host_queue, (ulong) s->hostt, (ulong) s->block);
10509 printk(
10510 " base %lu, io_port %lu, n_io_port %u, irq %d,\n",
10511 (ulong) s->base, (ulong) s->io_port, s->n_io_port,
10512 s->irq);
10514 printk(
10515 " dma_channel %d, this_id %d, can_queue %d,\n",
10516 s->dma_channel, s->this_id, s->can_queue);
10518 printk(
10519 " cmd_per_lun %d, sg_tablesize %d, unchecked_isa_dma %d, loaded_as_module %d\n",
10520 s->cmd_per_lun, s->sg_tablesize, s->unchecked_isa_dma,
10521 s->loaded_as_module);
10523 if (ASC_NARROW_BOARD(boardp)) {
10524 asc_prt_asc_dvc_var(&ASC_BOARDP(s)->dvc_var.asc_dvc_var);
10525 asc_prt_asc_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.asc_dvc_cfg);
10526 } else {
10527 asc_prt_adv_dvc_var(&ASC_BOARDP(s)->dvc_var.adv_dvc_var);
10528 asc_prt_adv_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.adv_dvc_cfg);
10533 * asc_prt_scsi_cmnd()
10535 STATIC void
10536 asc_prt_scsi_cmnd(Scsi_Cmnd *s)
10538 printk("Scsi_Cmnd at addr %lx\n", (ulong) s);
10540 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0)
10541 printk(
10542 " host %x, device %x, target %u, lun %u\n",
10543 (unsigned) s->host, (unsigned) s->device, s->target, s->lun);
10544 #else /* version >= v1.3.0 */
10545 printk(
10546 " host %lx, device %lx, target %u, lun %u, channel %u,\n",
10547 (ulong) s->host, (ulong) s->device, s->target, s->lun,
10548 s->channel);
10549 #endif /* version >= v1.3.0 */
10551 asc_prt_hex(" CDB", s->cmnd, s->cmd_len);
10553 printk(
10554 " use_sg %u, sglist_len %u, abort_reason %x\n",
10555 s->use_sg, s->sglist_len, s->abort_reason);
10557 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,89)
10558 printk(
10559 " retries %d, allowed %d\n",
10560 s->retries, s->allowed);
10561 #else /* version >= v1.3.89 */
10562 printk(
10563 " serial_number %x, serial_number_at_timeout %x, retries %d, allowed %d\n",
10564 (unsigned) s->serial_number, (unsigned) s->serial_number_at_timeout,
10565 s->retries, s->allowed);
10566 #endif /* version >= v1.3.89 */
10568 printk(
10569 " timeout_per_command %d, timeout_total %d, timeout %d\n",
10570 s->timeout_per_command, s->timeout_total, s->timeout);
10572 printk(
10573 " internal_timeout %u, flags %u, this_count %d\n",
10574 s->internal_timeout, s->flags, s->this_count);
10576 printk(
10577 " scsi_done %lx, done %lx, host_scribble %lx, result %x\n",
10578 (ulong) s->scsi_done, (ulong) s->done,
10579 (ulong) s->host_scribble, s->result);
10581 printk(
10582 " tag %u, pid %u\n",
10583 (unsigned) s->tag, (unsigned) s->pid);
10587 * asc_prt_asc_dvc_var()
10589 STATIC void
10590 asc_prt_asc_dvc_var(ASC_DVC_VAR *h)
10592 printk("ASC_DVC_VAR at addr %lx\n", (ulong) h);
10594 printk(
10595 " iop_base %x, err_code %x, dvc_cntl %x, bug_fix_cntl %d,\n",
10596 h->iop_base, h->err_code, h->dvc_cntl, h->bug_fix_cntl);
10598 printk(
10599 " bus_type %d, isr_callback %lx, exe_callback %lx, init_sdtr %x,\n",
10600 h->bus_type, (ulong) h->isr_callback, (ulong) h->exe_callback,
10601 (unsigned) h->init_sdtr);
10603 printk(
10604 " sdtr_done %x, use_tagged_qng %x, unit_not_ready %x, chip_no %x,\n",
10605 (unsigned) h->sdtr_done, (unsigned) h->use_tagged_qng,
10606 (unsigned) h->unit_not_ready, (unsigned) h->chip_no);
10608 printk(
10609 " queue_full_or_busy %x, start_motor %x, scsi_reset_wait %x, irq_no %x,\n",
10610 (unsigned) h->queue_full_or_busy, (unsigned) h->start_motor,
10611 (unsigned) h->scsi_reset_wait, (unsigned) h->irq_no);
10613 printk(
10614 " is_in_int %x, max_total_qng %x, cur_total_qng %x, in_critical_cnt %x,\n",
10615 (unsigned) h->is_in_int, (unsigned) h->max_total_qng,
10616 (unsigned) h->cur_total_qng, (unsigned) h->in_critical_cnt);
10618 printk(
10619 " last_q_shortage %x, init_state %x, no_scam %x, pci_fix_asyn_xfer %x,\n",
10620 (unsigned) h->last_q_shortage, (unsigned) h->init_state,
10621 (unsigned) h->no_scam, (unsigned) h->pci_fix_asyn_xfer);
10623 printk(
10624 " cfg %lx\n",
10625 (ulong) h->cfg);
10629 * asc_prt_asc_dvc_cfg()
10631 STATIC void
10632 asc_prt_asc_dvc_cfg(ASC_DVC_CFG *h)
10634 printk("ASC_DVC_CFG at addr %lx\n", (ulong) h);
10636 printk(
10637 " can_tagged_qng %x, cmd_qng_enabled %x, disc_enable %x, sdtr_enable %x,\n",
10638 h->can_tagged_qng, h->cmd_qng_enabled, h->disc_enable,
10639 h->sdtr_enable);
10641 printk(
10642 " chip_scsi_id %d, isa_dma_speed %d, isa_dma_channel %d, chip_version %d,\n",
10643 h->chip_scsi_id, h->isa_dma_speed, h->isa_dma_channel,
10644 h->chip_version);
10646 printk(
10647 " pci_device_id %d, lib_serial_no %x, lib_version %x, mcode_date %x,\n",
10648 h->pci_device_id, h->lib_serial_no, h->lib_version, h->mcode_date);
10650 printk(
10651 " mcode_version %d, overrun_buf %lx\n",
10652 h->mcode_version, (ulong) h->overrun_buf);
10656 * asc_prt_asc_scsi_q()
10658 STATIC void
10659 asc_prt_asc_scsi_q(ASC_SCSI_Q *q)
10661 ASC_SG_HEAD *sgp;
10662 int i;
10664 printk("ASC_SCSI_Q at addr %lx\n", (ulong) q);
10666 printk(
10667 " target_ix %u, target_lun %u, srb_ptr %x, tag_code %u,\n",
10668 q->q2.target_ix, q->q1.target_lun,
10669 (unsigned) q->q2.srb_ptr, q->q2.tag_code);
10671 printk(
10672 " data_addr %lx, data_cnt %lu, sense_addr %lx, sense_len %u,\n",
10673 (ulong) q->q1.data_addr, (ulong) q->q1.data_cnt,
10674 (ulong) q->q1.sense_addr, q->q1.sense_len);
10676 printk(
10677 " cdbptr %lx, cdb_len %u, sg_head %lx, sg_queue_cnt %u\n",
10678 (ulong) q->cdbptr, q->q2.cdb_len,
10679 (ulong) q->sg_head, q->q1.sg_queue_cnt);
10681 if (q->sg_head) {
10682 sgp = q->sg_head;
10683 printk("ASC_SG_HEAD at addr %lx\n", (ulong) sgp);
10684 printk(" entry_cnt %u, queue_cnt %u\n", sgp->entry_cnt, sgp->queue_cnt);
10685 for (i = 0; i < sgp->entry_cnt; i++) {
10686 printk(" [%u]: addr %lx, bytes %lu\n",
10687 i, (ulong) sgp->sg_list[i].addr,
10688 (ulong) sgp->sg_list[i].bytes);
10695 * asc_prt_asc_qdone_info()
10697 STATIC void
10698 asc_prt_asc_qdone_info(ASC_QDONE_INFO *q)
10700 printk("ASC_QDONE_INFO at addr %lx\n", (ulong) q);
10701 printk(
10702 " srb_ptr %x, target_ix %u, cdb_len %u, tag_code %u, done_stat %x\n",
10703 (unsigned) q->d2.srb_ptr, q->d2.target_ix, q->d2.cdb_len,
10704 q->d2.tag_code, q->d3.done_stat);
10705 printk(
10706 " host_stat %x, scsi_stat %x, scsi_msg %x\n",
10707 q->d3.host_stat, q->d3.scsi_stat, q->d3.scsi_msg);
10711 * asc_prt_adv_dvc_var()
10713 * Display an ADV_DVC_VAR structure.
10715 STATIC void
10716 asc_prt_adv_dvc_var(ADV_DVC_VAR *h)
10718 printk(" ADV_DVC_VAR at addr 0x%lx\n", (ulong) h);
10720 printk(
10721 " iop_base 0x%lx, err_code 0x%x, ultra_able 0x%x\n",
10722 (ulong) h->iop_base, h->err_code, (unsigned) h->ultra_able);
10724 printk(
10725 " isr_callback 0x%lx, sdtr_able 0x%x, wdtr_able 0x%x\n",
10726 (ulong) h->isr_callback, (unsigned) h->wdtr_able,
10727 (unsigned) h->sdtr_able);
10729 printk(
10730 " start_motor 0x%x, scsi_reset_wait 0x%x, irq_no 0x%x,\n",
10731 (unsigned) h->start_motor,
10732 (unsigned) h->scsi_reset_wait, (unsigned) h->irq_no);
10734 printk(
10735 " max_host_qng %x, max_dvc_qng %x, carr_freelist %lxn\n",
10736 (unsigned) h->max_host_qng, (unsigned) h->max_dvc_qng,
10737 (ulong) h->carr_freelist);
10739 printk(
10740 " icq_sp %lx, irq_sp %lx\n",
10741 (ulong) h->icq_sp, (ulong) h->irq_sp);
10743 printk(
10744 " no_scam 0x%x, tagqng_able 0x%x\n",
10745 (unsigned) h->no_scam, (unsigned) h->tagqng_able);
10747 printk(
10748 " chip_scsi_id 0x%x, cfg %lx\n",
10749 (unsigned) h->chip_scsi_id, (ulong) h->cfg);
10753 * asc_prt_adv_dvc_cfg()
10755 * Display an ADV_DVC_CFG structure.
10757 STATIC void
10758 asc_prt_adv_dvc_cfg(ADV_DVC_CFG *h)
10760 printk(" ADV_DVC_CFG at addr 0x%lx\n", (ulong) h);
10762 printk(
10763 " disc_enable 0x%x, termination 0x%x\n",
10764 h->disc_enable, h->termination);
10766 printk(
10767 " chip_version 0x%x, mcode_date 0x%x\n",
10768 h->chip_version, h->mcode_date);
10770 printk(
10771 " mcode_version 0x%x, pci_device_id 0x%x, lib_version 0x%x\n",
10772 h->mcode_version, h->pci_device_id, h->lib_version);
10774 printk(
10775 " control_flag 0x%x, pci_slot_info 0x%x\n",
10776 h->control_flag, h->pci_slot_info);
10780 * asc_prt_adv_scsi_req_q()
10782 * Display an ADV_SCSI_REQ_Q structure.
10784 STATIC void
10785 asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *q)
10787 int sg_blk_cnt;
10788 struct asc_sg_block *sg_ptr;
10790 printk("ADV_SCSI_REQ_Q at addr %lx\n", (ulong) q);
10792 printk(
10793 " target_id %u, target_lun %u, srb_ptr 0x%lx, a_flag 0x%x\n",
10794 q->target_id, q->target_lun, (ulong) q->srb_ptr, q->a_flag);
10796 printk(" cntl 0x%x, data_addr 0x%lx, vdata_addr 0x%lx\n",
10797 q->cntl, (ulong) q->data_addr, (ulong) q->vdata_addr);
10799 printk(
10800 " data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
10801 (ulong) q->data_cnt, (ulong) q->sense_addr, q->sense_len);
10803 printk(
10804 " cdb_len %u, done_status 0x%x, host_status 0x%x, scsi_status 0x%x\n",
10805 q->cdb_len, q->done_status, q->host_status, q->scsi_status);
10807 printk(
10808 " sg_working_ix %x, sg_working_data_cnt %lx, target_cmd %u\n",
10809 q->sg_working_ix, (ulong) q->sg_working_data_cnt, q->target_cmd);
10811 printk(
10812 " scsiq_rptr %lx, sg_real_addr %lx, sg_list_ptr %lx\n",
10813 (ulong) q->scsiq_rptr, (ulong) q->sg_real_addr,
10814 (ulong) q->sg_list_ptr);
10816 /* Display the request's ADV_SG_BLOCK structures. */
10817 if (q->sg_list_ptr != NULL)
10819 sg_blk_cnt = 0;
10820 while (1) {
10822 * 'sg_ptr' is a physical address. Convert it to a virtual
10823 * address by indexing 'sg_blk_cnt' into the virtual address
10824 * array 'sg_list_ptr'.
10826 * XXX - Assumes all SG physical blocks are virtually contiguous.
10828 sg_ptr = &(((ADV_SG_BLOCK *) (q->sg_list_ptr))[sg_blk_cnt]);
10829 asc_prt_adv_sgblock(sg_blk_cnt, sg_ptr);
10830 if (sg_ptr->sg_ptr == 0)
10832 break;
10834 sg_blk_cnt++;
10840 * asc_prt_adv_sgblock()
10842 * Display an ADV_SG_BLOCK structure.
10844 STATIC void
10845 asc_prt_adv_sgblock(int sgblockno, ADV_SG_BLOCK *b)
10847 int i;
10849 printk(" ASC_SG_BLOCK at addr %lx (sgblockno %d)\n",
10850 (ulong) b, sgblockno);
10851 printk(" sg_cnt %u, sg_ptr %lx\n",
10852 b->sg_cnt, (ulong) b->sg_ptr);
10853 ASC_ASSERT(b->sg_cnt <= NO_OF_SG_PER_BLOCK);
10854 if (b->sg_ptr != 0)
10856 ASC_ASSERT(b->sg_cnt == NO_OF_SG_PER_BLOCK);
10858 for (i = 0; i < b->sg_cnt; i++) {
10859 printk(" [%u]: sg_addr %lx, sg_count %lx\n",
10860 i, (ulong) b->sg_list[i].sg_addr, (ulong) b->sg_list[i].sg_count);
10865 * asc_prt_hex()
10867 * Print hexadecimal output in 4 byte groupings 32 bytes
10868 * or 8 double-words per line.
10870 STATIC void
10871 asc_prt_hex(char *f, uchar *s, int l)
10873 int i;
10874 int j;
10875 int k;
10876 int m;
10878 printk("%s: (%d bytes)\n", f, l);
10880 for (i = 0; i < l; i += 32) {
10882 /* Display a maximum of 8 double-words per line. */
10883 if ((k = (l - i) / 4) >= 8) {
10884 k = 8;
10885 m = 0;
10886 } else {
10887 m = (l - i) % 4;
10890 for (j = 0; j < k; j++) {
10891 printk(" %2.2X%2.2X%2.2X%2.2X",
10892 (unsigned) s[i+(j*4)], (unsigned) s[i+(j*4)+1],
10893 (unsigned) s[i+(j*4)+2], (unsigned) s[i+(j*4)+3]);
10896 switch (m) {
10897 case 0:
10898 default:
10899 break;
10900 case 1:
10901 printk(" %2.2X",
10902 (unsigned) s[i+(j*4)]);
10903 break;
10904 case 2:
10905 printk(" %2.2X%2.2X",
10906 (unsigned) s[i+(j*4)],
10907 (unsigned) s[i+(j*4)+1]);
10908 break;
10909 case 3:
10910 printk(" %2.2X%2.2X%2.2X",
10911 (unsigned) s[i+(j*4)+1],
10912 (unsigned) s[i+(j*4)+2],
10913 (unsigned) s[i+(j*4)+3]);
10914 break;
10917 printk("\n");
10920 #endif /* ADVANSYS_DEBUG */
10922 #ifdef ADVANSYS_ASSERT
10924 * advansys_interrupts_enabled()
10926 * Return 1 if interrupts are enabled, otherwise return 0.
10928 STATIC int
10929 advansys_interrupts_enabled(void)
10931 int flags;
10933 save_flags(flags);
10934 if (flags & 0x0200) {
10935 return ASC_TRUE;
10936 } else {
10937 return ASC_FALSE;
10940 #endif /* ADVANSYS_ASSERT */
10944 * --- Asc Library Functions
10947 ASC_INITFUNC(
10948 STATIC ushort,
10949 AscGetEisaChipCfg(
10950 PortAddr iop_base
10954 PortAddr eisa_cfg_iop;
10956 eisa_cfg_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
10957 (PortAddr) (ASC_EISA_CFG_IOP_MASK);
10958 return (inpw(eisa_cfg_iop));
10961 ASC_INITFUNC(
10962 STATIC uchar,
10963 AscSetChipScsiID(
10964 PortAddr iop_base,
10965 uchar new_host_id
10969 ushort cfg_lsw;
10971 if (AscGetChipScsiID(iop_base) == new_host_id) {
10972 return (new_host_id);
10974 cfg_lsw = AscGetChipCfgLsw(iop_base);
10975 cfg_lsw &= 0xF8FF;
10976 cfg_lsw |= (ushort) ((new_host_id & ASC_MAX_TID) << 8);
10977 AscSetChipCfgLsw(iop_base, cfg_lsw);
10978 return (AscGetChipScsiID(iop_base));
10981 ASC_INITFUNC(
10982 STATIC uchar,
10983 AscGetChipScsiCtrl(
10984 PortAddr iop_base
10988 uchar sc;
10990 AscSetBank(iop_base, 1);
10991 sc = inp(iop_base + IOP_REG_SC);
10992 AscSetBank(iop_base, 0);
10993 return (sc);
10996 ASC_INITFUNC(
10997 STATIC uchar,
10998 AscGetChipVersion(
10999 PortAddr iop_base,
11000 ushort bus_type
11004 if ((bus_type & ASC_IS_EISA) != 0) {
11005 PortAddr eisa_iop;
11006 uchar revision;
11007 eisa_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
11008 (PortAddr) ASC_EISA_REV_IOP_MASK;
11009 revision = inp(eisa_iop);
11010 return ((uchar) ((ASC_CHIP_MIN_VER_EISA - 1) + revision));
11012 return (AscGetChipVerNo(iop_base));
11015 ASC_INITFUNC(
11016 STATIC ushort,
11017 AscGetChipBusType(
11018 PortAddr iop_base
11022 ushort chip_ver;
11024 chip_ver = AscGetChipVerNo(iop_base);
11025 if (
11026 (chip_ver >= ASC_CHIP_MIN_VER_VL)
11027 && (chip_ver <= ASC_CHIP_MAX_VER_VL)
11029 if (
11030 ((iop_base & 0x0C30) == 0x0C30)
11031 || ((iop_base & 0x0C50) == 0x0C50)
11033 return (ASC_IS_EISA);
11035 return (ASC_IS_VL);
11037 if ((chip_ver >= ASC_CHIP_MIN_VER_ISA) &&
11038 (chip_ver <= ASC_CHIP_MAX_VER_ISA)) {
11039 if (chip_ver >= ASC_CHIP_MIN_VER_ISA_PNP) {
11040 return (ASC_IS_ISAPNP);
11042 return (ASC_IS_ISA);
11043 } else if ((chip_ver >= ASC_CHIP_MIN_VER_PCI) &&
11044 (chip_ver <= ASC_CHIP_MAX_VER_PCI)) {
11045 return (ASC_IS_PCI);
11047 return (0);
11050 ASC_INITFUNC(
11051 STATIC ASC_DCNT,
11052 AscLoadMicroCode(
11053 PortAddr iop_base,
11054 ushort s_addr,
11055 ushort *mcode_buf,
11056 ushort mcode_size
11060 ASC_DCNT chksum;
11061 ushort mcode_word_size;
11062 ushort mcode_chksum;
11064 mcode_word_size = (ushort) (mcode_size >> 1);
11065 AscMemWordSetLram(iop_base, s_addr, 0, mcode_word_size);
11066 AscMemWordCopyToLram(iop_base, s_addr, mcode_buf, mcode_word_size);
11067 chksum = AscMemSumLramWord(iop_base, s_addr, mcode_word_size);
11068 mcode_chksum = (ushort) AscMemSumLramWord(iop_base,
11069 (ushort) ASC_CODE_SEC_BEG,
11070 (ushort) ((mcode_size - s_addr - (ushort) ASC_CODE_SEC_BEG) / 2));
11071 AscWriteLramWord(iop_base, ASCV_MCODE_CHKSUM_W, mcode_chksum);
11072 AscWriteLramWord(iop_base, ASCV_MCODE_SIZE_W, mcode_size);
11073 return (chksum);
11076 ASC_INITFUNC(
11077 STATIC int,
11078 AscFindSignature(
11079 PortAddr iop_base
11083 ushort sig_word;
11085 if (AscGetChipSignatureByte(iop_base) == (uchar) ASC_1000_ID1B) {
11086 sig_word = AscGetChipSignatureWord(iop_base);
11087 if ((sig_word == (ushort) ASC_1000_ID0W) ||
11088 (sig_word == (ushort) ASC_1000_ID0W_FIX)) {
11089 return (1);
11092 return (0);
11095 STATIC uchar _isa_pnp_inited ASC_INITDATA = 0;
11096 STATIC PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] ASC_INITDATA =
11098 0x100, ASC_IOADR_1, 0x120, ASC_IOADR_2, 0x140, ASC_IOADR_3, ASC_IOADR_4,
11099 ASC_IOADR_5, ASC_IOADR_6, ASC_IOADR_7, ASC_IOADR_8
11102 ASC_INITFUNC(
11103 STATIC PortAddr,
11104 AscSearchIOPortAddr(
11105 PortAddr iop_beg,
11106 ushort bus_type
11110 if (bus_type & ASC_IS_VL) {
11111 while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) {
11112 if (AscGetChipVersion(iop_beg, bus_type) <= ASC_CHIP_MAX_VER_VL) {
11113 return (iop_beg);
11116 return (0);
11118 if (bus_type & ASC_IS_ISA) {
11119 if (_isa_pnp_inited == 0) {
11120 AscSetISAPNPWaitForKey();
11121 _isa_pnp_inited++;
11123 while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) {
11124 if ((AscGetChipVersion(iop_beg, bus_type) & ASC_CHIP_VER_ISA_BIT) != 0) {
11125 return (iop_beg);
11128 return (0);
11130 if (bus_type & ASC_IS_EISA) {
11131 if ((iop_beg = AscSearchIOPortAddrEISA(iop_beg)) != 0) {
11132 return (iop_beg);
11134 return (0);
11136 return (0);
11139 ASC_INITFUNC(
11140 STATIC PortAddr,
11141 AscSearchIOPortAddr11(
11142 PortAddr s_addr
11146 int i;
11147 PortAddr iop_base;
11149 for (i = 0; i < ASC_IOADR_TABLE_MAX_IX; i++) {
11150 if (_asc_def_iop_base[i] > s_addr) {
11151 break;
11154 for (; i < ASC_IOADR_TABLE_MAX_IX; i++) {
11155 iop_base = _asc_def_iop_base[i];
11156 if (check_region(iop_base, ASC_IOADR_GAP) != 0) {
11157 ASC_DBG1(1,
11158 "AscSearchIOPortAddr11: check_region() failed I/O port %x\n",
11159 iop_base);
11160 continue;
11162 ASC_DBG1(1, "AscSearchIOPortAddr11: probing I/O port %x\n", iop_base);
11163 if (AscFindSignature(iop_base)) {
11164 return (iop_base);
11167 return (0);
11170 ASC_INITFUNC(
11171 STATIC void,
11172 AscToggleIRQAct(
11173 PortAddr iop_base
11177 AscSetChipStatus(iop_base, CIW_IRQ_ACT);
11178 AscSetChipStatus(iop_base, 0);
11179 return;
11182 ASC_INITFUNC(
11183 STATIC void,
11184 AscSetISAPNPWaitForKey(
11185 void)
11188 outp(ASC_ISA_PNP_PORT_ADDR, 0x02);
11189 outp(ASC_ISA_PNP_PORT_WRITE, 0x02);
11190 return;
11193 ASC_INITFUNC(
11194 STATIC uchar,
11195 AscGetChipIRQ(
11196 PortAddr iop_base,
11197 ushort bus_type
11201 ushort cfg_lsw;
11202 uchar chip_irq;
11204 if ((bus_type & ASC_IS_EISA) != 0) {
11205 cfg_lsw = AscGetEisaChipCfg(iop_base);
11206 chip_irq = (uchar) (((cfg_lsw >> 8) & 0x07) + 10);
11207 if ((chip_irq == 13) || (chip_irq > 15)) {
11208 return (0);
11210 return (chip_irq);
11212 if ((bus_type & ASC_IS_VL) != 0) {
11213 cfg_lsw = AscGetChipCfgLsw(iop_base);
11214 chip_irq = (uchar) (((cfg_lsw >> 2) & 0x07));
11215 if ((chip_irq == 0) ||
11216 (chip_irq == 4) ||
11217 (chip_irq == 7)) {
11218 return (0);
11220 return ((uchar) (chip_irq + (ASC_MIN_IRQ_NO - 1)));
11222 cfg_lsw = AscGetChipCfgLsw(iop_base);
11223 chip_irq = (uchar) (((cfg_lsw >> 2) & 0x03));
11224 if (chip_irq == 3)
11225 chip_irq += (uchar) 2;
11226 return ((uchar) (chip_irq + ASC_MIN_IRQ_NO));
11229 ASC_INITFUNC(
11230 STATIC uchar,
11231 AscSetChipIRQ(
11232 PortAddr iop_base,
11233 uchar irq_no,
11234 ushort bus_type
11238 ushort cfg_lsw;
11240 if ((bus_type & ASC_IS_VL) != 0) {
11241 if (irq_no != 0) {
11242 if ((irq_no < ASC_MIN_IRQ_NO) || (irq_no > ASC_MAX_IRQ_NO)) {
11243 irq_no = 0;
11244 } else {
11245 irq_no -= (uchar) ((ASC_MIN_IRQ_NO - 1));
11248 cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base) & 0xFFE3);
11249 cfg_lsw |= (ushort) 0x0010;
11250 AscSetChipCfgLsw(iop_base, cfg_lsw);
11251 AscToggleIRQAct(iop_base);
11252 cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base) & 0xFFE0);
11253 cfg_lsw |= (ushort) ((irq_no & 0x07) << 2);
11254 AscSetChipCfgLsw(iop_base, cfg_lsw);
11255 AscToggleIRQAct(iop_base);
11256 return (AscGetChipIRQ(iop_base, bus_type));
11258 if ((bus_type & (ASC_IS_ISA)) != 0) {
11259 if (irq_no == 15)
11260 irq_no -= (uchar) 2;
11261 irq_no -= (uchar) ASC_MIN_IRQ_NO;
11262 cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base) & 0xFFF3);
11263 cfg_lsw |= (ushort) ((irq_no & 0x03) << 2);
11264 AscSetChipCfgLsw(iop_base, cfg_lsw);
11265 return (AscGetChipIRQ(iop_base, bus_type));
11267 return (0);
11270 ASC_INITFUNC(
11271 STATIC void,
11272 AscEnableIsaDma(
11273 uchar dma_channel
11277 if (dma_channel < 4) {
11278 outp(0x000B, (ushort) (0xC0 | dma_channel));
11279 outp(0x000A, dma_channel);
11280 } else if (dma_channel < 8) {
11281 outp(0x00D6, (ushort) (0xC0 | (dma_channel - 4)));
11282 outp(0x00D4, (ushort) (dma_channel - 4));
11284 return;
11287 STATIC int
11288 AscIsrChipHalted(
11289 ASC_DVC_VAR *asc_dvc
11292 EXT_MSG ext_msg;
11293 EXT_MSG out_msg;
11294 ushort halt_q_addr;
11295 int sdtr_accept;
11296 ushort int_halt_code;
11297 ASC_SCSI_BIT_ID_TYPE scsi_busy;
11298 ASC_SCSI_BIT_ID_TYPE target_id;
11299 PortAddr iop_base;
11300 uchar tag_code;
11301 uchar q_status;
11302 uchar halt_qp;
11303 uchar sdtr_data;
11304 uchar target_ix;
11305 uchar q_cntl, tid_no;
11306 uchar cur_dvc_qng;
11307 uchar asyn_sdtr;
11308 uchar scsi_status;
11309 asc_board_t *boardp;
11311 ASC_ASSERT(asc_dvc->drv_ptr != NULL);
11312 boardp = asc_dvc->drv_ptr;
11314 iop_base = asc_dvc->iop_base;
11315 int_halt_code = AscReadLramWord(iop_base, ASCV_HALTCODE_W);
11317 halt_qp = AscReadLramByte(iop_base, ASCV_CURCDB_B);
11318 halt_q_addr = ASC_QNO_TO_QADDR(halt_qp);
11319 target_ix = AscReadLramByte(iop_base,
11320 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TARGET_IX));
11321 q_cntl = AscReadLramByte(iop_base,
11322 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL));
11323 tid_no = ASC_TIX_TO_TID(target_ix);
11324 target_id = (uchar) ASC_TID_TO_TARGET_ID(tid_no);
11325 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
11326 asyn_sdtr = ASYN_SDTR_DATA_FIX_PCI_REV_AB;
11327 } else {
11328 asyn_sdtr = 0;
11330 if (int_halt_code == ASC_HALT_DISABLE_ASYN_USE_SYN_FIX) {
11331 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
11332 AscSetChipSDTR(iop_base, 0, tid_no);
11333 boardp->sdtr_data[tid_no] = 0;
11335 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
11336 return (0);
11337 } else if (int_halt_code == ASC_HALT_ENABLE_ASYN_USE_SYN_FIX) {
11338 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
11339 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
11340 boardp->sdtr_data[tid_no] = asyn_sdtr;
11342 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
11343 return (0);
11344 } else if (int_halt_code == ASC_HALT_EXTMSG_IN) {
11346 AscMemWordCopyFromLram(iop_base,
11347 ASCV_MSGIN_BEG,
11348 (ushort *) & ext_msg,
11349 (ushort) (sizeof (EXT_MSG) >> 1));
11351 if (ext_msg.msg_type == MS_EXTEND &&
11352 ext_msg.msg_req == MS_SDTR_CODE &&
11353 ext_msg.msg_len == MS_SDTR_LEN) {
11354 sdtr_accept = TRUE;
11355 if ((ext_msg.req_ack_offset > ASC_SYN_MAX_OFFSET)) {
11357 sdtr_accept = FALSE;
11358 ext_msg.req_ack_offset = ASC_SYN_MAX_OFFSET;
11360 if ((ext_msg.xfer_period <
11361 asc_dvc->sdtr_period_tbl[asc_dvc->host_init_sdtr_index]) ||
11362 (ext_msg.xfer_period >
11363 asc_dvc->sdtr_period_tbl[asc_dvc->max_sdtr_index])) {
11364 sdtr_accept = FALSE;
11365 ext_msg.xfer_period =
11366 asc_dvc->sdtr_period_tbl[asc_dvc->host_init_sdtr_index];
11368 if (sdtr_accept) {
11369 sdtr_data = AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
11370 ext_msg.req_ack_offset);
11371 if ((sdtr_data == 0xFF)) {
11373 q_cntl |= QC_MSG_OUT;
11374 asc_dvc->init_sdtr &= ~target_id;
11375 asc_dvc->sdtr_done &= ~target_id;
11376 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
11377 boardp->sdtr_data[tid_no] = asyn_sdtr;
11380 if (ext_msg.req_ack_offset == 0) {
11382 q_cntl &= ~QC_MSG_OUT;
11383 asc_dvc->init_sdtr &= ~target_id;
11384 asc_dvc->sdtr_done &= ~target_id;
11385 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
11386 } else {
11387 if (sdtr_accept && (q_cntl & QC_MSG_OUT)) {
11389 q_cntl &= ~QC_MSG_OUT;
11390 asc_dvc->sdtr_done |= target_id;
11391 asc_dvc->init_sdtr |= target_id;
11392 asc_dvc->pci_fix_asyn_xfer &= ~target_id;
11393 sdtr_data = AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
11394 ext_msg.req_ack_offset);
11395 AscSetChipSDTR(iop_base, sdtr_data, tid_no);
11396 boardp->sdtr_data[tid_no] = sdtr_data;
11397 } else {
11399 q_cntl |= QC_MSG_OUT;
11400 AscMsgOutSDTR(asc_dvc,
11401 ext_msg.xfer_period,
11402 ext_msg.req_ack_offset);
11403 asc_dvc->pci_fix_asyn_xfer &= ~target_id;
11404 sdtr_data = AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
11405 ext_msg.req_ack_offset);
11406 AscSetChipSDTR(iop_base, sdtr_data, tid_no);
11407 boardp->sdtr_data[tid_no] = sdtr_data;
11408 asc_dvc->sdtr_done |= target_id;
11409 asc_dvc->init_sdtr |= target_id;
11413 AscWriteLramByte(iop_base,
11414 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
11415 q_cntl);
11416 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
11417 return (0);
11418 } else if (ext_msg.msg_type == MS_EXTEND &&
11419 ext_msg.msg_req == MS_WDTR_CODE &&
11420 ext_msg.msg_len == MS_WDTR_LEN) {
11422 ext_msg.wdtr_width = 0;
11423 AscMemWordCopyToLram(iop_base,
11424 ASCV_MSGOUT_BEG,
11425 (ushort *) & ext_msg,
11426 (ushort) (sizeof (EXT_MSG) >> 1));
11427 q_cntl |= QC_MSG_OUT;
11428 AscWriteLramByte(iop_base,
11429 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
11430 q_cntl);
11431 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
11432 return (0);
11433 } else {
11435 ext_msg.msg_type = M1_MSG_REJECT;
11436 AscMemWordCopyToLram(iop_base,
11437 ASCV_MSGOUT_BEG,
11438 (ushort *) & ext_msg,
11439 (ushort) (sizeof (EXT_MSG) >> 1));
11440 q_cntl |= QC_MSG_OUT;
11441 AscWriteLramByte(iop_base,
11442 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
11443 q_cntl);
11444 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
11445 return (0);
11447 } else if (int_halt_code == ASC_HALT_CHK_CONDITION) {
11449 q_cntl |= QC_REQ_SENSE;
11451 if ((asc_dvc->init_sdtr & target_id) != 0) {
11453 asc_dvc->sdtr_done &= ~target_id;
11455 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
11456 q_cntl |= QC_MSG_OUT;
11457 AscMsgOutSDTR(asc_dvc,
11458 asc_dvc->sdtr_period_tbl[(sdtr_data >> 4) &
11459 (uchar) (asc_dvc->max_sdtr_index - 1)],
11460 (uchar) (sdtr_data & (uchar) ASC_SYN_MAX_OFFSET));
11463 AscWriteLramByte(iop_base,
11464 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
11465 q_cntl);
11467 tag_code = AscReadLramByte(iop_base,
11468 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TAG_CODE));
11469 tag_code &= 0xDC;
11470 if (
11471 (asc_dvc->pci_fix_asyn_xfer & target_id)
11472 && !(asc_dvc->pci_fix_asyn_xfer_always & target_id)
11475 tag_code |= (ASC_TAG_FLAG_DISABLE_DISCONNECT
11476 | ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX);
11479 AscWriteLramByte(iop_base,
11480 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TAG_CODE),
11481 tag_code);
11483 q_status = AscReadLramByte(iop_base,
11484 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_STATUS));
11485 q_status |= (QS_READY | QS_BUSY);
11486 AscWriteLramByte(iop_base,
11487 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_STATUS),
11488 q_status);
11490 scsi_busy = AscReadLramByte(iop_base,
11491 (ushort) ASCV_SCSIBUSY_B);
11492 scsi_busy &= ~target_id;
11493 AscWriteLramByte(iop_base, (ushort) ASCV_SCSIBUSY_B, scsi_busy);
11495 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
11496 return (0);
11497 } else if (int_halt_code == ASC_HALT_SDTR_REJECTED) {
11499 AscMemWordCopyFromLram(iop_base,
11500 ASCV_MSGOUT_BEG,
11501 (ushort *) & out_msg,
11502 (ushort) (sizeof (EXT_MSG) >> 1));
11504 if ((out_msg.msg_type == MS_EXTEND) &&
11505 (out_msg.msg_len == MS_SDTR_LEN) &&
11506 (out_msg.msg_req == MS_SDTR_CODE)) {
11508 asc_dvc->init_sdtr &= ~target_id;
11509 asc_dvc->sdtr_done &= ~target_id;
11510 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
11511 boardp->sdtr_data[tid_no] = asyn_sdtr;
11513 q_cntl &= ~QC_MSG_OUT;
11514 AscWriteLramByte(iop_base,
11515 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
11516 q_cntl);
11517 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
11518 return (0);
11519 } else if (int_halt_code == ASC_HALT_SS_QUEUE_FULL) {
11521 scsi_status = AscReadLramByte(iop_base,
11522 (ushort) ((ushort) halt_q_addr + (ushort) ASC_SCSIQ_SCSI_STATUS));
11523 cur_dvc_qng = AscReadLramByte(iop_base,
11524 (ushort) ((ushort) ASC_QADR_BEG + (ushort) target_ix));
11525 if ((cur_dvc_qng > 0) &&
11526 (asc_dvc->cur_dvc_qng[tid_no] > 0)) {
11528 scsi_busy = AscReadLramByte(iop_base,
11529 (ushort) ASCV_SCSIBUSY_B);
11530 scsi_busy |= target_id;
11531 AscWriteLramByte(iop_base,
11532 (ushort) ASCV_SCSIBUSY_B, scsi_busy);
11533 asc_dvc->queue_full_or_busy |= target_id;
11535 if (scsi_status == SS_QUEUE_FULL) {
11536 if (cur_dvc_qng > ASC_MIN_TAGGED_CMD) {
11537 cur_dvc_qng -= 1;
11538 asc_dvc->max_dvc_qng[tid_no] = cur_dvc_qng;
11540 AscWriteLramByte(iop_base,
11541 (ushort) ((ushort) ASCV_MAX_DVC_QNG_BEG +
11542 (ushort) tid_no),
11543 cur_dvc_qng);
11546 * Set the device queue depth to the number of
11547 * active requests when the QUEUE FULL condition
11548 * was encountered.
11550 boardp->queue_full |= target_id;
11551 boardp->queue_full_cnt[tid_no] = cur_dvc_qng;
11555 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
11556 return (0);
11557 } else if (int_halt_code == ASC_HALT_HOST_COPY_SG_LIST_TO_RISC)
11559 uchar q_no;
11560 ushort q_addr;
11561 uchar sg_wk_q_no;
11562 uchar first_sg_wk_q_no;
11563 ASC_SCSI_Q *scsiq; /* Ptr to driver request. */
11564 ASC_SG_HEAD *sg_head; /* Ptr to driver SG request. */
11565 ASC_SG_LIST_Q scsi_sg_q; /* Structure written to queue. */
11566 ushort sg_list_dwords;
11567 ushort sg_entry_cnt;
11568 uchar next_qp;
11569 int i;
11571 q_no = AscReadLramByte(iop_base, (ushort) ASCV_REQ_SG_LIST_QP);
11572 if (q_no == ASC_QLINK_END)
11574 return(0);
11577 q_addr = ASC_QNO_TO_QADDR(q_no);
11580 * Convert the request's SRB pointer to a host ASC_SCSI_REQ
11581 * structure pointer using a macro provided by the driver.
11582 * The ASC_SCSI_REQ pointer provides a pointer to the
11583 * host ASC_SG_HEAD structure.
11585 /* Read request's SRB pointer. */
11586 scsiq = (ASC_SCSI_Q *)
11587 ASC_SRB2SCSIQ(
11588 ASC_U32_TO_VADDR(AscReadLramDWord(iop_base,
11589 (ushort) (q_addr + ASC_SCSIQ_D_SRBPTR))));
11592 * Get request's first and working SG queue.
11594 sg_wk_q_no = AscReadLramByte(iop_base,
11595 (ushort) (q_addr + ASC_SCSIQ_B_SG_WK_QP));
11597 first_sg_wk_q_no = AscReadLramByte(iop_base,
11598 (ushort) (q_addr + ASC_SCSIQ_B_FIRST_SG_WK_QP));
11601 * Reset request's working SG queue back to the
11602 * first SG queue.
11604 AscWriteLramByte(iop_base,
11605 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_SG_WK_QP),
11606 first_sg_wk_q_no);
11608 sg_head = scsiq->sg_head;
11611 * Set sg_entry_cnt to the number of SG elements
11612 * that will be completed on this interrupt.
11614 * Note: The allocated SG queues contain ASC_MAX_SG_LIST - 1
11615 * SG elements. The data_cnt and data_addr fields which
11616 * add 1 to the SG element capacity are not used when
11617 * restarting SG handling after a halt.
11619 if (scsiq->remain_sg_entry_cnt > (ASC_MAX_SG_LIST - 1))
11621 sg_entry_cnt = ASC_MAX_SG_LIST - 1;
11624 * Keep track of remaining number of SG elements that will
11625 * need to be handled on the next interrupt.
11627 scsiq->remain_sg_entry_cnt -= (ASC_MAX_SG_LIST - 1);
11628 } else
11630 sg_entry_cnt = scsiq->remain_sg_entry_cnt;
11631 scsiq->remain_sg_entry_cnt = 0;
11635 * Copy SG elements into the list of allocated SG queues.
11637 * Last index completed is saved in scsiq->next_sg_index.
11639 next_qp = first_sg_wk_q_no;
11640 q_addr = ASC_QNO_TO_QADDR(next_qp);
11641 scsi_sg_q.sg_head_qp = q_no;
11642 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
11643 for( i = 0; i < sg_head->queue_cnt; i++)
11645 scsi_sg_q.seq_no = i + 1;
11646 if (sg_entry_cnt > ASC_SG_LIST_PER_Q)
11648 sg_list_dwords = (uchar) (ASC_SG_LIST_PER_Q * 2);
11649 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
11651 * After very first SG queue RISC FW uses next
11652 * SG queue first element then checks sg_list_cnt
11653 * against zero and then decrements, so set
11654 * sg_list_cnt 1 less than number of SG elements
11655 * in each SG queue.
11657 scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q - 1;
11658 scsi_sg_q.sg_cur_list_cnt = ASC_SG_LIST_PER_Q - 1;
11659 } else {
11661 * This is the last SG queue in the list of
11662 * allocated SG queues. If there are more
11663 * SG elements than will fit in the allocated
11664 * queues, then set the QCSG_SG_XFER_MORE flag.
11666 if (scsiq->remain_sg_entry_cnt != 0)
11668 scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
11669 } else
11671 scsi_sg_q.cntl |= QCSG_SG_XFER_END;
11673 /* equals sg_entry_cnt * 2 */
11674 sg_list_dwords = sg_entry_cnt << 1;
11675 scsi_sg_q.sg_list_cnt = sg_entry_cnt - 1;
11676 scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt - 1;
11677 sg_entry_cnt = 0;
11680 scsi_sg_q.q_no = next_qp;
11681 AscMemWordCopyToLram(iop_base,
11682 (ushort) (q_addr+ASC_SCSIQ_SGHD_CPY_BEG),
11683 (ushort *) &scsi_sg_q,
11684 (ushort) (sizeof(ASC_SG_LIST_Q) >> 1));
11686 AscMemDWordCopyToLram( iop_base,
11687 (ushort) (q_addr+ASC_SGQ_LIST_BEG ),
11688 (ADV_PADDR *)
11689 &sg_head->sg_list[scsiq->next_sg_index],
11690 (ushort) sg_list_dwords);
11692 scsiq->next_sg_index += ASC_SG_LIST_PER_Q;
11695 * If the just completed SG queue contained the
11696 * last SG element, then no more SG queues need
11697 * to be written.
11699 if (scsi_sg_q.cntl & QCSG_SG_XFER_END)
11701 break;
11704 next_qp = AscReadLramByte( iop_base,
11705 ( ushort )( q_addr+ASC_SCSIQ_B_FWD ) );
11706 q_addr = ASC_QNO_TO_QADDR( next_qp );
11710 * Clear the halt condition so the RISC will be restarted
11711 * after the return.
11713 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
11714 return(0);
11716 return (0);
11719 STATIC uchar
11720 _AscCopyLramScsiDoneQ(
11721 PortAddr iop_base,
11722 ushort q_addr,
11723 ASC_QDONE_INFO * scsiq,
11724 ASC_DCNT max_dma_count
11727 ushort _val;
11728 uchar sg_queue_cnt;
11730 DvcGetQinfo(iop_base,
11731 (ushort) (q_addr + (ushort) ASC_SCSIQ_DONE_INFO_BEG),
11732 (ushort *) scsiq,
11733 (ushort) ((sizeof (ASC_SCSIQ_2) + sizeof (ASC_SCSIQ_3)) / 2));
11734 _val = AscReadLramWord(iop_base,
11735 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS));
11736 scsiq->q_status = (uchar) _val;
11737 scsiq->q_no = (uchar) (_val >> 8);
11738 _val = AscReadLramWord(iop_base,
11739 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_CNTL));
11740 scsiq->cntl = (uchar) _val;
11741 sg_queue_cnt = (uchar) (_val >> 8);
11742 _val = AscReadLramWord(iop_base,
11743 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_SENSE_LEN));
11744 scsiq->sense_len = (uchar) _val;
11745 scsiq->extra_bytes = (uchar) (_val >> 8);
11748 * Read high word of remain bytes from alternate location.
11750 scsiq->remain_bytes = (((ADV_DCNT) AscReadLramWord( iop_base,
11751 (ushort) (q_addr+ (ushort) ASC_SCSIQ_W_ALT_DC1))) << 16);
11753 * Read low word of remain bytes from original location.
11755 scsiq->remain_bytes += AscReadLramWord(iop_base,
11756 (ushort) (q_addr+ (ushort) ASC_SCSIQ_DW_REMAIN_XFER_CNT));
11758 scsiq->remain_bytes &= max_dma_count;
11759 return (sg_queue_cnt);
11762 STATIC int
11763 AscIsrQDone(
11764 ASC_DVC_VAR *asc_dvc
11767 uchar next_qp;
11768 uchar n_q_used;
11769 uchar sg_list_qp;
11770 uchar sg_queue_cnt;
11771 uchar q_cnt;
11772 uchar done_q_tail;
11773 uchar tid_no;
11774 ASC_SCSI_BIT_ID_TYPE scsi_busy;
11775 ASC_SCSI_BIT_ID_TYPE target_id;
11776 PortAddr iop_base;
11777 ushort q_addr;
11778 ushort sg_q_addr;
11779 uchar cur_target_qng;
11780 ASC_QDONE_INFO scsiq_buf;
11781 ASC_QDONE_INFO *scsiq;
11782 int false_overrun;
11783 ASC_ISR_CALLBACK asc_isr_callback;
11785 iop_base = asc_dvc->iop_base;
11786 asc_isr_callback = asc_dvc->isr_callback;
11787 n_q_used = 1;
11788 scsiq = (ASC_QDONE_INFO *) & scsiq_buf;
11789 done_q_tail = (uchar) AscGetVarDoneQTail(iop_base);
11790 q_addr = ASC_QNO_TO_QADDR(done_q_tail);
11791 next_qp = AscReadLramByte(iop_base,
11792 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_FWD));
11793 if (next_qp != ASC_QLINK_END) {
11794 AscPutVarDoneQTail(iop_base, next_qp);
11795 q_addr = ASC_QNO_TO_QADDR(next_qp);
11796 sg_queue_cnt = _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq,
11797 asc_dvc->max_dma_count);
11798 AscWriteLramByte(iop_base,
11799 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS),
11800 (uchar) (scsiq->q_status & (uchar) ~ (QS_READY | QS_ABORTED)));
11801 tid_no = ASC_TIX_TO_TID(scsiq->d2.target_ix);
11802 target_id = ASC_TIX_TO_TARGET_ID(scsiq->d2.target_ix);
11803 if ((scsiq->cntl & QC_SG_HEAD) != 0) {
11804 sg_q_addr = q_addr;
11805 sg_list_qp = next_qp;
11806 for (q_cnt = 0; q_cnt < sg_queue_cnt; q_cnt++) {
11807 sg_list_qp = AscReadLramByte(iop_base,
11808 (ushort) (sg_q_addr + (ushort) ASC_SCSIQ_B_FWD));
11809 sg_q_addr = ASC_QNO_TO_QADDR(sg_list_qp);
11810 if (sg_list_qp == ASC_QLINK_END) {
11811 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SG_Q_LINKS);
11812 scsiq->d3.done_stat = QD_WITH_ERROR;
11813 scsiq->d3.host_stat = QHSTA_D_QDONE_SG_LIST_CORRUPTED;
11814 goto FATAL_ERR_QDONE;
11816 AscWriteLramByte(iop_base,
11817 (ushort) (sg_q_addr + (ushort) ASC_SCSIQ_B_STATUS),
11818 QS_FREE);
11820 n_q_used = sg_queue_cnt + 1;
11821 AscPutVarDoneQTail(iop_base, sg_list_qp);
11823 if (asc_dvc->queue_full_or_busy & target_id) {
11824 cur_target_qng = AscReadLramByte(iop_base,
11825 (ushort) ((ushort) ASC_QADR_BEG + (ushort) scsiq->d2.target_ix));
11826 if (cur_target_qng < asc_dvc->max_dvc_qng[tid_no]) {
11827 scsi_busy = AscReadLramByte(iop_base,
11828 (ushort) ASCV_SCSIBUSY_B);
11829 scsi_busy &= ~target_id;
11830 AscWriteLramByte(iop_base,
11831 (ushort) ASCV_SCSIBUSY_B, scsi_busy);
11832 asc_dvc->queue_full_or_busy &= ~target_id;
11835 if (asc_dvc->cur_total_qng >= n_q_used) {
11836 asc_dvc->cur_total_qng -= n_q_used;
11837 if (asc_dvc->cur_dvc_qng[tid_no] != 0) {
11838 asc_dvc->cur_dvc_qng[tid_no]--;
11840 } else {
11841 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CUR_QNG);
11842 scsiq->d3.done_stat = QD_WITH_ERROR;
11843 goto FATAL_ERR_QDONE;
11845 if ((scsiq->d2.srb_ptr == 0UL) ||
11846 ((scsiq->q_status & QS_ABORTED) != 0)) {
11847 return (0x11);
11848 } else if (scsiq->q_status == QS_DONE) {
11849 false_overrun = FALSE;
11850 if (scsiq->extra_bytes != 0) {
11851 scsiq->remain_bytes += (ADV_DCNT) scsiq->extra_bytes;
11853 if (scsiq->d3.done_stat == QD_WITH_ERROR) {
11854 if (scsiq->d3.host_stat == QHSTA_M_DATA_OVER_RUN) {
11855 if ((scsiq->cntl & (QC_DATA_IN | QC_DATA_OUT)) == 0) {
11856 scsiq->d3.done_stat = QD_NO_ERROR;
11857 scsiq->d3.host_stat = QHSTA_NO_ERROR;
11858 } else if (false_overrun) {
11859 scsiq->d3.done_stat = QD_NO_ERROR;
11860 scsiq->d3.host_stat = QHSTA_NO_ERROR;
11862 } else if (scsiq->d3.host_stat ==
11863 QHSTA_M_HUNG_REQ_SCSI_BUS_RESET) {
11864 AscStopChip(iop_base);
11865 AscSetChipControl(iop_base,
11866 (uchar) (CC_SCSI_RESET | CC_HALT));
11867 DvcDelayNanoSecond(asc_dvc, 60000);
11868 AscSetChipControl(iop_base, CC_HALT);
11869 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
11870 AscSetChipStatus(iop_base, 0);
11871 AscSetChipControl(iop_base, 0);
11874 if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
11875 (*asc_isr_callback) (asc_dvc, scsiq);
11876 } else {
11877 if ((AscReadLramByte(iop_base,
11878 (ushort) (q_addr + (ushort) ASC_SCSIQ_CDB_BEG)) ==
11879 SCSICMD_StartStopUnit)) {
11880 asc_dvc->unit_not_ready &= ~target_id;
11881 if (scsiq->d3.done_stat != QD_NO_ERROR) {
11882 asc_dvc->start_motor &= ~target_id;
11886 return (1);
11887 } else {
11888 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_Q_STATUS);
11889 FATAL_ERR_QDONE:
11890 if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
11891 (*asc_isr_callback) (asc_dvc, scsiq);
11893 return (0x80);
11896 return (0);
11899 STATIC int
11900 AscISR(
11901 ASC_DVC_VAR *asc_dvc
11904 ASC_CS_TYPE chipstat;
11905 PortAddr iop_base;
11906 ushort saved_ram_addr;
11907 uchar ctrl_reg;
11908 uchar saved_ctrl_reg;
11909 int int_pending;
11910 int status;
11911 uchar host_flag;
11913 iop_base = asc_dvc->iop_base;
11914 int_pending = FALSE;
11916 if (AscIsIntPending(iop_base) == 0)
11918 return int_pending;
11921 if (((asc_dvc->init_state & ASC_INIT_STATE_END_LOAD_MC) == 0)
11922 || (asc_dvc->isr_callback == 0)
11924 return (ERR);
11926 if (asc_dvc->in_critical_cnt != 0) {
11927 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_ON_CRITICAL);
11928 return (ERR);
11930 if (asc_dvc->is_in_int) {
11931 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_RE_ENTRY);
11932 return (ERR);
11934 asc_dvc->is_in_int = TRUE;
11935 ctrl_reg = AscGetChipControl(iop_base);
11936 saved_ctrl_reg = ctrl_reg & (~(CC_SCSI_RESET | CC_CHIP_RESET |
11937 CC_SINGLE_STEP | CC_DIAG | CC_TEST));
11938 chipstat = AscGetChipStatus(iop_base);
11939 if (chipstat & CSW_SCSI_RESET_LATCH) {
11940 if (!(asc_dvc->bus_type & (ASC_IS_VL | ASC_IS_EISA))) {
11941 int i = 10;
11942 int_pending = TRUE;
11943 asc_dvc->sdtr_done = 0;
11944 saved_ctrl_reg &= (uchar) (~CC_HALT);
11945 while ((AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE) &&
11946 (i-- > 0))
11948 DvcSleepMilliSecond(100);
11950 AscSetChipControl(iop_base, (CC_CHIP_RESET | CC_HALT));
11951 AscSetChipControl(iop_base, CC_HALT);
11952 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
11953 AscSetChipStatus(iop_base, 0);
11954 chipstat = AscGetChipStatus(iop_base);
11957 saved_ram_addr = AscGetChipLramAddr(iop_base);
11958 host_flag = AscReadLramByte(iop_base,
11959 ASCV_HOST_FLAG_B) & (uchar) (~ASC_HOST_FLAG_IN_ISR);
11960 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
11961 (uchar) (host_flag | (uchar) ASC_HOST_FLAG_IN_ISR));
11962 if ((chipstat & CSW_INT_PENDING)
11963 || (int_pending)
11965 AscAckInterrupt(iop_base);
11966 int_pending = TRUE;
11967 if ((chipstat & CSW_HALTED) &&
11968 (ctrl_reg & CC_SINGLE_STEP)) {
11969 if (AscIsrChipHalted(asc_dvc) == ERR) {
11970 goto ISR_REPORT_QDONE_FATAL_ERROR;
11971 } else {
11972 saved_ctrl_reg &= (uchar) (~CC_HALT);
11974 } else {
11975 ISR_REPORT_QDONE_FATAL_ERROR:
11976 if ((asc_dvc->dvc_cntl & ASC_CNTL_INT_MULTI_Q) != 0) {
11977 while (((status = AscIsrQDone(asc_dvc)) & 0x01) != 0) {
11979 } else {
11980 do {
11981 if ((status = AscIsrQDone(asc_dvc)) == 1) {
11982 break;
11984 } while (status == 0x11);
11986 if ((status & 0x80) != 0)
11987 int_pending = ERR;
11990 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
11991 AscSetChipLramAddr(iop_base, saved_ram_addr);
11992 AscSetChipControl(iop_base, saved_ctrl_reg);
11993 asc_dvc->is_in_int = FALSE;
11994 return (int_pending);
11997 STATIC uchar _asc_mcode_buf[] ASC_INITDATA =
11999 0x01, 0x03, 0x01, 0x19, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12000 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12001 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12002 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12003 0x00, 0x00, 0x00, 0x00, 0xC3, 0x12, 0x0D, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00,
12004 0x00, 0x00, 0x00, 0x00, 0xFF, 0x80, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12005 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00,
12006 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE4, 0x88, 0x00, 0x00, 0x00, 0x00,
12007 0x80, 0x73, 0x48, 0x04, 0x36, 0x00, 0x00, 0xA2, 0xC2, 0x00, 0x80, 0x73, 0x03, 0x23, 0x36, 0x40,
12008 0xB6, 0x00, 0x36, 0x00, 0x05, 0xD6, 0x0C, 0xD2, 0x12, 0xDA, 0x00, 0xA2, 0xC2, 0x00, 0x92, 0x80,
12009 0x1E, 0x98, 0x50, 0x00, 0xF5, 0x00, 0x48, 0x98, 0xDF, 0x23, 0x36, 0x60, 0xB6, 0x00, 0x92, 0x80,
12010 0x4F, 0x00, 0xF5, 0x00, 0x48, 0x98, 0xEF, 0x23, 0x36, 0x60, 0xB6, 0x00, 0x92, 0x80, 0x80, 0x62,
12011 0x92, 0x80, 0x00, 0x46, 0x15, 0xEE, 0x13, 0xEA, 0x02, 0x01, 0x09, 0xD8, 0xCD, 0x04, 0x4D, 0x00,
12012 0x00, 0xA3, 0xD6, 0x00, 0xA6, 0x97, 0x7F, 0x23, 0x04, 0x61, 0x84, 0x01, 0xE6, 0x84, 0xD2, 0xC1,
12013 0x80, 0x73, 0xCD, 0x04, 0x4D, 0x00, 0x00, 0xA3, 0xDA, 0x01, 0xA6, 0x97, 0xC6, 0x81, 0xC2, 0x88,
12014 0x80, 0x73, 0x80, 0x77, 0x00, 0x01, 0x01, 0xA1, 0xFE, 0x00, 0x4F, 0x00, 0x84, 0x97, 0x07, 0xA6,
12015 0x08, 0x01, 0x00, 0x33, 0x03, 0x00, 0xC2, 0x88, 0x03, 0x03, 0x01, 0xDE, 0xC2, 0x88, 0xCE, 0x00,
12016 0x69, 0x60, 0xCE, 0x00, 0x02, 0x03, 0x4A, 0x60, 0x00, 0xA2, 0x78, 0x01, 0x80, 0x63, 0x07, 0xA6,
12017 0x24, 0x01, 0x78, 0x81, 0x03, 0x03, 0x80, 0x63, 0xE2, 0x00, 0x07, 0xA6, 0x34, 0x01, 0x00, 0x33,
12018 0x04, 0x00, 0xC2, 0x88, 0x03, 0x07, 0x02, 0x01, 0x04, 0xCA, 0x0D, 0x23, 0x68, 0x98, 0x4D, 0x04,
12019 0x04, 0x85, 0x05, 0xD8, 0x0D, 0x23, 0x68, 0x98, 0xCD, 0x04, 0x15, 0x23, 0xF8, 0x88, 0xFB, 0x23,
12020 0x02, 0x61, 0x82, 0x01, 0x80, 0x63, 0x02, 0x03, 0x06, 0xA3, 0x62, 0x01, 0x00, 0x33, 0x0A, 0x00,
12021 0xC2, 0x88, 0x4E, 0x00, 0x07, 0xA3, 0x6E, 0x01, 0x00, 0x33, 0x0B, 0x00, 0xC2, 0x88, 0xCD, 0x04,
12022 0x36, 0x2D, 0x00, 0x33, 0x1A, 0x00, 0xC2, 0x88, 0x50, 0x04, 0x88, 0x81, 0x06, 0xAB, 0x82, 0x01,
12023 0x88, 0x81, 0x4E, 0x00, 0x07, 0xA3, 0x92, 0x01, 0x50, 0x00, 0x00, 0xA3, 0x3C, 0x01, 0x00, 0x05,
12024 0x7C, 0x81, 0x46, 0x97, 0x02, 0x01, 0x05, 0xC6, 0x04, 0x23, 0xA0, 0x01, 0x15, 0x23, 0xA1, 0x01,
12025 0xBE, 0x81, 0xFD, 0x23, 0x02, 0x61, 0x82, 0x01, 0x0A, 0xDA, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA0,
12026 0xB4, 0x01, 0x80, 0x63, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33, 0x1B, 0x00, 0xC2, 0x88, 0x06, 0x23,
12027 0x68, 0x98, 0xCD, 0x04, 0xE6, 0x84, 0x06, 0x01, 0x00, 0xA2, 0xD4, 0x01, 0x57, 0x60, 0x00, 0xA0,
12028 0xDA, 0x01, 0xE6, 0x84, 0x80, 0x23, 0xA0, 0x01, 0xE6, 0x84, 0x80, 0x73, 0x4B, 0x00, 0x06, 0x61,
12029 0x00, 0xA2, 0x00, 0x02, 0x04, 0x01, 0x0C, 0xDE, 0x02, 0x01, 0x03, 0xCC, 0x4F, 0x00, 0x84, 0x97,
12030 0xFC, 0x81, 0x08, 0x23, 0x02, 0x41, 0x82, 0x01, 0x4F, 0x00, 0x62, 0x97, 0x48, 0x04, 0x84, 0x80,
12031 0xF0, 0x97, 0x00, 0x46, 0x56, 0x00, 0x03, 0xC0, 0x01, 0x23, 0xE8, 0x00, 0x81, 0x73, 0x06, 0x29,
12032 0x03, 0x42, 0x06, 0xE2, 0x03, 0xEE, 0x6B, 0xEB, 0x11, 0x23, 0xF8, 0x88, 0x04, 0x98, 0xF0, 0x80,
12033 0x80, 0x73, 0x80, 0x77, 0x07, 0xA4, 0x2A, 0x02, 0x7C, 0x95, 0x06, 0xA6, 0x34, 0x02, 0x03, 0xA6,
12034 0x4C, 0x04, 0x46, 0x82, 0x04, 0x01, 0x03, 0xD8, 0xB4, 0x98, 0x6A, 0x96, 0x46, 0x82, 0xFE, 0x95,
12035 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0xB6, 0x2D, 0x02, 0xA6, 0x6C, 0x02, 0x07, 0xA6, 0x5A, 0x02,
12036 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x62, 0x02, 0xC2, 0x88, 0x7C, 0x95, 0x48, 0x82, 0x60, 0x96,
12037 0x48, 0x82, 0x04, 0x23, 0xA0, 0x01, 0x14, 0x23, 0xA1, 0x01, 0x3C, 0x84, 0x04, 0x01, 0x0C, 0xDC,
12038 0xE0, 0x23, 0x25, 0x61, 0xEF, 0x00, 0x14, 0x01, 0x4F, 0x04, 0xA8, 0x01, 0x6F, 0x00, 0xA5, 0x01,
12039 0x03, 0x23, 0xA4, 0x01, 0x06, 0x23, 0x9C, 0x01, 0x24, 0x2B, 0x1C, 0x01, 0x02, 0xA6, 0xAA, 0x02,
12040 0x07, 0xA6, 0x5A, 0x02, 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x20, 0x04, 0x01, 0xA6, 0xB4, 0x02,
12041 0x00, 0xA6, 0xB4, 0x02, 0x00, 0x33, 0x12, 0x00, 0xC2, 0x88, 0x00, 0x0E, 0x80, 0x63, 0x00, 0x43,
12042 0x00, 0xA0, 0x8C, 0x02, 0x4D, 0x04, 0x04, 0x01, 0x0B, 0xDC, 0xE7, 0x23, 0x04, 0x61, 0x84, 0x01,
12043 0x10, 0x31, 0x12, 0x35, 0x14, 0x01, 0xEC, 0x00, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00, 0xEA, 0x82,
12044 0x18, 0x23, 0x04, 0x61, 0x18, 0xA0, 0xE2, 0x02, 0x04, 0x01, 0xA2, 0xC8, 0x00, 0x33, 0x1F, 0x00,
12045 0xC2, 0x88, 0x08, 0x31, 0x0A, 0x35, 0x0C, 0x39, 0x0E, 0x3D, 0x7E, 0x98, 0xB6, 0x2D, 0x01, 0xA6,
12046 0x14, 0x03, 0x00, 0xA6, 0x14, 0x03, 0x07, 0xA6, 0x0C, 0x03, 0x06, 0xA6, 0x10, 0x03, 0x03, 0xA6,
12047 0x20, 0x04, 0x02, 0xA6, 0x6C, 0x02, 0x00, 0x33, 0x33, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0xEE, 0x82,
12048 0x60, 0x96, 0xEE, 0x82, 0x82, 0x98, 0x80, 0x42, 0x7E, 0x98, 0x64, 0xE4, 0x04, 0x01, 0x2D, 0xC8,
12049 0x31, 0x05, 0x07, 0x01, 0x00, 0xA2, 0x54, 0x03, 0x00, 0x43, 0x87, 0x01, 0x05, 0x05, 0x86, 0x98,
12050 0x7E, 0x98, 0x00, 0xA6, 0x16, 0x03, 0x07, 0xA6, 0x4C, 0x03, 0x03, 0xA6, 0x3C, 0x04, 0x06, 0xA6,
12051 0x50, 0x03, 0x01, 0xA6, 0x16, 0x03, 0x00, 0x33, 0x25, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x32, 0x83,
12052 0x60, 0x96, 0x32, 0x83, 0x04, 0x01, 0x10, 0xCE, 0x07, 0xC8, 0x05, 0x05, 0xEB, 0x04, 0x00, 0x33,
12053 0x00, 0x20, 0xC0, 0x20, 0x81, 0x62, 0x72, 0x83, 0x00, 0x01, 0x05, 0x05, 0xFF, 0xA2, 0x7A, 0x03,
12054 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x2E, 0x83, 0x05, 0x05, 0x15, 0x01, 0x00, 0xA2, 0x9A, 0x03,
12055 0xEC, 0x00, 0x6E, 0x00, 0x95, 0x01, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00, 0x01, 0xA6, 0x96, 0x03,
12056 0x00, 0xA6, 0x96, 0x03, 0x10, 0x84, 0x80, 0x42, 0x7E, 0x98, 0x01, 0xA6, 0xA4, 0x03, 0x00, 0xA6,
12057 0xBC, 0x03, 0x10, 0x84, 0xA8, 0x98, 0x80, 0x42, 0x01, 0xA6, 0xA4, 0x03, 0x07, 0xA6, 0xB2, 0x03,
12058 0xD4, 0x83, 0x7C, 0x95, 0xA8, 0x83, 0x00, 0x33, 0x2F, 0x00, 0xC2, 0x88, 0xA8, 0x98, 0x80, 0x42,
12059 0x00, 0xA6, 0xBC, 0x03, 0x07, 0xA6, 0xCA, 0x03, 0xD4, 0x83, 0x7C, 0x95, 0xC0, 0x83, 0x00, 0x33,
12060 0x26, 0x00, 0xC2, 0x88, 0x38, 0x2B, 0x80, 0x32, 0x80, 0x36, 0x04, 0x23, 0xA0, 0x01, 0x12, 0x23,
12061 0xA1, 0x01, 0x10, 0x84, 0x07, 0xF0, 0x06, 0xA4, 0xF4, 0x03, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23,
12062 0x83, 0x03, 0x80, 0x63, 0x03, 0xA6, 0x0E, 0x04, 0x07, 0xA6, 0x06, 0x04, 0x06, 0xA6, 0x0A, 0x04,
12063 0x00, 0x33, 0x17, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0xF4, 0x83, 0x60, 0x96, 0xF4, 0x83, 0x20, 0x84,
12064 0x07, 0xF0, 0x06, 0xA4, 0x20, 0x04, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23, 0x83, 0x03, 0x80, 0x63,
12065 0xB6, 0x2D, 0x03, 0xA6, 0x3C, 0x04, 0x07, 0xA6, 0x34, 0x04, 0x06, 0xA6, 0x38, 0x04, 0x00, 0x33,
12066 0x30, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x20, 0x84, 0x60, 0x96, 0x20, 0x84, 0x1D, 0x01, 0x06, 0xCC,
12067 0x00, 0x33, 0x00, 0x84, 0xC0, 0x20, 0x00, 0x23, 0xEA, 0x00, 0x81, 0x62, 0xA2, 0x0D, 0x80, 0x63,
12068 0x07, 0xA6, 0x5A, 0x04, 0x00, 0x33, 0x18, 0x00, 0xC2, 0x88, 0x03, 0x03, 0x80, 0x63, 0xA3, 0x01,
12069 0x07, 0xA4, 0x64, 0x04, 0x23, 0x01, 0x00, 0xA2, 0x86, 0x04, 0x0A, 0xA0, 0x76, 0x04, 0xE0, 0x00,
12070 0x00, 0x33, 0x1D, 0x00, 0xC2, 0x88, 0x0B, 0xA0, 0x82, 0x04, 0xE0, 0x00, 0x00, 0x33, 0x1E, 0x00,
12071 0xC2, 0x88, 0x42, 0x23, 0xF8, 0x88, 0x00, 0x23, 0x22, 0xA3, 0xE6, 0x04, 0x08, 0x23, 0x22, 0xA3,
12072 0xA2, 0x04, 0x28, 0x23, 0x22, 0xA3, 0xAE, 0x04, 0x02, 0x23, 0x22, 0xA3, 0xC4, 0x04, 0x42, 0x23,
12073 0xF8, 0x88, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA0, 0xAE, 0x04, 0x45, 0x23, 0xF8, 0x88, 0x04, 0x98,
12074 0x00, 0xA2, 0xC0, 0x04, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x82, 0xC0, 0x20, 0x81, 0x62, 0xE8, 0x81,
12075 0x47, 0x23, 0xF8, 0x88, 0x04, 0x01, 0x0B, 0xDE, 0x04, 0x98, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x81,
12076 0xC0, 0x20, 0x81, 0x62, 0x14, 0x01, 0x00, 0xA0, 0x00, 0x02, 0x43, 0x23, 0xF8, 0x88, 0x04, 0x23,
12077 0xA0, 0x01, 0x44, 0x23, 0xA1, 0x01, 0x80, 0x73, 0x4D, 0x00, 0x03, 0xA3, 0xF4, 0x04, 0x00, 0x33,
12078 0x27, 0x00, 0xC2, 0x88, 0x04, 0x01, 0x04, 0xDC, 0x02, 0x23, 0xA2, 0x01, 0x04, 0x23, 0xA0, 0x01,
12079 0x04, 0x98, 0x26, 0x95, 0x4B, 0x00, 0xF6, 0x00, 0x4F, 0x04, 0x4F, 0x00, 0x00, 0xA3, 0x22, 0x05,
12080 0x00, 0x05, 0x76, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x1C, 0x05, 0x0A, 0x85, 0x46, 0x97, 0xCD, 0x04,
12081 0x24, 0x85, 0x48, 0x04, 0x84, 0x80, 0x02, 0x01, 0x03, 0xDA, 0x80, 0x23, 0x82, 0x01, 0x34, 0x85,
12082 0x02, 0x23, 0xA0, 0x01, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x40, 0x05, 0x1D, 0x01, 0x04, 0xD6,
12083 0xFF, 0x23, 0x86, 0x41, 0x4B, 0x60, 0xCB, 0x00, 0xFF, 0x23, 0x80, 0x01, 0x49, 0x00, 0x81, 0x01,
12084 0x04, 0x01, 0x02, 0xC8, 0x30, 0x01, 0x80, 0x01, 0xF7, 0x04, 0x03, 0x01, 0x49, 0x04, 0x80, 0x01,
12085 0xC9, 0x00, 0x00, 0x05, 0x00, 0x01, 0xFF, 0xA0, 0x60, 0x05, 0x77, 0x04, 0x01, 0x23, 0xEA, 0x00,
12086 0x5D, 0x00, 0xFE, 0xC7, 0x00, 0x62, 0x00, 0x23, 0xEA, 0x00, 0x00, 0x63, 0x07, 0xA4, 0xF8, 0x05,
12087 0x03, 0x03, 0x02, 0xA0, 0x8E, 0x05, 0xF4, 0x85, 0x00, 0x33, 0x2D, 0x00, 0xC2, 0x88, 0x04, 0xA0,
12088 0xB8, 0x05, 0x80, 0x63, 0x00, 0x23, 0xDF, 0x00, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0xA4, 0x05,
12089 0x1D, 0x01, 0x06, 0xD6, 0x02, 0x23, 0x02, 0x41, 0x82, 0x01, 0x50, 0x00, 0x62, 0x97, 0x04, 0x85,
12090 0x04, 0x23, 0x02, 0x41, 0x82, 0x01, 0x04, 0x85, 0x08, 0xA0, 0xBE, 0x05, 0xF4, 0x85, 0x03, 0xA0,
12091 0xC4, 0x05, 0xF4, 0x85, 0x01, 0xA0, 0xCE, 0x05, 0x88, 0x00, 0x80, 0x63, 0xCC, 0x86, 0x07, 0xA0,
12092 0xEE, 0x05, 0x5F, 0x00, 0x00, 0x2B, 0xDF, 0x08, 0x00, 0xA2, 0xE6, 0x05, 0x80, 0x67, 0x80, 0x63,
12093 0x01, 0xA2, 0x7A, 0x06, 0x7C, 0x85, 0x06, 0x23, 0x68, 0x98, 0x48, 0x23, 0xF8, 0x88, 0x07, 0x23,
12094 0x80, 0x00, 0x06, 0x87, 0x80, 0x63, 0x7C, 0x85, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63, 0x4A, 0x00,
12095 0x06, 0x61, 0x00, 0xA2, 0x36, 0x06, 0x1D, 0x01, 0x16, 0xD4, 0xC0, 0x23, 0x07, 0x41, 0x83, 0x03,
12096 0x80, 0x63, 0x06, 0xA6, 0x1C, 0x06, 0x00, 0x33, 0x37, 0x00, 0xC2, 0x88, 0x1D, 0x01, 0x01, 0xD6,
12097 0x20, 0x23, 0x63, 0x60, 0x83, 0x03, 0x80, 0x63, 0x02, 0x23, 0xDF, 0x00, 0x07, 0xA6, 0x7C, 0x05,
12098 0xEF, 0x04, 0x6F, 0x00, 0x00, 0x63, 0x4B, 0x00, 0x06, 0x41, 0xCB, 0x00, 0x52, 0x00, 0x06, 0x61,
12099 0x00, 0xA2, 0x4E, 0x06, 0x1D, 0x01, 0x03, 0xCA, 0xC0, 0x23, 0x07, 0x41, 0x00, 0x63, 0x1D, 0x01,
12100 0x04, 0xCC, 0x00, 0x33, 0x00, 0x83, 0xC0, 0x20, 0x81, 0x62, 0x80, 0x23, 0x07, 0x41, 0x00, 0x63,
12101 0x80, 0x67, 0x08, 0x23, 0x83, 0x03, 0x80, 0x63, 0x00, 0x63, 0x01, 0x23, 0xDF, 0x00, 0x06, 0xA6,
12102 0x84, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67, 0x80, 0x63, 0x00, 0x33, 0x00, 0x40, 0xC0, 0x20,
12103 0x81, 0x62, 0x00, 0x63, 0x00, 0x00, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6, 0x94, 0x06,
12104 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x00, 0x01, 0xA0, 0x14, 0x07, 0x00, 0x2B, 0x40, 0x0E, 0x80, 0x63,
12105 0x01, 0x00, 0x06, 0xA6, 0xAA, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x40, 0x0E, 0x80, 0x63, 0x00, 0x43,
12106 0x00, 0xA0, 0xA2, 0x06, 0x06, 0xA6, 0xBC, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67, 0x40, 0x0E,
12107 0x80, 0x63, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63, 0x07, 0xA6, 0xD6, 0x06,
12108 0x00, 0x33, 0x2A, 0x00, 0xC2, 0x88, 0x03, 0x03, 0x80, 0x63, 0x89, 0x00, 0x0A, 0x2B, 0x07, 0xA6,
12109 0xE8, 0x06, 0x00, 0x33, 0x29, 0x00, 0xC2, 0x88, 0x00, 0x43, 0x00, 0xA2, 0xF4, 0x06, 0xC0, 0x0E,
12110 0x80, 0x63, 0xDE, 0x86, 0xC0, 0x0E, 0x00, 0x33, 0x00, 0x80, 0xC0, 0x20, 0x81, 0x62, 0x04, 0x01,
12111 0x02, 0xDA, 0x80, 0x63, 0x7C, 0x85, 0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6, 0x8C, 0x06, 0x00, 0x33,
12112 0x2C, 0x00, 0xC2, 0x88, 0x0C, 0xA2, 0x2E, 0x07, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6,
12113 0x2C, 0x07, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x33, 0x3D, 0x00, 0xC2, 0x88, 0x00, 0x00, 0x80, 0x67,
12114 0x83, 0x03, 0x80, 0x63, 0x0C, 0xA0, 0x44, 0x07, 0x07, 0xA6, 0x7C, 0x05, 0xBF, 0x23, 0x04, 0x61,
12115 0x84, 0x01, 0xE6, 0x84, 0x00, 0x63, 0xF0, 0x04, 0x01, 0x01, 0xF1, 0x00, 0x00, 0x01, 0xF2, 0x00,
12116 0x01, 0x05, 0x80, 0x01, 0x72, 0x04, 0x71, 0x00, 0x81, 0x01, 0x70, 0x04, 0x80, 0x05, 0x81, 0x05,
12117 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x01, 0x01, 0xF1, 0x00, 0x70, 0x00, 0x81, 0x01,
12118 0x70, 0x04, 0x71, 0x00, 0x81, 0x01, 0x72, 0x00, 0x80, 0x01, 0x71, 0x04, 0x70, 0x00, 0x80, 0x01,
12119 0x70, 0x04, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x00, 0x01, 0xF1, 0x00, 0x70, 0x00,
12120 0x80, 0x01, 0x70, 0x04, 0x71, 0x00, 0x80, 0x01, 0x72, 0x00, 0x81, 0x01, 0x71, 0x04, 0x70, 0x00,
12121 0x81, 0x01, 0x70, 0x04, 0x00, 0x63, 0x00, 0x23, 0xB3, 0x01, 0x83, 0x05, 0xA3, 0x01, 0xA2, 0x01,
12122 0xA1, 0x01, 0x01, 0x23, 0xA0, 0x01, 0x00, 0x01, 0xC8, 0x00, 0x03, 0xA1, 0xC4, 0x07, 0x00, 0x33,
12123 0x07, 0x00, 0xC2, 0x88, 0x80, 0x05, 0x81, 0x05, 0x04, 0x01, 0x11, 0xC8, 0x48, 0x00, 0xB0, 0x01,
12124 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x05, 0x01, 0x48, 0x04, 0x00, 0x43, 0x00, 0xA2, 0xE4, 0x07,
12125 0x00, 0x05, 0xDA, 0x87, 0x00, 0x01, 0xC8, 0x00, 0xFF, 0x23, 0x80, 0x01, 0x05, 0x05, 0x00, 0x63,
12126 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, 0x00, 0x02, 0x80, 0x43, 0x76, 0x08, 0x80, 0x02,
12127 0x77, 0x04, 0x00, 0x63, 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, 0x00, 0x02, 0x00, 0xA0,
12128 0x14, 0x08, 0x16, 0x88, 0x00, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04, 0x00, 0x63, 0xF3, 0x04,
12129 0x00, 0x23, 0xF4, 0x00, 0x74, 0x00, 0x80, 0x43, 0xF4, 0x00, 0xCF, 0x40, 0x00, 0xA2, 0x44, 0x08,
12130 0x74, 0x04, 0x02, 0x01, 0xF7, 0xC9, 0xF6, 0xD9, 0x00, 0x01, 0x01, 0xA1, 0x24, 0x08, 0x04, 0x98,
12131 0x26, 0x95, 0x24, 0x88, 0x73, 0x04, 0x00, 0x63, 0xF3, 0x04, 0x75, 0x04, 0x5A, 0x88, 0x02, 0x01,
12132 0x04, 0xD8, 0x46, 0x97, 0x04, 0x98, 0x26, 0x95, 0x4A, 0x88, 0x75, 0x00, 0x00, 0xA3, 0x64, 0x08,
12133 0x00, 0x05, 0x4E, 0x88, 0x73, 0x04, 0x00, 0x63, 0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6, 0x76, 0x08,
12134 0x00, 0x33, 0x3E, 0x00, 0xC2, 0x88, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0x00, 0x63, 0x38, 0x2B,
12135 0x9C, 0x88, 0x38, 0x2B, 0x92, 0x88, 0x32, 0x09, 0x31, 0x05, 0x92, 0x98, 0x05, 0x05, 0xB2, 0x09,
12136 0x00, 0x63, 0x00, 0x32, 0x00, 0x36, 0x00, 0x3A, 0x00, 0x3E, 0x00, 0x63, 0x80, 0x32, 0x80, 0x36,
12137 0x80, 0x3A, 0x80, 0x3E, 0xB4, 0x3D, 0x00, 0x63, 0x38, 0x2B, 0x40, 0x32, 0x40, 0x36, 0x40, 0x3A,
12138 0x40, 0x3E, 0x00, 0x63, 0x5A, 0x20, 0xC9, 0x40, 0x00, 0xA0, 0xB4, 0x08, 0x5D, 0x00, 0xFE, 0xC3,
12139 0x00, 0x63, 0x80, 0x73, 0xE6, 0x20, 0x02, 0x23, 0xE8, 0x00, 0x82, 0x73, 0xFF, 0xFD, 0x80, 0x73,
12140 0x13, 0x23, 0xF8, 0x88, 0x66, 0x20, 0xC0, 0x20, 0x04, 0x23, 0xA0, 0x01, 0xA1, 0x23, 0xA1, 0x01,
12141 0x81, 0x62, 0xE2, 0x88, 0x80, 0x73, 0x80, 0x77, 0x68, 0x00, 0x00, 0xA2, 0x80, 0x00, 0x03, 0xC2,
12142 0xF1, 0xC7, 0x41, 0x23, 0xF8, 0x88, 0x11, 0x23, 0xA1, 0x01, 0x04, 0x23, 0xA0, 0x01, 0xE6, 0x84,
12145 STATIC ushort _asc_mcode_size ASC_INITDATA = sizeof(_asc_mcode_buf);
12146 STATIC ADV_DCNT _asc_mcode_chksum ASC_INITDATA = 0x012C453FUL;
12148 #define ASC_SYN_OFFSET_ONE_DISABLE_LIST 16
12149 STATIC uchar _syn_offset_one_disable_cmd[ASC_SYN_OFFSET_ONE_DISABLE_LIST] =
12151 SCSICMD_Inquiry,
12152 SCSICMD_RequestSense,
12153 SCSICMD_ReadCapacity,
12154 SCSICMD_ReadTOC,
12155 SCSICMD_ModeSelect6,
12156 SCSICMD_ModeSense6,
12157 SCSICMD_ModeSelect10,
12158 SCSICMD_ModeSense10,
12159 0xFF,
12160 0xFF,
12161 0xFF,
12162 0xFF,
12163 0xFF,
12164 0xFF,
12165 0xFF,
12166 0xFF
12169 STATIC int
12170 AscExeScsiQueue(
12171 ASC_DVC_VAR *asc_dvc,
12172 ASC_SCSI_Q *scsiq
12175 PortAddr iop_base;
12176 int last_int_level;
12177 int sta;
12178 int n_q_required;
12179 int disable_syn_offset_one_fix;
12180 int i;
12181 ASC_PADDR addr;
12182 ASC_EXE_CALLBACK asc_exe_callback;
12183 ushort sg_entry_cnt = 0;
12184 ushort sg_entry_cnt_minus_one = 0;
12185 uchar target_ix;
12186 uchar tid_no;
12187 uchar sdtr_data;
12188 uchar extra_bytes;
12189 uchar scsi_cmd;
12190 uchar disable_cmd;
12191 ASC_SG_HEAD *sg_head;
12192 ASC_DCNT data_cnt;
12194 iop_base = asc_dvc->iop_base;
12195 sg_head = scsiq->sg_head;
12196 asc_exe_callback = asc_dvc->exe_callback;
12197 if (asc_dvc->err_code != 0)
12198 return (ERR);
12199 if (scsiq == (ASC_SCSI_Q *) 0L) {
12200 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SCSIQ_NULL_PTR);
12201 return (ERR);
12203 scsiq->q1.q_no = 0;
12204 if ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES) == 0) {
12205 scsiq->q1.extra_bytes = 0;
12207 sta = 0;
12208 target_ix = scsiq->q2.target_ix;
12209 tid_no = ASC_TIX_TO_TID(target_ix);
12210 n_q_required = 1;
12211 if (scsiq->cdbptr[0] == SCSICMD_RequestSense) {
12212 if ((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) {
12213 asc_dvc->sdtr_done &= ~scsiq->q1.target_id;
12214 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
12215 AscMsgOutSDTR(asc_dvc,
12216 asc_dvc->sdtr_period_tbl[(sdtr_data >> 4) &
12217 (uchar) (asc_dvc->max_sdtr_index - 1)],
12218 (uchar) (sdtr_data & (uchar) ASC_SYN_MAX_OFFSET));
12219 scsiq->q1.cntl |= (QC_MSG_OUT | QC_URGENT);
12222 last_int_level = DvcEnterCritical();
12223 if (asc_dvc->in_critical_cnt != 0) {
12224 DvcLeaveCritical(last_int_level);
12225 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CRITICAL_RE_ENTRY);
12226 return (ERR);
12228 asc_dvc->in_critical_cnt++;
12229 if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
12230 if ((sg_entry_cnt = sg_head->entry_cnt) == 0) {
12231 asc_dvc->in_critical_cnt--;
12232 DvcLeaveCritical(last_int_level);
12233 return (ERR);
12235 #if !CC_VERY_LONG_SG_LIST
12236 if (sg_entry_cnt > ASC_MAX_SG_LIST)
12238 return(ERR);
12240 #endif /* !CC_VERY_LONG_SG_LIST */
12241 if (sg_entry_cnt == 1) {
12242 scsiq->q1.data_addr = (ADV_PADDR) sg_head->sg_list[0].addr;
12243 scsiq->q1.data_cnt = (ADV_DCNT) sg_head->sg_list[0].bytes;
12244 scsiq->q1.cntl &= ~(QC_SG_HEAD | QC_SG_SWAP_QUEUE);
12246 sg_entry_cnt_minus_one = sg_entry_cnt - 1;
12248 scsi_cmd = scsiq->cdbptr[0];
12249 disable_syn_offset_one_fix = FALSE;
12250 if ((asc_dvc->pci_fix_asyn_xfer & scsiq->q1.target_id) &&
12251 !(asc_dvc->pci_fix_asyn_xfer_always & scsiq->q1.target_id)) {
12252 if (scsiq->q1.cntl & QC_SG_HEAD) {
12253 data_cnt = 0;
12254 for (i = 0; i < sg_entry_cnt; i++) {
12255 data_cnt += (ADV_DCNT) sg_head->sg_list[i].bytes;
12257 } else {
12258 data_cnt = scsiq->q1.data_cnt;
12260 if (data_cnt != 0UL) {
12261 if (data_cnt < 512UL) {
12262 disable_syn_offset_one_fix = TRUE;
12263 } else {
12264 for (i = 0; i < ASC_SYN_OFFSET_ONE_DISABLE_LIST; i++) {
12265 disable_cmd = _syn_offset_one_disable_cmd[i];
12266 if (disable_cmd == 0xFF) {
12267 break;
12269 if (scsi_cmd == disable_cmd) {
12270 disable_syn_offset_one_fix = TRUE;
12271 break;
12277 if (disable_syn_offset_one_fix) {
12278 scsiq->q2.tag_code &= ~M2_QTAG_MSG_SIMPLE;
12279 scsiq->q2.tag_code |= (ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX |
12280 ASC_TAG_FLAG_DISABLE_DISCONNECT);
12281 } else {
12282 scsiq->q2.tag_code &= 0x23;
12284 if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
12285 if (asc_dvc->bug_fix_cntl) {
12286 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
12287 if ((scsi_cmd == SCSICMD_Read6) ||
12288 (scsi_cmd == SCSICMD_Read10)) {
12289 addr =
12290 (ADV_PADDR)
12291 sg_head->sg_list[sg_entry_cnt_minus_one].addr +
12292 (ADV_DCNT)
12293 sg_head->sg_list[sg_entry_cnt_minus_one].bytes;
12294 extra_bytes = (uchar) ((ushort) addr & 0x0003);
12295 if ((extra_bytes != 0) &&
12296 ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES)
12297 == 0)) {
12298 scsiq->q2.tag_code |= ASC_TAG_FLAG_EXTRA_BYTES;
12299 scsiq->q1.extra_bytes = extra_bytes;
12300 sg_head->sg_list[sg_entry_cnt_minus_one].bytes -=
12301 (ASC_DCNT) extra_bytes;
12306 sg_head->entry_to_copy = sg_head->entry_cnt;
12308 * Set the sg_entry_cnt to the maximum possible. The rest of
12309 * the SG elements will be copied when the RISC completes the
12310 * SG elements that fit and halts.
12312 if (sg_entry_cnt > ASC_MAX_SG_LIST)
12314 sg_entry_cnt = ASC_MAX_SG_LIST;
12316 n_q_required = AscSgListToQueue(sg_entry_cnt);
12317 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, n_q_required) >=
12318 (uint) n_q_required) || ((scsiq->q1.cntl & QC_URGENT) != 0)) {
12319 if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
12320 n_q_required)) == 1) {
12321 asc_dvc->in_critical_cnt--;
12322 if (asc_exe_callback != 0) {
12323 (*asc_exe_callback) (asc_dvc, scsiq);
12325 DvcLeaveCritical(last_int_level);
12326 return (sta);
12329 } else {
12330 if (asc_dvc->bug_fix_cntl) {
12331 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
12332 if ((scsi_cmd == SCSICMD_Read6) ||
12333 (scsi_cmd == SCSICMD_Read10)) {
12334 addr = scsiq->q1.data_addr + scsiq->q1.data_cnt;
12335 extra_bytes = (uchar) ((ushort) addr & 0x0003);
12336 if ((extra_bytes != 0) &&
12337 ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES)
12338 == 0)) {
12339 if (((ushort) scsiq->q1.data_cnt & 0x01FF) == 0) {
12340 scsiq->q2.tag_code |= ASC_TAG_FLAG_EXTRA_BYTES;
12341 scsiq->q1.data_cnt -= (ASC_DCNT) extra_bytes;
12342 scsiq->q1.extra_bytes = extra_bytes;
12348 n_q_required = 1;
12349 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, 1) >= 1) ||
12350 ((scsiq->q1.cntl & QC_URGENT) != 0)) {
12351 if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
12352 n_q_required)) == 1) {
12353 asc_dvc->in_critical_cnt--;
12354 if (asc_exe_callback != 0) {
12355 (*asc_exe_callback) (asc_dvc, scsiq);
12357 DvcLeaveCritical(last_int_level);
12358 return (sta);
12362 asc_dvc->in_critical_cnt--;
12363 DvcLeaveCritical(last_int_level);
12364 return (sta);
12367 STATIC int
12368 AscSendScsiQueue(
12369 ASC_DVC_VAR *asc_dvc,
12370 ASC_SCSI_Q *scsiq,
12371 uchar n_q_required
12374 PortAddr iop_base;
12375 uchar free_q_head;
12376 uchar next_qp;
12377 uchar tid_no;
12378 uchar target_ix;
12379 int sta;
12381 iop_base = asc_dvc->iop_base;
12382 target_ix = scsiq->q2.target_ix;
12383 tid_no = ASC_TIX_TO_TID(target_ix);
12384 sta = 0;
12385 free_q_head = (uchar) AscGetVarFreeQHead(iop_base);
12386 if (n_q_required > 1) {
12387 if ((next_qp = AscAllocMultipleFreeQueue(iop_base,
12388 free_q_head, (uchar) (n_q_required)))
12389 != (uchar) ASC_QLINK_END) {
12390 asc_dvc->last_q_shortage = 0;
12391 scsiq->sg_head->queue_cnt = n_q_required - 1;
12392 scsiq->q1.q_no = free_q_head;
12393 if ((sta = AscPutReadySgListQueue(asc_dvc, scsiq,
12394 free_q_head)) == 1) {
12395 AscPutVarFreeQHead(iop_base, next_qp);
12396 asc_dvc->cur_total_qng += (uchar) (n_q_required);
12397 asc_dvc->cur_dvc_qng[tid_no]++;
12399 return (sta);
12401 } else if (n_q_required == 1) {
12402 if ((next_qp = AscAllocFreeQueue(iop_base,
12403 free_q_head)) != ASC_QLINK_END) {
12404 scsiq->q1.q_no = free_q_head;
12405 if ((sta = AscPutReadyQueue(asc_dvc, scsiq,
12406 free_q_head)) == 1) {
12407 AscPutVarFreeQHead(iop_base, next_qp);
12408 asc_dvc->cur_total_qng++;
12409 asc_dvc->cur_dvc_qng[tid_no]++;
12411 return (sta);
12414 return (sta);
12417 STATIC int
12418 AscSgListToQueue(
12419 int sg_list
12422 int n_sg_list_qs;
12424 n_sg_list_qs = ((sg_list - 1) / ASC_SG_LIST_PER_Q);
12425 if (((sg_list - 1) % ASC_SG_LIST_PER_Q) != 0)
12426 n_sg_list_qs++;
12427 return (n_sg_list_qs + 1);
12431 STATIC uint
12432 AscGetNumOfFreeQueue(
12433 ASC_DVC_VAR *asc_dvc,
12434 uchar target_ix,
12435 uchar n_qs
12438 uint cur_used_qs;
12439 uint cur_free_qs;
12440 ASC_SCSI_BIT_ID_TYPE target_id;
12441 uchar tid_no;
12443 target_id = ASC_TIX_TO_TARGET_ID(target_ix);
12444 tid_no = ASC_TIX_TO_TID(target_ix);
12445 if ((asc_dvc->unit_not_ready & target_id) ||
12446 (asc_dvc->queue_full_or_busy & target_id)) {
12447 return (0);
12449 if (n_qs == 1) {
12450 cur_used_qs = (uint) asc_dvc->cur_total_qng +
12451 (uint) asc_dvc->last_q_shortage +
12452 (uint) ASC_MIN_FREE_Q;
12453 } else {
12454 cur_used_qs = (uint) asc_dvc->cur_total_qng +
12455 (uint) ASC_MIN_FREE_Q;
12457 if ((uint) (cur_used_qs + n_qs) <= (uint) asc_dvc->max_total_qng) {
12458 cur_free_qs = (uint) asc_dvc->max_total_qng - cur_used_qs;
12459 if (asc_dvc->cur_dvc_qng[tid_no] >=
12460 asc_dvc->max_dvc_qng[tid_no]) {
12461 return (0);
12463 return (cur_free_qs);
12465 if (n_qs > 1) {
12466 if ((n_qs > asc_dvc->last_q_shortage) && (n_qs <= (asc_dvc->max_total_qng - ASC_MIN_FREE_Q))) {
12467 asc_dvc->last_q_shortage = n_qs;
12470 return (0);
12473 STATIC int
12474 AscPutReadyQueue(
12475 ASC_DVC_VAR *asc_dvc,
12476 ASC_SCSI_Q *scsiq,
12477 uchar q_no
12480 ushort q_addr;
12481 uchar tid_no;
12482 uchar sdtr_data;
12483 uchar syn_period_ix;
12484 uchar syn_offset;
12485 PortAddr iop_base;
12487 iop_base = asc_dvc->iop_base;
12488 if (((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) &&
12489 ((asc_dvc->sdtr_done & scsiq->q1.target_id) == 0)) {
12490 tid_no = ASC_TIX_TO_TID(scsiq->q2.target_ix);
12491 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
12492 syn_period_ix = (sdtr_data >> 4) & (asc_dvc->max_sdtr_index - 1);
12493 syn_offset = sdtr_data & ASC_SYN_MAX_OFFSET;
12494 AscMsgOutSDTR(asc_dvc,
12495 asc_dvc->sdtr_period_tbl[syn_period_ix],
12496 syn_offset);
12497 scsiq->q1.cntl |= QC_MSG_OUT;
12499 q_addr = ASC_QNO_TO_QADDR(q_no);
12500 if ((scsiq->q1.target_id & asc_dvc->use_tagged_qng) == 0) {
12501 scsiq->q2.tag_code &= ~M2_QTAG_MSG_SIMPLE;
12503 scsiq->q1.status = QS_FREE;
12504 AscMemWordCopyToLram(iop_base,
12505 (ushort) (q_addr + (ushort) ASC_SCSIQ_CDB_BEG),
12506 (ushort *) scsiq->cdbptr,
12507 (ushort) ((ushort) scsiq->q2.cdb_len >> 1));
12508 DvcPutScsiQ(iop_base,
12509 (ushort) (q_addr + (ushort) ASC_SCSIQ_CPY_BEG),
12510 (ushort *) & scsiq->q1.cntl,
12511 (ushort) ((((sizeof (ASC_SCSIQ_1) + sizeof (ASC_SCSIQ_2)) / 2) - 1)));
12512 AscWriteLramWord(iop_base,
12513 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS),
12514 (ushort) (((ushort) scsiq->q1.q_no << 8) | (ushort) QS_READY));
12515 return (1);
12518 STATIC int
12519 AscPutReadySgListQueue(
12520 ASC_DVC_VAR *asc_dvc,
12521 ASC_SCSI_Q *scsiq,
12522 uchar q_no
12525 int sta;
12526 int i;
12527 ASC_SG_HEAD *sg_head;
12528 ASC_SG_LIST_Q scsi_sg_q;
12529 ASC_DCNT saved_data_addr;
12530 ASC_DCNT saved_data_cnt;
12531 PortAddr iop_base;
12532 ushort sg_list_dwords;
12533 ushort sg_index;
12534 ushort sg_entry_cnt;
12535 ushort q_addr;
12536 uchar next_qp;
12538 iop_base = asc_dvc->iop_base;
12539 sg_head = scsiq->sg_head;
12540 saved_data_addr = scsiq->q1.data_addr;
12541 saved_data_cnt = scsiq->q1.data_cnt;
12542 scsiq->q1.data_addr = (ASC_PADDR) sg_head->sg_list[0].addr;
12543 scsiq->q1.data_cnt = (ASC_DCNT) sg_head->sg_list[0].bytes;
12545 * If sg_head->entry_cnt is greater than ASC_MAX_SG_LIST
12546 * then not all SG elements will fit in the allocated queues.
12547 * The rest of the SG elements will be copied when the RISC
12548 * completes the SG elements that fit and halts.
12550 if (sg_head->entry_cnt > ASC_MAX_SG_LIST)
12553 * Set sg_entry_cnt to be the number of SG elements that
12554 * will fit in the allocated SG queues. It is minus 1 because
12555 * first SG element handled above. ASC_MAX_SG_LIST is already
12556 * inflated by 1 to account for this. For example it may
12557 * be 50 which is 1 + 7 queues * 7 SG elements.
12559 sg_entry_cnt = ASC_MAX_SG_LIST - 1;
12562 * Keep track of remaining number of SG elements that will
12563 * need to be handled from a_isr.c.
12565 scsiq->remain_sg_entry_cnt = sg_head->entry_cnt - ASC_MAX_SG_LIST;
12566 } else
12569 * Set sg_entry_cnt to be the number of SG elements that
12570 * will fit in the allocated SG queues. Refer to comment
12571 * above regarding why it is - 1.
12573 sg_entry_cnt = sg_head->entry_cnt - 1;
12575 if (sg_entry_cnt != 0) {
12576 scsiq->q1.cntl |= QC_SG_HEAD;
12577 q_addr = ASC_QNO_TO_QADDR(q_no);
12578 sg_index = 1;
12579 scsiq->q1.sg_queue_cnt = sg_head->queue_cnt;
12580 scsi_sg_q.sg_head_qp = q_no;
12581 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
12582 for (i = 0; i < sg_head->queue_cnt; i++) {
12583 scsi_sg_q.seq_no = i + 1;
12584 if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
12585 sg_list_dwords = (uchar) (ASC_SG_LIST_PER_Q * 2);
12586 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
12587 if (i == 0) {
12588 scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q;
12589 scsi_sg_q.sg_cur_list_cnt = ASC_SG_LIST_PER_Q;
12590 } else {
12591 scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q - 1;
12592 scsi_sg_q.sg_cur_list_cnt = ASC_SG_LIST_PER_Q - 1;
12594 } else {
12596 * This is the last SG queue in the list of
12597 * allocated SG queues. If there are more
12598 * SG elements than will fit in the allocated
12599 * queues, then set the QCSG_SG_XFER_MORE flag.
12601 if (sg_head->entry_cnt > ASC_MAX_SG_LIST)
12603 scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
12604 } else
12606 scsi_sg_q.cntl |= QCSG_SG_XFER_END;
12608 sg_list_dwords = sg_entry_cnt << 1;
12609 if (i == 0) {
12610 scsi_sg_q.sg_list_cnt = sg_entry_cnt;
12611 scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt;
12612 } else {
12613 scsi_sg_q.sg_list_cnt = sg_entry_cnt - 1;
12614 scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt - 1;
12616 sg_entry_cnt = 0;
12618 next_qp = AscReadLramByte(iop_base,
12619 (ushort) (q_addr + ASC_SCSIQ_B_FWD));
12620 scsi_sg_q.q_no = next_qp;
12621 q_addr = ASC_QNO_TO_QADDR(next_qp);
12622 AscMemWordCopyToLram(iop_base,
12623 (ushort) (q_addr + ASC_SCSIQ_SGHD_CPY_BEG),
12624 (ushort *) & scsi_sg_q,
12625 (ushort) (sizeof (ASC_SG_LIST_Q) >> 1));
12626 AscMemDWordCopyToLram(iop_base,
12627 (ushort) (q_addr + ASC_SGQ_LIST_BEG),
12628 (ADV_PADDR *) &sg_head->sg_list[sg_index],
12629 (ushort) sg_list_dwords);
12630 sg_index += ASC_SG_LIST_PER_Q;
12631 scsiq->next_sg_index = sg_index;
12633 } else {
12634 scsiq->q1.cntl &= ~QC_SG_HEAD;
12636 sta = AscPutReadyQueue(asc_dvc, scsiq, q_no);
12637 scsiq->q1.data_addr = saved_data_addr;
12638 scsiq->q1.data_cnt = saved_data_cnt;
12639 return (sta);
12642 STATIC int
12643 AscAbortSRB(
12644 ASC_DVC_VAR *asc_dvc,
12645 ADV_VADDR srb_ptr
12648 int sta;
12649 ASC_SCSI_BIT_ID_TYPE saved_unit_not_ready;
12650 PortAddr iop_base;
12652 iop_base = asc_dvc->iop_base;
12653 sta = ERR;
12654 saved_unit_not_ready = asc_dvc->unit_not_ready;
12655 asc_dvc->unit_not_ready = 0xFF;
12656 AscWaitISRDone(asc_dvc);
12657 if (AscStopQueueExe(iop_base) == 1) {
12658 if (AscRiscHaltedAbortSRB(asc_dvc, srb_ptr) == 1) {
12659 sta = 1;
12660 AscCleanUpBusyQueue(iop_base);
12661 AscStartQueueExe(iop_base);
12662 } else {
12663 sta = 0;
12664 AscStartQueueExe(iop_base);
12667 asc_dvc->unit_not_ready = saved_unit_not_ready;
12668 return (sta);
12671 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
12672 STATIC int
12673 AscResetDevice(
12674 ASC_DVC_VAR *asc_dvc,
12675 uchar target_ix
12678 PortAddr iop_base;
12679 int sta;
12680 uchar tid_no;
12682 ASC_SCSI_BIT_ID_TYPE target_id;
12683 int i;
12684 ASC_SCSI_REQ_Q scsiq_buf;
12685 ASC_SCSI_REQ_Q *scsiq;
12686 uchar *buf;
12687 ASC_SCSI_BIT_ID_TYPE saved_unit_not_ready;
12688 iop_base = asc_dvc->iop_base;
12689 tid_no = ASC_TIX_TO_TID(target_ix);
12690 target_id = ASC_TID_TO_TARGET_ID(tid_no);
12691 saved_unit_not_ready = asc_dvc->unit_not_ready;
12692 asc_dvc->unit_not_ready = target_id;
12693 sta = ERR;
12694 AscWaitTixISRDone(asc_dvc, target_ix);
12695 if (AscStopQueueExe(iop_base) == 1) {
12696 if (AscRiscHaltedAbortTIX(asc_dvc, target_ix) == 1) {
12697 AscCleanUpBusyQueue(iop_base);
12698 AscStartQueueExe(iop_base);
12699 AscWaitTixISRDone(asc_dvc, target_ix);
12700 sta = TRUE;
12701 scsiq = (ASC_SCSI_REQ_Q *) & scsiq_buf;
12702 buf = (uchar *) & scsiq_buf;
12703 for (i = 0; i < sizeof (ASC_SCSI_REQ_Q); i++) {
12704 *buf++ = 0x00;
12706 scsiq->r1.status = (uchar) QS_READY;
12707 scsiq->r2.cdb_len = 6;
12708 scsiq->r2.tag_code = M2_QTAG_MSG_SIMPLE;
12709 scsiq->r1.target_id = target_id;
12710 scsiq->r2.target_ix = ASC_TIDLUN_TO_IX(tid_no, 0);
12711 scsiq->cdbptr = (uchar *) scsiq->cdb;
12712 scsiq->r1.cntl = QC_NO_CALLBACK | QC_MSG_OUT | QC_URGENT;
12713 AscWriteLramByte(asc_dvc->iop_base, ASCV_MSGOUT_BEG,
12714 M1_BUS_DVC_RESET);
12715 asc_dvc->unit_not_ready &= ~target_id;
12716 asc_dvc->sdtr_done |= target_id;
12717 if (AscExeScsiQueue(asc_dvc, (ASC_SCSI_Q *) scsiq)
12718 == 1) {
12719 asc_dvc->unit_not_ready = target_id;
12720 DvcSleepMilliSecond(1000);
12721 _AscWaitQDone(iop_base, (ASC_SCSI_Q *) scsiq);
12722 if (AscStopQueueExe(iop_base) == 1) {
12723 AscCleanUpDiscQueue(iop_base);
12724 AscStartQueueExe(iop_base);
12725 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
12726 AscSetRunChipSynRegAtID(iop_base, tid_no,
12727 ASYN_SDTR_DATA_FIX_PCI_REV_AB);
12729 AscWaitTixISRDone(asc_dvc, target_ix);
12731 } else {
12732 sta = 0;
12734 asc_dvc->sdtr_done &= ~target_id;
12735 } else {
12736 sta = ERR;
12737 AscStartQueueExe(iop_base);
12740 asc_dvc->unit_not_ready = saved_unit_not_ready;
12741 return (sta);
12743 #endif /* version >= v1.3.89 */
12745 STATIC int
12746 AscResetSB(
12747 ASC_DVC_VAR *asc_dvc
12750 int sta;
12751 int i;
12752 PortAddr iop_base;
12754 iop_base = asc_dvc->iop_base;
12755 asc_dvc->unit_not_ready = 0xFF;
12756 sta = TRUE;
12757 AscWaitISRDone(asc_dvc);
12758 AscStopQueueExe(iop_base);
12759 asc_dvc->sdtr_done = 0;
12760 AscResetChipAndScsiBus(asc_dvc);
12761 DvcSleepMilliSecond((ASC_DCNT) ((ushort) asc_dvc->scsi_reset_wait * 1000));
12762 AscReInitLram(asc_dvc);
12763 for (i = 0; i <= ASC_MAX_TID; i++) {
12764 asc_dvc->cur_dvc_qng[i] = 0;
12765 if (asc_dvc->pci_fix_asyn_xfer & (ASC_SCSI_BIT_ID_TYPE) (0x01 << i)) {
12766 AscSetChipSynRegAtID(iop_base, i, ASYN_SDTR_DATA_FIX_PCI_REV_AB);
12769 asc_dvc->err_code = 0;
12770 AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
12771 if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
12772 sta = ERR;
12774 if (AscStartChip(iop_base) == 0) {
12775 sta = ERR;
12777 AscStartQueueExe(iop_base);
12778 asc_dvc->unit_not_ready = 0;
12779 asc_dvc->queue_full_or_busy = 0;
12780 return (sta);
12783 STATIC int
12784 AscSetRunChipSynRegAtID(
12785 PortAddr iop_base,
12786 uchar tid_no,
12787 uchar sdtr_data
12790 int sta = FALSE;
12792 if (AscHostReqRiscHalt(iop_base)) {
12793 sta = AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
12794 AscStartChip(iop_base);
12795 return (sta);
12797 return (sta);
12800 STATIC int
12801 AscSetChipSynRegAtID(
12802 PortAddr iop_base,
12803 uchar id,
12804 uchar sdtr_data
12807 ASC_SCSI_BIT_ID_TYPE org_id;
12808 int i;
12809 int sta = TRUE;
12811 AscSetBank(iop_base, 1);
12812 org_id = AscReadChipDvcID(iop_base);
12813 for (i = 0; i <= ASC_MAX_TID; i++) {
12814 if (org_id == (0x01 << i))
12815 break;
12817 org_id = (ASC_SCSI_BIT_ID_TYPE) i;
12818 AscWriteChipDvcID(iop_base, id);
12819 if (AscReadChipDvcID(iop_base) == (0x01 << id)) {
12820 AscSetBank(iop_base, 0);
12821 AscSetChipSyn(iop_base, sdtr_data);
12822 if (AscGetChipSyn(iop_base) != sdtr_data) {
12823 sta = FALSE;
12825 } else {
12826 sta = FALSE;
12828 AscSetBank(iop_base, 1);
12829 AscWriteChipDvcID(iop_base, org_id);
12830 AscSetBank(iop_base, 0);
12831 return (sta);
12834 STATIC int
12835 AscReInitLram(
12836 ASC_DVC_VAR *asc_dvc
12839 AscInitLram(asc_dvc);
12840 AscInitQLinkVar(asc_dvc);
12841 return (0);
12844 STATIC ushort
12845 AscInitLram(
12846 ASC_DVC_VAR *asc_dvc
12849 uchar i;
12850 ushort s_addr;
12851 PortAddr iop_base;
12852 ushort warn_code;
12854 iop_base = asc_dvc->iop_base;
12855 warn_code = 0;
12856 AscMemWordSetLram(iop_base, ASC_QADR_BEG, 0,
12857 (ushort) (((int) (asc_dvc->max_total_qng + 2 + 1) * 64) >> 1)
12859 i = ASC_MIN_ACTIVE_QNO;
12860 s_addr = ASC_QADR_BEG + ASC_QBLK_SIZE;
12861 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_FWD),
12862 (uchar) (i + 1));
12863 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_BWD),
12864 (uchar) (asc_dvc->max_total_qng));
12865 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_QNO),
12866 (uchar) i);
12867 i++;
12868 s_addr += ASC_QBLK_SIZE;
12869 for (; i < asc_dvc->max_total_qng; i++, s_addr += ASC_QBLK_SIZE) {
12870 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_FWD),
12871 (uchar) (i + 1));
12872 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_BWD),
12873 (uchar) (i - 1));
12874 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_QNO),
12875 (uchar) i);
12877 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_FWD),
12878 (uchar) ASC_QLINK_END);
12879 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_BWD),
12880 (uchar) (asc_dvc->max_total_qng - 1));
12881 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_QNO),
12882 (uchar) asc_dvc->max_total_qng);
12883 i++;
12884 s_addr += ASC_QBLK_SIZE;
12885 for (; i <= (uchar) (asc_dvc->max_total_qng + 3);
12886 i++, s_addr += ASC_QBLK_SIZE) {
12887 AscWriteLramByte(iop_base,
12888 (ushort) (s_addr + (ushort) ASC_SCSIQ_B_FWD), i);
12889 AscWriteLramByte(iop_base,
12890 (ushort) (s_addr + (ushort) ASC_SCSIQ_B_BWD), i);
12891 AscWriteLramByte(iop_base,
12892 (ushort) (s_addr + (ushort) ASC_SCSIQ_B_QNO), i);
12894 return (warn_code);
12897 STATIC ushort
12898 AscInitQLinkVar(
12899 ASC_DVC_VAR *asc_dvc
12902 PortAddr iop_base;
12903 int i;
12904 ushort lram_addr;
12906 iop_base = asc_dvc->iop_base;
12907 AscPutRiscVarFreeQHead(iop_base, 1);
12908 AscPutRiscVarDoneQTail(iop_base, asc_dvc->max_total_qng);
12909 AscPutVarFreeQHead(iop_base, 1);
12910 AscPutVarDoneQTail(iop_base, asc_dvc->max_total_qng);
12911 AscWriteLramByte(iop_base, ASCV_BUSY_QHEAD_B,
12912 (uchar) ((int) asc_dvc->max_total_qng + 1));
12913 AscWriteLramByte(iop_base, ASCV_DISC1_QHEAD_B,
12914 (uchar) ((int) asc_dvc->max_total_qng + 2));
12915 AscWriteLramByte(iop_base, (ushort) ASCV_TOTAL_READY_Q_B,
12916 asc_dvc->max_total_qng);
12917 AscWriteLramWord(iop_base, ASCV_ASCDVC_ERR_CODE_W, 0);
12918 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
12919 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 0);
12920 AscWriteLramByte(iop_base, ASCV_SCSIBUSY_B, 0);
12921 AscWriteLramByte(iop_base, ASCV_WTM_FLAG_B, 0);
12922 AscPutQDoneInProgress(iop_base, 0);
12923 lram_addr = ASC_QADR_BEG;
12924 for (i = 0; i < 32; i++, lram_addr += 2) {
12925 AscWriteLramWord(iop_base, lram_addr, 0);
12927 return (0);
12930 STATIC int
12931 AscSetLibErrorCode(
12932 ASC_DVC_VAR *asc_dvc,
12933 ushort err_code
12936 if (asc_dvc->err_code == 0) {
12937 asc_dvc->err_code = err_code;
12938 AscWriteLramWord(asc_dvc->iop_base, ASCV_ASCDVC_ERR_CODE_W,
12939 err_code);
12941 return (err_code);
12945 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
12946 STATIC int
12947 _AscWaitQDone(
12948 PortAddr iop_base,
12949 ASC_SCSI_Q * scsiq
12952 ushort q_addr;
12953 uchar q_status;
12954 int count = 0;
12956 while (scsiq->q1.q_no == 0);
12957 q_addr = ASC_QNO_TO_QADDR(scsiq->q1.q_no);
12958 do {
12959 q_status = AscReadLramByte(iop_base, q_addr + ASC_SCSIQ_B_STATUS);
12960 DvcSleepMilliSecond(100L);
12961 if (count++ > 30) {
12962 return (0);
12964 } while ((q_status & QS_READY) != 0);
12965 return (1);
12967 #endif /* version >= v1.3.89 */
12969 STATIC uchar
12970 AscMsgOutSDTR(
12971 ASC_DVC_VAR *asc_dvc,
12972 uchar sdtr_period,
12973 uchar sdtr_offset
12976 EXT_MSG sdtr_buf;
12977 uchar sdtr_period_index;
12978 PortAddr iop_base;
12980 iop_base = asc_dvc->iop_base;
12981 sdtr_buf.msg_type = MS_EXTEND;
12982 sdtr_buf.msg_len = MS_SDTR_LEN;
12983 sdtr_buf.msg_req = MS_SDTR_CODE;
12984 sdtr_buf.xfer_period = sdtr_period;
12985 sdtr_offset &= ASC_SYN_MAX_OFFSET;
12986 sdtr_buf.req_ack_offset = sdtr_offset;
12987 if ((sdtr_period_index =
12988 AscGetSynPeriodIndex(asc_dvc, sdtr_period)) <=
12989 asc_dvc->max_sdtr_index) {
12990 AscMemWordCopyToLram(iop_base,
12991 ASCV_MSGOUT_BEG,
12992 (ushort *) & sdtr_buf,
12993 (ushort) (sizeof (EXT_MSG) >> 1));
12994 return ((sdtr_period_index << 4) | sdtr_offset);
12995 } else {
12997 sdtr_buf.req_ack_offset = 0;
12998 AscMemWordCopyToLram(iop_base,
12999 ASCV_MSGOUT_BEG,
13000 (ushort *) & sdtr_buf,
13001 (ushort) (sizeof (EXT_MSG) >> 1));
13002 return (0);
13006 STATIC uchar
13007 AscCalSDTRData(
13008 ASC_DVC_VAR *asc_dvc,
13009 uchar sdtr_period,
13010 uchar syn_offset
13013 uchar byte;
13014 uchar sdtr_period_ix;
13016 sdtr_period_ix = AscGetSynPeriodIndex(asc_dvc, sdtr_period);
13017 if (
13018 (sdtr_period_ix > asc_dvc->max_sdtr_index)
13020 return (0xFF);
13022 byte = (sdtr_period_ix << 4) | (syn_offset & ASC_SYN_MAX_OFFSET);
13023 return (byte);
13026 STATIC void
13027 AscSetChipSDTR(
13028 PortAddr iop_base,
13029 uchar sdtr_data,
13030 uchar tid_no
13033 AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
13034 AscPutMCodeSDTRDoneAtID(iop_base, tid_no, sdtr_data);
13035 return;
13038 STATIC uchar
13039 AscGetSynPeriodIndex(
13040 ASC_DVC_VAR *asc_dvc,
13041 uchar syn_time
13044 uchar *period_table;
13045 int max_index;
13046 int min_index;
13047 int i;
13049 period_table = asc_dvc->sdtr_period_tbl;
13050 max_index = (int) asc_dvc->max_sdtr_index;
13051 min_index = (int)asc_dvc->host_init_sdtr_index;
13052 if ((syn_time <= period_table[max_index])) {
13053 for (i = min_index; i < (max_index - 1); i++) {
13054 if (syn_time <= period_table[i]) {
13055 return ((uchar) i);
13058 return ((uchar) max_index);
13059 } else {
13060 return ((uchar) (max_index + 1));
13064 STATIC uchar
13065 AscAllocFreeQueue(
13066 PortAddr iop_base,
13067 uchar free_q_head
13070 ushort q_addr;
13071 uchar next_qp;
13072 uchar q_status;
13074 q_addr = ASC_QNO_TO_QADDR(free_q_head);
13075 q_status = (uchar) AscReadLramByte(iop_base,
13076 (ushort) (q_addr + ASC_SCSIQ_B_STATUS));
13077 next_qp = AscReadLramByte(iop_base,
13078 (ushort) (q_addr + ASC_SCSIQ_B_FWD));
13079 if (((q_status & QS_READY) == 0) && (next_qp != ASC_QLINK_END)) {
13080 return (next_qp);
13082 return (ASC_QLINK_END);
13085 STATIC uchar
13086 AscAllocMultipleFreeQueue(
13087 PortAddr iop_base,
13088 uchar free_q_head,
13089 uchar n_free_q
13092 uchar i;
13094 for (i = 0; i < n_free_q; i++) {
13095 if ((free_q_head = AscAllocFreeQueue(iop_base, free_q_head))
13096 == ASC_QLINK_END) {
13097 return (ASC_QLINK_END);
13100 return (free_q_head);
13103 STATIC int
13104 AscRiscHaltedAbortSRB(
13105 ASC_DVC_VAR *asc_dvc,
13106 ASC_VADDR srb_ptr
13109 PortAddr iop_base;
13110 ushort q_addr;
13111 uchar q_no;
13112 ASC_QDONE_INFO scsiq_buf;
13113 ASC_QDONE_INFO *scsiq;
13114 ASC_ISR_CALLBACK asc_isr_callback;
13115 int last_int_level;
13117 iop_base = asc_dvc->iop_base;
13118 asc_isr_callback = asc_dvc->isr_callback;
13119 last_int_level = DvcEnterCritical();
13120 scsiq = (ASC_QDONE_INFO *) & scsiq_buf;
13121 for (q_no = ASC_MIN_ACTIVE_QNO; q_no <= asc_dvc->max_total_qng;
13122 q_no++) {
13123 q_addr = ASC_QNO_TO_QADDR(q_no);
13124 scsiq->d2.srb_ptr = AscReadLramDWord(iop_base,
13125 (ushort) (q_addr + (ushort) ASC_SCSIQ_D_SRBPTR));
13126 if (scsiq->d2.srb_ptr == srb_ptr) {
13127 _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq, asc_dvc->max_dma_count);
13128 if (((scsiq->q_status & QS_READY) != 0)
13129 && ((scsiq->q_status & QS_ABORTED) == 0)
13130 && ((scsiq->cntl & QCSG_SG_XFER_LIST) == 0)) {
13131 scsiq->q_status |= QS_ABORTED;
13132 scsiq->d3.done_stat = QD_ABORTED_BY_HOST;
13133 AscWriteLramDWord(iop_base,
13134 (ushort) (q_addr + (ushort) ASC_SCSIQ_D_SRBPTR),
13135 0L);
13136 AscWriteLramByte(iop_base,
13137 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS),
13138 scsiq->q_status);
13139 (*asc_isr_callback) (asc_dvc, scsiq);
13140 return (1);
13144 DvcLeaveCritical(last_int_level);
13145 return (0);
13148 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
13149 STATIC int
13150 AscRiscHaltedAbortTIX(
13151 ASC_DVC_VAR *asc_dvc,
13152 uchar target_ix
13155 PortAddr iop_base;
13156 ushort q_addr;
13157 uchar q_no;
13158 ASC_QDONE_INFO scsiq_buf;
13159 ASC_QDONE_INFO *scsiq;
13160 ASC_ISR_CALLBACK asc_isr_callback;
13161 int last_int_level;
13163 iop_base = asc_dvc->iop_base;
13164 asc_isr_callback = asc_dvc->isr_callback;
13165 last_int_level = DvcEnterCritical();
13166 scsiq = (ASC_QDONE_INFO *) & scsiq_buf;
13167 for (q_no = ASC_MIN_ACTIVE_QNO; q_no <= asc_dvc->max_total_qng;
13168 q_no++) {
13169 q_addr = ASC_QNO_TO_QADDR(q_no);
13170 _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq, asc_dvc->max_dma_count);
13171 if (((scsiq->q_status & QS_READY) != 0) &&
13172 ((scsiq->q_status & QS_ABORTED) == 0) &&
13173 ((scsiq->cntl & QCSG_SG_XFER_LIST) == 0)) {
13174 if (scsiq->d2.target_ix == target_ix) {
13175 scsiq->q_status |= QS_ABORTED;
13176 scsiq->d3.done_stat = QD_ABORTED_BY_HOST;
13177 AscWriteLramDWord(iop_base,
13178 (ushort) (q_addr + (ushort) ASC_SCSIQ_D_SRBPTR),
13179 0L);
13180 AscWriteLramByte(iop_base,
13181 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS),
13182 scsiq->q_status);
13183 (*asc_isr_callback) (asc_dvc, scsiq);
13187 DvcLeaveCritical(last_int_level);
13188 return (1);
13190 #endif /* version >= v1.3.89 */
13192 STATIC int
13193 AscHostReqRiscHalt(
13194 PortAddr iop_base
13197 int count = 0;
13198 int sta = 0;
13199 uchar saved_stop_code;
13201 if (AscIsChipHalted(iop_base))
13202 return (1);
13203 saved_stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
13204 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
13205 ASC_STOP_HOST_REQ_RISC_HALT | ASC_STOP_REQ_RISC_STOP
13207 do {
13208 if (AscIsChipHalted(iop_base)) {
13209 sta = 1;
13210 break;
13212 DvcSleepMilliSecond(100);
13213 } while (count++ < 20);
13214 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, saved_stop_code);
13215 return (sta);
13218 STATIC int
13219 AscStopQueueExe(
13220 PortAddr iop_base
13223 int count = 0;
13225 if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) == 0) {
13226 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
13227 ASC_STOP_REQ_RISC_STOP);
13228 do {
13229 if (
13230 AscReadLramByte(iop_base, ASCV_STOP_CODE_B) &
13231 ASC_STOP_ACK_RISC_STOP) {
13232 return (1);
13234 DvcSleepMilliSecond(100);
13235 } while (count++ < 20);
13237 return (0);
13240 STATIC int
13241 AscStartQueueExe(
13242 PortAddr iop_base
13245 if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) != 0) {
13246 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 0);
13248 return (1);
13251 STATIC int
13252 AscCleanUpBusyQueue(
13253 PortAddr iop_base
13256 int count;
13257 uchar stop_code;
13259 count = 0;
13260 if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) != 0) {
13261 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
13262 ASC_STOP_CLEAN_UP_BUSY_Q);
13263 do {
13264 stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
13265 if ((stop_code & ASC_STOP_CLEAN_UP_BUSY_Q) == 0)
13266 break;
13267 DvcSleepMilliSecond(100);
13268 } while (count++ < 20);
13270 return (1);
13273 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
13274 STATIC int
13275 AscCleanUpDiscQueue(
13276 PortAddr iop_base
13279 int count;
13280 uchar stop_code;
13282 count = 0;
13283 if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) != 0) {
13284 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
13285 ASC_STOP_CLEAN_UP_DISC_Q);
13286 do {
13287 stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
13288 if ((stop_code & ASC_STOP_CLEAN_UP_DISC_Q) == 0)
13289 break;
13290 DvcSleepMilliSecond(100);
13291 } while (count++ < 20);
13293 return (1);
13295 #endif /* version >= v1.3.89 */
13297 STATIC int
13298 AscWaitTixISRDone(
13299 ASC_DVC_VAR *asc_dvc,
13300 uchar target_ix
13303 uchar cur_req;
13304 uchar tid_no;
13305 int i = 0;
13307 tid_no = ASC_TIX_TO_TID(target_ix);
13308 while (i++ < 10) {
13309 if ((cur_req = asc_dvc->cur_dvc_qng[tid_no]) == 0) {
13310 break;
13312 DvcSleepMilliSecond(1000L);
13313 if (asc_dvc->cur_dvc_qng[tid_no] == cur_req) {
13314 break;
13317 return (1);
13320 STATIC int
13321 AscWaitISRDone(
13322 ASC_DVC_VAR *asc_dvc
13325 int tid;
13327 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
13328 AscWaitTixISRDone(asc_dvc, ASC_TID_TO_TIX(tid));
13330 return (1);
13333 STATIC ASC_PADDR
13334 AscGetOnePhyAddr(
13335 ASC_DVC_VAR *asc_dvc,
13336 uchar * buf_addr,
13337 ASC_DCNT buf_size
13340 ASC_MIN_SG_HEAD sg_head;
13342 sg_head.entry_cnt = ASC_MIN_SG_LIST;
13343 if (DvcGetSGList(asc_dvc, (uchar *) buf_addr,
13344 buf_size, (ASC_SG_HEAD *) &sg_head) != buf_size) {
13345 return (0L);
13347 if (sg_head.entry_cnt > 1) {
13348 return (0L);
13350 return ((ASC_PADDR) sg_head.sg_list[0].addr);
13353 STATIC void
13354 DvcDelayMicroSecond(ADV_DVC_VAR *asc_dvc, ushort micro_sec)
13356 udelay(micro_sec);
13359 STATIC void
13360 DvcDelayNanoSecond(ASC_DVC_VAR *asc_dvc, ASC_DCNT nano_sec)
13362 udelay((nano_sec + 999)/1000);
13365 ASC_INITFUNC(
13366 STATIC ASC_DCNT,
13367 AscGetEisaProductID(
13368 PortAddr iop_base
13372 PortAddr eisa_iop;
13373 ushort product_id_high, product_id_low;
13374 ASC_DCNT product_id;
13376 eisa_iop = ASC_GET_EISA_SLOT(iop_base) | ASC_EISA_PID_IOP_MASK;
13377 product_id_low = inpw(eisa_iop);
13378 product_id_high = inpw(eisa_iop + 2);
13379 product_id = ((ASC_DCNT) product_id_high << 16) |
13380 (ASC_DCNT) product_id_low;
13381 return (product_id);
13384 ASC_INITFUNC(
13385 STATIC PortAddr,
13386 AscSearchIOPortAddrEISA(
13387 PortAddr iop_base
13391 ASC_DCNT eisa_product_id;
13393 if (iop_base == 0) {
13394 iop_base = ASC_EISA_MIN_IOP_ADDR;
13395 } else {
13396 if (iop_base == ASC_EISA_MAX_IOP_ADDR)
13397 return (0);
13398 if ((iop_base & 0x0050) == 0x0050) {
13399 iop_base += ASC_EISA_BIG_IOP_GAP;
13400 } else {
13401 iop_base += ASC_EISA_SMALL_IOP_GAP;
13404 while (iop_base <= ASC_EISA_MAX_IOP_ADDR) {
13405 eisa_product_id = AscGetEisaProductID(iop_base);
13406 if ((eisa_product_id == ASC_EISA_ID_740) ||
13407 (eisa_product_id == ASC_EISA_ID_750)) {
13408 if (AscFindSignature(iop_base)) {
13409 inpw(iop_base + 4);
13410 return (iop_base);
13413 if (iop_base == ASC_EISA_MAX_IOP_ADDR)
13414 return (0);
13415 if ((iop_base & 0x0050) == 0x0050) {
13416 iop_base += ASC_EISA_BIG_IOP_GAP;
13417 } else {
13418 iop_base += ASC_EISA_SMALL_IOP_GAP;
13421 return (0);
13424 STATIC int
13425 AscStartChip(
13426 PortAddr iop_base
13429 AscSetChipControl(iop_base, 0);
13430 if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
13431 return (0);
13433 return (1);
13436 STATIC int
13437 AscStopChip(
13438 PortAddr iop_base
13441 uchar cc_val;
13443 cc_val = AscGetChipControl(iop_base) & (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG));
13444 AscSetChipControl(iop_base, (uchar) (cc_val | CC_HALT));
13445 AscSetChipIH(iop_base, INS_HALT);
13446 AscSetChipIH(iop_base, INS_RFLAG_WTM);
13447 if ((AscGetChipStatus(iop_base) & CSW_HALTED) == 0) {
13448 return (0);
13450 return (1);
13453 STATIC int
13454 AscIsChipHalted(
13455 PortAddr iop_base
13458 if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
13459 if ((AscGetChipControl(iop_base) & CC_HALT) != 0) {
13460 return (1);
13463 return (0);
13466 STATIC void
13467 AscSetChipIH(
13468 PortAddr iop_base,
13469 ushort ins_code
13472 AscSetBank(iop_base, 1);
13473 AscWriteChipIH(iop_base, ins_code);
13474 AscSetBank(iop_base, 0);
13475 return;
13478 STATIC void
13479 AscAckInterrupt(
13480 PortAddr iop_base
13483 uchar host_flag;
13484 uchar risc_flag;
13485 ushort loop;
13487 loop = 0;
13488 do {
13489 risc_flag = AscReadLramByte(iop_base, ASCV_RISC_FLAG_B);
13490 if (loop++ > 0x7FFF) {
13491 break;
13493 } while ((risc_flag & ASC_RISC_FLAG_GEN_INT) != 0);
13494 host_flag = AscReadLramByte(iop_base, ASCV_HOST_FLAG_B) & (~ASC_HOST_FLAG_ACK_INT);
13495 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
13496 (uchar) (host_flag | ASC_HOST_FLAG_ACK_INT));
13497 AscSetChipStatus(iop_base, CIW_INT_ACK);
13498 loop = 0;
13499 while (AscGetChipStatus(iop_base) & CSW_INT_PENDING) {
13500 AscSetChipStatus(iop_base, CIW_INT_ACK);
13501 if (loop++ > 3) {
13502 break;
13505 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
13506 return;
13509 STATIC void
13510 AscDisableInterrupt(
13511 PortAddr iop_base
13514 ushort cfg;
13516 cfg = AscGetChipCfgLsw(iop_base);
13517 AscSetChipCfgLsw(iop_base, cfg & (~ASC_CFG0_HOST_INT_ON));
13518 return;
13521 STATIC void
13522 AscEnableInterrupt(
13523 PortAddr iop_base
13526 ushort cfg;
13528 cfg = AscGetChipCfgLsw(iop_base);
13529 AscSetChipCfgLsw(iop_base, cfg | ASC_CFG0_HOST_INT_ON);
13530 return;
13535 STATIC void
13536 AscSetBank(
13537 PortAddr iop_base,
13538 uchar bank
13541 uchar val;
13543 val = AscGetChipControl(iop_base) &
13544 (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG | CC_SCSI_RESET | CC_CHIP_RESET));
13545 if (bank == 1) {
13546 val |= CC_BANK_ONE;
13547 } else if (bank == 2) {
13548 val |= CC_DIAG | CC_BANK_ONE;
13549 } else {
13550 val &= ~CC_BANK_ONE;
13552 AscSetChipControl(iop_base, val);
13553 return;
13556 STATIC int
13557 AscResetChipAndScsiBus(
13558 ASC_DVC_VAR *asc_dvc
13561 PortAddr iop_base;
13562 int i = 10;
13564 iop_base = asc_dvc->iop_base;
13565 while ((AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE) && (i-- > 0))
13567 DvcSleepMilliSecond(100);
13569 AscStopChip(iop_base);
13570 AscSetChipControl(iop_base, CC_CHIP_RESET | CC_SCSI_RESET | CC_HALT);
13571 DvcDelayNanoSecond(asc_dvc, 60000);
13572 AscSetChipIH(iop_base, INS_RFLAG_WTM);
13573 AscSetChipIH(iop_base, INS_HALT);
13574 AscSetChipControl(iop_base, CC_CHIP_RESET | CC_HALT);
13575 AscSetChipControl(iop_base, CC_HALT);
13576 DvcSleepMilliSecond(200);
13577 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
13578 AscSetChipStatus(iop_base, 0);
13579 return (AscIsChipHalted(iop_base));
13582 ASC_INITFUNC(
13583 STATIC ASC_DCNT,
13584 AscGetMaxDmaCount(
13585 ushort bus_type
13589 if (bus_type & ASC_IS_ISA)
13590 return (ASC_MAX_ISA_DMA_COUNT);
13591 else if (bus_type & (ASC_IS_EISA | ASC_IS_VL))
13592 return (ASC_MAX_VL_DMA_COUNT);
13593 return (ASC_MAX_PCI_DMA_COUNT);
13596 ASC_INITFUNC(
13597 STATIC ushort,
13598 AscGetIsaDmaChannel(
13599 PortAddr iop_base
13603 ushort channel;
13605 channel = AscGetChipCfgLsw(iop_base) & 0x0003;
13606 if (channel == 0x03)
13607 return (0);
13608 else if (channel == 0x00)
13609 return (7);
13610 return (channel + 4);
13613 ASC_INITFUNC(
13614 STATIC ushort,
13615 AscSetIsaDmaChannel(
13616 PortAddr iop_base,
13617 ushort dma_channel
13621 ushort cfg_lsw;
13622 uchar value;
13624 if ((dma_channel >= 5) && (dma_channel <= 7)) {
13625 if (dma_channel == 7)
13626 value = 0x00;
13627 else
13628 value = dma_channel - 4;
13629 cfg_lsw = AscGetChipCfgLsw(iop_base) & 0xFFFC;
13630 cfg_lsw |= value;
13631 AscSetChipCfgLsw(iop_base, cfg_lsw);
13632 return (AscGetIsaDmaChannel(iop_base));
13634 return (0);
13637 ASC_INITFUNC(
13638 STATIC uchar,
13639 AscSetIsaDmaSpeed(
13640 PortAddr iop_base,
13641 uchar speed_value
13645 speed_value &= 0x07;
13646 AscSetBank(iop_base, 1);
13647 AscWriteChipDmaSpeed(iop_base, speed_value);
13648 AscSetBank(iop_base, 0);
13649 return (AscGetIsaDmaSpeed(iop_base));
13652 ASC_INITFUNC(
13653 STATIC uchar,
13654 AscGetIsaDmaSpeed(
13655 PortAddr iop_base
13659 uchar speed_value;
13661 AscSetBank(iop_base, 1);
13662 speed_value = AscReadChipDmaSpeed(iop_base);
13663 speed_value &= 0x07;
13664 AscSetBank(iop_base, 0);
13665 return (speed_value);
13668 ASC_INITFUNC(
13669 STATIC ushort,
13670 AscReadPCIConfigWord(
13671 ASC_DVC_VAR *asc_dvc,
13672 ushort pci_config_offset)
13675 uchar lsb, msb;
13677 lsb = DvcReadPCIConfigByte(asc_dvc, pci_config_offset);
13678 msb = DvcReadPCIConfigByte(asc_dvc, pci_config_offset + 1);
13679 return ((ushort) ((msb << 8) | lsb));
13682 ASC_INITFUNC(
13683 STATIC ushort,
13684 AscInitGetConfig(
13685 ASC_DVC_VAR *asc_dvc
13689 ushort warn_code;
13690 PortAddr iop_base;
13691 ushort PCIDeviceID;
13692 ushort PCIVendorID;
13693 uchar PCIRevisionID;
13694 uchar prevCmdRegBits;
13696 warn_code = 0;
13697 iop_base = asc_dvc->iop_base;
13698 asc_dvc->init_state = ASC_INIT_STATE_BEG_GET_CFG;
13699 if (asc_dvc->err_code != 0) {
13700 return (UW_ERR);
13702 if (asc_dvc->bus_type == ASC_IS_PCI) {
13703 PCIVendorID = AscReadPCIConfigWord(asc_dvc,
13704 AscPCIConfigVendorIDRegister);
13706 PCIDeviceID = AscReadPCIConfigWord(asc_dvc,
13707 AscPCIConfigDeviceIDRegister);
13709 PCIRevisionID = DvcReadPCIConfigByte(asc_dvc,
13710 AscPCIConfigRevisionIDRegister);
13712 if (PCIVendorID != ASC_PCI_VENDORID) {
13713 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
13715 prevCmdRegBits = DvcReadPCIConfigByte(asc_dvc,
13716 AscPCIConfigCommandRegister);
13718 if ((prevCmdRegBits & AscPCICmdRegBits_IOMemBusMaster) !=
13719 AscPCICmdRegBits_IOMemBusMaster) {
13720 DvcWritePCIConfigByte(asc_dvc,
13721 AscPCIConfigCommandRegister,
13722 (prevCmdRegBits |
13723 AscPCICmdRegBits_IOMemBusMaster));
13725 if ((DvcReadPCIConfigByte(asc_dvc,
13726 AscPCIConfigCommandRegister)
13727 & AscPCICmdRegBits_IOMemBusMaster)
13728 != AscPCICmdRegBits_IOMemBusMaster) {
13729 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
13732 if ((PCIDeviceID == ASC_PCI_DEVICEID_1200A) ||
13733 (PCIDeviceID == ASC_PCI_DEVICEID_1200B)) {
13734 DvcWritePCIConfigByte(asc_dvc,
13735 AscPCIConfigLatencyTimer, 0x00);
13736 if (DvcReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer)
13737 != 0x00) {
13738 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
13740 } else if (PCIDeviceID == ASC_PCI_DEVICEID_ULTRA) {
13741 if (DvcReadPCIConfigByte(asc_dvc,
13742 AscPCIConfigLatencyTimer) < 0x20) {
13743 DvcWritePCIConfigByte(asc_dvc,
13744 AscPCIConfigLatencyTimer, 0x20);
13746 if (DvcReadPCIConfigByte(asc_dvc,
13747 AscPCIConfigLatencyTimer) < 0x20) {
13748 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
13754 if (AscFindSignature(iop_base)) {
13755 warn_code |= AscInitAscDvcVar(asc_dvc);
13756 warn_code |= AscInitFromEEP(asc_dvc);
13757 asc_dvc->init_state |= ASC_INIT_STATE_END_GET_CFG;
13758 if (asc_dvc->scsi_reset_wait > ASC_MAX_SCSI_RESET_WAIT) {
13759 asc_dvc->scsi_reset_wait = ASC_MAX_SCSI_RESET_WAIT;
13761 } else {
13762 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
13764 return(warn_code);
13767 ASC_INITFUNC(
13768 STATIC ushort,
13769 AscInitSetConfig(
13770 ASC_DVC_VAR *asc_dvc
13774 ushort warn_code = 0;
13776 asc_dvc->init_state |= ASC_INIT_STATE_BEG_SET_CFG;
13777 if (asc_dvc->err_code != 0)
13778 return (UW_ERR);
13779 if (AscFindSignature(asc_dvc->iop_base)) {
13780 warn_code |= AscInitFromAscDvcVar(asc_dvc);
13781 asc_dvc->init_state |= ASC_INIT_STATE_END_SET_CFG;
13782 } else {
13783 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
13785 return (warn_code);
13788 ASC_INITFUNC(
13789 STATIC ushort,
13790 AscInitFromAscDvcVar(
13791 ASC_DVC_VAR *asc_dvc
13795 PortAddr iop_base;
13796 ushort cfg_msw;
13797 ushort warn_code;
13798 ushort pci_device_id;
13800 iop_base = asc_dvc->iop_base;
13801 pci_device_id = asc_dvc->cfg->pci_device_id;
13802 warn_code = 0;
13803 cfg_msw = AscGetChipCfgMsw(iop_base);
13804 if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
13805 cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
13806 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
13807 AscSetChipCfgMsw(iop_base, cfg_msw);
13809 if ((asc_dvc->cfg->cmd_qng_enabled & asc_dvc->cfg->disc_enable) !=
13810 asc_dvc->cfg->cmd_qng_enabled) {
13811 asc_dvc->cfg->disc_enable = asc_dvc->cfg->cmd_qng_enabled;
13812 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
13814 if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
13815 warn_code |= ASC_WARN_AUTO_CONFIG;
13817 if ((asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL)) != 0) {
13818 if (AscSetChipIRQ(iop_base, asc_dvc->irq_no, asc_dvc->bus_type)
13819 != asc_dvc->irq_no) {
13820 asc_dvc->err_code |= ASC_IERR_SET_IRQ_NO;
13823 if (asc_dvc->bus_type & ASC_IS_PCI) {
13824 cfg_msw &= 0xFFC0;
13825 AscSetChipCfgMsw(iop_base, cfg_msw);
13826 if ((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) {
13827 } else {
13828 if ((pci_device_id == ASC_PCI_DEVICE_ID_REV_A) ||
13829 (pci_device_id == ASC_PCI_DEVICE_ID_REV_B)) {
13830 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_IF_NOT_DWB;
13831 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN;
13834 } else if (asc_dvc->bus_type == ASC_IS_ISAPNP) {
13835 if (AscGetChipVersion(iop_base, asc_dvc->bus_type)
13836 == ASC_CHIP_VER_ASYN_BUG) {
13837 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN;
13840 if (AscSetChipScsiID(iop_base, asc_dvc->cfg->chip_scsi_id) !=
13841 asc_dvc->cfg->chip_scsi_id) {
13842 asc_dvc->err_code |= ASC_IERR_SET_SCSI_ID;
13844 if (asc_dvc->bus_type & ASC_IS_ISA) {
13845 AscSetIsaDmaChannel(iop_base, asc_dvc->cfg->isa_dma_channel);
13846 AscSetIsaDmaSpeed(iop_base, asc_dvc->cfg->isa_dma_speed);
13848 return (warn_code);
13851 ASC_INITFUNC(
13852 STATIC ushort,
13853 AscInitAsc1000Driver(
13854 ASC_DVC_VAR *asc_dvc
13858 ushort warn_code;
13859 PortAddr iop_base;
13861 iop_base = asc_dvc->iop_base;
13862 warn_code = 0;
13863 if ((asc_dvc->dvc_cntl & ASC_CNTL_RESET_SCSI) &&
13864 !(asc_dvc->init_state & ASC_INIT_RESET_SCSI_DONE)) {
13865 AscResetChipAndScsiBus(asc_dvc);
13866 DvcSleepMilliSecond((ASC_DCNT)
13867 ((ushort) asc_dvc->scsi_reset_wait * 1000));
13869 asc_dvc->init_state |= ASC_INIT_STATE_BEG_LOAD_MC;
13870 if (asc_dvc->err_code != 0)
13871 return (UW_ERR);
13872 if (!AscFindSignature(asc_dvc->iop_base)) {
13873 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
13874 return (warn_code);
13876 AscDisableInterrupt(iop_base);
13877 warn_code |= AscInitLram(asc_dvc);
13878 if (asc_dvc->err_code != 0)
13879 return (UW_ERR);
13880 if (AscLoadMicroCode(iop_base, 0, (ushort *) _asc_mcode_buf,
13881 _asc_mcode_size) != _asc_mcode_chksum) {
13882 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
13883 return (warn_code);
13885 warn_code |= AscInitMicroCodeVar(asc_dvc);
13886 asc_dvc->init_state |= ASC_INIT_STATE_END_LOAD_MC;
13887 AscEnableInterrupt(iop_base);
13888 return (warn_code);
13891 ASC_INITFUNC(
13892 STATIC ushort,
13893 AscInitAscDvcVar(
13894 ASC_DVC_VAR *asc_dvc
13898 int i;
13899 PortAddr iop_base;
13900 ushort warn_code;
13901 uchar chip_version;
13903 iop_base = asc_dvc->iop_base;
13904 warn_code = 0;
13905 asc_dvc->err_code = 0;
13906 if ((asc_dvc->bus_type &
13907 (ASC_IS_ISA | ASC_IS_PCI | ASC_IS_EISA | ASC_IS_VL)) == 0) {
13908 asc_dvc->err_code |= ASC_IERR_NO_BUS_TYPE;
13910 AscSetChipControl(iop_base, CC_HALT);
13911 AscSetChipStatus(iop_base, 0);
13912 asc_dvc->bug_fix_cntl = 0;
13913 asc_dvc->pci_fix_asyn_xfer = 0;
13914 asc_dvc->pci_fix_asyn_xfer_always = 0;
13915 asc_dvc->init_state = 0;
13916 asc_dvc->sdtr_done = 0;
13917 asc_dvc->cur_total_qng = 0;
13918 asc_dvc->is_in_int = 0;
13919 asc_dvc->in_critical_cnt = 0;
13920 asc_dvc->last_q_shortage = 0;
13921 asc_dvc->use_tagged_qng = 0;
13922 asc_dvc->no_scam = 0;
13923 asc_dvc->unit_not_ready = 0;
13924 asc_dvc->queue_full_or_busy = 0;
13925 asc_dvc->redo_scam = 0;
13926 asc_dvc->res2 = 0;
13927 asc_dvc->host_init_sdtr_index = 0;
13928 asc_dvc->cfg->can_tagged_qng = 0;
13929 asc_dvc->cfg->cmd_qng_enabled = 0;
13930 asc_dvc->dvc_cntl = ASC_DEF_DVC_CNTL;
13931 asc_dvc->init_sdtr = 0;
13932 asc_dvc->max_total_qng = ASC_DEF_MAX_TOTAL_QNG;
13933 asc_dvc->scsi_reset_wait = 3;
13934 asc_dvc->start_motor = ASC_SCSI_WIDTH_BIT_SET;
13935 asc_dvc->max_dma_count = AscGetMaxDmaCount(asc_dvc->bus_type);
13936 asc_dvc->cfg->sdtr_enable = ASC_SCSI_WIDTH_BIT_SET;
13937 asc_dvc->cfg->disc_enable = ASC_SCSI_WIDTH_BIT_SET;
13938 asc_dvc->cfg->chip_scsi_id = ASC_DEF_CHIP_SCSI_ID;
13939 asc_dvc->cfg->lib_serial_no = ASC_LIB_SERIAL_NUMBER;
13940 asc_dvc->cfg->lib_version = (ASC_LIB_VERSION_MAJOR << 8) |
13941 ASC_LIB_VERSION_MINOR;
13942 chip_version = AscGetChipVersion(iop_base, asc_dvc->bus_type);
13943 asc_dvc->cfg->chip_version = chip_version;
13944 asc_dvc->sdtr_period_tbl[0] = SYN_XFER_NS_0;
13945 asc_dvc->sdtr_period_tbl[1] = SYN_XFER_NS_1;
13946 asc_dvc->sdtr_period_tbl[2] = SYN_XFER_NS_2;
13947 asc_dvc->sdtr_period_tbl[3] = SYN_XFER_NS_3;
13948 asc_dvc->sdtr_period_tbl[4] = SYN_XFER_NS_4;
13949 asc_dvc->sdtr_period_tbl[5] = SYN_XFER_NS_5;
13950 asc_dvc->sdtr_period_tbl[6] = SYN_XFER_NS_6;
13951 asc_dvc->sdtr_period_tbl[7] = SYN_XFER_NS_7;
13952 asc_dvc->max_sdtr_index = 7;
13953 if ((asc_dvc->bus_type & ASC_IS_PCI) &&
13954 (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3150)) {
13955 asc_dvc->bus_type = ASC_IS_PCI_ULTRA;
13956 asc_dvc->sdtr_period_tbl[0] = SYN_ULTRA_XFER_NS_0;
13957 asc_dvc->sdtr_period_tbl[1] = SYN_ULTRA_XFER_NS_1;
13958 asc_dvc->sdtr_period_tbl[2] = SYN_ULTRA_XFER_NS_2;
13959 asc_dvc->sdtr_period_tbl[3] = SYN_ULTRA_XFER_NS_3;
13960 asc_dvc->sdtr_period_tbl[4] = SYN_ULTRA_XFER_NS_4;
13961 asc_dvc->sdtr_period_tbl[5] = SYN_ULTRA_XFER_NS_5;
13962 asc_dvc->sdtr_period_tbl[6] = SYN_ULTRA_XFER_NS_6;
13963 asc_dvc->sdtr_period_tbl[7] = SYN_ULTRA_XFER_NS_7;
13964 asc_dvc->sdtr_period_tbl[8] = SYN_ULTRA_XFER_NS_8;
13965 asc_dvc->sdtr_period_tbl[9] = SYN_ULTRA_XFER_NS_9;
13966 asc_dvc->sdtr_period_tbl[10] = SYN_ULTRA_XFER_NS_10;
13967 asc_dvc->sdtr_period_tbl[11] = SYN_ULTRA_XFER_NS_11;
13968 asc_dvc->sdtr_period_tbl[12] = SYN_ULTRA_XFER_NS_12;
13969 asc_dvc->sdtr_period_tbl[13] = SYN_ULTRA_XFER_NS_13;
13970 asc_dvc->sdtr_period_tbl[14] = SYN_ULTRA_XFER_NS_14;
13971 asc_dvc->sdtr_period_tbl[15] = SYN_ULTRA_XFER_NS_15;
13972 asc_dvc->max_sdtr_index = 15;
13973 if (chip_version == ASC_CHIP_VER_PCI_ULTRA_3150)
13975 AscSetExtraControl(iop_base,
13976 (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
13977 } else if (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3050) {
13978 AscSetExtraControl(iop_base,
13979 (SEC_ACTIVE_NEGATE | SEC_ENABLE_FILTER));
13982 if (asc_dvc->bus_type == ASC_IS_PCI) {
13983 AscSetExtraControl(iop_base, (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
13986 asc_dvc->cfg->isa_dma_speed = ASC_DEF_ISA_DMA_SPEED;
13987 if (AscGetChipBusType(iop_base) == ASC_IS_ISAPNP) {
13988 AscSetChipIFC(iop_base, IFC_INIT_DEFAULT);
13989 asc_dvc->bus_type = ASC_IS_ISAPNP;
13991 if ((asc_dvc->bus_type & ASC_IS_ISA) != 0) {
13992 asc_dvc->cfg->isa_dma_channel = (uchar) AscGetIsaDmaChannel(iop_base);
13994 for (i = 0; i <= ASC_MAX_TID; i++) {
13995 asc_dvc->cur_dvc_qng[i] = 0;
13996 asc_dvc->max_dvc_qng[i] = ASC_MAX_SCSI1_QNG;
13997 asc_dvc->scsiq_busy_head[i] = (ASC_SCSI_Q *) 0L;
13998 asc_dvc->scsiq_busy_tail[i] = (ASC_SCSI_Q *) 0L;
13999 asc_dvc->cfg->max_tag_qng[i] = ASC_MAX_INRAM_TAG_QNG;
14001 return (warn_code);
14004 ASC_INITFUNC(
14005 STATIC ushort,
14006 AscInitFromEEP(
14007 ASC_DVC_VAR *asc_dvc
14011 ASCEEP_CONFIG eep_config_buf;
14012 ASCEEP_CONFIG *eep_config;
14013 PortAddr iop_base;
14014 ushort chksum;
14015 ushort warn_code;
14016 ushort cfg_msw, cfg_lsw;
14017 int i;
14018 int write_eep = 0;
14020 iop_base = asc_dvc->iop_base;
14021 warn_code = 0;
14022 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0x00FE);
14023 AscStopQueueExe(iop_base);
14024 if ((AscStopChip(iop_base) == FALSE) ||
14025 (AscGetChipScsiCtrl(iop_base) != 0)) {
14026 asc_dvc->init_state |= ASC_INIT_RESET_SCSI_DONE;
14027 AscResetChipAndScsiBus(asc_dvc);
14028 DvcSleepMilliSecond((ASC_DCNT)
14029 ((ushort) asc_dvc->scsi_reset_wait * 1000));
14031 if (AscIsChipHalted(iop_base) == FALSE) {
14032 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
14033 return (warn_code);
14035 AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
14036 if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
14037 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
14038 return (warn_code);
14040 eep_config = (ASCEEP_CONFIG *) & eep_config_buf;
14041 cfg_msw = AscGetChipCfgMsw(iop_base);
14042 cfg_lsw = AscGetChipCfgLsw(iop_base);
14043 if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
14044 cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
14045 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
14046 AscSetChipCfgMsw(iop_base, cfg_msw);
14048 chksum = AscGetEEPConfig(iop_base, eep_config, asc_dvc->bus_type);
14049 if (chksum == 0) {
14050 chksum = 0xaa55;
14052 if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
14053 warn_code |= ASC_WARN_AUTO_CONFIG;
14054 if (asc_dvc->cfg->chip_version == 3) {
14055 if (eep_config->cfg_lsw != cfg_lsw) {
14056 warn_code |= ASC_WARN_EEPROM_RECOVER;
14057 eep_config->cfg_lsw = AscGetChipCfgLsw(iop_base);
14059 if (eep_config->cfg_msw != cfg_msw) {
14060 warn_code |= ASC_WARN_EEPROM_RECOVER;
14061 eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
14065 eep_config->cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
14066 eep_config->cfg_lsw |= ASC_CFG0_HOST_INT_ON;
14067 if (chksum != eep_config->chksum) {
14068 if (AscGetChipVersion(iop_base, asc_dvc->bus_type) ==
14069 ASC_CHIP_VER_PCI_ULTRA_3050 )
14071 eep_config->init_sdtr = 0xFF;
14072 eep_config->disc_enable = 0xFF;
14073 eep_config->start_motor = 0xFF;
14074 eep_config->use_cmd_qng = 0;
14075 eep_config->max_total_qng = 0xF0;
14076 eep_config->max_tag_qng = 0x20;
14077 eep_config->cntl = 0xBFFF;
14078 eep_config->chip_scsi_id = 7;
14079 eep_config->no_scam = 0;
14080 eep_config->adapter_info[0] = 0;
14081 eep_config->adapter_info[1] = 0;
14082 eep_config->adapter_info[2] = 0;
14083 eep_config->adapter_info[3] = 0;
14084 eep_config->adapter_info[4] = 0;
14085 /* Indicate EEPROM-less board. */
14086 eep_config->adapter_info[5] = 0xBB;
14087 } else {
14088 write_eep = 1;
14089 warn_code |= ASC_WARN_EEPROM_CHKSUM;
14092 asc_dvc->cfg->sdtr_enable = eep_config->init_sdtr;
14093 asc_dvc->cfg->disc_enable = eep_config->disc_enable;
14094 asc_dvc->cfg->cmd_qng_enabled = eep_config->use_cmd_qng;
14095 asc_dvc->cfg->isa_dma_speed = eep_config->isa_dma_speed;
14096 asc_dvc->start_motor = eep_config->start_motor;
14097 asc_dvc->dvc_cntl = eep_config->cntl;
14098 asc_dvc->no_scam = eep_config->no_scam;
14099 asc_dvc->cfg->adapter_info[0] = eep_config->adapter_info[0];
14100 asc_dvc->cfg->adapter_info[1] = eep_config->adapter_info[1];
14101 asc_dvc->cfg->adapter_info[2] = eep_config->adapter_info[2];
14102 asc_dvc->cfg->adapter_info[3] = eep_config->adapter_info[3];
14103 asc_dvc->cfg->adapter_info[4] = eep_config->adapter_info[4];
14104 asc_dvc->cfg->adapter_info[5] = eep_config->adapter_info[5];
14105 if (!AscTestExternalLram(asc_dvc)) {
14106 if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA)) {
14107 eep_config->max_total_qng = ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG;
14108 eep_config->max_tag_qng = ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG;
14109 } else {
14110 eep_config->cfg_msw |= 0x0800;
14111 cfg_msw |= 0x0800;
14112 AscSetChipCfgMsw(iop_base, cfg_msw);
14113 eep_config->max_total_qng = ASC_MAX_PCI_INRAM_TOTAL_QNG;
14114 eep_config->max_tag_qng = ASC_MAX_INRAM_TAG_QNG;
14116 } else {
14118 if (eep_config->max_total_qng < ASC_MIN_TOTAL_QNG) {
14119 eep_config->max_total_qng = ASC_MIN_TOTAL_QNG;
14121 if (eep_config->max_total_qng > ASC_MAX_TOTAL_QNG) {
14122 eep_config->max_total_qng = ASC_MAX_TOTAL_QNG;
14124 if (eep_config->max_tag_qng > eep_config->max_total_qng) {
14125 eep_config->max_tag_qng = eep_config->max_total_qng;
14127 if (eep_config->max_tag_qng < ASC_MIN_TAG_Q_PER_DVC) {
14128 eep_config->max_tag_qng = ASC_MIN_TAG_Q_PER_DVC;
14130 asc_dvc->max_total_qng = eep_config->max_total_qng;
14131 if ((eep_config->use_cmd_qng & eep_config->disc_enable) !=
14132 eep_config->use_cmd_qng) {
14133 eep_config->disc_enable = eep_config->use_cmd_qng;
14134 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
14136 if (asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL | ASC_IS_EISA)) {
14137 asc_dvc->irq_no = AscGetChipIRQ(iop_base, asc_dvc->bus_type);
14139 eep_config->chip_scsi_id &= ASC_MAX_TID;
14140 asc_dvc->cfg->chip_scsi_id = eep_config->chip_scsi_id;
14141 if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) &&
14142 !(asc_dvc->dvc_cntl & ASC_CNTL_SDTR_ENABLE_ULTRA)) {
14143 asc_dvc->host_init_sdtr_index = ASC_SDTR_ULTRA_PCI_10MB_INDEX;
14146 for (i = 0; i <= ASC_MAX_TID; i++) {
14147 asc_dvc->dos_int13_table[i] = eep_config->dos_int13_table[i];
14148 asc_dvc->cfg->max_tag_qng[i] = eep_config->max_tag_qng;
14149 asc_dvc->cfg->sdtr_period_offset[i] =
14150 (uchar) (ASC_DEF_SDTR_OFFSET |
14151 (asc_dvc->host_init_sdtr_index << 4));
14153 eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
14154 if (write_eep) {
14155 (void) AscSetEEPConfig(iop_base, eep_config, asc_dvc->bus_type);
14157 return (warn_code);
14160 ASC_INITFUNC(
14161 STATIC ushort,
14162 AscInitMicroCodeVar(
14163 ASC_DVC_VAR *asc_dvc
14167 int i;
14168 ushort warn_code;
14169 PortAddr iop_base;
14170 ASC_PADDR phy_addr;
14172 iop_base = asc_dvc->iop_base;
14173 warn_code = 0;
14174 for (i = 0; i <= ASC_MAX_TID; i++) {
14175 AscPutMCodeInitSDTRAtID(iop_base, i,
14176 asc_dvc->cfg->sdtr_period_offset[i]
14179 AscInitQLinkVar(asc_dvc);
14180 AscWriteLramByte(iop_base, ASCV_DISC_ENABLE_B,
14181 asc_dvc->cfg->disc_enable);
14182 AscWriteLramByte(iop_base, ASCV_HOSTSCSI_ID_B,
14183 ASC_TID_TO_TARGET_ID(asc_dvc->cfg->chip_scsi_id));
14184 if ((phy_addr = AscGetOnePhyAddr(asc_dvc,
14185 (uchar *) asc_dvc->cfg->overrun_buf,
14186 ASC_OVERRUN_BSIZE)) == 0L) {
14187 asc_dvc->err_code |= ASC_IERR_GET_PHY_ADDR;
14188 } else {
14189 /* Align on an 8 byte boundary. */
14190 phy_addr = cpu_to_le32((phy_addr + 7) & ~0x7);
14191 AscWriteLramDWord(iop_base, ASCV_OVERRUN_PADDR_D, phy_addr);
14192 AscWriteLramDWord(iop_base, ASCV_OVERRUN_BSIZE_D,
14193 ASC_OVERRUN_BSIZE - 8);
14195 asc_dvc->cfg->mcode_date = AscReadLramWord(iop_base,
14196 (ushort) ASCV_MC_DATE_W);
14197 asc_dvc->cfg->mcode_version = AscReadLramWord(iop_base,
14198 (ushort) ASCV_MC_VER_W);
14199 AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
14200 if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
14201 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
14202 return (warn_code);
14204 if (AscStartChip(iop_base) != 1) {
14205 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
14206 return (warn_code);
14208 return (warn_code);
14211 ASC_INITFUNC(
14212 STATIC int,
14213 AscTestExternalLram(
14214 ASC_DVC_VAR *asc_dvc
14218 PortAddr iop_base;
14219 ushort q_addr;
14220 ushort saved_word;
14221 int sta;
14223 iop_base = asc_dvc->iop_base;
14224 sta = 0;
14225 q_addr = ASC_QNO_TO_QADDR(241);
14226 saved_word = AscReadLramWord(iop_base, q_addr);
14227 AscSetChipLramAddr(iop_base, q_addr);
14228 AscSetChipLramData(iop_base, 0x55AA);
14229 DvcSleepMilliSecond(10);
14230 AscSetChipLramAddr(iop_base, q_addr);
14231 if (AscGetChipLramData(iop_base) == 0x55AA) {
14232 sta = 1;
14233 AscWriteLramWord(iop_base, q_addr, saved_word);
14235 return (sta);
14238 ASC_INITFUNC(
14239 STATIC int,
14240 AscWriteEEPCmdReg(
14241 PortAddr iop_base,
14242 uchar cmd_reg
14246 uchar read_back;
14247 int retry;
14249 retry = 0;
14250 while (TRUE) {
14251 AscSetChipEEPCmd(iop_base, cmd_reg);
14252 DvcSleepMilliSecond(1);
14253 read_back = AscGetChipEEPCmd(iop_base);
14254 if (read_back == cmd_reg) {
14255 return (1);
14257 if (retry++ > ASC_EEP_MAX_RETRY) {
14258 return (0);
14263 ASC_INITFUNC(
14264 STATIC int,
14265 AscWriteEEPDataReg(
14266 PortAddr iop_base,
14267 ushort data_reg
14271 ushort read_back;
14272 int retry;
14274 retry = 0;
14275 while (TRUE) {
14276 AscSetChipEEPData(iop_base, data_reg);
14277 DvcSleepMilliSecond(1);
14278 read_back = AscGetChipEEPData(iop_base);
14279 if (read_back == data_reg) {
14280 return (1);
14282 if (retry++ > ASC_EEP_MAX_RETRY) {
14283 return (0);
14288 ASC_INITFUNC(
14289 STATIC void,
14290 AscWaitEEPRead(
14291 void
14295 DvcSleepMilliSecond(1);
14296 return;
14299 ASC_INITFUNC(
14300 STATIC void,
14301 AscWaitEEPWrite(
14302 void
14306 DvcSleepMilliSecond(20);
14307 return;
14310 ASC_INITFUNC(
14311 STATIC ushort,
14312 AscReadEEPWord(
14313 PortAddr iop_base,
14314 uchar addr
14318 ushort read_wval;
14319 uchar cmd_reg;
14321 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
14322 AscWaitEEPRead();
14323 cmd_reg = addr | ASC_EEP_CMD_READ;
14324 AscWriteEEPCmdReg(iop_base, cmd_reg);
14325 AscWaitEEPRead();
14326 read_wval = AscGetChipEEPData(iop_base);
14327 AscWaitEEPRead();
14328 return (read_wval);
14331 ASC_INITFUNC(
14332 STATIC ushort,
14333 AscWriteEEPWord(
14334 PortAddr iop_base,
14335 uchar addr,
14336 ushort word_val
14340 ushort read_wval;
14342 read_wval = AscReadEEPWord(iop_base, addr);
14343 if (read_wval != word_val) {
14344 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_ABLE);
14345 AscWaitEEPRead();
14346 AscWriteEEPDataReg(iop_base, word_val);
14347 AscWaitEEPRead();
14348 AscWriteEEPCmdReg(iop_base,
14349 (uchar) ((uchar) ASC_EEP_CMD_WRITE | addr));
14350 AscWaitEEPWrite();
14351 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
14352 AscWaitEEPRead();
14353 return (AscReadEEPWord(iop_base, addr));
14355 return (read_wval);
14358 ASC_INITFUNC(
14359 STATIC ushort,
14360 AscGetEEPConfig(
14361 PortAddr iop_base,
14362 ASCEEP_CONFIG * cfg_buf, ushort bus_type
14366 ushort wval;
14367 ushort sum;
14368 ushort *wbuf;
14369 int cfg_beg;
14370 int cfg_end;
14371 int s_addr;
14372 int isa_pnp_wsize;
14374 wbuf = (ushort *) cfg_buf;
14375 sum = 0;
14376 isa_pnp_wsize = 0;
14377 for (s_addr = 0; s_addr < (2 + isa_pnp_wsize); s_addr++, wbuf++) {
14378 wval = AscReadEEPWord(iop_base, (uchar) s_addr);
14379 sum += wval;
14380 *wbuf = wval;
14382 if (bus_type & ASC_IS_VL) {
14383 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
14384 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
14385 } else {
14386 cfg_beg = ASC_EEP_DVC_CFG_BEG;
14387 cfg_end = ASC_EEP_MAX_DVC_ADDR;
14389 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1);
14390 s_addr++, wbuf++) {
14391 wval = AscReadEEPWord(iop_base, (uchar) s_addr);
14392 sum += wval;
14393 *wbuf = wval;
14395 *wbuf = AscReadEEPWord(iop_base, (uchar) s_addr);
14396 return (sum);
14399 ASC_INITFUNC(
14400 STATIC int,
14401 AscSetEEPConfigOnce(
14402 PortAddr iop_base,
14403 ASCEEP_CONFIG * cfg_buf, ushort bus_type
14407 int n_error;
14408 ushort *wbuf;
14409 ushort sum;
14410 int s_addr;
14411 int cfg_beg;
14412 int cfg_end;
14414 wbuf = (ushort *) cfg_buf;
14415 n_error = 0;
14416 sum = 0;
14417 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
14418 sum += *wbuf;
14419 if (*wbuf != AscWriteEEPWord(iop_base, (uchar) s_addr, *wbuf)) {
14420 n_error++;
14423 if (bus_type & ASC_IS_VL) {
14424 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
14425 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
14426 } else {
14427 cfg_beg = ASC_EEP_DVC_CFG_BEG;
14428 cfg_end = ASC_EEP_MAX_DVC_ADDR;
14430 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1);
14431 s_addr++, wbuf++) {
14432 sum += *wbuf;
14433 if (*wbuf != AscWriteEEPWord(iop_base, (uchar) s_addr, *wbuf)) {
14434 n_error++;
14437 *wbuf = sum;
14438 if (sum != AscWriteEEPWord(iop_base, (uchar) s_addr, sum)) {
14439 n_error++;
14441 wbuf = (ushort *) cfg_buf;
14442 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
14443 if (*wbuf != AscReadEEPWord(iop_base, (uchar) s_addr)) {
14444 n_error++;
14447 for (s_addr = cfg_beg; s_addr <= cfg_end;
14448 s_addr++, wbuf++) {
14449 if (*wbuf != AscReadEEPWord(iop_base, (uchar) s_addr)) {
14450 n_error++;
14453 return (n_error);
14456 ASC_INITFUNC(
14457 STATIC int,
14458 AscSetEEPConfig(
14459 PortAddr iop_base,
14460 ASCEEP_CONFIG * cfg_buf, ushort bus_type
14464 int retry;
14465 int n_error;
14467 retry = 0;
14468 while (TRUE) {
14469 if ((n_error = AscSetEEPConfigOnce(iop_base, cfg_buf,
14470 bus_type)) == 0) {
14471 break;
14473 if (++retry > ASC_EEP_MAX_RETRY) {
14474 break;
14477 return (n_error);
14480 STATIC void
14481 AscAsyncFix(
14482 ASC_DVC_VAR *asc_dvc,
14483 uchar tid_no,
14484 ASC_SCSI_INQUIRY *inq)
14486 uchar dvc_type;
14487 ASC_SCSI_BIT_ID_TYPE tid_bits;
14489 dvc_type = inq->byte0.peri_dvc_type;
14490 tid_bits = ASC_TIX_TO_TARGET_ID(tid_no);
14492 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ASYN_USE_SYN)
14494 if (!(asc_dvc->init_sdtr & tid_bits))
14496 if ((dvc_type == SCSI_TYPE_CDROM) &&
14497 (AscCompareString((uchar *) inq->vendor_id,
14498 (uchar *) "HP ", 3) == 0))
14500 asc_dvc->pci_fix_asyn_xfer_always |= tid_bits;
14502 asc_dvc->pci_fix_asyn_xfer |= tid_bits;
14503 if ((dvc_type == SCSI_TYPE_PROC) ||
14504 (dvc_type == SCSI_TYPE_SCANNER) ||
14505 (dvc_type == SCSI_TYPE_CDROM) ||
14506 (dvc_type == SCSI_TYPE_SASD))
14508 asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
14511 if (asc_dvc->pci_fix_asyn_xfer & tid_bits)
14513 AscSetRunChipSynRegAtID(asc_dvc->iop_base, tid_no,
14514 ASYN_SDTR_DATA_FIX_PCI_REV_AB);
14518 return;
14521 STATIC int
14522 AscTagQueuingSafe(ASC_SCSI_INQUIRY *inq)
14524 if ((inq->add_len >= 32) &&
14525 (AscCompareString((uchar *) inq->vendor_id,
14526 (uchar *) "QUANTUM XP34301", 15) == 0) &&
14527 (AscCompareString((uchar *) inq->product_rev_level,
14528 (uchar *) "1071", 4) == 0))
14530 return 0;
14532 return 1;
14535 STATIC void
14536 AscInquiryHandling(ASC_DVC_VAR *asc_dvc,
14537 uchar tid_no, ASC_SCSI_INQUIRY *inq)
14539 ASC_SCSI_BIT_ID_TYPE tid_bit = ASC_TIX_TO_TARGET_ID(tid_no);
14540 ASC_SCSI_BIT_ID_TYPE orig_init_sdtr, orig_use_tagged_qng;
14542 orig_init_sdtr = asc_dvc->init_sdtr;
14543 orig_use_tagged_qng = asc_dvc->use_tagged_qng;
14545 asc_dvc->init_sdtr &= ~tid_bit;
14546 asc_dvc->cfg->can_tagged_qng &= ~tid_bit;
14547 asc_dvc->use_tagged_qng &= ~tid_bit;
14549 if (inq->byte3.rsp_data_fmt >= 2 || inq->byte2.ansi_apr_ver >= 2) {
14550 if ((asc_dvc->cfg->sdtr_enable & tid_bit) && inq->byte7.Sync) {
14551 asc_dvc->init_sdtr |= tid_bit;
14553 if ((asc_dvc->cfg->cmd_qng_enabled & tid_bit) && inq->byte7.CmdQue) {
14554 if (AscTagQueuingSafe(inq)) {
14555 asc_dvc->use_tagged_qng |= tid_bit;
14556 asc_dvc->cfg->can_tagged_qng |= tid_bit;
14560 if (orig_use_tagged_qng != asc_dvc->use_tagged_qng) {
14561 AscWriteLramByte(asc_dvc->iop_base, ASCV_DISC_ENABLE_B,
14562 asc_dvc->cfg->disc_enable);
14563 AscWriteLramByte(asc_dvc->iop_base, ASCV_USE_TAGGED_QNG_B,
14564 asc_dvc->use_tagged_qng);
14565 AscWriteLramByte(asc_dvc->iop_base, ASCV_CAN_TAGGED_QNG_B,
14566 asc_dvc->cfg->can_tagged_qng);
14568 asc_dvc->max_dvc_qng[tid_no] =
14569 asc_dvc->cfg->max_tag_qng[tid_no];
14570 AscWriteLramByte(asc_dvc->iop_base,
14571 (ushort) (ASCV_MAX_DVC_QNG_BEG + tid_no),
14572 asc_dvc->max_dvc_qng[tid_no]);
14574 if (orig_init_sdtr != asc_dvc->init_sdtr) {
14575 AscAsyncFix(asc_dvc, tid_no, inq);
14577 return;
14580 STATIC int
14581 AscCompareString(
14582 uchar *str1,
14583 uchar *str2,
14584 int len
14587 int i;
14588 int diff;
14590 for (i = 0; i < len; i++) {
14591 diff = (int) (str1[i] - str2[i]);
14592 if (diff != 0)
14593 return (diff);
14595 return (0);
14598 STATIC uchar
14599 AscReadLramByte(
14600 PortAddr iop_base,
14601 ushort addr
14604 uchar byte_data;
14605 ushort word_data;
14607 if (isodd_word(addr)) {
14608 AscSetChipLramAddr(iop_base, addr - 1);
14609 word_data = AscGetChipLramData(iop_base);
14610 byte_data = (uchar) ((word_data >> 8) & 0xFF);
14611 } else {
14612 AscSetChipLramAddr(iop_base, addr);
14613 word_data = AscGetChipLramData(iop_base);
14614 byte_data = (uchar) (word_data & 0xFF);
14616 return (byte_data);
14619 STATIC ushort
14620 AscReadLramWord(
14621 PortAddr iop_base,
14622 ushort addr
14625 ushort word_data;
14627 AscSetChipLramAddr(iop_base, addr);
14628 word_data = AscGetChipLramData(iop_base);
14629 return (word_data);
14632 STATIC ASC_DCNT
14633 AscReadLramDWord(
14634 PortAddr iop_base,
14635 ushort addr
14638 ushort val_low, val_high;
14639 ASC_DCNT dword_data;
14641 AscSetChipLramAddr(iop_base, addr);
14642 val_low = AscGetChipLramData(iop_base);
14643 val_high = AscGetChipLramData(iop_base);
14644 dword_data = ((ASC_DCNT) val_high << 16) | (ASC_DCNT) val_low;
14645 return (dword_data);
14648 STATIC void
14649 AscWriteLramWord(
14650 PortAddr iop_base,
14651 ushort addr,
14652 ushort word_val
14655 AscSetChipLramAddr(iop_base, addr);
14656 AscSetChipLramData(iop_base, word_val);
14657 return;
14660 STATIC void
14661 AscWriteLramDWord(
14662 PortAddr iop_base,
14663 ushort addr,
14664 ASC_DCNT dword_val
14667 ushort word_val;
14669 AscSetChipLramAddr(iop_base, addr);
14670 word_val = (ushort) dword_val;
14671 AscSetChipLramData(iop_base, word_val);
14672 word_val = (ushort) (dword_val >> 16);
14673 AscSetChipLramData(iop_base, word_val);
14674 return;
14677 STATIC void
14678 AscWriteLramByte(
14679 PortAddr iop_base,
14680 ushort addr,
14681 uchar byte_val
14684 ushort word_data;
14686 if (isodd_word(addr)) {
14687 addr--;
14688 word_data = AscReadLramWord(iop_base, addr);
14689 word_data &= 0x00FF;
14690 word_data |= (((ushort) byte_val << 8) & 0xFF00);
14691 } else {
14692 word_data = AscReadLramWord(iop_base, addr);
14693 word_data &= 0xFF00;
14694 word_data |= ((ushort) byte_val & 0x00FF);
14696 AscWriteLramWord(iop_base, addr, word_data);
14697 return;
14700 STATIC void
14701 AscMemWordCopyToLram(
14702 PortAddr iop_base,
14703 ushort s_addr,
14704 ushort * s_buffer,
14705 int words
14708 AscSetChipLramAddr(iop_base, s_addr);
14709 DvcOutPortWords(iop_base + IOP_RAM_DATA, s_buffer, words);
14710 return;
14713 STATIC void
14714 AscMemDWordCopyToLram(
14715 PortAddr iop_base,
14716 ushort s_addr,
14717 ASC_DCNT *s_buffer,
14718 int dwords
14721 AscSetChipLramAddr(iop_base, s_addr);
14722 DvcOutPortDWords(iop_base + IOP_RAM_DATA, s_buffer, dwords);
14723 return;
14726 STATIC void
14727 AscMemWordCopyFromLram(
14728 PortAddr iop_base,
14729 ushort s_addr,
14730 ushort * d_buffer,
14731 int words
14734 AscSetChipLramAddr(iop_base, s_addr);
14735 DvcInPortWords(iop_base + IOP_RAM_DATA, d_buffer, words);
14736 return;
14739 STATIC ASC_DCNT
14740 AscMemSumLramWord(
14741 PortAddr iop_base,
14742 ushort s_addr,
14743 int words
14746 ASC_DCNT sum;
14747 int i;
14749 sum = 0L;
14750 for (i = 0; i < words; i++, s_addr += 2) {
14751 sum += AscReadLramWord(iop_base, s_addr);
14753 return (sum);
14756 STATIC void
14757 AscMemWordSetLram(
14758 PortAddr iop_base,
14759 ushort s_addr,
14760 ushort set_wval,
14761 int words
14764 int i;
14766 AscSetChipLramAddr(iop_base, s_addr);
14767 for (i = 0; i < words; i++) {
14768 AscSetChipLramData(iop_base, set_wval);
14770 return;
14775 * --- Adv Library Functions
14778 /* a_mcode.h */
14779 STATIC unsigned char _adv_asc3550_buf[] = {
14780 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0x16, 0x00, 0xfc, 0x48, 0xe4, 0x01, 0x00, 0x18, 0xe4,
14781 0x00, 0xf6, 0x01, 0xf6, 0x18, 0x80, 0x48, 0x19, 0x02, 0x00, 0xff, 0xff, 0x03, 0xf6, 0x00, 0xfa,
14782 0xff, 0x00, 0x82, 0xe7, 0x01, 0xfa, 0x9e, 0xe7, 0x09, 0xe7, 0x3a, 0x0e, 0x00, 0xea, 0x01, 0xe6,
14783 0x55, 0xf0, 0x03, 0x00, 0x08, 0x00, 0x18, 0xf4, 0x3e, 0x01, 0x3e, 0x57, 0x04, 0x00, 0x85, 0xf0,
14784 0x00, 0xe6, 0x00, 0xec, 0x1e, 0xf0, 0x32, 0xf0, 0x34, 0x19, 0x86, 0xf0, 0xd0, 0x01, 0xd5, 0xf0,
14785 0xde, 0x0c, 0x98, 0x57, 0xbc, 0x00, 0x0c, 0x1c, 0x0e, 0x13, 0x38, 0x54, 0xb1, 0xf0, 0xb4, 0x00,
14786 0x01, 0xfc, 0x03, 0xfc, 0xd8, 0x0c, 0x00, 0x57, 0x01, 0xf0, 0x02, 0x13, 0x03, 0xe6, 0x10, 0x00,
14787 0x18, 0x40, 0x3e, 0x1c, 0x6c, 0x01, 0x6e, 0x01, 0xbd, 0x00, 0xe0, 0x00, 0x02, 0x48, 0x02, 0x80,
14788 0x08, 0x12, 0x30, 0xe4, 0x3c, 0x00, 0x4e, 0x01, 0x64, 0x12, 0x80, 0x00, 0x9c, 0x15, 0xbb, 0x00,
14789 0x00, 0x4e, 0x01, 0x01, 0x01, 0xea, 0x04, 0x12, 0x9e, 0x0f, 0xb6, 0x00, 0xb9, 0x54, 0xe2, 0x0f,
14790 0x00, 0x80, 0x06, 0xf7, 0x10, 0x44, 0x24, 0x01, 0x28, 0x01, 0x32, 0x00, 0x3c, 0x01, 0x3c, 0x56,
14791 0x3e, 0x00, 0x4b, 0xe4, 0x4c, 0x1c, 0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01, 0x74, 0x01,
14792 0x76, 0x01, 0x78, 0x01, 0xe2, 0x0c, 0x00, 0x01, 0x02, 0xee, 0x02, 0xfc, 0x03, 0x58, 0x03, 0xf7,
14793 0x04, 0x80, 0x05, 0xfc, 0x08, 0x44, 0x09, 0xf0, 0x0f, 0x00, 0x1b, 0x80, 0x20, 0x01, 0x38, 0x1c,
14794 0x40, 0x00, 0x40, 0x15, 0x4b, 0xf4, 0x4e, 0x1c, 0x5b, 0xf0, 0x5d, 0xf0, 0xaa, 0x00, 0xbb, 0x55,
14795 0xbe, 0x00, 0xc0, 0x00, 0xe0, 0x08, 0xe0, 0x14, 0xec, 0x0f, 0x00, 0x4c, 0x00, 0xdc, 0x02, 0x4a,
14796 0x05, 0x00, 0x05, 0xf0, 0x05, 0xf8, 0x06, 0x13, 0x08, 0x13, 0x0c, 0x00, 0x0e, 0x47, 0x0e, 0xf7,
14797 0x19, 0x00, 0x20, 0x00, 0x2a, 0x01, 0x30, 0x0e, 0x32, 0x1c, 0x36, 0x00, 0x45, 0x5a, 0x59, 0xf0,
14798 0x62, 0x0a, 0x69, 0x08, 0x72, 0x0b, 0x83, 0x59, 0xb8, 0xf0, 0xbd, 0x56, 0xcc, 0x12, 0xec, 0x17,
14799 0xee, 0x0f, 0xf0, 0x00, 0xf8, 0x17, 0x01, 0x48, 0x02, 0xfa, 0x03, 0xfa, 0x04, 0x10, 0x04, 0xea,
14800 0x04, 0xf6, 0x04, 0xfc, 0x05, 0x80, 0x05, 0xe6, 0x06, 0x00, 0x06, 0x12, 0x0a, 0x10, 0x0b, 0xf0,
14801 0x0c, 0x10, 0x0c, 0xf0, 0x12, 0x10, 0x26, 0x0e, 0x30, 0x1c, 0x33, 0x00, 0x34, 0x00, 0x38, 0x44,
14802 0x40, 0x5c, 0x4a, 0xe4, 0x62, 0x1a, 0x68, 0x08, 0x68, 0x54, 0x83, 0x55, 0x83, 0x5a, 0x8c, 0x14,
14803 0x8e, 0x0a, 0x90, 0x14, 0x91, 0x44, 0xa4, 0x00, 0xb0, 0x57, 0xb5, 0x00, 0xba, 0x00, 0xce, 0x45,
14804 0xd0, 0x00, 0xd8, 0x16, 0xe1, 0x00, 0xe7, 0x00, 0x00, 0x54, 0x01, 0x58, 0x02, 0x10, 0x02, 0xe6,
14805 0x03, 0xa1, 0x04, 0x13, 0x06, 0x83, 0x06, 0xf0, 0x07, 0x00, 0x0a, 0x00, 0x0a, 0x12, 0x0a, 0xf0,
14806 0x0c, 0x04, 0x0c, 0x12, 0x0c, 0x90, 0x10, 0x10, 0x10, 0x13, 0x12, 0x1c, 0x17, 0x00, 0x19, 0xe4,
14807 0x1a, 0x10, 0x1c, 0x00, 0x1c, 0x12, 0x1d, 0xf7, 0x1e, 0x13, 0x20, 0x1c, 0x20, 0xe7, 0x22, 0x01,
14808 0x26, 0x01, 0x2a, 0x12, 0x30, 0xe7, 0x34, 0x1c, 0x36, 0x1c, 0x38, 0x12, 0x41, 0x58, 0x43, 0x48,
14809 0x44, 0x55, 0x46, 0x1c, 0x4c, 0x0e, 0x4e, 0xe4, 0x52, 0x14, 0x5c, 0xf0, 0x72, 0x02, 0x74, 0x03,
14810 0x77, 0x57, 0x89, 0x48, 0x8e, 0x90, 0x99, 0x00, 0x9b, 0x00, 0x9c, 0x32, 0x9e, 0x00, 0xa8, 0x00,
14811 0xb9, 0x00, 0xba, 0x06, 0xbc, 0x12, 0xbf, 0x57, 0xc0, 0x01, 0xfe, 0x9c, 0xf0, 0x26, 0x02, 0xfe,
14812 0x00, 0x0d, 0xff, 0x10, 0x00, 0x00, 0xfe, 0xc2, 0x01, 0xfe, 0x56, 0x19, 0x00, 0xfc, 0xfe, 0x80,
14813 0x01, 0xff, 0x03, 0x00, 0x00, 0xfe, 0x6a, 0x13, 0xfe, 0x05, 0x05, 0xff, 0x40, 0x00, 0x00, 0x0d,
14814 0xff, 0x09, 0x00, 0x00, 0xff, 0x08, 0x01, 0x01, 0xff, 0x10, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00,
14815 0xff, 0x10, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21,
14816 0x00, 0x00, 0xfe, 0x04, 0xf7, 0xfc, 0x2b, 0x51, 0x0c, 0x01, 0xfe, 0xea, 0x0e, 0xfe, 0x04, 0xf7,
14817 0xfc, 0x51, 0x0c, 0x1d, 0x2b, 0xfe, 0x3d, 0xf0, 0xfe, 0xf8, 0x01, 0xfe, 0x20, 0xf0, 0xd0, 0x04,
14818 0x56, 0x4b, 0x02, 0xfe, 0x1c, 0x0d, 0x01, 0xfe, 0x7c, 0x0d, 0xfe, 0xe9, 0x12, 0x02, 0xfe, 0x04,
14819 0x03, 0xfe, 0x28, 0x1c, 0x04, 0xfe, 0xa6, 0x00, 0xfe, 0xdd, 0x12, 0x4e, 0x12, 0xfe, 0xa6, 0x00,
14820 0xc5, 0xfe, 0x48, 0xf0, 0xfe, 0x7c, 0x02, 0xfe, 0x49, 0xf0, 0xfe, 0x96, 0x02, 0xfe, 0x4a, 0xf0,
14821 0xfe, 0xb4, 0x02, 0xfe, 0x46, 0xf0, 0xfe, 0x46, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x4c, 0x02, 0xfe,
14822 0x43, 0xf0, 0xfe, 0x3a, 0x02, 0xfe, 0x44, 0xf0, 0xfe, 0x3e, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x42,
14823 0x02, 0x09, 0x0c, 0x9e, 0x09, 0x06, 0x12, 0xbb, 0x02, 0x26, 0xfe, 0x00, 0x1c, 0xfe, 0xf1, 0x10,
14824 0xfe, 0x02, 0x1c, 0xfe, 0xed, 0x10, 0xfe, 0x1e, 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0xfe, 0x4c, 0x17,
14825 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc, 0xf7, 0x0e, 0x78, 0x01, 0xab, 0x02, 0x26, 0x17, 0x55, 0x4a,
14826 0xbd, 0x01, 0xfe, 0x60, 0x0f, 0x0e, 0x78, 0x01, 0x8b, 0xfe, 0xbd, 0x10, 0x0e, 0x78, 0x01, 0x8b,
14827 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe, 0x58, 0x1c, 0x09, 0x06, 0x12, 0xbb, 0x2b, 0x22, 0x26,
14828 0xfe, 0x3d, 0xf0, 0xfe, 0xf8, 0x01, 0x27, 0xfe, 0x8a, 0x02, 0xfe, 0x5a, 0x1c, 0xd5, 0xfe, 0x14,
14829 0x1c, 0x17, 0xfe, 0x30, 0x00, 0x4a, 0xbd, 0x01, 0xfe, 0x50, 0x0f, 0x09, 0x06, 0x12, 0xbb, 0x02,
14830 0xfe, 0xc2, 0x01, 0x21, 0x2a, 0x05, 0x10, 0x35, 0xfe, 0x69, 0x10, 0x09, 0x06, 0x12, 0xbb, 0xfe,
14831 0x04, 0xec, 0x2a, 0x08, 0x2a, 0x09, 0x3c, 0x1d, 0x01, 0x46, 0x7f, 0xfe, 0x05, 0xf6, 0xf7, 0x01,
14832 0xfe, 0x76, 0x16, 0x0a, 0x41, 0x89, 0x38, 0x11, 0x47, 0x1d, 0xca, 0x08, 0x1c, 0x09, 0x43, 0x01,
14833 0x71, 0x02, 0x26, 0x0e, 0x3d, 0x01, 0x15, 0x05, 0x10, 0x2c, 0x08, 0x1c, 0x09, 0x43, 0x01, 0x7b,
14834 0xfe, 0x28, 0x10, 0x0e, 0xc0, 0x01, 0x15, 0xe6, 0x0e, 0x79, 0x01, 0x15, 0xfe, 0x49, 0x54, 0x74,
14835 0xfe, 0x12, 0x03, 0x08, 0x1c, 0x09, 0x43, 0x01, 0x71, 0x02, 0x26, 0x2b, 0x7f, 0xfe, 0x02, 0xe8,
14836 0x2f, 0xfb, 0xfe, 0x9e, 0x43, 0xf0, 0xfe, 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xd0, 0xfe, 0x40, 0x1c,
14837 0x22, 0xef, 0xfe, 0x26, 0xf0, 0xfe, 0x70, 0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x5e, 0x03, 0xfe, 0x11,
14838 0xf0, 0xd0, 0xfe, 0x0e, 0x10, 0xfe, 0x9f, 0xf0, 0xfe, 0x7e, 0x03, 0xe9, 0x13, 0xfe, 0x11, 0x00,
14839 0x02, 0x62, 0x2b, 0xfe, 0x48, 0x1c, 0xe9, 0x22, 0xef, 0x34, 0xef, 0xfe, 0x82, 0xf0, 0xfe, 0x84,
14840 0x03, 0x2d, 0x21, 0xbe, 0x6a, 0x16, 0xbe, 0x0e, 0x79, 0x01, 0x15, 0x6a, 0x7d, 0x08, 0x1c, 0x09,
14841 0x43, 0x01, 0x46, 0x11, 0x3d, 0x08, 0x3d, 0x09, 0x99, 0x01, 0x71, 0xf5, 0x11, 0xfe, 0xe4, 0x00,
14842 0x2e, 0xfe, 0xca, 0x03, 0x22, 0x32, 0x1f, 0xfe, 0xda, 0x03, 0x01, 0x4c, 0xcb, 0xfe, 0xea, 0x03,
14843 0x6b, 0x92, 0xcf, 0xfe, 0xaa, 0x06, 0x02, 0x28, 0x04, 0x78, 0x29, 0x18, 0xfe, 0x1c, 0x05, 0x17,
14844 0x85, 0x01, 0x44, 0x01, 0x97, 0x01, 0x9a, 0x34, 0xfe, 0x5c, 0x02, 0x02, 0xee, 0xe9, 0x2b, 0x51,
14845 0x19, 0xfe, 0x67, 0x1b, 0xfb, 0xf0, 0xfe, 0x48, 0x1c, 0x8c, 0x01, 0xfa, 0xac, 0xfe, 0x96, 0xf0,
14846 0xfe, 0x24, 0x04, 0x2e, 0xfe, 0x28, 0x04, 0x34, 0x26, 0x0e, 0x3d, 0x01, 0x15, 0x05, 0x10, 0x18,
14847 0xfe, 0x08, 0x05, 0x3e, 0x90, 0x9f, 0x2f, 0x82, 0x6e, 0x22, 0x32, 0x1f, 0x28, 0x04, 0x78, 0x29,
14848 0xfe, 0x10, 0x12, 0x17, 0x85, 0x01, 0x44, 0x34, 0xfe, 0x5c, 0x02, 0x02, 0xee, 0x31, 0xfe, 0xa0,
14849 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x5e, 0x12, 0x0a, 0x07, 0x06, 0xfe, 0x56, 0x12, 0x23, 0x24, 0x91,
14850 0x01, 0x0b, 0x82, 0x6e, 0x1f, 0xfe, 0xd8, 0x04, 0x23, 0x24, 0x91, 0x01, 0x0b, 0x1f, 0x28, 0x23,
14851 0x24, 0xb3, 0xfe, 0x4c, 0x44, 0xfe, 0x32, 0x12, 0x57, 0xfe, 0x44, 0x48, 0x08, 0xd6, 0xfe, 0x4c,
14852 0x54, 0x74, 0xfe, 0x08, 0x05, 0x7f, 0x9f, 0x2f, 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x48,
14853 0x13, 0x3f, 0x05, 0xfe, 0xcc, 0x00, 0xfe, 0x40, 0x13, 0x0a, 0x07, 0x06, 0xe5, 0xfe, 0x06, 0x10,
14854 0x23, 0x24, 0xb3, 0x0a, 0x07, 0x37, 0xda, 0x17, 0xa4, 0x0a, 0x07, 0x06, 0x4b, 0x17, 0xfe, 0x0d,
14855 0x00, 0x01, 0x44, 0x34, 0xfe, 0xc0, 0x0c, 0x02, 0x28, 0x39, 0x11, 0xfe, 0xe6, 0x00, 0xfe, 0x1c,
14856 0x90, 0xb0, 0x03, 0x17, 0xa4, 0x01, 0x44, 0x34, 0x26, 0x22, 0x26, 0x02, 0xfe, 0x10, 0x05, 0xfe,
14857 0x42, 0x5b, 0x51, 0x19, 0xfe, 0x46, 0x59, 0xfb, 0xf0, 0x17, 0x45, 0xfe, 0x07, 0x80, 0xfe, 0x31,
14858 0x44, 0x0a, 0x07, 0x0c, 0xfe, 0x78, 0x13, 0xfe, 0x20, 0x80, 0x05, 0x19, 0xfe, 0x70, 0x12, 0x6d,
14859 0x07, 0x06, 0xfe, 0x60, 0x13, 0x04, 0xfe, 0xa2, 0x00, 0x29, 0x18, 0xfe, 0xa8, 0x05, 0xfe, 0x31,
14860 0xe4, 0x70, 0x6d, 0x07, 0x0c, 0xfe, 0x4a, 0x13, 0x04, 0xfe, 0xa0, 0x00, 0x29, 0xfe, 0x42, 0x12,
14861 0x5a, 0x2e, 0xfe, 0x68, 0x05, 0x22, 0x32, 0xf1, 0x01, 0x0b, 0x25, 0xfe, 0xc0, 0x05, 0x11, 0xfe,
14862 0xe3, 0x00, 0x2d, 0x6d, 0xfe, 0x4a, 0xf0, 0xfe, 0x92, 0x05, 0xfe, 0x49, 0xf0, 0xfe, 0x8c, 0x05,
14863 0xa8, 0x20, 0xfe, 0x21, 0x00, 0xa6, 0x20, 0xfe, 0x22, 0x00, 0x9e, 0x20, 0x89, 0xfe, 0x09, 0x48,
14864 0x01, 0x0b, 0x25, 0xfe, 0xc0, 0x05, 0xfe, 0xe2, 0x08, 0x6d, 0x07, 0xd9, 0x4b, 0x01, 0x96, 0x20,
14865 0x06, 0x16, 0xe0, 0x4a, 0xfe, 0x27, 0x01, 0x0a, 0x07, 0x37, 0xe1, 0x4e, 0x01, 0xb9, 0x17, 0xa4,
14866 0x0a, 0x07, 0x06, 0x4b, 0x17, 0xfe, 0x0d, 0x00, 0x01, 0x44, 0x01, 0x97, 0x01, 0x9a, 0x34, 0xfe,
14867 0xc0, 0x0c, 0x02, 0x28, 0x04, 0xfe, 0x9c, 0x00, 0x29, 0xfe, 0x3e, 0x12, 0x04, 0x53, 0x29, 0xfe,
14868 0x36, 0x13, 0x4e, 0x01, 0xb9, 0x25, 0xfe, 0x38, 0x06, 0x0e, 0x06, 0x6d, 0x07, 0x1a, 0xfe, 0x02,
14869 0x12, 0x77, 0x01, 0xfe, 0x26, 0x14, 0x1f, 0xfe, 0x2e, 0x06, 0x11, 0xc2, 0x01, 0x4c, 0x11, 0xfe,
14870 0xe5, 0x00, 0x04, 0x53, 0xbc, 0x0f, 0x53, 0x04, 0xf6, 0x29, 0xfe, 0x62, 0x12, 0x04, 0x4d, 0x29,
14871 0xfe, 0x5a, 0x13, 0x01, 0xfe, 0x9e, 0x18, 0x01, 0xfe, 0xf0, 0x18, 0xe7, 0xa3, 0x1a, 0x08, 0x63,
14872 0xff, 0x02, 0x00, 0x57, 0x66, 0x7e, 0x1b, 0x50, 0xc9, 0xa3, 0x6c, 0x4e, 0x01, 0xb9, 0x25, 0xfe,
14873 0xa2, 0x06, 0x6d, 0x07, 0x1e, 0xa5, 0x95, 0x0e, 0x55, 0x01, 0xfe, 0x54, 0x14, 0x1f, 0xfe, 0x98,
14874 0x06, 0x11, 0xc2, 0x01, 0x4c, 0x11, 0xfe, 0xe5, 0x00, 0x04, 0x4d, 0xbc, 0x0f, 0x4d, 0x09, 0x06,
14875 0x01, 0xb9, 0xf5, 0x73, 0x8c, 0x01, 0xfa, 0xac, 0x11, 0xfe, 0xe2, 0x00, 0x2e, 0xf9, 0x22, 0x32,
14876 0xcf, 0xfe, 0xd6, 0x06, 0x81, 0xfe, 0x74, 0x07, 0xcb, 0xfe, 0x7c, 0x07, 0x6b, 0x92, 0x02, 0x28,
14877 0x0a, 0x07, 0x0c, 0xfe, 0x2e, 0x12, 0x14, 0x19, 0x01, 0x0b, 0x14, 0x00, 0x01, 0x0b, 0x14, 0x00,
14878 0x01, 0x0b, 0x14, 0x00, 0x01, 0x0b, 0xfe, 0x99, 0xa4, 0x01, 0x0b, 0x14, 0x00, 0x02, 0xfe, 0x4c,
14879 0x08, 0x68, 0x07, 0x1e, 0xe5, 0x0a, 0x07, 0x1e, 0xfe, 0x30, 0x13, 0x14, 0xfe, 0x1b, 0x00, 0x01,
14880 0x0b, 0x14, 0x00, 0x01, 0x0b, 0x14, 0x00, 0x01, 0x0b, 0x14, 0x00, 0x01, 0x0b, 0x14, 0x06, 0x01,
14881 0x0b, 0x14, 0x00, 0x02, 0xfe, 0x2a, 0x0b, 0x77, 0xfe, 0x9a, 0x81, 0x67, 0x89, 0xfe, 0x09, 0x6f,
14882 0xfe, 0x93, 0x45, 0x18, 0xfe, 0x84, 0x07, 0x2e, 0xfe, 0x5c, 0x07, 0x22, 0x32, 0xcf, 0xfe, 0x54,
14883 0x07, 0x6b, 0x92, 0x81, 0xfe, 0x74, 0x07, 0x02, 0x28, 0x01, 0x4c, 0x02, 0xf9, 0x14, 0x1a, 0x02,
14884 0xf9, 0xfe, 0x9c, 0xf7, 0xfe, 0xec, 0x07, 0xfe, 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x75, 0xfe, 0xd2,
14885 0x07, 0x0f, 0x5d, 0x12, 0x5e, 0x0a, 0x41, 0x70, 0x38, 0x01, 0xfe, 0x34, 0x18, 0x05, 0x10, 0x83,
14886 0xfe, 0x83, 0xe7, 0x88, 0xa6, 0xfe, 0x03, 0x40, 0x0a, 0x41, 0x45, 0x38, 0x01, 0xc1, 0xaf, 0xfe,
14887 0x1f, 0x40, 0x16, 0x61, 0x01, 0xfe, 0xde, 0x12, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe, 0x34,
14888 0x51, 0xfe, 0xb6, 0x51, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90, 0x0f, 0x5b, 0x12, 0x5c, 0xd2, 0xf2,
14889 0x0f, 0x3a, 0x12, 0x3b, 0xfe, 0x60, 0x10, 0x0a, 0x07, 0x70, 0xe1, 0xfe, 0x2c, 0x90, 0xfe, 0xae,
14890 0x90, 0x0f, 0x5d, 0x12, 0x5e, 0x0a, 0x07, 0x45, 0xc9, 0x01, 0xc1, 0xfe, 0x1f, 0x80, 0x16, 0x61,
14891 0xfe, 0x34, 0x90, 0xfe, 0xb6, 0x90, 0x0f, 0x5f, 0x12, 0x60, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90,
14892 0x0f, 0x5b, 0x12, 0x5c, 0xa2, 0x07, 0x45, 0x2c, 0xd2, 0xf2, 0x0f, 0x3a, 0x12, 0x3b, 0xa8, 0xfe,
14893 0x28, 0x90, 0xfe, 0xaa, 0x90, 0x0f, 0x3a, 0x12, 0x3b, 0x0f, 0x42, 0x12, 0x58, 0x0a, 0x41, 0x1a,
14894 0x38, 0x2b, 0x08, 0x80, 0x2e, 0xfe, 0x62, 0x08, 0xfe, 0x9e, 0xf0, 0xfe, 0x76, 0x08, 0x9b, 0x18,
14895 0x32, 0x2b, 0x52, 0xfe, 0xed, 0x10, 0xa7, 0xfe, 0x9a, 0x08, 0xa9, 0xfe, 0xb6, 0x08, 0x81, 0xfe,
14896 0x8e, 0x08, 0xcb, 0xfe, 0x94, 0x08, 0x6b, 0x92, 0x02, 0x28, 0x01, 0x4c, 0xfe, 0xc9, 0x10, 0x14,
14897 0x1a, 0xfe, 0xc9, 0x10, 0x68, 0x07, 0x06, 0xfe, 0x10, 0x12, 0x68, 0x07, 0x0c, 0x40, 0x0a, 0x07,
14898 0x0c, 0xfe, 0x7e, 0x12, 0xfe, 0x2e, 0x1c, 0xaa, 0x68, 0x07, 0x06, 0x40, 0x68, 0x07, 0x0c, 0xfe,
14899 0x6a, 0x12, 0xfe, 0x2c, 0x1c, 0xa2, 0x07, 0x45, 0xd4, 0xa2, 0x41, 0x45, 0xfe, 0x05, 0x40, 0xd2,
14900 0xf2, 0xfe, 0x28, 0x50, 0xfe, 0xaa, 0x50, 0xfe, 0xaa, 0xf0, 0xfe, 0x4e, 0x09, 0xfe, 0xac, 0xf0,
14901 0xfe, 0xee, 0x08, 0xfe, 0x92, 0x10, 0xe3, 0xfe, 0xf3, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0xfa, 0x08,
14902 0x02, 0xfe, 0x5c, 0x0a, 0xe4, 0xfe, 0xe7, 0x10, 0xfe, 0x2b, 0xf0, 0xb8, 0xfe, 0x6b, 0x18, 0x1b,
14903 0xfe, 0x00, 0xfe, 0xda, 0xc5, 0xfe, 0xd2, 0xf0, 0xb8, 0xfe, 0x76, 0x18, 0x1b, 0x19, 0x18, 0xb8,
14904 0x04, 0xdf, 0x1b, 0x06, 0x18, 0xb8, 0xa7, 0x7a, 0xa9, 0x7a, 0xe3, 0xe4, 0xfe, 0xb1, 0x10, 0x8c,
14905 0x5a, 0x39, 0x17, 0xa4, 0x01, 0x44, 0x13, 0xfe, 0x35, 0x00, 0x34, 0x62, 0x13, 0x8d, 0x02, 0x62,
14906 0xfe, 0x74, 0x18, 0x1b, 0xfe, 0x00, 0xf8, 0x18, 0x7a, 0x51, 0x1e, 0x01, 0xfe, 0x7c, 0x0d, 0xd1,
14907 0x08, 0x1c, 0x09, 0x43, 0x01, 0x71, 0x21, 0x2f, 0x3e, 0x51, 0x19, 0x02, 0x7a, 0xfe, 0x98, 0x80,
14908 0xd7, 0x0c, 0x27, 0xfe, 0x3e, 0x0a, 0x0a, 0x07, 0x70, 0xfe, 0x82, 0x12, 0x0a, 0x07, 0x1a, 0xfe,
14909 0x66, 0x13, 0x21, 0x61, 0x6a, 0xc8, 0xfe, 0x83, 0x80, 0xfe, 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe,
14910 0x04, 0x91, 0xfe, 0x86, 0x91, 0x64, 0x2f, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x75, 0xfe, 0xea,
14911 0x08, 0x04, 0x5d, 0x30, 0x5e, 0x0f, 0xae, 0x12, 0x8d, 0x9c, 0x5d, 0x9d, 0x5e, 0x01, 0xc1, 0xaf,
14912 0x64, 0x2f, 0x16, 0x61, 0xa1, 0x42, 0x69, 0x58, 0x65, 0x5f, 0x31, 0x60, 0xe8, 0xfe, 0xe5, 0x55,
14913 0xfe, 0x04, 0xfa, 0x42, 0xfe, 0x05, 0xfa, 0x58, 0x01, 0xfe, 0xde, 0x12, 0xfe, 0x36, 0x10, 0x2d,
14914 0x0f, 0xae, 0x0f, 0x8d, 0x65, 0x5f, 0x31, 0x60, 0xaa, 0x0a, 0x07, 0x1a, 0x18, 0xfe, 0xea, 0x08,
14915 0x65, 0x3a, 0x31, 0x3b, 0x0a, 0x07, 0xfe, 0xf7, 0x00, 0x38, 0x04, 0x5b, 0x30, 0x5c, 0xfe, 0x10,
14916 0x58, 0xfe, 0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x02, 0x7a, 0x0a, 0x07, 0x1a, 0x18,
14917 0xfe, 0xea, 0x08, 0x0a, 0x07, 0xfe, 0xf7, 0x00, 0x38, 0xfe, 0x3a, 0x55, 0xfe, 0x19, 0x81, 0x77,
14918 0xfe, 0x10, 0x90, 0xfe, 0x92, 0x90, 0xfe, 0xd7, 0x10, 0x3f, 0x05, 0xc3, 0x18, 0xfe, 0xf6, 0x08,
14919 0x11, 0xc3, 0xfe, 0x98, 0x80, 0xd7, 0x0c, 0xfe, 0x14, 0x13, 0x04, 0x3a, 0x30, 0x3b, 0x75, 0xfe,
14920 0xf6, 0x08, 0xfe, 0x0c, 0x58, 0xfe, 0x8d, 0x58, 0x02, 0x7a, 0x2d, 0x4e, 0xfe, 0x19, 0x80, 0xfe,
14921 0xf1, 0x10, 0x0a, 0x07, 0x0c, 0xa5, 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, 0xfe, 0x8e, 0x10, 0xfe,
14922 0x6c, 0x19, 0x9c, 0x3a, 0xfe, 0xed, 0x19, 0x9d, 0x3b, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xfe,
14923 0x6b, 0x18, 0x1b, 0xfe, 0x00, 0xff, 0x35, 0xfe, 0x74, 0x10, 0xc5, 0xfe, 0xd2, 0xf0, 0xfe, 0xd6,
14924 0x0a, 0xfe, 0x76, 0x18, 0x1b, 0x19, 0xce, 0x04, 0xdf, 0x1b, 0x06, 0x84, 0x13, 0xfe, 0x16, 0x00,
14925 0x02, 0x62, 0xfe, 0xd1, 0xf0, 0xfe, 0xe8, 0x0a, 0x17, 0x80, 0x01, 0x44, 0x13, 0xd6, 0xfe, 0x42,
14926 0x10, 0xfe, 0xce, 0xf0, 0xfe, 0xee, 0x0a, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xfa, 0x0a,
14927 0x13, 0xfe, 0x22, 0x00, 0x02, 0x62, 0xfe, 0xcb, 0xf0, 0xfe, 0x06, 0x0b, 0x13, 0xfe, 0x24, 0x00,
14928 0x02, 0x62, 0xfe, 0xd0, 0xf0, 0xfe, 0x10, 0x0b, 0x13, 0x88, 0xd8, 0xfe, 0xcf, 0xf0, 0xfe, 0x1a,
14929 0x0b, 0x13, 0x89, 0xd3, 0xfe, 0xcc, 0xf0, 0xfe, 0x2a, 0x0b, 0xfe, 0x84, 0x80, 0xd7, 0x1a, 0x4b,
14930 0x13, 0xfe, 0x12, 0x00, 0x2b, 0x08, 0x80, 0x2e, 0xfe, 0x30, 0x0b, 0xfe, 0x9e, 0xf0, 0xfe, 0x44,
14931 0x0b, 0x9b, 0x18, 0x32, 0x2b, 0x52, 0xfe, 0xed, 0x10, 0xa7, 0x28, 0xa9, 0x28, 0x2b, 0xf5, 0x2e,
14932 0xfe, 0x50, 0x0b, 0x22, 0x32, 0x81, 0xfe, 0x6c, 0x0b, 0x6b, 0x92, 0xa7, 0xfe, 0xec, 0x07, 0xa9,
14933 0xfe, 0xec, 0x07, 0x02, 0x28, 0x01, 0x4c, 0xfe, 0xdb, 0x10, 0x11, 0xfe, 0xe8, 0x00, 0xe3, 0xe4,
14934 0x8c, 0x82, 0x6e, 0xfe, 0x89, 0xf0, 0x28, 0x23, 0x24, 0xfe, 0xe9, 0x09, 0x01, 0x0b, 0x82, 0x6e,
14935 0x1f, 0x28, 0x23, 0x24, 0x91, 0x34, 0xfe, 0xa8, 0x0b, 0x22, 0x32, 0x02, 0xfe, 0x9c, 0x0b, 0x9b,
14936 0x40, 0x13, 0xfe, 0x42, 0x00, 0x02, 0x62, 0xa0, 0x06, 0xfe, 0x81, 0x49, 0x96, 0x0a, 0x07, 0x0c,
14937 0xfe, 0x5a, 0x13, 0x13, 0x00, 0x59, 0x0c, 0xfe, 0x6a, 0x12, 0x59, 0xfe, 0x28, 0x00, 0x27, 0xfe,
14938 0xee, 0x0c, 0x0e, 0x79, 0x01, 0x15, 0x05, 0x00, 0x84, 0x36, 0xfe, 0x28, 0x00, 0x02, 0xfe, 0xee,
14939 0x0c, 0x01, 0x97, 0x01, 0x9a, 0x0e, 0xc0, 0x01, 0xfe, 0x44, 0x0e, 0xb2, 0x08, 0x3d, 0x09, 0x99,
14940 0x01, 0x46, 0x11, 0x47, 0x08, 0x1c, 0x09, 0x43, 0x01, 0x7b, 0x02, 0x26, 0x13, 0xfe, 0x44, 0x00,
14941 0x59, 0x0c, 0xa5, 0x36, 0x0c, 0xfe, 0xc0, 0x10, 0x01, 0x96, 0x36, 0x0c, 0xfe, 0xb6, 0x10, 0x01,
14942 0x96, 0xfe, 0x19, 0x82, 0xfe, 0x34, 0x46, 0xfe, 0x0a, 0x13, 0x36, 0x0c, 0x13, 0xfe, 0x43, 0x00,
14943 0xfe, 0xa2, 0x10, 0x0a, 0x41, 0x0c, 0x38, 0x01, 0x97, 0x01, 0x9a, 0xb2, 0x08, 0x3d, 0x09, 0x99,
14944 0x01, 0x46, 0x11, 0x47, 0x08, 0x1c, 0x09, 0x43, 0x01, 0x7b, 0x51, 0x0c, 0xb2, 0x1d, 0xca, 0x02,
14945 0xfe, 0x48, 0x03, 0x0a, 0x07, 0x0c, 0xce, 0x36, 0x0c, 0x13, 0x00, 0xfe, 0x54, 0x10, 0x68, 0x07,
14946 0x1e, 0xfe, 0x50, 0x12, 0x0a, 0x07, 0x1e, 0xfe, 0x48, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0,
14947 0xfe, 0xac, 0x0c, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0xb2, 0x0c, 0x0a, 0x41, 0x1e, 0x38,
14948 0xfe, 0x95, 0x10, 0x13, 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0c, 0x77, 0xfe, 0x26, 0x10, 0x13,
14949 0xfe, 0x13, 0x00, 0xd3, 0x13, 0xfe, 0x47, 0x00, 0xa6, 0x13, 0xfe, 0x41, 0x00, 0x9e, 0x13, 0xfe,
14950 0x24, 0x00, 0x04, 0x78, 0x29, 0x27, 0xee, 0x77, 0xfe, 0x04, 0xe6, 0x1e, 0xfe, 0x9d, 0x41, 0xfe,
14951 0x1c, 0x42, 0xb2, 0x01, 0xea, 0x02, 0x26, 0xd5, 0x17, 0x0c, 0x4a, 0xf4, 0xdd, 0x17, 0xfe, 0x31,
14952 0x00, 0x4a, 0xbd, 0x01, 0xfe, 0x50, 0x0f, 0x02, 0xfe, 0xc2, 0x01, 0x1d, 0xfe, 0x06, 0xec, 0xf8,
14953 0x86, 0x36, 0x37, 0xbf, 0x35, 0x1d, 0xfe, 0x06, 0xea, 0xf8, 0xfe, 0x47, 0x4b, 0x95, 0xfe, 0x75,
14954 0x57, 0x04, 0x56, 0xfe, 0x98, 0x56, 0xfe, 0x28, 0x12, 0x0e, 0x79, 0xfe, 0xf4, 0x14, 0x4e, 0xe6,
14955 0x0e, 0xc0, 0xfe, 0xea, 0x14, 0xfe, 0x49, 0x54, 0x8f, 0xfe, 0x62, 0x0d, 0x0e, 0x1c, 0xfe, 0xde,
14956 0x14, 0xfe, 0x44, 0x48, 0x02, 0xfe, 0x48, 0x03, 0x0e, 0x56, 0xfe, 0xc8, 0x14, 0x86, 0x36, 0x37,
14957 0xbf, 0x35, 0x1d, 0xfe, 0xce, 0x47, 0xfe, 0xbd, 0x13, 0x02, 0x26, 0x21, 0x2a, 0x05, 0x10, 0xfe,
14958 0x78, 0x12, 0x2d, 0x16, 0x55, 0x16, 0xad, 0x21, 0x47, 0x4e, 0x4a, 0x47, 0x9b, 0xfe, 0x0c, 0x13,
14959 0xfe, 0xbc, 0xf0, 0xfe, 0xfe, 0x0d, 0x08, 0x06, 0x16, 0x55, 0x01, 0xfe, 0x06, 0x16, 0x04, 0xfe,
14960 0x38, 0x01, 0x30, 0xfe, 0x3a, 0x01, 0x75, 0xfe, 0x02, 0x0e, 0x04, 0xfe, 0x38, 0x01, 0x1b, 0xfe,
14961 0xf0, 0xff, 0x0f, 0xfe, 0x60, 0x01, 0x04, 0xfe, 0x3a, 0x01, 0x0f, 0xfe, 0x62, 0x01, 0x20, 0x06,
14962 0x16, 0x47, 0xfe, 0x04, 0xec, 0x2a, 0x08, 0x2a, 0x09, 0x3c, 0x1d, 0x01, 0x46, 0x7f, 0xfe, 0x05,
14963 0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x76, 0x16, 0x11, 0x47, 0xca, 0x08, 0x06, 0x03, 0x2d, 0x03,
14964 0x21, 0x55, 0xfe, 0xf7, 0x12, 0x21, 0xad, 0x6a, 0x16, 0xad, 0x05, 0x80, 0xfe, 0x93, 0x13, 0xfe,
14965 0x24, 0x1c, 0x17, 0x19, 0x4a, 0xf4, 0xdd, 0xfe, 0xd9, 0x10, 0x93, 0xfe, 0x03, 0xdc, 0xfe, 0x73,
14966 0x57, 0xfe, 0x80, 0x5d, 0x03, 0x93, 0xfe, 0x03, 0xdc, 0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x03,
14967 0xfe, 0x03, 0x57, 0x93, 0x2d, 0xfe, 0x00, 0xcc, 0x03, 0xfe, 0x03, 0x57, 0x93, 0x7d, 0x03, 0x01,
14968 0xfe, 0xae, 0x16, 0x3f, 0x05, 0x47, 0xfe, 0x0a, 0x13, 0x08, 0x1c, 0x09, 0x43, 0xd3, 0x01, 0x97,
14969 0x01, 0x9a, 0x08, 0x3d, 0x09, 0x99, 0x01, 0x46, 0x11, 0xfe, 0xe9, 0x00, 0x0a, 0x07, 0x89, 0xfe,
14970 0x52, 0x13, 0x01, 0xfe, 0x38, 0x16, 0xfe, 0x1e, 0x1c, 0xfe, 0x14, 0x90, 0x0f, 0xfe, 0x64, 0x01,
14971 0xfe, 0x16, 0x90, 0x0f, 0xfe, 0x66, 0x01, 0x0a, 0x07, 0x45, 0xe5, 0xfe, 0x03, 0x80, 0x52, 0x3e,
14972 0x11, 0x76, 0x08, 0x2a, 0x09, 0x3c, 0x1d, 0x90, 0x01, 0x71, 0xfe, 0x62, 0x08, 0x6a, 0x3e, 0x11,
14973 0x76, 0x08, 0x2a, 0x09, 0x3c, 0x1d, 0x90, 0x01, 0x71, 0x64, 0x2f, 0x11, 0x76, 0x08, 0x2a, 0x09,
14974 0x3c, 0x1d, 0x90, 0x01, 0x7b, 0x03, 0xfe, 0x08, 0x1c, 0x04, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58,
14975 0x04, 0xfe, 0xae, 0x00, 0xfe, 0x07, 0x58, 0x04, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58, 0x04, 0xfe,
14976 0xb2, 0x00, 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c, 0x20, 0x6c, 0x16, 0xf8, 0x2d, 0x0f, 0x53, 0x0f,
14977 0x4d, 0x20, 0x10, 0x16, 0x2a, 0x16, 0x3c, 0x57, 0xa0, 0xd6, 0x08, 0x2a, 0x09, 0x3c, 0x1d, 0x01,
14978 0x7b, 0x7f, 0x11, 0x76, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x2a, 0x0f, 0xd5, 0x8c, 0xfe,
14979 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe, 0x18, 0x1c, 0x03, 0x1d, 0xfe, 0x0c, 0x14, 0x86, 0xfe, 0x07,
14980 0xe6, 0x37, 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x03, 0x01, 0x96, 0x0e, 0x3d, 0x01, 0x15, 0x05,
14981 0x10, 0x2c, 0x0e, 0x1c, 0x01, 0x15, 0x05, 0x10, 0xda, 0xfe, 0x44, 0x58, 0x3e, 0xfe, 0x01, 0xec,
14982 0xbd, 0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x1e, 0x9f, 0x2f, 0x01, 0xea,
14983 0xfe, 0xc9, 0x10, 0x03, 0x2b, 0x82, 0x6e, 0x23, 0x24, 0xb3, 0x05, 0x1e, 0xfe, 0x48, 0x12, 0x05,
14984 0x0c, 0xfe, 0x4c, 0x12, 0x05, 0x19, 0xfe, 0x30, 0x12, 0x05, 0xcc, 0x18, 0xfe, 0xf4, 0x10, 0x05,
14985 0xfe, 0x23, 0x00, 0x18, 0xfe, 0x00, 0x11, 0x05, 0x06, 0x18, 0xfe, 0x5e, 0x11, 0x05, 0x1a, 0xfe,
14986 0x12, 0x12, 0x05, 0x00, 0x18, 0x28, 0x17, 0xcc, 0x01, 0x44, 0xc6, 0x39, 0x01, 0x0b, 0x81, 0x4c,
14987 0x03, 0x39, 0x11, 0xfe, 0xcc, 0x00, 0x02, 0x26, 0x39, 0x3f, 0x05, 0xc3, 0xfe, 0xe3, 0x13, 0x65,
14988 0x3a, 0x31, 0x3b, 0x75, 0xfe, 0xb2, 0x10, 0x0a, 0x07, 0x70, 0xfe, 0x72, 0x12, 0xa1, 0x42, 0x69,
14989 0x58, 0xe8, 0xfe, 0xe5, 0x55, 0x8f, 0xfe, 0x7c, 0x10, 0x21, 0x61, 0xfe, 0x26, 0x13, 0x04, 0xae,
14990 0x30, 0x8d, 0x75, 0xfe, 0xd2, 0x0c, 0x0f, 0x5d, 0x12, 0x5e, 0x2d, 0x0f, 0xae, 0x0f, 0x8d, 0x01,
14991 0xc1, 0x20, 0x6c, 0x52, 0x16, 0x61, 0x01, 0xfe, 0xde, 0x12, 0xa1, 0x42, 0x69, 0x58, 0xfe, 0x04,
14992 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x42, 0xfe, 0x05, 0xfa, 0x58, 0xfe, 0x91, 0x10, 0x04,
14993 0x5f, 0x30, 0x60, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56, 0x0f, 0x5f, 0x12, 0x60, 0xa8, 0xa1, 0x42,
14994 0x69, 0x58, 0xe8, 0xfe, 0xe5, 0x55, 0x04, 0x5b, 0x30, 0x5c, 0xfe, 0x00, 0x56, 0xfe, 0xa1, 0x56,
14995 0x0f, 0x5b, 0x12, 0x5c, 0x0a, 0x07, 0x70, 0xfe, 0x1e, 0x12, 0x21, 0x61, 0xfe, 0x1f, 0x40, 0x04,
14996 0x5d, 0x30, 0x5e, 0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x04, 0x5f, 0x30, 0x60, 0xfe, 0x34, 0x50,
14997 0xfe, 0xb6, 0x50, 0x04, 0x5b, 0x30, 0x5c, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x04, 0x3a, 0x30,
14998 0x3b, 0xfe, 0x28, 0x50, 0xfe, 0xaa, 0x50, 0x02, 0x98, 0x20, 0x06, 0x16, 0xf3, 0x02, 0x7c, 0x39,
14999 0x01, 0x0b, 0x1f, 0x4f, 0x23, 0x24, 0xb3, 0x05, 0x06, 0x27, 0x4f, 0x3f, 0x05, 0xc3, 0x27, 0x7c,
15000 0x01, 0xfa, 0x1b, 0x50, 0x18, 0x4f, 0x0a, 0x07, 0x0c, 0xdc, 0x65, 0x3a, 0x31, 0x3b, 0xfe, 0x0a,
15001 0x55, 0x35, 0xfe, 0x8b, 0x55, 0x9c, 0x3a, 0x9d, 0x3b, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0x02,
15002 0x7c, 0xfe, 0x19, 0x81, 0xfe, 0x0a, 0x45, 0xfe, 0x19, 0x41, 0x02, 0x7c, 0x39, 0x01, 0x0b, 0x1f,
15003 0xfe, 0xf6, 0x0f, 0x23, 0x24, 0xfe, 0xe9, 0x09, 0x59, 0x19, 0xfe, 0x94, 0x12, 0x59, 0x0c, 0x4b,
15004 0x02, 0x4f, 0x2e, 0xfe, 0x7e, 0x11, 0x22, 0x32, 0x1f, 0xfe, 0xf6, 0x0f, 0x23, 0x24, 0x91, 0x05,
15005 0x19, 0x27, 0x4f, 0x01, 0x0b, 0x1f, 0xfe, 0xf6, 0x0f, 0x23, 0x24, 0xfe, 0xe8, 0x09, 0x57, 0x04,
15006 0xfe, 0x9c, 0x00, 0x29, 0x35, 0xfe, 0xbb, 0x45, 0x59, 0x00, 0x40, 0x36, 0x06, 0xa0, 0x50, 0xfe,
15007 0xc0, 0x14, 0xfe, 0xf8, 0x14, 0xac, 0x3f, 0x05, 0xc2, 0xfe, 0x16, 0x13, 0x04, 0xf6, 0x29, 0xce,
15008 0x04, 0x4d, 0x29, 0x35, 0x5a, 0x02, 0x7c, 0xfe, 0xc0, 0x5d, 0xfe, 0xe4, 0x14, 0xfe, 0x03, 0x17,
15009 0x04, 0x53, 0xbc, 0x0f, 0x53, 0x5a, 0x39, 0x01, 0x0b, 0x25, 0x98, 0x01, 0xfe, 0x26, 0x14, 0x02,
15010 0x98, 0x2e, 0x40, 0x22, 0x32, 0x1f, 0x4f, 0x23, 0x24, 0x91, 0x05, 0x06, 0x27, 0x4f, 0xfe, 0xf6,
15011 0x14, 0xfe, 0x42, 0x58, 0xfe, 0x70, 0x14, 0xfe, 0x92, 0x14, 0xac, 0xfe, 0x4a, 0xf4, 0x0c, 0x18,
15012 0x4f, 0xfe, 0x4a, 0xf4, 0x06, 0xd1, 0x3f, 0x05, 0xc2, 0xc9, 0x02, 0x7c, 0x04, 0x4d, 0xbc, 0x0f,
15013 0x4d, 0x5a, 0x39, 0x01, 0x0b, 0x25, 0x98, 0x01, 0xfe, 0x54, 0x14, 0x02, 0x98, 0x25, 0xfe, 0x70,
15014 0x12, 0x73, 0xf1, 0x73, 0x03, 0x34, 0xfe, 0x6c, 0x12, 0x6b, 0xfe, 0x6c, 0x12, 0x5a, 0x39, 0x01,
15015 0x0b, 0xfe, 0xe3, 0x10, 0x08, 0x63, 0xff, 0x02, 0x00, 0x57, 0x66, 0x7e, 0x1b, 0xfe, 0xff, 0x7f,
15016 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x08, 0x63, 0xff, 0x02, 0x00, 0x57, 0x66, 0x7e, 0x1b,
15017 0x50, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x08, 0x63, 0xff, 0x02, 0x00, 0x57, 0x66, 0x7e,
15018 0x03, 0x08, 0x63, 0xff, 0x02, 0x00, 0x57, 0x66, 0x7e, 0xfe, 0x0b, 0x58, 0x03, 0x0e, 0x53, 0x01,
15019 0x8b, 0x0e, 0x4d, 0x01, 0x8b, 0x03, 0xc8, 0x1b, 0x10, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4,
15020 0x1a, 0x66, 0xfe, 0x00, 0x7d, 0xfe, 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c, 0x64, 0x2f,
15021 0x0f, 0x5b, 0x12, 0x5c, 0x9c, 0x5f, 0x9d, 0x60, 0x03, 0xfe, 0x62, 0x18, 0xfe, 0x82, 0x5a, 0xfe,
15022 0xe1, 0x1a, 0xb6, 0xfe, 0x02, 0x58, 0x03, 0x01, 0xfe, 0x9e, 0x18, 0xfe, 0x42, 0x48, 0x77, 0x57,
15023 0x95, 0x01, 0x0b, 0x1f, 0xfe, 0x1e, 0x14, 0x23, 0x24, 0xfe, 0xe9, 0x09, 0xfe, 0xc1, 0x59, 0x01,
15024 0x0b, 0x1f, 0xfe, 0x1e, 0x14, 0x23, 0x24, 0xfe, 0xe8, 0x0a, 0x04, 0xf6, 0x29, 0xfe, 0xc4, 0x12,
15025 0x2d, 0xb1, 0x1e, 0xdc, 0x59, 0xcd, 0x74, 0xfe, 0x6c, 0x13, 0x4b, 0x08, 0x06, 0x09, 0xcd, 0xa0,
15026 0xfe, 0x00, 0x10, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xa6, 0xff, 0x02, 0x83, 0x55, 0xb1,
15027 0x19, 0xfe, 0x12, 0x13, 0x72, 0xfe, 0x30, 0x00, 0x8f, 0xfe, 0xc6, 0x13, 0x09, 0x85, 0x08, 0x06,
15028 0xfe, 0x56, 0x10, 0xb1, 0x0c, 0xfe, 0x16, 0x13, 0x72, 0xfe, 0x64, 0x00, 0x8f, 0xfe, 0xc6, 0x13,
15029 0x0e, 0xfe, 0x64, 0x00, 0x09, 0x88, 0x08, 0x06, 0xfe, 0x28, 0x10, 0xb1, 0x06, 0xfe, 0x60, 0x13,
15030 0x72, 0xfe, 0xc8, 0x00, 0x8f, 0xfe, 0xc6, 0x13, 0x0e, 0xfe, 0xc8, 0x00, 0x09, 0x55, 0x08, 0x06,
15031 0xa8, 0x72, 0xfe, 0x90, 0x01, 0xed, 0xfe, 0xd2, 0x13, 0x95, 0xaa, 0xfe, 0x43, 0xf4, 0xad, 0xfe,
15032 0x56, 0xf0, 0xfe, 0xe4, 0x13, 0xfe, 0x04, 0xf4, 0x63, 0xfe, 0x43, 0xf4, 0x88, 0xfe, 0xf3, 0x10,
15033 0xb0, 0x01, 0xfe, 0xae, 0x12, 0x1b, 0x50, 0xd4, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x6c, 0xed,
15034 0xfe, 0x18, 0x14, 0xa3, 0x6c, 0xfe, 0x14, 0x10, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x1a, 0xed,
15035 0xfe, 0x18, 0x14, 0xa3, 0x1a, 0x9e, 0x57, 0x95, 0x08, 0x06, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58,
15036 0x03, 0x57, 0x08, 0x0c, 0x03, 0x14, 0x06, 0x01, 0x0b, 0x25, 0xec, 0x14, 0x0c, 0x01, 0x0b, 0x25,
15037 0xec, 0x14, 0x19, 0x01, 0x0b, 0x25, 0xec, 0x73, 0xfe, 0x89, 0x49, 0x01, 0x0b, 0x03, 0x14, 0x06,
15038 0x01, 0x0b, 0x25, 0xb7, 0x14, 0x19, 0x01, 0x0b, 0x25, 0xb7, 0x14, 0x06, 0x01, 0x0b, 0x25, 0xb7,
15039 0xfe, 0x89, 0x49, 0x01, 0x0b, 0x25, 0xb7, 0x73, 0xfe, 0x89, 0x4a, 0x01, 0x0b, 0x03, 0x57, 0x03,
15040 0x21, 0xe0, 0x05, 0x06, 0xfe, 0x44, 0x13, 0xaf, 0x16, 0xe0, 0xfe, 0x49, 0xf4, 0x00, 0x4b, 0x73,
15041 0xc6, 0x5a, 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xf1, 0x01, 0x0b, 0x3f, 0x05, 0xfe, 0xe3, 0x00,
15042 0xfe, 0x20, 0x13, 0x1f, 0xfe, 0xd6, 0x14, 0x2d, 0x16, 0xf3, 0x01, 0x4c, 0x21, 0xf3, 0x05, 0x06,
15043 0x40, 0x0a, 0x41, 0x06, 0x38, 0x03, 0x0f, 0x54, 0x12, 0x8a, 0xfe, 0x43, 0x58, 0x01, 0x15, 0x05,
15044 0x10, 0xfe, 0x1e, 0x12, 0x48, 0xe7, 0x8e, 0x01, 0x2c, 0xfe, 0x90, 0x4d, 0xde, 0x10, 0xfe, 0xc5,
15045 0x59, 0x01, 0x2c, 0xfe, 0x8d, 0x56, 0xb6, 0x48, 0x03, 0x48, 0x31, 0x8a, 0x01, 0x15, 0x48, 0x8e,
15046 0x01, 0x2c, 0xe2, 0x10, 0xde, 0x10, 0x31, 0x54, 0x72, 0x1c, 0x84, 0x0e, 0x56, 0x01, 0xab, 0x03,
15047 0x0f, 0x54, 0x12, 0x8a, 0xfe, 0xc3, 0x58, 0x01, 0x15, 0x05, 0x10, 0xfe, 0x1a, 0x12, 0x48, 0xe7,
15048 0x8e, 0x01, 0x2c, 0xe2, 0x10, 0xfe, 0x80, 0x4d, 0xfe, 0xc5, 0x59, 0x01, 0x2c, 0x48, 0x03, 0x48,
15049 0x31, 0x54, 0x01, 0x15, 0x48, 0x8e, 0x01, 0x2c, 0xe2, 0x10, 0xde, 0x10, 0x31, 0x54, 0x72, 0x1c,
15050 0x84, 0x0e, 0x56, 0x01, 0xab, 0x03, 0x0f, 0x54, 0x12, 0x8a, 0xfe, 0x43, 0x58, 0x01, 0x15, 0xfe,
15051 0x42, 0x48, 0x8e, 0x01, 0x2c, 0xfe, 0xc0, 0x5a, 0xb0, 0xfe, 0x00, 0xcd, 0xfe, 0x01, 0xcc, 0xfe,
15052 0x4a, 0x46, 0xdc, 0x93, 0x7d, 0x05, 0x10, 0xfe, 0x2e, 0x13, 0x69, 0x54, 0xfe, 0x4d, 0xf4, 0x1c,
15053 0xfe, 0x1c, 0x13, 0x0e, 0x56, 0x01, 0x8b, 0xaa, 0xfe, 0x40, 0x4c, 0xfe, 0xc5, 0x58, 0x01, 0x2c,
15054 0xfe, 0x00, 0x07, 0x7d, 0x05, 0x10, 0x84, 0x69, 0x8a, 0xfe, 0x05, 0x57, 0xfe, 0x08, 0x10, 0xfe,
15055 0x45, 0x58, 0x01, 0x2c, 0xfe, 0x8d, 0x56, 0xb6, 0xfe, 0x80, 0x4c, 0xfe, 0x05, 0x17, 0x03, 0x09,
15056 0x10, 0x6f, 0x67, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x24, 0x1c, 0xdb,
15057 0x37, 0x94, 0xfe, 0x1a, 0x16, 0x01, 0xfe, 0x28, 0x17, 0xfe, 0x0c, 0x13, 0x87, 0x37, 0x67, 0xfe,
15058 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x03, 0xba, 0x27, 0xfe, 0x0a, 0x16, 0xfe, 0xe2, 0x10, 0x09, 0x10,
15059 0x6f, 0x04, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x1a, 0xfe, 0x18, 0x58, 0x04, 0xfe, 0x66, 0x01,
15060 0xfe, 0x19, 0x58, 0x87, 0x1a, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4, 0x06, 0xfe, 0x3c, 0x50, 0x67,
15061 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x1a, 0x94, 0xfe, 0x64, 0x16, 0xfe, 0xbe,
15062 0x14, 0x35, 0x03, 0xba, 0x27, 0xfe, 0x3c, 0x16, 0xfe, 0xa4, 0x10, 0x09, 0x10, 0x6f, 0xb6, 0xfe,
15063 0x18, 0xdf, 0xfe, 0x19, 0xdf, 0xdb, 0x42, 0x94, 0xfe, 0x86, 0x16, 0xfe, 0x9c, 0x14, 0xfe, 0x18,
15064 0x13, 0x87, 0x42, 0x67, 0x1e, 0xfe, 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00, 0xa2, 0x07, 0xfe, 0x7f,
15065 0x00, 0xfe, 0x05, 0x40, 0x03, 0xba, 0x27, 0xfe, 0x7a, 0x16, 0xfe, 0x6c, 0x10, 0x09, 0x10, 0x6f,
15066 0xfe, 0x30, 0xbc, 0xfe, 0xb2, 0xbc, 0x87, 0xd9, 0x67, 0x1e, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7,
15067 0xd9, 0x94, 0xfe, 0xc6, 0x16, 0xfe, 0x5c, 0x14, 0x35, 0x03, 0xba, 0x27, 0xfe, 0xb2, 0x16, 0xfe,
15068 0x42, 0x10, 0xfe, 0x02, 0xf6, 0x10, 0x6f, 0xfe, 0x18, 0xfe, 0x5d, 0xfe, 0x19, 0xfe, 0x5e, 0xc8,
15069 0xdb, 0x45, 0x94, 0xfe, 0xec, 0x16, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13, 0x87, 0x45, 0x4e, 0xfe,
15070 0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x10, 0xfe, 0x81, 0xe7, 0x10, 0x11, 0xfe, 0xdd,
15071 0x00, 0x64, 0x2f, 0x03, 0x64, 0x2f, 0xfe, 0x12, 0x45, 0x27, 0xfe, 0xdc, 0x16, 0x17, 0x06, 0x4a,
15072 0xf4, 0xdd, 0x02, 0x26, 0xfe, 0x39, 0xf0, 0xfe, 0x30, 0x17, 0x2d, 0x03, 0xfe, 0x7e, 0x18, 0x1b,
15073 0x19, 0x83, 0x08, 0x0d, 0x03, 0x6f, 0x04, 0xdf, 0x1b, 0x06, 0xfe, 0xef, 0x12, 0xfe, 0xe1, 0x10,
15074 0x1d, 0x0e, 0x1c, 0x01, 0x15, 0x05, 0x10, 0x40, 0x3e, 0xfe, 0x78, 0x14, 0xfe, 0x34, 0x12, 0x50,
15075 0x86, 0x36, 0x37, 0xbf, 0xfe, 0xe9, 0x13, 0x1d, 0x0e, 0x3d, 0x01, 0x15, 0x05, 0x10, 0x40, 0x3e,
15076 0xfe, 0x56, 0x14, 0xe1, 0x50, 0x86, 0x36, 0x37, 0xbf, 0xfe, 0xe9, 0x13, 0x09, 0x0c, 0x03, 0xfe,
15077 0x9c, 0xe7, 0x0c, 0x13, 0xfe, 0x15, 0x00, 0x90, 0x9f, 0x2f, 0x01, 0xea, 0x09, 0x06, 0x03, 0x0a,
15078 0x41, 0x37, 0x38, 0x08, 0x3d, 0x09, 0x99, 0x01, 0x46, 0x11, 0x47, 0x08, 0x1c, 0x09, 0x43, 0x01,
15079 0x7b, 0x09, 0x06, 0x03, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x65, 0xf7, 0x31, 0x76, 0xfe, 0x48,
15080 0x55, 0x35, 0xfe, 0xc9, 0x55, 0x03, 0x21, 0xbe, 0x52, 0x16, 0xbe, 0x03, 0x0e, 0xc0, 0x01, 0x15,
15081 0xe6, 0x0e, 0x79, 0x01, 0x15, 0xfe, 0x49, 0x44, 0x27, 0xfe, 0x26, 0x18, 0x0e, 0x1c, 0x01, 0x15,
15082 0x05, 0x10, 0x40, 0x0e, 0x56, 0x01, 0xab, 0x0e, 0x79, 0x01, 0x15, 0x52, 0x7d, 0x03, 0xfe, 0x40,
15083 0x5e, 0xfe, 0xe2, 0x08, 0xfe, 0xc0, 0x4c, 0x21, 0x3c, 0x05, 0x10, 0xfe, 0x52, 0x12, 0x3e, 0x05,
15084 0x00, 0xfe, 0x18, 0x12, 0xfe, 0xe1, 0x18, 0xfe, 0x19, 0xf4, 0xfe, 0x7f, 0x00, 0xd4, 0xfe, 0xe2,
15085 0x08, 0x52, 0x3e, 0x3f, 0x05, 0x76, 0xa5, 0xfe, 0x82, 0x48, 0xfe, 0x01, 0x80, 0xfe, 0xd7, 0x10,
15086 0xfe, 0xc4, 0x48, 0x08, 0x2a, 0x09, 0x3c, 0xfe, 0x40, 0x5f, 0x1d, 0x01, 0x46, 0x11, 0xfe, 0xdd,
15087 0x00, 0xfe, 0x14, 0x46, 0x08, 0x2a, 0x09, 0x3c, 0x01, 0x46, 0x11, 0xfe, 0xdd, 0x00, 0xfe, 0x40,
15088 0x4a, 0x6a, 0xfe, 0x06, 0x17, 0xfe, 0x01, 0x07, 0xfe, 0x82, 0x48, 0xfe, 0x04, 0x17, 0x03, 0xeb,
15089 0x19, 0x74, 0xfe, 0xae, 0x18, 0x04, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xeb,
15090 0xcc, 0x74, 0xfe, 0xc0, 0x18, 0x04, 0xfe, 0x92, 0x00, 0xc7, 0x1e, 0xd8, 0xeb, 0xfe, 0x0b, 0x00,
15091 0x74, 0xfe, 0xd2, 0x18, 0x04, 0xfe, 0x94, 0x00, 0xc7, 0x1a, 0xfe, 0x08, 0x10, 0x04, 0xfe, 0x96,
15092 0x00, 0xc7, 0x85, 0xfe, 0x4e, 0x45, 0xd1, 0xfe, 0x0a, 0x45, 0xff, 0x04, 0x68, 0x54, 0xfe, 0xf1,
15093 0x10, 0x1b, 0x6c, 0x03, 0x05, 0x80, 0xfe, 0x5a, 0xf0, 0xfe, 0xfe, 0x18, 0x20, 0xfe, 0x09, 0x00,
15094 0xfe, 0x34, 0x10, 0x05, 0x1e, 0xfe, 0x5a, 0xf0, 0xfe, 0x0c, 0x19, 0x20, 0xcd, 0xfe, 0x26, 0x10,
15095 0x05, 0x19, 0x83, 0x20, 0x85, 0xd8, 0x05, 0x0c, 0x83, 0x20, 0x88, 0xfe, 0x0e, 0x10, 0x05, 0x06,
15096 0x83, 0x20, 0x55, 0xc6, 0xaf, 0x03, 0x17, 0xfe, 0x09, 0x00, 0x01, 0x44, 0x2e, 0xfe, 0x3c, 0x19,
15097 0x04, 0x6e, 0xb0, 0x03, 0x22, 0xfe, 0x54, 0x19, 0xfe, 0x14, 0xf0, 0x0b, 0x2e, 0xfe, 0x50, 0x19,
15098 0x03, 0xff, 0x15, 0x00, 0x00,
15101 STATIC unsigned short _adv_asc3550_size =
15102 sizeof(_adv_asc3550_buf); /* 0x13E5 */
15103 STATIC ADV_DCNT _adv_asc3550_chksum =
15104 0x04FFFF0E; /* Expanded checksum. */
15106 STATIC unsigned char _adv_asc38C0800_buf[] = {
15107 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0x16, 0x00, 0xfc, 0x48, 0xe4, 0x01, 0x00, 0x18, 0xe4,
15108 0x00, 0xf6, 0x01, 0xf6, 0x18, 0x80, 0x02, 0x00, 0x40, 0x1a, 0x00, 0xfa, 0xff, 0xff, 0x03, 0xf6,
15109 0xff, 0x00, 0x82, 0xe7, 0x01, 0xfa, 0x9e, 0xe7, 0x09, 0xe7, 0x1a, 0x0f, 0x00, 0xea, 0x01, 0xe6,
15110 0x03, 0x00, 0x55, 0xf0, 0x18, 0xf4, 0x1e, 0xf0, 0x3e, 0x57, 0x04, 0x00, 0x3e, 0x01, 0x85, 0xf0,
15111 0x00, 0xe6, 0x03, 0xfc, 0x08, 0x00, 0x2c, 0x1a, 0x32, 0xf0, 0x86, 0xf0, 0xbe, 0x0d, 0xd4, 0x01,
15112 0xd5, 0xf0, 0x00, 0xec, 0x01, 0xfc, 0x38, 0x54, 0x98, 0x57, 0xbc, 0x00, 0x0c, 0x1c, 0xb1, 0xf0,
15113 0x3c, 0x00, 0xb4, 0x00, 0xb8, 0x0d, 0x00, 0x57, 0x01, 0xf0, 0x02, 0x13, 0x02, 0xfc, 0x03, 0xe6,
15114 0x10, 0x00, 0x18, 0x40, 0x3e, 0x1c, 0x44, 0x13, 0x6c, 0x01, 0x6e, 0x01, 0xbd, 0x00, 0xe0, 0x00,
15115 0x02, 0x80, 0x30, 0xe4, 0x3e, 0x00, 0x74, 0x01, 0x76, 0x01, 0x7c, 0x16, 0x80, 0x00, 0xb9, 0x54,
15116 0xbb, 0x00, 0xee, 0x13, 0x00, 0x4e, 0x01, 0x01, 0x01, 0xea, 0x02, 0x48, 0x02, 0xfa, 0x04, 0x12,
15117 0x08, 0x12, 0x3c, 0x56, 0x4e, 0x01, 0x5d, 0xf0, 0x7a, 0x01, 0x7e, 0x10, 0xb6, 0x00, 0xc2, 0x10,
15118 0xee, 0x08, 0x00, 0x80, 0x05, 0xfc, 0x10, 0x44, 0x24, 0x01, 0x28, 0x01, 0x32, 0x00, 0x3c, 0x01,
15119 0x40, 0x00, 0x4b, 0xe4, 0x4b, 0xf4, 0x4c, 0x1c, 0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01,
15120 0x78, 0x01, 0x7c, 0x01, 0xbb, 0x55, 0xc2, 0x0d, 0x00, 0x01, 0x02, 0xee, 0x03, 0x58, 0x03, 0xf7,
15121 0x03, 0xfa, 0x04, 0x80, 0x08, 0x44, 0x09, 0xf0, 0x0f, 0x00, 0x1b, 0x80, 0x20, 0x01, 0x38, 0x1c,
15122 0x4e, 0x1c, 0x5b, 0xf0, 0x62, 0x0a, 0xaa, 0x00, 0xbe, 0x00, 0xc0, 0x00, 0xc0, 0x15, 0xcc, 0x10,
15123 0x00, 0x4c, 0x00, 0xdc, 0x02, 0x4a, 0x04, 0xfc, 0x05, 0x00, 0x05, 0xf0, 0x05, 0xf8, 0x06, 0x13,
15124 0x06, 0xf7, 0x08, 0x13, 0x0a, 0x10, 0x0c, 0x00, 0x0e, 0x47, 0x0e, 0xf7, 0x10, 0x0f, 0x20, 0x00,
15125 0x20, 0x16, 0x2a, 0x01, 0x32, 0x1c, 0x36, 0x00, 0x42, 0x54, 0x44, 0x55, 0x45, 0x5a, 0x52, 0x0c,
15126 0x59, 0xf0, 0x5c, 0xf0, 0x69, 0x08, 0x6e, 0x0b, 0x83, 0x59, 0xb8, 0xf0, 0xbd, 0x56, 0xcc, 0x18,
15127 0xce, 0x10, 0xd8, 0x18, 0xf0, 0x00, 0x01, 0x48, 0x04, 0x10, 0x04, 0xea, 0x04, 0xf6, 0x05, 0x80,
15128 0x05, 0xe6, 0x06, 0x00, 0x06, 0x0f, 0x06, 0x12, 0x0b, 0xf0, 0x0c, 0x10, 0x0c, 0xf0, 0x10, 0x13,
15129 0x12, 0x10, 0x19, 0x00, 0x19, 0xe4, 0x30, 0x1c, 0x33, 0x00, 0x34, 0x00, 0x38, 0x44, 0x40, 0x5c,
15130 0x4a, 0xe4, 0x62, 0x1a, 0x68, 0x08, 0x68, 0x54, 0x6c, 0x15, 0x70, 0x15, 0x83, 0x55, 0x83, 0x5a,
15131 0x91, 0x44, 0xa4, 0x00, 0xac, 0x13, 0xb0, 0x57, 0xb5, 0x00, 0xb8, 0x17, 0xba, 0x00, 0xce, 0x45,
15132 0xd0, 0x00, 0xe1, 0x00, 0xe5, 0x55, 0xe7, 0x00, 0x00, 0x54, 0x01, 0x58, 0x02, 0x10, 0x02, 0xe6,
15133 0x03, 0xa1, 0x04, 0x13, 0x06, 0x83, 0x06, 0xf0, 0x07, 0x00, 0x0a, 0x00, 0x0a, 0x12, 0x0a, 0xf0,
15134 0x0c, 0x12, 0x0c, 0x13, 0x0c, 0x90, 0x0e, 0x13, 0x10, 0x04, 0x10, 0x10, 0x12, 0x1c, 0x19, 0x81,
15135 0x1a, 0x10, 0x1c, 0x00, 0x1c, 0x12, 0x1d, 0xf7, 0x1e, 0x13, 0x20, 0x1c, 0x20, 0xe7, 0x22, 0x01,
15136 0x26, 0x01, 0x2a, 0x12, 0x2c, 0x0f, 0x30, 0xe7, 0x32, 0x15, 0x34, 0x1c, 0x36, 0x1c, 0x38, 0x12,
15137 0x3a, 0x55, 0x3f, 0x00, 0x41, 0x58, 0x43, 0x48, 0x46, 0x1c, 0x4e, 0xe4, 0x76, 0x02, 0x77, 0x57,
15138 0x78, 0x03, 0x89, 0x48, 0x8e, 0x90, 0x98, 0x80, 0x99, 0x00, 0xfe, 0x9c, 0xf0, 0x27, 0x02, 0xfe,
15139 0xe0, 0x0d, 0xff, 0x10, 0x00, 0x00, 0xfe, 0xc6, 0x01, 0xfe, 0x56, 0x1a, 0x00, 0xfe, 0xc4, 0x01,
15140 0xfe, 0x84, 0x01, 0xff, 0x03, 0x00, 0x00, 0xfe, 0x6a, 0x13, 0xfe, 0x05, 0x05, 0xff, 0x40, 0x00,
15141 0x00, 0x0e, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08, 0x01, 0x01, 0xff, 0x10, 0xff, 0xff, 0xff, 0x1f,
15142 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x11, 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12,
15143 0xff, 0x21, 0x00, 0x00, 0xfe, 0x04, 0xf7, 0xfe, 0xc4, 0x01, 0x2e, 0x88, 0x0b, 0x01, 0xfe, 0xca,
15144 0x0f, 0xfe, 0x04, 0xf7, 0xfe, 0xc4, 0x01, 0x88, 0x0b, 0x1c, 0x2e, 0xfe, 0x3d, 0xf0, 0xfe, 0xfc,
15145 0x01, 0xfe, 0x20, 0xf0, 0xdc, 0x04, 0x5f, 0x4f, 0x02, 0xfe, 0xfc, 0x0d, 0x01, 0xfe, 0x5c, 0x0e,
15146 0xfe, 0xe9, 0x12, 0x02, 0xfe, 0x08, 0x03, 0xfe, 0x28, 0x1c, 0x04, 0xfe, 0xa6, 0x00, 0xfe, 0xdd,
15147 0x12, 0x47, 0x12, 0xfe, 0xa6, 0x00, 0xcd, 0xfe, 0x48, 0xf0, 0xfe, 0x80, 0x02, 0xfe, 0x49, 0xf0,
15148 0xfe, 0x9a, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xb8, 0x02, 0xfe, 0x46, 0xf0, 0xfe, 0x4a, 0x02, 0xfe,
15149 0x47, 0xf0, 0xfe, 0x50, 0x02, 0xfe, 0x43, 0xf0, 0xfe, 0x3e, 0x02, 0xfe, 0x44, 0xf0, 0xfe, 0x42,
15150 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x46, 0x02, 0x09, 0x0b, 0xa4, 0x09, 0x06, 0x12, 0xc1, 0x02, 0x27,
15151 0xfe, 0x00, 0x1c, 0xfe, 0xf1, 0x10, 0xfe, 0x02, 0x1c, 0xfe, 0xed, 0x10, 0xfe, 0x1e, 0x1c, 0xfe,
15152 0xe9, 0x10, 0x01, 0xfe, 0x2c, 0x18, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc, 0xfe, 0xa8, 0x00, 0x0f,
15153 0x7c, 0x01, 0xaa, 0x02, 0x27, 0x17, 0x5e, 0x4c, 0xc4, 0x01, 0xfe, 0x40, 0x10, 0x0f, 0x7c, 0x01,
15154 0x8e, 0xfe, 0xbd, 0x10, 0x0f, 0x7c, 0x01, 0x8e, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe, 0x58,
15155 0x1c, 0x09, 0x06, 0x12, 0xc1, 0x2e, 0x1b, 0x27, 0xfe, 0x3d, 0xf0, 0xfe, 0xfc, 0x01, 0x28, 0xfe,
15156 0x8e, 0x02, 0xfe, 0x5a, 0x1c, 0xde, 0xfe, 0x14, 0x1c, 0x17, 0xfe, 0x30, 0x00, 0x4c, 0xc4, 0x01,
15157 0xfe, 0x30, 0x10, 0x09, 0x06, 0x12, 0xc1, 0x02, 0xfe, 0xc6, 0x01, 0x29, 0x2d, 0x05, 0x10, 0x35,
15158 0xfe, 0x69, 0x10, 0x09, 0x06, 0x12, 0xc1, 0xfe, 0x04, 0xec, 0x2d, 0x08, 0x2d, 0x09, 0x3e, 0x1c,
15159 0x01, 0x45, 0x82, 0xfe, 0x05, 0xf6, 0xfe, 0xa8, 0x00, 0x01, 0xfe, 0x56, 0x17, 0x0a, 0x41, 0x8f,
15160 0x39, 0x11, 0x48, 0x1c, 0xd2, 0x08, 0x1e, 0x09, 0x52, 0x01, 0x90, 0x02, 0x27, 0x0f, 0x3f, 0x01,
15161 0x15, 0x05, 0x10, 0xdb, 0x08, 0x1e, 0x09, 0x52, 0x01, 0x7e, 0xfe, 0x28, 0x10, 0x0f, 0xc8, 0x01,
15162 0x15, 0xf2, 0x0f, 0x7d, 0x01, 0x15, 0xfe, 0x49, 0x54, 0x79, 0xfe, 0x16, 0x03, 0x08, 0x1e, 0x09,
15163 0x52, 0x01, 0x90, 0x02, 0x27, 0x2e, 0x82, 0xfe, 0x02, 0xe8, 0x31, 0xfe, 0xbf, 0x57, 0xfe, 0x9e,
15164 0x43, 0xf7, 0xfe, 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xdc, 0xfe, 0x40, 0x1c, 0x1b, 0xf8, 0xfe, 0x26,
15165 0xf0, 0xfe, 0x74, 0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x62, 0x03, 0xfe, 0x11, 0xf0, 0xdc, 0xfe, 0x0e,
15166 0x10, 0xfe, 0x9f, 0xf0, 0xfe, 0x82, 0x03, 0xf4, 0x13, 0xfe, 0x11, 0x00, 0x02, 0x6b, 0x2e, 0xfe,
15167 0x48, 0x1c, 0xf4, 0x1b, 0xf8, 0x34, 0xf8, 0xfe, 0x82, 0xf0, 0xfe, 0x88, 0x03, 0x2b, 0x29, 0xc6,
15168 0x72, 0x16, 0xc6, 0x0f, 0x7d, 0x01, 0x15, 0x72, 0x80, 0x08, 0x1e, 0x09, 0x52, 0x01, 0x45, 0x11,
15169 0x3f, 0x08, 0x3f, 0x09, 0xa2, 0x01, 0x90, 0xfe, 0x9c, 0x32, 0x11, 0xfe, 0xe4, 0x00, 0x2f, 0xfe,
15170 0xce, 0x03, 0x1b, 0x32, 0x1f, 0xfe, 0xde, 0x03, 0x01, 0x55, 0xd3, 0xfe, 0xee, 0x03, 0x73, 0x97,
15171 0xd7, 0xfe, 0xae, 0x06, 0x02, 0x26, 0x04, 0x7c, 0x2c, 0x19, 0xfe, 0x20, 0x05, 0x17, 0x8b, 0x01,
15172 0x3b, 0x01, 0x9f, 0x01, 0xa1, 0x34, 0xfe, 0x60, 0x02, 0x02, 0xf6, 0xf4, 0x2e, 0x88, 0x18, 0xfe,
15173 0x67, 0x1b, 0xfe, 0xbf, 0x57, 0xf7, 0xfe, 0x48, 0x1c, 0x92, 0x01, 0xfe, 0x9c, 0x13, 0xb3, 0xfe,
15174 0x96, 0xf0, 0xfe, 0x28, 0x04, 0x2f, 0xfe, 0x2c, 0x04, 0x34, 0x27, 0x0f, 0x3f, 0x01, 0x15, 0x05,
15175 0x10, 0x19, 0xfe, 0x0c, 0x05, 0x4d, 0x7a, 0xa5, 0x31, 0x86, 0x76, 0x1b, 0x32, 0x1f, 0x26, 0x04,
15176 0x7c, 0x2c, 0xfe, 0x10, 0x12, 0x17, 0x8b, 0x01, 0x3b, 0x34, 0xfe, 0x60, 0x02, 0x02, 0xf6, 0x21,
15177 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x5e, 0x12, 0x0a, 0x07, 0x06, 0xfe, 0x56, 0x12, 0x24,
15178 0x23, 0x9a, 0x01, 0x0c, 0x86, 0x76, 0x1f, 0xfe, 0xdc, 0x04, 0x24, 0x23, 0x9a, 0x01, 0x0c, 0x1f,
15179 0x26, 0x24, 0x23, 0xba, 0xfe, 0x4c, 0x44, 0xfe, 0x32, 0x12, 0x51, 0xfe, 0x44, 0x48, 0x08, 0xfe,
15180 0x93, 0x00, 0xfe, 0x4c, 0x54, 0x79, 0xfe, 0x0c, 0x05, 0x82, 0xa5, 0x31, 0xfe, 0x06, 0x80, 0xfe,
15181 0x48, 0x47, 0xfe, 0x48, 0x13, 0x40, 0x05, 0xfe, 0xcc, 0x00, 0xfe, 0x40, 0x13, 0x0a, 0x07, 0x06,
15182 0xef, 0xfe, 0x06, 0x10, 0x24, 0x23, 0xba, 0x0a, 0x07, 0x38, 0xe2, 0x17, 0xa9, 0x0a, 0x07, 0x06,
15183 0x4f, 0x17, 0xfe, 0x0d, 0x00, 0x01, 0x3b, 0x34, 0xfe, 0xa0, 0x0d, 0x02, 0x26, 0x3a, 0x11, 0xfe,
15184 0xe6, 0x00, 0xfe, 0x1c, 0x90, 0xb7, 0x03, 0x17, 0xa9, 0x01, 0x3b, 0x34, 0x27, 0x1b, 0x27, 0x02,
15185 0xfe, 0x14, 0x05, 0xfe, 0x42, 0x5b, 0x88, 0x18, 0xfe, 0x46, 0x59, 0xfe, 0xbf, 0x57, 0xf7, 0x17,
15186 0x46, 0xfe, 0x07, 0x80, 0xfe, 0x31, 0x44, 0x0a, 0x07, 0x0b, 0xfe, 0x78, 0x13, 0xfe, 0x20, 0x80,
15187 0x05, 0x18, 0xfe, 0x70, 0x12, 0x75, 0x07, 0x06, 0xfe, 0x60, 0x13, 0x04, 0xfe, 0xa2, 0x00, 0x2c,
15188 0x19, 0xfe, 0xac, 0x05, 0xfe, 0x31, 0xe4, 0x60, 0x75, 0x07, 0x0b, 0xfe, 0x4a, 0x13, 0x04, 0xfe,
15189 0xa0, 0x00, 0x2c, 0xfe, 0x42, 0x12, 0x63, 0x2f, 0xfe, 0x6c, 0x05, 0x1b, 0x32, 0xf9, 0x01, 0x0c,
15190 0x25, 0xfe, 0xc4, 0x05, 0x11, 0xfe, 0xe3, 0x00, 0x2b, 0x75, 0xfe, 0x4a, 0xf0, 0xfe, 0x96, 0x05,
15191 0xfe, 0x49, 0xf0, 0xfe, 0x90, 0x05, 0xad, 0x20, 0xfe, 0x21, 0x00, 0x8a, 0x20, 0xfe, 0x22, 0x00,
15192 0xa4, 0x20, 0x8f, 0xfe, 0x09, 0x48, 0x01, 0x0c, 0x25, 0xfe, 0xc4, 0x05, 0xfe, 0xe2, 0x08, 0x75,
15193 0x07, 0xe1, 0x4f, 0x01, 0xc2, 0x20, 0x06, 0x16, 0xe8, 0x4c, 0xfe, 0x27, 0x01, 0x0a, 0x07, 0x38,
15194 0xe9, 0x47, 0x01, 0xbd, 0x17, 0xa9, 0x0a, 0x07, 0x06, 0x4f, 0x17, 0xfe, 0x0d, 0x00, 0x01, 0x3b,
15195 0x01, 0x9f, 0x01, 0xa1, 0x34, 0xfe, 0xa0, 0x0d, 0x02, 0x26, 0x04, 0xfe, 0x9c, 0x00, 0x2c, 0xfe,
15196 0x3e, 0x12, 0x04, 0x5c, 0x2c, 0xfe, 0x36, 0x13, 0x47, 0x01, 0xbd, 0x25, 0xfe, 0x3c, 0x06, 0x0f,
15197 0x06, 0x75, 0x07, 0x22, 0xfe, 0x02, 0x12, 0x6a, 0x01, 0xfe, 0x06, 0x15, 0x1f, 0xfe, 0x32, 0x06,
15198 0x11, 0xc9, 0x01, 0x55, 0x11, 0xfe, 0xe5, 0x00, 0x04, 0x5c, 0xc3, 0x0d, 0x5c, 0x04, 0xfe, 0x9e,
15199 0x00, 0x2c, 0xfe, 0x62, 0x12, 0x04, 0x56, 0x2c, 0xfe, 0x5a, 0x13, 0x01, 0xfe, 0x7e, 0x19, 0x01,
15200 0xfe, 0xe8, 0x19, 0xf3, 0xa8, 0xf1, 0x08, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x6e, 0x81, 0x1a, 0x59,
15201 0xd1, 0xa8, 0x74, 0x47, 0x01, 0xbd, 0x25, 0xfe, 0xa6, 0x06, 0x75, 0x07, 0x1d, 0xab, 0x9e, 0x0f,
15202 0x5e, 0x01, 0xfe, 0x34, 0x15, 0x1f, 0xfe, 0x9c, 0x06, 0x11, 0xc9, 0x01, 0x55, 0x11, 0xfe, 0xe5,
15203 0x00, 0x04, 0x56, 0xc3, 0x0d, 0x56, 0x09, 0x06, 0x01, 0xbd, 0xfe, 0x9c, 0x32, 0x78, 0x92, 0x01,
15204 0xfe, 0x9c, 0x13, 0xb3, 0x11, 0xfe, 0xe2, 0x00, 0x2f, 0xfe, 0xbe, 0x06, 0x1b, 0x32, 0xd7, 0xfe,
15205 0xda, 0x06, 0x85, 0xfe, 0x78, 0x07, 0xd3, 0xfe, 0x80, 0x07, 0x73, 0x97, 0x02, 0x26, 0x0a, 0x07,
15206 0x0b, 0xfe, 0x2e, 0x12, 0x14, 0x18, 0x01, 0x0c, 0x14, 0x00, 0x01, 0x0c, 0x14, 0x00, 0x01, 0x0c,
15207 0x14, 0x00, 0x01, 0x0c, 0xfe, 0x99, 0xa4, 0x01, 0x0c, 0x14, 0x00, 0x02, 0xfe, 0x50, 0x08, 0x71,
15208 0x07, 0x1d, 0xef, 0x0a, 0x07, 0x1d, 0xfe, 0x30, 0x13, 0x14, 0xfe, 0x1b, 0x00, 0x01, 0x0c, 0x14,
15209 0x00, 0x01, 0x0c, 0x14, 0x00, 0x01, 0x0c, 0x14, 0x00, 0x01, 0x0c, 0x14, 0x06, 0x01, 0x0c, 0x14,
15210 0x00, 0x02, 0xfe, 0x0a, 0x0c, 0x6a, 0xfe, 0x9a, 0x81, 0x6f, 0x8f, 0xfe, 0x09, 0x6f, 0xfe, 0x93,
15211 0x45, 0x19, 0xfe, 0x88, 0x07, 0x2f, 0xfe, 0x60, 0x07, 0x1b, 0x32, 0xd7, 0xfe, 0x58, 0x07, 0x73,
15212 0x97, 0x85, 0xfe, 0x78, 0x07, 0x02, 0x26, 0x01, 0x55, 0x02, 0xfe, 0xbe, 0x06, 0x14, 0x22, 0x02,
15213 0xfe, 0xbe, 0x06, 0xfe, 0x9c, 0xf7, 0xfe, 0xf0, 0x07, 0xfe, 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x53,
15214 0xfe, 0xd6, 0x07, 0x0d, 0x66, 0x12, 0x67, 0x0a, 0x41, 0x60, 0x39, 0x01, 0xfe, 0x14, 0x19, 0x05,
15215 0x10, 0x87, 0xfe, 0x83, 0xe7, 0xfe, 0x95, 0x00, 0x8a, 0xfe, 0x03, 0x40, 0x0a, 0x41, 0x46, 0x39,
15216 0x01, 0xc5, 0xb6, 0xfe, 0x1f, 0x40, 0x16, 0x68, 0x01, 0xfe, 0xbe, 0x13, 0xfe, 0x08, 0x50, 0xfe,
15217 0x8a, 0x50, 0xfe, 0x34, 0x51, 0xfe, 0xb6, 0x51, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90, 0x0d, 0x64,
15218 0x12, 0x65, 0xda, 0xfa, 0x0d, 0x3c, 0x12, 0x3d, 0xfe, 0x60, 0x10, 0x0a, 0x07, 0x60, 0xe9, 0xfe,
15219 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0d, 0x66, 0x12, 0x67, 0x0a, 0x07, 0x46, 0xd1, 0x01, 0xc5, 0xfe,
15220 0x1f, 0x80, 0x16, 0x68, 0xfe, 0x34, 0x90, 0xfe, 0xb6, 0x90, 0x0d, 0x43, 0x12, 0x44, 0xfe, 0x08,
15221 0x90, 0xfe, 0x8a, 0x90, 0x0d, 0x64, 0x12, 0x65, 0xa7, 0x07, 0x46, 0xdb, 0xda, 0xfa, 0x0d, 0x3c,
15222 0x12, 0x3d, 0xad, 0xfe, 0x28, 0x90, 0xfe, 0xaa, 0x90, 0x0d, 0x3c, 0x12, 0x3d, 0x0d, 0x30, 0x12,
15223 0x42, 0x2b, 0x0d, 0x54, 0x0d, 0x69, 0x0a, 0x41, 0x22, 0x39, 0x2e, 0x08, 0x84, 0x2f, 0xfe, 0x70,
15224 0x08, 0xfe, 0x9e, 0xf0, 0xfe, 0x84, 0x08, 0xa3, 0x19, 0x32, 0x2e, 0x5b, 0xfe, 0xed, 0x10, 0xac,
15225 0xfe, 0xa8, 0x08, 0xae, 0xfe, 0xc4, 0x08, 0x85, 0xfe, 0x9c, 0x08, 0xd3, 0xfe, 0xa2, 0x08, 0x73,
15226 0x97, 0x02, 0x26, 0x01, 0x55, 0xfe, 0xc9, 0x10, 0x14, 0x22, 0xfe, 0xc9, 0x10, 0x71, 0x07, 0x06,
15227 0xfe, 0x10, 0x12, 0x71, 0x07, 0x0b, 0x50, 0x0a, 0x07, 0x0b, 0xfe, 0xa6, 0x12, 0xfe, 0x2e, 0x1c,
15228 0xb0, 0x71, 0x07, 0x06, 0x50, 0x71, 0x07, 0x0b, 0xfe, 0x92, 0x12, 0xfe, 0x2c, 0x1c, 0xa7, 0x07,
15229 0x46, 0xaf, 0xa7, 0x41, 0x46, 0xfe, 0x05, 0x40, 0xda, 0xfa, 0xfe, 0x28, 0x50, 0xfe, 0xaa, 0x50,
15230 0xfe, 0xaa, 0xf0, 0xfe, 0xf6, 0x09, 0xfe, 0xac, 0xf0, 0xfe, 0x24, 0x09, 0x02, 0xfe, 0x02, 0x0a,
15231 0xfe, 0xb7, 0xf0, 0xfe, 0x20, 0x09, 0xfe, 0x02, 0xf6, 0x1d, 0x6a, 0xfe, 0x70, 0x18, 0xfe, 0xf1,
15232 0x18, 0xfe, 0x40, 0x55, 0xfe, 0xe1, 0x55, 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0xfe, 0x14, 0x59,
15233 0xfe, 0x95, 0x59, 0x1b, 0x9b, 0xfe, 0x8c, 0xf0, 0xfe, 0x20, 0x09, 0xfe, 0xac, 0xf0, 0xfe, 0x14,
15234 0x09, 0xed, 0xfe, 0xcb, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0x30, 0x09, 0x02, 0xfe, 0x3c, 0x0b, 0xee,
15235 0xfe, 0xbf, 0x10, 0xfe, 0x2b, 0xf0, 0x9b, 0xfe, 0x6b, 0x18, 0x1a, 0xfe, 0x00, 0xfe, 0xe2, 0xcd,
15236 0xfe, 0xd2, 0xf0, 0x9b, 0xfe, 0x76, 0x18, 0x1a, 0x18, 0x19, 0x9b, 0x04, 0xe7, 0x1a, 0x06, 0x19,
15237 0x9b, 0xac, 0x58, 0xae, 0x58, 0xed, 0xee, 0xfe, 0x89, 0x10, 0x92, 0x63, 0x3a, 0x17, 0xa9, 0x01,
15238 0x3b, 0x13, 0xfe, 0x35, 0x00, 0x34, 0x6b, 0x13, 0x93, 0x02, 0x6b, 0xfb, 0xb2, 0x0b, 0xfe, 0x1a,
15239 0x12, 0x51, 0xfe, 0x19, 0x82, 0xfe, 0x6c, 0x18, 0xfe, 0x44, 0x54, 0xf0, 0xdf, 0xfe, 0x74, 0x18,
15240 0x94, 0x95, 0x19, 0xfe, 0xf2, 0x08, 0x02, 0x58, 0x0a, 0x07, 0x60, 0xaf, 0x04, 0x30, 0x2a, 0x42,
15241 0x0d, 0x43, 0x12, 0x44, 0x83, 0x30, 0x5a, 0x42, 0xfe, 0x6c, 0x18, 0xfe, 0xed, 0x18, 0xfe, 0x44,
15242 0x54, 0xfe, 0xe5, 0x54, 0x36, 0x43, 0x21, 0x44, 0x04, 0x54, 0x2a, 0x69, 0x94, 0xfe, 0xe3, 0x54,
15243 0xfe, 0x74, 0x18, 0xfe, 0xf5, 0x18, 0x94, 0xfe, 0xe3, 0x54, 0x95, 0xca, 0x53, 0xfe, 0xf2, 0x08,
15244 0x02, 0x58, 0xfe, 0x37, 0xf0, 0xfe, 0xfe, 0x09, 0xfe, 0x8b, 0xf0, 0xfe, 0x84, 0x09, 0x02, 0x58,
15245 0xfb, 0xb2, 0x0b, 0x28, 0xfe, 0x1e, 0x0b, 0x36, 0x54, 0x21, 0x69, 0x53, 0x7a, 0x08, 0xfe, 0xc0,
15246 0x07, 0x47, 0x62, 0x00, 0xd9, 0xfe, 0x01, 0x59, 0xfe, 0x52, 0xf0, 0xfe, 0x30, 0x0a, 0x94, 0x99,
15247 0xfe, 0x48, 0x0a, 0x36, 0x54, 0x94, 0xfe, 0xe3, 0x54, 0x4e, 0x54, 0x70, 0x69, 0xfe, 0x14, 0x58,
15248 0xfe, 0x95, 0x58, 0x02, 0x58, 0x36, 0x54, 0x21, 0x69, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0xf0,
15249 0x4e, 0x54, 0x4e, 0x69, 0x02, 0x58, 0x0a, 0x07, 0x60, 0xfe, 0x82, 0x12, 0x0a, 0x07, 0x22, 0xfe,
15250 0x66, 0x13, 0x29, 0x68, 0x72, 0xd0, 0xfe, 0x83, 0x80, 0xfe, 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe,
15251 0x04, 0x91, 0xfe, 0x86, 0x91, 0x6d, 0x31, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x53, 0xfe, 0xfa,
15252 0x08, 0x04, 0x66, 0x2a, 0x67, 0x0d, 0xb5, 0x12, 0x93, 0x4e, 0x66, 0x70, 0x67, 0x01, 0xc5, 0xb6,
15253 0x6d, 0x31, 0x16, 0x68, 0x83, 0x30, 0x5a, 0x42, 0x36, 0x43, 0x21, 0x44, 0x95, 0xca, 0xfe, 0x04,
15254 0xfa, 0x30, 0xfe, 0x05, 0xfa, 0x42, 0x01, 0xfe, 0xbe, 0x13, 0xfe, 0x36, 0x10, 0x2b, 0x0d, 0xb5,
15255 0x0d, 0x93, 0x36, 0x43, 0x21, 0x44, 0xb0, 0x0a, 0x07, 0x22, 0x19, 0xfe, 0xfa, 0x08, 0x36, 0x3c,
15256 0x21, 0x3d, 0x0a, 0x07, 0xfe, 0xf7, 0x00, 0x39, 0x04, 0x64, 0x2a, 0x65, 0xfe, 0x10, 0x58, 0xfe,
15257 0x91, 0x58, 0x4e, 0x54, 0x70, 0x69, 0x02, 0xfe, 0x18, 0x0a, 0x0a, 0x07, 0x22, 0x19, 0xfe, 0xfa,
15258 0x08, 0x0a, 0x07, 0xfe, 0xf7, 0x00, 0x39, 0xf0, 0xdf, 0x6a, 0xfe, 0x10, 0x90, 0xfe, 0x92, 0x90,
15259 0xfe, 0xd3, 0x10, 0x40, 0x05, 0xcb, 0x19, 0xfe, 0x2c, 0x09, 0x11, 0xcb, 0xfb, 0xb2, 0x0b, 0xfe,
15260 0x14, 0x13, 0x04, 0x3c, 0x2a, 0x3d, 0x53, 0xfe, 0x2c, 0x09, 0xfe, 0x0c, 0x58, 0xfe, 0x8d, 0x58,
15261 0x02, 0x58, 0x2b, 0x47, 0xfe, 0x19, 0x80, 0xfe, 0xf1, 0x10, 0x0a, 0x07, 0x0b, 0xab, 0xfe, 0x6c,
15262 0x19, 0xfe, 0x19, 0x41, 0xfe, 0x8e, 0x10, 0xfe, 0x6c, 0x19, 0x4e, 0x3c, 0xfe, 0xed, 0x19, 0x70,
15263 0x3d, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xfe, 0x6b, 0x18, 0x1a, 0xfe, 0x00, 0xff, 0x35, 0xfe,
15264 0x74, 0x10, 0xcd, 0xfe, 0xd2, 0xf0, 0xfe, 0xb6, 0x0b, 0xfe, 0x76, 0x18, 0x1a, 0x18, 0xd6, 0x04,
15265 0xe7, 0x1a, 0x06, 0x89, 0x13, 0xfe, 0x16, 0x00, 0x02, 0x6b, 0xfe, 0xd1, 0xf0, 0xfe, 0xc8, 0x0b,
15266 0x17, 0x84, 0x01, 0x3b, 0x13, 0xfe, 0x17, 0x00, 0xfe, 0x42, 0x10, 0xfe, 0xce, 0xf0, 0xfe, 0xce,
15267 0x0b, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xda, 0x0b, 0x13, 0xfe, 0x22, 0x00, 0x02, 0x6b,
15268 0xfe, 0xcb, 0xf0, 0xfe, 0xe6, 0x0b, 0x13, 0xfe, 0x24, 0x00, 0x02, 0x6b, 0xfe, 0xd0, 0xf0, 0xfe,
15269 0xf0, 0x0b, 0x13, 0xb1, 0xe0, 0xfe, 0xcf, 0xf0, 0xfe, 0xfa, 0x0b, 0x13, 0x8f, 0xdd, 0xfe, 0xcc,
15270 0xf0, 0xfe, 0x0a, 0x0c, 0xfe, 0x84, 0x80, 0xb2, 0x22, 0x4f, 0x13, 0xfe, 0x12, 0x00, 0x2e, 0x08,
15271 0x84, 0x2f, 0xfe, 0x10, 0x0c, 0xfe, 0x9e, 0xf0, 0xfe, 0x24, 0x0c, 0xa3, 0x19, 0x32, 0x2e, 0x5b,
15272 0xfe, 0xed, 0x10, 0xac, 0x26, 0xae, 0x26, 0x2e, 0xfe, 0x9c, 0x32, 0x2f, 0xfe, 0x30, 0x0c, 0x1b,
15273 0x32, 0x85, 0xfe, 0x4c, 0x0c, 0x73, 0x97, 0xac, 0xfe, 0xf0, 0x07, 0xae, 0xfe, 0xf0, 0x07, 0x02,
15274 0x26, 0x01, 0x55, 0xfe, 0xdb, 0x10, 0x11, 0xfe, 0xe8, 0x00, 0xed, 0xee, 0x92, 0x86, 0x76, 0xfe,
15275 0x89, 0xf0, 0x26, 0x24, 0x23, 0xfe, 0xe9, 0x09, 0x01, 0x0c, 0x86, 0x76, 0x1f, 0x26, 0x24, 0x23,
15276 0x9a, 0x34, 0xfe, 0x88, 0x0c, 0x1b, 0x32, 0x02, 0xfe, 0x7c, 0x0c, 0xa3, 0x50, 0x13, 0xfe, 0x42,
15277 0x00, 0x02, 0x6b, 0xa6, 0x06, 0xfe, 0x81, 0x49, 0xfe, 0xcc, 0x12, 0x0a, 0x07, 0x0b, 0xfe, 0x5a,
15278 0x13, 0x13, 0x00, 0x61, 0x0b, 0xfe, 0x6a, 0x12, 0x61, 0xfe, 0x28, 0x00, 0x28, 0xfe, 0xce, 0x0d,
15279 0x0f, 0x7d, 0x01, 0x15, 0x05, 0x00, 0x89, 0x37, 0xfe, 0x28, 0x00, 0x02, 0xfe, 0xce, 0x0d, 0x01,
15280 0x9f, 0x01, 0xa1, 0x0f, 0xc8, 0x01, 0xfe, 0x24, 0x0f, 0xb9, 0x08, 0x3f, 0x09, 0xa2, 0x01, 0x45,
15281 0x11, 0x48, 0x08, 0x1e, 0x09, 0x52, 0x01, 0x7e, 0x02, 0x27, 0x13, 0xfe, 0x44, 0x00, 0x61, 0x0b,
15282 0xab, 0x37, 0x0b, 0xfe, 0xc0, 0x10, 0x01, 0xc2, 0x37, 0x0b, 0xfe, 0xb6, 0x10, 0x01, 0xc2, 0xfe,
15283 0x19, 0x82, 0xfe, 0x34, 0x46, 0xfe, 0x0a, 0x13, 0x37, 0x0b, 0x13, 0xfe, 0x43, 0x00, 0xfe, 0xa2,
15284 0x10, 0x0a, 0x41, 0x0b, 0x39, 0x01, 0x9f, 0x01, 0xa1, 0xb9, 0x08, 0x3f, 0x09, 0xa2, 0x01, 0x45,
15285 0x11, 0x48, 0x08, 0x1e, 0x09, 0x52, 0x01, 0x7e, 0x88, 0x0b, 0xb9, 0x1c, 0xd2, 0x02, 0xfe, 0x4c,
15286 0x03, 0x0a, 0x07, 0x0b, 0xd6, 0x37, 0x0b, 0x13, 0x00, 0xfe, 0x54, 0x10, 0x71, 0x07, 0x1d, 0xfe,
15287 0x50, 0x12, 0x0a, 0x07, 0x1d, 0xfe, 0x48, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x8c,
15288 0x0d, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x92, 0x0d, 0x0a, 0x41, 0x1d, 0x39, 0xfe, 0x95,
15289 0x10, 0x13, 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0b, 0x6a, 0xfe, 0x26, 0x10, 0x13, 0xfe, 0x13,
15290 0x00, 0xdd, 0x13, 0xfe, 0x47, 0x00, 0x8a, 0x13, 0xfe, 0x41, 0x00, 0xa4, 0x13, 0xfe, 0x24, 0x00,
15291 0x04, 0x7c, 0x2c, 0x28, 0xf6, 0x6a, 0xfe, 0x04, 0xe6, 0x1d, 0xfe, 0x9d, 0x41, 0xfe, 0x1c, 0x42,
15292 0xb9, 0x01, 0xea, 0x02, 0x27, 0xde, 0x17, 0x0b, 0x4c, 0xfe, 0x9b, 0x00, 0xe5, 0x17, 0xfe, 0x31,
15293 0x00, 0x4c, 0xc4, 0x01, 0xfe, 0x30, 0x10, 0x02, 0xfe, 0xc6, 0x01, 0x1c, 0xfe, 0x06, 0xec, 0xfe,
15294 0xb9, 0x00, 0x8c, 0x37, 0x38, 0xc7, 0x35, 0x1c, 0xfe, 0x06, 0xea, 0xfe, 0xb9, 0x00, 0xfe, 0x47,
15295 0x4b, 0x9e, 0xfe, 0x75, 0x57, 0x04, 0x5f, 0xfe, 0x98, 0x56, 0xfe, 0x28, 0x12, 0x0f, 0x7d, 0xfe,
15296 0xf4, 0x14, 0x47, 0xf2, 0x0f, 0xc8, 0xfe, 0xea, 0x14, 0xfe, 0x49, 0x54, 0x98, 0xfe, 0x42, 0x0e,
15297 0x0f, 0x1e, 0xfe, 0xde, 0x14, 0xfe, 0x44, 0x48, 0x02, 0xfe, 0x4c, 0x03, 0x0f, 0x5f, 0xfe, 0xc8,
15298 0x14, 0x8c, 0x37, 0x38, 0xc7, 0x35, 0x1c, 0xfe, 0xce, 0x47, 0xfe, 0xbd, 0x13, 0x02, 0x27, 0x29,
15299 0x2d, 0x05, 0x10, 0xfe, 0x78, 0x12, 0x2b, 0x16, 0x5e, 0x16, 0xb4, 0x29, 0x48, 0x47, 0x4c, 0x48,
15300 0xa3, 0xd9, 0xfe, 0xbc, 0xf0, 0xfe, 0xde, 0x0e, 0x08, 0x06, 0x16, 0x5e, 0x01, 0xfe, 0xe6, 0x16,
15301 0x04, 0xfe, 0x38, 0x01, 0x2a, 0xfe, 0x3a, 0x01, 0x53, 0xfe, 0xe2, 0x0e, 0x04, 0xfe, 0x38, 0x01,
15302 0x1a, 0xfe, 0xf0, 0xff, 0x0d, 0xfe, 0x60, 0x01, 0x04, 0xfe, 0x3a, 0x01, 0x0d, 0xfe, 0x62, 0x01,
15303 0x20, 0x06, 0x16, 0x48, 0xfe, 0x04, 0xec, 0x2d, 0x08, 0x2d, 0x09, 0x3e, 0x1c, 0x01, 0x45, 0x82,
15304 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x56, 0x17, 0x11, 0x48, 0xd2, 0x08, 0x06, 0x03,
15305 0x2b, 0x03, 0x29, 0x5e, 0xfe, 0xf7, 0x12, 0x29, 0xb4, 0x72, 0x16, 0xb4, 0x05, 0x84, 0xfe, 0x93,
15306 0x13, 0xfe, 0x24, 0x1c, 0x17, 0x18, 0x4c, 0xfe, 0x9b, 0x00, 0xe5, 0xfe, 0xd9, 0x10, 0x9c, 0xfe,
15307 0x03, 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x03, 0x9c, 0xfe, 0x03, 0xdc, 0xfe, 0x5b, 0x57,
15308 0xfe, 0x80, 0x5d, 0x03, 0xfe, 0x03, 0x57, 0x9c, 0x2b, 0xfe, 0x00, 0xcc, 0x03, 0xfe, 0x03, 0x57,
15309 0x9c, 0x80, 0x03, 0x01, 0xfe, 0x8e, 0x17, 0x40, 0x05, 0x48, 0xfe, 0x0a, 0x13, 0x08, 0x1e, 0x09,
15310 0x52, 0xdd, 0x01, 0x9f, 0x01, 0xa1, 0x08, 0x3f, 0x09, 0xa2, 0x01, 0x45, 0x11, 0xfe, 0xe9, 0x00,
15311 0x0a, 0x07, 0x8f, 0xfe, 0x52, 0x13, 0x01, 0xfe, 0x18, 0x17, 0xfe, 0x1e, 0x1c, 0xfe, 0x14, 0x90,
15312 0x0d, 0xfe, 0x64, 0x01, 0xfe, 0x16, 0x90, 0x0d, 0xfe, 0x66, 0x01, 0x0a, 0x07, 0x46, 0xef, 0xfe,
15313 0x03, 0x80, 0x5b, 0x4d, 0x11, 0x7b, 0x08, 0x2d, 0x09, 0x3e, 0x1c, 0x7a, 0x01, 0x90, 0xfe, 0x62,
15314 0x08, 0x72, 0x4d, 0x11, 0x7b, 0x08, 0x2d, 0x09, 0x3e, 0x1c, 0x7a, 0x01, 0x90, 0x6d, 0x31, 0x11,
15315 0x7b, 0x08, 0x2d, 0x09, 0x3e, 0x1c, 0x7a, 0x01, 0x7e, 0x03, 0xfe, 0x08, 0x1c, 0x04, 0xfe, 0xac,
15316 0x00, 0xfe, 0x06, 0x58, 0x04, 0xfe, 0xae, 0x00, 0xfe, 0x07, 0x58, 0x04, 0xfe, 0xb0, 0x00, 0xfe,
15317 0x08, 0x58, 0x04, 0xfe, 0xb2, 0x00, 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c, 0x20, 0x74, 0x16, 0xfe,
15318 0xb9, 0x00, 0x2b, 0x0d, 0x5c, 0x0d, 0x56, 0x20, 0x10, 0x16, 0x2d, 0x16, 0x3e, 0x51, 0xa6, 0xfe,
15319 0x93, 0x00, 0x08, 0x2d, 0x09, 0x3e, 0x1c, 0x01, 0x7e, 0x82, 0x11, 0x7b, 0xfe, 0x14, 0x56, 0xfe,
15320 0xd6, 0xf0, 0x8a, 0xde, 0x92, 0xfe, 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe, 0x18, 0x1c, 0x03, 0x1c,
15321 0xfe, 0x0c, 0x14, 0x8c, 0xfe, 0x07, 0xe6, 0x38, 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x03, 0x01,
15322 0xc2, 0x0f, 0x3f, 0x01, 0x15, 0x05, 0x10, 0xdb, 0x0f, 0x1e, 0x01, 0x15, 0x05, 0x10, 0xe2, 0xfe,
15323 0x44, 0x58, 0x4d, 0xfe, 0x01, 0xec, 0xc4, 0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c,
15324 0xe7, 0x1d, 0xa5, 0x31, 0x01, 0xea, 0xfe, 0xc9, 0x10, 0x03, 0x2e, 0x86, 0x76, 0x24, 0x23, 0xba,
15325 0x05, 0x1d, 0xfe, 0x48, 0x12, 0x05, 0x0b, 0xfe, 0x4c, 0x12, 0x05, 0x18, 0xfe, 0x30, 0x12, 0x05,
15326 0xd4, 0x19, 0xfe, 0xd4, 0x11, 0x05, 0xfe, 0x23, 0x00, 0x19, 0xfe, 0xe0, 0x11, 0x05, 0x06, 0x19,
15327 0xfe, 0x3e, 0x12, 0x05, 0x22, 0xfe, 0x12, 0x12, 0x05, 0x00, 0x19, 0x26, 0x17, 0xd4, 0x01, 0x3b,
15328 0xce, 0x3a, 0x01, 0x0c, 0x85, 0x55, 0x03, 0x3a, 0x11, 0xfe, 0xcc, 0x00, 0x02, 0x27, 0x3a, 0x40,
15329 0x05, 0xcb, 0xfe, 0xe3, 0x13, 0x36, 0x3c, 0x21, 0x3d, 0x53, 0xfe, 0x92, 0x11, 0x0a, 0x07, 0x60,
15330 0xfe, 0x72, 0x12, 0x83, 0x30, 0x5a, 0x42, 0x95, 0xca, 0x98, 0xfe, 0x5c, 0x11, 0x29, 0x68, 0xfe,
15331 0x26, 0x13, 0x04, 0xb5, 0x2a, 0x93, 0x53, 0xfe, 0xb2, 0x0d, 0x0d, 0x66, 0x12, 0x67, 0x2b, 0x0d,
15332 0xb5, 0x0d, 0x93, 0x01, 0xc5, 0x20, 0x74, 0x5b, 0x16, 0x68, 0x01, 0xfe, 0xbe, 0x13, 0x83, 0x30,
15333 0x5a, 0x42, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x30, 0xfe, 0x05, 0xfa, 0x42,
15334 0xfe, 0x91, 0x10, 0x04, 0x43, 0x2a, 0x44, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56, 0x0d, 0x43, 0x12,
15335 0x44, 0xad, 0x83, 0x30, 0x5a, 0x42, 0x95, 0xca, 0x04, 0x64, 0x2a, 0x65, 0xfe, 0x00, 0x56, 0xfe,
15336 0xa1, 0x56, 0x0d, 0x64, 0x12, 0x65, 0x0a, 0x07, 0x60, 0xfe, 0x1e, 0x12, 0x29, 0x68, 0xfe, 0x1f,
15337 0x40, 0x04, 0x66, 0x2a, 0x67, 0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x04, 0x43, 0x2a, 0x44, 0xfe,
15338 0x34, 0x50, 0xfe, 0xb6, 0x50, 0x04, 0x64, 0x2a, 0x65, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x04,
15339 0x3c, 0x2a, 0x3d, 0xfe, 0x28, 0x50, 0xfe, 0xaa, 0x50, 0x02, 0xa0, 0x20, 0x06, 0x16, 0xfc, 0x02,
15340 0x7f, 0x3a, 0x01, 0x0c, 0x1f, 0x57, 0x24, 0x23, 0xba, 0x05, 0x06, 0x28, 0x57, 0x40, 0x05, 0xcb,
15341 0x28, 0x7f, 0x01, 0xfe, 0x9c, 0x13, 0x1a, 0x59, 0x19, 0x57, 0x0a, 0x07, 0x0b, 0xe4, 0x36, 0x3c,
15342 0x21, 0x3d, 0xfe, 0x0a, 0x55, 0x35, 0xfe, 0x8b, 0x55, 0x4e, 0x3c, 0x70, 0x3d, 0xfe, 0x0c, 0x51,
15343 0xfe, 0x8e, 0x51, 0x02, 0x7f, 0xdf, 0xfe, 0x0a, 0x45, 0xfe, 0x19, 0x41, 0x02, 0x7f, 0x3a, 0x01,
15344 0x0c, 0x1f, 0xfe, 0xd6, 0x10, 0x24, 0x23, 0xfe, 0xe9, 0x09, 0x61, 0x18, 0xfe, 0x94, 0x12, 0x61,
15345 0x0b, 0x4f, 0x02, 0x57, 0x2f, 0xfe, 0x5e, 0x12, 0x1b, 0x32, 0x1f, 0xfe, 0xd6, 0x10, 0x24, 0x23,
15346 0x9a, 0x05, 0x18, 0x28, 0x57, 0x01, 0x0c, 0x1f, 0xfe, 0xd6, 0x10, 0x24, 0x23, 0xfe, 0xe8, 0x09,
15347 0x51, 0x04, 0xfe, 0x9c, 0x00, 0x2c, 0x35, 0xfe, 0xbb, 0x45, 0x61, 0x00, 0x50, 0x37, 0x06, 0xa6,
15348 0x59, 0xfe, 0xc0, 0x14, 0xfe, 0xf8, 0x14, 0xb3, 0x40, 0x05, 0xc9, 0xfe, 0x16, 0x13, 0x04, 0xfe,
15349 0x9e, 0x00, 0x2c, 0xd6, 0x04, 0x56, 0x2c, 0x35, 0x63, 0x02, 0x7f, 0xfe, 0xc0, 0x5d, 0xfe, 0xe4,
15350 0x14, 0xfe, 0x03, 0x17, 0x04, 0x5c, 0xc3, 0x0d, 0x5c, 0x63, 0x3a, 0x01, 0x0c, 0x25, 0xa0, 0x01,
15351 0xfe, 0x06, 0x15, 0x02, 0xa0, 0x2f, 0xfe, 0xe8, 0x12, 0x1b, 0x32, 0x1f, 0x57, 0x24, 0x23, 0x9a,
15352 0x05, 0x06, 0x28, 0x57, 0xfe, 0xf6, 0x14, 0xfe, 0x42, 0x58, 0xfe, 0x70, 0x14, 0xfe, 0x92, 0x14,
15353 0xb3, 0xfe, 0x4a, 0xf4, 0x0b, 0x19, 0x57, 0xfe, 0x4a, 0xf4, 0x06, 0xd8, 0x40, 0x05, 0xc9, 0xd1,
15354 0x02, 0x7f, 0x04, 0x56, 0xc3, 0x0d, 0x56, 0x63, 0x3a, 0x01, 0x0c, 0x25, 0xa0, 0x01, 0xfe, 0x34,
15355 0x15, 0x02, 0xa0, 0x25, 0xfe, 0x50, 0x13, 0x78, 0xf9, 0x78, 0x03, 0x34, 0xfe, 0x4c, 0x13, 0x73,
15356 0xfe, 0x4c, 0x13, 0x63, 0x3a, 0x01, 0x0c, 0xfe, 0xe3, 0x10, 0x08, 0x6c, 0xff, 0x02, 0x00, 0x57,
15357 0x6e, 0x81, 0x1a, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x08, 0x6c, 0xff,
15358 0x02, 0x00, 0x57, 0x6e, 0x81, 0x1a, 0x59, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x08, 0x6c,
15359 0xff, 0x02, 0x00, 0x57, 0x6e, 0x81, 0x03, 0x08, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x6e, 0x81, 0xfe,
15360 0x0b, 0x58, 0x03, 0x0f, 0x5c, 0x01, 0x8e, 0x0f, 0x56, 0x01, 0x8e, 0x03, 0xd0, 0x1a, 0x10, 0xff,
15361 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4, 0x22, 0x6e, 0xfe, 0x00, 0x7d, 0xfe, 0x01, 0x7d, 0xfe, 0x02,
15362 0x7d, 0xfe, 0x03, 0x7c, 0x6d, 0x31, 0x0d, 0x64, 0x12, 0x65, 0x4e, 0x43, 0x70, 0x44, 0x03, 0xfe,
15363 0x62, 0x18, 0xfe, 0x82, 0x5a, 0xfe, 0xe1, 0x1a, 0xbf, 0xfe, 0x02, 0x58, 0x03, 0x01, 0xfe, 0x7e,
15364 0x19, 0xfe, 0x42, 0x48, 0x6a, 0x51, 0x9e, 0x01, 0x0c, 0x1f, 0xfe, 0xfe, 0x14, 0x24, 0x23, 0xfe,
15365 0xe9, 0x09, 0xfe, 0xc1, 0x59, 0x01, 0x0c, 0x1f, 0xfe, 0xfe, 0x14, 0x24, 0x23, 0xfe, 0xe8, 0x0a,
15366 0x04, 0xfe, 0x9e, 0x00, 0x2c, 0xfe, 0xc4, 0x12, 0x2b, 0xb8, 0x1d, 0xe4, 0x61, 0xd5, 0x79, 0xfe,
15367 0x4c, 0x14, 0x4f, 0x08, 0x06, 0x09, 0xd5, 0xa6, 0xfe, 0x00, 0x10, 0xfe, 0x78, 0x10, 0xff, 0x02,
15368 0x83, 0x55, 0x8a, 0xff, 0x02, 0x83, 0x55, 0xb8, 0x18, 0xfe, 0x12, 0x13, 0x62, 0xfe, 0x30, 0x00,
15369 0x98, 0xfe, 0xa6, 0x14, 0x09, 0x8b, 0x08, 0x06, 0xfe, 0x56, 0x10, 0xb8, 0x0b, 0xfe, 0x16, 0x13,
15370 0x62, 0xfe, 0x64, 0x00, 0x98, 0xfe, 0xa6, 0x14, 0x0f, 0xfe, 0x64, 0x00, 0x09, 0xb1, 0x08, 0x06,
15371 0xfe, 0x28, 0x10, 0xb8, 0x06, 0xfe, 0x60, 0x13, 0x62, 0xfe, 0xc8, 0x00, 0x98, 0xfe, 0xa6, 0x14,
15372 0x0f, 0xfe, 0xc8, 0x00, 0x09, 0x5e, 0x08, 0x06, 0xad, 0x62, 0xfe, 0x90, 0x01, 0x99, 0xfe, 0xb2,
15373 0x14, 0x9e, 0xb0, 0xfe, 0x43, 0xf4, 0xb4, 0xfe, 0x56, 0xf0, 0xfe, 0xc4, 0x14, 0xfe, 0x04, 0xf4,
15374 0x6c, 0xfe, 0x43, 0xf4, 0xb1, 0xfe, 0xf3, 0x10, 0xb7, 0x01, 0xfe, 0x8e, 0x13, 0x1a, 0x59, 0xaf,
15375 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x74, 0x99, 0xfe, 0xf8, 0x14, 0xa8, 0x74, 0xfe, 0x14, 0x10,
15376 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0xf1, 0x99, 0xfe, 0xf8, 0x14, 0xa8, 0xf1, 0xa4, 0x51, 0x9e,
15377 0x08, 0x06, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58, 0x03, 0x51, 0x08, 0x0b, 0x03, 0x14, 0x06, 0x01,
15378 0x0c, 0x25, 0xec, 0x14, 0x0b, 0x01, 0x0c, 0x25, 0xec, 0x14, 0x18, 0x01, 0x0c, 0x25, 0xec, 0x78,
15379 0xfe, 0x89, 0x49, 0x01, 0x0c, 0x03, 0x14, 0x06, 0x01, 0x0c, 0x25, 0xbc, 0x14, 0x18, 0x01, 0x0c,
15380 0x25, 0xbc, 0x14, 0x06, 0x01, 0x0c, 0x25, 0xbc, 0xfe, 0x89, 0x49, 0x01, 0x0c, 0x25, 0xbc, 0x78,
15381 0xfe, 0x89, 0x4a, 0x01, 0x0c, 0x03, 0x51, 0x03, 0x29, 0xe8, 0x05, 0x06, 0x3b, 0xb6, 0x16, 0xe8,
15382 0xfe, 0x49, 0xf4, 0x00, 0x4f, 0x78, 0xce, 0x63, 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xf9, 0x01,
15383 0x0c, 0x40, 0x05, 0xfe, 0xe3, 0x00, 0xfe, 0x20, 0x13, 0x1f, 0xfe, 0xb6, 0x15, 0x2b, 0x16, 0xfc,
15384 0x01, 0x55, 0x29, 0xfc, 0x05, 0x06, 0x50, 0x0a, 0x41, 0x06, 0x39, 0x03, 0x0d, 0x5d, 0x12, 0x91,
15385 0xfe, 0x43, 0x58, 0x01, 0x15, 0x05, 0x10, 0xfe, 0x1e, 0x12, 0x4a, 0xf3, 0x96, 0x01, 0x49, 0xfe,
15386 0x90, 0x4d, 0xe6, 0x10, 0xfe, 0xc5, 0x59, 0x01, 0x49, 0xfe, 0x8d, 0x56, 0xbf, 0x4a, 0x03, 0x4a,
15387 0x21, 0x91, 0x01, 0x15, 0x4a, 0x96, 0x01, 0x49, 0xeb, 0x10, 0xe6, 0x10, 0x21, 0x5d, 0x62, 0x1e,
15388 0x89, 0x0f, 0x5f, 0x01, 0xaa, 0x03, 0x0d, 0x5d, 0x12, 0x91, 0xfe, 0xc3, 0x58, 0x01, 0x15, 0x05,
15389 0x10, 0xfe, 0x1a, 0x12, 0x4a, 0xf3, 0x96, 0x01, 0x49, 0xeb, 0x10, 0xfe, 0x80, 0x4d, 0xfe, 0xc5,
15390 0x59, 0x01, 0x49, 0x4a, 0x03, 0x4a, 0x21, 0x5d, 0x01, 0x15, 0x4a, 0x96, 0x01, 0x49, 0xeb, 0x10,
15391 0xe6, 0x10, 0x21, 0x5d, 0x62, 0x1e, 0x89, 0x0f, 0x5f, 0x01, 0xaa, 0x03, 0x0d, 0x5d, 0x12, 0x91,
15392 0xfe, 0x43, 0x58, 0x01, 0x15, 0xfe, 0x42, 0x48, 0x96, 0x01, 0x49, 0xfe, 0xc0, 0x5a, 0xb7, 0xfe,
15393 0x00, 0xcd, 0xfe, 0x01, 0xcc, 0xfe, 0x4a, 0x46, 0xe4, 0x9c, 0x80, 0x05, 0x10, 0xfe, 0x2e, 0x13,
15394 0x5a, 0x5d, 0xfe, 0x4d, 0xf4, 0x1e, 0xfe, 0x1c, 0x13, 0x0f, 0x5f, 0x01, 0x8e, 0xb0, 0xfe, 0x40,
15395 0x4c, 0xfe, 0xc5, 0x58, 0x01, 0x49, 0xfe, 0x00, 0x07, 0x80, 0x05, 0x10, 0x89, 0x5a, 0x91, 0xfe,
15396 0x05, 0x57, 0xfe, 0x08, 0x10, 0xfe, 0x45, 0x58, 0x01, 0x49, 0xfe, 0x8d, 0x56, 0xbf, 0xfe, 0x80,
15397 0x4c, 0xfe, 0x05, 0x17, 0x03, 0x09, 0x10, 0x77, 0x6f, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe,
15398 0x19, 0xde, 0xfe, 0x24, 0x1c, 0xe3, 0x38, 0x9d, 0xfe, 0xfa, 0x16, 0x01, 0xfe, 0x08, 0x18, 0xd9,
15399 0x8d, 0x38, 0x6f, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x03, 0xc0, 0x28, 0xfe, 0xea, 0x16, 0xfe,
15400 0xe2, 0x10, 0x09, 0x10, 0x77, 0x04, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x22, 0xfe, 0x18, 0x58,
15401 0x04, 0xfe, 0x66, 0x01, 0xfe, 0x19, 0x58, 0x8d, 0x22, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4, 0x06,
15402 0xfe, 0x3c, 0x50, 0x6f, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x22, 0x9d, 0xfe,
15403 0x44, 0x17, 0xfe, 0xbe, 0x14, 0x35, 0x03, 0xc0, 0x28, 0xfe, 0x1c, 0x17, 0xfe, 0xa4, 0x10, 0x09,
15404 0x10, 0x77, 0xbf, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xdf, 0xe3, 0x30, 0x9d, 0xfe, 0x66, 0x17, 0xfe,
15405 0x9c, 0x14, 0xfe, 0x18, 0x13, 0x8d, 0x30, 0x6f, 0x1d, 0xfe, 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00,
15406 0xa7, 0x07, 0xfe, 0x7f, 0x00, 0xfe, 0x05, 0x40, 0x03, 0xc0, 0x28, 0xfe, 0x5a, 0x17, 0xfe, 0x6c,
15407 0x10, 0x09, 0x10, 0x77, 0xfe, 0x30, 0xbc, 0xfe, 0xb2, 0xbc, 0x8d, 0xe1, 0x6f, 0x1d, 0xfe, 0x0f,
15408 0x79, 0xfe, 0x1c, 0xf7, 0xe1, 0x9d, 0xfe, 0xa6, 0x17, 0xfe, 0x5c, 0x14, 0x35, 0x03, 0xc0, 0x28,
15409 0xfe, 0x92, 0x17, 0xfe, 0x42, 0x10, 0xfe, 0x02, 0xf6, 0x10, 0x77, 0xfe, 0x18, 0xfe, 0x66, 0xfe,
15410 0x19, 0xfe, 0x67, 0xd0, 0xe3, 0x46, 0x9d, 0xfe, 0xcc, 0x17, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13,
15411 0x8d, 0x46, 0x47, 0xfe, 0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x10, 0xfe, 0x81, 0xe7,
15412 0x10, 0x11, 0xfe, 0xdd, 0x00, 0x6d, 0x31, 0x03, 0x6d, 0x31, 0xfe, 0x12, 0x45, 0x28, 0xfe, 0xbc,
15413 0x17, 0x17, 0x06, 0x4c, 0xfe, 0x9b, 0x00, 0xe5, 0x02, 0x27, 0xfe, 0x39, 0xf0, 0xfe, 0x10, 0x18,
15414 0x2b, 0x03, 0xfe, 0x7e, 0x18, 0x1a, 0x18, 0x87, 0x08, 0x0e, 0x03, 0x77, 0x04, 0xe7, 0x1a, 0x06,
15415 0xfe, 0xef, 0x12, 0xfe, 0xe1, 0x10, 0x1c, 0x0f, 0x1e, 0x01, 0x15, 0x05, 0x10, 0x50, 0x4d, 0xfe,
15416 0x78, 0x14, 0xfe, 0x34, 0x12, 0x59, 0x8c, 0x37, 0x38, 0xc7, 0xfe, 0xe9, 0x13, 0x1c, 0x0f, 0x3f,
15417 0x01, 0x15, 0x05, 0x10, 0x50, 0x4d, 0xfe, 0x56, 0x14, 0xe9, 0x59, 0x8c, 0x37, 0x38, 0xc7, 0xfe,
15418 0xe9, 0x13, 0x09, 0x0b, 0x03, 0xfe, 0x9c, 0xe7, 0x0b, 0x13, 0xfe, 0x15, 0x00, 0x7a, 0xa5, 0x31,
15419 0x01, 0xea, 0x09, 0x06, 0x03, 0x0a, 0x41, 0x38, 0x39, 0x08, 0x3f, 0x09, 0xa2, 0x01, 0x45, 0x11,
15420 0x48, 0x08, 0x1e, 0x09, 0x52, 0x01, 0x7e, 0x09, 0x06, 0x03, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90,
15421 0x36, 0xfe, 0xa8, 0x00, 0x21, 0x7b, 0xfe, 0x48, 0x55, 0x35, 0xfe, 0xc9, 0x55, 0x03, 0x29, 0xc6,
15422 0x5b, 0x16, 0xc6, 0x03, 0x0f, 0xc8, 0x01, 0x15, 0xf2, 0x0f, 0x7d, 0x01, 0x15, 0xfe, 0x49, 0x44,
15423 0x28, 0xfe, 0x06, 0x19, 0x0f, 0x1e, 0x01, 0x15, 0x05, 0x10, 0x50, 0x0f, 0x5f, 0x01, 0xaa, 0x0f,
15424 0x7d, 0x01, 0x15, 0x5b, 0x80, 0x03, 0xfe, 0x40, 0x5e, 0xfe, 0xe2, 0x08, 0xfe, 0xc0, 0x4c, 0x29,
15425 0x3e, 0x05, 0x10, 0xfe, 0x52, 0x12, 0x4d, 0x05, 0x00, 0xfe, 0x18, 0x12, 0xfe, 0xe1, 0x18, 0xfe,
15426 0x19, 0xf4, 0xfe, 0x7f, 0x00, 0xaf, 0xfe, 0xe2, 0x08, 0x5b, 0x4d, 0x40, 0x05, 0x7b, 0xab, 0xfe,
15427 0x82, 0x48, 0xfe, 0x01, 0x80, 0xfe, 0xd7, 0x10, 0xfe, 0xc4, 0x48, 0x08, 0x2d, 0x09, 0x3e, 0xfe,
15428 0x40, 0x5f, 0x1c, 0x01, 0x45, 0x11, 0xfe, 0xdd, 0x00, 0xfe, 0x14, 0x46, 0x08, 0x2d, 0x09, 0x3e,
15429 0x01, 0x45, 0x11, 0xfe, 0xdd, 0x00, 0xfe, 0x40, 0x4a, 0x72, 0xfe, 0x06, 0x17, 0xfe, 0x01, 0x07,
15430 0xfe, 0x82, 0x48, 0xfe, 0x04, 0x17, 0x03, 0xf5, 0x18, 0x79, 0xfe, 0x8e, 0x19, 0x04, 0xfe, 0x90,
15431 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xf5, 0xd4, 0x79, 0xfe, 0xa0, 0x19, 0x04, 0xfe, 0x92,
15432 0x00, 0xcf, 0x1d, 0xe0, 0xf5, 0xfe, 0x0b, 0x00, 0x79, 0xfe, 0xb2, 0x19, 0x04, 0xfe, 0x94, 0x00,
15433 0xcf, 0x22, 0xfe, 0x08, 0x10, 0x04, 0xfe, 0x96, 0x00, 0xcf, 0x8b, 0xfe, 0x4e, 0x45, 0xd8, 0xfe,
15434 0x0a, 0x45, 0xff, 0x04, 0x68, 0x54, 0xfe, 0xf1, 0x10, 0x1a, 0x74, 0xfe, 0x08, 0x1c, 0xfe, 0x67,
15435 0x19, 0xfe, 0x0a, 0x1c, 0xfe, 0x1a, 0xf4, 0xfe, 0x00, 0x04, 0xd8, 0xfe, 0x48, 0xf4, 0x18, 0x99,
15436 0xfe, 0xe6, 0x19, 0x08, 0x18, 0x03, 0x05, 0x84, 0xfe, 0x5a, 0xf0, 0xfe, 0xf6, 0x19, 0x20, 0xfe,
15437 0x09, 0x00, 0xfe, 0x34, 0x10, 0x05, 0x1d, 0xfe, 0x5a, 0xf0, 0xfe, 0x04, 0x1a, 0x20, 0xd5, 0xfe,
15438 0x26, 0x10, 0x05, 0x18, 0x87, 0x20, 0x8b, 0xe0, 0x05, 0x0b, 0x87, 0x20, 0xb1, 0xfe, 0x0e, 0x10,
15439 0x05, 0x06, 0x87, 0x20, 0x5e, 0xce, 0xb6, 0x03, 0x17, 0xfe, 0x09, 0x00, 0x01, 0x3b, 0x2f, 0xfe,
15440 0x34, 0x1a, 0x04, 0x76, 0xb7, 0x03, 0x1b, 0xfe, 0x54, 0x1a, 0xfe, 0x14, 0xf0, 0x0c, 0x2f, 0xfe,
15441 0x48, 0x1a, 0x1b, 0xfe, 0x54, 0x1a, 0xfe, 0x82, 0xf0, 0xfe, 0x4c, 0x1a, 0x03, 0xff, 0x15, 0x00,
15442 0x00,
15445 STATIC unsigned short _adv_asc38C0800_size =
15446 sizeof(_adv_asc38C0800_buf); /* 0x14F1 */
15447 STATIC ADV_DCNT _adv_asc38C0800_chksum =
15448 0x053503A5; /* Expanded checksum. */
15450 /* a_init.c */
15452 * EEPROM Configuration.
15454 * All drivers should use this structure to set the default EEPROM
15455 * configuration. The BIOS now uses this structure when it is built.
15456 * Additional structure information can be found in a_condor.h where
15457 * the structure is defined.
15459 STATIC ADVEEP_3550_CONFIG
15460 Default_3550_EEPROM_Config ASC_INITDATA = {
15461 ADV_EEPROM_BIOS_ENABLE, /* cfg_lsw */
15462 0x0000, /* cfg_msw */
15463 0xFFFF, /* disc_enable */
15464 0xFFFF, /* wdtr_able */
15465 0xFFFF, /* sdtr_able */
15466 0xFFFF, /* start_motor */
15467 0xFFFF, /* tagqng_able */
15468 0xFFFF, /* bios_scan */
15469 0, /* scam_tolerant */
15470 7, /* adapter_scsi_id */
15471 0, /* bios_boot_delay */
15472 3, /* scsi_reset_delay */
15473 0, /* bios_id_lun */
15474 0, /* termination */
15475 0, /* reserved1 */
15476 0xFFE7, /* bios_ctrl */
15477 0xFFFF, /* ultra_able */
15478 0, /* reserved2 */
15479 ASC_DEF_MAX_HOST_QNG, /* max_host_qng */
15480 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
15481 0, /* dvc_cntl */
15482 0, /* bug_fix */
15483 0, /* serial_number_word1 */
15484 0, /* serial_number_word2 */
15485 0, /* serial_number_word3 */
15486 0, /* check_sum */
15487 { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, /* oem_name[16] */
15488 0, /* dvc_err_code */
15489 0, /* adv_err_code */
15490 0, /* adv_err_addr */
15491 0, /* saved_dvc_err_code */
15492 0, /* saved_adv_err_code */
15493 0, /* saved_adv_err_addr */
15494 0 /* num_of_err */
15497 STATIC ADVEEP_38C0800_CONFIG
15498 Default_38C0800_EEPROM_Config ASC_INITDATA = {
15499 ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
15500 0x0000, /* 01 cfg_msw */
15501 0xFFFF, /* 02 disc_enable */
15502 0xFFFF, /* 03 wdtr_able */
15503 0x4444, /* 04 sdtr_speed1 */
15504 0xFFFF, /* 05 start_motor */
15505 0xFFFF, /* 06 tagqng_able */
15506 0xFFFF, /* 07 bios_scan */
15507 0, /* 08 scam_tolerant */
15508 7, /* 09 adapter_scsi_id */
15509 0, /* bios_boot_delay */
15510 3, /* 10 scsi_reset_delay */
15511 0, /* bios_id_lun */
15512 0, /* 11 termination_se */
15513 0, /* termination_lvd */
15514 0xFFE7, /* 12 bios_ctrl */
15515 0x4444, /* 13 sdtr_speed2 */
15516 0x4444, /* 14 sdtr_speed3 */
15517 ASC_DEF_MAX_HOST_QNG, /* 15 max_host_qng */
15518 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
15519 0, /* 16 dvc_cntl */
15520 0x4444, /* 17 sdtr_speed4 */
15521 0, /* 18 serial_number_word1 */
15522 0, /* 19 serial_number_word2 */
15523 0, /* 20 serial_number_word3 */
15524 0, /* 21 check_sum */
15525 { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, /* 22-29 oem_name[16] */
15526 0, /* 30 dvc_err_code */
15527 0, /* 31 adv_err_code */
15528 0, /* 32 adv_err_addr */
15529 0, /* 33 saved_dvc_err_code */
15530 0, /* 34 saved_adv_err_code */
15531 0, /* 35 saved_adv_err_addr */
15532 0, /* 36 reserved */
15533 0, /* 37 reserved */
15534 0, /* 38 reserved */
15535 0, /* 39 reserved */
15536 0, /* 40 reserved */
15537 0, /* 41 reserved */
15538 0, /* 42 reserved */
15539 0, /* 43 reserved */
15540 0, /* 44 reserved */
15541 0, /* 45 reserved */
15542 0, /* 46 reserved */
15543 0, /* 47 reserved */
15544 0, /* 48 reserved */
15545 0, /* 49 reserved */
15546 0, /* 50 reserved */
15547 0, /* 51 reserved */
15548 0, /* 52 reserved */
15549 0, /* 53 reserved */
15550 0, /* 54 reserved */
15551 0, /* 55 reserved */
15552 0, /* 56 cisptr_lsw */
15553 0, /* 57 cisprt_msw */
15554 ADV_PCI_VENDOR_ID, /* 58 subsysvid */
15555 ADV_PCI_DEVID_38C0800_REV1, /* 59 subsysid */
15556 0, /* 60 reserved */
15557 0, /* 61 reserved */
15558 0, /* 62 reserved */
15559 0 /* 63 reserved */
15563 * Initialize the ADV_DVC_VAR structure.
15565 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
15567 * For a non-fatal error return a warning code. If there are no warnings
15568 * then 0 is returned.
15570 ASC_INITFUNC(
15571 STATIC int,
15572 AdvInitGetConfig(ADV_DVC_VAR *asc_dvc)
15575 ushort warn_code;
15576 AdvPortAddr iop_base;
15577 uchar pci_cmd_reg;
15578 int status;
15580 warn_code = 0;
15581 asc_dvc->err_code = 0;
15582 iop_base = asc_dvc->iop_base;
15585 * PCI Command Register
15587 * Note: AscPCICmdRegBits_BusMastering definition (0x0007) includes
15588 * I/O Space Control, Memory Space Control and Bus Master Control bits.
15591 if (((pci_cmd_reg = DvcAdvReadPCIConfigByte(asc_dvc,
15592 AscPCIConfigCommandRegister))
15593 & AscPCICmdRegBits_BusMastering)
15594 != AscPCICmdRegBits_BusMastering)
15596 pci_cmd_reg |= AscPCICmdRegBits_BusMastering;
15598 DvcAdvWritePCIConfigByte(asc_dvc,
15599 AscPCIConfigCommandRegister, pci_cmd_reg);
15601 if (((DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigCommandRegister))
15602 & AscPCICmdRegBits_BusMastering)
15603 != AscPCICmdRegBits_BusMastering)
15605 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
15610 * PCI Latency Timer
15612 * If the "latency timer" register is 0x20 or above, then we don't need
15613 * to change it. Otherwise, set it to 0x20 (i.e. set it to 0x20 if it
15614 * comes up less than 0x20).
15616 if (DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer) < 0x20) {
15617 DvcAdvWritePCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer, 0x20);
15618 if (DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer) < 0x20)
15620 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
15625 * Save the state of the PCI Configuration Command Register
15626 * "Parity Error Response Control" Bit. If the bit is clear (0),
15627 * in AdvInitAsc3550/38C0800Driver() tell the microcode to ignore
15628 * DMA parity errors.
15630 asc_dvc->cfg->control_flag = 0;
15631 if (((DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigCommandRegister)
15632 & AscPCICmdRegBits_ParErrRespCtrl)) == 0)
15634 asc_dvc->cfg->control_flag |= CONTROL_FLAG_IGNORE_PERR;
15637 asc_dvc->cfg->lib_version = (ADV_LIB_VERSION_MAJOR << 8) |
15638 ADV_LIB_VERSION_MINOR;
15639 asc_dvc->cfg->chip_version =
15640 AdvGetChipVersion(iop_base, asc_dvc->bus_type);
15642 ASC_DBG2(1, "AdvInitGetConfig: iopb_chip_id_1: %x %x\n",
15643 (ushort) AdvReadByteRegister(iop_base, IOPB_CHIP_ID_1),
15644 (ushort) ADV_CHIP_ID_BYTE);
15646 ASC_DBG2(1, "AdvInitGetConfig: iopw_chip_id_0: %x %x\n",
15647 (ushort) AdvReadWordRegister(iop_base, IOPW_CHIP_ID_0),
15648 (ushort) ADV_CHIP_ID_WORD);
15651 * Reset the chip to start and allow register writes.
15653 if (AdvFindSignature(iop_base) == 0)
15655 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
15656 return ADV_ERROR;
15658 else {
15660 * The caller must set 'chip_type' to a valid setting.
15662 if (asc_dvc->chip_type != ADV_CHIP_ASC3550 &&
15663 asc_dvc->chip_type != ADV_CHIP_ASC38C0800 &&
15664 asc_dvc->chip_type != ADV_CHIP_ASC38C1600)
15666 asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE;
15667 return ADV_ERROR;
15671 * Reset Chip.
15673 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
15674 ADV_CTRL_REG_CMD_RESET);
15675 DvcSleepMilliSecond(100);
15676 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
15677 ADV_CTRL_REG_CMD_WR_IO_REG);
15679 if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800)
15681 if ((status = AdvInitFrom38C0800EEP(asc_dvc)) == ADV_ERROR)
15683 return ADV_ERROR;
15685 } else
15687 if ((status = AdvInitFrom3550EEP(asc_dvc)) == ADV_ERROR)
15689 return ADV_ERROR;
15692 warn_code |= status;
15695 return warn_code;
15699 * Initialize the ASC-3550.
15701 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
15703 * For a non-fatal error return a warning code. If there are no warnings
15704 * then 0 is returned.
15706 STATIC int
15707 AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
15709 AdvPortAddr iop_base;
15710 ushort warn_code;
15711 ADV_DCNT sum;
15712 int begin_addr;
15713 int end_addr;
15714 ushort code_sum;
15715 int word;
15716 int j;
15717 int adv_asc3550_expanded_size;
15718 ADV_CARR_T *carrp;
15719 ADV_DCNT contig_len;
15720 ADV_SDCNT buf_size;
15721 ADV_PADDR carr_paddr;
15722 int i;
15723 ushort scsi_cfg1;
15724 uchar tid;
15725 ushort bios_mem[ASC_MC_BIOSLEN/2]; /* BIOS RISC Memory 0x40-0x8F. */
15726 ushort wdtr_able = 0, sdtr_able, tagqng_able;
15727 uchar max_cmd[ADV_MAX_TID + 1];
15729 /* If there is already an error, don't continue. */
15730 if (asc_dvc->err_code != 0)
15732 return ADV_ERROR;
15736 * The caller must set 'chip_type' to ADV_CHIP_ASC3550.
15738 if (asc_dvc->chip_type != ADV_CHIP_ASC3550)
15740 asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE;
15741 return ADV_ERROR;
15744 warn_code = 0;
15745 iop_base = asc_dvc->iop_base;
15748 * Save the RISC memory BIOS region before writing the microcode.
15749 * The BIOS may already be loaded and using its RISC LRAM region
15750 * so its region must be saved and restored.
15752 * Note: This code makes the assumption, which is currently true,
15753 * that a chip reset does not clear RISC LRAM.
15755 for (i = 0; i < ASC_MC_BIOSLEN/2; i++)
15757 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]);
15761 * Save current per TID negotiated values.
15763 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM)/2] == 0x55AA)
15765 ushort bios_version, major, minor;
15767 bios_version = bios_mem[(ASC_MC_BIOS_VERSION - ASC_MC_BIOSMEM)/2];
15768 major = (bios_version >> 12) & 0xF;
15769 minor = (bios_version >> 8) & 0xF;
15770 if (major < 3 || (major == 3 && minor == 1))
15772 /* BIOS 3.1 and earlier location of 'wdtr_able' variable. */
15773 AdvReadWordLram(iop_base, 0x120, wdtr_able);
15774 } else
15776 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
15779 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
15780 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
15781 for (tid = 0; tid <= ADV_MAX_TID; tid++)
15783 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
15784 max_cmd[tid]);
15788 * Load the Microcode
15790 * Write the microcode image to RISC memory starting at address 0.
15792 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
15793 /* Assume the following compressed format of the microcode buffer:
15795 * 254 word (508 byte) table indexed by byte code followed
15796 * by the following byte codes:
15798 * 1-Byte Code:
15799 * 00: Emit word 0 in table.
15800 * 01: Emit word 1 in table.
15802 * FD: Emit word 253 in table.
15804 * Multi-Byte Code:
15805 * FE WW WW: (3 byte code) Word to emit is the next word WW WW.
15806 * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
15808 word = 0;
15809 for (i = 253 * 2; i < _adv_asc3550_size; i++)
15811 if (_adv_asc3550_buf[i] == 0xff)
15813 for (j = 0; j < _adv_asc3550_buf[i + 1]; j++)
15815 AdvWriteWordAutoIncLram(iop_base, (((ushort)
15816 _adv_asc3550_buf[i + 3] << 8) |
15817 _adv_asc3550_buf[i + 2]));
15818 word++;
15820 i += 3;
15821 } else if (_adv_asc3550_buf[i] == 0xfe)
15823 AdvWriteWordAutoIncLram(iop_base, (((ushort)
15824 _adv_asc3550_buf[i + 2] << 8) |
15825 _adv_asc3550_buf[i + 1]));
15826 i += 2;
15827 word++;
15828 } else
15830 AdvWriteWordAutoIncLram(iop_base, (((ushort)
15831 _adv_asc3550_buf[(_adv_asc3550_buf[i] * 2) + 1] << 8) |
15832 _adv_asc3550_buf[_adv_asc3550_buf[i] * 2]));
15833 word++;
15838 * Set 'word' for later use to clear the rest of memory and save
15839 * the expanded mcode size.
15841 word *= 2;
15842 adv_asc3550_expanded_size = word;
15845 * Clear the rest of ASC-3550 Internal RAM (8KB).
15847 for (; word < ADV_3550_MEMSIZE; word += 2)
15849 AdvWriteWordAutoIncLram(iop_base, 0);
15853 * Verify the microcode checksum.
15855 sum = 0;
15856 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
15858 for (word = 0; word < adv_asc3550_expanded_size; word += 2)
15860 sum += AdvReadWordAutoIncLram(iop_base);
15863 if (sum != _adv_asc3550_chksum)
15865 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
15866 return ADV_ERROR;
15870 * Restore the RISC memory BIOS region.
15872 for (i = 0; i < ASC_MC_BIOSLEN/2; i++)
15874 AdvWriteByteLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]);
15878 * Calculate and write the microcode code checksum to the microcode
15879 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
15881 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
15882 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
15883 code_sum = 0;
15884 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
15885 for (word = begin_addr; word < end_addr; word += 2)
15887 code_sum += AdvReadWordAutoIncLram(iop_base);
15889 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
15892 * Read and save microcode version and date.
15894 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE, asc_dvc->cfg->mcode_date);
15895 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM, asc_dvc->cfg->mcode_version);
15898 * Set the chip type to indicate the ASC3550.
15900 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC3550);
15903 * If the PCI Configuration Command Register "Parity Error Response
15904 * Control" Bit was clear (0), then set the microcode variable
15905 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
15906 * to ignore DMA parity errors.
15908 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR)
15911 * Note: Don't remove the use of a temporary variable in
15912 * the following code, otherwise the Microsoft C compiler
15913 * will turn the following lines into a no-op.
15915 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15916 word |= CONTROL_FLAG_IGNORE_PERR;
15917 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15921 * For ASC-3550, setting the START_CTL_EMFU [3:2] bits sets a FIFO
15922 * threshold of 128 bytes. This register is only accessible to the host.
15924 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
15925 START_CTL_EMFU | READ_CMD_MRM);
15928 * Microcode operating variables for WDTR, SDTR, and command tag
15929 * queuing will be set in AdvInquiryHandling() based on what a
15930 * device reports it is capable of in Inquiry byte 7.
15932 * If SCSI Bus Resets have been disabled, then directly set
15933 * SDTR and WDTR from the EEPROM configuration. This will allow
15934 * the BIOS and warm boot to work without a SCSI bus hang on
15935 * the Inquiry caused by host and target mismatched DTR values.
15936 * Without the SCSI Bus Reset, before an Inquiry a device can't
15937 * be assumed to be in Asynchronous, Narrow mode.
15939 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0)
15941 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, asc_dvc->wdtr_able);
15942 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, asc_dvc->sdtr_able);
15946 * Set microcode operating variables for SDTR_SPEED1, SDTR_SPEED2,
15947 * SDTR_SPEED3, and SDTR_SPEED4 based on the ULTRA EEPROM per TID
15948 * bitmask. These values determine the maximum SDTR speed negotiated
15949 * with a device.
15951 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
15952 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
15953 * without determining here whether the device supports SDTR.
15955 * 4-bit speed SDTR speed name
15956 * =========== ===============
15957 * 0000b (0x0) SDTR disabled
15958 * 0001b (0x1) 5 Mhz
15959 * 0010b (0x2) 10 Mhz
15960 * 0011b (0x3) 20 Mhz (Ultra)
15961 * 0100b (0x4) 40 Mhz (LVD/Ultra2)
15962 * 0101b (0x5) 80 Mhz (LVD2/Ultra3)
15963 * 0110b (0x6) Undefined
15965 * 1111b (0xF) Undefined
15967 word = 0;
15968 for (tid = 0; tid <= ADV_MAX_TID; tid++)
15970 if (ADV_TID_TO_TIDMASK(tid) & asc_dvc->ultra_able)
15972 /* Set Ultra speed for TID 'tid'. */
15973 word |= (0x3 << (4 * (tid % 4)));
15974 } else
15976 /* Set Fast speed for TID 'tid'. */
15977 word |= (0x2 << (4 * (tid % 4)));
15979 if (tid == 3) /* Check if done with sdtr_speed1. */
15981 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, word);
15982 word = 0;
15983 } else if (tid == 7) /* Check if done with sdtr_speed2. */
15985 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, word);
15986 word = 0;
15987 } else if (tid == 11) /* Check if done with sdtr_speed3. */
15989 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, word);
15990 word = 0;
15991 } else if (tid == 15) /* Check if done with sdtr_speed4. */
15993 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, word);
15994 /* End of loop. */
15999 * Set microcode operating variable for the disconnect per TID bitmask.
16001 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE, asc_dvc->cfg->disc_enable);
16005 * Set SCSI_CFG0 Microcode Default Value.
16007 * The microcode will set the SCSI_CFG0 register using this value
16008 * after it is started below.
16010 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
16011 PARITY_EN | SEL_TMO_LONG | OUR_ID_EN | asc_dvc->chip_scsi_id);
16014 * Determine SCSI_CFG1 Microcode Default Value.
16016 * The microcode will set the SCSI_CFG1 register using this value
16017 * after it is started below.
16020 /* Read current SCSI_CFG1 Register value. */
16021 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
16024 * If all three connectors are in use, return an error.
16026 if ((scsi_cfg1 & CABLE_ILLEGAL_A) == 0 ||
16027 (scsi_cfg1 & CABLE_ILLEGAL_B) == 0)
16029 asc_dvc->err_code |= ASC_IERR_ILLEGAL_CONNECTION;
16030 return ADV_ERROR;
16034 * If the internal narrow cable is reversed all of the SCSI_CTRL
16035 * register signals will be set. Check for and return an error if
16036 * this condition is found.
16038 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07)
16040 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
16041 return ADV_ERROR;
16045 * If this is a differential board and a single-ended device
16046 * is attached to one of the connectors, return an error.
16048 if ((scsi_cfg1 & DIFF_MODE) && (scsi_cfg1 & DIFF_SENSE) == 0)
16050 asc_dvc->err_code |= ASC_IERR_SINGLE_END_DEVICE;
16051 return ADV_ERROR;
16055 * If automatic termination control is enabled, then set the
16056 * termination value based on a table listed in a_condor.h.
16058 * If manual termination was specified with an EEPROM setting
16059 * then 'termination' was set-up in AdvInitFrom3550EEPROM() and
16060 * is ready to be 'ored' into SCSI_CFG1.
16062 if (asc_dvc->cfg->termination == 0)
16065 * The software always controls termination by setting TERM_CTL_SEL.
16066 * If TERM_CTL_SEL were set to 0, the hardware would set termination.
16068 asc_dvc->cfg->termination |= TERM_CTL_SEL;
16070 switch(scsi_cfg1 & CABLE_DETECT)
16072 /* TERM_CTL_H: on, TERM_CTL_L: on */
16073 case 0x3: case 0x7: case 0xB: case 0xD: case 0xE: case 0xF:
16074 asc_dvc->cfg->termination |= (TERM_CTL_H | TERM_CTL_L);
16075 break;
16077 /* TERM_CTL_H: on, TERM_CTL_L: off */
16078 case 0x1: case 0x5: case 0x9: case 0xA: case 0xC:
16079 asc_dvc->cfg->termination |= TERM_CTL_H;
16080 break;
16082 /* TERM_CTL_H: off, TERM_CTL_L: off */
16083 case 0x2: case 0x6:
16084 break;
16089 * Clear any set TERM_CTL_H and TERM_CTL_L bits.
16091 scsi_cfg1 &= ~TERM_CTL;
16094 * Invert the TERM_CTL_H and TERM_CTL_L bits and then
16095 * set 'scsi_cfg1'. The TERM_POL bit does not need to be
16096 * referenced, because the hardware internally inverts
16097 * the Termination High and Low bits if TERM_POL is set.
16099 scsi_cfg1 |= (TERM_CTL_SEL | (~asc_dvc->cfg->termination & TERM_CTL));
16102 * Set SCSI_CFG1 Microcode Default Value
16104 * Set filter value and possibly modified termination control
16105 * bits in the Microcode SCSI_CFG1 Register Value.
16107 * The microcode will set the SCSI_CFG1 register using this value
16108 * after it is started below.
16110 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1,
16111 FLTR_DISABLE | scsi_cfg1);
16114 * Set MEM_CFG Microcode Default Value
16116 * The microcode will set the MEM_CFG register using this value
16117 * after it is started below.
16119 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
16120 * are defined.
16122 * ASC-3550 has 8KB internal memory.
16124 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
16125 BIOS_EN | RAM_SZ_8KB);
16128 * Set SEL_MASK Microcode Default Value
16130 * The microcode will set the SEL_MASK register using this value
16131 * after it is started below.
16133 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
16134 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
16137 * Build carrier freelist.
16139 * Driver must have already allocated memory and set 'carrier_buf'.
16141 ASC_ASSERT(asc_dvc->carrier_buf != NULL);
16143 carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
16144 asc_dvc->carr_freelist = NULL;
16145 if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf)
16147 buf_size = ADV_CARRIER_BUFSIZE;
16148 } else
16150 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
16153 do {
16155 * Get physical address of the carrier 'carrp'.
16157 contig_len = sizeof(ADV_CARR_T);
16158 carr_paddr = cpu_to_le32(DvcGetPhyAddr(asc_dvc, NULL, (uchar *) carrp,
16159 (ADV_SDCNT *) &contig_len, ADV_IS_CARRIER_FLAG));
16161 buf_size -= sizeof(ADV_CARR_T);
16164 * If the current carrier is not physically contiguous, then
16165 * maybe there was a page crossing. Try the next carrier aligned
16166 * start address.
16168 if (contig_len < sizeof(ADV_CARR_T))
16170 carrp++;
16171 continue;
16174 carrp->carr_pa = carr_paddr;
16175 carrp->carr_va = ADV_VADDR_TO_U32(carrp);
16178 * Insert the carrier at the beginning of the freelist.
16180 carrp->next_vpa = ADV_VADDR_TO_U32(asc_dvc->carr_freelist);
16181 asc_dvc->carr_freelist = carrp;
16183 carrp++;
16185 while (buf_size > 0);
16188 * Set-up the Host->RISC Initiator Command Queue (ICQ).
16191 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL)
16193 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
16194 return ADV_ERROR;
16196 asc_dvc->carr_freelist =
16197 (ADV_CARR_T *) ADV_U32_TO_VADDR(asc_dvc->icq_sp->next_vpa);
16200 * The first command issued will be placed in the stopper carrier.
16202 asc_dvc->icq_sp->next_vpa = ASC_CQ_STOPPER;
16205 * Set RISC ICQ physical address start value.
16207 AdvWriteDWordLram(iop_base, ASC_MC_ICQ,
16208 cpu_to_le32(asc_dvc->icq_sp->carr_pa));
16211 * Set-up the RISC->Host Initiator Response Queue (IRQ).
16213 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL)
16215 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
16216 return ADV_ERROR;
16218 asc_dvc->carr_freelist =
16219 (ADV_CARR_T *) ADV_U32_TO_VADDR(asc_dvc->irq_sp->next_vpa);
16222 * The first command completed by the RISC will be placed in
16223 * the stopper.
16225 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
16226 * completed the RISC will set the ASC_RQ_STOPPER bit.
16228 asc_dvc->irq_sp->next_vpa = ASC_CQ_STOPPER;
16231 * Set RISC IRQ physical address start value.
16233 AdvWriteDWordLram(iop_base, ASC_MC_IRQ,
16234 cpu_to_le32(asc_dvc->irq_sp->carr_pa));
16235 asc_dvc->carr_pending_cnt = 0;
16237 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
16238 (ADV_INTR_ENABLE_HOST_INTR | ADV_INTR_ENABLE_GLOBAL_INTR));
16241 * Note: Don't remove the use of a temporary variable in
16242 * the following code, otherwise the Microsoft C compiler
16243 * will turn the following lines into a no-op.
16245 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
16246 AdvWriteWordRegister(iop_base, IOPW_PC, word);
16248 /* finally, finally, gentlemen, start your engine */
16249 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
16252 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
16253 * Resets should be performed. The RISC has to be running
16254 * to issue a SCSI Bus Reset.
16256 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS)
16259 * If the BIOS Signature is present in memory, restore the
16260 * BIOS Handshake Configuration Table and do not perform
16261 * a SCSI Bus Reset.
16263 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM)/2] == 0x55AA)
16266 * Restore per TID negotiated values.
16268 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
16269 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
16270 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
16271 for (tid = 0; tid <= ADV_MAX_TID; tid++)
16273 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
16274 max_cmd[tid]);
16276 } else
16278 if (AdvResetSB(asc_dvc) != ADV_TRUE)
16280 warn_code = ASC_WARN_BUSRESET_ERROR;
16285 return warn_code;
16289 * Initialize the ASC-38C0800.
16291 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
16293 * For a non-fatal error return a warning code. If there are no warnings
16294 * then 0 is returned.
16296 STATIC int
16297 AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc)
16299 AdvPortAddr iop_base;
16300 ushort warn_code;
16301 ADV_DCNT sum;
16302 int begin_addr;
16303 int end_addr;
16304 ushort code_sum;
16305 int word;
16306 int j;
16307 int adv_asc38C0800_expanded_size;
16308 ADV_CARR_T *carrp;
16309 ADV_DCNT contig_len;
16310 ADV_SDCNT buf_size;
16311 ADV_PADDR carr_paddr;
16312 int i;
16313 ushort scsi_cfg1;
16314 uchar byte;
16315 uchar tid;
16316 ushort bios_mem[ASC_MC_BIOSLEN/2]; /* BIOS RISC Memory 0x40-0x8F. */
16317 ushort wdtr_able, sdtr_able, tagqng_able;
16318 uchar max_cmd[ADV_MAX_TID + 1];
16320 /* If there is already an error, don't continue. */
16321 if (asc_dvc->err_code != 0)
16323 return ADV_ERROR;
16327 * The caller must set 'chip_type' to ADV_CHIP_ASC38C0800.
16329 if (asc_dvc->chip_type != ADV_CHIP_ASC38C0800)
16331 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
16332 return ADV_ERROR;
16335 warn_code = 0;
16336 iop_base = asc_dvc->iop_base;
16339 * Save the RISC memory BIOS region before writing the microcode.
16340 * The BIOS may already be loaded and using its RISC LRAM region
16341 * so its region must be saved and restored.
16343 * Note: This code makes the assumption, which is currently true,
16344 * that a chip reset does not clear RISC LRAM.
16346 for (i = 0; i < ASC_MC_BIOSLEN/2; i++)
16348 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]);
16352 * Save current per TID negotiated values.
16354 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
16355 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
16356 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
16357 for (tid = 0; tid <= ADV_MAX_TID; tid++)
16359 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
16360 max_cmd[tid]);
16364 * RAM BIST (RAM Built-In Self Test)
16366 * Address : I/O base + offset 0x38h register (byte).
16367 * Function: Bit 7-6(RW) : RAM mode
16368 * Normal Mode : 0x00
16369 * Pre-test Mode : 0x40
16370 * RAM Test Mode : 0x80
16371 * Bit 5 : unused
16372 * Bit 4(RO) : Done bit
16373 * Bit 3-0(RO) : Status
16374 * Host Error : 0x08
16375 * Int_RAM Error : 0x04
16376 * RISC Error : 0x02
16377 * SCSI Error : 0x01
16378 * No Error : 0x00
16380 * Note: RAM BIST code should be put right here, before loading the
16381 * microcode and after saving the RISC memory BIOS region.
16385 * LRAM Pre-test
16387 * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
16388 * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
16389 * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
16390 * to NORMAL_MODE, return an error too.
16392 for (i = 0; i < 2; i++)
16394 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
16395 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
16396 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
16397 if ((byte & RAM_TEST_DONE) == 0 || (byte & 0x0F) != PRE_TEST_VALUE)
16399 asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
16400 return ADV_ERROR;
16403 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
16404 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
16405 if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
16406 != NORMAL_VALUE)
16408 asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
16409 return ADV_ERROR;
16414 * LRAM Test - It takes about 1.5 ms to run through the test.
16416 * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
16417 * If Done bit not set or Status not 0, save register byte, set the
16418 * err_code, and return an error.
16420 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
16421 DvcSleepMilliSecond(10); /* Wait for 10ms before checking status. */
16423 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
16424 if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0)
16426 /* Get here if Done bit not set or Status not 0. */
16427 asc_dvc->bist_err_code = byte; /* for BIOS display message */
16428 asc_dvc->err_code |= ASC_IERR_BIST_RAM_TEST;
16429 return ADV_ERROR;
16432 /* We need to reset back to normal mode after LRAM test passes. */
16433 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
16436 * Load the Microcode
16438 * Write the microcode image to RISC memory starting at address 0.
16441 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
16443 /* Assume the following compressed format of the microcode buffer:
16445 * 254 word (508 byte) table indexed by byte code followed
16446 * by the following byte codes:
16448 * 1-Byte Code:
16449 * 00: Emit word 0 in table.
16450 * 01: Emit word 1 in table.
16452 * FD: Emit word 253 in table.
16454 * Multi-Byte Code:
16455 * FE WW WW: (3 byte code) Word to emit is the next word WW WW.
16456 * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
16458 word = 0;
16459 for (i = 253 * 2; i < _adv_asc38C0800_size; i++)
16461 if (_adv_asc38C0800_buf[i] == 0xff)
16463 for (j = 0; j < _adv_asc38C0800_buf[i + 1]; j++)
16465 AdvWriteWordAutoIncLram(iop_base, (((ushort)
16466 _adv_asc38C0800_buf[i + 3] << 8) |
16467 _adv_asc38C0800_buf[i + 2]));
16468 word++;
16470 i += 3;
16471 } else if (_adv_asc38C0800_buf[i] == 0xfe)
16473 AdvWriteWordAutoIncLram(iop_base, (((ushort)
16474 _adv_asc38C0800_buf[i + 2] << 8) |
16475 _adv_asc38C0800_buf[i + 1]));
16476 i += 2;
16477 word++;
16478 } else
16480 AdvWriteWordAutoIncLram(iop_base, (((ushort)
16481 _adv_asc38C0800_buf[(_adv_asc38C0800_buf[i] * 2) + 1] << 8) |
16482 _adv_asc38C0800_buf[_adv_asc38C0800_buf[i] * 2]));
16483 word++;
16488 * Set 'word' for later use to clear the rest of memory and save
16489 * the expanded mcode size.
16491 word *= 2;
16492 adv_asc38C0800_expanded_size = word;
16495 * Clear the rest of ASC-38C0800 Internal RAM (16KB).
16497 for (; word < ADV_38C0800_MEMSIZE; word += 2)
16499 AdvWriteWordAutoIncLram(iop_base, 0);
16503 * Verify the microcode checksum.
16505 sum = 0;
16506 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
16508 for (word = 0; word < adv_asc38C0800_expanded_size; word += 2)
16510 sum += AdvReadWordAutoIncLram(iop_base);
16512 ASC_DBG2(1, "AdvInitAsc38C0800Driver: word %d, i %d\n", word, i);
16514 ASC_DBG2(1,
16515 "AdvInitAsc38C0800Driver: sum 0x%lx, _adv_asc38C0800_chksum 0x%lx\n",
16516 (ulong) sum, (ulong) _adv_asc38C0800_chksum);
16518 if (sum != _adv_asc38C0800_chksum)
16520 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
16521 return ADV_ERROR;
16525 * Restore the RISC memory BIOS region.
16527 for (i = 0; i < ASC_MC_BIOSLEN/2; i++)
16529 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]);
16533 * Calculate and write the microcode code checksum to the microcode
16534 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
16536 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
16537 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
16538 code_sum = 0;
16539 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
16540 for (word = begin_addr; word < end_addr; word += 2)
16542 code_sum += AdvReadWordAutoIncLram(iop_base);
16544 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
16547 * Read microcode version and date.
16549 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE, asc_dvc->cfg->mcode_date);
16550 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM, asc_dvc->cfg->mcode_version);
16553 * Set the chip type to indicate the ASC38C0800.
16555 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C0800);
16558 * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
16559 * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
16560 * cable detection and then we are able to read C_DET[3:0].
16562 * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
16563 * Microcode Default Value' section below.
16565 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
16566 AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1, scsi_cfg1 | DIS_TERM_DRV);
16569 * If the PCI Configuration Command Register "Parity Error Response
16570 * Control" Bit was clear (0), then set the microcode variable
16571 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
16572 * to ignore DMA parity errors.
16574 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR)
16577 * Note: Don't remove the use of a temporary variable in
16578 * the following code, otherwise the Microsoft C compiler
16579 * will turn the following lines into a no-op.
16581 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
16582 word |= CONTROL_FLAG_IGNORE_PERR;
16583 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
16587 * For ASC-38C0800, set FIFO_THRESH_80B [6:4] bits and START_CTL_TH [3:2]
16588 * bits for the default FIFO threshold.
16590 * Note: ASC-38C0800 FIFO threshold has been changed to 256 bytes.
16592 * For DMA Errata #4 set the BC_THRESH_ENB bit.
16594 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
16595 BC_THRESH_ENB | FIFO_THRESH_80B | START_CTL_TH | READ_CMD_MRM);
16598 * Microcode operating variables for WDTR, SDTR, and command tag
16599 * queuing will be set in AdvInquiryHandling() based on what a
16600 * device reports it is capable of in Inquiry byte 7.
16602 * If SCSI Bus Resets have been disabled, then directly set
16603 * SDTR and WDTR from the EEPROM configuration. This will allow
16604 * the BIOS and warm boot to work without a SCSI bus hang on
16605 * the Inquiry caused by host and target mismatched DTR values.
16606 * Without the SCSI Bus Reset, before an Inquiry a device can't
16607 * be assumed to be in Asynchronous, Narrow mode.
16609 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0)
16611 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, asc_dvc->wdtr_able);
16612 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, asc_dvc->sdtr_able);
16616 * Set microcode operating variables for DISC and SDTR_SPEED1,
16617 * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
16618 * configuration values.
16620 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
16621 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
16622 * without determining here whether the device supports SDTR.
16624 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE, asc_dvc->cfg->disc_enable);
16625 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
16626 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
16627 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
16628 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
16631 * Set SCSI_CFG0 Microcode Default Value.
16633 * The microcode will set the SCSI_CFG0 register using this value
16634 * after it is started below.
16636 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
16637 PARITY_EN | SEL_TMO_LONG | OUR_ID_EN | asc_dvc->chip_scsi_id);
16640 * Determine SCSI_CFG1 Microcode Default Value.
16642 * The microcode will set the SCSI_CFG1 register using this value
16643 * after it is started below.
16646 /* Read current SCSI_CFG1 Register value. */
16647 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
16650 * If the internal narrow cable is reversed all of the SCSI_CTRL
16651 * register signals will be set. Check for and return an error if
16652 * this condition is found.
16654 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07)
16656 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
16657 return ADV_ERROR;
16661 * All kind of combinations of devices attached to one of four connectors
16662 * are acceptable except HVD device attached. For example, LVD device can
16663 * be attached to SE connector while SE device attached to LVD connector.
16664 * If LVD device attached to SE connector, it only runs up to Ultra speed.
16666 * If an HVD device is attached to one of LVD connectors, return an error.
16667 * However, there is no way to detect HVD device attached to SE connectors.
16669 if (scsi_cfg1 & HVD)
16671 asc_dvc->err_code |= ASC_IERR_HVD_DEVICE;
16672 return ADV_ERROR;
16676 * If either SE or LVD automatic termination control is enabled, then
16677 * set the termination value based on a table listed in a_condor.h.
16679 * If manual termination was specified with an EEPROM setting then
16680 * 'termination' was set-up in AdvInitFrom38C0800EEPROM() and is ready to
16681 * be 'ored' into SCSI_CFG1.
16683 if ((asc_dvc->cfg->termination & TERM_SE) == 0)
16685 /* SE automatic termination control is enabled. */
16686 switch(scsi_cfg1 & C_DET_SE)
16688 /* TERM_SE_HI: on, TERM_SE_LO: on */
16689 case 0x1: case 0x2: case 0x3:
16690 asc_dvc->cfg->termination |= TERM_SE;
16691 break;
16693 /* TERM_SE_HI: on, TERM_SE_LO: off */
16694 case 0x0:
16695 asc_dvc->cfg->termination |= TERM_SE_HI;
16696 break;
16700 if ((asc_dvc->cfg->termination & TERM_LVD) == 0)
16702 /* LVD automatic termination control is enabled. */
16703 switch(scsi_cfg1 & C_DET_LVD)
16705 /* TERM_LVD_HI: on, TERM_LVD_LO: on */
16706 case 0x4: case 0x8: case 0xC:
16707 asc_dvc->cfg->termination |= TERM_LVD;
16708 break;
16710 /* TERM_LVD_HI: off, TERM_LVD_LO: off */
16711 case 0x0:
16712 break;
16717 * Clear any set TERM_SE and TERM_LVD bits.
16719 scsi_cfg1 &= (~TERM_SE & ~TERM_LVD);
16722 * Invert the TERM_SE and TERM_LVD bits and then set 'scsi_cfg1'.
16724 scsi_cfg1 |= (~asc_dvc->cfg->termination & 0xF0);
16727 * Clear BIG_ENDIAN, DIS_TERM_DRV, Terminator Polarity and HVD/LVD/SE bits
16728 * and set possibly modified termination control bits in the Microcode
16729 * SCSI_CFG1 Register Value.
16731 scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL & ~HVD_LVD_SE);
16734 * Set SCSI_CFG1 Microcode Default Value
16736 * Set possibly modified termination control and reset DIS_TERM_DRV
16737 * bits in the Microcode SCSI_CFG1 Register Value.
16739 * The microcode will set the SCSI_CFG1 register using this value
16740 * after it is started below.
16742 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
16745 * Set MEM_CFG Microcode Default Value
16747 * The microcode will set the MEM_CFG register using this value
16748 * after it is started below.
16750 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
16751 * are defined.
16753 * ASC-38C0800 has 16KB internal memory.
16755 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
16756 BIOS_EN | RAM_SZ_16KB);
16759 * Set SEL_MASK Microcode Default Value
16761 * The microcode will set the SEL_MASK register using this value
16762 * after it is started below.
16764 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
16765 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
16768 * Build the carrier freelist.
16770 * Driver must have already allocated memory and set 'carrier_buf'.
16772 ASC_ASSERT(asc_dvc->carrier_buf != NULL);
16774 carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
16775 asc_dvc->carr_freelist = NULL;
16776 if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf)
16778 buf_size = ADV_CARRIER_BUFSIZE;
16779 } else
16781 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
16784 do {
16786 * Get physical address for the carrier 'carrp'.
16788 contig_len = sizeof(ADV_CARR_T);
16789 carr_paddr = cpu_to_le32(DvcGetPhyAddr(asc_dvc, NULL, (uchar *) carrp,
16790 (ADV_SDCNT *) &contig_len, ADV_IS_CARRIER_FLAG));
16792 buf_size -= sizeof(ADV_CARR_T);
16795 * If the current carrier is not physically contiguous, then
16796 * maybe there was a page crossing. Try the next carrier aligned
16797 * start address.
16799 if (contig_len < sizeof(ADV_CARR_T))
16801 carrp++;
16802 continue;
16805 carrp->carr_pa = carr_paddr;
16806 carrp->carr_va = ADV_VADDR_TO_U32(carrp);
16809 * Insert the carrier at the beginning of the freelist.
16811 carrp->next_vpa = ADV_VADDR_TO_U32(asc_dvc->carr_freelist);
16812 asc_dvc->carr_freelist = carrp;
16814 carrp++;
16816 while (buf_size > 0);
16819 * Set-up the Host->RISC Initiator Command Queue (ICQ).
16822 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL)
16824 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
16825 return ADV_ERROR;
16827 asc_dvc->carr_freelist =
16828 (ADV_CARR_T *) ADV_U32_TO_VADDR(asc_dvc->icq_sp->next_vpa);
16831 * The first command issued will be placed in the stopper carrier.
16833 asc_dvc->icq_sp->next_vpa = ASC_CQ_STOPPER;
16836 * Set RISC ICQ physical address start value.
16838 AdvWriteDWordLram(iop_base, ASC_MC_ICQ,
16839 cpu_to_le32(asc_dvc->icq_sp->carr_pa));
16842 * Set-up the RISC->Host Initiator Response Queue (IRQ).
16844 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL)
16846 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
16847 return ADV_ERROR;
16849 asc_dvc->carr_freelist =
16850 (ADV_CARR_T *) ADV_U32_TO_VADDR(asc_dvc->irq_sp->next_vpa);
16853 * The first command completed by the RISC will be placed in
16854 * the stopper.
16856 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
16857 * completed the RISC will set the ASC_RQ_STOPPER bit.
16859 asc_dvc->irq_sp->next_vpa = ASC_CQ_STOPPER;
16862 * Set RISC IRQ physical address start value.
16864 AdvWriteDWordLram(iop_base, ASC_MC_IRQ,
16865 cpu_to_le32(asc_dvc->irq_sp->carr_pa));
16866 asc_dvc->carr_pending_cnt = 0;
16868 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
16869 (ADV_INTR_ENABLE_HOST_INTR | ADV_INTR_ENABLE_GLOBAL_INTR));
16871 * Note: Don't remove the use of a temporary variable in
16872 * the following code, otherwise the Microsoft C compiler
16873 * will turn the following lines into a no-op.
16875 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
16876 AdvWriteWordRegister(iop_base, IOPW_PC, word);
16878 /* finally, finally, gentlemen, start your engine */
16879 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
16882 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
16883 * Resets should be performed. The RISC has to be running
16884 * to issue a SCSI Bus Reset.
16886 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS)
16889 * If the BIOS Signature is present in memory, restore the
16890 * BIOS Handshake Configuration Table and do not perform
16891 * a SCSI Bus Reset.
16893 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM)/2] == 0x55AA)
16896 * Restore per TID negotiated values.
16898 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
16899 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
16900 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
16901 for (tid = 0; tid <= ADV_MAX_TID; tid++)
16903 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
16904 max_cmd[tid]);
16906 } else
16908 if (AdvResetSB(asc_dvc) != ADV_TRUE)
16910 warn_code = ASC_WARN_BUSRESET_ERROR;
16915 return warn_code;
16919 * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
16920 * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
16921 * all of this is done.
16923 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
16925 * For a non-fatal error return a warning code. If there are no warnings
16926 * then 0 is returned.
16928 * Note: Chip is stopped on entry.
16930 ASC_INITFUNC(
16931 STATIC int,
16932 AdvInitFrom3550EEP(ADV_DVC_VAR *asc_dvc)
16935 AdvPortAddr iop_base;
16936 ushort warn_code;
16937 ADVEEP_3550_CONFIG eep_config;
16938 int i;
16940 iop_base = asc_dvc->iop_base;
16942 warn_code = 0;
16945 * Read the board's EEPROM configuration.
16947 * Set default values if a bad checksum is found.
16949 * XXX - Don't handle big-endian access to EEPROM yet.
16951 if (AdvGet3550EEPConfig(iop_base, &eep_config) != eep_config.check_sum)
16953 warn_code |= ASC_WARN_EEPROM_CHKSUM;
16956 * Set EEPROM default values.
16958 for (i = 0; i < sizeof(ADVEEP_3550_CONFIG); i++)
16960 *((uchar *) &eep_config + i) =
16961 *((uchar *) &Default_3550_EEPROM_Config + i);
16965 * Assume the 6 byte board serial number that was read
16966 * from EEPROM is correct even if the EEPROM checksum
16967 * failed.
16969 eep_config.serial_number_word3 =
16970 AdvReadEEPWord(iop_base, ASC_EEP_DVC_CFG_END - 1);
16972 eep_config.serial_number_word2 =
16973 AdvReadEEPWord(iop_base, ASC_EEP_DVC_CFG_END - 2);
16975 eep_config.serial_number_word1 =
16976 AdvReadEEPWord(iop_base, ASC_EEP_DVC_CFG_END - 3);
16978 AdvSet3550EEPConfig(iop_base, &eep_config);
16981 * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
16982 * EEPROM configuration that was read.
16984 * This is the mapping of EEPROM fields to Adv Library fields.
16986 asc_dvc->wdtr_able = eep_config.wdtr_able;
16987 asc_dvc->sdtr_able = eep_config.sdtr_able;
16988 asc_dvc->ultra_able = eep_config.ultra_able;
16989 asc_dvc->tagqng_able = eep_config.tagqng_able;
16990 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
16991 asc_dvc->max_host_qng = eep_config.max_host_qng;
16992 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16993 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
16994 asc_dvc->start_motor = eep_config.start_motor;
16995 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
16996 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
16997 asc_dvc->no_scam = eep_config.scam_tolerant;
16998 asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
16999 asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
17000 asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
17003 * Set the host maximum queuing (max. 253, min. 16) and the per device
17004 * maximum queuing (max. 63, min. 4).
17006 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG)
17008 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
17009 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG)
17011 /* If the value is zero, assume it is uninitialized. */
17012 if (eep_config.max_host_qng == 0)
17014 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
17015 } else
17017 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
17021 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG)
17023 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
17024 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG)
17026 /* If the value is zero, assume it is uninitialized. */
17027 if (eep_config.max_dvc_qng == 0)
17029 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
17030 } else
17032 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
17037 * If 'max_dvc_qng' is greater than 'max_host_qng', then
17038 * set 'max_dvc_qng' to 'max_host_qng'.
17040 if (eep_config.max_dvc_qng > eep_config.max_host_qng)
17042 eep_config.max_dvc_qng = eep_config.max_host_qng;
17046 * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
17047 * values based on possibly adjusted EEPROM values.
17049 asc_dvc->max_host_qng = eep_config.max_host_qng;
17050 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
17054 * If the EEPROM 'termination' field is set to automatic (0), then set
17055 * the ADV_DVC_CFG 'termination' field to automatic also.
17057 * If the termination is specified with a non-zero 'termination'
17058 * value check that a legal value is set and set the ADV_DVC_CFG
17059 * 'termination' field appropriately.
17061 if (eep_config.termination == 0)
17063 asc_dvc->cfg->termination = 0; /* auto termination */
17064 } else
17066 /* Enable manual control with low off / high off. */
17067 if (eep_config.termination == 1)
17069 asc_dvc->cfg->termination = TERM_CTL_SEL;
17071 /* Enable manual control with low off / high on. */
17072 } else if (eep_config.termination == 2)
17074 asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H;
17076 /* Enable manual control with low on / high on. */
17077 } else if (eep_config.termination == 3)
17079 asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H | TERM_CTL_L;
17080 } else
17083 * The EEPROM 'termination' field contains a bad value. Use
17084 * automatic termination instead.
17086 asc_dvc->cfg->termination = 0;
17087 warn_code |= ASC_WARN_EEPROM_TERMINATION;
17091 return warn_code;
17095 * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
17096 * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
17097 * all of this is done.
17099 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
17101 * For a non-fatal error return a warning code. If there are no warnings
17102 * then 0 is returned.
17104 * Note: Chip is stopped on entry.
17106 ASC_INITFUNC(
17107 STATIC int,
17108 AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_dvc)
17111 AdvPortAddr iop_base;
17112 ushort warn_code;
17113 ADVEEP_38C0800_CONFIG eep_config;
17114 int i;
17115 uchar tid, termination;
17116 ushort sdtr_speed = 0;
17118 iop_base = asc_dvc->iop_base;
17120 warn_code = 0;
17123 * Read the board's EEPROM configuration.
17125 * Set default values if a bad checksum is found.
17127 * XXX - Don't handle big-endian access to EEPROM yet.
17129 if (AdvGet38C0800EEPConfig(iop_base, &eep_config) != eep_config.check_sum)
17131 warn_code |= ASC_WARN_EEPROM_CHKSUM;
17134 * Set EEPROM default values.
17136 for (i = 0; i < sizeof(ADVEEP_38C0800_CONFIG); i++)
17138 *((uchar *) &eep_config + i) =
17139 *((uchar *) &Default_38C0800_EEPROM_Config + i);
17143 * Assume the 6 byte board serial number that was read
17144 * from EEPROM is correct even if the EEPROM checksum
17145 * failed.
17147 eep_config.serial_number_word3 =
17148 AdvReadEEPWord(iop_base, ASC_EEP_DVC_CFG_END - 1);
17150 eep_config.serial_number_word2 =
17151 AdvReadEEPWord(iop_base, ASC_EEP_DVC_CFG_END - 2);
17153 eep_config.serial_number_word1 =
17154 AdvReadEEPWord(iop_base, ASC_EEP_DVC_CFG_END - 3);
17156 AdvSet38C0800EEPConfig(iop_base, &eep_config);
17159 * Set ADV_DVC_VAR and ADV_DVC_CFG variables from the
17160 * EEPROM configuration that was read.
17162 * This is the mapping of EEPROM fields to Adv Library fields.
17164 asc_dvc->wdtr_able = eep_config.wdtr_able;
17165 asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
17166 asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
17167 asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
17168 asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
17169 asc_dvc->tagqng_able = eep_config.tagqng_able;
17170 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
17171 asc_dvc->max_host_qng = eep_config.max_host_qng;
17172 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
17173 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
17174 asc_dvc->start_motor = eep_config.start_motor;
17175 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
17176 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
17177 asc_dvc->no_scam = eep_config.scam_tolerant;
17178 asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
17179 asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
17180 asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
17183 * For every Target ID if any of its 'sdtr_speed[1234]' bits
17184 * are set, then set an 'sdtr_able' bit for it.
17186 asc_dvc->sdtr_able = 0;
17187 for (tid = 0; tid <= ADV_MAX_TID; tid++)
17189 if (tid == 0)
17191 sdtr_speed = asc_dvc->sdtr_speed1;
17192 } else if (tid == 4)
17194 sdtr_speed = asc_dvc->sdtr_speed2;
17195 } else if (tid == 8)
17197 sdtr_speed = asc_dvc->sdtr_speed3;
17198 } else if (tid == 12)
17200 sdtr_speed = asc_dvc->sdtr_speed4;
17202 if (sdtr_speed & ADV_MAX_TID)
17204 asc_dvc->sdtr_able |= (1 << tid);
17206 sdtr_speed >>= 4;
17210 * Set the host maximum queuing (max. 253, min. 16) and the per device
17211 * maximum queuing (max. 63, min. 4).
17213 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG)
17215 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
17216 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG)
17218 /* If the value is zero, assume it is uninitialized. */
17219 if (eep_config.max_host_qng == 0)
17221 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
17222 } else
17224 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
17228 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG)
17230 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
17231 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG)
17233 /* If the value is zero, assume it is uninitialized. */
17234 if (eep_config.max_dvc_qng == 0)
17236 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
17237 } else
17239 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
17244 * If 'max_dvc_qng' is greater than 'max_host_qng', then
17245 * set 'max_dvc_qng' to 'max_host_qng'.
17247 if (eep_config.max_dvc_qng > eep_config.max_host_qng)
17249 eep_config.max_dvc_qng = eep_config.max_host_qng;
17253 * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
17254 * values based on possibly adjusted EEPROM values.
17256 asc_dvc->max_host_qng = eep_config.max_host_qng;
17257 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
17260 * If the EEPROM 'termination' field is set to automatic (0), then set
17261 * the ADV_DVC_CFG 'termination' field to automatic also.
17263 * If the termination is specified with a non-zero 'termination'
17264 * value check that a legal value is set and set the ADV_DVC_CFG
17265 * 'termination' field appropriately.
17267 if (eep_config.termination_se == 0)
17269 termination = 0; /* auto termination for SE */
17270 } else
17272 /* Enable manual control with low off / high off. */
17273 if (eep_config.termination_se == 1)
17275 termination = 0;
17277 /* Enable manual control with low off / high on. */
17278 } else if (eep_config.termination_se == 2)
17280 termination = TERM_SE_HI;
17282 /* Enable manual control with low on / high on. */
17283 } else if (eep_config.termination_se == 3)
17285 termination = TERM_SE;
17286 } else
17289 * The EEPROM 'termination_se' field contains a bad value.
17290 * Use automatic termination instead.
17292 termination = 0;
17293 warn_code |= ASC_WARN_EEPROM_TERMINATION;
17297 if (eep_config.termination_lvd == 0)
17299 asc_dvc->cfg->termination = termination; /* auto termination for LVD */
17300 } else
17302 /* Enable manual control with low off / high off. */
17303 if (eep_config.termination_lvd == 1)
17305 asc_dvc->cfg->termination = termination;
17307 /* Enable manual control with low off / high on. */
17308 } else if (eep_config.termination_lvd == 2)
17310 asc_dvc->cfg->termination = termination | TERM_LVD_HI;
17312 /* Enable manual control with low on / high on. */
17313 } else if (eep_config.termination_lvd == 3)
17315 asc_dvc->cfg->termination =
17316 termination | TERM_LVD;
17317 } else
17320 * The EEPROM 'termination_lvd' field contains a bad value.
17321 * Use automatic termination instead.
17323 asc_dvc->cfg->termination = termination;
17324 warn_code |= ASC_WARN_EEPROM_TERMINATION;
17328 return warn_code;
17332 * Read EEPROM configuration into the specified buffer.
17334 * Return a checksum based on the EEPROM configuration read.
17336 ASC_INITFUNC(
17337 STATIC ushort,
17338 AdvGet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
17341 ushort wval, chksum;
17342 ushort *wbuf;
17343 int eep_addr;
17345 wbuf = (ushort *) cfg_buf;
17346 chksum = 0;
17348 for (eep_addr = ASC_EEP_DVC_CFG_BEGIN;
17349 eep_addr < ASC_EEP_DVC_CFG_END;
17350 eep_addr++, wbuf++)
17352 wval = AdvReadEEPWord(iop_base, eep_addr);
17353 chksum += wval;
17354 *wbuf = wval;
17356 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
17357 wbuf++;
17358 for (eep_addr = ASC_EEP_DVC_CTL_BEGIN;
17359 eep_addr < ASC_EEP_MAX_WORD_ADDR;
17360 eep_addr++, wbuf++)
17362 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
17364 return chksum;
17368 * Read EEPROM configuration into the specified buffer.
17370 * Return a checksum based on the EEPROM configuration read.
17372 ASC_INITFUNC(
17373 STATIC ushort,
17374 AdvGet38C0800EEPConfig(AdvPortAddr iop_base,
17375 ADVEEP_38C0800_CONFIG *cfg_buf)
17378 ushort wval, chksum;
17379 ushort *wbuf;
17380 int eep_addr;
17382 wbuf = (ushort *) cfg_buf;
17383 chksum = 0;
17385 for (eep_addr = ASC_EEP_DVC_CFG_BEGIN;
17386 eep_addr < ASC_EEP_DVC_CFG_END;
17387 eep_addr++, wbuf++)
17389 wval = AdvReadEEPWord(iop_base, eep_addr);
17390 chksum += wval;
17391 *wbuf = wval;
17393 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
17394 wbuf++;
17395 for (eep_addr = ASC_EEP_DVC_CTL_BEGIN;
17396 eep_addr < ASC_EEP_MAX_WORD_ADDR;
17397 eep_addr++, wbuf++)
17399 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
17401 return chksum;
17406 * Read the EEPROM from specified location
17408 ASC_INITFUNC(
17409 STATIC ushort,
17410 AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr)
17413 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
17414 ASC_EEP_CMD_READ | eep_word_addr);
17415 AdvWaitEEPCmd(iop_base);
17416 return AdvReadWordRegister(iop_base, IOPW_EE_DATA);
17420 * Wait for EEPROM command to complete
17422 ASC_INITFUNC(
17423 STATIC void,
17424 AdvWaitEEPCmd(AdvPortAddr iop_base)
17427 int eep_delay_ms;
17429 for (eep_delay_ms = 0; eep_delay_ms < ASC_EEP_DELAY_MS; eep_delay_ms++)
17431 if (AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE)
17433 break;
17435 DvcSleepMilliSecond(1);
17437 if ((AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE) == 0)
17439 ASC_ASSERT(0);
17441 return;
17445 * Write the EEPROM from 'cfg_buf'.
17447 void
17448 AdvSet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
17450 ushort *wbuf;
17451 ushort addr, chksum;
17453 wbuf = (ushort *) cfg_buf;
17454 chksum = 0;
17456 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
17457 AdvWaitEEPCmd(iop_base);
17460 * Write EEPROM from word 0 to word 20
17462 for (addr = ASC_EEP_DVC_CFG_BEGIN;
17463 addr < ASC_EEP_DVC_CFG_END; addr++, wbuf++)
17465 chksum += *wbuf;
17466 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, *wbuf);
17467 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17468 AdvWaitEEPCmd(iop_base);
17469 DvcSleepMilliSecond(ASC_EEP_DELAY_MS);
17473 * Write EEPROM checksum at word 21
17475 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
17476 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17477 AdvWaitEEPCmd(iop_base);
17478 wbuf++; /* skip over check_sum */
17481 * Write EEPROM OEM name at words 22 to 29
17483 for (addr = ASC_EEP_DVC_CTL_BEGIN;
17484 addr < ASC_EEP_MAX_WORD_ADDR; addr++, wbuf++)
17486 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, *wbuf);
17487 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17488 AdvWaitEEPCmd(iop_base);
17490 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
17491 AdvWaitEEPCmd(iop_base);
17492 return;
17496 * Write the EEPROM from 'cfg_buf'.
17498 void
17499 AdvSet38C0800EEPConfig(AdvPortAddr iop_base,
17500 ADVEEP_38C0800_CONFIG *cfg_buf)
17502 ushort *wbuf;
17503 ushort addr, chksum;
17505 wbuf = (ushort *) cfg_buf;
17506 chksum = 0;
17508 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
17509 AdvWaitEEPCmd(iop_base);
17512 * Write EEPROM from word 0 to word 20
17514 for (addr = ASC_EEP_DVC_CFG_BEGIN;
17515 addr < ASC_EEP_DVC_CFG_END; addr++, wbuf++)
17517 chksum += *wbuf;
17518 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, *wbuf);
17519 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17520 AdvWaitEEPCmd(iop_base);
17521 DvcSleepMilliSecond(ASC_EEP_DELAY_MS);
17525 * Write EEPROM checksum at word 21
17527 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
17528 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17529 AdvWaitEEPCmd(iop_base);
17530 wbuf++; /* skip over check_sum */
17533 * Write EEPROM OEM name at words 22 to 29
17535 for (addr = ASC_EEP_DVC_CTL_BEGIN;
17536 addr < ASC_EEP_MAX_WORD_ADDR; addr++, wbuf++)
17538 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, *wbuf);
17539 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17540 AdvWaitEEPCmd(iop_base);
17542 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
17543 AdvWaitEEPCmd(iop_base);
17544 return;
17547 /* a_advlib.c */
17549 * AdvExeScsiQueue() - Send a request to the RISC microcode program.
17551 * Allocate a carrier structure, point the carrier to the ADV_SCSI_REQ_Q,
17552 * add the carrier to the ICQ (Initiator Command Queue), and tickle the
17553 * RISC to notify it a new command is ready to be executed.
17555 * If 'done_status' is not set to QD_DO_RETRY, then 'error_retry' will be
17556 * set to SCSI_MAX_RETRY.
17558 * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the microcode
17559 * for DMA addresses or math operations are byte swapped to little-endian
17560 * order.
17562 * Return:
17563 * ADV_SUCCESS(1) - The request was successfully queued.
17564 * ADV_BUSY(0) - Resource unavailable; Retry again after pending
17565 * request completes.
17566 * ADV_ERROR(-1) - Invalid ADV_SCSI_REQ_Q request structure
17567 * host IC error.
17569 STATIC int
17570 AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc,
17571 ADV_SCSI_REQ_Q *scsiq)
17573 int last_int_level;
17574 AdvPortAddr iop_base;
17575 ADV_DCNT req_size;
17576 ADV_PADDR req_paddr;
17577 ADV_CARR_T *new_carrp;
17579 ASC_ASSERT(scsiq != NULL); /* 'scsiq' should never be NULL. */
17582 * The ADV_SCSI_REQ_Q 'target_id' field should never exceed ADV_MAX_TID.
17584 if (scsiq->target_id > ADV_MAX_TID)
17586 scsiq->host_status = QHSTA_M_INVALID_DEVICE;
17587 scsiq->done_status = QD_WITH_ERROR;
17588 return ADV_ERROR;
17591 iop_base = asc_dvc->iop_base;
17593 last_int_level = DvcEnterCritical();
17596 * Allocate a carrier ensuring at least one carrier always
17597 * remains on the freelist and initialize fields.
17599 if ((new_carrp = asc_dvc->carr_freelist) == NULL)
17601 return ADV_BUSY;
17603 asc_dvc->carr_freelist =
17604 (ADV_CARR_T *) ADV_U32_TO_VADDR(new_carrp->next_vpa);
17605 asc_dvc->carr_pending_cnt++;
17608 * Set the carrier to be a stopper by setting 'next_vpa'
17609 * to the stopper value. The current stopper will be changed
17610 * below to point to the new stopper.
17612 new_carrp->next_vpa = ASC_CQ_STOPPER;
17615 * Clear the ADV_SCSI_REQ_Q done flag.
17617 scsiq->a_flag &= ~ADV_SCSIQ_DONE;
17619 req_size = sizeof(ADV_SCSI_REQ_Q);
17620 req_paddr = cpu_to_le32(DvcGetPhyAddr(asc_dvc, scsiq, (uchar *) scsiq,
17621 (ADV_SDCNT *) &req_size, ADV_IS_SCSIQ_FLAG));
17623 ASC_ASSERT(ADV_DWALIGN(req_paddr) == req_paddr);
17624 ASC_ASSERT(req_size >= sizeof(ADV_SCSI_REQ_Q));
17626 /* Save virtual and physical address of ADV_SCSI_REQ_Q and carrier. */
17627 scsiq->scsiq_ptr = ADV_VADDR_TO_U32(scsiq);
17628 scsiq->scsiq_rptr = req_paddr;
17630 scsiq->carr_va = ADV_VADDR_TO_U32(asc_dvc->icq_sp);
17632 * Every ADV_CARR_T.carr_pa is byte swapped to little-endian
17633 * order during initialization.
17635 scsiq->carr_pa = asc_dvc->icq_sp->carr_pa;
17638 * Use the current stopper to send the ADV_SCSI_REQ_Q command to
17639 * the microcode. The newly allocated stopper will become the new
17640 * stopper.
17642 asc_dvc->icq_sp->areq_vpa = req_paddr;
17645 * Set the 'next_vpa' pointer for the old stopper to be the
17646 * physical address of the new stopper. The RISC can only
17647 * follow physical addresses.
17649 asc_dvc->icq_sp->next_vpa = new_carrp->carr_pa;
17652 * Set the host adapter stopper pointer to point to the new carrier.
17654 asc_dvc->icq_sp = new_carrp;
17657 * Tickle the RISC to tell it to read its Command Queue Head pointer.
17659 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_A);
17660 if (asc_dvc->chip_type == ADV_CHIP_ASC3550)
17663 * Clear the tickle value. In the ASC-3550 the RISC flag
17664 * command 'clr_tickle_a' does not work unless the host
17665 * value is cleared.
17667 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
17670 DvcLeaveCritical(last_int_level);
17672 return ADV_SUCCESS;
17676 * Reset SCSI Bus and purge all outstanding requests.
17678 * Return Value:
17679 * ADV_TRUE(1) - All requests are purged and SCSI Bus is reset.
17680 * ADV_FALSE(0) - Microcode command failed.
17681 * ADV_ERROR(-1) - Microcode command timed-out. Microcode or IC
17682 * may be hung which requires driver recovery.
17684 STATIC int
17685 AdvResetSB(ADV_DVC_VAR *asc_dvc)
17687 int status;
17690 * Send the SCSI Bus Reset idle start idle command which asserts
17691 * the SCSI Bus Reset signal.
17693 status = AdvSendIdleCmd(asc_dvc, (ushort) IDLE_CMD_SCSI_RESET_START, 0L);
17694 if (status != ADV_TRUE)
17696 return status;
17700 * Delay for the specified SCSI Bus Reset hold time.
17702 * The hold time delay is done on the host because the RISC has no
17703 * microsecond accurate timer.
17705 DvcDelayMicroSecond(asc_dvc, (ushort) ASC_SCSI_RESET_HOLD_TIME_US);
17708 * Send the SCSI Bus Reset end idle command which de-asserts
17709 * the SCSI Bus Reset signal and purges any pending requests.
17711 status = AdvSendIdleCmd(asc_dvc, (ushort) IDLE_CMD_SCSI_RESET_END, 0L);
17712 if (status != ADV_TRUE)
17714 return status;
17717 DvcSleepMilliSecond((ADV_DCNT) asc_dvc->scsi_reset_wait * 1000);
17719 return status;
17723 * Reset chip and SCSI Bus.
17725 * Return Value:
17726 * ADV_TRUE(1) - Chip re-initialization and SCSI Bus Reset successful.
17727 * ADV_FALSE(0) - Chip re-initialization and SCSI Bus Reset failure.
17729 STATIC int
17730 AdvResetChipAndSB(ADV_DVC_VAR *asc_dvc)
17732 int status;
17733 ushort wdtr_able, sdtr_able, tagqng_able;
17734 uchar tid, max_cmd[ADV_MAX_TID + 1];
17735 AdvPortAddr iop_base;
17736 ushort bios_sig;
17738 iop_base = asc_dvc->iop_base;
17741 * Save current per TID negotiated values.
17743 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
17744 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
17745 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
17746 for (tid = 0; tid <= ADV_MAX_TID; tid++)
17748 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
17749 max_cmd[tid]);
17753 * Force the AdvInitAsc3550/38C0800Driver() function to
17754 * perform a SCSI Bus Reset by clearing the BIOS signature word.
17755 * The initialization functions assumes a SCSI Bus Reset is not
17756 * needed if the BIOS signature word is present.
17758 AdvReadWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
17759 AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, 0);
17762 * Stop chip and reset it.
17764 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_STOP);
17765 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_RESET);
17766 DvcSleepMilliSecond(100);
17767 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_WR_IO_REG);
17770 * Reset Adv Library error code, if any, and try
17771 * re-initializing the chip.
17773 asc_dvc->err_code = 0;
17774 if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800)
17776 status = AdvInitAsc38C0800Driver(asc_dvc);
17777 } else
17779 status = AdvInitAsc3550Driver(asc_dvc);
17782 /* Translate initialization return value to status value. */
17783 if (status == 0)
17785 status = ADV_TRUE;
17786 } else
17788 status = ADV_FALSE;
17792 * Restore the BIOS signature word.
17794 AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
17797 * Restore per TID negotiated values.
17799 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
17800 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
17801 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
17802 for (tid = 0; tid <= ADV_MAX_TID; tid++)
17804 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
17805 max_cmd[tid]);
17808 return status;
17812 * Adv Library Interrupt Service Routine
17814 * This function is called by a driver's interrupt service routine.
17815 * The function disables and re-enables interrupts.
17817 * When a microcode idle command is completed, the ADV_DVC_VAR
17818 * 'idle_cmd_done' field is set to ADV_TRUE.
17820 * Note: AdvISR() can be called when interrupts are disabled or even
17821 * when there is no hardware interrupt condition present. It will
17822 * always check for completed idle commands and microcode requests.
17823 * This is an important feature that shouldn't be changed because it
17824 * allows commands to be completed from polling mode loops.
17826 * Return:
17827 * ADV_TRUE(1) - interrupt was pending
17828 * ADV_FALSE(0) - no interrupt was pending
17830 STATIC int
17831 AdvISR(ADV_DVC_VAR *asc_dvc)
17833 AdvPortAddr iop_base;
17834 uchar int_stat;
17835 ushort target_bit;
17836 ADV_CARR_T *free_carrp;
17837 ADV_VADDR irq_next_vpa;
17838 int flags;
17839 ADV_SCSI_REQ_Q *scsiq;
17841 flags = DvcEnterCritical();
17843 iop_base = asc_dvc->iop_base;
17845 /* Reading the register clears the interrupt. */
17846 int_stat = AdvReadByteRegister(iop_base, IOPB_INTR_STATUS_REG);
17848 if ((int_stat & (ADV_INTR_STATUS_INTRA | ADV_INTR_STATUS_INTRB |
17849 ADV_INTR_STATUS_INTRC)) == 0)
17851 return ADV_FALSE;
17855 * Notify the driver of an asynchronous microcode condition by
17856 * calling the ADV_DVC_VAR.async_callback function. The function
17857 * is passed the microcode ASC_MC_INTRB_CODE byte value.
17859 if (int_stat & ADV_INTR_STATUS_INTRB)
17861 uchar intrb_code;
17863 AdvReadByteLram(iop_base, ASC_MC_INTRB_CODE, intrb_code);
17864 if (intrb_code == ADV_ASYNC_CARRIER_READY_FAILURE &&
17865 asc_dvc->carr_pending_cnt != 0)
17867 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_A);
17868 if (asc_dvc->chip_type == ADV_CHIP_ASC3550)
17870 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
17874 if (asc_dvc->async_callback != 0)
17876 (*asc_dvc->async_callback)(asc_dvc, intrb_code);
17881 * Check if the IRQ stopper carrier contains a completed request.
17883 while (((irq_next_vpa = asc_dvc->irq_sp->next_vpa) & ASC_RQ_DONE) != 0)
17886 * Get a pointer to the newly completed ADV_SCSI_REQ_Q structure.
17887 * The RISC will have set 'areq_vpa' to a virtual address.
17889 * The firmware will have copied the ASC_SCSI_REQ_Q.scsiq_ptr
17890 * field to the carrier ADV_CARR_T.areq_vpa field. The conversion
17891 * below complements the conversion of ASC_SCSI_REQ_Q.scsiq_ptr'
17892 * in AdvExeScsiQueue().
17894 scsiq = (ADV_SCSI_REQ_Q *) ADV_U32_TO_VADDR(asc_dvc->irq_sp->areq_vpa);
17897 * Advance the stopper pointer to the next carrier
17898 * ignoring the lower four bits. Free the previous
17899 * stopper carrier.
17901 free_carrp = asc_dvc->irq_sp;
17902 asc_dvc->irq_sp = (ADV_CARR_T *)
17903 ADV_U32_TO_VADDR(ASC_GET_CARRP(irq_next_vpa));
17905 free_carrp->next_vpa = ADV_VADDR_TO_U32(asc_dvc->carr_freelist);
17906 asc_dvc->carr_freelist = free_carrp;
17907 asc_dvc->carr_pending_cnt--;
17909 ASC_ASSERT(scsiq != NULL);
17910 target_bit = ADV_TID_TO_TIDMASK(scsiq->target_id);
17913 * Clear request microcode control flag.
17915 scsiq->cntl = 0;
17917 #if __BIG_ENDIAN
17919 * After the request completes the only field in the ASC_SCSI_REQ_Q
17920 * structure needs to be byte swapped from little endian order to
17921 * big endian order is the residual data count.
17923 scsiqp->data_cnt = le32_to_cpu(scsiqp->data_cnt);
17924 #endif /* __BIG_ENDIAN */
17927 * If the command that completed was a SCSI INQUIRY and
17928 * LUN 0 was sent the command, then process the INQUIRY
17929 * command information for the device.
17931 if (scsiq->done_status == QD_NO_ERROR &&
17932 scsiq->cdb[0] == SCSICMD_Inquiry &&
17933 scsiq->target_lun == 0)
17935 AdvInquiryHandling(asc_dvc, scsiq);
17939 * Notify the driver of the completed request by passing
17940 * the ADV_SCSI_REQ_Q pointer to its callback function.
17942 scsiq->a_flag |= ADV_SCSIQ_DONE;
17943 (*asc_dvc->isr_callback)(asc_dvc, scsiq);
17945 * Note: After the driver callback function is called, 'scsiq'
17946 * can no longer be referenced.
17948 * Fall through and continue processing other completed
17949 * requests...
17953 * Disable interrupts again in case the driver inadvertently
17954 * enabled interrupts in its callback function.
17956 * The DvcEnterCritical() return value is ignored, because
17957 * the 'flags' saved when AdvISR() was first entered will be
17958 * used to restore the interrupt flag on exit.
17960 (void) DvcEnterCritical();
17962 DvcLeaveCritical(flags);
17963 return ADV_TRUE;
17967 * Send an idle command to the chip and wait for completion.
17969 * Command completion is polled for once per microsecond.
17971 * The function can be called from anywhere including an interrupt handler.
17972 * But the function is not re-entrant, so it uses the DvcEnter/LeaveCritical()
17973 * functions to prevent reentrancy.
17975 * Return Values:
17976 * ADV_TRUE - command completed successfully
17977 * ADV_FALSE - command failed
17978 * ADV_ERROR - command timed out
17980 STATIC int
17981 AdvSendIdleCmd(ADV_DVC_VAR *asc_dvc,
17982 ushort idle_cmd,
17983 ADV_DCNT idle_cmd_parameter)
17985 int last_int_level;
17986 int result;
17987 ADV_DCNT i, j;
17988 AdvPortAddr iop_base;
17990 last_int_level = DvcEnterCritical();
17992 iop_base = asc_dvc->iop_base;
17995 * Clear the idle command status which is set by the microcode
17996 * to a non-zero value to indicate when the command is completed.
17997 * The non-zero result is one of the IDLE_CMD_STATUS_* values
17998 * defined in a_advlib.h.
18000 AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS, (ushort) 0);
18003 * Write the idle command value after the idle command parameter
18004 * has been written to avoid a race condition. If the order is not
18005 * followed, the microcode may process the idle command before the
18006 * parameters have been written to LRAM.
18008 AdvWriteDWordLram(iop_base, ASC_MC_IDLE_CMD_PARAMETER,
18009 idle_cmd_parameter);
18010 AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD, idle_cmd);
18013 * Tickle the RISC to tell it to process the idle command.
18015 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_B);
18016 if (asc_dvc->chip_type == ADV_CHIP_ASC3550)
18019 * Clear the tickle value. In the ASC-3550 the RISC flag
18020 * command 'clr_tickle_b' does not work unless the host
18021 * value is cleared.
18023 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
18026 /* Wait for up to 100 millisecond for the idle command to timeout. */
18027 for (i = 0; i < SCSI_WAIT_100_MSEC; i++)
18029 /* Poll once each microsecond for command completion. */
18030 for (j = 0; j < SCSI_US_PER_MSEC; j++)
18032 AdvReadWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS, result);
18033 if (result != 0)
18035 DvcLeaveCritical(last_int_level);
18036 return result;
18038 DvcDelayMicroSecond(asc_dvc, (ushort) 1);
18042 ASC_ASSERT(0); /* The idle command should never timeout. */
18043 DvcLeaveCritical(last_int_level);
18044 return ADV_ERROR;
18048 * Inquiry Information Byte 7 Handling
18050 * Handle SCSI Inquiry Command information for a device by setting
18051 * microcode operating variables that affect WDTR, SDTR, and Tag
18052 * Queuing.
18054 STATIC void
18055 AdvInquiryHandling(
18056 ADV_DVC_VAR *asc_dvc,
18057 ADV_SCSI_REQ_Q *scsiq)
18059 AdvPortAddr iop_base;
18060 uchar tid;
18061 ADV_SCSI_INQUIRY *inq;
18062 ushort tidmask;
18063 ushort cfg_word;
18066 * AdvInquiryHandling() requires up to INQUIRY information Byte 7
18067 * to be available.
18069 * If less than 8 bytes of INQUIRY information were requested or less
18070 * than 8 bytes were transferred, then return. cdb[4] is the request
18071 * length and the ADV_SCSI_REQ_Q 'data_cnt' field is set by the
18072 * microcode to the transfer residual count.
18075 if (scsiq->cdb[4] < 8 || (scsiq->cdb[4] - scsiq->data_cnt) < 8)
18077 return;
18080 iop_base = asc_dvc->iop_base;
18081 tid = scsiq->target_id;
18083 inq = (ADV_SCSI_INQUIRY *) scsiq->vdata_addr;
18086 * WDTR, SDTR, and Tag Queuing cannot be enabled for old devices.
18088 if (inq->rsp_data_fmt < 2 && inq->ansi_apr_ver < 2)
18090 return;
18091 } else
18094 * INQUIRY Byte 7 Handling
18096 * Use a device's INQUIRY byte 7 to determine whether it
18097 * supports WDTR, SDTR, and Tag Queuing. If the feature
18098 * is enabled in the EEPROM and the device supports the
18099 * feature, then enable it in the microcode.
18102 tidmask = ADV_TID_TO_TIDMASK(tid);
18105 * Wide Transfers
18107 * If the EEPROM enabled WDTR for the device and the device
18108 * supports wide bus (16 bit) transfers, then turn on the
18109 * device's 'wdtr_able' bit and write the new value to the
18110 * microcode.
18112 if ((asc_dvc->wdtr_able & tidmask) && inq->WBus16)
18114 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
18115 if ((cfg_word & tidmask) == 0)
18117 cfg_word |= tidmask;
18118 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
18121 * Clear the microcode "SDTR negotiation" and "WDTR
18122 * negotiation" done indicators for the target to cause
18123 * it to negotiate with the new setting set above.
18124 * WDTR when accepted causes the target to enter
18125 * asynchronous mode, so SDTR must be negotiated.
18127 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
18128 cfg_word &= ~tidmask;
18129 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
18130 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
18131 cfg_word &= ~tidmask;
18132 AdvWriteWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
18137 * Synchronous Transfers
18139 * If the EEPROM enabled SDTR for the device and the device
18140 * supports synchronous transfers, then turn on the device's
18141 * 'sdtr_able' bit. Write the new value to the microcode.
18143 if ((asc_dvc->sdtr_able & tidmask) && inq->Sync)
18145 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
18146 if ((cfg_word & tidmask) == 0)
18148 cfg_word |= tidmask;
18149 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
18152 * Clear the microcode "SDTR negotiation" done indicator
18153 * for the target to cause it to negotiate with the new
18154 * setting set above.
18156 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
18157 cfg_word &= ~tidmask;
18158 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
18163 * If the EEPROM enabled Tag Queuing for the device and the
18164 * device supports Tag Queueing, then turn on the device's
18165 * 'tagqng_enable' bit in the microcode and set the microcode
18166 * maximum command count to the ADV_DVC_VAR 'max_dvc_qng'
18167 * value.
18169 * Tag Queuing is disabled for the BIOS which runs in polled
18170 * mode and would see no benefit from Tag Queuing. Also by
18171 * disabling Tag Queuing in the BIOS devices with Tag Queuing
18172 * bugs will at least work with the BIOS.
18174 if ((asc_dvc->tagqng_able & tidmask) && inq->CmdQue)
18176 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
18177 cfg_word |= tidmask;
18178 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
18180 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
18181 asc_dvc->max_dvc_qng);