Bug Summary

File:obj-scan-build/../linux/src/drivers/scsi/advansys.c
Location:line 12746, column 9
Description:Value stored to 'PCIRevisionID' is never read

Annotated Source Code

1/* $Id: advansys.c,v 1.1.4.1 2005/06/02 18:52:38 ams Exp $ */
2#define ASC_VERSION"3.1E" "3.1E" /* AdvanSys Driver Version */
3
4/*
5 * advansys.c - Linux Host Driver for AdvanSys SCSI Adapters
6 *
7 * Copyright (c) 1995-1998 Advanced System Products, Inc.
8 * All Rights Reserved.
9 *
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.
14 *
15 * There is an AdvanSys Linux WWW page at:
16 * http://www.advansys.com/linux.html
17 *
18 * The latest version of the AdvanSys driver is available at:
19 * ftp://ftp.advansys.com/pub/linux/linux.tgz
20 *
21 * Please send questions, comments, bug reports to:
22 * bobf@advansys.com (Bob Frey)
23 */
24
25/*
26
27 Documentation for the AdvanSys Driver
28
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 or Issues
39 K. Credits
40 L. AdvanSys Contact Information
41
42 A. Linux Kernel Testing
43
44 This driver has been tested in the following Linux kernels: v1.2.13,
45 v1.3.57, v2.0.33, v2.1.77. These kernel versions are major releases
46 of Linux or the latest Linux kernel versions available when this version
47 of the driver was released. The driver should also work in earlier
48 versions of the Linux kernel. Beginning with v1.3.58 the AdvanSys driver
49 is included with all Linux kernels. Please refer to sections C, D, and
50 E for instructions on adding or upgrading the AdvanSys driver.
51
52 B. Adapters Supported by this Driver
53
54 AdvanSys (Advanced System Products, Inc.) manufactures the following
55 RISC-based, Bus-Mastering, Fast (10 Mhz) and Ultra (20 Mhz) Narrow
56 (8-bit transfer) SCSI Host Adapters for the ISA, EISA, VL, and PCI
57 buses and RISC-based, Bus-Mastering, Ultra (20 Mhz) Wide (16-bit
58 transfer) SCSI Host Adapters for the PCI bus.
59
60 The CDB counts below indicate the number of SCSI CDB (Command
61 Descriptor Block) requests that can be stored in the RISC chip
62 cache and board LRAM. A CDB is a single SCSI command. The driver
63 detect routine will display the number of CDBs available for each
64 adapter detected. The number of CDBs used by the driver can be
65 lowered in the BIOS by changing the 'Host Queue Size' adapter setting.
66
67 Connectivity Products:
68 ABP510/5150 - Bus-Master ISA (240 CDB) (Footnote 1)
69 ABP5140 - Bus-Master ISA PnP (16 CDB) (Footnote 1, 3)
70 ABP5142 - Bus-Master ISA PnP with floppy (16 CDB) (Footnote 4)
71 ABP920 - Bus-Master PCI (16 CDB)
72 ABP930 - Bus-Master PCI (16 CDB) (Footnote 5)
73 ABP930U - Bus-Master PCI Ultra (16 CDB)
74 ABP930UA - Bus-Master PCI Ultra (16 CDB)
75 ABP960 - Bus-Master PCI MAC/PC (16 CDB) (Footnote 2)
76 ABP960U - Bus-Master PCI MAC/PC Ultra (16 CDB) (Footnote 2)
77
78 Single Channel Products:
79 ABP542 - Bus-Master ISA with floppy (240 CDB)
80 ABP742 - Bus-Master EISA (240 CDB)
81 ABP842 - Bus-Master VL (240 CDB)
82 ABP940 - Bus-Master PCI (240 CDB)
83 ABP940U - Bus-Master PCI Ultra (240 CDB)
84 ABP970 - Bus-Master PCI MAC/PC (240 CDB)
85 ABP970U - Bus-Master PCI MAC/PC Ultra (240 CDB)
86 ABP940UW - Bus-Master PCI Ultra-Wide (240 CDB)
87
88 Multi Channel Products:
89 ABP752 - Dual Channel Bus-Master EISA (240 CDB Per Channel)
90 ABP852 - Dual Channel Bus-Master VL (240 CDB Per Channel)
91 ABP950 - Dual Channel Bus-Master PCI (240 CDB Per Channel)
92 ABP980 - Four Channel Bus-Master PCI (240 CDB Per Channel)
93 ABP980U - Four Channel Bus-Master PCI Ultra (240 CDB Per Channel)
94
95 Footnotes:
96 1. This board has been shipped by HP with the 4020i CD-R drive.
97 The board has no BIOS so it cannot control a boot device, but
98 it can control any secondary SCSI device.
99 2. This board has been sold by Iomega as a Jaz Jet PCI adapter.
100 3. This board has been sold by SIIG as the i540 SpeedMaster.
101 4. This board has been sold by SIIG as the i542 SpeedMaster.
102 5. This board has been sold by SIIG as the Fast SCSI Pro PCI.
103
104 C. Linux v1.2.X - Directions for Adding the AdvanSys Driver
105
106 These directions apply to v1.2.13. For versions that follow v1.2.13.
107 but precede v1.3.57 some of the changes for Linux v1.3.X listed
108 below may need to be modified or included. A patch is available
109 for v1.2.13 from the AdvanSys WWW and FTP sites.
110
111 There are two source files: advansys.h and advansys.c. Copy
112 both of these files to the directory /usr/src/linux/drivers/scsi.
113
114 1. Add the following line to /usr/src/linux/arch/i386/config.in
115 after "comment 'SCSI low-level drivers'":
116
117 bool 'AdvanSys SCSI support' CONFIG_SCSI_ADVANSYS y
118
119 2. Add the following lines to /usr/src/linux/drivers/scsi/hosts.c
120 after "#include "hosts.h"":
121
122 #ifdef CONFIG_SCSI_ADVANSYS
123 #include "advansys.h"
124 #endif
125
126 and after "static Scsi_Host_Template builtin_scsi_hosts[] =":
127
128 #ifdef CONFIG_SCSI_ADVANSYS
129 ADVANSYS,
130 #endif
131
132 3. Add the following lines to /usr/src/linux/drivers/scsi/Makefile:
133
134 ifdef CONFIG_SCSI_ADVANSYS
135 SCSI_SRCS := $(SCSI_SRCS) advansys.c
136 SCSI_OBJS := $(SCSI_OBJS) advansys.o
137 else
138 SCSI_MODULE_OBJS := $(SCSI_MODULE_OBJS) advansys.o
139 endif
140
141 4. (Optional) If you would like to enable the LILO command line
142 and /etc/lilo.conf 'advansys' option, make the following changes.
143 This option can be used to disable I/O port scanning or to limit
144 I/O port scanning to specific addresses. Refer to the 'Driver
145 LILO Option' section below. Add the following lines to
146 /usr/src/linux/init/main.c in the prototype section:
147
148 extern void advansys_setup(char *str, int *ints);
149
150 and add the following lines to the bootsetups[] array.
151
152 #ifdef CONFIG_SCSI_ADVANSYS
153 { "advansys=", advansys_setup },
154 #endif
155
156 5. If you have the HP 4020i CD-R driver and Linux v1.2.X you should
157 add a fix to the CD-ROM target driver. This fix will allow
158 you to mount CDs with the iso9660 file system. Linux v1.3.X
159 already has this fix. In the file /usr/src/linux/drivers/scsi/sr.c
160 and function get_sectorsize() after the line:
161
162 if(scsi_CDs[i].sector_size == 0) scsi_CDs[i].sector_size = 2048;
163
164 add the following line:
165
166 if(scsi_CDs[i].sector_size == 2340) scsi_CDs[i].sector_size = 2048;
167
168 6. In the directory /usr/src/linux run 'make config' to configure
169 the AdvanSys driver, then run 'make vmlinux' or 'make zlilo' to
170 make the kernel. If the AdvanSys driver is not configured, then
171 a loadable module can be built by running 'make modules' and
172 'make modules_install'. Use 'insmod' and 'rmmod' to install
173 and remove advansys.o.
174
175 D. Linux v1.3.1 - v1.3.57 - Directions for Adding the AdvanSys Driver
176
177 These directions apply to v1.3.57. For versions that precede v1.3.57
178 some of these changes may need to be modified or eliminated. A patch
179 is available for v1.3.57 from the AdvanSys WWW and FTP sites.
180 Beginning with v1.3.58 this driver is included with the Linux
181 distribution eliminating the need for making any changes.
182
183 There are two source files: advansys.h and advansys.c. Copy
184 both of these files to the directory /usr/src/linux/drivers/scsi.
185
186 1. Add the following line to /usr/src/linux/drivers/scsi/Config.in
187 after "comment 'SCSI low-level drivers'":
188
189 dep_tristate 'AdvanSys SCSI support' CONFIG_SCSI_ADVANSYS $CONFIG_SCSI
190
191 2. Add the following lines to /usr/src/linux/drivers/scsi/hosts.c
192 after "#include "hosts.h"":
193
194 #ifdef CONFIG_SCSI_ADVANSYS
195 #include "advansys.h"
196 #endif
197
198 and after "static Scsi_Host_Template builtin_scsi_hosts[] =":
199
200 #ifdef CONFIG_SCSI_ADVANSYS
201 ADVANSYS,
202 #endif
203
204 3. Add the following lines to /usr/src/linux/drivers/scsi/Makefile:
205
206 ifeq ($(CONFIG_SCSI_ADVANSYS),y)
207 L_OBJS += advansys.o
208 else
209 ifeq ($(CONFIG_SCSI_ADVANSYS),m)
210 M_OBJS += advansys.o
211 endif
212 endif
213
214 4. Add the following line to /usr/src/linux/include/linux/proc_fs.h
215 in the enum scsi_directory_inos array:
216
217 PROC_SCSI_ADVANSYS,
218
219 5. (Optional) If you would like to enable the LILO command line
220 and /etc/lilo.conf 'advansys' option, make the following changes.
221 This option can be used to disable I/O port scanning or to limit
222 I/O port scanning to specific addresses. Refer to the 'Driver
223 LILO Option' section below. Add the following lines to
224 /usr/src/linux/init/main.c in the prototype section:
225
226 extern void advansys_setup(char *str, int *ints);
227
228 and add the following lines to the bootsetups[] array.
229
230 #ifdef CONFIG_SCSI_ADVANSYS
231 { "advansys=", advansys_setup },
232 #endif
233
234 6. In the directory /usr/src/linux run 'make config' to configure
235 the AdvanSys driver, then run 'make vmlinux' or 'make zlilo' to
236 make the kernel. If the AdvanSys driver is not configured, then
237 a loadable module can be built by running 'make modules' and
238 'make modules_install'. Use 'insmod' and 'rmmod' to install
239 and remove advansys.o.
240
241 E. Linux v1.3.58 and Newer - Upgrading the AdvanSys Driver
242
243 To upgrade the AdvanSys driver in a Linux v1.3.58 and newer
244 kernel, first check the version of the current driver. The
245 version is defined by the manifest constant ASC_VERSION at
246 the beginning of advansys.c. The new driver should have a
247 ASC_VERSION value greater than the current version. To install
248 the new driver rename advansys.c and advansys.h in the Linux
249 kernel source tree drivers/scsi directory to different names
250 or save them to a different directory in case you want to revert
251 to the old version of the driver. After the old driver is saved
252 copy the new advansys.c and advansys.h to drivers/scsi, rebuild
253 the kernel, and install the new kernel. No other changes are needed.
254
255 F. Source Comments
256
257 1. Use tab stops set to 4 for the source files. For vi use 'se tabstops=4'.
258
259 2. This driver should be maintained in multiple files. But to make
260 it easier to include with Linux and to follow Linux conventions,
261 the whole driver is maintained in the source files advansys.h and
262 advansys.c. In this file logical sections of the driver begin with
263 a comment that contains '---'. The following are the logical sections
264 of the driver below.
265
266 --- Linux Version
267 --- Linux Include Files
268 --- Driver Options
269 --- Debugging Header
270 --- Asc Library Constants and Macros
271 --- Adv Library Constants and Macros
272 --- Driver Constants and Macros
273 --- Driver Structures
274 --- Driver Data
275 --- Driver Function Prototypes
276 --- Linux 'Scsi_Host_Template' and advansys_setup() Functions
277 --- Loadable Driver Support
278 --- Miscellaneous Driver Functions
279 --- Functions Required by the Asc Library
280 --- Functions Required by the Adv Library
281 --- Tracing and Debugging Functions
282 --- Asc Library Functions
283 --- Adv Library Functions
284
285 3. The string 'XXX' is used to flag code that needs to be re-written
286 or that contains a problem that needs to be addressed.
287
288 4. I have stripped comments from and reformatted the source for the
289 Asc Library and Adv Library to reduce the size of this file. This
290 source can be found under the following headings. The Asc Library
291 is used to support Narrow Boards. The Adv Library is used to
292 support Wide Boards.
293
294 --- Asc Library Constants and Macros
295 --- Adv Library Constants and Macros
296 --- Asc Library Functions
297 --- Adv Library Functions
298
299 G. Driver Compile Time Options and Debugging
300
301 In this source file the following constants can be defined. They are
302 defined in the source below. Both of these options are enabled by
303 default.
304
305 1. ADVANSYS_ASSERT - Enable driver assertions (Def: Enabled)
306
307 Enabling this option adds assertion logic statements to the
308 driver. If an assertion fails a message will be displayed to
309 the console, but the system will continue to operate. Any
310 assertions encountered should be reported to the person
311 responsible for the driver. Assertion statements may proactively
312 detect problems with the driver and facilitate fixing these
313 problems. Enabling assertions will add a small overhead to the
314 execution of the driver.
315
316 2. ADVANSYS_DEBUG - Enable driver debugging (Def: Disabled)
317
318 Enabling this option adds tracing functions to the driver and
319 the ability to set a driver tracing level at boot time. This
320 option will also export symbols not required outside the driver to
321 the kernel name space. This option is very useful for debugging
322 the driver, but it will add to the size of the driver execution
323 image and add overhead to the execution of the driver.
324
325 The amount of debugging output can be controlled with the global
326 variable 'asc_dbglvl'. The higher the number the more output. By
327 default the debug level is 0.
328
329 If the driver is loaded at boot time and the LILO Driver Option
330 is included in the system, the debug level can be changed by
331 specifying a 5th (ASC_NUM_IOPORT_PROBE + 1) I/O Port. The
332 first three hex digits of the pseudo I/O Port must be set to
333 'deb' and the fourth hex digit specifies the debug level: 0 - F.
334 The following command line will look for an adapter at 0x330
335 and set the debug level to 2.
336
337 linux advansys=0x330,0,0,0,0xdeb2
338
339 If the driver is built as a loadable module this variable can be
340 defined when the driver is loaded. The following insmod command
341 will set the debug level to one.
342
343 insmod advansys.o asc_dbglvl=1
344
345 Debugging Message Levels:
346 0: Errors Only
347 1: High-Level Tracing
348 2-N: Verbose Tracing
349
350 I don't know the approved way for turning on printk()s to the
351 console. Here's a program I use to do this. Debug output is
352 logged in /var/adm/messages.
353
354 main()
355 {
356 syscall(103, 7, 0, 0);
357 }
358
359 I found that increasing LOG_BUF_LEN to 40960 in kernel/printk.c
360 prevents most level 1 debug messages from being lost.
361
362 3. ADVANSYS_STATS - Enable statistics (Def: Enabled >= v1.3.0)
363
364 Enabling this option adds statistics collection and display
365 through /proc to the driver. The information is useful for
366 monitoring driver and device performance. It will add to the
367 size of the driver execution image and add minor overhead to
368 the execution of the driver.
369
370 Statistics are maintained on a per adapter basis. Driver entry
371 point call counts and transfer size counts are maintained.
372 Statistics are only available for kernels greater than or equal
373 to v1.3.0 with the CONFIG_PROC_FS (/proc) file system configured.
374
375 AdvanSys SCSI adapter files have the following path name format:
376
377 /proc/scsi/advansys/[0-(ASC_NUM_BOARD_SUPPORTED-1)]
378
379 This information can be displayed with cat. For example:
380
381 cat /proc/scsi/advansys/0
382
383 When ADVANSYS_STATS is not defined the AdvanSys /proc files only
384 contain adapter and device configuration information.
385
386 H. Driver LILO Option
387
388 If init/main.c is modified as described in the 'Directions for Adding
389 the AdvanSys Driver to Linux' section (B.4.) above, the driver will
390 recognize the 'advansys' LILO command line and /etc/lilo.conf option.
391 This option can be used to either disable I/O port scanning or to limit
392 scanning to 1 - 4 I/O ports. Regardless of the option setting EISA and
393 PCI boards will still be searched for and detected. This option only
394 affects searching for ISA and VL boards.
395
396 Examples:
397 1. Eliminate I/O port scanning:
398 boot: linux advansys=
399 or
400 boot: linux advansys=0x0
401 2. Limit I/O port scanning to one I/O port:
402 boot: linux advansys=0x110
403 3. Limit I/O port scanning to four I/O ports:
404 boot: linux advansys=0x110,0x210,0x230,0x330
405
406 For a loadable module the same effect can be achieved by setting
407 the 'asc_iopflag' variable and 'asc_ioport' array when loading
408 the driver, e.g.
409
410 insmod advansys.o asc_iopflag=1 asc_ioport=0x110,0x330
411
412 If ADVANSYS_DEBUG is defined a 5th (ASC_NUM_IOPORT_PROBE + 1)
413 I/O Port may be added to specify the driver debug level. Refer to
414 the 'Driver Compile Time Options and Debugging' section above for
415 more information.
416
417 I. Release History
418
419 BETA-1.0 (12/23/95):
420 First Release
421
422 BETA-1.1 (12/28/95):
423 1. Prevent advansys_detect() from being called twice.
424 2. Add LILO 0xdeb[0-f] option to set 'asc_dbglvl'.
425
426 1.2 (1/12/96):
427 1. Prevent re-entrancy in the interrupt handler which
428 resulted in the driver hanging Linux.
429 2. Fix problem that prevented ABP-940 cards from being
430 recognized on some PCI motherboards.
431 3. Add support for the ABP-5140 PnP ISA card.
432 4. Fix check condition return status.
433 5. Add conditionally compiled code for Linux v1.3.X.
434
435 1.3 (2/23/96):
436 1. Fix problem in advansys_biosparam() that resulted in the
437 wrong drive geometry being returned for drives > 1GB with
438 extended translation enabled.
439 2. Add additional tracing during device initialization.
440 3. Change code that only applies to ISA PnP adapter.
441 4. Eliminate 'make dep' warning.
442 5. Try to fix problem with handling resets by increasing their
443 timeout value.
444
445 1.4 (5/8/96):
446 1. Change definitions to eliminate conflicts with other subsystems.
447 2. Add versioning code for the shared interrupt changes.
448 3. Eliminate problem in asc_rmqueue() with iterating after removing
449 a request.
450 4. Remove reset request loop problem from the "Known Problems or
451 Issues" section. This problem was isolated and fixed in the
452 mid-level SCSI driver.
453
454 1.5 (8/8/96):
455 1. Add support for ABP-940U (PCI Ultra) adapter.
456 2. Add support for IRQ sharing by setting the SA_SHIRQ flag for
457 request_irq and supplying a dev_id pointer to both request_irq()
458 and free_irq().
459 3. In AscSearchIOPortAddr11() restore a call to check_region() which
460 should be used before I/O port probing.
461 4. Fix bug in asc_prt_hex() which resulted in the displaying
462 the wrong data.
463 5. Incorporate miscellaneous Asc Library bug fixes and new microcode.
464 6. Change driver versioning to be specific to each Linux sub-level.
465 7. Change statistics gathering to be per adapter instead of global
466 to the driver.
467 8. Add more information and statistics to the adapter /proc file:
468 /proc/scsi/advansys[0...].
469 9. Remove 'cmd_per_lun' from the "Known Problems or Issues" list.
470 This problem has been addressed with the SCSI mid-level changes
471 made in v1.3.89. The advansys_select_queue_depths() function
472 was added for the v1.3.89 changes.
473
474 1.6 (9/10/96):
475 1. Incorporate miscellaneous Asc Library bug fixes and new microcode.
476
477 1.7 (9/25/96):
478 1. Enable clustering and optimize the setting of the maximum number
479 of scatter gather elements for any particular board. Clustering
480 increases CPU utilization, but results in a relatively larger
481 increase in I/O throughput.
482 2. Improve the performance of the request queuing functions by
483 adding a last pointer to the queue structure.
484 3. Correct problems with reset and abort request handling that
485 could have hung or crashed Linux.
486 4. Add more information to the adapter /proc file:
487 /proc/scsi/advansys[0...].
488 5. Remove the request timeout issue form the driver issues list.
489 6. Miscellaneous documentation additions and changes.
490
491 1.8 (10/4/96):
492 1. Make changes to handle the new v2.1.0 kernel memory mapping
493 in which a kernel virtual address may not be equivalent to its
494 bus or DMA memory address.
495 2. Change abort and reset request handling to make it yet even
496 more robust.
497 3. Try to mitigate request starvation by sending ordered requests
498 to heavily loaded, tag queuing enabled devices.
499 4. Maintain statistics on request response time.
500 5. Add request response time statistics and other information to
501 the adapter /proc file: /proc/scsi/advansys[0...].
502
503 1.9 (10/21/96):
504 1. Add conditionally compiled code (ASC_QUEUE_FLOW_CONTROL) to
505 make use of mid-level SCSI driver device queue depth flow
506 control mechanism. This will eliminate aborts caused by a
507 device being unable to keep up with requests and eliminate
508 repeat busy or QUEUE FULL status returned by a device.
509 2. Incorporate miscellaneous Asc Library bug fixes.
510 3. To allow the driver to work in kernels with broken module
511 support set 'cmd_per_lun' if the driver is compiled as a
512 module. This change affects kernels v1.3.89 to present.
513 4. Remove PCI BIOS address from the driver banner. The PCI BIOS
514 is relocated by the motherboard BIOS and its new address can
515 not be determined by the driver.
516 5. Add mid-level SCSI queue depth information to the adapter
517 /proc file: /proc/scsi/advansys[0...].
518
519 2.0 (11/14/96):
520 1. Change allocation of global structures used for device
521 initialization to guarantee they are in DMA-able memory.
522 Previously when the driver was loaded as a module these
523 structures might not have been in DMA-able memory, causing
524 device initialization to fail.
525
526 2.1 (12/30/96):
527 1. In advansys_reset(), if the request is a synchronous reset
528 request, even if the request serial number has changed, then
529 complete the request.
530 2. Add Asc Library bug fixes including new microcode.
531 3. Clear inquiry buffer before using it.
532 4. Correct ifdef typo.
533
534 2.2 (1/15/97):
535 1. Add Asc Library bug fixes including new microcode.
536 2. Add synchronous data transfer rate information to the
537 adapter /proc file: /proc/scsi/advansys[0...].
538 3. Change ADVANSYS_DEBUG to be disabled by default. This
539 will reduce the size of the driver image, eliminate execution
540 overhead, and remove unneeded symbols from the kernel symbol
541 space that were previously added by the driver.
542 4. Add new compile-time option ADVANSYS_ASSERT for assertion
543 code that used to be defined within ADVANSYS_DEBUG. This
544 option is enabled by default.
545
546 2.8 (5/26/97):
547 1. Change version number to 2.8 to synchronize the Linux driver
548 version numbering with other AdvanSys drivers.
549 2. Reformat source files without tabs to present the same view
550 of the file to everyone regardless of the editor tab setting
551 being used.
552 3. Add Asc Library bug fixes.
553
554 3.1A (1/8/98):
555 1. Change version number to 3.1 to indicate that support for
556 Ultra-Wide adapters (ABP-940UW) is included in this release.
557 2. Add Asc Library (Narrow Board) bug fixes.
558 3. Report an underrun condition with the host status byte set
559 to DID_UNDERRUN. Currently DID_UNDERRUN is defined to 0 which
560 causes the underrun condition to be ignored. When Linux defines
561 its own DID_UNDERRUN the constant defined in this file can be
562 removed.
563 4. Add patch to AscWaitTixISRDone().
564 5. Add support for up to 16 different AdvanSys host adapter SCSI
565 channels in one system. This allows four cards with four channels
566 to be used in one system.
567
568 3.1B (1/9/98):
569 1. Handle that PCI register base addresses are not always page
570 aligned even though ioremap() requires that the address argument
571 be page aligned.
572
573 3.1C (1/10/98):
574 1. Update latest BIOS version checked for from the /proc file.
575 2. Don't set microcode SDTR variable at initialization. Instead
576 wait until device capabilities have been detected from an Inquiry
577 command.
578
579 3.1D (1/21/98):
580 1. Improve performance when the driver is compiled as module by
581 allowing up to 64 scatter-gather elements instead of 8.
582
583 3.1E (5/1/98):
584 1. Set time delay in AscWaitTixISRDone() to 1000 ms.
585 2. Include SMP locking changes.
586 3. For v2.1.93 and newer kernels use CONFIG_PCI and new PCI BIOS
587 access functions.
588 4. Update board serial number printing.
589 5. Try allocating an IRQ both with and without the SA_INTERRUPT
590 flag set to allow IRQ sharing with drivers that do not set
591 the SA_INTERRUPT flag. Also display a more descriptive error
592 message if request_irq() fails.
593 5. Update to latest Asc and Adv Libraries.
594
595 J. Known Problems or Issues
596
597 1. Remove conditional constants (ASC_QUEUE_FLOW_CONTROL) around
598 the queue depth flow control code when mid-level SCSI changes
599 are included in Linux.
600
601 K. Credits
602
603 Nathan Hartwell <mage@cdc3.cdc.net> provided the directions and
604 basis for the Linux v1.3.X changes which were included in the
605 1.2 release.
606
607 Thomas E Zerucha <zerucha@shell.portal.com> pointed out a bug
608 in advansys_biosparam() which was fixed in the 1.3 release.
609
610 Erik Ratcliffe <erik@caldera.com> has done testing of the
611 AdvanSys driver in the Caldera releases.
612
613 Rik van Riel <H.H.vanRiel@fys.ruu.nl> provided a patch to
614 AscWaitTixISRDone() which he found necessary to make the
615 driver work with a SCSI-1 disk.
616
617 Mark Moran <mmoran@mmoran.com> has helped test Ultra-Wide
618 support in the 3.1A driver.
619
620 L. AdvanSys Contact Information
621
622 Mail: Advanced System Products, Inc.
623 1150 Ringwood Court
624 San Jose, CA 95131
625 Operator: 1-408-383-9400
626 FAX: 1-408-383-9612
627 Tech Support: 1-800-525-7440/1-408-467-2930
628 BBS: 1-408-383-9540 (14400,N,8,1)
629 Interactive FAX: 1-408-383-9753
630 Customer Direct Sales: 1-800-525-7443/1-408-383-5777
631 Tech Support E-Mail: support@advansys.com
632 FTP Site: ftp.advansys.com (login: anonymous)
633 Web Site: http://www.advansys.com
634
635*/
636
637
638/*
639 * --- Linux Version
640 */
641
642/* Convert Linux Version, Patch-level, Sub-level to LINUX_VERSION_CODE. */
643#define ASC_LINUX_VERSION(V, P, S)(((V) * 65536) + ((P) * 256) + (S)) (((V) * 65536) + ((P) * 256) + (S))
644
645#ifndef LINUX_VERSION_CODE131108
646#include <linux/version.h>
647#endif /* LINUX_VERSION_CODE */
648
649
650/*
651 * --- Linux Include Files
652 */
653
654#include <linux/config.h>
655#if LINUX_VERSION_CODE131108 >= ASC_LINUX_VERSION(1,3,0)(((1) * 65536) + ((3) * 256) + (0))
656#ifdef MODULE
657#include <linux/module.h>
658#endif /* MODULE */
659#endif /* version >= v1.3.0 */
660#include <linux/string.h>
661#include <linux/sched.h>
662#include <linux/kernel.h>
663#include <linux/head.h>
664#include <linux/types.h>
665#include <linux/ioport.h>
666#include <linux/delay.h>
667#include <linux/malloc.h>
668#include <linux/mm.h>
669#if LINUX_VERSION_CODE131108 >= ASC_LINUX_VERSION(1,3,0)(((1) * 65536) + ((3) * 256) + (0))
670#include <linux/proc_fs.h>
671#endif /* version >= v1.3.0 */
672#if LINUX_VERSION_CODE131108 >= ASC_LINUX_VERSION(2,1,23)(((2) * 65536) + ((1) * 256) + (23))
673#include <linux/init.h>
674#endif /* version >= v2.1.23 */
675#include <asm/io.h>
676#include <asm/system.h>
677#include <asm/dma.h>
678#if LINUX_VERSION_CODE131108 < ASC_LINUX_VERSION(1,3,0)(((1) * 65536) + ((3) * 256) + (0))
679#include "../block/blk.h"
680#else /* version >= v1.3.0 */
681#include <linux/blk.h>
682#include <linux/stat.h>
683#endif /* version >= v1.3.0 */
684#if LINUX_VERSION_CODE131108 >= ASC_LINUX_VERSION(2,1,95)(((2) * 65536) + ((1) * 256) + (95))
685#include <asm/spinlock.h>
686#endif /* version >= 2.1.95 */
687#include "scsi.h"
688#include "hosts.h"
689#include "sd.h"
690#include "advansys.h"
691#if LINUX_VERSION_CODE131108 >= ASC_LINUX_VERSION(2,1,93)(((2) * 65536) + ((1) * 256) + (93))
692#ifdef CONFIG_PCI1
693#include <linux/pci.h>
694#endif /* CONFIG_PCI */
695#else /* version < v2.1.93 */
696/*
697 * For earlier than v2.1.93 the driver has its own PCI configuration.
698 * If PCI is not needed in a kernel before v2.1.93 this define can be
699 * turned-off to make the driver object smaller.
700 */
701#define ASC_CONFIG_PCI
702#endif /* version < v2.1.93 */
703
704/*
705 * If Linux eventually defines a DID_UNDERRUN, the constant here can be
706 * removed. The current value of zero for DID_UNDERRUN results in underrun
707 * conditions being ignored.
708 */
709#define DID_UNDERRUN0 0
710
711
712/*
713 * --- Driver Options
714 */
715
716/* Enable driver assertions. */
717#define ADVANSYS_ASSERT
718
719/* Enable driver tracing. */
720/* #define ADVANSYS_DEBUG */
721
722/*
723 * Because of no /proc to display them, statistics are disabled
724 * for versions prior to v1.3.0.
725 */
726#if LINUX_VERSION_CODE131108 < ASC_LINUX_VERSION(1,3,0)(((1) * 65536) + ((3) * 256) + (0))
727#undef ADVANSYS_STATS /* Disable statistics */
728#else /* version >= v1.3.0 */
729#define ADVANSYS_STATS /* Enable statistics. */
730#endif /* version >= v1.3.0 */
731
732
733/*
734 * --- Debugging Header
735 */
736
737#ifdef ADVANSYS_DEBUG
738#define STATICstatic
739#else /* ADVANSYS_DEBUG */
740#define STATICstatic static
741#endif /* ADVANSYS_DEBUG */
742
743
744/*
745 * --- Asc Library Constants and Macros
746 */
747
748#define ASC_LIB_VERSION_MAJOR1 1
749#define ASC_LIB_VERSION_MINOR22 22
750#define ASC_LIB_SERIAL_NUMBER113 113
751
752typedef unsigned char uchar;
753
754#ifndef NULL((void *) 0)
755#define NULL((void *) 0) (0)
756#endif
757#ifndef TRUE1
758#define TRUE1 (1)
759#endif
760#ifndef FALSE0
761#define FALSE0 (0)
762#endif
763#define REGregister register
764#define rcharregister __s8 REGregister __s8
765#define rshortregister __s16 REGregister __s16
766#define rintregister __s32 REGregister __s32
767#define rlongregister __s32 REGregister __s32
768#define rucharregister __u8 REGregister __u8
769#define rushortregister __u16 REGregister __u16
770#define ruintregister __u32 REGregister __u32
771#define rulongregister __u32 REGregister __u32
772#define NULLPTR(void *)0 (void *)0
773#define FNULLPTR(void *)0UL (void *)0UL
774#define EOF(-1) (-1)
775#define EOS'\0' '\0'
776#define ERR(-1) (-1)
777#define UB_ERR(uchar)(0xFF) (uchar)(0xFF)
778#define UW_ERR(uint)(0xFFFF) (uint)(0xFFFF)
779#define UL_ERR(ulong)(0xFFFFFFFFUL) (ulong)(0xFFFFFFFFUL)
780#define iseven_word(val)((((uint)val) & (uint)0x0001) == 0) ((((uint)val) & (uint)0x0001) == 0)
781#define isodd_word(val)((((uint)val) & (uint)0x0001) != 0) ((((uint)val) & (uint)0x0001) != 0)
782#define toeven_word(val)(((uint)val) & (uint)0xFFFE) (((uint)val) & (uint)0xFFFE)
783#define biton(val, bits)(((uint)(val >> bits) & (uint)0x0001) != 0) (((uint)(val >> bits) & (uint)0x0001) != 0)
784#define bitoff(val, bits)(((uint)(val >> bits) & (uint)0x0001) == 0) (((uint)(val >> bits) & (uint)0x0001) == 0)
785#define lbiton(val, bits)(((ulong)(val >> bits) & (ulong)0x00000001UL) != 0) (((ulong)(val >> bits) & (ulong)0x00000001UL) != 0)
786#define lbitoff(val, bits)(((ulong)(val >> bits) & (ulong)0x00000001UL) == 0) (((ulong)(val >> bits) & (ulong)0x00000001UL) == 0)
787#define absh(val)((val) < 0 ? -(val) : (val)) ((val) < 0 ? -(val) : (val))
788#define swapbyte(ch)((((ch) << 4) | ((ch) >> 4))) ((((ch) << 4) | ((ch) >> 4)))
789#ifndef GBYTE(0x40000000UL)
790#define GBYTE(0x40000000UL) (0x40000000UL)
791#endif
792#ifndef MBYTE(0x100000UL)
793#define MBYTE(0x100000UL) (0x100000UL)
794#endif
795#ifndef KBYTE(0x400)
796#define KBYTE(0x400) (0x400)
797#endif
798#define HI_BYTE(x)(*((__u8 *)(&x)+1)) (*((__u8 *)(&x)+1))
799#define LO_BYTE(x)(*((__u8 *)&x)) (*((__u8 *)&x))
800#define HI_WORD(x)(*((__u16 *)(&x)+1)) (*((__u16 *)(&x)+1))
801#define LO_WORD(x)(*((__u16 *)&x)) (*((__u16 *)&x))
802#ifndef MAKEWORD
803#define MAKEWORD(lo, hi)((__u16) (((__u16) lo) | ((__u16) hi << 8))) ((__u16) (((__u16) lo) | ((__u16) hi << 8)))
804#endif
805#ifndef MAKELONG
806#define MAKELONG(lo, hi)((__u32) (((__u32) lo) | ((__u32) hi << 16))) ((__u32) (((__u32) lo) | ((__u32) hi << 16)))
807#endif
808#define SwapWords(dWord)((__u32) ((dWord >> 16) | (dWord << 16))) ((__u32) ((dWord >> 16) | (dWord << 16)))
809#define SwapBytes(word)((__u16) ((word >> 8) | (word << 8))) ((__u16) ((word >> 8) | (word << 8)))
810#define BigToLittle(dWord)((__u32) (((__u32) ((((__u32) (((__u32) ((__u16) (((*((__u16 *
)&dWord)) >> 8) | ((*((__u16 *)&dWord)) <<
8)))) | ((__u32) ((__u16) (((*((__u16 *)(&dWord)+1)) >>
8) | ((*((__u16 *)(&dWord)+1)) << 8))) << 16
))) >> 16) | (((__u32) (((__u32) ((__u16) (((*((__u16 *
)&dWord)) >> 8) | ((*((__u16 *)&dWord)) <<
8)))) | ((__u32) ((__u16) (((*((__u16 *)(&dWord)+1)) >>
8) | ((*((__u16 *)(&dWord)+1)) << 8))) << 16
))) << 16)))))
((__u32) (SwapWords(MAKELONG(SwapBytes(LO_WORD(dWord)), SwapBytes(HI_WORD(dWord))))((__u32) ((((__u32) (((__u32) ((__u16) (((*((__u16 *)&dWord
)) >> 8) | ((*((__u16 *)&dWord)) << 8)))) | (
(__u32) ((__u16) (((*((__u16 *)(&dWord)+1)) >> 8) |
((*((__u16 *)(&dWord)+1)) << 8))) << 16))) >>
16) | (((__u32) (((__u32) ((__u16) (((*((__u16 *)&dWord)
) >> 8) | ((*((__u16 *)&dWord)) << 8)))) | ((
__u32) ((__u16) (((*((__u16 *)(&dWord)+1)) >> 8) | (
(*((__u16 *)(&dWord)+1)) << 8))) << 16))) <<
16)))
))
811#define LittleToBig(dWord)((__u32) (((__u32) ((((__u32) (((__u32) ((__u16) (((*((__u16 *
)&dWord)) >> 8) | ((*((__u16 *)&dWord)) <<
8)))) | ((__u32) ((__u16) (((*((__u16 *)(&dWord)+1)) >>
8) | ((*((__u16 *)(&dWord)+1)) << 8))) << 16
))) >> 16) | (((__u32) (((__u32) ((__u16) (((*((__u16 *
)&dWord)) >> 8) | ((*((__u16 *)&dWord)) <<
8)))) | ((__u32) ((__u16) (((*((__u16 *)(&dWord)+1)) >>
8) | ((*((__u16 *)(&dWord)+1)) << 8))) << 16
))) << 16)))))
BigToLittle(dWord)((__u32) (((__u32) ((((__u32) (((__u32) ((__u16) (((*((__u16 *
)&dWord)) >> 8) | ((*((__u16 *)&dWord)) <<
8)))) | ((__u32) ((__u16) (((*((__u16 *)(&dWord)+1)) >>
8) | ((*((__u16 *)(&dWord)+1)) << 8))) << 16
))) >> 16) | (((__u32) (((__u32) ((__u16) (((*((__u16 *
)&dWord)) >> 8) | ((*((__u16 *)&dWord)) <<
8)))) | ((__u32) ((__u16) (((*((__u16 *)(&dWord)+1)) >>
8) | ((*((__u16 *)(&dWord)+1)) << 8))) << 16
))) << 16)))))
812#define AscPCIConfigVendorIDRegister0x0000 0x0000
813#define AscPCIConfigDeviceIDRegister0x0002 0x0002
814#define AscPCIConfigCommandRegister0x0004 0x0004
815#define AscPCIConfigStatusRegister0x0006 0x0006
816#define AscPCIConfigRevisionIDRegister0x0008 0x0008
817#define AscPCIConfigCacheSize0x000C 0x000C
818#define AscPCIConfigLatencyTimer0x000D 0x000D
819#define AscPCIIOBaseRegister0x0010 0x0010
820#define AscPCICmdRegBits_IOMemBusMaster0x0007 0x0007
821#define ASC_PCI_ID2BUS(id)((id) & 0xFF) ((id) & 0xFF)
822#define ASC_PCI_ID2DEV(id)(((id) >> 11) & 0x1F) (((id) >> 11) & 0x1F)
823#define ASC_PCI_ID2FUNC(id)(((id) >> 8) & 0x7) (((id) >> 8) & 0x7)
824#define ASC_PCI_MKID(bus, dev, func)((((dev) & 0x1F) << 11) | (((func) & 0x7) <<
8) | ((bus) & 0xFF))
((((dev) & 0x1F) << 11) | (((func) & 0x7) << 8) | ((bus) & 0xFF))
825#define ASC_PCI_VENDORID0x10CD 0x10CD
826#define ASC_PCI_DEVICEID_1200A0x1100 0x1100
827#define ASC_PCI_DEVICEID_1200B0x1200 0x1200
828#define ASC_PCI_DEVICEID_ULTRA0x1300 0x1300
829#define ASC_PCI_REVISION_31500x02 0x02
830#define ASC_PCI_REVISION_30500x03 0x03
831
832#define ASC_DVCLIB_CALL_DONE(1) (1)
833#define ASC_DVCLIB_CALL_FAILED(0) (0)
834#define ASC_DVCLIB_CALL_ERROR(-1) (-1)
835
836#define PortAddrunsigned short unsigned short /* port address size */
837#define Ptr2Funculong ulong
838#define inp(port)((__builtin_constant_p((port)) && (port) < 256) ? __inbc
(port) : __inb(port))
inb(port)((__builtin_constant_p((port)) && (port) < 256) ? __inbc
(port) : __inb(port))
839#define inpw(port)((__builtin_constant_p((port)) && (port) < 256) ? __inwc
(port) : __inw(port))
inw(port)((__builtin_constant_p((port)) && (port) < 256) ? __inwc
(port) : __inw(port))
840#define inpl(port)((__builtin_constant_p((port)) && (port) < 256) ? __inlc
(port) : __inl(port))
inl(port)((__builtin_constant_p((port)) && (port) < 256) ? __inlc
(port) : __inl(port))
841#define outp(port, byte)((__builtin_constant_p(((port))) && ((port)) < 256
) ? __outbc(((byte)),((port))) : __outb(((byte)),((port))))
outb((byte), (port))((__builtin_constant_p(((port))) && ((port)) < 256
) ? __outbc(((byte)),((port))) : __outb(((byte)),((port))))
842#define outpw(port, word)((__builtin_constant_p(((port))) && ((port)) < 256
) ? __outwc(((word)),((port))) : __outw(((word)),((port))))
outw((word), (port))((__builtin_constant_p(((port))) && ((port)) < 256
) ? __outwc(((word)),((port))) : __outw(((word)),((port))))
843#define outpl(port, long)((__builtin_constant_p(((port))) && ((port)) < 256
) ? __outlc(((long)),((port))) : __outl(((long)),((port))))
outl((long), (port))((__builtin_constant_p(((port))) && ((port)) < 256
) ? __outlc(((long)),((port))) : __outl(((long)),((port))))
844#define ASC_MAX_SG_QUEUE7 7
845#define ASC_MAX_SG_LIST0xff SG_ALL0xff
846
847#define ASC_CS_TYPEunsigned short unsigned short
848#ifndef asc_ptr_type
849#define asc_ptr_type
850#endif
851
852#ifndef ASC_GET_PTR2FUNC
853#define ASC_GET_PTR2FUNC(fun)(ulong)(fun) (Ptr2Funculong)(fun)
854#endif
855#define FLIP_BYTE_NIBBLE(x)(((x<<4)& 0xFF) | (x>>4)) (((x<<4)& 0xFF) | (x>>4))
856#define ASC_IS_ISA(0x0001) (0x0001)
857#define ASC_IS_ISAPNP(0x0081) (0x0081)
858#define ASC_IS_EISA(0x0002) (0x0002)
859#define ASC_IS_PCI(0x0004) (0x0004)
860#define ASC_IS_PCI_ULTRA(0x0104) (0x0104)
861#define ASC_IS_PCMCIA(0x0008) (0x0008)
862#define ASC_IS_MCA(0x0020) (0x0020)
863#define ASC_IS_VL(0x0040) (0x0040)
864#define ASC_ISA_PNP_PORT_ADDR(0x279) (0x279)
865#define ASC_ISA_PNP_PORT_WRITE((0x279)+0x800) (ASC_ISA_PNP_PORT_ADDR(0x279)+0x800)
866#define ASC_IS_WIDESCSI_16(0x0100) (0x0100)
867#define ASC_IS_WIDESCSI_32(0x0200) (0x0200)
868#define ASC_IS_BIG_ENDIAN(0x8000) (0x8000)
869#define ASC_CHIP_MIN_VER_VL(0x01) (0x01)
870#define ASC_CHIP_MAX_VER_VL(0x07) (0x07)
871#define ASC_CHIP_MIN_VER_PCI(0x09) (0x09)
872#define ASC_CHIP_MAX_VER_PCI(0x0F) (0x0F)
873#define ASC_CHIP_VER_PCI_BIT(0x08) (0x08)
874#define ASC_CHIP_MIN_VER_ISA(0x11) (0x11)
875#define ASC_CHIP_MIN_VER_ISA_PNP(0x21) (0x21)
876#define ASC_CHIP_MAX_VER_ISA(0x27) (0x27)
877#define ASC_CHIP_VER_ISA_BIT(0x30) (0x30)
878#define ASC_CHIP_VER_ISAPNP_BIT(0x20) (0x20)
879#define ASC_CHIP_VER_ASYN_BUG(0x21) (0x21)
880#define ASC_CHIP_VER_PCI0x08 0x08
881#define ASC_CHIP_VER_PCI_ULTRA_3150(0x08 | 0x02) (ASC_CHIP_VER_PCI0x08 | 0x02)
882#define ASC_CHIP_VER_PCI_ULTRA_3050(0x08 | 0x03) (ASC_CHIP_VER_PCI0x08 | 0x03)
883#define ASC_CHIP_MIN_VER_EISA(0x41) (0x41)
884#define ASC_CHIP_MAX_VER_EISA(0x47) (0x47)
885#define ASC_CHIP_VER_EISA_BIT(0x40) (0x40)
886#define ASC_CHIP_LATEST_VER_EISA(((0x41) - 1) + 3) ((ASC_CHIP_MIN_VER_EISA(0x41) - 1) + 3)
887#define ASC_MAX_LIB_SUPPORTED_ISA_CHIP_VER0x21 0x21
888#define ASC_MAX_LIB_SUPPORTED_PCI_CHIP_VER0x0A 0x0A
889#define ASC_MAX_VL_DMA_ADDR(0x07FFFFFFL) (0x07FFFFFFL)
890#define ASC_MAX_VL_DMA_COUNT(0x07FFFFFFL) (0x07FFFFFFL)
891#define ASC_MAX_PCI_DMA_ADDR(0xFFFFFFFFL) (0xFFFFFFFFL)
892#define ASC_MAX_PCI_DMA_COUNT(0xFFFFFFFFL) (0xFFFFFFFFL)
893#define ASC_MAX_ISA_DMA_ADDR(0x00FFFFFFL) (0x00FFFFFFL)
894#define ASC_MAX_ISA_DMA_COUNT(0x00FFFFFFL) (0x00FFFFFFL)
895#define ASC_MAX_EISA_DMA_ADDR(0x07FFFFFFL) (0x07FFFFFFL)
896#define ASC_MAX_EISA_DMA_COUNT(0x07FFFFFFL) (0x07FFFFFFL)
897#ifndef inpw_noswap
898#define inpw_noswap(port)((__builtin_constant_p((port)) && (port) < 256) ? __inwc
(port) : __inw(port))
inpw(port)((__builtin_constant_p((port)) && (port) < 256) ? __inwc
(port) : __inw(port))
899#endif
900#ifndef outpw_noswap
901#define outpw_noswap(port, data)((__builtin_constant_p(((port))) && ((port)) < 256
) ? __outwc(((data)),((port))) : __outw(((data)),((port))))
outpw(port, data)((__builtin_constant_p(((port))) && ((port)) < 256
) ? __outwc(((data)),((port))) : __outw(((data)),((port))))
902#endif
903#define ASC_SCSI_ID_BITS3 3
904#define ASC_SCSI_TIX_TYPEuchar uchar
905#define ASC_ALL_DEVICE_BIT_SET0xFF 0xFF
906#ifdef ASC_WIDESCSI_16
907#undef ASC_SCSI_ID_BITS3
908#define ASC_SCSI_ID_BITS3 4
909#define ASC_ALL_DEVICE_BIT_SET0xFF 0xFFFF
910#endif
911#ifdef ASC_WIDESCSI_32
912#undef ASC_SCSI_ID_BITS3
913#define ASC_SCSI_ID_BITS3 5
914#define ASC_ALL_DEVICE_BIT_SET0xFF 0xFFFFFFFFL
915#endif
916#if ASC_SCSI_ID_BITS3 == 3
917#define ASC_SCSI_BIT_ID_TYPEuchar uchar
918#define ASC_MAX_TID7 7
919#define ASC_MAX_LUN7 7
920#define ASC_SCSI_WIDTH_BIT_SET0xFF 0xFF
921#elif ASC_SCSI_ID_BITS3 == 4
922#define ASC_SCSI_BIT_ID_TYPEuchar ushort
923#define ASC_MAX_TID7 15
924#define ASC_MAX_LUN7 7
925#define ASC_SCSI_WIDTH_BIT_SET0xFF 0xFFFF
926#elif ASC_SCSI_ID_BITS3 == 5
927#define ASC_SCSI_BIT_ID_TYPEuchar ulong
928#define ASC_MAX_TID7 31
929#define ASC_MAX_LUN7 7
930#define ASC_SCSI_WIDTH_BIT_SET0xFF 0xFFFFFFFF
931#else
932#error ASC_SCSI_ID_BITS3 definition is wrong
933#endif
934#define ASC_MAX_SENSE_LEN32 32
935#define ASC_MIN_SENSE_LEN14 14
936#define ASC_MAX_CDB_LEN12 12
937#define ASC_SCSI_RESET_HOLD_TIME_US60 60
938#define SCSICMD_TestUnitReady0x00 0x00
939#define SCSICMD_Rewind0x01 0x01
940#define SCSICMD_Rezero0x01 0x01
941#define SCSICMD_RequestSense0x03 0x03
942#define SCSICMD_Format0x04 0x04
943#define SCSICMD_FormatUnit0x04 0x04
944#define SCSICMD_Read60x08 0x08
945#define SCSICMD_Write60x0A 0x0A
946#define SCSICMD_Seek60x0B 0x0B
947#define SCSICMD_Inquiry0x12 0x12
948#define SCSICMD_Verify60x13 0x13
949#define SCSICMD_ModeSelect60x15 0x15
950#define SCSICMD_ModeSense60x1A 0x1A
951#define SCSICMD_StartStopUnit0x1B 0x1B
952#define SCSICMD_LoadUnloadTape0x1B 0x1B
953#define SCSICMD_ReadCapacity0x25 0x25
954#define SCSICMD_Read100x28 0x28
955#define SCSICMD_Write100x2A 0x2A
956#define SCSICMD_Seek100x2B 0x2B
957#define SCSICMD_Erase100x2C 0x2C
958#define SCSICMD_WriteAndVerify100x2E 0x2E
959#define SCSICMD_Verify100x2F 0x2F
960#define SCSICMD_WriteBuffer0x3B 0x3B
961#define SCSICMD_ReadBuffer0x3C 0x3C
962#define SCSICMD_ReadLong0x3E 0x3E
963#define SCSICMD_WriteLong0x3F 0x3F
964#define SCSICMD_ReadTOC0x43 0x43
965#define SCSICMD_ReadHeader0x44 0x44
966#define SCSICMD_ModeSelect100x55 0x55
967#define SCSICMD_ModeSense100x5A 0x5A
968#define SCSI_TYPE_DASD0x00 0x00
969#define SCSI_TYPE_SASD0x01 0x01
970#define SCSI_TYPE_PRN0x02 0x02
971#define SCSI_TYPE_PROC0x03 0x03
972#define SCSI_TYPE_WORM0x04 0x04
973#define SCSI_TYPE_CDROM0x05 0x05
974#define SCSI_TYPE_SCANNER0x06 0x06
975#define SCSI_TYPE_OPTMEM0x07 0x07
976#define SCSI_TYPE_MED_CHG0x08 0x08
977#define SCSI_TYPE_COMM0x09 0x09
978#define SCSI_TYPE_UNKNOWN0x1F 0x1F
979#define SCSI_TYPE_NO_DVC0xFF 0xFF
980#define ASC_SCSIDIR_NOCHK0x00 0x00
981#define ASC_SCSIDIR_T2H0x08 0x08
982#define ASC_SCSIDIR_H2T0x10 0x10
983#define ASC_SCSIDIR_NODATA0x18 0x18
984#define SCSI_SENKEY_NO_SENSE0x00 0x00
985#define SCSI_SENKEY_UNDEFINED0x01 0x01
986#define SCSI_SENKEY_NOT_READY0x02 0x02
987#define SCSI_SENKEY_MEDIUM_ERR0x03 0x03
988#define SCSI_SENKEY_HW_ERR0x04 0x04
989#define SCSI_SENKEY_ILLEGAL0x05 0x05
990#define SCSI_SENKEY_ATTENTION0x06 0x06
991#define SCSI_SENKEY_PROTECTED0x07 0x07
992#define SCSI_SENKEY_BLANK0x08 0x08
993#define SCSI_SENKEY_V_UNIQUE0x09 0x09
994#define SCSI_SENKEY_CPY_ABORT0x0A 0x0A
995#define SCSI_SENKEY_ABORT0x0B 0x0B
996#define SCSI_SENKEY_EQUAL0x0C 0x0C
997#define SCSI_SENKEY_VOL_OVERFLOW0x0D 0x0D
998#define SCSI_SENKEY_MISCOMP0x0E 0x0E
999#define SCSI_SENKEY_RESERVED0x0F 0x0F
1000#define SCSI_ASC_NOMEDIA0x3A 0x3A
1001#define ASC_SRB_HOST(x)((uchar)((uchar)(x) >> 4)) ((uchar)((uchar)(x) >> 4))
1002#define ASC_SRB_TID(x)((uchar)((uchar)(x) & (uchar)0x0F)) ((uchar)((uchar)(x) & (uchar)0x0F))
1003#define ASC_SRB_LUN(x)((uchar)((uint)(x) >> 13)) ((uchar)((uint)(x) >> 13))
1004#define PUT_CDB1(x)((uchar)((uint)(x) >> 8)) ((uchar)((uint)(x) >> 8))
1005#define SS_GOOD0x00 0x00
1006#define SS_CHK_CONDITION0x02 0x02
1007#define SS_CONDITION_MET0x04 0x04
1008#define SS_TARGET_BUSY0x08 0x08
1009#define SS_INTERMID0x10 0x10
1010#define SS_INTERMID_COND_MET0x14 0x14
1011#define SS_RSERV_CONFLICT0x18 0x18
1012#define SS_CMD_TERMINATED0x22 0x22
1013#define SS_QUEUE_FULL0x28 0x28
1014#define MS_CMD_DONE0x00 0x00
1015#define MS_EXTEND0x01 0x01
1016#define MS_SDTR_LEN0x03 0x03
1017#define MS_SDTR_CODE0x01 0x01
1018#define MS_WDTR_LEN0x02 0x02
1019#define MS_WDTR_CODE0x03 0x03
1020#define MS_MDP_LEN0x05 0x05
1021#define MS_MDP_CODE0x00 0x00
1022#define M1_SAVE_DATA_PTR0x02 0x02
1023#define M1_RESTORE_PTRS0x03 0x03
1024#define M1_DISCONNECT0x04 0x04
1025#define M1_INIT_DETECTED_ERR0x05 0x05
1026#define M1_ABORT0x06 0x06
1027#define M1_MSG_REJECT0x07 0x07
1028#define M1_NO_OP0x08 0x08
1029#define M1_MSG_PARITY_ERR0x09 0x09
1030#define M1_LINK_CMD_DONE0x0A 0x0A
1031#define M1_LINK_CMD_DONE_WFLAG0x0B 0x0B
1032#define M1_BUS_DVC_RESET0x0C 0x0C
1033#define M1_ABORT_TAG0x0D 0x0D
1034#define M1_CLR_QUEUE0x0E 0x0E
1035#define M1_INIT_RECOVERY0x0F 0x0F
1036#define M1_RELEASE_RECOVERY0x10 0x10
1037#define M1_KILL_IO_PROC0x11 0x11
1038#define M2_QTAG_MSG_SIMPLE0x20 0x20
1039#define M2_QTAG_MSG_HEAD0x21 0x21
1040#define M2_QTAG_MSG_ORDERED0x22 0x22
1041#define M2_IGNORE_WIDE_RESIDUE0x23 0x23
1042
1043typedef struct {
1044 uchar peri_dvc_type:5;
1045 uchar peri_qualifier:3;
1046} ASC_SCSI_INQ0;
1047
1048typedef struct {
1049 uchar dvc_type_modifier:7;
1050 uchar rmb:1;
1051} ASC_SCSI_INQ1;
1052
1053typedef struct {
1054 uchar ansi_apr_ver:3;
1055 uchar ecma_ver:3;
1056 uchar iso_ver:2;
1057} ASC_SCSI_INQ2;
1058
1059typedef struct {
1060 uchar rsp_data_fmt:4;
1061 uchar res:2;
1062 uchar TemIOP:1;
1063 uchar aenc:1;
1064} ASC_SCSI_INQ3;
1065
1066typedef struct {
1067 uchar StfRe:1;
1068 uchar CmdQue:1;
1069 uchar Reserved:1;
1070 uchar Linked:1;
1071 uchar Sync:1;
1072 uchar WBus16:1;
1073 uchar WBus32:1;
1074 uchar RelAdr:1;
1075} ASC_SCSI_INQ7;
1076
1077typedef struct {
1078 ASC_SCSI_INQ0 byte0;
1079 ASC_SCSI_INQ1 byte1;
1080 ASC_SCSI_INQ2 byte2;
1081 ASC_SCSI_INQ3 byte3;
1082 uchar add_len;
1083 uchar res1;
1084 uchar res2;
1085 ASC_SCSI_INQ7 byte7;
1086 uchar vendor_id[8];
1087 uchar product_id[16];
1088 uchar product_rev_level[4];
1089} ASC_SCSI_INQUIRY;
1090
1091typedef struct asc_req_sense {
1092 uchar err_code:7;
1093 uchar info_valid:1;
1094 uchar segment_no;
1095 uchar sense_key:4;
1096 uchar reserved_bit:1;
1097 uchar sense_ILI:1;
1098 uchar sense_EOM:1;
1099 uchar file_mark:1;
1100 uchar info1[4];
1101 uchar add_sense_len;
1102 uchar cmd_sp_info[4];
1103 uchar asc;
1104 uchar ascq;
1105 uchar fruc;
1106 uchar sks_byte0:7;
1107 uchar sks_valid:1;
1108 uchar sks_bytes[2];
1109 uchar notused[2];
1110 uchar ex_sense_code;
1111 uchar info2[4];
1112} ASC_REQ_SENSE;
1113
1114#define ASC_SG_LIST_PER_Q7 7
1115#define QS_FREE0x00 0x00
1116#define QS_READY0x01 0x01
1117#define QS_DISC10x02 0x02
1118#define QS_DISC20x04 0x04
1119#define QS_BUSY0x08 0x08
1120#define QS_ABORTED0x40 0x40
1121#define QS_DONE0x80 0x80
1122#define QC_NO_CALLBACK0x01 0x01
1123#define QC_SG_SWAP_QUEUE0x02 0x02
1124#define QC_SG_HEAD0x04 0x04
1125#define QC_DATA_IN0x08 0x08
1126#define QC_DATA_OUT0x10 0x10
1127#define QC_URGENT0x20 0x20
1128#define QC_MSG_OUT0x40 0x40
1129#define QC_REQ_SENSE0x80 0x80
1130#define QCSG_SG_XFER_LIST0x02 0x02
1131#define QCSG_SG_XFER_MORE0x04 0x04
1132#define QCSG_SG_XFER_END0x08 0x08
1133#define QD_IN_PROGRESS0x00 0x00
1134#define QD_NO_ERROR0x01 0x01
1135#define QD_ABORTED_BY_HOST0x02 0x02
1136#define QD_WITH_ERROR0x04 0x04
1137#define QD_INVALID_REQUEST0x80 0x80
1138#define QD_INVALID_HOST_NUM0x81 0x81
1139#define QD_INVALID_DEVICE0x82 0x82
1140#define QD_ERR_INTERNAL0xFF 0xFF
1141#define QHSTA_NO_ERROR0x00 0x00
1142#define QHSTA_M_SEL_TIMEOUT0x11 0x11
1143#define QHSTA_M_DATA_OVER_RUN0x12 0x12
1144#define QHSTA_M_DATA_UNDER_RUN0x12 0x12
1145#define QHSTA_M_UNEXPECTED_BUS_FREE0x13 0x13
1146#define QHSTA_M_BAD_BUS_PHASE_SEQ0x14 0x14
1147#define QHSTA_D_QDONE_SG_LIST_CORRUPTED0x21 0x21
1148#define QHSTA_D_ASC_DVC_ERROR_CODE_SET0x22 0x22
1149#define QHSTA_D_HOST_ABORT_FAILED0x23 0x23
1150#define QHSTA_D_EXE_SCSI_Q_FAILED0x24 0x24
1151#define QHSTA_D_EXE_SCSI_Q_BUSY_TIMEOUT0x25 0x25
1152#define QHSTA_D_ASPI_NO_BUF_POOL0x26 0x26
1153#define QHSTA_M_WTM_TIMEOUT0x41 0x41
1154#define QHSTA_M_BAD_CMPL_STATUS_IN0x42 0x42
1155#define QHSTA_M_NO_AUTO_REQ_SENSE0x43 0x43
1156#define QHSTA_M_AUTO_REQ_SENSE_FAIL0x44 0x44
1157#define QHSTA_M_TARGET_STATUS_BUSY0x45 0x45
1158#define QHSTA_M_BAD_TAG_CODE0x46 0x46
1159#define QHSTA_M_BAD_QUEUE_FULL_OR_BUSY0x47 0x47
1160#define QHSTA_M_HUNG_REQ_SCSI_BUS_RESET0x48 0x48
1161#define QHSTA_D_LRAM_CMP_ERROR0x81 0x81
1162#define QHSTA_M_MICRO_CODE_ERROR_HALT0xA1 0xA1
1163#define ASC_FLAG_SCSIQ_REQ0x01 0x01
1164#define ASC_FLAG_BIOS_SCSIQ_REQ0x02 0x02
1165#define ASC_FLAG_BIOS_ASYNC_IO0x04 0x04
1166#define ASC_FLAG_SRB_LINEAR_ADDR0x08 0x08
1167#define ASC_FLAG_WIN160x10 0x10
1168#define ASC_FLAG_WIN320x20 0x20
1169#define ASC_FLAG_ISA_OVER_16MB0x40 0x40
1170#define ASC_FLAG_DOS_VM_CALLBACK0x80 0x80
1171#define ASC_TAG_FLAG_EXTRA_BYTES0x10 0x10
1172#define ASC_TAG_FLAG_DISABLE_DISCONNECT0x04 0x04
1173#define ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX0x08 0x08
1174#define ASC_TAG_FLAG_DISABLE_CHK_COND_INT_HOST0x40 0x40
1175#define ASC_SCSIQ_CPY_BEG4 4
1176#define ASC_SCSIQ_SGHD_CPY_BEG2 2
1177#define ASC_SCSIQ_B_FWD0 0
1178#define ASC_SCSIQ_B_BWD1 1
1179#define ASC_SCSIQ_B_STATUS2 2
1180#define ASC_SCSIQ_B_QNO3 3
1181#define ASC_SCSIQ_B_CNTL4 4
1182#define ASC_SCSIQ_B_SG_QUEUE_CNT5 5
1183#define ASC_SCSIQ_D_DATA_ADDR8 8
1184#define ASC_SCSIQ_D_DATA_CNT12 12
1185#define ASC_SCSIQ_B_SENSE_LEN20 20
1186#define ASC_SCSIQ_DONE_INFO_BEG22 22
1187#define ASC_SCSIQ_D_SRBPTR22 22
1188#define ASC_SCSIQ_B_TARGET_IX26 26
1189#define ASC_SCSIQ_B_CDB_LEN28 28
1190#define ASC_SCSIQ_B_TAG_CODE29 29
1191#define ASC_SCSIQ_W_VM_ID30 30
1192#define ASC_SCSIQ_DONE_STATUS32 32
1193#define ASC_SCSIQ_HOST_STATUS33 33
1194#define ASC_SCSIQ_SCSI_STATUS34 34
1195#define ASC_SCSIQ_CDB_BEG36 36
1196#define ASC_SCSIQ_DW_REMAIN_XFER_ADDR56 56
1197#define ASC_SCSIQ_DW_REMAIN_XFER_CNT60 60
1198#define ASC_SCSIQ_B_SG_WK_QP49 49
1199#define ASC_SCSIQ_B_SG_WK_IX50 50
1200#define ASC_SCSIQ_W_REQ_COUNT52 52
1201#define ASC_SCSIQ_B_LIST_CNT6 6
1202#define ASC_SCSIQ_B_CUR_LIST_CNT7 7
1203#define ASC_SGQ_B_SG_CNTL4 4
1204#define ASC_SGQ_B_SG_HEAD_QP5 5
1205#define ASC_SGQ_B_SG_LIST_CNT6 6
1206#define ASC_SGQ_B_SG_CUR_LIST_CNT7 7
1207#define ASC_SGQ_LIST_BEG8 8
1208#define ASC_DEF_SCSI1_QNG4 4
1209#define ASC_MAX_SCSI1_QNG4 4
1210#define ASC_DEF_SCSI2_QNG16 16
1211#define ASC_MAX_SCSI2_QNG32 32
1212#define ASC_TAG_CODE_MASK0x23 0x23
1213#define ASC_STOP_REQ_RISC_STOP0x01 0x01
1214#define ASC_STOP_ACK_RISC_STOP0x03 0x03
1215#define ASC_STOP_CLEAN_UP_BUSY_Q0x10 0x10
1216#define ASC_STOP_CLEAN_UP_DISC_Q0x20 0x20
1217#define ASC_STOP_HOST_REQ_RISC_HALT0x40 0x40
1218#define ASC_TIDLUN_TO_IX(tid, lun)(uchar)((tid) + ((lun)<<3)) (ASC_SCSI_TIX_TYPEuchar)((tid) + ((lun)<<ASC_SCSI_ID_BITS3))
1219#define ASC_TID_TO_TARGET_ID(tid)(uchar)(0x01 << (tid)) (ASC_SCSI_BIT_ID_TYPEuchar)(0x01 << (tid))
1220#define ASC_TIX_TO_TARGET_ID(tix)(0x01 << ((tix) & 7)) (0x01 << ((tix) & ASC_MAX_TID7))
1221#define ASC_TIX_TO_TID(tix)((tix) & 7) ((tix) & ASC_MAX_TID7)
1222#define ASC_TID_TO_TIX(tid)((tid) & 7) ((tid) & ASC_MAX_TID7)
1223#define ASC_TIX_TO_LUN(tix)(((tix) >> 3) & 7) (((tix) >> ASC_SCSI_ID_BITS3) & ASC_MAX_LUN7)
1224#define ASC_QNO_TO_QADDR(q_no)(((0x4000))+((int)(q_no) << 6)) ((ASC_QADR_BEG(0x4000))+((int)(q_no) << 6))
1225
1226typedef struct asc_scisq_1 {
1227 uchar status;
1228 uchar q_no;
1229 uchar cntl;
1230 uchar sg_queue_cnt;
1231 uchar target_id;
1232 uchar target_lun;
1233 ulong data_addr;
1234 ulong data_cnt;
1235 ulong sense_addr;
1236 uchar sense_len;
1237 uchar extra_bytes;
1238} ASC_SCSIQ_1;
1239
1240typedef struct asc_scisq_2 {
1241 ulong srb_ptr;
1242 uchar target_ix;
1243 uchar flag;
1244 uchar cdb_len;
1245 uchar tag_code;
1246 ushort vm_id;
1247} ASC_SCSIQ_2;
1248
1249typedef struct asc_scsiq_3 {
1250 uchar done_stat;
1251 uchar host_stat;
1252 uchar scsi_stat;
1253 uchar scsi_msg;
1254} ASC_SCSIQ_3;
1255
1256typedef struct asc_scsiq_4 {
1257 uchar cdb[ASC_MAX_CDB_LEN12];
1258 uchar y_first_sg_list_qp;
1259 uchar y_working_sg_qp;
1260 uchar y_working_sg_ix;
1261 uchar y_res;
1262 ushort x_req_count;
1263 ushort x_reconnect_rtn;
1264 ulong x_saved_data_addr;
1265 ulong x_saved_data_cnt;
1266} ASC_SCSIQ_4;
1267
1268typedef struct asc_q_done_info {
1269 ASC_SCSIQ_2 d2;
1270 ASC_SCSIQ_3 d3;
1271 uchar q_status;
1272 uchar q_no;
1273 uchar cntl;
1274 uchar sense_len;
1275 uchar extra_bytes;
1276 uchar res;
1277 ulong remain_bytes;
1278} ASC_QDONE_INFO;
1279
1280typedef struct asc_sg_list {
1281 ulong addr;
1282 ulong bytes;
1283} ASC_SG_LIST;
1284
1285typedef struct asc_sg_head {
1286 ushort entry_cnt;
1287 ushort queue_cnt;
1288 ushort entry_to_copy;
1289 ushort res;
1290 ASC_SG_LIST sg_list[ASC_MAX_SG_LIST0xff];
1291} ASC_SG_HEAD;
1292
1293#define ASC_MIN_SG_LIST2 2
1294
1295typedef struct asc_min_sg_head {
1296 ushort entry_cnt;
1297 ushort queue_cnt;
1298 ushort entry_to_copy;
1299 ushort res;
1300 ASC_SG_LIST sg_list[ASC_MIN_SG_LIST2];
1301} ASC_MIN_SG_HEAD;
1302
1303#define QCX_SORT(0x0001) (0x0001)
1304#define QCX_COALEASE(0x0002) (0x0002)
1305
1306typedef struct asc_scsi_q {
1307 ASC_SCSIQ_1 q1;
1308 ASC_SCSIQ_2 q2;
1309 uchar *cdbptr;
1310 ASC_SG_HEAD *sg_head;
1311} ASC_SCSI_Q;
1312
1313typedef struct asc_scsi_req_q {
1314 ASC_SCSIQ_1 r1;
1315 ASC_SCSIQ_2 r2;
1316 uchar *cdbptr;
1317 ASC_SG_HEAD *sg_head;
1318 uchar *sense_ptr;
1319 ASC_SCSIQ_3 r3;
1320 uchar cdb[ASC_MAX_CDB_LEN12];
1321 uchar sense[ASC_MIN_SENSE_LEN14];
1322} ASC_SCSI_REQ_Q;
1323
1324typedef struct asc_scsi_bios_req_q {
1325 ASC_SCSIQ_1 r1;
1326 ASC_SCSIQ_2 r2;
1327 uchar *cdbptr;
1328 ASC_SG_HEAD *sg_head;
1329 uchar *sense_ptr;
1330 ASC_SCSIQ_3 r3;
1331 uchar cdb[ASC_MAX_CDB_LEN12];
1332 uchar sense[ASC_MIN_SENSE_LEN14];
1333} ASC_SCSI_BIOS_REQ_Q;
1334
1335typedef struct asc_risc_q {
1336 uchar fwd;
1337 uchar bwd;
1338 ASC_SCSIQ_1 i1;
1339 ASC_SCSIQ_2 i2;
1340 ASC_SCSIQ_3 i3;
1341 ASC_SCSIQ_4 i4;
1342} ASC_RISC_Q;
1343
1344typedef struct asc_sg_list_q {
1345 uchar seq_no;
1346 uchar q_no;
1347 uchar cntl;
1348 uchar sg_head_qp;
1349 uchar sg_list_cnt;
1350 uchar sg_cur_list_cnt;
1351} ASC_SG_LIST_Q;
1352
1353typedef struct asc_risc_sg_list_q {
1354 uchar fwd;
1355 uchar bwd;
1356 ASC_SG_LIST_Q sg;
1357 ASC_SG_LIST sg_list[7];
1358} ASC_RISC_SG_LIST_Q;
1359
1360#define ASC_EXE_SCSI_IO_MAX_IDLE_LOOP0x1000000UL 0x1000000UL
1361#define ASC_EXE_SCSI_IO_MAX_WAIT_LOOP1024 1024
1362#define ASCQ_ERR_NO_ERROR0 0
1363#define ASCQ_ERR_IO_NOT_FOUND1 1
1364#define ASCQ_ERR_LOCAL_MEM2 2
1365#define ASCQ_ERR_CHKSUM3 3
1366#define ASCQ_ERR_START_CHIP4 4
1367#define ASCQ_ERR_INT_TARGET_ID5 5
1368#define ASCQ_ERR_INT_LOCAL_MEM6 6
1369#define ASCQ_ERR_HALT_RISC7 7
1370#define ASCQ_ERR_GET_ASPI_ENTRY8 8
1371#define ASCQ_ERR_CLOSE_ASPI9 9
1372#define ASCQ_ERR_HOST_INQUIRY0x0A 0x0A
1373#define ASCQ_ERR_SAVED_SRB_BAD0x0B 0x0B
1374#define ASCQ_ERR_QCNTL_SG_LIST0x0C 0x0C
1375#define ASCQ_ERR_Q_STATUS0x0D 0x0D
1376#define ASCQ_ERR_WR_SCSIQ0x0E 0x0E
1377#define ASCQ_ERR_PC_ADDR0x0F 0x0F
1378#define ASCQ_ERR_SYN_OFFSET0x10 0x10
1379#define ASCQ_ERR_SYN_XFER_TIME0x11 0x11
1380#define ASCQ_ERR_LOCK_DMA0x12 0x12
1381#define ASCQ_ERR_UNLOCK_DMA0x13 0x13
1382#define ASCQ_ERR_VDS_CHK_INSTALL0x14 0x14
1383#define ASCQ_ERR_MICRO_CODE_HALT0x15 0x15
1384#define ASCQ_ERR_SET_LRAM_ADDR0x16 0x16
1385#define ASCQ_ERR_CUR_QNG0x17 0x17
1386#define ASCQ_ERR_SG_Q_LINKS0x18 0x18
1387#define ASCQ_ERR_SCSIQ_PTR0x19 0x19
1388#define ASCQ_ERR_ISR_RE_ENTRY0x1A 0x1A
1389#define ASCQ_ERR_CRITICAL_RE_ENTRY0x1B 0x1B
1390#define ASCQ_ERR_ISR_ON_CRITICAL0x1C 0x1C
1391#define ASCQ_ERR_SG_LIST_ODD_ADDRESS0x1D 0x1D
1392#define ASCQ_ERR_XFER_ADDRESS_TOO_BIG0x1E 0x1E
1393#define ASCQ_ERR_SCSIQ_NULL_PTR0x1F 0x1F
1394#define ASCQ_ERR_SCSIQ_BAD_NEXT_PTR0x20 0x20
1395#define ASCQ_ERR_GET_NUM_OF_FREE_Q0x21 0x21
1396#define ASCQ_ERR_SEND_SCSI_Q0x22 0x22
1397#define ASCQ_ERR_HOST_REQ_RISC_HALT0x23 0x23
1398#define ASCQ_ERR_RESET_SDTR0x24 0x24
1399#define ASC_WARN_NO_ERROR0x0000 0x0000
1400#define ASC_WARN_IO_PORT_ROTATE0x0001 0x0001
1401#define ASC_WARN_EEPROM_CHKSUM0x0002 0x0002
1402#define ASC_WARN_IRQ_MODIFIED0x0004 0x0004
1403#define ASC_WARN_AUTO_CONFIG0x0008 0x0008
1404#define ASC_WARN_CMD_QNG_CONFLICT0x0010 0x0010
1405#define ASC_WARN_EEPROM_RECOVER0x0020 0x0020
1406#define ASC_WARN_CFG_MSW_RECOVER0x0040 0x0040
1407#define ASC_WARN_SET_PCI_CONFIG_SPACE0x0080 0x0080
1408#define ASC_IERR_WRITE_EEPROM0x0001 0x0001
1409#define ASC_IERR_MCODE_CHKSUM0x0002 0x0002
1410#define ASC_IERR_SET_PC_ADDR0x0004 0x0004
1411#define ASC_IERR_START_STOP_CHIP0x0008 0x0008
1412#define ASC_IERR_IRQ_NO0x0010 0x0010
1413#define ASC_IERR_SET_IRQ_NO0x0020 0x0020
1414#define ASC_IERR_CHIP_VERSION0x0040 0x0040
1415#define ASC_IERR_SET_SCSI_ID0x0080 0x0080
1416#define ASC_IERR_GET_PHY_ADDR0x0100 0x0100
1417#define ASC_IERR_BAD_SIGNATURE0x0200 0x0200
1418#define ASC_IERR_NO_BUS_TYPE0x0400 0x0400
1419#define ASC_IERR_SCAM0x0800 0x0800
1420#define ASC_IERR_SET_SDTR0x1000 0x1000
1421#define ASC_IERR_RW_LRAM0x8000 0x8000
1422#define ASC_DEF_IRQ_NO10 10
1423#define ASC_MAX_IRQ_NO15 15
1424#define ASC_MIN_IRQ_NO10 10
1425#define ASC_MIN_REMAIN_Q(0x02) (0x02)
1426#define ASC_DEF_MAX_TOTAL_QNG(0xF0) (0xF0)
1427#define ASC_MIN_TAG_Q_PER_DVC(0x04) (0x04)
1428#define ASC_DEF_TAG_Q_PER_DVC(0x04) (0x04)
1429#define ASC_MIN_FREE_Q(0x02) ASC_MIN_REMAIN_Q(0x02)
1430#define ASC_MIN_TOTAL_QNG((7)+((0x02))) ((ASC_MAX_SG_QUEUE7)+(ASC_MIN_FREE_Q(0x02)))
1431#define ASC_MAX_TOTAL_QNG240 240
1432#define ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG16 16
1433#define ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG8 8
1434#define ASC_MAX_PCI_INRAM_TOTAL_QNG20 20
1435#define ASC_MAX_INRAM_TAG_QNG16 16
1436#define ASC_IOADR_TABLE_MAX_IX11 11
1437#define ASC_IOADR_GAP0x10 0x10
1438#define ASC_SEARCH_IOP_GAP0x10 0x10
1439#define ASC_MIN_IOP_ADDR(unsigned short)0x0100 (PortAddrunsigned short)0x0100
1440#define ASC_MAX_IOP_ADDR(unsigned short)0x3F0 (PortAddrunsigned short)0x3F0
1441#define ASC_IOADR_1(unsigned short)0x0110 (PortAddrunsigned short)0x0110
1442#define ASC_IOADR_2(unsigned short)0x0130 (PortAddrunsigned short)0x0130
1443#define ASC_IOADR_3(unsigned short)0x0150 (PortAddrunsigned short)0x0150
1444#define ASC_IOADR_4(unsigned short)0x0190 (PortAddrunsigned short)0x0190
1445#define ASC_IOADR_5(unsigned short)0x0210 (PortAddrunsigned short)0x0210
1446#define ASC_IOADR_6(unsigned short)0x0230 (PortAddrunsigned short)0x0230
1447#define ASC_IOADR_7(unsigned short)0x0250 (PortAddrunsigned short)0x0250
1448#define ASC_IOADR_8(unsigned short)0x0330 (PortAddrunsigned short)0x0330
1449#define ASC_IOADR_DEF(unsigned short)0x0330 ASC_IOADR_8(unsigned short)0x0330
1450#define ASC_LIB_SCSIQ_WK_SP256 256
1451#define ASC_MAX_SYN_XFER_NO16 16
1452#define ASC_SYN_MAX_OFFSET0x0F 0x0F
1453#define ASC_DEF_SDTR_OFFSET0x0F 0x0F
1454#define ASC_DEF_SDTR_INDEX0x00 0x00
1455#define ASC_SDTR_ULTRA_PCI_10MB_INDEX0x02 0x02
1456#define SYN_XFER_NS_025 25
1457#define SYN_XFER_NS_130 30
1458#define SYN_XFER_NS_235 35
1459#define SYN_XFER_NS_340 40
1460#define SYN_XFER_NS_450 50
1461#define SYN_XFER_NS_560 60
1462#define SYN_XFER_NS_670 70
1463#define SYN_XFER_NS_785 85
1464#define SYN_ULTRA_XFER_NS_012 12
1465#define SYN_ULTRA_XFER_NS_119 19
1466#define SYN_ULTRA_XFER_NS_225 25
1467#define SYN_ULTRA_XFER_NS_332 32
1468#define SYN_ULTRA_XFER_NS_438 38
1469#define SYN_ULTRA_XFER_NS_544 44
1470#define SYN_ULTRA_XFER_NS_650 50
1471#define SYN_ULTRA_XFER_NS_757 57
1472#define SYN_ULTRA_XFER_NS_863 63
1473#define SYN_ULTRA_XFER_NS_969 69
1474#define SYN_ULTRA_XFER_NS_1075 75
1475#define SYN_ULTRA_XFER_NS_1182 82
1476#define SYN_ULTRA_XFER_NS_1288 88
1477#define SYN_ULTRA_XFER_NS_1394 94
1478#define SYN_ULTRA_XFER_NS_14100 100
1479#define SYN_ULTRA_XFER_NS_15107 107
1480
1481typedef struct ext_msg {
1482 uchar msg_type;
1483 uchar msg_len;
1484 uchar msg_req;
1485 union {
1486 struct {
1487 uchar sdtr_xfer_period;
1488 uchar sdtr_req_ack_offset;
1489 } sdtr;
1490 struct {
1491 uchar wdtr_widthu_ext_msg.wdtr.wdtr_width;
1492 } wdtr;
1493 struct {
1494 uchar mdp_b3u_ext_msg.mdp_b3;
1495 uchar mdp_b2u_ext_msg.mdp_b2;
1496 uchar mdp_b1u_ext_msg.mdp_b1;
1497 uchar mdp_b0u_ext_msg.mdp_b0;
1498 } mdp;
1499 } u_ext_msg;
1500 uchar res;
1501} EXT_MSG;
1502
1503#define xfer_periodu_ext_msg.sdtr.sdtr_xfer_period u_ext_msg.sdtr.sdtr_xfer_period
1504#define req_ack_offsetu_ext_msg.sdtr.sdtr_req_ack_offset u_ext_msg.sdtr.sdtr_req_ack_offset
1505#define wdtr_widthu_ext_msg.wdtr.wdtr_width u_ext_msg.wdtr.wdtr_widthu_ext_msg.wdtr.wdtr_width
1506#define mdp_b3u_ext_msg.mdp_b3 u_ext_msg.mdp_b3u_ext_msg.mdp_b3
1507#define mdp_b2u_ext_msg.mdp_b2 u_ext_msg.mdp_b2u_ext_msg.mdp_b2
1508#define mdp_b1u_ext_msg.mdp_b1 u_ext_msg.mdp_b1u_ext_msg.mdp_b1
1509#define mdp_b0u_ext_msg.mdp_b0 u_ext_msg.mdp_b0u_ext_msg.mdp_b0
1510
1511typedef struct asc_dvc_cfg {
1512 ASC_SCSI_BIT_ID_TYPEuchar can_tagged_qng;
1513 ASC_SCSI_BIT_ID_TYPEuchar cmd_qng_enabled;
1514 ASC_SCSI_BIT_ID_TYPEuchar disc_enable;
1515 ASC_SCSI_BIT_ID_TYPEuchar sdtr_enable;
1516 uchar chip_scsi_id:4;
1517 uchar isa_dma_speed:4;
1518 uchar isa_dma_channel;
1519 uchar chip_version;
1520 ushort pci_device_id;
1521 ushort lib_serial_no;
1522 ushort lib_version;
1523 ushort mcode_date;
1524 ushort mcode_version;
1525 uchar max_tag_qng[ASC_MAX_TID7 + 1];
1526 uchar *overrun_buf;
1527 uchar sdtr_period_offset[ASC_MAX_TID7 + 1];
1528 ushort pci_slot_info;
1529 uchar adapter_info[6];
1530} ASC_DVC_CFG;
1531
1532#define ASC_DEF_DVC_CNTL0xFFFF 0xFFFF
1533#define ASC_DEF_CHIP_SCSI_ID7 7
1534#define ASC_DEF_ISA_DMA_SPEED4 4
1535#define ASC_INIT_STATE_NULL0x0000 0x0000
1536#define ASC_INIT_STATE_BEG_GET_CFG0x0001 0x0001
1537#define ASC_INIT_STATE_END_GET_CFG0x0002 0x0002
1538#define ASC_INIT_STATE_BEG_SET_CFG0x0004 0x0004
1539#define ASC_INIT_STATE_END_SET_CFG0x0008 0x0008
1540#define ASC_INIT_STATE_BEG_LOAD_MC0x0010 0x0010
1541#define ASC_INIT_STATE_END_LOAD_MC0x0020 0x0020
1542#define ASC_INIT_STATE_BEG_INQUIRY0x0040 0x0040
1543#define ASC_INIT_STATE_END_INQUIRY0x0080 0x0080
1544#define ASC_INIT_RESET_SCSI_DONE0x0100 0x0100
1545#define ASC_INIT_STATE_WITHOUT_EEP0x8000 0x8000
1546#define ASC_PCI_DEVICE_ID_REV_A0x1100 0x1100
1547#define ASC_PCI_DEVICE_ID_REV_B0x1200 0x1200
1548#define ASC_BUG_FIX_IF_NOT_DWB0x0001 0x0001
1549#define ASC_BUG_FIX_ASYN_USE_SYN0x0002 0x0002
1550#define ASYN_SDTR_DATA_FIX_PCI_REV_AB0x41 0x41
1551#define ASC_MIN_TAGGED_CMD7 7
1552#define ASC_MAX_SCSI_RESET_WAIT30 30
1553
1554typedef struct asc_dvc_var {
1555 PortAddrunsigned short iop_base;
1556 ushort err_code;
1557 ushort dvc_cntl;
1558 ushort bug_fix_cntl;
1559 ushort bus_type;
1560 Ptr2Funculong isr_callback;
1561 Ptr2Funculong exe_callback;
1562 ASC_SCSI_BIT_ID_TYPEuchar init_sdtr;
1563 ASC_SCSI_BIT_ID_TYPEuchar sdtr_done;
1564 ASC_SCSI_BIT_ID_TYPEuchar use_tagged_qng;
1565 ASC_SCSI_BIT_ID_TYPEuchar unit_not_ready;
1566 ASC_SCSI_BIT_ID_TYPEuchar queue_full_or_busy;
1567 ASC_SCSI_BIT_ID_TYPEuchar start_motor;
1568 uchar scsi_reset_wait;
1569 uchar chip_no;
1570 char is_in_int;
1571 uchar max_total_qng;
1572 uchar cur_total_qng;
1573 uchar in_critical_cnt;
1574 uchar irq_no;
1575 uchar last_q_shortage;
1576 ushort init_state;
1577 uchar cur_dvc_qng[ASC_MAX_TID7 + 1];
1578 uchar max_dvc_qng[ASC_MAX_TID7 + 1];
1579 ASC_SCSI_Q *scsiq_busy_head[ASC_MAX_TID7 + 1];
1580 ASC_SCSI_Q *scsiq_busy_tail[ASC_MAX_TID7 + 1];
1581 uchar sdtr_period_tbl[ASC_MAX_SYN_XFER_NO16];
1582 ASC_DVC_CFG *cfg;
1583 Ptr2Funculong saved_ptr2func;
1584 ASC_SCSI_BIT_ID_TYPEuchar pci_fix_asyn_xfer_always;
1585 char redo_scam;
1586 ushort res2;
1587 uchar dos_int13_table[ASC_MAX_TID7 + 1];
1588 ulong max_dma_count;
1589 ASC_SCSI_BIT_ID_TYPEuchar no_scam;
1590 ASC_SCSI_BIT_ID_TYPEuchar pci_fix_asyn_xfer;
1591 uchar max_sdtr_index;
1592 uchar host_init_sdtr_index;
1593 ulong drv_ptr;
1594 ulong uc_break;
1595 ulong res7;
1596 ulong res8;
1597} ASC_DVC_VAR;
1598
1599typedef int (* ASC_ISR_CALLBACK) (ASC_DVC_VAR asc_ptr_type *, ASC_QDONE_INFO *);
1600typedef int (* ASC_EXE_CALLBACK) (ASC_DVC_VAR asc_ptr_type *, ASC_SCSI_Q *);
1601
1602typedef struct asc_dvc_inq_info {
1603 uchar type[ASC_MAX_TID7 + 1][ASC_MAX_LUN7 + 1];
1604} ASC_DVC_INQ_INFO;
1605
1606typedef struct asc_cap_info {
1607 ulong lba;
1608 ulong blk_size;
1609} ASC_CAP_INFO;
1610
1611typedef struct asc_cap_info_array {
1612 ASC_CAP_INFO cap_info[ASC_MAX_TID7 + 1][ASC_MAX_LUN7 + 1];
1613} ASC_CAP_INFO_ARRAY;
1614
1615#define ASC_MCNTL_NO_SEL_TIMEOUT(ushort)0x0001 (ushort)0x0001
1616#define ASC_MCNTL_NULL_TARGET(ushort)0x0002 (ushort)0x0002
1617#define ASC_CNTL_INITIATOR(ushort)0x0001 (ushort)0x0001
1618#define ASC_CNTL_BIOS_GT_1GB(ushort)0x0002 (ushort)0x0002
1619#define ASC_CNTL_BIOS_GT_2_DISK(ushort)0x0004 (ushort)0x0004
1620#define ASC_CNTL_BIOS_REMOVABLE(ushort)0x0008 (ushort)0x0008
1621#define ASC_CNTL_NO_SCAM(ushort)0x0010 (ushort)0x0010
1622#define ASC_CNTL_INT_MULTI_Q(ushort)0x0080 (ushort)0x0080
1623#define ASC_CNTL_NO_LUN_SUPPORT(ushort)0x0040 (ushort)0x0040
1624#define ASC_CNTL_NO_VERIFY_COPY(ushort)0x0100 (ushort)0x0100
1625#define ASC_CNTL_RESET_SCSI(ushort)0x0200 (ushort)0x0200
1626#define ASC_CNTL_INIT_INQUIRY(ushort)0x0400 (ushort)0x0400
1627#define ASC_CNTL_INIT_VERBOSE(ushort)0x0800 (ushort)0x0800
1628#define ASC_CNTL_SCSI_PARITY(ushort)0x1000 (ushort)0x1000
1629#define ASC_CNTL_BURST_MODE(ushort)0x2000 (ushort)0x2000
1630#define ASC_CNTL_SDTR_ENABLE_ULTRA(ushort)0x4000 (ushort)0x4000
1631#define ASC_EEP_DVC_CFG_BEG_VL2 2
1632#define ASC_EEP_MAX_DVC_ADDR_VL15 15
1633#define ASC_EEP_DVC_CFG_BEG32 32
1634#define ASC_EEP_MAX_DVC_ADDR45 45
1635#define ASC_EEP_DEFINED_WORDS10 10
1636#define ASC_EEP_MAX_ADDR63 63
1637#define ASC_EEP_RES_WORDS0 0
1638#define ASC_EEP_MAX_RETRY20 20
1639#define ASC_MAX_INIT_BUSY_RETRY8 8
1640#define ASC_EEP_ISA_PNP_WSIZE16 16
1641
1642typedef struct asceep_config {
1643 ushort cfg_lsw;
1644 ushort cfg_msw;
1645 uchar init_sdtr;
1646 uchar disc_enable;
1647 uchar use_cmd_qng;
1648 uchar start_motor;
1649 uchar max_total_qng;
1650 uchar max_tag_qng;
1651 uchar bios_scan;
1652 uchar power_up_wait;
1653 uchar no_scam;
1654 uchar chip_scsi_id:4;
1655 uchar isa_dma_speed:4;
1656 uchar dos_int13_table[ASC_MAX_TID7 + 1];
1657 uchar adapter_info[6];
1658 ushort cntl;
1659 ushort chksum;
1660} ASCEEP_CONFIG;
1661
1662#define ASC_PCI_CFG_LSW_SCSI_PARITY0x0800 0x0800
1663#define ASC_PCI_CFG_LSW_BURST_MODE0x0080 0x0080
1664#define ASC_PCI_CFG_LSW_INTR_ABLE0x0020 0x0020
1665
1666#define ASC_EEP_CMD_READ0x80 0x80
1667#define ASC_EEP_CMD_WRITE0x40 0x40
1668#define ASC_EEP_CMD_WRITE_ABLE0x30 0x30
1669#define ASC_EEP_CMD_WRITE_DISABLE0x00 0x00
1670#define ASC_OVERRUN_BSIZE0x00000048UL 0x00000048UL
1671#define ASC_CTRL_BREAK_ONCE0x0001 0x0001
1672#define ASC_CTRL_BREAK_STAY_IDLE0x0002 0x0002
1673#define ASCV_MSGOUT_BEG0x0000 0x0000
1674#define ASCV_MSGOUT_SDTR_PERIOD(0x0000 +3) (ASCV_MSGOUT_BEG0x0000+3)
1675#define ASCV_MSGOUT_SDTR_OFFSET(0x0000 +4) (ASCV_MSGOUT_BEG0x0000+4)
1676#define ASCV_BREAK_SAVED_CODE(ushort)0x0006 (ushort)0x0006
1677#define ASCV_MSGIN_BEG(0x0000 +8) (ASCV_MSGOUT_BEG0x0000+8)
1678#define ASCV_MSGIN_SDTR_PERIOD((0x0000 +8)+3) (ASCV_MSGIN_BEG(0x0000 +8)+3)
1679#define ASCV_MSGIN_SDTR_OFFSET((0x0000 +8)+4) (ASCV_MSGIN_BEG(0x0000 +8)+4)
1680#define ASCV_SDTR_DATA_BEG((0x0000 +8)+8) (ASCV_MSGIN_BEG(0x0000 +8)+8)
1681#define ASCV_SDTR_DONE_BEG(((0x0000 +8)+8)+8) (ASCV_SDTR_DATA_BEG((0x0000 +8)+8)+8)
1682#define ASCV_MAX_DVC_QNG_BEG(ushort)0x0020 (ushort)0x0020
1683#define ASCV_BREAK_ADDR(ushort)0x0028 (ushort)0x0028
1684#define ASCV_BREAK_NOTIFY_COUNT(ushort)0x002A (ushort)0x002A
1685#define ASCV_BREAK_CONTROL(ushort)0x002C (ushort)0x002C
1686#define ASCV_BREAK_HIT_COUNT(ushort)0x002E (ushort)0x002E
1687
1688#define ASCV_ASCDVC_ERR_CODE_W(ushort)0x0030 (ushort)0x0030
1689#define ASCV_MCODE_CHKSUM_W(ushort)0x0032 (ushort)0x0032
1690#define ASCV_MCODE_SIZE_W(ushort)0x0034 (ushort)0x0034
1691#define ASCV_STOP_CODE_B(ushort)0x0036 (ushort)0x0036
1692#define ASCV_DVC_ERR_CODE_B(ushort)0x0037 (ushort)0x0037
1693#define ASCV_OVERRUN_PADDR_D(ushort)0x0038 (ushort)0x0038
1694#define ASCV_OVERRUN_BSIZE_D(ushort)0x003C (ushort)0x003C
1695#define ASCV_HALTCODE_W(ushort)0x0040 (ushort)0x0040
1696#define ASCV_CHKSUM_W(ushort)0x0042 (ushort)0x0042
1697#define ASCV_MC_DATE_W(ushort)0x0044 (ushort)0x0044
1698#define ASCV_MC_VER_W(ushort)0x0046 (ushort)0x0046
1699#define ASCV_NEXTRDY_B(ushort)0x0048 (ushort)0x0048
1700#define ASCV_DONENEXT_B(ushort)0x0049 (ushort)0x0049
1701#define ASCV_USE_TAGGED_QNG_B(ushort)0x004A (ushort)0x004A
1702#define ASCV_SCSIBUSY_B(ushort)0x004B (ushort)0x004B
1703#define ASCV_Q_DONE_IN_PROGRESS_B(ushort)0x004C (ushort)0x004C
1704#define ASCV_CURCDB_B(ushort)0x004D (ushort)0x004D
1705#define ASCV_RCLUN_B(ushort)0x004E (ushort)0x004E
1706#define ASCV_BUSY_QHEAD_B(ushort)0x004F (ushort)0x004F
1707#define ASCV_DISC1_QHEAD_B(ushort)0x0050 (ushort)0x0050
1708#define ASCV_DISC_ENABLE_B(ushort)0x0052 (ushort)0x0052
1709#define ASCV_CAN_TAGGED_QNG_B(ushort)0x0053 (ushort)0x0053
1710#define ASCV_HOSTSCSI_ID_B(ushort)0x0055 (ushort)0x0055
1711#define ASCV_MCODE_CNTL_B(ushort)0x0056 (ushort)0x0056
1712#define ASCV_NULL_TARGET_B(ushort)0x0057 (ushort)0x0057
1713#define ASCV_FREE_Q_HEAD_W(ushort)0x0058 (ushort)0x0058
1714#define ASCV_DONE_Q_TAIL_W(ushort)0x005A (ushort)0x005A
1715#define ASCV_FREE_Q_HEAD_B(ushort)((ushort)0x0058 +1) (ushort)(ASCV_FREE_Q_HEAD_W(ushort)0x0058+1)
1716#define ASCV_DONE_Q_TAIL_B(ushort)((ushort)0x005A +1) (ushort)(ASCV_DONE_Q_TAIL_W(ushort)0x005A+1)
1717#define ASCV_HOST_FLAG_B(ushort)0x005D (ushort)0x005D
1718#define ASCV_TOTAL_READY_Q_B(ushort)0x0064 (ushort)0x0064
1719#define ASCV_VER_SERIAL_B(ushort)0x0065 (ushort)0x0065
1720#define ASCV_HALTCODE_SAVED_W(ushort)0x0066 (ushort)0x0066
1721#define ASCV_WTM_FLAG_B(ushort)0x0068 (ushort)0x0068
1722#define ASCV_RISC_FLAG_B(ushort)0x006A (ushort)0x006A
1723#define ASCV_REQ_SG_LIST_QP(ushort)0x006B (ushort)0x006B
1724#define ASC_HOST_FLAG_IN_ISR0x01 0x01
1725#define ASC_HOST_FLAG_ACK_INT0x02 0x02
1726#define ASC_RISC_FLAG_GEN_INT0x01 0x01
1727#define ASC_RISC_FLAG_REQ_SG_LIST0x02 0x02
1728#define IOP_CTRL(0x0F) (0x0F)
1729#define IOP_STATUS(0x0E) (0x0E)
1730#define IOP_INT_ACK(0x0E) IOP_STATUS(0x0E)
1731#define IOP_REG_IFC(0x0D) (0x0D)
1732#define IOP_SYN_OFFSET(0x0B) (0x0B)
1733#define IOP_EXTRA_CONTROL(0x0D) (0x0D)
1734#define IOP_REG_PC(0x0C) (0x0C)
1735#define IOP_RAM_ADDR(0x0A) (0x0A)
1736#define IOP_RAM_DATA(0x08) (0x08)
1737#define IOP_EEP_DATA(0x06) (0x06)
1738#define IOP_EEP_CMD(0x07) (0x07)
1739#define IOP_VERSION(0x03) (0x03)
1740#define IOP_CONFIG_HIGH(0x04) (0x04)
1741#define IOP_CONFIG_LOW(0x02) (0x02)
1742#define IOP_SIG_BYTE(0x01) (0x01)
1743#define IOP_SIG_WORD(0x00) (0x00)
1744#define IOP_REG_DC1(0x0E) (0x0E)
1745#define IOP_REG_DC0(0x0C) (0x0C)
1746#define IOP_REG_SB(0x0B) (0x0B)
1747#define IOP_REG_DA1(0x0A) (0x0A)
1748#define IOP_REG_DA0(0x08) (0x08)
1749#define IOP_REG_SC(0x09) (0x09)
1750#define IOP_DMA_SPEED(0x07) (0x07)
1751#define IOP_REG_FLAG(0x07) (0x07)
1752#define IOP_FIFO_H(0x06) (0x06)
1753#define IOP_FIFO_L(0x04) (0x04)
1754#define IOP_REG_ID(0x05) (0x05)
1755#define IOP_REG_QP(0x03) (0x03)
1756#define IOP_REG_IH(0x02) (0x02)
1757#define IOP_REG_IX(0x01) (0x01)
1758#define IOP_REG_AX(0x00) (0x00)
1759#define IFC_REG_LOCK(0x00) (0x00)
1760#define IFC_REG_UNLOCK(0x09) (0x09)
1761#define IFC_WR_EN_FILTER(0x10) (0x10)
1762#define IFC_RD_NO_EEPROM(0x10) (0x10)
1763#define IFC_SLEW_RATE(0x20) (0x20)
1764#define IFC_ACT_NEG(0x40) (0x40)
1765#define IFC_INP_FILTER(0x80) (0x80)
1766#define IFC_INIT_DEFAULT((0x40) | (0x09)) (IFC_ACT_NEG(0x40) | IFC_REG_UNLOCK(0x09))
1767#define SC_SEL(uchar)(0x80) (uchar)(0x80)
1768#define SC_BSY(uchar)(0x40) (uchar)(0x40)
1769#define SC_ACK(uchar)(0x20) (uchar)(0x20)
1770#define SC_REQ(uchar)(0x10) (uchar)(0x10)
1771#define SC_ATN(uchar)(0x08) (uchar)(0x08)
1772#define SC_IO(uchar)(0x04) (uchar)(0x04)
1773#define SC_CD(uchar)(0x02) (uchar)(0x02)
1774#define SC_MSG(uchar)(0x01) (uchar)(0x01)
1775#define SEC_SCSI_CTL(uchar)(0x80) (uchar)(0x80)
1776#define SEC_ACTIVE_NEGATE(uchar)(0x40) (uchar)(0x40)
1777#define SEC_SLEW_RATE(uchar)(0x20) (uchar)(0x20)
1778#define SEC_ENABLE_FILTER(uchar)(0x10) (uchar)(0x10)
1779#define ASC_HALT_EXTMSG_IN(ushort)0x8000 (ushort)0x8000
1780#define ASC_HALT_CHK_CONDITION(ushort)0x8100 (ushort)0x8100
1781#define ASC_HALT_SS_QUEUE_FULL(ushort)0x8200 (ushort)0x8200
1782#define ASC_HALT_DISABLE_ASYN_USE_SYN_FIX(ushort)0x8300 (ushort)0x8300
1783#define ASC_HALT_ENABLE_ASYN_USE_SYN_FIX(ushort)0x8400 (ushort)0x8400
1784#define ASC_HALT_SDTR_REJECTED(ushort)0x4000 (ushort)0x4000
1785#define ASC_MAX_QNO0xF8 0xF8
1786#define ASC_DATA_SEC_BEG(ushort)0x0080 (ushort)0x0080
1787#define ASC_DATA_SEC_END(ushort)0x0080 (ushort)0x0080
1788#define ASC_CODE_SEC_BEG(ushort)0x0080 (ushort)0x0080
1789#define ASC_CODE_SEC_END(ushort)0x0080 (ushort)0x0080
1790#define ASC_QADR_BEG(0x4000) (0x4000)
1791#define ASC_QADR_USED(ushort)(0xF8 * 64) (ushort)(ASC_MAX_QNO0xF8 * 64)
1792#define ASC_QADR_END(ushort)0x7FFF (ushort)0x7FFF
1793#define ASC_QLAST_ADR(ushort)0x7FC0 (ushort)0x7FC0
1794#define ASC_QBLK_SIZE0x40 0x40
1795#define ASC_BIOS_DATA_QBEG0xF8 0xF8
1796#define ASC_MIN_ACTIVE_QNO0x01 0x01
1797#define ASC_QLINK_END0xFF 0xFF
1798#define ASC_EEPROM_WORDS0x10 0x10
1799#define ASC_MAX_MGS_LEN0x10 0x10
1800#define ASC_BIOS_ADDR_DEF0xDC00 0xDC00
1801#define ASC_BIOS_SIZE0x3800 0x3800
1802#define ASC_BIOS_RAM_OFF0x3800 0x3800
1803#define ASC_BIOS_RAM_SIZE0x800 0x800
1804#define ASC_BIOS_MIN_ADDR0xC000 0xC000
1805#define ASC_BIOS_MAX_ADDR0xEC00 0xEC00
1806#define ASC_BIOS_BANK_SIZE0x0400 0x0400
1807#define ASC_MCODE_START_ADDR0x0080 0x0080
1808#define ASC_CFG0_HOST_INT_ON0x0020 0x0020
1809#define ASC_CFG0_BIOS_ON0x0040 0x0040
1810#define ASC_CFG0_VERA_BURST_ON0x0080 0x0080
1811#define ASC_CFG0_SCSI_PARITY_ON0x0800 0x0800
1812#define ASC_CFG1_SCSI_TARGET_ON0x0080 0x0080
1813#define ASC_CFG1_LRAM_8BITS_ON0x0800 0x0800
1814#define ASC_CFG_MSW_CLR_MASK0x3080 0x3080
1815#define CSW_TEST1(unsigned short)0x8000 (ASC_CS_TYPEunsigned short)0x8000
1816#define CSW_AUTO_CONFIG(unsigned short)0x4000 (ASC_CS_TYPEunsigned short)0x4000
1817#define CSW_RESERVED1(unsigned short)0x2000 (ASC_CS_TYPEunsigned short)0x2000
1818#define CSW_IRQ_WRITTEN(unsigned short)0x1000 (ASC_CS_TYPEunsigned short)0x1000
1819#define CSW_33MHZ_SELECTED(unsigned short)0x0800 (ASC_CS_TYPEunsigned short)0x0800
1820#define CSW_TEST2(unsigned short)0x0400 (ASC_CS_TYPEunsigned short)0x0400
1821#define CSW_TEST3(unsigned short)0x0200 (ASC_CS_TYPEunsigned short)0x0200
1822#define CSW_RESERVED2(unsigned short)0x0100 (ASC_CS_TYPEunsigned short)0x0100
1823#define CSW_DMA_DONE(unsigned short)0x0080 (ASC_CS_TYPEunsigned short)0x0080
1824#define CSW_FIFO_RDY(unsigned short)0x0040 (ASC_CS_TYPEunsigned short)0x0040
1825#define CSW_EEP_READ_DONE(unsigned short)0x0020 (ASC_CS_TYPEunsigned short)0x0020
1826#define CSW_HALTED(unsigned short)0x0010 (ASC_CS_TYPEunsigned short)0x0010
1827#define CSW_SCSI_RESET_ACTIVE(unsigned short)0x0008 (ASC_CS_TYPEunsigned short)0x0008
1828#define CSW_PARITY_ERR(unsigned short)0x0004 (ASC_CS_TYPEunsigned short)0x0004
1829#define CSW_SCSI_RESET_LATCH(unsigned short)0x0002 (ASC_CS_TYPEunsigned short)0x0002
1830#define CSW_INT_PENDING(unsigned short)0x0001 (ASC_CS_TYPEunsigned short)0x0001
1831#define CIW_CLR_SCSI_RESET_INT(unsigned short)0x1000 (ASC_CS_TYPEunsigned short)0x1000
1832#define CIW_INT_ACK(unsigned short)0x0100 (ASC_CS_TYPEunsigned short)0x0100
1833#define CIW_TEST1(unsigned short)0x0200 (ASC_CS_TYPEunsigned short)0x0200
1834#define CIW_TEST2(unsigned short)0x0400 (ASC_CS_TYPEunsigned short)0x0400
1835#define CIW_SEL_33MHZ(unsigned short)0x0800 (ASC_CS_TYPEunsigned short)0x0800
1836#define CIW_IRQ_ACT(unsigned short)0x1000 (ASC_CS_TYPEunsigned short)0x1000
1837#define CC_CHIP_RESET(uchar)0x80 (uchar)0x80
1838#define CC_SCSI_RESET(uchar)0x40 (uchar)0x40
1839#define CC_HALT(uchar)0x20 (uchar)0x20
1840#define CC_SINGLE_STEP(uchar)0x10 (uchar)0x10
1841#define CC_DMA_ABLE(uchar)0x08 (uchar)0x08
1842#define CC_TEST(uchar)0x04 (uchar)0x04
1843#define CC_BANK_ONE(uchar)0x02 (uchar)0x02
1844#define CC_DIAG(uchar)0x01 (uchar)0x01
1845#define ASC_1000_ID0W0x04C1 0x04C1
1846#define ASC_1000_ID0W_FIX0x00C1 0x00C1
1847#define ASC_1000_ID1B0x25 0x25
1848#define ASC_EISA_BIG_IOP_GAP(0x1C30 -0x0C50) (0x1C30-0x0C50)
1849#define ASC_EISA_SMALL_IOP_GAP(0x0020) (0x0020)
1850#define ASC_EISA_MIN_IOP_ADDR(0x0C30) (0x0C30)
1851#define ASC_EISA_MAX_IOP_ADDR(0xFC50) (0xFC50)
1852#define ASC_EISA_REV_IOP_MASK(0x0C83) (0x0C83)
1853#define ASC_EISA_PID_IOP_MASK(0x0C80) (0x0C80)
1854#define ASC_EISA_CFG_IOP_MASK(0x0C86) (0x0C86)
1855#define ASC_GET_EISA_SLOT(iop)(unsigned short)((iop) & 0xF000) (PortAddrunsigned short)((iop) & 0xF000)
1856#define ASC_EISA_ID_7400x01745004UL 0x01745004UL
1857#define ASC_EISA_ID_7500x01755004UL 0x01755004UL
1858#define INS_HALTINT(ushort)0x6281 (ushort)0x6281
1859#define INS_HALT(ushort)0x6280 (ushort)0x6280
1860#define INS_SINT(ushort)0x6200 (ushort)0x6200
1861#define INS_RFLAG_WTM(ushort)0x7380 (ushort)0x7380
1862#define ASC_MC_SAVE_CODE_WSIZE0x500 0x500
1863#define ASC_MC_SAVE_DATA_WSIZE0x40 0x40
1864
1865typedef struct asc_mc_saved {
1866 ushort data[ASC_MC_SAVE_DATA_WSIZE0x40];
1867 ushort code[ASC_MC_SAVE_CODE_WSIZE0x500];
1868} ASC_MC_SAVED;
1869
1870#define AscGetQDoneInProgress(port)AscReadLramByte((port), (ushort)0x004C) AscReadLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B(ushort)0x004C)
1871#define AscPutQDoneInProgress(port, val)AscWriteLramByte((port), (ushort)0x004C, val) AscWriteLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B(ushort)0x004C, val)
1872#define AscGetVarFreeQHead(port)AscReadLramWord((port), (ushort)0x0058) AscReadLramWord((port), ASCV_FREE_Q_HEAD_W(ushort)0x0058)
1873#define AscGetVarDoneQTail(port)AscReadLramWord((port), (ushort)0x005A) AscReadLramWord((port), ASCV_DONE_Q_TAIL_W(ushort)0x005A)
1874#define AscPutVarFreeQHead(port, val)AscWriteLramWord((port), (ushort)0x0058, val) AscWriteLramWord((port), ASCV_FREE_Q_HEAD_W(ushort)0x0058, val)
1875#define AscPutVarDoneQTail(port, val)AscWriteLramWord((port), (ushort)0x005A, val) AscWriteLramWord((port), ASCV_DONE_Q_TAIL_W(ushort)0x005A, val)
1876#define AscGetRiscVarFreeQHead(port)AscReadLramByte((port), (ushort)0x0048) AscReadLramByte((port), ASCV_NEXTRDY_B(ushort)0x0048)
1877#define AscGetRiscVarDoneQTail(port)AscReadLramByte((port), (ushort)0x0049) AscReadLramByte((port), ASCV_DONENEXT_B(ushort)0x0049)
1878#define AscPutRiscVarFreeQHead(port, val)AscWriteLramByte((port), (ushort)0x0048, val) AscWriteLramByte((port), ASCV_NEXTRDY_B(ushort)0x0048, val)
1879#define AscPutRiscVarDoneQTail(port, val)AscWriteLramByte((port), (ushort)0x0049, val) AscWriteLramByte((port), ASCV_DONENEXT_B(ushort)0x0049, val)
1880#define AscPutMCodeSDTRDoneAtID(port, id, data)AscWriteLramByte((port), (ushort)((ushort)(((0x0000 +8)+8)+8)
+(ushort)id), (data)) ;
AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG(((0x0000 +8)+8)+8)+(ushort)id), (data)) ;
1881#define AscGetMCodeSDTRDoneAtID(port, id)AscReadLramByte((port), (ushort)((ushort)(((0x0000 +8)+8)+8)+
(ushort)id)) ;
AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG(((0x0000 +8)+8)+8)+(ushort)id)) ;
1882#define AscPutMCodeInitSDTRAtID(port, id, data)AscWriteLramByte((port), (ushort)((ushort)((0x0000 +8)+8)+(ushort
)id), data) ;
AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG((0x0000 +8)+8)+(ushort)id), data) ;
1883#define AscGetMCodeInitSDTRAtID(port, id)AscReadLramByte((port), (ushort)((ushort)((0x0000 +8)+8)+(ushort
)id)) ;
AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG((0x0000 +8)+8)+(ushort)id)) ;
1884#define AscSynIndexToPeriod(index)(uchar)(asc_dvc->sdtr_period_tbl[ (index) ]) (uchar)(asc_dvc->sdtr_period_tbl[ (index) ])
1885#define AscGetChipSignatureByte(port)(uchar)((__builtin_constant_p(((port)+(0x01))) && ((port
)+(0x01)) < 256) ? __inbc((port)+(0x01)) : __inb((port)+(0x01
)))
(uchar)inp((port)+IOP_SIG_BYTE)((__builtin_constant_p(((port)+(0x01))) && ((port)+(0x01
)) < 256) ? __inbc((port)+(0x01)) : __inb((port)+(0x01)))
1886#define AscGetChipSignatureWord(port)(ushort)((__builtin_constant_p(((port)+(0x00))) && ((
port)+(0x00)) < 256) ? __inwc((port)+(0x00)) : __inw((port
)+(0x00)))
(ushort)inpw((port)+IOP_SIG_WORD)((__builtin_constant_p(((port)+(0x00))) && ((port)+(0x00
)) < 256) ? __inwc((port)+(0x00)) : __inw((port)+(0x00)))
1887#define AscGetChipVerNo(port)(uchar)((__builtin_constant_p(((port)+(0x03))) && ((port
)+(0x03)) < 256) ? __inbc((port)+(0x03)) : __inb((port)+(0x03
)))
(uchar)inp((port)+IOP_VERSION)((__builtin_constant_p(((port)+(0x03))) && ((port)+(0x03
)) < 256) ? __inbc((port)+(0x03)) : __inb((port)+(0x03)))
1888#define AscGetChipCfgLsw(port)(ushort)((__builtin_constant_p(((port)+(0x02))) && ((
port)+(0x02)) < 256) ? __inwc((port)+(0x02)) : __inw((port
)+(0x02)))
(ushort)inpw((port)+IOP_CONFIG_LOW)((__builtin_constant_p(((port)+(0x02))) && ((port)+(0x02
)) < 256) ? __inwc((port)+(0x02)) : __inw((port)+(0x02)))
1889#define AscGetChipCfgMsw(port)(ushort)((__builtin_constant_p(((port)+(0x04))) && ((
port)+(0x04)) < 256) ? __inwc((port)+(0x04)) : __inw((port
)+(0x04)))
(ushort)inpw((port)+IOP_CONFIG_HIGH)((__builtin_constant_p(((port)+(0x04))) && ((port)+(0x04
)) < 256) ? __inwc((port)+(0x04)) : __inw((port)+(0x04)))
1890#define AscSetChipCfgLsw(port, data)((__builtin_constant_p((((port)+(0x02)))) && (((port)
+(0x02))) < 256) ? __outwc(((data)),(((port)+(0x02)))) : __outw
(((data)),(((port)+(0x02)))))
outpw((port)+IOP_CONFIG_LOW, data)((__builtin_constant_p((((port)+(0x02)))) && (((port)
+(0x02))) < 256) ? __outwc(((data)),(((port)+(0x02)))) : __outw
(((data)),(((port)+(0x02)))))
1891#define AscSetChipCfgMsw(port, data)((__builtin_constant_p((((port)+(0x04)))) && (((port)
+(0x04))) < 256) ? __outwc(((data)),(((port)+(0x04)))) : __outw
(((data)),(((port)+(0x04)))))
outpw((port)+IOP_CONFIG_HIGH, data)((__builtin_constant_p((((port)+(0x04)))) && (((port)
+(0x04))) < 256) ? __outwc(((data)),(((port)+(0x04)))) : __outw
(((data)),(((port)+(0x04)))))
1892#define AscGetChipEEPCmd(port)(uchar)((__builtin_constant_p(((port)+(0x07))) && ((port
)+(0x07)) < 256) ? __inbc((port)+(0x07)) : __inb((port)+(0x07
)))
(uchar)inp((port)+IOP_EEP_CMD)((__builtin_constant_p(((port)+(0x07))) && ((port)+(0x07
)) < 256) ? __inbc((port)+(0x07)) : __inb((port)+(0x07)))
1893#define AscSetChipEEPCmd(port, data)((__builtin_constant_p((((port)+(0x07)))) && (((port)
+(0x07))) < 256) ? __outbc(((data)),(((port)+(0x07)))) : __outb
(((data)),(((port)+(0x07)))))
outp((port)+IOP_EEP_CMD, data)((__builtin_constant_p((((port)+(0x07)))) && (((port)
+(0x07))) < 256) ? __outbc(((data)),(((port)+(0x07)))) : __outb
(((data)),(((port)+(0x07)))))
1894#define AscGetChipEEPData(port)(ushort)((__builtin_constant_p(((port)+(0x06))) && ((
port)+(0x06)) < 256) ? __inwc((port)+(0x06)) : __inw((port
)+(0x06)))
(ushort)inpw((port)+IOP_EEP_DATA)((__builtin_constant_p(((port)+(0x06))) && ((port)+(0x06
)) < 256) ? __inwc((port)+(0x06)) : __inw((port)+(0x06)))
1895#define AscSetChipEEPData(port, data)((__builtin_constant_p((((port)+(0x06)))) && (((port)
+(0x06))) < 256) ? __outwc(((data)),(((port)+(0x06)))) : __outw
(((data)),(((port)+(0x06)))))
outpw((port)+IOP_EEP_DATA, data)((__builtin_constant_p((((port)+(0x06)))) && (((port)
+(0x06))) < 256) ? __outwc(((data)),(((port)+(0x06)))) : __outw
(((data)),(((port)+(0x06)))))
1896#define AscGetChipLramAddr(port)(ushort)((__builtin_constant_p(((unsigned short)((port)+(0x0A
)))) && ((unsigned short)((port)+(0x0A))) < 256) ?
__inwc((unsigned short)((port)+(0x0A))) : __inw((unsigned short
)((port)+(0x0A))))
(ushort)inpw((PortAddr)((port)+IOP_RAM_ADDR))((__builtin_constant_p(((unsigned short)((port)+(0x0A)))) &&
((unsigned short)((port)+(0x0A))) < 256) ? __inwc((unsigned
short)((port)+(0x0A))) : __inw((unsigned short)((port)+(0x0A
))))
1897#define AscSetChipLramAddr(port, addr)((__builtin_constant_p((((unsigned short)((port)+(0x0A))))) &&
(((unsigned short)((port)+(0x0A)))) < 256) ? __outwc(((addr
)),(((unsigned short)((port)+(0x0A))))) : __outw(((addr)),(((
unsigned short)((port)+(0x0A))))))
outpw((PortAddr)((port)+IOP_RAM_ADDR), addr)((__builtin_constant_p((((unsigned short)((port)+(0x0A))))) &&
(((unsigned short)((port)+(0x0A)))) < 256) ? __outwc(((addr
)),(((unsigned short)((port)+(0x0A))))) : __outw(((addr)),(((
unsigned short)((port)+(0x0A))))))
1898#define AscGetChipLramData(port)(ushort)((__builtin_constant_p(((port)+(0x08))) && ((
port)+(0x08)) < 256) ? __inwc((port)+(0x08)) : __inw((port
)+(0x08)))
(ushort)inpw((port)+IOP_RAM_DATA)((__builtin_constant_p(((port)+(0x08))) && ((port)+(0x08
)) < 256) ? __inwc((port)+(0x08)) : __inw((port)+(0x08)))
1899#define AscSetChipLramData(port, data)((__builtin_constant_p((((port)+(0x08)))) && (((port)
+(0x08))) < 256) ? __outwc(((data)),(((port)+(0x08)))) : __outw
(((data)),(((port)+(0x08)))))
outpw((port)+IOP_RAM_DATA, data)((__builtin_constant_p((((port)+(0x08)))) && (((port)
+(0x08))) < 256) ? __outwc(((data)),(((port)+(0x08)))) : __outw
(((data)),(((port)+(0x08)))))
1900#define AscGetChipLramDataNoSwap(port)(ushort)((__builtin_constant_p(((port)+(0x08))) && ((
port)+(0x08)) < 256) ? __inwc((port)+(0x08)) : __inw((port
)+(0x08)))
(ushort)inpw_noswap((port)+IOP_RAM_DATA)((__builtin_constant_p(((port)+(0x08))) && ((port)+(0x08
)) < 256) ? __inwc((port)+(0x08)) : __inw((port)+(0x08)))
1901#define AscSetChipLramDataNoSwap(port, data)((__builtin_constant_p((((port)+(0x08)))) && (((port)
+(0x08))) < 256) ? __outwc(((data)),(((port)+(0x08)))) : __outw
(((data)),(((port)+(0x08)))))
outpw_noswap((port)+IOP_RAM_DATA, data)((__builtin_constant_p((((port)+(0x08)))) && (((port)
+(0x08))) < 256) ? __outwc(((data)),(((port)+(0x08)))) : __outw
(((data)),(((port)+(0x08)))))
1902#define AscGetChipIFC(port)(uchar)((__builtin_constant_p(((port)+(0x0D))) && ((port
)+(0x0D)) < 256) ? __inbc((port)+(0x0D)) : __inb((port)+(0x0D
)))
(uchar)inp((port)+IOP_REG_IFC)((__builtin_constant_p(((port)+(0x0D))) && ((port)+(0x0D
)) < 256) ? __inbc((port)+(0x0D)) : __inb((port)+(0x0D)))
1903#define AscSetChipIFC(port, data)((__builtin_constant_p((((port)+(0x0D)))) && (((port)
+(0x0D))) < 256) ? __outbc(((data)),(((port)+(0x0D)))) : __outb
(((data)),(((port)+(0x0D)))))
outp((port)+IOP_REG_IFC, data)((__builtin_constant_p((((port)+(0x0D)))) && (((port)
+(0x0D))) < 256) ? __outbc(((data)),(((port)+(0x0D)))) : __outb
(((data)),(((port)+(0x0D)))))
1904#define AscGetChipStatus(port)(unsigned short)((__builtin_constant_p(((port)+(0x0E))) &&
((port)+(0x0E)) < 256) ? __inwc((port)+(0x0E)) : __inw((port
)+(0x0E)))
(ASC_CS_TYPEunsigned short)inpw((port)+IOP_STATUS)((__builtin_constant_p(((port)+(0x0E))) && ((port)+(0x0E
)) < 256) ? __inwc((port)+(0x0E)) : __inw((port)+(0x0E)))
1905#define AscSetChipStatus(port, cs_val)((__builtin_constant_p((((port)+(0x0E)))) && (((port)
+(0x0E))) < 256) ? __outwc(((cs_val)),(((port)+(0x0E)))) :
__outw(((cs_val)),(((port)+(0x0E)))))
outpw((port)+IOP_STATUS, cs_val)((__builtin_constant_p((((port)+(0x0E)))) && (((port)
+(0x0E))) < 256) ? __outwc(((cs_val)),(((port)+(0x0E)))) :
__outw(((cs_val)),(((port)+(0x0E)))))
1906#define AscGetChipControl(port)(uchar)((__builtin_constant_p(((port)+(0x0F))) && ((port
)+(0x0F)) < 256) ? __inbc((port)+(0x0F)) : __inb((port)+(0x0F
)))
(uchar)inp((port)+IOP_CTRL)((__builtin_constant_p(((port)+(0x0F))) && ((port)+(0x0F
)) < 256) ? __inbc((port)+(0x0F)) : __inb((port)+(0x0F)))
1907#define AscSetChipControl(port, cc_val)((__builtin_constant_p((((port)+(0x0F)))) && (((port)
+(0x0F))) < 256) ? __outbc(((cc_val)),(((port)+(0x0F)))) :
__outb(((cc_val)),(((port)+(0x0F)))))
outp((port)+IOP_CTRL, cc_val)((__builtin_constant_p((((port)+(0x0F)))) && (((port)
+(0x0F))) < 256) ? __outbc(((cc_val)),(((port)+(0x0F)))) :
__outb(((cc_val)),(((port)+(0x0F)))))
1908#define AscGetChipSyn(port)(uchar)((__builtin_constant_p(((port)+(0x0B))) && ((port
)+(0x0B)) < 256) ? __inbc((port)+(0x0B)) : __inb((port)+(0x0B
)))
(uchar)inp((port)+IOP_SYN_OFFSET)((__builtin_constant_p(((port)+(0x0B))) && ((port)+(0x0B
)) < 256) ? __inbc((port)+(0x0B)) : __inb((port)+(0x0B)))
1909#define AscSetChipSyn(port, data)((__builtin_constant_p((((port)+(0x0B)))) && (((port)
+(0x0B))) < 256) ? __outbc(((data)),(((port)+(0x0B)))) : __outb
(((data)),(((port)+(0x0B)))))
outp((port)+IOP_SYN_OFFSET, data)((__builtin_constant_p((((port)+(0x0B)))) && (((port)
+(0x0B))) < 256) ? __outbc(((data)),(((port)+(0x0B)))) : __outb
(((data)),(((port)+(0x0B)))))
1910#define AscSetPCAddr(port, data)((__builtin_constant_p((((port)+(0x0C)))) && (((port)
+(0x0C))) < 256) ? __outwc(((data)),(((port)+(0x0C)))) : __outw
(((data)),(((port)+(0x0C)))))
outpw((port)+IOP_REG_PC, data)((__builtin_constant_p((((port)+(0x0C)))) && (((port)
+(0x0C))) < 256) ? __outwc(((data)),(((port)+(0x0C)))) : __outw
(((data)),(((port)+(0x0C)))))
1911#define AscGetPCAddr(port)(ushort)((__builtin_constant_p(((port)+(0x0C))) && ((
port)+(0x0C)) < 256) ? __inwc((port)+(0x0C)) : __inw((port
)+(0x0C)))
(ushort)inpw((port)+IOP_REG_PC)((__builtin_constant_p(((port)+(0x0C))) && ((port)+(0x0C
)) < 256) ? __inwc((port)+(0x0C)) : __inw((port)+(0x0C)))
1912#define AscIsIntPending(port)((unsigned short)((__builtin_constant_p(((port)+(0x0E))) &&
((port)+(0x0E)) < 256) ? __inwc((port)+(0x0E)) : __inw((port
)+(0x0E))) & ((unsigned short)0x0001 | (unsigned short)0x0002
))
(AscGetChipStatus(port)(unsigned short)((__builtin_constant_p(((port)+(0x0E))) &&
((port)+(0x0E)) < 256) ? __inwc((port)+(0x0E)) : __inw((port
)+(0x0E)))
& (CSW_INT_PENDING(unsigned short)0x0001 | CSW_SCSI_RESET_LATCH(unsigned short)0x0002))
1913#define AscGetChipScsiID(port)(((ushort)((__builtin_constant_p(((port)+(0x02))) && (
(port)+(0x02)) < 256) ? __inwc((port)+(0x02)) : __inw((port
)+(0x02))) >> 8) & 7)
((AscGetChipCfgLsw(port)(ushort)((__builtin_constant_p(((port)+(0x02))) && ((
port)+(0x02)) < 256) ? __inwc((port)+(0x02)) : __inw((port
)+(0x02)))
>> 8) & ASC_MAX_TID7)
1914#define AscGetExtraControl(port)(uchar)((__builtin_constant_p(((port)+(0x0D))) && ((port
)+(0x0D)) < 256) ? __inbc((port)+(0x0D)) : __inb((port)+(0x0D
)))
(uchar)inp((port)+IOP_EXTRA_CONTROL)((__builtin_constant_p(((port)+(0x0D))) && ((port)+(0x0D
)) < 256) ? __inbc((port)+(0x0D)) : __inb((port)+(0x0D)))
1915#define AscSetExtraControl(port, data)((__builtin_constant_p((((port)+(0x0D)))) && (((port)
+(0x0D))) < 256) ? __outbc(((data)),(((port)+(0x0D)))) : __outb
(((data)),(((port)+(0x0D)))))
outp((port)+IOP_EXTRA_CONTROL, data)((__builtin_constant_p((((port)+(0x0D)))) && (((port)
+(0x0D))) < 256) ? __outbc(((data)),(((port)+(0x0D)))) : __outb
(((data)),(((port)+(0x0D)))))
1916#define AscReadChipAX(port)(ushort)((__builtin_constant_p(((port)+(0x00))) && ((
port)+(0x00)) < 256) ? __inwc((port)+(0x00)) : __inw((port
)+(0x00)))
(ushort)inpw((port)+IOP_REG_AX)((__builtin_constant_p(((port)+(0x00))) && ((port)+(0x00
)) < 256) ? __inwc((port)+(0x00)) : __inw((port)+(0x00)))
1917#define AscWriteChipAX(port, data)((__builtin_constant_p((((port)+(0x00)))) && (((port)
+(0x00))) < 256) ? __outwc(((data)),(((port)+(0x00)))) : __outw
(((data)),(((port)+(0x00)))))
outpw((port)+IOP_REG_AX, data)((__builtin_constant_p((((port)+(0x00)))) && (((port)
+(0x00))) < 256) ? __outwc(((data)),(((port)+(0x00)))) : __outw
(((data)),(((port)+(0x00)))))
1918#define AscReadChipIX(port)(uchar)((__builtin_constant_p(((port)+(0x01))) && ((port
)+(0x01)) < 256) ? __inbc((port)+(0x01)) : __inb((port)+(0x01
)))
(uchar)inp((port)+IOP_REG_IX)((__builtin_constant_p(((port)+(0x01))) && ((port)+(0x01
)) < 256) ? __inbc((port)+(0x01)) : __inb((port)+(0x01)))
1919#define AscWriteChipIX(port, data)((__builtin_constant_p((((port)+(0x01)))) && (((port)
+(0x01))) < 256) ? __outbc(((data)),(((port)+(0x01)))) : __outb
(((data)),(((port)+(0x01)))))
outp((port)+IOP_REG_IX, data)((__builtin_constant_p((((port)+(0x01)))) && (((port)
+(0x01))) < 256) ? __outbc(((data)),(((port)+(0x01)))) : __outb
(((data)),(((port)+(0x01)))))
1920#define AscReadChipIH(port)(ushort)((__builtin_constant_p(((port)+(0x02))) && ((
port)+(0x02)) < 256) ? __inwc((port)+(0x02)) : __inw((port
)+(0x02)))
(ushort)inpw((port)+IOP_REG_IH)((__builtin_constant_p(((port)+(0x02))) && ((port)+(0x02
)) < 256) ? __inwc((port)+(0x02)) : __inw((port)+(0x02)))
1921#define AscWriteChipIH(port, data)((__builtin_constant_p((((port)+(0x02)))) && (((port)
+(0x02))) < 256) ? __outwc(((data)),(((port)+(0x02)))) : __outw
(((data)),(((port)+(0x02)))))
outpw((port)+IOP_REG_IH, data)((__builtin_constant_p((((port)+(0x02)))) && (((port)
+(0x02))) < 256) ? __outwc(((data)),(((port)+(0x02)))) : __outw
(((data)),(((port)+(0x02)))))
1922#define AscReadChipQP(port)(uchar)((__builtin_constant_p(((port)+(0x03))) && ((port
)+(0x03)) < 256) ? __inbc((port)+(0x03)) : __inb((port)+(0x03
)))
(uchar)inp((port)+IOP_REG_QP)((__builtin_constant_p(((port)+(0x03))) && ((port)+(0x03
)) < 256) ? __inbc((port)+(0x03)) : __inb((port)+(0x03)))
1923#define AscWriteChipQP(port, data)((__builtin_constant_p((((port)+(0x03)))) && (((port)
+(0x03))) < 256) ? __outbc(((data)),(((port)+(0x03)))) : __outb
(((data)),(((port)+(0x03)))))
outp((port)+IOP_REG_QP, data)((__builtin_constant_p((((port)+(0x03)))) && (((port)
+(0x03))) < 256) ? __outbc(((data)),(((port)+(0x03)))) : __outb
(((data)),(((port)+(0x03)))))
1924#define AscReadChipFIFO_L(port)(ushort)((__builtin_constant_p(((port)+IOP_REG_FIFO_L)) &&
((port)+IOP_REG_FIFO_L) < 256) ? __inwc((port)+IOP_REG_FIFO_L
) : __inw((port)+IOP_REG_FIFO_L))
(ushort)inpw((port)+IOP_REG_FIFO_L)((__builtin_constant_p(((port)+IOP_REG_FIFO_L)) && ((
port)+IOP_REG_FIFO_L) < 256) ? __inwc((port)+IOP_REG_FIFO_L
) : __inw((port)+IOP_REG_FIFO_L))
1925#define AscWriteChipFIFO_L(port, data)((__builtin_constant_p((((port)+IOP_REG_FIFO_L))) && (
((port)+IOP_REG_FIFO_L)) < 256) ? __outwc(((data)),(((port
)+IOP_REG_FIFO_L))) : __outw(((data)),(((port)+IOP_REG_FIFO_L
))))
outpw((port)+IOP_REG_FIFO_L, data)((__builtin_constant_p((((port)+IOP_REG_FIFO_L))) && (
((port)+IOP_REG_FIFO_L)) < 256) ? __outwc(((data)),(((port
)+IOP_REG_FIFO_L))) : __outw(((data)),(((port)+IOP_REG_FIFO_L
))))
1926#define AscReadChipFIFO_H(port)(ushort)((__builtin_constant_p(((port)+IOP_REG_FIFO_H)) &&
((port)+IOP_REG_FIFO_H) < 256) ? __inwc((port)+IOP_REG_FIFO_H
) : __inw((port)+IOP_REG_FIFO_H))
(ushort)inpw((port)+IOP_REG_FIFO_H)((__builtin_constant_p(((port)+IOP_REG_FIFO_H)) && ((
port)+IOP_REG_FIFO_H) < 256) ? __inwc((port)+IOP_REG_FIFO_H
) : __inw((port)+IOP_REG_FIFO_H))
1927#define AscWriteChipFIFO_H(port, data)((__builtin_constant_p((((port)+IOP_REG_FIFO_H))) && (
((port)+IOP_REG_FIFO_H)) < 256) ? __outwc(((data)),(((port
)+IOP_REG_FIFO_H))) : __outw(((data)),(((port)+IOP_REG_FIFO_H
))))
outpw((port)+IOP_REG_FIFO_H, data)((__builtin_constant_p((((port)+IOP_REG_FIFO_H))) && (
((port)+IOP_REG_FIFO_H)) < 256) ? __outwc(((data)),(((port
)+IOP_REG_FIFO_H))) : __outw(((data)),(((port)+IOP_REG_FIFO_H
))))
1928#define AscReadChipDmaSpeed(port)(uchar)((__builtin_constant_p(((port)+(0x07))) && ((port
)+(0x07)) < 256) ? __inbc((port)+(0x07)) : __inb((port)+(0x07
)))
(uchar)inp((port)+IOP_DMA_SPEED)((__builtin_constant_p(((port)+(0x07))) && ((port)+(0x07
)) < 256) ? __inbc((port)+(0x07)) : __inb((port)+(0x07)))
1929#define AscWriteChipDmaSpeed(port, data)((__builtin_constant_p((((port)+(0x07)))) && (((port)
+(0x07))) < 256) ? __outbc(((data)),(((port)+(0x07)))) : __outb
(((data)),(((port)+(0x07)))))
outp((port)+IOP_DMA_SPEED, data)((__builtin_constant_p((((port)+(0x07)))) && (((port)
+(0x07))) < 256) ? __outbc(((data)),(((port)+(0x07)))) : __outb
(((data)),(((port)+(0x07)))))
1930#define AscReadChipDA0(port)(ushort)((__builtin_constant_p(((port)+(0x08))) && ((
port)+(0x08)) < 256) ? __inwc((port)+(0x08)) : __inw((port
)+(0x08)))
(ushort)inpw((port)+IOP_REG_DA0)((__builtin_constant_p(((port)+(0x08))) && ((port)+(0x08
)) < 256) ? __inwc((port)+(0x08)) : __inw((port)+(0x08)))
1931#define AscWriteChipDA0(port)((__builtin_constant_p((((port)+(0x08)))) && (((port)
+(0x08))) < 256) ? __outwc(((data)),(((port)+(0x08)))) : __outw
(((data)),(((port)+(0x08)))))
outpw((port)+IOP_REG_DA0, data)((__builtin_constant_p((((port)+(0x08)))) && (((port)
+(0x08))) < 256) ? __outwc(((data)),(((port)+(0x08)))) : __outw
(((data)),(((port)+(0x08)))))
1932#define AscReadChipDA1(port)(ushort)((__builtin_constant_p(((port)+(0x0A))) && ((
port)+(0x0A)) < 256) ? __inwc((port)+(0x0A)) : __inw((port
)+(0x0A)))
(ushort)inpw((port)+IOP_REG_DA1)((__builtin_constant_p(((port)+(0x0A))) && ((port)+(0x0A
)) < 256) ? __inwc((port)+(0x0A)) : __inw((port)+(0x0A)))
1933#define AscWriteChipDA1(port)((__builtin_constant_p((((port)+(0x0A)))) && (((port)
+(0x0A))) < 256) ? __outwc(((data)),(((port)+(0x0A)))) : __outw
(((data)),(((port)+(0x0A)))))
outpw((port)+IOP_REG_DA1, data)((__builtin_constant_p((((port)+(0x0A)))) && (((port)
+(0x0A))) < 256) ? __outwc(((data)),(((port)+(0x0A)))) : __outw
(((data)),(((port)+(0x0A)))))
1934#define AscReadChipDC0(port)(ushort)((__builtin_constant_p(((port)+(0x0C))) && ((
port)+(0x0C)) < 256) ? __inwc((port)+(0x0C)) : __inw((port
)+(0x0C)))
(ushort)inpw((port)+IOP_REG_DC0)((__builtin_constant_p(((port)+(0x0C))) && ((port)+(0x0C
)) < 256) ? __inwc((port)+(0x0C)) : __inw((port)+(0x0C)))
1935#define AscWriteChipDC0(port)((__builtin_constant_p((((port)+(0x0C)))) && (((port)
+(0x0C))) < 256) ? __outwc(((data)),(((port)+(0x0C)))) : __outw
(((data)),(((port)+(0x0C)))))
outpw((port)+IOP_REG_DC0, data)((__builtin_constant_p((((port)+(0x0C)))) && (((port)
+(0x0C))) < 256) ? __outwc(((data)),(((port)+(0x0C)))) : __outw
(((data)),(((port)+(0x0C)))))
1936#define AscReadChipDC1(port)(ushort)((__builtin_constant_p(((port)+(0x0E))) && ((
port)+(0x0E)) < 256) ? __inwc((port)+(0x0E)) : __inw((port
)+(0x0E)))
(ushort)inpw((port)+IOP_REG_DC1)((__builtin_constant_p(((port)+(0x0E))) && ((port)+(0x0E
)) < 256) ? __inwc((port)+(0x0E)) : __inw((port)+(0x0E)))
1937#define AscWriteChipDC1(port)((__builtin_constant_p((((port)+(0x0E)))) && (((port)
+(0x0E))) < 256) ? __outwc(((data)),(((port)+(0x0E)))) : __outw
(((data)),(((port)+(0x0E)))))
outpw((port)+IOP_REG_DC1, data)((__builtin_constant_p((((port)+(0x0E)))) && (((port)
+(0x0E))) < 256) ? __outwc(((data)),(((port)+(0x0E)))) : __outw
(((data)),(((port)+(0x0E)))))
1938#define AscReadChipDvcID(port)(uchar)((__builtin_constant_p(((port)+(0x05))) && ((port
)+(0x05)) < 256) ? __inbc((port)+(0x05)) : __inb((port)+(0x05
)))
(uchar)inp((port)+IOP_REG_ID)((__builtin_constant_p(((port)+(0x05))) && ((port)+(0x05
)) < 256) ? __inbc((port)+(0x05)) : __inb((port)+(0x05)))
1939#define AscWriteChipDvcID(port, data)((__builtin_constant_p((((port)+(0x05)))) && (((port)
+(0x05))) < 256) ? __outbc(((data)),(((port)+(0x05)))) : __outb
(((data)),(((port)+(0x05)))))
outp((port)+IOP_REG_ID, data)((__builtin_constant_p((((port)+(0x05)))) && (((port)
+(0x05))) < 256) ? __outbc(((data)),(((port)+(0x05)))) : __outb
(((data)),(((port)+(0x05)))))
1940
1941STATICstatic int AscWriteEEPCmdReg(PortAddrunsigned short iop_base, uchar cmd_reg);
1942STATICstatic int AscWriteEEPDataReg(PortAddrunsigned short iop_base, ushort data_reg);
1943STATICstatic void AscWaitEEPRead(void);
1944STATICstatic void AscWaitEEPWrite(void);
1945STATICstatic ushort AscReadEEPWord(PortAddrunsigned short, uchar);
1946STATICstatic ushort AscWriteEEPWord(PortAddrunsigned short, uchar, ushort);
1947STATICstatic ushort AscGetEEPConfig(PortAddrunsigned short, ASCEEP_CONFIG *, ushort);
1948STATICstatic int AscSetEEPConfigOnce(PortAddrunsigned short, ASCEEP_CONFIG *, ushort);
1949STATICstatic int AscSetEEPConfig(PortAddrunsigned short, ASCEEP_CONFIG *, ushort);
1950STATICstatic int AscStartChip(PortAddrunsigned short);
1951STATICstatic int AscStopChip(PortAddrunsigned short);
1952STATICstatic void AscSetChipIH(PortAddrunsigned short, ushort);
1953STATICstatic int AscIsChipHalted(PortAddrunsigned short);
1954STATICstatic void AscAckInterrupt(PortAddrunsigned short);
1955STATICstatic void AscDisableInterrupt(PortAddrunsigned short);
1956STATICstatic void AscEnableInterrupt(PortAddrunsigned short);
1957STATICstatic void AscSetBank(PortAddrunsigned short, uchar);
1958STATICstatic int AscResetChipAndScsiBus(ASC_DVC_VAR *);
1959STATICstatic ushort AscGetIsaDmaChannel(PortAddrunsigned short);
1960STATICstatic ushort AscSetIsaDmaChannel(PortAddrunsigned short, ushort);
1961STATICstatic uchar AscSetIsaDmaSpeed(PortAddrunsigned short, uchar);
1962STATICstatic uchar AscGetIsaDmaSpeed(PortAddrunsigned short);
1963STATICstatic uchar AscReadLramByte(PortAddrunsigned short, ushort);
1964STATICstatic ushort AscReadLramWord(PortAddrunsigned short, ushort);
1965STATICstatic ulong AscReadLramDWord(PortAddrunsigned short, ushort);
1966STATICstatic void AscWriteLramWord(PortAddrunsigned short, ushort, ushort);
1967STATICstatic void AscWriteLramDWord(PortAddrunsigned short, ushort, ulong);
1968STATICstatic void AscWriteLramByte(PortAddrunsigned short, ushort, uchar);
1969STATICstatic ulong AscMemSumLramWord(PortAddrunsigned short, ushort, rintregister __s32);
1970STATICstatic void AscMemWordSetLram(PortAddrunsigned short, ushort, ushort, rintregister __s32);
1971STATICstatic void AscMemWordCopyToLram(PortAddrunsigned short, ushort, ushort *, int);
1972STATICstatic void AscMemDWordCopyToLram(PortAddrunsigned short, ushort, ulong *, int);
1973STATICstatic void AscMemWordCopyFromLram(PortAddrunsigned short, ushort, ushort *, int);
1974STATICstatic ushort AscInitAscDvcVar(ASC_DVC_VAR asc_ptr_type *);
1975STATICstatic ushort AscInitFromEEP(ASC_DVC_VAR asc_ptr_type *);
1976STATICstatic ushort AscInitFromAscDvcVar(ASC_DVC_VAR asc_ptr_type *);
1977STATICstatic ushort AscInitMicroCodeVar(ASC_DVC_VAR asc_ptr_type * asc_dvc);
1978STATICstatic int AscTestExternalLram(ASC_DVC_VAR asc_ptr_type *);
1979STATICstatic uchar AscMsgOutSDTR(ASC_DVC_VAR asc_ptr_type *, uchar, uchar);
1980STATICstatic uchar AscCalSDTRData(ASC_DVC_VAR asc_ptr_type *, uchar, uchar);
1981STATICstatic void AscSetChipSDTR(PortAddrunsigned short, uchar, uchar);
1982STATICstatic uchar AscGetSynPeriodIndex(ASC_DVC_VAR asc_ptr_type *, rucharregister __u8);
1983STATICstatic uchar AscAllocFreeQueue(PortAddrunsigned short, uchar);
1984STATICstatic uchar AscAllocMultipleFreeQueue(PortAddrunsigned short, uchar, uchar);
1985STATICstatic int AscRiscHaltedAbortSRB(ASC_DVC_VAR asc_ptr_type *, ulong);
1986#if LINUX_VERSION_CODE131108 >= ASC_LINUX_VERSION(1,3,89)(((1) * 65536) + ((3) * 256) + (89))
1987STATICstatic int AscRiscHaltedAbortTIX(ASC_DVC_VAR asc_ptr_type *, uchar);
1988#endif /* version >= v1.3.89 */
1989STATICstatic int AscHostReqRiscHalt(PortAddrunsigned short);
1990STATICstatic int AscStopQueueExe(PortAddrunsigned short);
1991STATICstatic int AscStartQueueExe(PortAddrunsigned short);
1992#if LINUX_VERSION_CODE131108 >= ASC_LINUX_VERSION(1,3,89)(((1) * 65536) + ((3) * 256) + (89))
1993STATICstatic int AscCleanUpDiscQueue(PortAddrunsigned short);
1994#endif /* version >= v1.3.89 */
1995STATICstatic int AscCleanUpBusyQueue(PortAddrunsigned short);
1996STATICstatic int AscWaitTixISRDone(ASC_DVC_VAR asc_ptr_type *, uchar);
1997STATICstatic int AscWaitISRDone(ASC_DVC_VAR asc_ptr_type *);
1998STATICstatic ulong AscGetOnePhyAddr(ASC_DVC_VAR asc_ptr_type *, uchar *,
1999 ulong);
2000STATICstatic int AscSendScsiQueue(ASC_DVC_VAR asc_ptr_type * asc_dvc,
2001 ASC_SCSI_Q * scsiq,
2002 uchar n_q_required);
2003STATICstatic int AscPutReadyQueue(ASC_DVC_VAR asc_ptr_type *,
2004 ASC_SCSI_Q *, uchar);
2005STATICstatic int AscPutReadySgListQueue(ASC_DVC_VAR asc_ptr_type *,
2006 ASC_SCSI_Q *, uchar);
2007STATICstatic int AscSetChipSynRegAtID(PortAddrunsigned short, uchar, uchar);
2008STATICstatic int AscSetRunChipSynRegAtID(PortAddrunsigned short, uchar, uchar);
2009STATICstatic ushort AscInitLram(ASC_DVC_VAR asc_ptr_type *);
2010STATICstatic int AscReInitLram(ASC_DVC_VAR asc_ptr_type *);
2011STATICstatic ushort AscInitQLinkVar(ASC_DVC_VAR asc_ptr_type *);
2012STATICstatic int AscSetLibErrorCode(ASC_DVC_VAR asc_ptr_type *, ushort);
2013#if LINUX_VERSION_CODE131108 >= ASC_LINUX_VERSION(1,3,89)(((1) * 65536) + ((3) * 256) + (89))
2014STATICstatic int _AscWaitQDone(PortAddrunsigned short, ASC_SCSI_Q *);
2015#endif /* version >= v1.3.89 */
2016STATICstatic int AscIsrChipHalted(ASC_DVC_VAR asc_ptr_type *);
2017STATICstatic uchar _AscCopyLramScsiDoneQ(PortAddrunsigned short, ushort,
2018 ASC_QDONE_INFO *, ulong);
2019STATICstatic int AscIsrQDone(ASC_DVC_VAR asc_ptr_type *);
2020STATICstatic int AscCompareString(uchar *, uchar *, int);
2021STATICstatic ushort AscGetEisaChipCfg(PortAddrunsigned short);
2022STATICstatic ulong AscGetEisaProductID(PortAddrunsigned short);
2023STATICstatic PortAddrunsigned short AscSearchIOPortAddrEISA(PortAddrunsigned short);
2024STATICstatic uchar AscGetChipScsiCtrl(PortAddrunsigned short);
2025STATICstatic uchar AscSetChipScsiID(PortAddrunsigned short, uchar);
2026STATICstatic uchar AscGetChipVersion(PortAddrunsigned short, ushort);
2027STATICstatic ushort AscGetChipBusType(PortAddrunsigned short);
2028STATICstatic ulong AscLoadMicroCode(PortAddrunsigned short, ushort, ushort *, ushort);
2029STATICstatic int AscFindSignature(PortAddrunsigned short);
2030STATICstatic PortAddrunsigned short AscSearchIOPortAddr11(PortAddrunsigned short);
2031STATICstatic void AscToggleIRQAct(PortAddrunsigned short);
2032STATICstatic void AscSetISAPNPWaitForKey(void);
2033STATICstatic uchar AscGetChipIRQ(PortAddrunsigned short, ushort);
2034STATICstatic uchar AscSetChipIRQ(PortAddrunsigned short, uchar, ushort);
2035STATICstatic ushort AscGetChipBiosAddress(PortAddrunsigned short, ushort);
2036STATICstatic long DvcEnterCritical(void);
2037STATICstatic void DvcLeaveCritical(long);
2038STATICstatic void DvcInPortWords(PortAddrunsigned short, ushort *, int);
2039STATICstatic void DvcOutPortWords(PortAddrunsigned short, ushort *, int);
2040STATICstatic void DvcOutPortDWords(PortAddrunsigned short, ulong *, int);
2041STATICstatic uchar DvcReadPCIConfigByte(ASC_DVC_VAR asc_ptr_type *, ushort);
2042STATICstatic void DvcWritePCIConfigByte(ASC_DVC_VAR asc_ptr_type *,
2043 ushort, uchar);
2044STATICstatic ushort AscGetChipBiosAddress(PortAddrunsigned short, ushort);
2045STATICstatic void DvcSleepMilliSecond(ulong);
2046STATICstatic void DvcDelayNanoSecond(ASC_DVC_VAR asc_ptr_type *, ulong);
2047STATICstatic ulong DvcGetSGList(ASC_DVC_VAR asc_ptr_type *, uchar *,
2048 ulong, ASC_SG_HEAD *);
2049STATICstatic void DvcPutScsiQ(PortAddrunsigned short, ushort, ushort *, int);
2050STATICstatic void DvcGetQinfo(PortAddrunsigned short, ushort, ushort *, int);
2051STATICstatic PortAddrunsigned short AscSearchIOPortAddr(PortAddrunsigned short, ushort);
2052STATICstatic ushort AscInitGetConfig(ASC_DVC_VAR asc_ptr_type *);
2053STATICstatic ushort AscInitSetConfig(ASC_DVC_VAR asc_ptr_type *);
2054STATICstatic ushort AscInitAsc1000Driver(ASC_DVC_VAR asc_ptr_type *);
2055STATICstatic void AscAsyncFix(ASC_DVC_VAR asc_ptr_type *, uchar,
2056 ASC_SCSI_INQUIRY *);
2057STATICstatic int AscTagQueuingSafe(ASC_SCSI_INQUIRY *);
2058STATICstatic void AscInquiryHandling(ASC_DVC_VAR asc_ptr_type *,
2059 uchar, ASC_SCSI_INQUIRY *);
2060STATICstatic int AscExeScsiQueue(ASC_DVC_VAR asc_ptr_type *, ASC_SCSI_Q *);
2061STATICstatic int AscISR(ASC_DVC_VAR asc_ptr_type *);
2062STATICstatic uint AscGetNumOfFreeQueue(ASC_DVC_VAR asc_ptr_type *, uchar,
2063 uchar);
2064STATICstatic int AscSgListToQueue(int);
2065STATICstatic int AscAbortSRB(ASC_DVC_VAR asc_ptr_type *, ulong);
2066#if LINUX_VERSION_CODE131108 >= ASC_LINUX_VERSION(1,3,89)(((1) * 65536) + ((3) * 256) + (89))
2067STATICstatic int AscResetDevice(ASC_DVC_VAR asc_ptr_type *, uchar);
2068#endif /* version >= v1.3.89 */
2069STATICstatic int AscResetSB(ASC_DVC_VAR asc_ptr_type *);
2070STATICstatic void AscEnableIsaDma(uchar);
2071STATICstatic ulong AscGetMaxDmaCount(ushort);
2072
2073
2074/*
2075 * --- Adv Library Constants and Macros
2076 */
2077
2078#define ADV_LIB_VERSION_MAJOR3 3
2079#define ADV_LIB_VERSION_MINOR45 45
2080
2081/* d_os_dep.h */
2082#define ADV_OS_LINUX
2083
2084/*
2085 * Define Adv Library required special types.
2086 */
2087#if LINUX_VERSION_CODE131108 < ASC_LINUX_VERSION(1,3,0)(((1) * 65536) + ((3) * 256) + (0))
2088#define AdvPortAddrunsigned long unsigned short /* I/O Port address size */
2089#else /* version >= v1,3,0 */
2090#define AdvPortAddrunsigned long unsigned long /* Virtual memory address size */
2091#endif /* version >= v1,3,0 */
2092
2093/*
2094 * Define Adv Library required memory access macros.
2095 */
2096#define ADV_MEM_READB(addr)(*(volatile unsigned char *) (addr)) readb(addr)(*(volatile unsigned char *) (addr))
2097#define ADV_MEM_READW(addr)(*(volatile unsigned short *) (addr)) readw(addr)(*(volatile unsigned short *) (addr))
2098#define ADV_MEM_WRITEB(addr, byte)((*(volatile unsigned char *) (addr)) = (byte)) writeb(byte, addr)((*(volatile unsigned char *) (addr)) = (byte))
2099#define ADV_MEM_WRITEW(addr, word)((*(volatile unsigned short *) (addr)) = (word)) writew(word, addr)((*(volatile unsigned short *) (addr)) = (word))
2100
2101/*
2102 * The I/O memory mapping function names changed in 2.1.X.
2103 */
2104#if LINUX_VERSION_CODE131108 < ASC_LINUX_VERSION(2,1,0)(((2) * 65536) + ((1) * 256) + (0))
2105#define ioremapvremap vremap
2106#define iounmapvfree vfree
2107#endif /* version < v2.1.0 */
2108
2109/*
2110 * Define total number of simultaneous maximum element scatter-gather
2111 * requests, i.e. ADV_TOT_SG_LIST * ADV_MAX_SG_LIST is the total number
2112 * of simultaneous scatter-gather elements supported per wide adapter.
2113 */
2114#define ADV_TOT_SG_LIST64 64
2115
2116/*
2117 * Define Adv Library required per request scatter-gather element limit.
2118 */
2119#define ADV_MAX_SG_LIST64 64
2120
2121/*
2122 * Scatter-Gather Definitions per request.
2123 *
2124 * Because SG block memory is allocated in virtual memory but is
2125 * referenced by the microcode as physical memory, we need to do
2126 * calculations to insure there will be enough physically contiguous
2127 * memory to support ADV_MAX_SG_LIST SG entries.
2128 */
2129
2130/* Number of SG blocks needed. */
2131#define ADV_NUM_SG_BLOCK((64 + (15 - 1))/15) \
2132 ((ADV_MAX_SG_LIST64 + (NO_OF_SG_PER_BLOCK15 - 1))/NO_OF_SG_PER_BLOCK15)
2133
2134/* Total contiguous memory needed for SG blocks. */
2135#define ADV_SG_TOTAL_MEM_SIZE(sizeof(ADV_SG_BLOCK) * ((64 + (15 - 1))/15)) \
2136 (sizeof(ADV_SG_BLOCK) * ADV_NUM_SG_BLOCK((64 + (15 - 1))/15))
2137
2138#define ASC_PAGE_SIZE(1 << 12) PAGE_SIZE(1 << 12)
2139
2140/*
2141 * Number of page crossings possible for the total contiguous virtual memory
2142 * needed for SG blocks.
2143 *
2144 * We need to allocate this many additional SG blocks in virtual memory to
2145 * insure there will be space for ADV_NUM_SG_BLOCK physically contiguous
2146 * scatter-gather blocks.
2147 */
2148#define ADV_NUM_PAGE_CROSSING(((sizeof(ADV_SG_BLOCK) * ((64 + (15 - 1))/15)) + ((1 <<
12) - 1))/(1 << 12))
\
2149 ((ADV_SG_TOTAL_MEM_SIZE(sizeof(ADV_SG_BLOCK) * ((64 + (15 - 1))/15)) + (ASC_PAGE_SIZE(1 << 12) - 1))/ASC_PAGE_SIZE(1 << 12))
2150
2151/*
2152 * Define Adv Library Assertion Macro.
2153 */
2154
2155#define ADV_ASSERT(a){ if (!(a)) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 2155); } }
ASC_ASSERT(a){ if (!(a)) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 2155); } }
2156
2157/* a_condor.h */
2158#define ADV_PCI_VENDOR_ID0x10CD 0x10CD
2159#define ADV_PCI_DEVICE_ID_REV_A0x2300 0x2300
2160
2161#define ASC_EEP_DVC_CFG_BEGIN(0x00) (0x00)
2162#define ASC_EEP_DVC_CFG_END(0x15) (0x15)
2163#define ASC_EEP_DVC_CTL_BEGIN(0x16) (0x16) /* location of OEM name */
2164#define ASC_EEP_MAX_WORD_ADDR(0x1E) (0x1E)
2165
2166#define ASC_EEP_DELAY_MS100 100
2167
2168/*
2169 * EEPROM bits reference by the RISC after initialization.
2170 */
2171#define ADV_EEPROM_BIG_ENDIAN0x8000 0x8000 /* EEPROM Bit 15 */
2172#define ADV_EEPROM_BIOS_ENABLE0x4000 0x4000 /* EEPROM Bit 14 */
2173#define ADV_EEPROM_TERM_POL0x2000 0x2000 /* EEPROM Bit 13 */
2174
2175/*
2176 * EEPROM configuration format
2177 *
2178 * Field naming convention:
2179 *
2180 * *_enable indicates the field enables or disables the feature. The
2181 * value is never reset.
2182 *
2183 * *_able indicates both whether a feature should be enabled or disabled
2184 * and whether a device isi capable of the feature. At initialization
2185 * this field may be set, but later if a device is found to be incapable
2186 * of the feature, the field is cleared.
2187 *
2188 * Default values are maintained in a_init.c in the structure
2189 * Default_EEPROM_Config.
2190 */
2191typedef struct adveep_config
2192{
2193 /* Word Offset, Description */
2194
2195 ushort cfg_lsw; /* 00 power up initialization */
2196 /* bit 13 set - Term Polarity Control */
2197 /* bit 14 set - BIOS Enable */
2198 /* bit 15 set - Big Endian Mode */
2199 ushort cfg_msw; /* 01 unused */
2200 ushort disc_enable; /* 02 disconnect enable */
2201 ushort wdtr_able; /* 03 Wide DTR able */
2202 ushort sdtr_able; /* 04 Synchronous DTR able */
2203 ushort start_motor; /* 05 send start up motor */
2204 ushort tagqng_able; /* 06 tag queuing able */
2205 ushort bios_scan; /* 07 BIOS device control */
2206 ushort scam_tolerant; /* 08 no scam */
2207
2208 uchar adapter_scsi_id; /* 09 Host Adapter ID */
2209 uchar bios_boot_delay; /* power up wait */
2210
2211 uchar scsi_reset_delay; /* 10 reset delay */
2212 uchar bios_id_lun; /* first boot device scsi id & lun */
2213 /* high nibble is lun */
2214 /* low nibble is scsi id */
2215
2216 uchar termination; /* 11 0 - automatic */
2217 /* 1 - low off / high off */
2218 /* 2 - low off / high on */
2219 /* 3 - low on / high on */
2220 /* There is no low on / high off */
2221
2222 uchar reserved1; /* reserved byte (not used) */
2223
2224 ushort bios_ctrl; /* 12 BIOS control bits */
2225 /* bit 0 set: BIOS don't act as initiator. */
2226 /* bit 1 set: BIOS > 1 GB support */
2227 /* bit 2 set: BIOS > 2 Disk Support */
2228 /* bit 3 set: BIOS don't support removables */
2229 /* bit 4 set: BIOS support bootable CD */
2230 /* bit 5 set: */
2231 /* bit 6 set: BIOS support multiple LUNs */
2232 /* bit 7 set: BIOS display of message */
2233 /* bit 8 set: */
2234 /* bit 9 set: Reset SCSI bus during init. */
2235 /* bit 10 set: */
2236 /* bit 11 set: No verbose initialization. */
2237 /* bit 12 set: SCSI parity enabled */
2238 /* bit 13 set: */
2239 /* bit 14 set: */
2240 /* bit 15 set: */
2241 ushort ultra_able; /* 13 ULTRA speed able */
2242 ushort reserved2; /* 14 reserved */
2243 uchar max_host_qng; /* 15 maximum host queuing */
2244 uchar max_dvc_qng; /* maximum per device queuing */
2245 ushort dvc_cntl; /* 16 control bit for driver */
2246 ushort bug_fix; /* 17 control bit for bug fix */
2247 ushort serial_number_word1; /* 18 Board serial number word 1 */
2248 ushort serial_number_word2; /* 19 Board serial number word 2 */
2249 ushort serial_number_word3; /* 20 Board serial number word 3 */
2250 ushort check_sum; /* 21 EEP check sum */
2251 uchar oem_name[16]; /* 22 OEM name */
2252 ushort dvc_err_code; /* 30 last device driver error code */
2253 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
2254 ushort adv_err_addr; /* 32 last uc error address */
2255 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
2256 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
2257 ushort saved_adv_err_addr; /* 35 saved last uc error address */
2258 ushort num_of_err; /* 36 number of error */
2259} ADVEEP_CONFIG;
2260
2261/*
2262 * EEPROM Commands
2263 */
2264#define ASC_EEP_CMD_DONE0x0200 0x0200
2265#define ASC_EEP_CMD_DONE_ERR0x0001 0x0001
2266
2267/* cfg_word */
2268#define EEP_CFG_WORD_BIG_ENDIAN0x8000 0x8000
2269
2270/* bios_ctrl */
2271#define BIOS_CTRL_BIOS0x0001 0x0001
2272#define BIOS_CTRL_EXTENDED_XLAT0x0002 0x0002
2273#define BIOS_CTRL_GT_2_DISK0x0004 0x0004
2274#define BIOS_CTRL_BIOS_REMOVABLE0x0008 0x0008
2275#define BIOS_CTRL_BOOTABLE_CD0x0010 0x0010
2276#define BIOS_CTRL_MULTIPLE_LUN0x0040 0x0040
2277#define BIOS_CTRL_DISPLAY_MSG0x0080 0x0080
2278#define BIOS_CTRL_NO_SCAM0x0100 0x0100
2279#define BIOS_CTRL_RESET_SCSI_BUS0x0200 0x0200
2280#define BIOS_CTRL_INIT_VERBOSE0x0800 0x0800
2281#define BIOS_CTRL_SCSI_PARITY0x1000 0x1000
2282
2283/*
2284 * ASC 3550 Internal Memory Size - 8KB
2285 */
2286#define ADV_CONDOR_MEMSIZE0x2000 0x2000 /* 8 KB Internal Memory */
2287
2288/*
2289 * ASC 3550 I/O Length - 64 bytes
2290 */
2291#define ADV_CONDOR_IOLEN0x40 0x40 /* I/O Port Range in bytes */
2292
2293/*
2294 * Byte I/O register address from base of 'iop_base'.
2295 */
2296#define IOPB_INTR_STATUS_REG0x00 0x00
2297#define IOPB_CHIP_ID_10x01 0x01
2298#define IOPB_INTR_ENABLES0x02 0x02
2299#define IOPB_CHIP_TYPE_REV0x03 0x03
2300#define IOPB_RES_ADDR_40x04 0x04
2301#define IOPB_RES_ADDR_50x05 0x05
2302#define IOPB_RAM_DATA0x06 0x06
2303#define IOPB_RES_ADDR_70x07 0x07
2304#define IOPB_FLAG_REG0x08 0x08
2305#define IOPB_RES_ADDR_90x09 0x09
2306#define IOPB_RISC_CSR0x0A 0x0A
2307#define IOPB_RES_ADDR_B0x0B 0x0B
2308#define IOPB_RES_ADDR_C0x0C 0x0C
2309#define IOPB_RES_ADDR_D0x0D 0x0D
2310#define IOPB_RES_ADDR_E0x0E 0x0E
2311#define IOPB_RES_ADDR_F0x0F 0x0F
2312#define IOPB_MEM_CFG0x10 0x10
2313#define IOPB_RES_ADDR_110x11 0x11
2314#define IOPB_RES_ADDR_120x12 0x12
2315#define IOPB_RES_ADDR_130x13 0x13
2316#define IOPB_FLASH_PAGE0x14 0x14
2317#define IOPB_RES_ADDR_150x15 0x15
2318#define IOPB_RES_ADDR_160x16 0x16
2319#define IOPB_RES_ADDR_170x17 0x17
2320#define IOPB_FLASH_DATA0x18 0x18
2321#define IOPB_RES_ADDR_190x19 0x19
2322#define IOPB_RES_ADDR_1A0x1A 0x1A
2323#define IOPB_RES_ADDR_1B0x1B 0x1B
2324#define IOPB_RES_ADDR_1C0x1C 0x1C
2325#define IOPB_RES_ADDR_1D0x1D 0x1D
2326#define IOPB_RES_ADDR_1E0x1E 0x1E
2327#define IOPB_RES_ADDR_1F0x1F 0x1F
2328#define IOPB_DMA_CFG00x20 0x20
2329#define IOPB_DMA_CFG10x21 0x21
2330#define IOPB_TICKLE0x22 0x22
2331#define IOPB_DMA_REG_WR0x23 0x23
2332#define IOPB_SDMA_STATUS0x24 0x24
2333#define IOPB_SCSI_BYTE_CNT0x25 0x25
2334#define IOPB_HOST_BYTE_CNT0x26 0x26
2335#define IOPB_BYTE_LEFT_TO_XFER0x27 0x27
2336#define IOPB_BYTE_TO_XFER_00x28 0x28
2337#define IOPB_BYTE_TO_XFER_10x29 0x29
2338#define IOPB_BYTE_TO_XFER_20x2A 0x2A
2339#define IOPB_BYTE_TO_XFER_30x2B 0x2B
2340#define IOPB_ACC_GRP0x2C 0x2C
2341#define IOPB_RES_ADDR_2D0x2D 0x2D
2342#define IOPB_DEV_ID0x2E 0x2E
2343#define IOPB_RES_ADDR_2F0x2F 0x2F
2344#define IOPB_SCSI_DATA0x30 0x30
2345#define IOPB_RES_ADDR_310x31 0x31
2346#define IOPB_RES_ADDR_320x32 0x32
2347#define IOPB_SCSI_DATA_HSHK0x33 0x33
2348#define IOPB_SCSI_CTRL0x34 0x34
2349#define IOPB_RES_ADDR_350x35 0x35
2350#define IOPB_RES_ADDR_360x36 0x36
2351#define IOPB_RES_ADDR_370x37 0x37
2352#define IOPB_RES_ADDR_380x38 0x38
2353#define IOPB_RES_ADDR_390x39 0x39
2354#define IOPB_RES_ADDR_3A0x3A 0x3A
2355#define IOPB_RES_ADDR_3B0x3B 0x3B
2356#define IOPB_RFIFO_CNT0x3C 0x3C
2357#define IOPB_RES_ADDR_3D0x3D 0x3D
2358#define IOPB_RES_ADDR_3E0x3E 0x3E
2359#define IOPB_RES_ADDR_3F0x3F 0x3F
2360
2361/*
2362 * Word I/O register address from base of 'iop_base'.
2363 */
2364#define IOPW_CHIP_ID_00x00 0x00 /* CID0 */
2365#define IOPW_CTRL_REG0x02 0x02 /* CC */
2366#define IOPW_RAM_ADDR0x04 0x04 /* LA */
2367#define IOPW_RAM_DATA0x06 0x06 /* LD */
2368#define IOPW_RES_ADDR_080x08 0x08
2369#define IOPW_RISC_CSR0x0A 0x0A /* CSR */
2370#define IOPW_SCSI_CFG00x0C 0x0C /* CFG0 */
2371#define IOPW_SCSI_CFG10x0E 0x0E /* CFG1 */
2372#define IOPW_RES_ADDR_100x10 0x10
2373#define IOPW_SEL_MASK0x12 0x12 /* SM */
2374#define IOPW_RES_ADDR_140x14 0x14
2375#define IOPW_FLASH_ADDR0x16 0x16 /* FA */
2376#define IOPW_RES_ADDR_180x18 0x18
2377#define IOPW_EE_CMD0x1A 0x1A /* EC */
2378#define IOPW_EE_DATA0x1C 0x1C /* ED */
2379#define IOPW_SFIFO_CNT0x1E 0x1E /* SFC */
2380#define IOPW_RES_ADDR_200x20 0x20
2381#define IOPW_Q_BASE0x22 0x22 /* QB */
2382#define IOPW_QP0x24 0x24 /* QP */
2383#define IOPW_IX0x26 0x26 /* IX */
2384#define IOPW_SP0x28 0x28 /* SP */
2385#define IOPW_PC0x2A 0x2A /* PC */
2386#define IOPW_RES_ADDR_2C0x2C 0x2C
2387#define IOPW_RES_ADDR_2E0x2E 0x2E
2388#define IOPW_SCSI_DATA0x30 0x30 /* SD */
2389#define IOPW_SCSI_DATA_HSHK0x32 0x32 /* SDH */
2390#define IOPW_SCSI_CTRL0x34 0x34 /* SC */
2391#define IOPW_HSHK_CFG0x36 0x36 /* HCFG */
2392#define IOPW_SXFR_STATUS0x36 0x36 /* SXS */
2393#define IOPW_SXFR_CNTL0x38 0x38 /* SXL */
2394#define IOPW_SXFR_CNTH0x3A 0x3A /* SXH */
2395#define IOPW_RES_ADDR_3C0x3C 0x3C
2396#define IOPW_RFIFO_DATA0x3E 0x3E /* RFD */
2397
2398/*
2399 * Doubleword I/O register address from base of 'iop_base'.
2400 */
2401#define IOPDW_RES_ADDR_00x00 0x00
2402#define IOPDW_RAM_DATA0x04 0x04
2403#define IOPDW_RES_ADDR_80x08 0x08
2404#define IOPDW_RES_ADDR_C0x0C 0x0C
2405#define IOPDW_RES_ADDR_100x10 0x10
2406#define IOPDW_RES_ADDR_140x14 0x14
2407#define IOPDW_RES_ADDR_180x18 0x18
2408#define IOPDW_RES_ADDR_1C0x1C 0x1C
2409#define IOPDW_SDMA_ADDR00x20 0x20
2410#define IOPDW_SDMA_ADDR10x24 0x24
2411#define IOPDW_SDMA_COUNT0x28 0x28
2412#define IOPDW_SDMA_ERROR0x2C 0x2C
2413#define IOPDW_RDMA_ADDR00x30 0x30
2414#define IOPDW_RDMA_ADDR10x34 0x34
2415#define IOPDW_RDMA_COUNT0x38 0x38
2416#define IOPDW_RDMA_ERROR0x3C 0x3C
2417
2418#define ADV_CHIP_ID_BYTE0x25 0x25
2419#define ADV_CHIP_ID_WORD0x04C1 0x04C1
2420
2421#define ADV_SC_SCSI_BUS_RESET0x2000 0x2000
2422
2423#define ADV_INTR_ENABLE_HOST_INTR0x01 0x01
2424#define ADV_INTR_ENABLE_SEL_INTR0x02 0x02
2425#define ADV_INTR_ENABLE_DPR_INTR0x04 0x04
2426#define ADV_INTR_ENABLE_RTA_INTR0x08 0x08
2427#define ADV_INTR_ENABLE_RMA_INTR0x10 0x10
2428#define ADV_INTR_ENABLE_RST_INTR0x20 0x20
2429#define ADV_INTR_ENABLE_DPE_INTR0x40 0x40
2430#define ADV_INTR_ENABLE_GLOBAL_INTR0x80 0x80
2431
2432#define ADV_INTR_STATUS_INTRA0x01 0x01
2433#define ADV_INTR_STATUS_INTRB0x02 0x02
2434#define ADV_INTR_STATUS_INTRC0x04 0x04
2435
2436#define ADV_RISC_CSR_STOP(0x0000) (0x0000)
2437#define ADV_RISC_TEST_COND(0x2000) (0x2000)
2438#define ADV_RISC_CSR_RUN(0x4000) (0x4000)
2439#define ADV_RISC_CSR_SINGLE_STEP(0x8000) (0x8000)
2440
2441#define ADV_CTRL_REG_HOST_INTR0x0100 0x0100
2442#define ADV_CTRL_REG_SEL_INTR0x0200 0x0200
2443#define ADV_CTRL_REG_DPR_INTR0x0400 0x0400
2444#define ADV_CTRL_REG_RTA_INTR0x0800 0x0800
2445#define ADV_CTRL_REG_RMA_INTR0x1000 0x1000
2446#define ADV_CTRL_REG_RES_BIT140x2000 0x2000
2447#define ADV_CTRL_REG_DPE_INTR0x4000 0x4000
2448#define ADV_CTRL_REG_POWER_DONE0x8000 0x8000
2449#define ADV_CTRL_REG_ANY_INTR0xFF00 0xFF00
2450
2451#define ADV_CTRL_REG_CMD_RESET0x00C6 0x00C6
2452#define ADV_CTRL_REG_CMD_WR_IO_REG0x00C5 0x00C5
2453#define ADV_CTRL_REG_CMD_RD_IO_REG0x00C4 0x00C4
2454#define ADV_CTRL_REG_CMD_WR_PCI_CFG_SPACE0x00C3 0x00C3
2455#define ADV_CTRL_REG_CMD_RD_PCI_CFG_SPACE0x00C2 0x00C2
2456
2457#define ADV_SCSI_CTRL_RSTOUT0x2000 0x2000
2458
2459#define AdvIsIntPending(port)(((*(volatile unsigned short *) ((port) + (0x02)))) & 0x0100
)
\
2460 (AdvReadWordRegister(port, IOPW_CTRL_REG)((*(volatile unsigned short *) ((port) + (0x02)))) & ADV_CTRL_REG_HOST_INTR0x0100)
2461
2462/*
2463 * SCSI_CFG0 Register bit definitions
2464 */
2465#define TIMER_MODEAB0xC000 0xC000 /* Watchdog, Second, and Select. Timer Ctrl. */
2466#define PARITY_EN0x2000 0x2000 /* Enable SCSI Parity Error detection */
2467#define EVEN_PARITY0x1000 0x1000 /* Select Even Parity */
2468#define WD_LONG0x0800 0x0800 /* Watchdog Interval, 1: 57 min, 0: 13 sec */
2469#define QUEUE_1280x0400 0x0400 /* Queue Size, 1: 128 byte, 0: 64 byte */
2470#define PRIM_MODE0x0100 0x0100 /* Primitive SCSI mode */
2471#define SCAM_EN0x0080 0x0080 /* Enable SCAM selection */
2472#define SEL_TMO_LONG0x0040 0x0040 /* Sel/Resel Timeout, 1: 400 ms, 0: 1.6 ms */
2473#define CFRM_ID0x0020 0x0020 /* SCAM id sel. confirm., 1: fast, 0: 6.4 ms */
2474#define OUR_ID_EN0x0010 0x0010 /* Enable OUR_ID bits */
2475#define OUR_ID0x000F 0x000F /* SCSI ID */
2476
2477/*
2478 * SCSI_CFG1 Register bit definitions
2479 */
2480#define BIG_ENDIAN0x8000 0x8000 /* Enable Big Endian Mode MIO:15, EEP:15 */
2481#define TERM_POL0x2000 0x2000 /* Terminator Polarity Ctrl. MIO:13, EEP:13 */
2482#define SLEW_RATE0x1000 0x1000 /* SCSI output buffer slew rate */
2483#define FILTER_SEL0x0C00 0x0C00 /* Filter Period Selection */
2484#define FLTR_DISABLE0x0000 0x0000 /* Input Filtering Disabled */
2485#define FLTR_11_TO_20NS0x0800 0x0800 /* Input Filtering 11ns to 20ns */
2486#define FLTR_21_TO_39NS0x0C00 0x0C00 /* Input Filtering 21ns to 39ns */
2487#define ACTIVE_DBL0x0200 0x0200 /* Disable Active Negation */
2488#define DIFF_MODE0x0100 0x0100 /* SCSI differential Mode (Read-Only) */
2489#define DIFF_SENSE0x0080 0x0080 /* 1: No SE cables, 0: SE cable (Read-Only) */
2490#define TERM_CTL_SEL0x0040 0x0040 /* Enable TERM_CTL_H and TERM_CTL_L */
2491#define TERM_CTL0x0030 0x0030 /* External SCSI Termination Bits */
2492#define TERM_CTL_H0x0020 0x0020 /* Enable External SCSI Upper Termination */
2493#define TERM_CTL_L0x0010 0x0010 /* Enable External SCSI Lower Termination */
2494#define CABLE_DETECT0x000F 0x000F /* External SCSI Cable Connection Status */
2495
2496#define CABLE_ILLEGAL_A0x7 0x7
2497 /* x 0 0 0 | on on | Illegal (all 3 connectors are used) */
2498
2499#define CABLE_ILLEGAL_B0xB 0xB
2500 /* 0 x 0 0 | on on | Illegal (all 3 connectors are used) */
2501
2502/*
2503 The following table details the SCSI_CFG1 Termination Polarity,
2504 Termination Control and Cable Detect bits.
2505
2506 Cable Detect | Termination
2507 Bit 3 2 1 0 | 5 4 | Notes
2508 _____________|________|____________________
2509 1 1 1 0 | on on | Internal wide only
2510 1 1 0 1 | on on | Internal narrow only
2511 1 0 1 1 | on on | External narrow only
2512 0 x 1 1 | on on | External wide only
2513 1 1 0 0 | on off| Internal wide and internal narrow
2514 1 0 1 0 | on off| Internal wide and external narrow
2515 0 x 1 0 | off off| Internal wide and external wide
2516 1 0 0 1 | on off| Internal narrow and external narrow
2517 0 x 0 1 | on off| Internal narrow and external wide
2518 1 1 1 1 | on on | No devices are attached
2519 x 0 0 0 | on on | Illegal (all 3 connectors are used)
2520 0 x 0 0 | on on | Illegal (all 3 connectors are used)
2521
2522 x means don't-care (either '0' or '1')
2523
2524 If term_pol (bit 13) is '0' (active-low terminator enable), then:
2525 'on' is '0' and 'off' is '1'.
2526
2527 If term_pol bit is '1' (meaning active-hi terminator enable), then:
2528 'on' is '1' and 'off' is '0'.
2529 */
2530
2531/*
2532 * MEM_CFG Register bit definitions
2533 */
2534#define BIOS_EN0x40 0x40 /* BIOS Enable MIO:14,EEP:14 */
2535#define FAST_EE_CLK0x20 0x20 /* Diagnostic Bit */
2536#define RAM_SZ0x1C 0x1C /* Specify size of RAM to RISC */
2537#define RAM_SZ_2KB0x00 0x00 /* 2 KB */
2538#define RAM_SZ_4KB0x04 0x04 /* 4 KB */
2539#define RAM_SZ_8KB0x08 0x08 /* 8 KB */
2540#define RAM_SZ_16KB0x0C 0x0C /* 16 KB */
2541#define RAM_SZ_32KB0x10 0x10 /* 32 KB */
2542#define RAM_SZ_64KB0x14 0x14 /* 64 KB */
2543
2544/*
2545 * DMA_CFG0 Register bit definitions
2546 *
2547 * This register is only accessible to the host.
2548 */
2549#define BC_THRESH_ENB0x80 0x80 /* PCI DMA Start Conditions */
2550#define FIFO_THRESH0x70 0x70 /* PCI DMA FIFO Threshold */
2551#define FIFO_THRESH_16B0x00 0x00 /* 16 bytes */
2552#define FIFO_THRESH_32B0x20 0x20 /* 32 bytes */
2553#define FIFO_THRESH_48B0x30 0x30 /* 48 bytes */
2554#define FIFO_THRESH_64B0x40 0x40 /* 64 bytes */
2555#define FIFO_THRESH_80B0x50 0x50 /* 80 bytes (default) */
2556#define FIFO_THRESH_96B0x60 0x60 /* 96 bytes */
2557#define FIFO_THRESH_112B0x70 0x70 /* 112 bytes */
2558#define START_CTL0x0C 0x0C /* DMA start conditions */
2559#define START_CTL_TH0x00 0x00 /* Wait threshold level (default) */
2560#define START_CTL_ID0x04 0x04 /* Wait SDMA/SBUS idle */
2561#define START_CTL_THID0x08 0x08 /* Wait threshold and SDMA/SBUS idle */
2562#define START_CTL_EMFU0x0C 0x0C /* Wait SDMA FIFO empty/full */
2563#define READ_CMD0x03 0x03 /* Memory Read Method */
2564#define READ_CMD_MR0x00 0x00 /* Memory Read */
2565#define READ_CMD_MRL0x02 0x02 /* Memory Read Long */
2566#define READ_CMD_MRM0x03 0x03 /* Memory Read Multiple (default) */
2567
2568/* a_advlib.h */
2569
2570/*
2571 * Adv Library Status Definitions
2572 */
2573#define ADV_TRUE1 1
2574#define ADV_FALSE0 0
2575#define ADV_NOERROR1 1
2576#define ADV_SUCCESS1 1
2577#define ADV_BUSY0 0
2578#define ADV_ERROR(-1) (-1)
2579
2580
2581/*
2582 * ASC_DVC_VAR 'warn_code' values
2583 */
2584#define ASC_WARN_EEPROM_CHKSUM0x0002 0x0002 /* EEP check sum error */
2585#define ASC_WARN_EEPROM_TERMINATION0x0004 0x0004 /* EEP termination bad field */
2586#define ASC_WARN_SET_PCI_CONFIG_SPACE0x0080 0x0080 /* PCI config space set error */
2587#define ASC_WARN_ERROR0xFFFF 0xFFFF /* ADV_ERROR return */
2588
2589#define ADV_MAX_TID15 15 /* max. target identifier */
2590#define ADV_MAX_LUN7 7 /* max. logical unit number */
2591
2592
2593/*
2594 * AscInitGetConfig() and AscInitAsc1000Driver() Definitions
2595 *
2596 * Error code values are set in ASC_DVC_VAR 'err_code'.
2597 */
2598#define ASC_IERR_WRITE_EEPROM0x0001 0x0001 /* write EEPROM error */
2599#define ASC_IERR_MCODE_CHKSUM0x0002 0x0002 /* micro code check sum error */
2600#define ASC_IERR_START_STOP_CHIP0x0008 0x0008 /* start/stop chip failed */
2601#define ASC_IERR_CHIP_VERSION0x0040 0x0040 /* wrong chip version */
2602#define ASC_IERR_SET_SCSI_ID0x0080 0x0080 /* set SCSI ID failed */
2603#define ASC_IERR_BAD_SIGNATURE0x0200 0x0200 /* signature not found */
2604#define ASC_IERR_ILLEGAL_CONNECTION0x0400 0x0400 /* Illegal cable connection */
2605#define ASC_IERR_SINGLE_END_DEVICE0x0800 0x0800 /* Single-end used w/differential */
2606#define ASC_IERR_REVERSED_CABLE0x1000 0x1000 /* Narrow flat cable reversed */
2607#define ASC_IERR_RW_LRAM0x8000 0x8000 /* read/write local RAM error */
2608
2609/*
2610 * Fixed locations of microcode operating variables.
2611 */
2612#define ASC_MC_CODE_BEGIN_ADDR0x0028 0x0028 /* microcode start address */
2613#define ASC_MC_CODE_END_ADDR0x002A 0x002A /* microcode end address */
2614#define ASC_MC_CODE_CHK_SUM0x002C 0x002C /* microcode code checksum */
2615#define ASC_MC_STACK_BEGIN0x002E 0x002E /* microcode stack begin */
2616#define ASC_MC_STACK_END0x0030 0x0030 /* microcode stack end */
2617#define ASC_MC_VERSION_DATE0x0038 0x0038 /* microcode version */
2618#define ASC_MC_VERSION_NUM0x003A 0x003A /* microcode number */
2619#define ASCV_VER_SERIAL_W0x003C 0x003C /* used in dos_init */
2620#define ASC_MC_BIOSMEM0x0040 0x0040 /* BIOS RISC Memory Start */
2621#define ASC_MC_BIOSLEN0x0050 0x0050 /* BIOS RISC Memory Length */
2622#define ASC_MC_HALTCODE0x0094 0x0094 /* microcode halt code */
2623#define ASC_MC_CALLERPC0x0096 0x0096 /* microcode halt caller PC */
2624#define ASC_MC_ADAPTER_SCSI_ID0x0098 0x0098 /* one ID byte + reserved */
2625#define ASC_MC_ULTRA_ABLE0x009C 0x009C
2626#define ASC_MC_SDTR_ABLE0x009E 0x009E
2627#define ASC_MC_TAGQNG_ABLE0x00A0 0x00A0
2628#define ASC_MC_DISC_ENABLE0x00A2 0x00A2
2629#define ASC_MC_IDLE_CMD0x00A6 0x00A6
2630#define ASC_MC_IDLE_PARA_STAT0x00A8 0x00A8
2631#define ASC_MC_DEFAULT_SCSI_CFG00x00AC 0x00AC
2632#define ASC_MC_DEFAULT_SCSI_CFG10x00AE 0x00AE
2633#define ASC_MC_DEFAULT_MEM_CFG0x00B0 0x00B0
2634#define ASC_MC_DEFAULT_SEL_MASK0x00B2 0x00B2
2635#define ASC_MC_RISC_NEXT_READY0x00B4 0x00B4
2636#define ASC_MC_RISC_NEXT_DONE0x00B5 0x00B5
2637#define ASC_MC_SDTR_DONE0x00B6 0x00B6
2638#define ASC_MC_NUMBER_OF_QUEUED_CMD0x00C0 0x00C0
2639#define ASC_MC_NUMBER_OF_MAX_CMD0x00D0 0x00D0
2640#define ASC_MC_DEVICE_HSHK_CFG_TABLE0x0100 0x0100
2641#define ASC_MC_WDTR_ABLE0x0120 0x0120 /* Wide Transfer TID bitmask. */
2642#define ASC_MC_CONTROL_FLAG0x0122 0x0122 /* Microcode control flag. */
2643#define ASC_MC_WDTR_DONE0x0124 0x0124
2644#define ASC_MC_HOST_NEXT_READY0x0128 0x0128 /* Host Next Ready RQL Entry. */
2645#define ASC_MC_HOST_NEXT_DONE0x0129 0x0129 /* Host Next Done RQL Entry. */
2646
2647/*
2648 * BIOS LRAM variable absolute offsets.
2649 */
2650#define BIOS_CODESEG0x54 0x54
2651#define BIOS_CODELEN0x56 0x56
2652#define BIOS_SIGNATURE0x58 0x58
2653#define BIOS_VERSION0x5A 0x5A
2654#define BIOS_SIGNATURE0x58 0x58
2655
2656/*
2657 * Microcode Control Flags
2658 *
2659 * Flags set by the Adv Library in RISC variable 'control_flag' (0x122)
2660 * and handled by the microcode.
2661 */
2662#define CONTROL_FLAG_IGNORE_PERR0x0001 0x0001 /* Ignore DMA Parity Errors */
2663
2664/*
2665 * ASC_MC_DEVICE_HSHK_CFG_TABLE microcode table or HSHK_CFG register format
2666 */
2667#define HSHK_CFG_WIDE_XFR0x8000 0x8000
2668#define HSHK_CFG_RATE0x0F00 0x0F00
2669#define HSHK_CFG_OFFSET0x001F 0x001F
2670
2671/*
2672 * LRAM RISC Queue Lists (LRAM addresses 0x1200 - 0x19FF)
2673 *
2674 * Each of the 255 Adv Library/Microcode RISC queue lists or mailboxes
2675 * starting at LRAM address 0x1200 is 8 bytes and has the following
2676 * structure. Only 253 of these are actually used for command queues.
2677 */
2678
2679#define ASC_MC_RISC_Q_LIST_BASE0x1200 0x1200
2680#define ASC_MC_RISC_Q_LIST_SIZE0x0008 0x0008
2681#define ASC_MC_RISC_Q_TOTAL_CNT0x00FF 0x00FF /* Num. queue slots in LRAM. */
2682#define ASC_MC_RISC_Q_FIRST0x0001 0x0001
2683#define ASC_MC_RISC_Q_LAST0x00FF 0x00FF
2684
2685#define ASC_DEF_MAX_HOST_QNG0xFD 0xFD /* Max. number of host commands (253) */
2686#define ASC_DEF_MIN_HOST_QNG0x10 0x10 /* Min. number of host commands (16) */
2687#define ASC_DEF_MAX_DVC_QNG0x3F 0x3F /* Max. number commands per device (63) */
2688#define ASC_DEF_MIN_DVC_QNG0x04 0x04 /* Min. number commands per device (4) */
2689
2690/* RISC Queue List structure - 8 bytes */
2691#define RQL_FWD0 0 /* forward pointer (1 byte) */
2692#define RQL_BWD1 1 /* backward pointer (1 byte) */
2693#define RQL_STATE2 2 /* state byte - free, ready, done, aborted (1 byte) */
2694#define RQL_TID3 3 /* request target id (1 byte) */
2695#define RQL_PHYADDR4 4 /* request physical pointer (4 bytes) */
2696
2697/* RISC Queue List state values */
2698#define ASC_MC_QS_FREE0x00 0x00
2699#define ASC_MC_QS_READY0x01 0x01
2700#define ASC_MC_QS_DONE0x40 0x40
2701#define ASC_MC_QS_ABORTED0x80 0x80
2702
2703/* RISC Queue List pointer values */
2704#define ASC_MC_NULL_Q0x00 0x00 /* NULL_Q == 0 */
2705#define ASC_MC_BIOS_Q0xFF 0xFF /* BIOS_Q = 255 */
2706
2707/* ASC_SCSI_REQ_Q 'cntl' field values */
2708#define ASC_MC_QC_START_MOTOR0x02 0x02 /* Issue start motor. */
2709#define ASC_MC_QC_NO_OVERRUN0x04 0x04 /* Don't report overrun. */
2710#define ASC_MC_QC_FIRST_DMA0x08 0x08 /* Internal microcode flag. */
2711#define ASC_MC_QC_ABORTED0x10 0x10 /* Request aborted by host. */
2712#define ASC_MC_QC_REQ_SENSE0x20 0x20 /* Auto-Request Sense. */
2713#define ASC_MC_QC_DOS_REQ0x80 0x80 /* Request issued by DOS. */
2714
2715
2716/*
2717 * ASC_SCSI_REQ_Q 'a_flag' definitions
2718 *
2719 * The Adv Library should limit use to the lower nibble (4 bits) of
2720 * a_flag. Drivers are free to use the upper nibble (4 bits) of a_flag.
2721 */
2722#define ADV_POLL_REQUEST0x01 0x01 /* poll for request completion */
2723#define ADV_SCSIQ_DONE0x02 0x02 /* request done */
2724
2725/*
2726 * Adapter temporary configuration structure
2727 *
2728 * This structure can be discarded after initialization. Don't add
2729 * fields here needed after initialization.
2730 *
2731 * Field naming convention:
2732 *
2733 * *_enable indicates the field enables or disables a feature. The
2734 * value of the field is never reset.
2735 */
2736typedef struct adv_dvc_cfg {
2737 ushort disc_enable; /* enable disconnection */
2738 uchar chip_version; /* chip version */
2739 uchar termination; /* Term. Ctrl. bits 6-5 of SCSI_CFG1 register */
2740 ushort pci_device_id; /* PCI device code number */
2741 ushort lib_version; /* Adv Library version number */
2742 ushort control_flag; /* Microcode Control Flag */
2743 ushort mcode_date; /* Microcode date */
2744 ushort mcode_version; /* Microcode version */
2745 ushort pci_slot_info; /* high byte device/function number */
2746 /* bits 7-3 device num., bits 2-0 function num. */
2747 /* low byte bus num. */
2748 ushort bios_boot_wait; /* BIOS boot time delay */
2749 ushort serial1; /* EEPROM serial number word 1 */
2750 ushort serial2; /* EEPROM serial number word 2 */
2751 ushort serial3; /* EEPROM serial number word 3 */
2752} ADV_DVC_CFG;
2753
2754/*
2755 * Adapter operation variable structure.
2756 *
2757 * One structure is required per host adapter.
2758 *
2759 * Field naming convention:
2760 *
2761 * *_able indicates both whether a feature should be enabled or disabled
2762 * and whether a device isi capable of the feature. At initialization
2763 * this field may be set, but later if a device is found to be incapable
2764 * of the feature, the field is cleared.
2765 */
2766typedef struct adv_dvc_var {
2767 AdvPortAddrunsigned long iop_base; /* I/O port address */
2768 ushort err_code; /* fatal error code */
2769 ushort bios_ctrl; /* BIOS control word, EEPROM word 12 */
2770 Ptr2Funculong isr_callback; /* pointer to function, called in AdvISR() */
2771 Ptr2Funculong sbreset_callback; /* pointer to function, called in AdvISR() */
2772 ushort wdtr_able; /* try WDTR for a device */
2773 ushort sdtr_able; /* try SDTR for a device */
2774 ushort ultra_able; /* try SDTR Ultra speed for a device */
2775 ushort tagqng_able; /* try tagged queuing with a device */
2776 uchar max_dvc_qng; /* maximum number of tagged commands per device */
2777 ushort start_motor; /* start motor command allowed */
2778 uchar scsi_reset_wait; /* delay in seconds after scsi bus reset */
2779 uchar chip_no; /* should be assigned by caller */
2780 uchar max_host_qng; /* maximum number of Q'ed command allowed */
2781 uchar cur_host_qng; /* total number of queue command */
2782 uchar irq_no; /* IRQ number */
2783 ushort no_scam; /* scam_tolerant of EEPROM */
2784 ushort idle_cmd_done; /* microcode idle command done set by AdvISR() */
2785 ulong drv_ptr; /* driver pointer to private structure */
2786 uchar chip_scsi_id; /* chip SCSI target ID */
2787 /*
2788 * Note: The following fields will not be used after initialization. The
2789 * driver may discard the buffer after initialization is done.
2790 */
2791 ADV_DVC_CFG *cfg; /* temporary configuration structure */
2792} ADV_DVC_VAR;
2793
2794#define NO_OF_SG_PER_BLOCK15 15
2795
2796typedef struct asc_sg_block {
2797 uchar reserved1;
2798 uchar reserved2;
2799 uchar first_entry_no; /* starting entry number */
2800 uchar last_entry_no; /* last entry number */
2801 struct asc_sg_block *sg_ptr; /* links to the next sg block */
2802 struct {
2803 ulong sg_addr; /* SG element address */
2804 ulong sg_count; /* SG element count */
2805 } sg_list[NO_OF_SG_PER_BLOCK15];
2806} ADV_SG_BLOCK;
2807
2808/*
2809 * ASC_SCSI_REQ_Q - microcode request structure
2810 *
2811 * All fields in this structure up to byte 60 are used by the microcode.
2812 * The microcode makes assumptions about the size and ordering of fields
2813 * in this structure. Do not change the structure definition here without
2814 * coordinating the change with the microcode.
2815 */
2816typedef struct adv_scsi_req_q {
2817 uchar cntl; /* Ucode flags and state (ASC_MC_QC_*). */
2818 uchar sg_entry_cnt; /* SG element count. Zero for no SG. */
2819 uchar target_id; /* Device target identifier. */
2820 uchar target_lun; /* Device target logical unit number. */
2821 ulong data_addr; /* Data buffer physical address. */
2822 ulong data_cnt; /* Data count. Ucode sets to residual. */
2823 ulong sense_addr; /* Sense buffer physical address. */
2824 ulong srb_ptr; /* Driver request pointer. */
2825 uchar a_flag; /* Adv Library flag field. */
2826 uchar sense_len; /* Auto-sense length. Ucode sets to residual. */
2827 uchar cdb_len; /* SCSI CDB length. */
2828 uchar tag_code; /* SCSI-2 Tag Queue Code: 00, 20-22. */
2829 uchar done_status; /* Completion status. */
2830 uchar scsi_status; /* SCSI status byte. */
2831 uchar host_status; /* Ucode host status. */
2832 uchar ux_sg_ix; /* Ucode working SG variable. */
2833 uchar cdb[12]; /* SCSI command block. */
2834 ulong sg_real_addr; /* SG list physical address. */
2835 struct adv_scsi_req_q *free_scsiq_link;
2836 ulong ux_wk_data_cnt; /* Saved data count at disconnection. */
2837 struct adv_scsi_req_q *scsiq_ptr;
2838 ADV_SG_BLOCK *sg_list_ptr; /* SG list virtual address. */
2839 /*
2840 * End of microcode structure - 60 bytes. The rest of the structure
2841 * is used by the Adv Library and ignored by the microcode.
2842 */
2843 ulong vsense_addr; /* Sense buffer virtual address. */
2844 ulong vdata_addr; /* Data buffer virtual address. */
2845 uchar orig_sense_len; /* Original length of sense buffer. */
2846} ADV_SCSI_REQ_Q; /* BIOS - 70 bytes, DOS - 76 bytes, W95, WNT - 69 bytes */
2847
2848/*
2849 * Microcode idle loop commands
2850 */
2851#define IDLE_CMD_COMPLETED0 0
2852#define IDLE_CMD_STOP_CHIP0x0001 0x0001
2853#define IDLE_CMD_STOP_CHIP_SEND_INT0x0002 0x0002
2854#define IDLE_CMD_SEND_INT0x0004 0x0004
2855#define IDLE_CMD_ABORT0x0008 0x0008
2856#define IDLE_CMD_DEVICE_RESET0x0010 0x0010
2857#define IDLE_CMD_SCSI_RESET0x0020 0x0020
2858
2859/*
2860 * AdvSendIdleCmd() flag definitions.
2861 */
2862#define ADV_NOWAIT0x01 0x01
2863
2864/*
2865 * Wait loop time out values.
2866 */
2867#define SCSI_WAIT_10_SEC10 10 /* 10 seconds */
2868#define SCSI_MS_PER_SEC1000 1000 /* milliseconds per second */
2869
2870/*
2871 * Device drivers must define the following functions.
2872 */
2873STATICstatic long DvcEnterCritical(void);
2874STATICstatic void DvcLeaveCritical(long);
2875STATICstatic void DvcSleepMilliSecond(ulong);
2876STATICstatic uchar DvcAdvReadPCIConfigByte(ADV_DVC_VAR *, ushort);
2877STATICstatic void DvcAdvWritePCIConfigByte(ADV_DVC_VAR *, ushort, uchar);
2878STATICstatic ulong DvcGetPhyAddr(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *,
2879 uchar *, long *, int);
2880STATICstatic void DvcDelayMicroSecond(ADV_DVC_VAR *, ushort);
2881
2882/*
2883 * Adv Library functions available to drivers.
2884 */
2885STATICstatic int AdvExeScsiQueue(ADV_DVC_VAR *,
2886 ADV_SCSI_REQ_Q *);
2887STATICstatic int AdvISR(ADV_DVC_VAR *);
2888STATICstatic int AdvInitGetConfig(ADV_DVC_VAR *);
2889STATICstatic int AdvInitAsc3550Driver(ADV_DVC_VAR *);
2890STATICstatic int AdvResetSB(ADV_DVC_VAR *);
2891
2892/*
2893 * Internal Adv Library functions.
2894 */
2895STATICstatic int AdvSendIdleCmd(ADV_DVC_VAR *, ushort, ulong, int);
2896STATICstatic void AdvResetChip(ADV_DVC_VAR *);
2897STATICstatic int AdvSendScsiCmd(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
2898STATICstatic void AdvInquiryHandling(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
2899STATICstatic int AdvInitFromEEP(ADV_DVC_VAR *);
2900STATICstatic ushort AdvGetEEPConfig(AdvPortAddrunsigned long, ADVEEP_CONFIG *);
2901STATICstatic void AdvSetEEPConfig(AdvPortAddrunsigned long, ADVEEP_CONFIG *);
2902STATICstatic void AdvWaitEEPCmd(AdvPortAddrunsigned long);
2903STATICstatic ushort AdvReadEEPWord(AdvPortAddrunsigned long, int);
2904STATICstatic void AdvResetSCSIBus(ADV_DVC_VAR *);
2905
2906/*
2907 * PCI Bus Definitions
2908 */
2909#define AscPCICmdRegBits_BusMastering0x0007 0x0007
2910#define AscPCICmdRegBits_ParErrRespCtrl0x0040 0x0040
2911
2912#if LINUX_VERSION_CODE131108 < ASC_LINUX_VERSION(1,3,0)(((1) * 65536) + ((3) * 256) + (0))
2913
2914/* Read byte from a register. */
2915#define AdvReadByteRegister(iop_base, reg_off)((*(volatile unsigned char *) ((iop_base) + (reg_off)))) \
2916 (inp((iop_base) + (reg_off))((__builtin_constant_p(((iop_base) + (reg_off))) && (
(iop_base) + (reg_off)) < 256) ? __inbc((iop_base) + (reg_off
)) : __inb((iop_base) + (reg_off)))
)
2917
2918/* Write byte to a register. */
2919#define AdvWriteByteRegister(iop_base, reg_off, byte)(((*(volatile unsigned char *) ((iop_base) + (reg_off))) = ((
byte))))
\
2920 (outp((iop_base) + (reg_off), (byte))((__builtin_constant_p((((iop_base) + (reg_off)))) &&
(((iop_base) + (reg_off))) < 256) ? __outbc((((byte))),((
(iop_base) + (reg_off)))) : __outb((((byte))),(((iop_base) + (
reg_off)))))
)
2921
2922/* Read word (2 bytes) from a register. */
2923#define AdvReadWordRegister(iop_base, reg_off)((*(volatile unsigned short *) ((iop_base) + (reg_off)))) \
2924 (inpw((iop_base) + (reg_off))((__builtin_constant_p(((iop_base) + (reg_off))) && (
(iop_base) + (reg_off)) < 256) ? __inwc((iop_base) + (reg_off
)) : __inw((iop_base) + (reg_off)))
)
2925
2926/* Write word (2 bytes) to a register. */
2927#define AdvWriteWordRegister(iop_base, reg_off, word)(((*(volatile unsigned short *) ((iop_base) + (reg_off))) = (
(word))))
\
2928 (outpw((iop_base) + (reg_off), (word))((__builtin_constant_p((((iop_base) + (reg_off)))) &&
(((iop_base) + (reg_off))) < 256) ? __outwc((((word))),((
(iop_base) + (reg_off)))) : __outw((((word))),(((iop_base) + (
reg_off)))))
)
2929
2930/* Read byte from LRAM. */
2931#define AdvReadByteLram(iop_base, addr, byte)do { ((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((
addr))); (byte) = (*(volatile unsigned char *) ((iop_base) + 0x06
)); } while (0)
\
2932do { \
2933 outpw((iop_base) + IOPW_RAM_ADDR, (addr))((__builtin_constant_p((((iop_base) + 0x04))) && (((iop_base
) + 0x04)) < 256) ? __outwc((((addr))),(((iop_base) + 0x04
))) : __outw((((addr))),(((iop_base) + 0x04))))
; \
2934 (byte) = inp((iop_base) + IOPB_RAM_DATA)((__builtin_constant_p(((iop_base) + 0x06)) && ((iop_base
) + 0x06) < 256) ? __inbc((iop_base) + 0x06) : __inb((iop_base
) + 0x06))
; \
2935} while (0)
2936
2937/* Write byte to LRAM. */
2938#define AdvWriteByteLram(iop_base, addr, byte)(((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((addr
))), ((*(volatile unsigned char *) ((iop_base) + 0x06)) = ((byte
))))
\
2939 (outpw((iop_base) + IOPW_RAM_ADDR, (addr))((__builtin_constant_p((((iop_base) + 0x04))) && (((iop_base
) + 0x04)) < 256) ? __outwc((((addr))),(((iop_base) + 0x04
))) : __outw((((addr))),(((iop_base) + 0x04))))
, \
2940 outp((iop_base) + IOPB_RAM_DATA, (byte))((__builtin_constant_p((((iop_base) + 0x06))) && (((iop_base
) + 0x06)) < 256) ? __outbc((((byte))),(((iop_base) + 0x06
))) : __outb((((byte))),(((iop_base) + 0x06))))
)
2941
2942/* Read word (2 bytes) from LRAM. */
2943#define AdvReadWordLram(iop_base, addr, word)do { ((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((
addr))); (word) = (*(volatile unsigned short *) ((iop_base) +
0x06)); } while (0)
\
2944do { \
2945 outpw((iop_base) + IOPW_RAM_ADDR, (addr))((__builtin_constant_p((((iop_base) + 0x04))) && (((iop_base
) + 0x04)) < 256) ? __outwc((((addr))),(((iop_base) + 0x04
))) : __outw((((addr))),(((iop_base) + 0x04))))
; \
2946 (word) = inpw((iop_base) + IOPW_RAM_DATA)((__builtin_constant_p(((iop_base) + 0x06)) && ((iop_base
) + 0x06) < 256) ? __inwc((iop_base) + 0x06) : __inw((iop_base
) + 0x06))
; \
2947} while (0)
2948
2949/* Write word (2 bytes) to LRAM. */
2950#define AdvWriteWordLram(iop_base, addr, word)(((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((addr
))), ((*(volatile unsigned short *) ((iop_base) + 0x06)) = ((
word))))
\
2951 (outpw((iop_base) + IOPW_RAM_ADDR, (addr))((__builtin_constant_p((((iop_base) + 0x04))) && (((iop_base
) + 0x04)) < 256) ? __outwc((((addr))),(((iop_base) + 0x04
))) : __outw((((addr))),(((iop_base) + 0x04))))
, \
2952 outpw((iop_base) + IOPW_RAM_DATA, (word))((__builtin_constant_p((((iop_base) + 0x06))) && (((iop_base
) + 0x06)) < 256) ? __outwc((((word))),(((iop_base) + 0x06
))) : __outw((((word))),(((iop_base) + 0x06))))
)
2953
2954/* Write double word (4 bytes) to LRAM */
2955/* Because of unspecified C language ordering don't use auto-increment. */
2956#define AdvWriteDWordLram(iop_base, addr, dword)((((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((addr
))), ((*(volatile unsigned short *) ((iop_base) + 0x06)) = ((
ushort) ((dword) & 0xFFFF)))), (((*(volatile unsigned short
*) ((iop_base) + 0x04)) = ((addr) + 2)), ((*(volatile unsigned
short *) ((iop_base) + 0x06)) = ((ushort) ((dword >> 16
) & 0xFFFF)))))
\
2957 ((outpw((iop_base) + IOPW_RAM_ADDR, (addr))((__builtin_constant_p((((iop_base) + 0x04))) && (((iop_base
) + 0x04)) < 256) ? __outwc((((addr))),(((iop_base) + 0x04
))) : __outw((((addr))),(((iop_base) + 0x04))))
, \
2958 outpw((iop_base) + IOPW_RAM_DATA, (ushort) ((dword) & 0xFFFF))((__builtin_constant_p((((iop_base) + 0x06))) && (((iop_base
) + 0x06)) < 256) ? __outwc((((ushort) ((dword) & 0xFFFF
))),(((iop_base) + 0x06))) : __outw((((ushort) ((dword) &
0xFFFF))),(((iop_base) + 0x06))))
), \
2959 (outpw((iop_base) + IOPW_RAM_ADDR, (addr) + 2)((__builtin_constant_p((((iop_base) + 0x04))) && (((iop_base
) + 0x04)) < 256) ? __outwc((((addr) + 2)),(((iop_base) + 0x04
))) : __outw((((addr) + 2)),(((iop_base) + 0x04))))
, \
2960 outpw((iop_base) + IOPW_RAM_DATA, (ushort) ((dword >> 16) & 0xFFFF))((__builtin_constant_p((((iop_base) + 0x06))) && (((iop_base
) + 0x06)) < 256) ? __outwc((((ushort) ((dword >> 16
) & 0xFFFF))),(((iop_base) + 0x06))) : __outw((((ushort) (
(dword >> 16) & 0xFFFF))),(((iop_base) + 0x06))))
))
2961
2962/* Read word (2 bytes) from LRAM assuming that the address is already set. */
2963#define AdvReadWordAutoIncLram(iop_base)((*(volatile unsigned short *) ((iop_base) + 0x06))) \
2964 (inpw((iop_base) + IOPW_RAM_DATA)((__builtin_constant_p(((iop_base) + 0x06)) && ((iop_base
) + 0x06) < 256) ? __inwc((iop_base) + 0x06) : __inw((iop_base
) + 0x06))
)
2965
2966/* Write word (2 bytes) to LRAM assuming that the address is already set. */
2967#define AdvWriteWordAutoIncLram(iop_base, word)(((*(volatile unsigned short *) ((iop_base) + 0x06)) = ((word
))))
\
2968 (outpw((iop_base) + IOPW_RAM_DATA, (word))((__builtin_constant_p((((iop_base) + 0x06))) && (((iop_base
) + 0x06)) < 256) ? __outwc((((word))),(((iop_base) + 0x06
))) : __outw((((word))),(((iop_base) + 0x06))))
)
2969
2970#else /* version >= v1,3,0 */
2971
2972/* Read byte from a register. */
2973#define AdvReadByteRegister(iop_base, reg_off)((*(volatile unsigned char *) ((iop_base) + (reg_off)))) \
2974 (ADV_MEM_READB((iop_base) + (reg_off))(*(volatile unsigned char *) ((iop_base) + (reg_off))))
2975
2976/* Write byte to a register. */
2977#define AdvWriteByteRegister(iop_base, reg_off, byte)(((*(volatile unsigned char *) ((iop_base) + (reg_off))) = ((
byte))))
\
2978 (ADV_MEM_WRITEB((iop_base) + (reg_off), (byte))((*(volatile unsigned char *) ((iop_base) + (reg_off))) = ((byte
)))
)
2979
2980/* Read word (2 bytes) from a register. */
2981#define AdvReadWordRegister(iop_base, reg_off)((*(volatile unsigned short *) ((iop_base) + (reg_off)))) \
2982 (ADV_MEM_READW((iop_base) + (reg_off))(*(volatile unsigned short *) ((iop_base) + (reg_off))))
2983
2984/* Write word (2 bytes) to a register. */
2985#define AdvWriteWordRegister(iop_base, reg_off, word)(((*(volatile unsigned short *) ((iop_base) + (reg_off))) = (
(word))))
\
2986 (ADV_MEM_WRITEW((iop_base) + (reg_off), (word))((*(volatile unsigned short *) ((iop_base) + (reg_off))) = ((
word)))
)
2987
2988/* Read byte from LRAM. */
2989#define AdvReadByteLram(iop_base, addr, byte)do { ((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((
addr))); (byte) = (*(volatile unsigned char *) ((iop_base) + 0x06
)); } while (0)
\
2990do { \
2991 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr))((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((addr)
))
; \
2992 (byte) = ADV_MEM_READB((iop_base) + IOPB_RAM_DATA)(*(volatile unsigned char *) ((iop_base) + 0x06)); \
2993} while (0)
2994
2995/* Write byte to LRAM. */
2996#define AdvWriteByteLram(iop_base, addr, byte)(((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((addr
))), ((*(volatile unsigned char *) ((iop_base) + 0x06)) = ((byte
))))
\
2997 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr))((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((addr)
))
, \
2998 ADV_MEM_WRITEB((iop_base) + IOPB_RAM_DATA, (byte))((*(volatile unsigned char *) ((iop_base) + 0x06)) = ((byte))
)
)
2999
3000/* Read word (2 bytes) from LRAM. */
3001#define AdvReadWordLram(iop_base, addr, word)do { ((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((
addr))); (word) = (*(volatile unsigned short *) ((iop_base) +
0x06)); } while (0)
\
3002do { \
3003 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr))((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((addr)
))
; \
3004 (word) = ADV_MEM_READW((iop_base) + IOPW_RAM_DATA)(*(volatile unsigned short *) ((iop_base) + 0x06)); \
3005} while (0)
3006
3007/* Write word (2 bytes) to LRAM. */
3008#define AdvWriteWordLram(iop_base, addr, word)(((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((addr
))), ((*(volatile unsigned short *) ((iop_base) + 0x06)) = ((
word))))
\
3009 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr))((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((addr)
))
, \
3010 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word))((*(volatile unsigned short *) ((iop_base) + 0x06)) = ((word)
))
)
3011
3012/* Write double word (4 bytes) to LRAM */
3013/* Because of unspecified C language ordering don't use auto-increment. */
3014#define AdvWriteDWordLram(iop_base, addr, dword)((((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((addr
))), ((*(volatile unsigned short *) ((iop_base) + 0x06)) = ((
ushort) ((dword) & 0xFFFF)))), (((*(volatile unsigned short
*) ((iop_base) + 0x04)) = ((addr) + 2)), ((*(volatile unsigned
short *) ((iop_base) + 0x06)) = ((ushort) ((dword >> 16
) & 0xFFFF)))))
\
3015 ((ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr))((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((addr)
))
, \
3016 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \((*(volatile unsigned short *) ((iop_base) + 0x06)) = ((ushort
) ((dword) & 0xFFFF)))
3017 (ushort) ((dword) & 0xFFFF))((*(volatile unsigned short *) ((iop_base) + 0x06)) = ((ushort
) ((dword) & 0xFFFF)))
), \
3018 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr) + 2)((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((addr)
+ 2))
, \
3019 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \((*(volatile unsigned short *) ((iop_base) + 0x06)) = ((ushort
) ((dword >> 16) & 0xFFFF)))
3020 (ushort) ((dword >> 16) & 0xFFFF))((*(volatile unsigned short *) ((iop_base) + 0x06)) = ((ushort
) ((dword >> 16) & 0xFFFF)))
))
3021
3022/* Read word (2 bytes) from LRAM assuming that the address is already set. */
3023#define AdvReadWordAutoIncLram(iop_base)((*(volatile unsigned short *) ((iop_base) + 0x06))) \
3024 (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA)(*(volatile unsigned short *) ((iop_base) + 0x06)))
3025
3026/* Write word (2 bytes) to LRAM assuming that the address is already set. */
3027#define AdvWriteWordAutoIncLram(iop_base, word)(((*(volatile unsigned short *) ((iop_base) + 0x06)) = ((word
))))
\
3028 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word))((*(volatile unsigned short *) ((iop_base) + 0x06)) = ((word)
))
)
3029
3030#endif /* version >= v1,3,0 */
3031
3032/*
3033 * Define macro to check for Condor signature.
3034 *
3035 * Evaluate to ADV_TRUE if a Condor chip is found the specified port
3036 * address 'iop_base'. Otherwise evalue to ADV_FALSE.
3037 */
3038#define AdvFindSignature(iop_base)(((((*(volatile unsigned char *) (((iop_base)) + (0x01)))) ==
0x25) && (((*(volatile unsigned short *) (((iop_base
)) + (0x00)))) == 0x04C1)) ? 1 : 0)
\
3039 (((AdvReadByteRegister((iop_base), IOPB_CHIP_ID_1)((*(volatile unsigned char *) (((iop_base)) + (0x01)))) == \
3040 ADV_CHIP_ID_BYTE0x25) && \
3041 (AdvReadWordRegister((iop_base), IOPW_CHIP_ID_0)((*(volatile unsigned short *) (((iop_base)) + (0x00)))) == \
3042 ADV_CHIP_ID_WORD0x04C1)) ? ADV_TRUE1 : ADV_FALSE0)
3043
3044/*
3045 * Define macro to Return the version number of the chip at 'iop_base'.
3046 *
3047 * The second parameter 'bus_type' is currently unused.
3048 */
3049#define AdvGetChipVersion(iop_base, bus_type)((*(volatile unsigned char *) (((iop_base)) + (0x03)))) \
3050 AdvReadByteRegister((iop_base), IOPB_CHIP_TYPE_REV)((*(volatile unsigned char *) (((iop_base)) + (0x03))))
3051
3052/*
3053 * Abort an SRB in the chip's RISC Memory. The 'srb_ptr' argument must
3054 * match the ASC_SCSI_REQ_Q 'srb_ptr' field.
3055 *
3056 * If the request has not yet been sent to the device it will simply be
3057 * aborted from RISC memory. If the request is disconnected it will be
3058 * aborted on reselection by sending an Abort Message to the target ID.
3059 *
3060 * Return value:
3061 * ADV_TRUE(1) - Queue was successfully aborted.
3062 * ADV_FALSE(0) - Queue was not found on the active queue list.
3063 */
3064#define AdvAbortSRB(asc_dvc, srb_ptr)AdvSendIdleCmd((asc_dvc), (ushort) 0x0008, (ulong) (srb_ptr),
0)
\
3065 AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_ABORT0x0008, \
3066 (ulong) (srb_ptr), 0)
3067
3068/*
3069 * Send a Bus Device Reset Message to the specified target ID.
3070 *
3071 * All outstanding commands will be purged if sending the
3072 * Bus Device Reset Message is successful.
3073 *
3074 * Return Value:
3075 * ADV_TRUE(1) - All requests on the target are purged.
3076 * ADV_FALSE(0) - Couldn't issue Bus Device Reset Message; Requests
3077 * are not purged.
3078 */
3079#define AdvResetDevice(asc_dvc, target_id)AdvSendIdleCmd((asc_dvc), (ushort) 0x0010, (ulong) (target_id
), 0)
\
3080 AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_DEVICE_RESET0x0010, \
3081 (ulong) (target_id), 0)
3082
3083/*
3084 * SCSI Wide Type definition.
3085 */
3086#define ADV_SCSI_BIT_ID_TYPEushort ushort
3087
3088/*
3089 * AdvInitScsiTarget() 'cntl_flag' options.
3090 */
3091#define ADV_SCAN_LUN0x01 0x01
3092#define ADV_CAPINFO_NOLUN0x02 0x02
3093
3094/*
3095 * Convert target id to target id bit mask.
3096 */
3097#define ADV_TID_TO_TIDMASK(tid)(0x01 << ((tid) & 15)) (0x01 << ((tid) & ADV_MAX_TID15))
3098
3099/*
3100 * ASC_SCSI_REQ_Q 'done_status' and 'host_status' return values.
3101 */
3102
3103#define QD_NO_STATUS0x00 0x00 /* Request not completed yet. */
3104#define QD_NO_ERROR0x01 0x01
3105#define QD_ABORTED_BY_HOST0x02 0x02
3106#define QD_WITH_ERROR0x04 0x04
3107
3108#define QHSTA_NO_ERROR0x00 0x00
3109#define QHSTA_M_SEL_TIMEOUT0x11 0x11
3110#define QHSTA_M_DATA_OVER_RUN0x12 0x12
3111#define QHSTA_M_UNEXPECTED_BUS_FREE0x13 0x13
3112#define QHSTA_M_QUEUE_ABORTED0x15 0x15
3113#define QHSTA_M_SXFR_SDMA_ERR0x16 0x16 /* SXFR_STATUS SCSI DMA Error */
3114#define QHSTA_M_SXFR_SXFR_PERR0x17 0x17 /* SXFR_STATUS SCSI Bus Parity Error */
3115#define QHSTA_M_RDMA_PERR0x18 0x18 /* RISC PCI DMA parity error */
3116#define QHSTA_M_SXFR_OFF_UFLW0x19 0x19 /* SXFR_STATUS Offset Underflow */
3117#define QHSTA_M_SXFR_OFF_OFLW0x20 0x20 /* SXFR_STATUS Offset Overflow */
3118#define QHSTA_M_SXFR_WD_TMO0x21 0x21 /* SXFR_STATUS Watchdog Timeout */
3119#define QHSTA_M_SXFR_DESELECTED0x22 0x22 /* SXFR_STATUS Deselected */
3120/* Note: QHSTA_M_SXFR_XFR_OFLW is identical to QHSTA_M_DATA_OVER_RUN. */
3121#define QHSTA_M_SXFR_XFR_OFLW0x12 0x12 /* SXFR_STATUS Transfer Overflow */
3122#define QHSTA_M_SXFR_XFR_PH_ERR0x24 0x24 /* SXFR_STATUS Transfer Phase Error */
3123#define QHSTA_M_SXFR_UNKNOWN_ERROR0x25 0x25 /* SXFR_STATUS Unknown Error */
3124#define QHSTA_M_WTM_TIMEOUT0x41 0x41
3125#define QHSTA_M_BAD_CMPL_STATUS_IN0x42 0x42
3126#define QHSTA_M_NO_AUTO_REQ_SENSE0x43 0x43
3127#define QHSTA_M_AUTO_REQ_SENSE_FAIL0x44 0x44
3128#define QHSTA_M_INVALID_DEVICE0x45 0x45 /* Bad target ID */
3129
3130typedef int (* ADV_ISR_CALLBACK)
3131 (ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
3132
3133typedef int (* ADV_SBRESET_CALLBACK)
3134 (ADV_DVC_VAR *);
3135
3136/*
3137 * Default EEPROM Configuration structure defined in a_init.c.
3138 */
3139STATICstatic ADVEEP_CONFIG Default_EEPROM_Config;
3140
3141/*
3142 * DvcGetPhyAddr() flag arguments
3143 */
3144#define ADV_IS_SCSIQ_FLAG0x01 0x01 /* 'addr' is ASC_SCSI_REQ_Q pointer */
3145#define ADV_ASCGETSGLIST_VADDR0x02 0x02 /* 'addr' is AscGetSGList() virtual addr */
3146#define ADV_IS_SENSE_FLAG0x04 0x04 /* 'addr' is sense virtual pointer */
3147#define ADV_IS_DATA_FLAG0x08 0x08 /* 'addr' is data virtual pointer */
3148#define ADV_IS_SGLIST_FLAG0x10 0x10 /* 'addr' is sglist virtual pointer */
3149
3150/* Return the address that is aligned at the next doubleword >= to 'addr'. */
3151#define ADV_DWALIGN(addr)(((ulong) (addr) + 0x3) & ~0x3) (((ulong) (addr) + 0x3) & ~0x3)
3152
3153/*
3154 * Total contiguous memory needed for driver SG blocks.
3155 *
3156 * ADV_MAX_SG_LIST must be defined by a driver. It is the maximum
3157 * number of scatter-gather elements the driver supports in a
3158 * single request.
3159 */
3160
3161#ifndef ADV_MAX_SG_LIST64
3162Forced Error: Driver must define ADV_MAX_SG_LIST64.
3163#endif /* ADV_MAX_SG_LIST */
3164
3165#define ADV_SG_LIST_MAX_BYTE_SIZE(sizeof(ADV_SG_BLOCK) * ((64 + (15 - 1))/15)) \
3166 (sizeof(ADV_SG_BLOCK) * \
3167 ((ADV_MAX_SG_LIST64 + (NO_OF_SG_PER_BLOCK15 - 1))/NO_OF_SG_PER_BLOCK15))
3168
3169/*
3170 * A driver may optionally define the assertion macro ADV_ASSERT() in
3171 * its d_os_dep.h file. If the macro has not already been defined,
3172 * then define the macro to a no-op.
3173 */
3174#ifndef ADV_ASSERT
3175#define ADV_ASSERT(a){ if (!(a)) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 3175); } }
3176#endif /* ADV_ASSERT */
3177
3178
3179/*
3180 * --- Driver Constants and Macros
3181 */
3182
3183#define ASC_NUM_BOARD_SUPPORTED16 16
3184#define ASC_NUM_IOPORT_PROBE4 4
3185#define ASC_NUM_BUS4 4
3186
3187/* Reference Scsi_Host hostdata */
3188#define ASC_BOARDP(host)((asc_board_t *) &((host)->hostdata)) ((asc_board_t *) &((host)->hostdata))
3189
3190/* asc_board_t flags */
3191#define ASC_HOST_IN_RESET0x01 0x01
3192#define ASC_HOST_IN_ABORT0x02 0x02
3193#define ASC_IS_WIDE_BOARD0x04 0x04 /* AdvanSys Wide Board */
3194#define ASC_SELECT_QUEUE_DEPTHS0x08 0x08
3195
3196#define ASC_NARROW_BOARD(boardp)(((boardp)->flags & 0x04) == 0) (((boardp)->flags & ASC_IS_WIDE_BOARD0x04) == 0)
3197#define ASC_WIDE_BOARD(boardp)((boardp)->flags & 0x04) ((boardp)->flags & ASC_IS_WIDE_BOARD0x04)
3198
3199#define NO_ISA_DMA0xff 0xff /* No ISA DMA Channel Used */
3200
3201/*
3202 * If the Linux kernel version supports freeing initialization code
3203 * and data after loading, define macros for this purpose. These macros
3204 * are not used when the driver is built as a module, cf. linux/init.h.
3205 */
3206#if LINUX_VERSION_CODE131108 < ASC_LINUX_VERSION(2,1,23)(((2) * 65536) + ((1) * 256) + (23))
3207#define ASC_INITFUNC(func)func func
3208#define ASC_INITDATA
3209#define ASC_INIT
3210#else /* version >= v2.1.23 */
3211#define ASC_INITFUNC(func)func __initfunc(func)
3212#define ASC_INITDATA __initdata
3213#define ASC_INIT __init
3214#endif /* version >= v2.1.23 */
3215
3216#define ASC_INFO_SIZE128 128 /* advansys_info() line size */
3217
3218/* /proc/scsi/advansys/[0...] related definitions */
3219#define ASC_PRTBUF_SIZE2048 2048
3220#define ASC_PRTLINE_SIZE160 160
3221
3222#define ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
\
3223 if (cp) { \
3224 totlen += len; \
3225 leftlen -= len; \
3226 if (leftlen == 0) { \
3227 return totlen; \
3228 } \
3229 cp += len; \
3230 }
3231
3232#define ASC_MIN(a, b)(((a) < (b)) ? (a) : (b)) (((a) < (b)) ? (a) : (b))
3233
3234/* Asc Library return codes */
3235#define ASC_TRUE1 1
3236#define ASC_FALSE0 0
3237#define ASC_NOERROR1 1
3238#define ASC_BUSY0 0
3239#define ASC_ERROR(-1) (-1)
3240
3241/* Scsi_Cmnd function return codes */
3242#define STATUS_BYTE(byte)(byte) (byte)
3243#define MSG_BYTE(byte)((byte) << 8) ((byte) << 8)
3244#define HOST_BYTE(byte)((byte) << 16) ((byte) << 16)
3245#define DRIVER_BYTE(byte)((byte) << 24) ((byte) << 24)
3246
3247/*
3248 * The following definitions and macros are OS independent interfaces to
3249 * the queue functions:
3250 * REQ - SCSI request structure
3251 * REQP - pointer to SCSI request structure
3252 * REQPTID(reqp) - reqp's target id
3253 * REQPNEXT(reqp) - reqp's next pointer
3254 * REQPNEXTP(reqp) - pointer to reqp's next pointer
3255 * REQPTIME(reqp) - reqp's time stamp value
3256 * REQTIMESTAMP() - system time stamp value
3257 */
3258typedef Scsi_Cmnd REQ, *REQP;
3259#define REQPNEXT(reqp)((reqp)->host_scribble) ((reqp)->host_scribble)
3260#define REQPNEXTP(reqp)((REQP *) &((reqp)->host_scribble)) ((REQP *) &((reqp)->host_scribble))
3261#define REQPTID(reqp)((reqp)->target) ((reqp)->target)
3262#define REQPTIME(reqp)((reqp)->SCp.this_residual) ((reqp)->SCp.this_residual)
3263#define REQTIMESTAMP()(jiffies) (jiffies)
3264
3265#define REQTIMESTAT(function, ascq, reqp, tid){ if (((reqp)->SCp.this_residual) <= (jiffies)) { ((reqp
)->SCp.this_residual) = (jiffies) - ((reqp)->SCp.this_residual
); } else { { if (!(((reqp)->SCp.this_residual) <= (jiffies
))) { printk("ASC_ASSERT() Failure: file %s, line %d\n", "../linux/src/drivers/scsi/advansys.c"
, 3265); } }; ((reqp)->SCp.this_residual) = 0; } if (((ascq
)->q_tot_cnt[tid] == 1) || (((reqp)->SCp.this_residual)
< (ascq)->q_min_tim[tid])) { (ascq)->q_min_tim[tid]
= ((reqp)->SCp.this_residual); ; } if (((reqp)->SCp.this_residual
) > (ascq)->q_max_tim[tid]) { (ascq)->q_max_tim[tid]
= ((reqp)->SCp.this_residual); ; } (ascq)->q_tot_tim[tid
] += ((reqp)->SCp.this_residual); ((reqp)->SCp.this_residual
) = 0; }
\
3266{ \
3267 /*
3268 * If the request time stamp is less than the system time stamp, then \
3269 * maybe the system time stamp wrapped. Set the request time to zero.\
3270 */ \
3271 if (REQPTIME(reqp)((reqp)->SCp.this_residual) <= REQTIMESTAMP()(jiffies)) { \
3272 REQPTIME(reqp)((reqp)->SCp.this_residual) = REQTIMESTAMP()(jiffies) - REQPTIME(reqp)((reqp)->SCp.this_residual); \
3273 } else { \
3274 /* Indicate an error occurred with the assertion. */ \
3275 ASC_ASSERT(REQPTIME(reqp) <= REQTIMESTAMP()){ if (!(((reqp)->SCp.this_residual) <= (jiffies))) { printk
("ASC_ASSERT() Failure: file %s, line %d\n", "../linux/src/drivers/scsi/advansys.c"
, 3275); } }
; \
3276 REQPTIME(reqp)((reqp)->SCp.this_residual) = 0; \
3277 } \
3278 /* Handle first minimum time case without external initialization. */ \
3279 if (((ascq)->q_tot_cnt[tid] == 1) || \
3280 (REQPTIME(reqp)((reqp)->SCp.this_residual) < (ascq)->q_min_tim[tid])) { \
3281 (ascq)->q_min_tim[tid] = REQPTIME(reqp)((reqp)->SCp.this_residual); \
3282 ASC_DBG3(1, "%s: new q_min_tim[%d] %u\n", \
3283 (function), (tid), (ascq)->q_min_tim[tid]); \
3284 } \
3285 if (REQPTIME(reqp)((reqp)->SCp.this_residual) > (ascq)->q_max_tim[tid]) { \
3286 (ascq)->q_max_tim[tid] = REQPTIME(reqp)((reqp)->SCp.this_residual); \
3287 ASC_DBG3(1, "%s: new q_max_tim[%d] %u\n", \
3288 (function), tid, (ascq)->q_max_tim[tid]); \
3289 } \
3290 (ascq)->q_tot_tim[tid] += REQPTIME(reqp)((reqp)->SCp.this_residual); \
3291 /* Reset the time stamp field. */ \
3292 REQPTIME(reqp)((reqp)->SCp.this_residual) = 0; \
3293}
3294
3295/* asc_enqueue() flags */
3296#define ASC_FRONT1 1
3297#define ASC_BACK2 2
3298
3299/* asc_dequeue_list() argument */
3300#define ASC_TID_ALL(-1) (-1)
3301
3302/* Return non-zero, if the queue is empty. */
3303#define ASC_QUEUE_EMPTY(ascq)((ascq)->q_tidmask == 0) ((ascq)->q_tidmask == 0)
3304
3305/* PCI configuration declarations */
3306
3307#define PCI_BASE_CLASS_PREDEFINED0x00 0x00
3308#define PCI_BASE_CLASS_MASS_STORAGE0x01 0x01
3309#define PCI_BASE_CLASS_NETWORK0x02 0x02
3310#define PCI_BASE_CLASS_DISPLAY0x03 0x03
3311#define PCI_BASE_CLASS_MULTIMEDIA0x04 0x04
3312#define PCI_BASE_CLASS_MEMORY_CONTROLLER0x05 0x05
3313#define PCI_BASE_CLASS_BRIDGE_DEVICE0x06 0x06
3314
3315/* MASS STORAGE */
3316#define PCI_SUB_CLASS_SCSI_CONTROLLER0x00 0x00
3317#define PCI_SUB_CLASS_IDE_CONTROLLER0x01 0x01
3318#define PCI_SUB_CLASS_FLOPPY_DISK_CONTROLLER0x02 0x02
3319#define PCI_SUB_CLASS_IPI_BUS_CONTROLLER0x03 0x03
3320#define PCI_SUB_CLASS_OTHER_MASS_CONTROLLER0x80 0x80
3321
3322/* NETWORK CONTROLLER */
3323#define PCI_SUB_CLASS_ETHERNET_CONTROLLER0x00 0x00
3324#define PCI_SUB_CLASS_TOKEN_RING_CONTROLLER0x01 0x01
3325#define PCI_SUB_CLASS_FDDI_CONTROLLER0x02 0x02
3326#define PCI_SUB_CLASS_OTHER_NETWORK_CONTROLLER0x80 0x80
3327
3328/* DISPLAY CONTROLLER */
3329#define PCI_SUB_CLASS_VGA_CONTROLLER0x00 0x00
3330#define PCI_SUB_CLASS_XGA_CONTROLLER0x01 0x01
3331#define PCI_SUB_CLASS_OTHER_DISPLAY_CONTROLLER0x80 0x80
3332
3333/* MULTIMEDIA CONTROLLER */
3334#define PCI_SUB_CLASS_VIDEO_DEVICE0x00 0x00
3335#define PCI_SUB_CLASS_AUDIO_DEVICE0x01 0x01
3336#define PCI_SUB_CLASS_OTHER_MULTIMEDIA_DEVICE0x80 0x80
3337
3338/* MEMORY CONTROLLER */
3339#define PCI_SUB_CLASS_RAM_CONTROLLER0x00 0x00
3340#define PCI_SUB_CLASS_FLASH_CONTROLLER0x01 0x01
3341#define PCI_SUB_CLASS_OTHER_MEMORY_CONTROLLER0x80 0x80
3342
3343/* BRIDGE CONTROLLER */
3344#define PCI_SUB_CLASS_HOST_BRIDGE_CONTROLLER0x00 0x00
3345#define PCI_SUB_CLASS_ISA_BRIDGE_CONTROLLER0x01 0x01
3346#define PCI_SUB_CLASS_EISA_BRIDGE_CONTROLLER0x02 0x02
3347#define PCI_SUB_CLASS_MC_BRIDGE_CONTROLLER0x03 0x03
3348#define PCI_SUB_CLASS_PCI_TO_PCI_BRIDGE_CONTROLLER0x04 0x04
3349#define PCI_SUB_CLASS_PCMCIA_BRIDGE_CONTROLLER0x05 0x05
3350#define PCI_SUB_CLASS_OTHER_BRIDGE_CONTROLLER0x80 0x80
3351
3352#define PCI_MAX_SLOT0x1F 0x1F
3353#define PCI_MAX_BUS0xFF 0xFF
3354#define PCI_IOADDRESS_MASK0xFFFE 0xFFFE
3355#define ASC_PCI_VENDORID0x10CD 0x10CD
3356#define ASC_PCI_DEVICE_ID_CNT4 4 /* PCI Device ID count. */
3357#define ASC_PCI_DEVICE_ID_11000x1100 0x1100
3358#define ASC_PCI_DEVICE_ID_12000x1200 0x1200
3359#define ASC_PCI_DEVICE_ID_13000x1300 0x1300
3360#define ASC_PCI_DEVICE_ID_23000x2300 0x2300
3361
3362/* PCI IO Port Addresses to generate special cycle */
3363
3364#define PCI_CONFIG_ADDRESS_MECH10x0CF8 0x0CF8
3365#define PCI_CONFIG_DATA_MECH10x0CFC 0x0CFC
3366
3367#define PCI_CONFIG_FORWARD_REGISTER0x0CFA 0x0CFA /* 0=type 0; 1=type 1; */
3368
3369#define PCI_CONFIG_BUS_NUMBER_MASK0x00FF0000 0x00FF0000
3370#define PCI_CONFIG_DEVICE_FUNCTION_MASK0x0000FF00 0x0000FF00
3371#define PCI_CONFIG_REGISTER_NUMBER_MASK0x000000F8 0x000000F8
3372
3373#define PCI_DEVICE_FOUND0x0000 0x0000
3374#define PCI_DEVICE_NOT_FOUND0xffff 0xffff
3375
3376#define SUBCLASS_OFFSET0x0A 0x0A
3377#define CLASSCODE_OFFSET0x0B 0x0B
3378#define VENDORID_OFFSET0x00 0x00
3379#define DEVICEID_OFFSET0x02 0x02
3380
3381#ifndef ADVANSYS_STATS
3382#define ASC_STATS(shp, counter)(((asc_board_t *) &((shp)->hostdata))->asc_stats.counter
++)
3383#define ASC_STATS_ADD(shp, counter, count)(((asc_board_t *) &((shp)->hostdata))->asc_stats.counter
+= (count))
3384#else /* ADVANSYS_STATS */
3385#define ASC_STATS(shp, counter)(((asc_board_t *) &((shp)->hostdata))->asc_stats.counter
++)
\
3386 (ASC_BOARDP(shp)((asc_board_t *) &((shp)->hostdata))->asc_stats.counter++)
3387
3388#define ASC_STATS_ADD(shp, counter, count)(((asc_board_t *) &((shp)->hostdata))->asc_stats.counter
+= (count))
\
3389 (ASC_BOARDP(shp)((asc_board_t *) &((shp)->hostdata))->asc_stats.counter += (count))
3390#endif /* ADVANSYS_STATS */
3391
3392#define ASC_CEILING(val, unit)(((val) + ((unit) - 1))/(unit)) (((val) + ((unit) - 1))/(unit))
3393
3394/* If the result wraps when calculating tenths, return 0. */
3395#define ASC_TENTHS(num, den)(((10 * ((num)/(den))) > (((num) * 10)/(den))) ? 0 : ((((num
) * 10)/(den)) - (10 * ((num)/(den)))))
\
3396 (((10 * ((num)/(den))) > (((num) * 10)/(den))) ? \
3397 0 : ((((num) * 10)/(den)) - (10 * ((num)/(den)))))
3398
3399/*
3400 * Display a message to the console.
3401 */
3402#define ASC_PRINT(s){ printk("advansys: "); printk(s); } \
3403 { \
3404 printk("advansys: "); \
3405 printk(s); \
3406 }
3407
3408#define ASC_PRINT1(s, a1){ printk("advansys: "); printk((s), (a1)); } \
3409 { \
3410 printk("advansys: "); \
3411 printk((s), (a1)); \
3412 }
3413
3414#define ASC_PRINT2(s, a1, a2){ printk("advansys: "); printk((s), (a1), (a2)); } \
3415 { \
3416 printk("advansys: "); \
3417 printk((s), (a1), (a2)); \
3418 }
3419
3420#define ASC_PRINT3(s, a1, a2, a3){ printk("advansys: "); printk((s), (a1), (a2), (a3)); } \
3421 { \
3422 printk("advansys: "); \
3423 printk((s), (a1), (a2), (a3)); \
3424 }
3425
3426#define ASC_PRINT4(s, a1, a2, a3, a4){ printk("advansys: "); printk((s), (a1), (a2), (a3), (a4)); } \
3427 { \
3428 printk("advansys: "); \
3429 printk((s), (a1), (a2), (a3), (a4)); \
3430 }
3431
3432
3433#ifndef ADVANSYS_DEBUG
3434
3435#define ASC_DBG(lvl, s)
3436#define ASC_DBG1(lvl, s, a1)
3437#define ASC_DBG2(lvl, s, a1, a2)
3438#define ASC_DBG3(lvl, s, a1, a2, a3)
3439#define ASC_DBG4(lvl, s, a1, a2, a3, a4)
3440#define ASC_DBG_PRT_SCSI_HOST(lvl, s)
3441#define ASC_DBG_PRT_SCSI_CMND(lvl, s)
3442#define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp)
3443#define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
3444#define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone)
3445#define ADV_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
3446#define ASC_DBG_PRT_HEX(lvl, name, start, length)
3447#define ASC_DBG_PRT_CDB(lvl, cdb, len)
3448#define ASC_DBG_PRT_SENSE(lvl, sense, len)
3449#define ASC_DBG_PRT_INQUIRY(lvl, inq, len)
3450
3451#else /* ADVANSYS_DEBUG */
3452
3453/*
3454 * Debugging Message Levels:
3455 * 0: Errors Only
3456 * 1: High-Level Tracing
3457 * 2-N: Verbose Tracing
3458 */
3459
3460#define ASC_DBG(lvl, s) \
3461 { \
3462 if (asc_dbglvl >= (lvl)) { \
3463 printk(s); \
3464 } \
3465 }
3466
3467#define ASC_DBG1(lvl, s, a1) \
3468 { \
3469 if (asc_dbglvl >= (lvl)) { \
3470 printk((s), (a1)); \
3471 } \
3472 }
3473
3474#define ASC_DBG2(lvl, s, a1, a2) \
3475 { \
3476 if (asc_dbglvl >= (lvl)) { \
3477 printk((s), (a1), (a2)); \
3478 } \
3479 }
3480
3481#define ASC_DBG3(lvl, s, a1, a2, a3) \
3482 { \
3483 if (asc_dbglvl >= (lvl)) { \
3484 printk((s), (a1), (a2), (a3)); \
3485 } \
3486 }
3487
3488#define ASC_DBG4(lvl, s, a1, a2, a3, a4) \
3489 { \
3490 if (asc_dbglvl >= (lvl)) { \
3491 printk((s), (a1), (a2), (a3), (a4)); \
3492 } \
3493 }
3494
3495#define ASC_DBG_PRT_SCSI_HOST(lvl, s) \
3496 { \
3497 if (asc_dbglvl >= (lvl)) { \
3498 asc_prt_scsi_host(s); \
3499 } \
3500 }
3501
3502#define ASC_DBG_PRT_SCSI_CMND(lvl, s) \
3503 { \
3504 if (asc_dbglvl >= (lvl)) { \
3505 asc_prt_scsi_cmnd(s); \
3506 } \
3507 }
3508
3509#define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp) \
3510 { \
3511 if (asc_dbglvl >= (lvl)) { \
3512 asc_prt_asc_scsi_q(scsiqp); \
3513 } \
3514 }
3515
3516#define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone) \
3517 { \
3518 if (asc_dbglvl >= (lvl)) { \
3519 asc_prt_asc_qdone_info(qdone); \
3520 } \
3521 }
3522
3523#define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp) \
3524 { \
3525 if (asc_dbglvl >= (lvl)) { \
3526 asc_prt_adv_scsi_req_q(scsiqp); \
3527 } \
3528 }
3529
3530#define ASC_DBG_PRT_HEX(lvl, name, start, length) \
3531 { \
3532 if (asc_dbglvl >= (lvl)) { \
3533 asc_prt_hex((name), (start), (length)); \
3534 } \
3535 }
3536
3537#define ASC_DBG_PRT_CDB(lvl, cdb, len) \
3538 ASC_DBG_PRT_HEX((lvl), "CDB", (uchar *) (cdb), (len));
3539
3540#define ASC_DBG_PRT_SENSE(lvl, sense, len) \
3541 ASC_DBG_PRT_HEX((lvl), "SENSE", (uchar *) (sense), (len));
3542
3543#define ASC_DBG_PRT_INQUIRY(lvl, inq, len) \
3544 ASC_DBG_PRT_HEX((lvl), "INQUIRY", (uchar *) (inq), (len));
3545#endif /* ADVANSYS_DEBUG */
3546
3547#ifndef ADVANSYS_ASSERT
3548#define ASC_ASSERT(a){ if (!(a)) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 3548); } }
3549#else /* ADVANSYS_ASSERT */
3550
3551#define ASC_ASSERT(a){ if (!(a)) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 3551); } }
\
3552 { \
3553 if (!(a)) { \
3554 printk("ASC_ASSERT() Failure: file %s, line %d\n", \
3555 __FILE__"../linux/src/drivers/scsi/advansys.c", __LINE__3555); \
3556 } \
3557 }
3558
3559#endif /* ADVANSYS_ASSERT */
3560
3561
3562/*
3563 * --- Driver Structures
3564 */
3565
3566#ifdef ADVANSYS_STATS
3567
3568/* Per board statistics structure */
3569struct asc_stats {
3570 /* Driver Entrypoint Statistics */
3571 ulong command; /* # calls to advansys_command() */
3572 ulong queuecommand; /* # calls to advansys_queuecommand() */
3573 ulong abort; /* # calls to advansys_abort() */
3574 ulong reset; /* # calls to advansys_reset() */
3575 ulong biosparam; /* # calls to advansys_biosparam() */
3576 ulong interrupt; /* # advansys_interrupt() calls */
3577 ulong callback; /* # calls to asc/adv_isr_callback() */
3578 ulong done; /* # calls to request's scsi_done function */
3579 ulong build_error; /* # asc/adv_build_req() ASC_ERROR returns. */
3580 ulong adv_build_noreq; /* # adv_build_req() adv_req_t alloc. fail. */
3581 ulong adv_build_nosg; /* # adv_build_req() adv_sgblk_t alloc. fail. */
3582 /* AscExeScsiQueue()/AdvExeScsiQueue() Statistics */
3583 ulong exe_noerror; /* # ASC_NOERROR returns. */
3584 ulong exe_busy; /* # ASC_BUSY returns. */
3585 ulong exe_error; /* # ASC_ERROR returns. */
3586 ulong exe_unknown; /* # unknown returns. */
3587 /* Data Transfer Statistics */
3588 ulong cont_cnt; /* # non-scatter-gather I/O requests received */
3589 ulong cont_xfer; /* # contiguous transfer 512-bytes */
3590 ulong sg_cnt; /* # scatter-gather I/O requests received */
3591 ulong sg_elem; /* # scatter-gather elements */
3592 ulong sg_xfer; /* # scatter-gather transfer 512-bytes */
3593};
3594#endif /* ADVANSYS_STATS */
3595
3596/*
3597 * Request queuing structure
3598 */
3599typedef struct asc_queue {
3600 ADV_SCSI_BIT_ID_TYPEushort q_tidmask; /* queue mask */
3601 REQP q_first[ADV_MAX_TID15+1]; /* first queued request */
3602 REQP q_last[ADV_MAX_TID15+1]; /* last queued request */
3603#ifdef ADVANSYS_STATS
3604 short q_cur_cnt[ADV_MAX_TID15+1]; /* current queue count */
3605 short q_max_cnt[ADV_MAX_TID15+1]; /* maximum queue count */
3606 ulong q_tot_cnt[ADV_MAX_TID15+1]; /* total enqueue count */
3607 ulong q_tot_tim[ADV_MAX_TID15+1]; /* total time queued */
3608 ushort q_max_tim[ADV_MAX_TID15+1]; /* maximum time queued */
3609 ushort q_min_tim[ADV_MAX_TID15+1]; /* minimum time queued */
3610#endif /* ADVANSYS_STATS */
3611} asc_queue_t;
3612
3613/*
3614 * Adv Library Request Structures
3615 *
3616 * The following two se structures are used to process Wide Board requests.
3617 * One structure is needed for each command received from the Mid-Level SCSI
3618 * driver.
3619 *
3620 * The ADV_SCSI_REQ_Q structure in adv_req_t is passed to the Adv Library
3621 * and microcode with the ADV_SCSI_REQ_Q field 'srb_ptr' pointing to the
3622 * adv_req_t. The adv_req_t structure 'cmndp' field in turn points to the
3623 * Mid-Level SCSI request structure.
3624 *
3625 * The adv_sgblk_t structure is used to handle requests that include
3626 * scatter-gather elements.
3627 */
3628typedef struct adv_sgblk {
3629 ADV_SG_BLOCK sg_block[ADV_NUM_SG_BLOCK((64 + (15 - 1))/15) + ADV_NUM_PAGE_CROSSING(((sizeof(ADV_SG_BLOCK) * ((64 + (15 - 1))/15)) + ((1 <<
12) - 1))/(1 << 12))
];
3630 uchar align2[4]; /* Sgblock structure padding. */
3631 struct adv_sgblk *next_sgblkp; /* Next scatter-gather structure. */
3632} adv_sgblk_t;
3633
3634typedef struct adv_req {
3635 ADV_SCSI_REQ_Q scsi_req_q; /* Adv Library request structure. */
3636 uchar align1[4]; /* Request structure padding. */
3637 Scsi_Cmnd *cmndp; /* Mid-Level SCSI command pointer. */
3638 adv_sgblk_t *sgblkp; /* Adv Library scatter-gather pointer. */
3639 struct adv_req *next_reqp; /* Next Request Structure. */
3640} adv_req_t;
3641
3642/*
3643 * Structure allocated for each board.
3644 *
3645 * This structure is allocated by scsi_register() at the end
3646 * of the 'Scsi_Host' structure starting at the 'hostdata'
3647 * field. It is guaranteed to be allocated from DMA-able memory.
3648 */
3649typedef struct asc_board {
3650 int id; /* Board Id */
3651 uint flags; /* Board flags */
3652 union {
3653 ASC_DVC_VAR asc_dvc_var; /* Narrow board */
3654 ADV_DVC_VAR adv_dvc_var; /* Wide board */
3655 } dvc_var;
3656 union {
3657 ASC_DVC_CFG asc_dvc_cfg; /* Narrow board */
3658 ADV_DVC_CFG adv_dvc_cfg; /* Wide board */
3659 } dvc_cfg;
3660 asc_queue_t active; /* Active command queue */
3661 asc_queue_t waiting; /* Waiting command queue */
3662 asc_queue_t done; /* Done command queue */
3663 ADV_SCSI_BIT_ID_TYPEushort init_tidmask; /* Target init./valid mask */
3664 Scsi_Device *device[ADV_MAX_TID15+1]; /* Mid-Level Scsi Device */
3665 ushort reqcnt[ADV_MAX_TID15+1]; /* Starvation request count */
3666#if ASC_QUEUE_FLOW_CONTROL
3667 ushort nerrcnt[ADV_MAX_TID15+1]; /* No error request count */
3668#endif /* ASC_QUEUE_FLOW_CONTROL */
3669 ADV_SCSI_BIT_ID_TYPEushort queue_full; /* Queue full mask */
3670 ushort queue_full_cnt[ADV_MAX_TID15+1]; /* Queue full count */
3671 union {
3672 ASCEEP_CONFIG asc_eep; /* Narrow EEPROM config. */
3673 ADVEEP_CONFIG adv_eep; /* Wide EEPROM config. */
3674 } eep_config;
3675 ulong last_reset; /* Saved last reset time */
3676#if LINUX_VERSION_CODE131108 >= ASC_LINUX_VERSION(1,3,0)(((1) * 65536) + ((3) * 256) + (0))
3677 /* /proc/scsi/advansys/[0...] */
3678 char *prtbuf; /* Statistics Print Buffer */
3679#endif /* version >= v1.3.0 */
3680#ifdef ADVANSYS_STATS
3681 struct asc_stats asc_stats; /* Board statistics */
3682#endif /* ADVANSYS_STATS */
3683 /*
3684 * The following fields are used only for Narrow Boards.
3685 */
3686 /* The following three structures must be in DMA-able memory. */
3687 ASC_SCSI_REQ_Q scsireqq;
3688 ASC_CAP_INFO cap_info;
3689 ASC_SCSI_INQUIRY inquiry;
3690 uchar sdtr_data[ASC_MAX_TID7+1]; /* SDTR information */
3691 /*
3692 * The following fields are used only for Wide Boards.
3693 */
3694 void *ioremap_addr; /* I/O Memory remap address. */
3695 ushort ioport; /* I/O Port address. */
3696 adv_req_t *orig_reqp; /* adv_req_t memory block. */
3697 adv_req_t *adv_reqp; /* Request structures. */
3698 adv_sgblk_t *orig_sgblkp; /* adv_sgblk_t memory block. */
3699 adv_sgblk_t *adv_sgblkp; /* Scatter-gather structures. */
3700 ushort bios_signature; /* BIOS Signature. */
3701 ushort bios_version; /* BIOS Version. */
3702 ushort bios_codeseg; /* BIOS Code Segment. */
3703 ushort bios_codelen; /* BIOS Code Segment Length. */
3704} asc_board_t;
3705
3706/*
3707 * PCI configuration structures
3708 */
3709typedef struct _PCI_DATA_
3710{
3711 uchar type;
3712 uchar bus;
3713 uchar slot;
3714 uchar func;
3715 uchar offset;
3716} PCI_DATA;
3717
3718typedef struct _PCI_DEVICE_
3719{
3720 ushort vendorID;
3721 ushort deviceID;
3722 ushort slotNumber;
3723 ushort slotFound;
3724 uchar busNumber;
3725 uchar maxBusNumber;
3726 uchar devFunc;
3727 ushort startSlot;
3728 ushort endSlot;
3729 uchar bridge;
3730 uchar type;
3731} PCI_DEVICE;
3732
3733typedef struct _PCI_CONFIG_SPACE_
3734{
3735 ushort vendorID;
3736 ushort deviceID;
3737 ushort command;
3738 ushort status;
3739 uchar revision;
3740 uchar classCode[3];
3741 uchar cacheSize;
3742 uchar latencyTimer;
3743 uchar headerType;
3744 uchar bist;
3745 ulong baseAddress[6];
3746 ushort reserved[4];
3747 ulong optionRomAddr;
3748 ushort reserved2[4];
3749 uchar irqLine;
3750 uchar irqPin;
3751 uchar minGnt;
3752 uchar maxLatency;
3753} PCI_CONFIG_SPACE;
3754
3755
3756/*
3757 * --- Driver Data
3758 */
3759
3760/* Note: All driver global data should be initialized. */
3761
3762#if LINUX_VERSION_CODE131108 >= ASC_LINUX_VERSION(1,3,0)(((1) * 65536) + ((3) * 256) + (0))
3763struct proc_dir_entry proc_scsi_advansys =
3764{
3765 PROC_SCSI_ADVANSYS, /* unsigned short low_ino */
3766 8, /* unsigned short namelen */
3767 "advansys", /* const char *name */
3768 S_IFDIR0040000 | S_IRUGO(00400|00040|00004) | S_IXUGO(00100|00010|00001), /* mode_t mode */
3769 2 /* nlink_t nlink */
3770};
3771#endif /* version >= v1.3.0 */
3772
3773/* Number of boards detected in system. */
3774STATICstatic int asc_board_count = 0;
3775STATICstatic struct Scsi_Host *asc_host[ASC_NUM_BOARD_SUPPORTED16] = { 0 };
3776
3777/* Overrun buffer shared between all boards. */
3778STATICstatic uchar overrun_buf[ASC_OVERRUN_BSIZE0x00000048UL] = { 0 };
3779
3780/*
3781 * Global structures required to issue a command.
3782 */
3783STATICstatic ASC_SCSI_Q asc_scsi_q = { { 0 } };
3784STATICstatic ASC_SG_HEAD asc_sg_head = { 0 };
3785
3786/* List of supported bus types. */
3787STATICstatic ushort asc_bus[ASC_NUM_BUS4] ASC_INITDATA = {
3788 ASC_IS_ISA(0x0001),
3789 ASC_IS_VL(0x0040),
3790 ASC_IS_EISA(0x0002),
3791 ASC_IS_PCI(0x0004),
3792};
3793
3794#if LINUX_VERSION_CODE131108 < ASC_LINUX_VERSION(2,1,93)(((2) * 65536) + ((1) * 256) + (93))
3795#ifdef ASC_CONFIG_PCI
3796STATICstatic int pci_scan_method ASC_INITDATA = -1;
3797#endif /* ASC_CONFIG_PCI */
3798#endif /* version < v2.1.93 */
3799
3800/*
3801 * Used with the LILO 'advansys' option to eliminate or
3802 * limit I/O port probing at boot time, cf. advansys_setup().
3803 */
3804STATICstatic int asc_iopflag = ASC_FALSE0;
3805STATICstatic int asc_ioport[ASC_NUM_IOPORT_PROBE4] = { 0, 0, 0, 0 };
3806
3807#if LINUX_VERSION_CODE131108 < ASC_LINUX_VERSION(1,3,0)(((1) * 65536) + ((3) * 256) + (0))
3808/*
3809 * In kernels earlier than v1.3.0, kmalloc() does not work
3810 * during driver initialization. Therefore statically declare
3811 * 16 elements of each structure. v1.3.0 kernels will probably
3812 * not need any more than this number.
3813 */
3814uchar adv_req_buf[16 * sizeof(adv_req_t)] = { 0 };
3815uchar adv_sgblk_buf[16 * sizeof(adv_sgblk_t)] = { 0 };
3816#endif /* version >= v1,3,0 */
3817
3818#ifdef ADVANSYS_DEBUG
3819STATICstatic char *
3820asc_bus_name[ASC_NUM_BUS4] = {
3821 "ASC_IS_ISA",
3822 "ASC_IS_VL",
3823 "ASC_IS_EISA",
3824 "ASC_IS_PCI",
3825};
3826
3827STATICstatic int asc_dbglvl = 0;
3828#endif /* ADVANSYS_DEBUG */
3829
3830/* Declaration for Asc Library internal data referenced by driver. */
3831STATICstatic PortAddrunsigned short _asc_def_iop_base[];
3832
3833
3834/*
3835 * --- Driver Function Prototypes
3836 *
3837 * advansys.h contains function prototypes for functions global to Linux.
3838 */
3839
3840#if LINUX_VERSION_CODE131108 >= ASC_LINUX_VERSION(1,3,0)(((1) * 65536) + ((3) * 256) + (0))
3841STATICstatic int asc_proc_copy(off_t, off_t, char *, int , char *, int);
3842#endif /* version >= v1.3.0 */
3843#if LINUX_VERSION_CODE131108 < ASC_LINUX_VERSION(1,3,70)(((1) * 65536) + ((3) * 256) + (70))
3844STATICstatic void advansys_interrupt(int, struct pt_regs *);
3845#else /* version >= v1.3.70 */
3846STATICstatic void advansys_interrupt(int, void *, struct pt_regs *);
3847#endif /* version >= v1.3.70 */
3848#if LINUX_VERSION_CODE131108 >= ASC_LINUX_VERSION(1,3,89)(((1) * 65536) + ((3) * 256) + (89))
3849STATICstatic void advansys_select_queue_depths(struct Scsi_Host *,
3850 Scsi_Device *);
3851#endif /* version >= v1.3.89 */
3852STATICstatic void advansys_command_done(Scsi_Cmnd *);
3853STATICstatic void asc_scsi_done_list(Scsi_Cmnd *);
3854STATICstatic int asc_execute_scsi_cmnd(Scsi_Cmnd *);
3855STATICstatic int asc_build_req(asc_board_t *, Scsi_Cmnd *);
3856STATICstatic int adv_build_req(asc_board_t *, Scsi_Cmnd *, ADV_SCSI_REQ_Q **);
3857STATICstatic int adv_get_sglist(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *, Scsi_Cmnd *);
3858STATICstatic void asc_isr_callback(ASC_DVC_VAR *, ASC_QDONE_INFO *);
3859STATICstatic void adv_isr_callback(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
3860#if LINUX_VERSION_CODE131108 < ASC_LINUX_VERSION(2,1,93)(((2) * 65536) + ((1) * 256) + (93))
3861#ifdef ASC_CONFIG_PCI
3862STATICstatic int asc_srch_pci_dev(PCI_DEVICE *);
3863STATICstatic uchar asc_scan_method(void);
3864STATICstatic int asc_pci_find_dev(PCI_DEVICE *);
3865STATICstatic void asc_get_pci_cfg(PCI_DEVICE *, PCI_CONFIG_SPACE *);
3866STATICstatic ushort asc_get_cfg_word(PCI_DATA *);
3867STATICstatic uchar asc_get_cfg_byte(PCI_DATA *);
3868STATICstatic void asc_put_cfg_byte(PCI_DATA *, uchar);
3869#endif /* ASC_CONFIG_PCI */
3870#endif /* version < v2.1.93 */
3871STATICstatic void asc_enqueue(asc_queue_t *, REQP, int);
3872STATICstatic REQP asc_dequeue(asc_queue_t *, int);
3873STATICstatic REQP asc_dequeue_list(asc_queue_t *, REQP *, int);
3874STATICstatic int asc_rmqueue(asc_queue_t *, REQP);
3875STATICstatic int asc_isqueued(asc_queue_t *, REQP);
3876STATICstatic void asc_execute_queue(asc_queue_t *);
3877#if LINUX_VERSION_CODE131108 >= ASC_LINUX_VERSION(1,3,0)(((1) * 65536) + ((3) * 256) + (0))
3878STATICstatic int asc_prt_board_devices(struct Scsi_Host *, char *, int);
3879STATICstatic int asc_prt_adv_bios(struct Scsi_Host *, char *, int);
3880STATICstatic int asc_get_eeprom_string(ushort *serialnum, uchar *cp);
3881STATICstatic int asc_prt_asc_board_eeprom(struct Scsi_Host *, char *, int);
3882STATICstatic int asc_prt_adv_board_eeprom(struct Scsi_Host *, char *, int);
3883STATICstatic int asc_prt_driver_conf(struct Scsi_Host *, char *, int);
3884STATICstatic int asc_prt_asc_board_info(struct Scsi_Host *, char *, int);
3885STATICstatic int asc_prt_adv_board_info(struct Scsi_Host *, char *, int);
3886STATICstatic int asc_prt_line(char *, int, char *fmt, ...);
3887#endif /* version >= v1.3.0 */
3888
3889/* Declaration for Asc Library internal functions reference by driver. */
3890STATICstatic int AscFindSignature(PortAddrunsigned short);
3891STATICstatic ushort AscGetEEPConfig(PortAddrunsigned short, ASCEEP_CONFIG *, ushort);
3892
3893#ifdef ADVANSYS_STATS
3894STATICstatic int asc_prt_board_stats(struct Scsi_Host *, char *, int);
3895#endif /* ADVANSYS_STATS */
3896
3897#ifdef ADVANSYS_DEBUG
3898STATICstatic void asc_prt_scsi_host(struct Scsi_Host *);
3899STATICstatic void asc_prt_scsi_cmnd(Scsi_Cmnd *);
3900STATICstatic void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *);
3901STATICstatic void asc_prt_asc_dvc_var(ASC_DVC_VAR *);
3902STATICstatic void asc_prt_asc_scsi_q(ASC_SCSI_Q *);
3903STATICstatic void asc_prt_asc_qdone_info(ASC_QDONE_INFO *);
3904STATICstatic void asc_prt_adv_dvc_cfg(ADV_DVC_CFG *);
3905STATICstatic void asc_prt_adv_dvc_var(ADV_DVC_VAR *);
3906STATICstatic void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *);
3907STATICstatic void asc_prt_adv_sgblock(int, ADV_SG_BLOCK *);
3908STATICstatic void asc_prt_hex(char *f, uchar *, int);
3909#endif /* ADVANSYS_DEBUG */
3910
3911#ifdef ADVANSYS_ASSERT
3912STATICstatic int interrupts_enabled(void);
3913#endif /* ADVANSYS_ASSERT */
3914
3915
3916/*
3917 * --- Linux 'Scsi_Host_Template' and advansys_setup() Functions
3918 */
3919
3920#if LINUX_VERSION_CODE131108 >= ASC_LINUX_VERSION(1,3,0)(((1) * 65536) + ((3) * 256) + (0))
3921/*
3922 * advansys_proc_info() - /proc/scsi/advansys/[0-(ASC_NUM_BOARD_SUPPORTED-1)]
3923 *
3924 * *buffer: I/O buffer
3925 * **start: if inout == FALSE pointer into buffer where user read should start
3926 * offset: current offset into a /proc/scsi/advansys/[0...] file
3927 * length: length of buffer
3928 * hostno: Scsi_Host host_no
3929 * inout: TRUE - user is writing; FALSE - user is reading
3930 *
3931 * Return the number of bytes read from or written to a
3932 * /proc/scsi/advansys/[0...] file.
3933 *
3934 * Note: This function uses the per board buffer 'prtbuf' which is
3935 * allocated when the board is initialized in advansys_detect(). The
3936 * buffer is ASC_PRTBUF_SIZE bytes. The function asc_proc_copy() is
3937 * used to write to the buffer. The way asc_proc_copy() is written
3938 * if 'prtbuf' is too small it will not be overwritten. Instead the
3939 * user just won't get all the available statistics.
3940 */
3941int
3942advansys_proc_info(char *buffer, char **start, off_t offset, int length,
3943 int hostno, int inout)
3944{
3945 struct Scsi_Host *shp;
3946 asc_board_t *boardp;
3947 int i;
3948 char *cp;
3949 int cplen;
3950 int cnt;
3951 int totcnt;
3952 int leftlen;
3953 char *curbuf;
3954 off_t advoffset;
3955 Scsi_Device *scd;
3956
3957 ASC_DBG(1, "advansys_proc_info: begin\n");
3958
3959 /*
3960 * User write not supported.
3961 */
3962 if (inout == TRUE1) {
3963 return(-ENOSYS38);
3964 }
3965
3966 /*
3967 * User read of /proc/scsi/advansys/[0...] file.
3968 */
3969
3970 /* Find the specified board. */
3971 for (i = 0; i < asc_board_count; i++) {
3972 if (asc_host[i]->host_no == hostno) {
3973 break;
3974 }
3975 }
3976 if (i == asc_board_count) {
3977 return(-ENOENT2);
3978 }
3979
3980 shp = asc_host[i];
3981 boardp = ASC_BOARDP(shp)((asc_board_t *) &((shp)->hostdata));
3982
3983 /* Copy read data starting at the beginning of the buffer. */
3984 *start = buffer;
3985 curbuf = buffer;
3986 advoffset = 0;
3987 totcnt = 0;
3988 leftlen = length;
3989
3990 /*
3991 * Get board configuration information.
3992 *
3993 * advansys_info() returns the board string from its own static buffer.
3994 */
3995 cp = (char *) advansys_info(shp);
3996 strcat(cp, "\n");
3997 cplen = strlen(cp);
3998 /* Copy board information. */
3999 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4000 totcnt += cnt;
4001 leftlen -= cnt;
4002 if (leftlen == 0) {
4003 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4004 return totcnt;
4005 }
4006 advoffset += cplen;
4007 curbuf += cnt;
4008
4009 /*
4010 * Display Wide Board BIOS Information.
4011 */
4012 if (ASC_WIDE_BOARD(boardp)((boardp)->flags & 0x04)) {
4013 cp = boardp->prtbuf;
4014 cplen = asc_prt_adv_bios(shp, cp, ASC_PRTBUF_SIZE2048);
4015 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE){ if (!(cplen < 2048)) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 4015); } }
;
4016 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4017 totcnt += cnt;
4018 leftlen -= cnt;
4019 if (leftlen == 0) {
4020 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4021 return totcnt;
4022 }
4023 advoffset += cplen;
4024 curbuf += cnt;
4025 }
4026
4027 /*
4028 * Display driver information for each device attached to the board.
4029 */
4030 cp = boardp->prtbuf;
4031 cplen = asc_prt_board_devices(shp, cp, ASC_PRTBUF_SIZE2048);
4032 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE){ if (!(cplen < 2048)) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 4032); } }
;
4033 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4034 totcnt += cnt;
4035 leftlen -= cnt;
4036 if (leftlen == 0) {
4037 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4038 return totcnt;
4039 }
4040 advoffset += cplen;
4041 curbuf += cnt;
4042
4043 /*
4044 * Display target driver information for each device attached
4045 * to the board.
4046 */
4047#if LINUX_VERSION_CODE131108 < ASC_LINUX_VERSION(2,1,75)(((2) * 65536) + ((1) * 256) + (75))
4048 for (scd = scsi_devices; scd; scd = scd->next)
4049#else /* version >= v2.1.75 */
4050 for (scd = shp->host_queue; scd; scd = scd->next)
4051#endif /* version >= v2.1.75 */
4052 {
4053 if (scd->host == shp) {
4054 cp = boardp->prtbuf;
4055 /*
4056 * Note: If proc_print_scsidevice() writes more than
4057 * ASC_PRTBUF_SIZE bytes, it will overrun 'prtbuf'.
4058 */
4059 proc_print_scsidevice(scd, cp, &cplen, 0);
4060 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE){ if (!(cplen < 2048)) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 4060); } }
;
4061 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4062 totcnt += cnt;
4063 leftlen -= cnt;
4064 if (leftlen == 0) {
4065 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4066 return totcnt;
4067 }
4068 advoffset += cplen;
4069 curbuf += cnt;
4070 }
4071 }
4072
4073 /*
4074 * Display EEPROM configuration for the board.
4075 */
4076 cp = boardp->prtbuf;
4077 if (ASC_NARROW_BOARD(boardp)(((boardp)->flags & 0x04) == 0)) {
4078 cplen = asc_prt_asc_board_eeprom(shp, cp, ASC_PRTBUF_SIZE2048);
4079 } else {
4080 cplen = asc_prt_adv_board_eeprom(shp, cp, ASC_PRTBUF_SIZE2048);
4081 }
4082 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE){ if (!(cplen < 2048)) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 4082); } }
;
4083 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4084 totcnt += cnt;
4085 leftlen -= cnt;
4086 if (leftlen == 0) {
4087 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4088 return totcnt;
4089 }
4090 advoffset += cplen;
4091 curbuf += cnt;
4092
4093 /*
4094 * Display driver configuration and information for the board.
4095 */
4096 cp = boardp->prtbuf;
4097 cplen = asc_prt_driver_conf(shp, cp, ASC_PRTBUF_SIZE2048);
4098 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE){ if (!(cplen < 2048)) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 4098); } }
;
4099 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4100 totcnt += cnt;
4101 leftlen -= cnt;
4102 if (leftlen == 0) {
4103 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4104 return totcnt;
4105 }
4106 advoffset += cplen;
4107 curbuf += cnt;
4108
4109#ifdef ADVANSYS_STATS
4110 /*
4111 * Display driver statistics for the board.
4112 */
4113 cp = boardp->prtbuf;
4114 cplen = asc_prt_board_stats(shp, cp, ASC_PRTBUF_SIZE2048);
4115 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE){ if (!(cplen < 2048)) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 4115); } }
;
4116 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4117 totcnt += cnt;
4118 leftlen -= cnt;
4119 if (leftlen == 0) {
4120 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4121 return totcnt;
4122 }
4123 advoffset += cplen;
4124 curbuf += cnt;
4125#endif /* ADVANSYS_STATS */
4126
4127 /*
4128 * Display Asc Library dynamic configuration information
4129 * for the board.
4130 */
4131 cp = boardp->prtbuf;
4132 if (ASC_NARROW_BOARD(boardp)(((boardp)->flags & 0x04) == 0)) {
4133 cplen = asc_prt_asc_board_info(shp, cp, ASC_PRTBUF_SIZE2048);
4134 } else {
4135 cplen = asc_prt_adv_board_info(shp, cp, ASC_PRTBUF_SIZE2048);
4136 }
4137 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE){ if (!(cplen < 2048)) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 4137); } }
;
4138 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4139 totcnt += cnt;
4140 leftlen -= cnt;
4141 if (leftlen == 0) {
4142 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4143 return totcnt;
4144 }
4145 advoffset += cplen;
4146 curbuf += cnt;
4147
4148 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4149
4150 return totcnt;
4151}
4152#endif /* version >= v1.3.0 */
4153
4154/*
4155 * advansys_detect()
4156 *
4157 * Detect function for AdvanSys adapters.
4158 *
4159 * Argument is a pointer to the host driver's scsi_hosts entry.
4160 *
4161 * Return number of adapters found.
4162 *
4163 * Note: Because this function is called during system initialization
4164 * it must not call SCSI mid-level functions including scsi_malloc()
4165 * and scsi_free().
4166 */
4167ASC_INITFUNC(int advansys_detect(Scsi_Host_Template *tpnt)
4168intint advansys_detect(Scsi_Host_Template *tpnt)
4169advansys_detect(Scsi_Host_Template *tpnt)int advansys_detect(Scsi_Host_Template *tpnt)
4170)int advansys_detect(Scsi_Host_Template *tpnt)
4171{
4172 static int detect_called = ASC_FALSE0;
4173 int iop;
4174 int bus;
4175 struct Scsi_Host *shp;
4176 asc_board_t *boardp;
4177 ASC_DVC_VAR *asc_dvc_varp = NULL((void *) 0);
4178 ADV_DVC_VAR *adv_dvc_varp = NULL((void *) 0);
4179 int ioport = 0;
4180 int share_irq = FALSE0;
4181#if LINUX_VERSION_CODE131108 < ASC_LINUX_VERSION(2,1,93)(((2) * 65536) + ((1) * 256) + (93))
4182#ifdef ASC_CONFIG_PCI
4183 PCI_DEVICE pciDevice;
4184 PCI_CONFIG_SPACE pciConfig;
4185#if LINUX_VERSION_CODE131108 >= ASC_LINUX_VERSION(1,3,0)(((1) * 65536) + ((3) * 256) + (0))
4186 unsigned long pci_memory_address;
4187#endif /* version >= v1,3,0 */
4188#endif /* ASC_CONFIG_PCI */
4189#else /* version >= v2.1.93 */
4190#ifdef CONFIG_PCI1
4191 struct pci_dev *pci_devp = NULL((void *) 0);
4192 int pci_device_id_cnt = 0;
4193 unsigned int pci_device_id[ASC_PCI_DEVICE_ID_CNT4] = {
4194 ASC_PCI_DEVICE_ID_11000x1100,
4195 ASC_PCI_DEVICE_ID_12000x1200,
4196 ASC_PCI_DEVICE_ID_13000x1300,
4197 ASC_PCI_DEVICE_ID_23000x2300
4198 };
4199 unsigned long pci_memory_address;
4200#endif /* CONFIG_PCI */
4201#endif /* version >= v2.1.93 */
4202 int warn_code, err_code;
4203 int ret;
4204
4205 if (detect_called == ASC_FALSE0) {
4206 detect_called = ASC_TRUE1;
4207 } else {
4208 printk("AdvanSys SCSI: advansys_detect() multiple calls ignored\n");
4209 return 0;
4210 }
4211
4212 ASC_DBG(1, "advansys_detect: begin\n");
4213
4214#if LINUX_VERSION_CODE131108 >= ASC_LINUX_VERSION(1,3,0)(((1) * 65536) + ((3) * 256) + (0))
4215 tpnt->proc_dir = &proc_scsi_advansys;
4216#endif /* version >= v1.3.0 */
4217
4218 asc_board_count = 0;
4219
4220 /*
4221 * If I/O port probing has been modified, then verify and
4222 * clean-up the 'asc_ioport' list.
4223 */
4224 if (asc_iopflag == ASC_TRUE1) {
4225 for (ioport = 0; ioport < ASC_NUM_IOPORT_PROBE4; ioport++) {
4226 ASC_DBG2(1, "advansys_detect: asc_ioport[%d] %x\n",
4227 ioport, asc_ioport[ioport]);
4228 if (asc_ioport[ioport] != 0) {
4229 for (iop = 0; iop < ASC_IOADR_TABLE_MAX_IX11; iop++) {
4230 if (_asc_def_iop_base[iop] == asc_ioport[ioport]) {
4231 break;
4232 }
4233 }
4234 if (iop == ASC_IOADR_TABLE_MAX_IX11) {
4235 printk(
4236"AdvanSys SCSI: specified I/O Port 0x%X is invalid\n",
4237 asc_ioport[ioport]);
4238 asc_ioport[ioport] = 0;
4239 }
4240 }
4241 }
4242 ioport = 0;
4243 }
4244
4245#if LINUX_VERSION_CODE131108 < ASC_LINUX_VERSION(2,1,93)(((2) * 65536) + ((1) * 256) + (93))
4246#ifdef ASC_CONFIG_PCI
4247 memset(&pciDevice, 0, sizeof(PCI_DEVICE))(__builtin_constant_p(0) ? (__builtin_constant_p((sizeof(PCI_DEVICE
))) ? __constant_c_and_count_memset(((&pciDevice)),((0x01010101UL
*(unsigned char)(0))),((sizeof(PCI_DEVICE)))) : __constant_c_memset
(((&pciDevice)),((0x01010101UL*(unsigned char)(0))),((sizeof
(PCI_DEVICE))))) : (__builtin_constant_p((sizeof(PCI_DEVICE))
) ? __memset_generic((((&pciDevice))),(((0))),(((sizeof(PCI_DEVICE
))))) : __memset_generic(((&pciDevice)),((0)),((sizeof(PCI_DEVICE
))))))
;
4248 memset(&pciConfig, 0, sizeof(PCI_CONFIG_SPACE))(__builtin_constant_p(0) ? (__builtin_constant_p((sizeof(PCI_CONFIG_SPACE
))) ? __constant_c_and_count_memset(((&pciConfig)),((0x01010101UL
*(unsigned char)(0))),((sizeof(PCI_CONFIG_SPACE)))) : __constant_c_memset
(((&pciConfig)),((0x01010101UL*(unsigned char)(0))),((sizeof
(PCI_CONFIG_SPACE))))) : (__builtin_constant_p((sizeof(PCI_CONFIG_SPACE
))) ? __memset_generic((((&pciConfig))),(((0))),(((sizeof
(PCI_CONFIG_SPACE))))) : __memset_generic(((&pciConfig)),
((0)),((sizeof(PCI_CONFIG_SPACE))))))
;
4249 pciDevice.maxBusNumber = PCI_MAX_BUS0xFF;
4250 pciDevice.endSlot = PCI_MAX_SLOT0x1F;
4251#endif /* ASC_CONFIG_PCI */
4252#endif /* version < v2.1.93 */
4253
4254 for (bus = 0; bus < ASC_NUM_BUS4; bus++) {
4255
4256 ASC_DBG2(1, "advansys_detect: bus search type %d (%s)\n",
4257 bus, asc_bus_name[bus]);
4258 iop = 0;
4259
4260 while (asc_board_count < ASC_NUM_BOARD_SUPPORTED16) {
4261
4262 ASC_DBG1(2, "advansys_detect: asc_board_count %d\n",
4263 asc_board_count);
4264
4265 switch (asc_bus[bus]) {
4266 case ASC_IS_ISA(0x0001):
4267 case ASC_IS_VL(0x0040):
4268 if (asc_iopflag == ASC_FALSE0) {
4269 iop = AscSearchIOPortAddr(iop, asc_bus[bus]);
4270 } else {
4271 /*
4272 * ISA and VL I/O port scanning has either been
4273 * eliminated or limited to selected ports on
4274 * the LILO command line, /etc/lilo.conf, or
4275 * by setting variables when the module was loaded.
4276 */
4277 ASC_DBG(1, "advansys_detect: I/O port scanning modified\n");
4278 ioport_try_again:
4279 iop = 0;
4280 for (; ioport < ASC_NUM_IOPORT_PROBE4; ioport++) {
4281 if ((iop = asc_ioport[ioport]) != 0) {
4282 break;
4283 }
4284 }
4285 if (iop) {
4286 ASC_DBG1(1, "advansys_detect: probing I/O port %x...\n",
4287 iop);
4288 if (check_region(iop, ASC_IOADR_GAP0x10) != 0) {
4289 printk(
4290"AdvanSys SCSI: specified I/O Port 0x%X is busy\n", iop);
4291 /* Don't try this I/O port twice. */
4292 asc_ioport[ioport] = 0;
4293 goto ioport_try_again;
4294 } else if (AscFindSignature(iop) == ASC_FALSE0) {
4295 printk(
4296"AdvanSys SCSI: specified I/O Port 0x%X has no adapter\n", iop);
4297 /* Don't try this I/O port twice. */
4298 asc_ioport[ioport] = 0;
4299 goto ioport_try_again;
4300 } else {
4301 /*
4302 * If this isn't an ISA board, then it must be
4303 * a VL board. If currently looking an ISA
4304 * board is being looked for then try for
4305 * another ISA board in 'asc_ioport'.
4306 */
4307 if (asc_bus[bus] == ASC_IS_ISA(0x0001) &&
4308 (AscGetChipVersion(iop, ASC_IS_ISA(0x0001)) &
4309 ASC_CHIP_VER_ISA_BIT(0x30)) == 0) {
4310 /*
4311 * Don't clear 'asc_ioport[ioport]'. Try
4312 * this board again for VL. Increment
4313 * 'ioport' past this board.
4314 */
4315 ioport++;
4316 goto ioport_try_again;
4317 }
4318 }
4319 /*
4320 * This board appears good, don't try the I/O port
4321 * again by clearing its value. Increment 'ioport'
4322 * for the next iteration.
4323 */
4324 asc_ioport[ioport++] = 0;
4325 }
4326 }
4327 break;
4328
4329 case ASC_IS_EISA(0x0002):
4330 iop = AscSearchIOPortAddr(iop, asc_bus[bus]);
4331 break;
4332
4333#if LINUX_VERSION_CODE131108 < ASC_LINUX_VERSION(2,1,93)(((2) * 65536) + ((1) * 256) + (93))
4334#ifdef ASC_CONFIG_PCI
4335 case ASC_IS_PCI(0x0004):
4336 if (asc_srch_pci_dev(&pciDevice) != PCI_DEVICE_FOUND0x0000) {
4337 iop = 0;
4338 } else {
4339 ASC_DBG2(2,
4340 "advansys_detect: slotFound %d, busNumber %d\n",
4341 pciDevice.slotFound, pciDevice.busNumber);
4342 asc_get_pci_cfg(&pciDevice, &pciConfig);
4343 iop = pciConfig.baseAddress[0] & PCI_IOADDRESS_MASK0xFFFE;
4344 ASC_DBG2(1,
4345 "advansys_detect: vendorID %X, deviceID %X\n",
4346 pciConfig.vendorID, pciConfig.deviceID);
4347 ASC_DBG2(2, "advansys_detect: iop %X, irqLine %d\n",
4348 iop, pciConfig.irqLine);
4349 }
4350 break;
4351#endif /* ASC_CONFIG_PCI */
4352#else /* version >= v2.1.93 */
4353#ifdef CONFIG_PCI1
4354 case ASC_IS_PCI(0x0004):
4355 while (pci_device_id_cnt < ASC_PCI_DEVICE_ID_CNT4) {
4356 if ((pci_devp = pci_find_device(ASC_PCI_VENDORID0x10CD,
4357 pci_device_id[pci_device_id_cnt], pci_devp)) == NULL((void *) 0)) {
4358 pci_device_id_cnt++;
4359 } else {
4360 break;
4361 }
4362 }
4363 if (pci_devp == NULL((void *) 0)) {
4364 iop = 0;
4365 } else {
4366 ASC_DBG2(2,
4367 "advansys_detect: devfn %d, bus number %d\n",
4368 pci_devp->devfn, pci_devp->bus->number);
4369 iop = pci_devp->base_address[0] & PCI_IOADDRESS_MASK0xFFFE;
4370 ASC_DBG2(1,
4371 "advansys_detect: vendorID %X, deviceID %X\n",
4372 pci_devp->vendor, pci_devp->device);
4373 ASC_DBG2(2, "advansys_detect: iop %X, irqLine %d\n",
4374 iop, pci_devp->irq);
4375 }
4376 break;
4377#endif /* CONFIG_PCI */
4378#endif /* version >= v2.1.93 */
4379
4380 default:
4381 ASC_PRINT1("advansys_detect: unknown bus type: %d\n",{ printk("advansys: "); printk(("advansys_detect: unknown bus type: %d\n"
), (asc_bus[bus])); }
4382 asc_bus[bus]){ printk("advansys: "); printk(("advansys_detect: unknown bus type: %d\n"
), (asc_bus[bus])); }
;
4383 break;
4384 }
4385 ASC_DBG1(1, "advansys_detect: iop %x\n", iop);
4386
4387 /*
4388 * Adapter not found, try next bus type.
4389 */
4390 if (iop == 0) {
4391 break;
4392 }
4393
4394 /*
4395 * Adapter found.
4396 *
4397 * Register the adapter, get its configuration, and
4398 * initialize it.
4399 */
4400 ASC_DBG(2, "advansys_detect: scsi_register()\n");
4401 shp = scsi_register(tpnt, sizeof(asc_board_t));
4402
4403 /* Save a pointer to the Scsi_host of each board found. */
4404 asc_host[asc_board_count++] = shp;
4405
4406 /* Initialize private per board data */
4407 boardp = ASC_BOARDP(shp)((asc_board_t *) &((shp)->hostdata));
4408 memset(boardp, 0, sizeof(asc_board_t))(__builtin_constant_p(0) ? (__builtin_constant_p((sizeof(asc_board_t
))) ? __constant_c_and_count_memset(((boardp)),((0x01010101UL
*(unsigned char)(0))),((sizeof(asc_board_t)))) : __constant_c_memset
(((boardp)),((0x01010101UL*(unsigned char)(0))),((sizeof(asc_board_t
))))) : (__builtin_constant_p((sizeof(asc_board_t))) ? __memset_generic
((((boardp))),(((0))),(((sizeof(asc_board_t))))) : __memset_generic
(((boardp)),((0)),((sizeof(asc_board_t))))))
;
4409 boardp->id = asc_board_count - 1;
4410
4411 /*
4412 * Handle both narrow and wide boards.
4413 *
4414 * If a Wide board was detected, set the board structure
4415 * wide board flag. Set-up the board structure based on
4416 * the board type.
4417 */
4418#if LINUX_VERSION_CODE131108 < ASC_LINUX_VERSION(2,1,93)(((2) * 65536) + ((1) * 256) + (93))
4419#ifdef ASC_CONFIG_PCI
4420 if (asc_bus[bus] == ASC_IS_PCI(0x0004) &&
4421 pciConfig.deviceID == ASC_PCI_DEVICE_ID_23000x2300) {
4422 boardp->flags |= ASC_IS_WIDE_BOARD0x04;
4423 }
4424#endif /* ASC_CONFIG_PCI */
4425#else /* version >= v2.1.93 */
4426#ifdef CONFIG_PCI1
4427 if (asc_bus[bus] == ASC_IS_PCI(0x0004) &&
4428 pci_devp->device == ASC_PCI_DEVICE_ID_23000x2300) {
4429 boardp->flags |= ASC_IS_WIDE_BOARD0x04;
4430 }
4431#endif /* CONFIG_PCI */
4432#endif /* version >= v2.1.93 */
4433
4434 if (ASC_NARROW_BOARD(boardp)(((boardp)->flags & 0x04) == 0)) {
4435 ASC_DBG(1, "advansys_detect: narrow board\n");
4436 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
4437 asc_dvc_varp->bus_type = asc_bus[bus];
4438 asc_dvc_varp->drv_ptr = (ulong) boardp;
4439 asc_dvc_varp->cfg = &boardp->dvc_cfg.asc_dvc_cfg;
4440 asc_dvc_varp->cfg->overrun_buf = &overrun_buf[0];
4441 asc_dvc_varp->iop_base = iop;
4442 asc_dvc_varp->isr_callback = (Ptr2Funculong) asc_isr_callback;
4443 } else {
4444 ASC_DBG(1, "advansys_detect: wide board\n");
4445 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
4446 adv_dvc_varp->drv_ptr = (ulong) boardp;
4447 adv_dvc_varp->cfg = &boardp->dvc_cfg.adv_dvc_cfg;
4448 adv_dvc_varp->isr_callback = (Ptr2Funculong) adv_isr_callback;
4449
4450#if LINUX_VERSION_CODE131108 < ASC_LINUX_VERSION(1,3,0)(((1) * 65536) + ((3) * 256) + (0))
4451 adv_dvc_varp->iop_base = iop;
4452#else /* version >= v1,3,0 */
4453 /*
4454 * Map the board's registers into virtual memory for
4455 * PCI slave access. Only memory accesses are used to
4456 * access the board's registers.
4457 *
4458 * Note: The PCI register base address is not always
4459 * page aligned, but the address passed to ioremap()
4460 * must be page aligned. It is guaranteed that the
4461 * PCI register base address will not cross a page
4462 * boundary.
4463 */
4464#if LINUX_VERSION_CODE131108 < ASC_LINUX_VERSION(2,1,93)(((2) * 65536) + ((1) * 256) + (93))
4465#ifdef ASC_CONFIG_PCI
4466 pci_memory_address = pciConfig.baseAddress[1];
4467 if ((boardp->ioremap_addr =
4468 ioremapvremap(pci_memory_address & PAGE_MASK((1 << 12)-1),
4469 PAGE_SIZE(1 << 12))) == 0) {
4470 ASC_PRINT3({ printk("advansys: "); printk(("advansys_detect: board %d: ioremap(%lx, %d) returned NULL\n"
), (boardp->id), (pci_memory_address), (0x40)); }
4471"advansys_detect: board %d: ioremap(%lx, %d) returned NULL\n",{ printk("advansys: "); printk(("advansys_detect: board %d: ioremap(%lx, %d) returned NULL\n"
), (boardp->id), (pci_memory_address), (0x40)); }
4472 boardp->id, pci_memory_address, ADV_CONDOR_IOLEN){ printk("advansys: "); printk(("advansys_detect: board %d: ioremap(%lx, %d) returned NULL\n"
), (boardp->id), (pci_memory_address), (0x40)); }
;
4473 scsi_unregister(shp);
4474 asc_board_count--;
4475 continue;
4476 }
4477 adv_dvc_varp->iop_base = (AdvPortAddrunsigned long)
4478 (boardp->ioremap_addr +
4479 (pci_memory_address - (pci_memory_address & PAGE_MASK((1 << 12)-1))));
4480#endif /* ASC_CONFIG_PCI */
4481#else /* version >= v2.1.93 */
4482#ifdef CONFIG_PCI1
4483 pci_memory_address = pci_devp->base_address[1];
4484 if ((boardp->ioremap_addr =
4485 ioremapvremap(pci_memory_address & PAGE_MASK((1 << 12)-1),
4486 PAGE_SIZE(1 << 12))) == 0) {
4487 ASC_PRINT3({ printk("advansys: "); printk(("advansys_detect: board %d: ioremap(%lx, %d) returned NULL\n"
), (boardp->id), (pci_memory_address), (0x40)); }
4488"advansys_detect: board %d: ioremap(%lx, %d) returned NULL\n",{ printk("advansys: "); printk(("advansys_detect: board %d: ioremap(%lx, %d) returned NULL\n"
), (boardp->id), (pci_memory_address), (0x40)); }
4489 boardp->id, pci_memory_address, ADV_CONDOR_IOLEN){ printk("advansys: "); printk(("advansys_detect: board %d: ioremap(%lx, %d) returned NULL\n"
), (boardp->id), (pci_memory_address), (0x40)); }
;
4490 scsi_unregister(shp);
4491 asc_board_count--;
4492 continue;
4493 }
4494 adv_dvc_varp->iop_base = (AdvPortAddrunsigned long)
4495 (boardp->ioremap_addr +
4496 (pci_memory_address - (pci_memory_address & PAGE_MASK((1 << 12)-1))));
4497#endif /* CONFIG_PCI */
4498#endif /* version >= v2.1.93 */
4499#endif /* version >= v1,3,0 */
4500
4501 /*
4502 * Even though it isn't used to access the board in
4503 * kernels greater than or equal to v1.3.0, save
4504 * the I/O Port address so that it can be reported and
4505 * displayed.
4506 */
4507 boardp->ioport = iop;
4508 }
4509
4510#if LINUX_VERSION_CODE131108 >= ASC_LINUX_VERSION(1,3,0)(((1) * 65536) + ((3) * 256) + (0))
4511 /*
4512 * Allocate buffer for printing information from
4513 * /proc/scsi/advansys/[0...].
4514 */
4515 if ((boardp->prtbuf =
4516 kmalloclinux_kmalloc(ASC_PRTBUF_SIZE2048, GFP_ATOMIC0x01)) == NULL((void *) 0)) {
4517 ASC_PRINT3({ printk("advansys: "); printk(("advansys_detect: board %d: kmalloc(%d, %d) returned NULL\n"
), (boardp->id), (2048), (0x01)); }
4518"advansys_detect: board %d: kmalloc(%d, %d) returned NULL\n",{ printk("advansys: "); printk(("advansys_detect: board %d: kmalloc(%d, %d) returned NULL\n"
), (boardp->id), (2048), (0x01)); }
4519 boardp->id, ASC_PRTBUF_SIZE, GFP_ATOMIC){ printk("advansys: "); printk(("advansys_detect: board %d: kmalloc(%d, %d) returned NULL\n"
), (boardp->id), (2048), (0x01)); }
;
4520 scsi_unregister(shp);
4521 asc_board_count--;
4522 continue;
4523 }
4524#endif /* version >= v1.3.0 */
4525
4526 if (ASC_NARROW_BOARD(boardp)(((boardp)->flags & 0x04) == 0)) {
4527 /*
4528 * Set the board bus type and PCI IRQ before
4529 * calling AscInitGetConfig().
4530 */
4531 switch (asc_dvc_varp->bus_type) {
4532 case ASC_IS_ISA(0x0001):
4533 shp->unchecked_isa_dma = TRUE1;
4534 share_irq = FALSE0;
4535 break;
4536 case ASC_IS_VL(0x0040):
4537 shp->unchecked_isa_dma = FALSE0;
4538 share_irq = FALSE0;
4539 break;
4540 case ASC_IS_EISA(0x0002):
4541 shp->unchecked_isa_dma = FALSE0;
4542 share_irq = TRUE1;
4543 break;
4544#if LINUX_VERSION_CODE131108 < ASC_LINUX_VERSION(2,1,93)(((2) * 65536) + ((1) * 256) + (93))
4545#ifdef ASC_CONFIG_PCI
4546 case ASC_IS_PCI(0x0004):
4547 shp->irq = asc_dvc_varp->irq_no = pciConfig.irqLine;
4548 asc_dvc_varp->cfg->pci_device_id = pciConfig.deviceID;
4549 asc_dvc_varp->cfg->pci_slot_info =
4550 ASC_PCI_MKID(pciDevice.busNumber,((((pciDevice.slotFound) & 0x1F) << 11) | (((pciDevice
.devFunc) & 0x7) << 8) | ((pciDevice.busNumber) &
0xFF))
4551 pciDevice.slotFound,((((pciDevice.slotFound) & 0x1F) << 11) | (((pciDevice
.devFunc) & 0x7) << 8) | ((pciDevice.busNumber) &
0xFF))
4552 pciDevice.devFunc)((((pciDevice.slotFound) & 0x1F) << 11) | (((pciDevice
.devFunc) & 0x7) << 8) | ((pciDevice.busNumber) &
0xFF))
;
4553 shp->unchecked_isa_dma = FALSE0;
4554 share_irq = TRUE1;
4555 break;
4556#endif /* ASC_CONFIG_PCI */
4557#else /* version >= v2.1.93 */
4558#ifdef CONFIG_PCI1
4559 case ASC_IS_PCI(0x0004):
4560 shp->irq = asc_dvc_varp->irq_no = pci_devp->irq;
4561 asc_dvc_varp->cfg->pci_device_id = pci_devp->device;
4562 asc_dvc_varp->cfg->pci_slot_info =
4563 ASC_PCI_MKID(pci_devp->bus->number,((((PCI_SLOT(pci_devp->devfn)) & 0x1F) << 11) | (
((PCI_FUNC(pci_devp->devfn)) & 0x7) << 8) | ((pci_devp
->bus->number) & 0xFF))
4564 PCI_SLOT(pci_devp->devfn),((((PCI_SLOT(pci_devp->devfn)) & 0x1F) << 11) | (
((PCI_FUNC(pci_devp->devfn)) & 0x7) << 8) | ((pci_devp
->bus->number) & 0xFF))
4565 PCI_FUNC(pci_devp->devfn))((((PCI_SLOT(pci_devp->devfn)) & 0x1F) << 11) | (
((PCI_FUNC(pci_devp->devfn)) & 0x7) << 8) | ((pci_devp
->bus->number) & 0xFF))
;
4566 shp->unchecked_isa_dma = FALSE0;
4567 share_irq = TRUE1;
4568 break;
4569#endif /* CONFIG_PCI */
4570#endif /* version >= v2.1.93 */
4571 default:
4572 ASC_PRINT2({ printk("advansys: "); printk(("advansys_detect: board %d: unknown adapter type: %d\n"
), (boardp->id), (asc_dvc_varp->bus_type)); }
4573"advansys_detect: board %d: unknown adapter type: %d\n",{ printk("advansys: "); printk(("advansys_detect: board %d: unknown adapter type: %d\n"
), (boardp->id), (asc_dvc_varp->bus_type)); }
4574 boardp->id, asc_dvc_varp->bus_type){ printk("advansys: "); printk(("advansys_detect: board %d: unknown adapter type: %d\n"
), (boardp->id), (asc_dvc_varp->bus_type)); }
;
4575 shp->unchecked_isa_dma = TRUE1;
4576 share_irq = FALSE0;
4577 break;
4578 }
4579 } else {
4580 /*
4581 * For Wide boards set PCI information before calling
4582 * AdvInitGetConfig().
4583 */
4584#if LINUX_VERSION_CODE131108 < ASC_LINUX_VERSION(2,1,93)(((2) * 65536) + ((1) * 256) + (93))
4585#ifdef ASC_CONFIG_PCI
4586 shp->irq = adv_dvc_varp->irq_no = pciConfig.irqLine;
4587 adv_dvc_varp->cfg->pci_device_id = pciConfig.deviceID;
4588 adv_dvc_varp->cfg->pci_slot_info =
4589 ASC_PCI_MKID(pciDevice.busNumber,((((pciDevice.slotFound) & 0x1F) << 11) | (((pciDevice
.devFunc) & 0x7) << 8) | ((pciDevice.busNumber) &
0xFF))
4590 pciDevice.slotFound,((((pciDevice.slotFound) & 0x1F) << 11) | (((pciDevice
.devFunc) & 0x7) << 8) | ((pciDevice.busNumber) &
0xFF))
4591 pciDevice.devFunc)((((pciDevice.slotFound) & 0x1F) << 11) | (((pciDevice
.devFunc) & 0x7) << 8) | ((pciDevice.busNumber) &
0xFF))
;
4592 shp->unchecked_isa_dma = FALSE0;
4593 share_irq = TRUE1;
4594#endif /* ASC_CONFIG_PCI */
4595#else /* version >= v2.1.93 */
4596#ifdef CONFIG_PCI1
4597 shp->irq = adv_dvc_varp->irq_no = pci_devp->irq;
4598 adv_dvc_varp->cfg->pci_device_id = pci_devp->device;
4599 adv_dvc_varp->cfg->pci_slot_info =
4600 ASC_PCI_MKID(pci_devp->bus->number,((((PCI_SLOT(pci_devp->devfn)) & 0x1F) << 11) | (
((PCI_FUNC(pci_devp->devfn)) & 0x7) << 8) | ((pci_devp
->bus->number) & 0xFF))
4601 PCI_SLOT(pci_devp->devfn),((((PCI_SLOT(pci_devp->devfn)) & 0x1F) << 11) | (
((PCI_FUNC(pci_devp->devfn)) & 0x7) << 8) | ((pci_devp
->bus->number) & 0xFF))
4602 PCI_FUNC(pci_devp->devfn))((((PCI_SLOT(pci_devp->devfn)) & 0x1F) << 11) | (
((PCI_FUNC(pci_devp->devfn)) & 0x7) << 8) | ((pci_devp
->bus->number) & 0xFF))
;
4603 shp->unchecked_isa_dma = FALSE0;
4604 share_irq = TRUE1;
4605#endif /* CONFIG_PCI */
4606#endif /* version >= v2.1.93 */
4607 }
4608
4609 /*
4610 * Read the board configuration.
4611 */
4612 if (ASC_NARROW_BOARD(boardp)(((boardp)->flags & 0x04) == 0)) {
4613 /*
4614 * NOTE: AscInitGetConfig() may change the board's
4615 * bus_type value. The asc_bus[bus] value should no
4616 * longer be used. If the bus_type field must be
4617 * referenced only use the bit-wise AND operator "&".
4618 */
4619 ASC_DBG(2, "advansys_detect: AscInitGetConfig()\n");
4620 switch(ret = AscInitGetConfig(asc_dvc_varp)) {
4621 case 0: /* No error */
4622 break;
4623 case ASC_WARN_IO_PORT_ROTATE0x0001:
4624 ASC_PRINT1({ printk("advansys: "); printk(("AscInitGetConfig: board %d: I/O port address modified\n"
), (boardp->id)); }
4625"AscInitGetConfig: board %d: I/O port address modified\n",{ printk("advansys: "); printk(("AscInitGetConfig: board %d: I/O port address modified\n"
), (boardp->id)); }
4626 boardp->id){ printk("advansys: "); printk(("AscInitGetConfig: board %d: I/O port address modified\n"
), (boardp->id)); }
;
4627 break;
4628 case ASC_WARN_AUTO_CONFIG0x0008:
4629 ASC_PRINT1({ printk("advansys: "); printk(("AscInitGetConfig: board %d: I/O port increment switch enabled\n"
), (boardp->id)); }
4630"AscInitGetConfig: board %d: I/O port increment switch enabled\n",{ printk("advansys: "); printk(("AscInitGetConfig: board %d: I/O port increment switch enabled\n"
), (boardp->id)); }
4631 boardp->id){ printk("advansys: "); printk(("AscInitGetConfig: board %d: I/O port increment switch enabled\n"
), (boardp->id)); }
;
4632 break;
4633 case ASC_WARN_EEPROM_CHKSUM0x0002:
4634 ASC_PRINT1({ printk("advansys: "); printk(("AscInitGetConfig: board %d: EEPROM checksum error\n"
), (boardp->id)); }
4635"AscInitGetConfig: board %d: EEPROM checksum error\n",{ printk("advansys: "); printk(("AscInitGetConfig: board %d: EEPROM checksum error\n"
), (boardp->id)); }
4636 boardp->id){ printk("advansys: "); printk(("AscInitGetConfig: board %d: EEPROM checksum error\n"
), (boardp->id)); }
;
4637 break;
4638 case ASC_WARN_IRQ_MODIFIED0x0004:
4639 ASC_PRINT1({ printk("advansys: "); printk(("AscInitGetConfig: board %d: IRQ modified\n"
), (boardp->id)); }
4640"AscInitGetConfig: board %d: IRQ modified\n",{ printk("advansys: "); printk(("AscInitGetConfig: board %d: IRQ modified\n"
), (boardp->id)); }
4641 boardp->id){ printk("advansys: "); printk(("AscInitGetConfig: board %d: IRQ modified\n"
), (boardp->id)); }
;
4642 break;
4643 case ASC_WARN_CMD_QNG_CONFLICT0x0010:
4644 ASC_PRINT1({ printk("advansys: "); printk(("AscInitGetConfig: board %d: tag queuing enabled w/o disconnects\n"
), (boardp->id)); }
4645"AscInitGetConfig: board %d: tag queuing enabled w/o disconnects\n",{ printk("advansys: "); printk(("AscInitGetConfig: board %d: tag queuing enabled w/o disconnects\n"
), (boardp->id)); }
4646 boardp->id){ printk("advansys: "); printk(("AscInitGetConfig: board %d: tag queuing enabled w/o disconnects\n"
), (boardp->id)); }
;
4647 break;
4648 default:
4649 ASC_PRINT2({ printk("advansys: "); printk(("AscInitGetConfig: board %d: unknown warning: %x\n"
), (boardp->id), (ret)); }
4650"AscInitGetConfig: board %d: unknown warning: %x\n",{ printk("advansys: "); printk(("AscInitGetConfig: board %d: unknown warning: %x\n"
), (boardp->id), (ret)); }
4651 boardp->id, ret){ printk("advansys: "); printk(("AscInitGetConfig: board %d: unknown warning: %x\n"
), (boardp->id), (ret)); }
;
4652 break;
4653 }
4654 if ((err_code = asc_dvc_varp->err_code) != 0) {
4655 ASC_PRINT3({ printk("advansys: "); printk(("AscInitGetConfig: board %d error: init_state %x, err_code %x\n"
), (boardp->id), (asc_dvc_varp->init_state), (asc_dvc_varp
->err_code)); }
4656"AscInitGetConfig: board %d error: init_state %x, err_code %x\n",{ printk("advansys: "); printk(("AscInitGetConfig: board %d error: init_state %x, err_code %x\n"
), (boardp->id), (asc_dvc_varp->init_state), (asc_dvc_varp
->err_code)); }
4657 boardp->id, asc_dvc_varp->init_state,{ printk("advansys: "); printk(("AscInitGetConfig: board %d error: init_state %x, err_code %x\n"
), (boardp->id), (asc_dvc_varp->init_state), (asc_dvc_varp
->err_code)); }
4658 asc_dvc_varp->err_code){ printk("advansys: "); printk(("AscInitGetConfig: board %d error: init_state %x, err_code %x\n"
), (boardp->id), (asc_dvc_varp->init_state), (asc_dvc_varp
->err_code)); }
;
4659 }
4660 } else {
4661 ASC_DBG(2, "advansys_detect: AdvInitGetConfig()\n");
4662 if ((ret = AdvInitGetConfig(adv_dvc_varp)) != 0) {
4663 ASC_PRINT2("AdvInitGetConfig: board %d: warning: %x\n",{ printk("advansys: "); printk(("AdvInitGetConfig: board %d: warning: %x\n"
), (boardp->id), (ret)); }
4664 boardp->id, ret){ printk("advansys: "); printk(("AdvInitGetConfig: board %d: warning: %x\n"
), (boardp->id), (ret)); }
;
4665 }
4666 if ((err_code = adv_dvc_varp->err_code) != 0) {
4667 ASC_PRINT2({ printk("advansys: "); printk(("AdvInitGetConfig: board %d error: err_code %x\n"
), (boardp->id), (adv_dvc_varp->err_code)); }
4668"AdvInitGetConfig: board %d error: err_code %x\n",{ printk("advansys: "); printk(("AdvInitGetConfig: board %d error: err_code %x\n"
), (boardp->id), (adv_dvc_varp->err_code)); }
4669 boardp->id, adv_dvc_varp->err_code){ printk("advansys: "); printk(("AdvInitGetConfig: board %d error: err_code %x\n"
), (boardp->id), (adv_dvc_varp->err_code)); }
;
4670 }
4671 }
4672
4673 if (err_code != 0) {
4674#if LINUX_VERSION_CODE131108 >= ASC_LINUX_VERSION(1,3,0)(((1) * 65536) + ((3) * 256) + (0))
4675 kfreelinux_kfree(boardp->prtbuf);
4676#endif /* version >= v1.3.0 */
4677 scsi_unregister(shp);
4678 asc_board_count--;
4679 continue;
4680 }
4681
4682 /*
4683 * Save the EEPROM configuration so that it can be displayed
4684 * from /proc/scsi/advansys/[0...].
4685 */
4686 if (ASC_NARROW_BOARD(boardp)(((boardp)->flags & 0x04) == 0)) {
4687
4688 ASCEEP_CONFIG *ep;
4689
4690 /*
4691 * Set the adapter's target id bit in the 'init_tidmask' field.
4692 */
4693 boardp->init_tidmask |=
4694 ADV_TID_TO_TIDMASK(asc_dvc_varp->cfg->chip_scsi_id)(0x01 << ((asc_dvc_varp->cfg->chip_scsi_id) &
15))
;
4695
4696 /*
4697 * Save EEPROM settings for the board.
4698 */
4699 ep = &boardp->eep_config.asc_eep;
4700
4701 ep->init_sdtr = asc_dvc_varp->cfg->sdtr_enable;
4702 ep->disc_enable = asc_dvc_varp->cfg->disc_enable;
4703 ep->use_cmd_qng = asc_dvc_varp->cfg->cmd_qng_enabled;
4704 ep->isa_dma_speed = asc_dvc_varp->cfg->isa_dma_speed;
4705 ep->start_motor = asc_dvc_varp->start_motor;
4706 ep->cntl = asc_dvc_varp->dvc_cntl;
4707 ep->no_scam = asc_dvc_varp->no_scam;
4708 ep->max_total_qng = asc_dvc_varp->max_total_qng;
4709 ep->chip_scsi_id = asc_dvc_varp->cfg->chip_scsi_id;
4710 /* 'max_tag_qng' is set to the same value for every device. */
4711 ep->max_tag_qng = asc_dvc_varp->cfg->max_tag_qng[0];
4712 ep->adapter_info[0] = asc_dvc_varp->cfg->adapter_info[0];
4713 ep->adapter_info[1] = asc_dvc_varp->cfg->adapter_info[1];
4714 ep->adapter_info[2] = asc_dvc_varp->cfg->adapter_info[2];
4715 ep->adapter_info[3] = asc_dvc_varp->cfg->adapter_info[3];
4716 ep->adapter_info[4] = asc_dvc_varp->cfg->adapter_info[4];
4717 ep->adapter_info[5] = asc_dvc_varp->cfg->adapter_info[5];
4718 ep->adapter_info[6] = asc_dvc_varp->cfg->adapter_info[6];
4719
4720 /*
4721 * Modify board configuration.
4722 */
4723 ASC_DBG(2, "advansys_detect: AscInitSetConfig()\n");
4724 switch (ret = AscInitSetConfig(asc_dvc_varp)) {
4725 case 0: /* No error. */
4726 break;
4727 case ASC_WARN_IO_PORT_ROTATE0x0001:
4728 ASC_PRINT1({ printk("advansys: "); printk(("AscInitSetConfig: board %d: I/O port address modified\n"
), (boardp->id)); }
4729"AscInitSetConfig: board %d: I/O port address modified\n",{ printk("advansys: "); printk(("AscInitSetConfig: board %d: I/O port address modified\n"
), (boardp->id)); }
4730 boardp->id){ printk("advansys: "); printk(("AscInitSetConfig: board %d: I/O port address modified\n"
), (boardp->id)); }
;
4731 break;
4732 case ASC_WARN_AUTO_CONFIG0x0008:
4733 ASC_PRINT1({ printk("advansys: "); printk(("AscInitSetConfig: board %d: I/O port increment switch enabled\n"
), (boardp->id)); }
4734"AscInitSetConfig: board %d: I/O port increment switch enabled\n",{ printk("advansys: "); printk(("AscInitSetConfig: board %d: I/O port increment switch enabled\n"
), (boardp->id)); }
4735 boardp->id){ printk("advansys: "); printk(("AscInitSetConfig: board %d: I/O port increment switch enabled\n"
), (boardp->id)); }
;
4736 break;
4737 case ASC_WARN_EEPROM_CHKSUM0x0002:
4738 ASC_PRINT1({ printk("advansys: "); printk(("AscInitSetConfig: board %d: EEPROM checksum error\n"
), (boardp->id)); }
4739"AscInitSetConfig: board %d: EEPROM checksum error\n",{ printk("advansys: "); printk(("AscInitSetConfig: board %d: EEPROM checksum error\n"
), (boardp->id)); }
4740 boardp->id){ printk("advansys: "); printk(("AscInitSetConfig: board %d: EEPROM checksum error\n"
), (boardp->id)); }
;
4741 break;
4742 case ASC_WARN_IRQ_MODIFIED0x0004:
4743 ASC_PRINT1({ printk("advansys: "); printk(("AscInitSetConfig: board %d: IRQ modified\n"
), (boardp->id)); }
4744"AscInitSetConfig: board %d: IRQ modified\n",{ printk("advansys: "); printk(("AscInitSetConfig: board %d: IRQ modified\n"
), (boardp->id)); }
4745 boardp->id){ printk("advansys: "); printk(("AscInitSetConfig: board %d: IRQ modified\n"
), (boardp->id)); }
;
4746 break;
4747 case ASC_WARN_CMD_QNG_CONFLICT0x0010:
4748 ASC_PRINT1({ printk("advansys: "); printk(("AscInitSetConfig: board %d: tag queuing w/o disconnects\n"
), (boardp->id)); }
4749"AscInitSetConfig: board %d: tag queuing w/o disconnects\n",{ printk("advansys: "); printk(("AscInitSetConfig: board %d: tag queuing w/o disconnects\n"
), (boardp->id)); }
4750 boardp->id){ printk("advansys: "); printk(("AscInitSetConfig: board %d: tag queuing w/o disconnects\n"
), (boardp->id)); }
;
4751 break;
4752 default:
4753 ASC_PRINT2({ printk("advansys: "); printk(("AscInitSetConfig: board %d: unknown warning: %x\n"
), (boardp->id), (ret)); }
4754"AscInitSetConfig: board %d: unknown warning: %x\n",{ printk("advansys: "); printk(("AscInitSetConfig: board %d: unknown warning: %x\n"
), (boardp->id), (ret)); }
4755 boardp->id, ret){ printk("advansys: "); printk(("AscInitSetConfig: board %d: unknown warning: %x\n"
), (boardp->id), (ret)); }
;
4756 break;
4757 }
4758 if (asc_dvc_varp->err_code != 0) {
4759 ASC_PRINT3({ printk("advansys: "); printk(("AscInitSetConfig: board %d error: init_state %x, err_code %x\n"
), (boardp->id), (asc_dvc_varp->init_state), (asc_dvc_varp
->err_code)); }
4760"AscInitSetConfig: board %d error: init_state %x, err_code %x\n",{ printk("advansys: "); printk(("AscInitSetConfig: board %d error: init_state %x, err_code %x\n"
), (boardp->id), (asc_dvc_varp->init_state), (asc_dvc_varp
->err_code)); }
4761 boardp->id, asc_dvc_varp->init_state,{ printk("advansys: "); printk(("AscInitSetConfig: board %d error: init_state %x, err_code %x\n"
), (boardp->id), (asc_dvc_varp->init_state), (asc_dvc_varp
->err_code)); }
4762 asc_dvc_varp->err_code){ printk("advansys: "); printk(("AscInitSetConfig: board %d error: init_state %x, err_code %x\n"
), (boardp->id), (asc_dvc_varp->init_state), (asc_dvc_varp
->err_code)); }
;
4763#if LINUX_VERSION_CODE131108 >= ASC_LINUX_VERSION(1,3,0)(((1) * 65536) + ((3) * 256) + (0))
4764 kfreelinux_kfree(boardp->prtbuf);
4765#endif /* version >= v1.3.0 */
4766 scsi_unregister(shp);
4767 asc_board_count--;
4768 continue;
4769 }
4770
4771 /*
4772 * Finish initializing the 'Scsi_Host' structure.
4773 */
4774 /* AscInitSetConfig() will set the IRQ for non-PCI boards. */
4775 if ((asc_dvc_varp->bus_type & ASC_IS_PCI(0x0004)) == 0) {
4776 shp->irq = asc_dvc_varp->irq_no;
4777 }
4778 } else {
4779
4780 ADVEEP_CONFIG *ep;
4781
4782 /*
4783 * Save Wide EEP Configuration Information.
4784 */
4785 ep = &boardp->eep_config.adv_eep;
4786
4787 ep->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
4788 ep->max_host_qng = adv_dvc_varp->max_host_qng;
4789 ep->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
4790 ep->termination = adv_dvc_varp->cfg->termination;
4791 ep->disc_enable = adv_dvc_varp->cfg->disc_enable;
4792 ep->bios_ctrl = adv_dvc_varp->bios_ctrl;
4793 ep->wdtr_able = adv_dvc_varp->wdtr_able;
4794 ep->sdtr_able = adv_dvc_varp->sdtr_able;
4795 ep->ultra_able = adv_dvc_varp->ultra_able;
4796 ep->tagqng_able = adv_dvc_varp->tagqng_able;
4797 ep->start_motor = adv_dvc_varp->start_motor;
4798 ep->scsi_reset_delay = adv_dvc_varp->scsi_reset_wait;
4799 ep->bios_boot_delay = adv_dvc_varp->cfg->bios_boot_wait;
4800 ep->serial_number_word1 = adv_dvc_varp->cfg->serial1;
4801 ep->serial_number_word2 = adv_dvc_varp->cfg->serial2;
4802 ep->serial_number_word3 = adv_dvc_varp->cfg->serial3;
4803
4804 /*
4805 * Set the adapter's target id bit in the 'init_tidmask' field.
4806 */
4807 boardp->init_tidmask |=
4808 ADV_TID_TO_TIDMASK(adv_dvc_varp->chip_scsi_id)(0x01 << ((adv_dvc_varp->chip_scsi_id) & 15));
4809
4810 /*
4811 * Finish initializing the 'Scsi_Host' structure.
4812 */
4813 shp->irq = adv_dvc_varp->irq_no;
4814 }
4815
4816#if LINUX_VERSION_CODE131108 >= ASC_LINUX_VERSION(1,3,89)(((1) * 65536) + ((3) * 256) + (89))
4817 /*
4818 * Channels are numbered beginning with 0. For AdvanSys One host
4819 * structure supports one channel. Multi-channel boards have a
4820 * separate host structure for each channel.
4821 */
4822 shp->max_channel = 0;
4823#endif /* version >= v1.3.89 */
4824 if (ASC_NARROW_BOARD(boardp)(((boardp)->flags & 0x04) == 0)) {
4825 shp->max_id = ASC_MAX_TID7 + 1;
4826 shp->max_lun = ASC_MAX_LUN7 + 1;
4827
4828 shp->io_port = asc_dvc_varp->iop_base;
4829 shp->n_io_port = ASC_IOADR_GAP0x10;
4830 shp->this_id = asc_dvc_varp->cfg->chip_scsi_id;
4831
4832 /* Set maximum number of queues the adapter can handle. */
4833 shp->can_queue = asc_dvc_varp->max_total_qng;
4834 } else {
4835 shp->max_id = ADV_MAX_TID15 + 1;
4836 shp->max_lun = ADV_MAX_LUN7 + 1;
4837
4838 /*
4839 * Save the I/O Port address and length even though the
4840 * in v1.3.0 and greater kernels the region is not used
4841 * by a Wide board. Instead the board is accessed with
4842 * Memory Mapped I/O.
4843 */
4844 shp->io_port = iop;
4845 shp->n_io_port = ADV_CONDOR_IOLEN0x40;
4846
4847 shp->this_id = adv_dvc_varp->chip_scsi_id;
4848
4849 /* Set maximum number of queues the adapter can handle. */
4850 shp->can_queue = adv_dvc_varp->max_host_qng;
4851 }
4852
4853#if LINUX_VERSION_CODE131108 < ASC_LINUX_VERSION(1,3,89)(((1) * 65536) + ((3) * 256) + (89))
4854 /*
4855 * In old kernels without tag queuing support and with memory
4856 * allocation problems set a conservative 'cmd_per_lun' value.
4857 */
4858#ifdef MODULE
4859 shp->cmd_per_lun = 1;
4860#else /* MODULE */
4861 shp->cmd_per_lun = 4;
4862#endif /* MODULE */
4863 ASC_DBG1(1, "advansys_detect: cmd_per_lun: %d\n", shp->cmd_per_lun);
4864#else /* version >= v1.3.89 */
4865 /*
4866 * Following v1.3.89, 'cmd_per_lun' is no longer needed
4867 * and should be set to zero.
4868 *
4869 * But because of a bug introduced in v1.3.89 if the driver is
4870 * compiled as a module and 'cmd_per_lun' is zero, the Mid-Level
4871 * SCSI function 'allocate_device' will panic. To allow the driver
4872 * to work as a module in these kernels set 'cmd_per_lun' to 1.
4873 */
4874#ifdef MODULE
4875 shp->cmd_per_lun = 1;
4876#else /* MODULE */
4877 shp->cmd_per_lun = 0;
4878#endif /* MODULE */
4879 /*
4880 * Use the host 'select_queue_depths' function to determine
4881 * the number of commands to queue per device.
4882 */
4883 shp->select_queue_depths = advansys_select_queue_depths;
4884#endif /* version >= v1.3.89 */
4885
4886 /*
4887 * Set the maximum number of scatter-gather elements the
4888 * adapter can handle.
4889 */
4890 if (ASC_NARROW_BOARD(boardp)(((boardp)->flags & 0x04) == 0)) {
4891 /*
4892 * Allow two commands with 'sg_tablesize' scatter-gather
4893 * elements to be executed simultaneously. This value is
4894 * the theoretical hardware limit. It may be decreased
4895 * below.
4896 */
4897 shp->sg_tablesize =
4898 (((asc_dvc_varp->max_total_qng - 2) / 2) *
4899 ASC_SG_LIST_PER_Q7) + 1;
4900 } else {
4901 shp->sg_tablesize = ADV_MAX_SG_LIST64;
4902 }
4903
4904#ifdef MODULE
4905 /*
4906 * If the driver is compiled as a module, set a limit on the
4907 * 'sg_tablesize' value to prevent memory allocation failures.
4908 * Memory allocation errors are more likely to occur at module
4909 * load time, then at driver initialization time.
4910 */
4911 if (shp->sg_tablesize > 64) {
4912 shp->sg_tablesize = 64;
4913 }
4914#endif /* MODULE */
4915
4916 /*
4917 * The value of 'sg_tablesize' can not exceed the SCSI
4918 * mid-level driver definition of SG_ALL. SG_ALL also
4919 * must not be exceeded, because it is used to define the
4920 * size of the scatter-gather table in 'struct asc_sg_head'.
4921 */
4922 if (shp->sg_tablesize > SG_ALL0xff) {
4923 shp->sg_tablesize = SG_ALL0xff;
4924 }
4925
4926 ASC_DBG1(1, "advansys_detect: sg_tablesize: %d\n",
4927 shp->sg_tablesize);
4928
4929 /* BIOS start address. */
4930 if (ASC_NARROW_BOARD(boardp)(((boardp)->flags & 0x04) == 0)) {
4931 shp->base = (char *) ((ulong) AscGetChipBiosAddress(
4932 asc_dvc_varp->iop_base,
4933 asc_dvc_varp->bus_type));
4934 } else {
4935 /*
4936 * Fill-in BIOS board variables. The Wide BIOS saves
4937 * information in LRAM that is used by the driver.
4938 */
4939 AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_SIGNATURE,do { ((*(volatile unsigned short *) ((adv_dvc_varp->iop_base
) + 0x04)) = ((0x58))); (boardp->bios_signature) = (*(volatile
unsigned short *) ((adv_dvc_varp->iop_base) + 0x06)); } while
(0)
4940 boardp->bios_signature)do { ((*(volatile unsigned short *) ((adv_dvc_varp->iop_base
) + 0x04)) = ((0x58))); (boardp->bios_signature) = (*(volatile
unsigned short *) ((adv_dvc_varp->iop_base) + 0x06)); } while
(0)
;
4941 AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_VERSION,do { ((*(volatile unsigned short *) ((adv_dvc_varp->iop_base
) + 0x04)) = ((0x5A))); (boardp->bios_version) = (*(volatile
unsigned short *) ((adv_dvc_varp->iop_base) + 0x06)); } while
(0)
4942 boardp->bios_version)do { ((*(volatile unsigned short *) ((adv_dvc_varp->iop_base
) + 0x04)) = ((0x5A))); (boardp->bios_version) = (*(volatile
unsigned short *) ((adv_dvc_varp->iop_base) + 0x06)); } while
(0)
;
4943 AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_CODESEG,do { ((*(volatile unsigned short *) ((adv_dvc_varp->iop_base
) + 0x04)) = ((0x54))); (boardp->bios_codeseg) = (*(volatile
unsigned short *) ((adv_dvc_varp->iop_base) + 0x06)); } while
(0)
4944 boardp->bios_codeseg)do { ((*(volatile unsigned short *) ((adv_dvc_varp->iop_base
) + 0x04)) = ((0x54))); (boardp->bios_codeseg) = (*(volatile
unsigned short *) ((adv_dvc_varp->iop_base) + 0x06)); } while
(0)
;
4945 AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_CODELEN,do { ((*(volatile unsigned short *) ((adv_dvc_varp->iop_base
) + 0x04)) = ((0x56))); (boardp->bios_codelen) = (*(volatile
unsigned short *) ((adv_dvc_varp->iop_base) + 0x06)); } while
(0)
4946 boardp->bios_codelen)do { ((*(volatile unsigned short *) ((adv_dvc_varp->iop_base
) + 0x04)) = ((0x56))); (boardp->bios_codelen) = (*(volatile
unsigned short *) ((adv_dvc_varp->iop_base) + 0x06)); } while
(0)
;
4947
4948 ASC_DBG2(1,
4949 "advansys_detect: bios_signature %x, bios_version %x\n",
4950 boardp->bios_signature, boardp->bios_version);
4951
4952 ASC_DBG2(1,
4953 "advansys_detect: bios_codeseg %x, bios_codelen %x\n",
4954 boardp->bios_codeseg, boardp->bios_codelen);
4955
4956 /*
4957 * If the BIOS saved a valid signature, then fill in
4958 * the BIOS code segment base address.
4959 */
4960 if (boardp->bios_signature == 0x55AA) {
4961 /*
4962 * Convert x86 realmode code segment to a linear
4963 * address by shifting left 4.
4964 */
4965 shp->base = (uchar *) (boardp->bios_codeseg << 4);
4966 } else {
4967 shp->base = 0;
4968 }
4969 }
4970
4971 /*
4972 * Register Board Resources - I/O Port, DMA, IRQ
4973 */
4974
4975 /* Register I/O port range. */
4976 ASC_DBG(2, "advansys_detect: request_region()\n");
4977 request_region(shp->io_port, shp->n_io_port, "advansys");
4978
4979 /* Register DMA Channel for Narrow boards. */
4980 shp->dma_channel = NO_ISA_DMA0xff; /* Default to no ISA DMA. */
4981 if (ASC_NARROW_BOARD(boardp)(((boardp)->flags & 0x04) == 0)) {
4982 /* Register DMA channel for ISA bus. */
4983 if (asc_dvc_varp->bus_type & ASC_IS_ISA(0x0001)) {
4984 shp->dma_channel = asc_dvc_varp->cfg->isa_dma_channel;
4985 if ((ret =
4986 request_dma(shp->dma_channel, "advansys")) != 0) {
4987 ASC_PRINT3({ printk("advansys: "); printk(("advansys_detect: board %d: request_dma() %d failed %d\n"
), (boardp->id), (shp->dma_channel), (ret)); }
4988"advansys_detect: board %d: request_dma() %d failed %d\n",{ printk("advansys: "); printk(("advansys_detect: board %d: request_dma() %d failed %d\n"
), (boardp->id), (shp->dma_channel), (ret)); }
4989 boardp->id, shp->dma_channel, ret){ printk("advansys: "); printk(("advansys_detect: board %d: request_dma() %d failed %d\n"
), (boardp->id), (shp->dma_channel), (ret)); }
;
4990 release_region(shp->io_port, shp->n_io_port);
4991#if LINUX_VERSION_CODE131108 >= ASC_LINUX_VERSION(1,3,0)(((1) * 65536) + ((3) * 256) + (0))
4992 kfreelinux_kfree(boardp->prtbuf);
4993#endif /* version >= v1.3.0 */
4994 scsi_unregister(shp);
4995 asc_board_count--;
4996 continue;
4997 }
4998 AscEnableIsaDma(shp->dma_channel);
4999 }
5000 }
5001
5002 /* Register IRQ Number. */
5003 ASC_DBG1(2, "advansys_detect: request_irq() %d\n", shp->irq);
5004#if LINUX_VERSION_CODE131108 < ASC_LINUX_VERSION(1,3,70)(((1) * 65536) + ((3) * 256) + (70))
5005 if ((ret = request_irq(shp->irq, advansys_interrupt,
5006 SA_INTERRUPT0x20000000, "advansys")) != 0)
5007#else /* version >= v1.3.70 */
5008 /*
5009 * If request_irq() fails with the SA_INTERRUPT flag set,
5010 * then try again without the SA_INTERRUPT flag set. This
5011 * allows IRQ sharing to work even with other drivers that
5012 * do not set the SA_INTERRUPT flag.
5013 *
5014 * If SA_INTERRUPT is not set, then interrupts are enabled
5015 * before the driver interrupt function is called.
5016 */
5017 if (((ret = request_irq(shp->irq, advansys_interrupt,
5018 SA_INTERRUPT0x20000000 | (share_irq == TRUE1 ? SA_SHIRQ0x04000000 : 0),
5019 "advansys", boardp)) != 0) &&
5020 ((ret = request_irq(shp->irq, advansys_interrupt,
5021 (share_irq == TRUE1 ? SA_SHIRQ0x04000000 : 0),
5022 "advansys", boardp)) != 0))
5023#endif /* version >= v1.3.70 */
5024 {
5025 if (ret == -EBUSY16) {
5026 ASC_PRINT2({ printk("advansys: "); printk(("advansys_detect: board %d: request_irq(): IRQ %d already in use.\n"
), (boardp->id), (shp->irq)); }
5027"advansys_detect: board %d: request_irq(): IRQ %d already in use.\n",{ printk("advansys: "); printk(("advansys_detect: board %d: request_irq(): IRQ %d already in use.\n"
), (boardp->id), (shp->irq)); }
5028 boardp->id, shp->irq){ printk("advansys: "); printk(("advansys_detect: board %d: request_irq(): IRQ %d already in use.\n"
), (boardp->id), (shp->irq)); }
;
5029 } else if (ret == -EINVAL22) {
5030 ASC_PRINT2({ printk("advansys: "); printk(("advansys_detect: board %d: request_irq(): IRQ %d not valid.\n"
), (boardp->id), (shp->irq)); }
5031"advansys_detect: board %d: request_irq(): IRQ %d not valid.\n",{ printk("advansys: "); printk(("advansys_detect: board %d: request_irq(): IRQ %d not valid.\n"
), (boardp->id), (shp->irq)); }
5032 boardp->id, shp->irq){ printk("advansys: "); printk(("advansys_detect: board %d: request_irq(): IRQ %d not valid.\n"
), (boardp->id), (shp->irq)); }
;
5033 } else {
5034 ASC_PRINT3({ printk("advansys: "); printk(("advansys_detect: board %d: request_irq(): IRQ %d failed with %d\n"
), (boardp->id), (shp->irq), (ret)); }
5035"advansys_detect: board %d: request_irq(): IRQ %d failed with %d\n",{ printk("advansys: "); printk(("advansys_detect: board %d: request_irq(): IRQ %d failed with %d\n"
), (boardp->id), (shp->irq), (ret)); }
5036 boardp->id, shp->irq, ret){ printk("advansys: "); printk(("advansys_detect: board %d: request_irq(): IRQ %d failed with %d\n"
), (boardp->id), (shp->irq), (ret)); }
;
5037 }
5038 release_region(shp->io_port, shp->n_io_port);
5039#if LINUX_VERSION_CODE131108 >= ASC_LINUX_VERSION(1,3,0)(((1) * 65536) + ((3) * 256) + (0))
5040 iounmapvfree(boardp->ioremap_addr);
5041#endif /* version >= v1,3,0 */
5042 if (shp->dma_channel != NO_ISA_DMA0xff) {
5043 free_dma(shp->dma_channel);
5044 }
5045#if LINUX_VERSION_CODE131108 >= ASC_LINUX_VERSION(1,3,0)(((1) * 65536) + ((3) * 256) + (0))
5046 kfreelinux_kfree(boardp->prtbuf);
5047#endif /* version >= v1.3.0 */
5048 scsi_unregister(shp);
5049 asc_board_count--;
5050 continue;
5051 }
5052
5053 /*
5054 * Initialize board RISC chip and enable interrupts.
5055 */
5056 if (ASC_NARROW_BOARD(boardp)(((boardp)->flags & 0x04) == 0)) {
5057 ASC_DBG(2, "advansys_detect: AscInitAsc1000Driver()\n");
5058 warn_code = AscInitAsc1000Driver(asc_dvc_varp);
5059 err_code = asc_dvc_varp->err_code;
5060
5061 if (warn_code || err_code) {
5062 ASC_PRINT4({ printk("advansys: "); printk(("AscInitAsc1000Driver: board %d: error: init_state %x, warn %x error %x\n"
), (boardp->id), (asc_dvc_varp->init_state), (warn_code
), (err_code)); }
5063"AscInitAsc1000Driver: board %d: error: init_state %x, warn %x error %x\n",{ printk("advansys: "); printk(("AscInitAsc1000Driver: board %d: error: init_state %x, warn %x error %x\n"
), (boardp->id), (asc_dvc_varp->init_state), (warn_code
), (err_code)); }
5064 boardp->id, asc_dvc_varp->init_state,{ printk("advansys: "); printk(("AscInitAsc1000Driver: board %d: error: init_state %x, warn %x error %x\n"
), (boardp->id), (asc_dvc_varp->init_state), (warn_code
), (err_code)); }
5065 warn_code, err_code){ printk("advansys: "); printk(("AscInitAsc1000Driver: board %d: error: init_state %x, warn %x error %x\n"
), (boardp->id), (asc_dvc_varp->init_state), (warn_code
), (err_code)); }
;
5066 }
5067 } else {
5068 int req_cnt;
5069 adv_req_t *reqp = NULL((void *) 0);
5070 int sg_cnt;
5071 adv_sgblk_t *sgp = NULL((void *) 0);
5072
5073#if LINUX_VERSION_CODE131108 < ASC_LINUX_VERSION(1,3,0)(((1) * 65536) + ((3) * 256) + (0))
5074 req_cnt = sizeof(adv_req_buf)/sizeof(adv_req_t);
5075 sg_cnt = sizeof(adv_sgblk_buf)/sizeof(adv_sgblk_t);
5076 reqp = (adv_req_t *) &adv_req_buf[0];
5077 sgp = (adv_sgblk_t *) &adv_sgblk_buf[0];
5078#else /* version >= v1.3.0 */
5079 /*
5080 * Allocate up to 'max_host_qng' request structures for
5081 * the Wide board.
5082 */
5083 for (req_cnt = adv_dvc_varp->max_host_qng;
5084 req_cnt > 0; req_cnt--) {
5085
5086 reqp = (adv_req_t *)
5087 kmalloclinux_kmalloc(sizeof(adv_req_t) * req_cnt, GFP_ATOMIC0x01);
5088
5089 ASC_DBG3(1,
5090 "advansys_detect: reqp %x, req_cnt %d, bytes %d\n",
5091 (unsigned) reqp, req_cnt, sizeof(adv_req_t) * req_cnt);
5092
5093 if (reqp != NULL((void *) 0)) {
5094 break;
5095 }
5096 }
5097
5098 /*
5099 * Allocate up to ADV_TOT_SG_LIST request structures for
5100 * the Wide board.
5101 */
5102 for (sg_cnt = ADV_TOT_SG_LIST64; sg_cnt > 0; sg_cnt--) {
5103
5104 sgp = (adv_sgblk_t *)
5105 kmalloclinux_kmalloc(sizeof(adv_sgblk_t) * sg_cnt, GFP_ATOMIC0x01);
5106
5107 ASC_DBG3(1,
5108 "advansys_detect: sgp %x, sg_cnt %d, bytes %d\n",
5109 (unsigned) sgp, sg_cnt, sizeof(adv_sgblk_t) * sg_cnt);
5110
5111 if (sgp != NULL((void *) 0)) {
5112 break;
5113 }
5114 }
5115#endif /* version >= v1.3.0 */
5116
5117 /*
5118 * If no request structures or scatter-gather structures could
5119 * be allocated, then return an error. Otherwise continue with
5120 * initialization.
5121 */
5122 if (reqp == NULL((void *) 0)) {
5123 ASC_PRINT1({ printk("advansys: "); printk(("advansys_detect: board %d: error: failed to kmalloc() adv_req_t buffer.\n"
), (boardp->id)); }
5124"advansys_detect: board %d: error: failed to kmalloc() adv_req_t buffer.\n",{ printk("advansys: "); printk(("advansys_detect: board %d: error: failed to kmalloc() adv_req_t buffer.\n"
), (boardp->id)); }
5125 boardp->id){ printk("advansys: "); printk(("advansys_detect: board %d: error: failed to kmalloc() adv_req_t buffer.\n"
), (boardp->id)); }
;
5126 err_code = ADV_ERROR(-1);
5127 } else if (sgp == NULL((void *) 0)) {
5128 kfreelinux_kfree(reqp);
5129 ASC_PRINT1({ printk("advansys: "); printk(("advansys_detect: board %d: error: failed to kmalloc() adv_sgblk_t buffer.\n"
), (boardp->id)); }
5130"advansys_detect: board %d: error: failed to kmalloc() adv_sgblk_t buffer.\n",{ printk("advansys: "); printk(("advansys_detect: board %d: error: failed to kmalloc() adv_sgblk_t buffer.\n"
), (boardp->id)); }
5131 boardp->id){ printk("advansys: "); printk(("advansys_detect: board %d: error: failed to kmalloc() adv_sgblk_t buffer.\n"
), (boardp->id)); }
;
5132 err_code = ADV_ERROR(-1);
5133 } else {
5134
5135 /*
5136 * Save original pointer for kfree() in case the
5137 * driver is built as a module and can be unloaded.
5138 */
5139 boardp->orig_reqp = reqp;
5140
5141 /*
5142 * Point 'adv_reqp' to the request structures and
5143 * link them together.
5144 */
5145 req_cnt--;
5146 reqp[req_cnt].next_reqp = NULL((void *) 0);
5147 for (; req_cnt > 0; req_cnt--) {
5148 reqp[req_cnt - 1].next_reqp = &reqp[req_cnt];
5149 }
5150 boardp->adv_reqp = &reqp[0];
5151
5152 /*
5153 * Save original pointer for kfree() in case the
5154 * driver is built as a module and can be unloaded.
5155 */
5156 boardp->orig_sgblkp = sgp;
5157
5158 /*
5159 * Point 'adv_sgblkp' to the request structures and
5160 * link them together.
5161 */
5162 sg_cnt--;
5163 sgp[sg_cnt].next_sgblkp = NULL((void *) 0);
5164 for (; sg_cnt > 0; sg_cnt--) {
5165 sgp[sg_cnt - 1].next_sgblkp = &sgp[sg_cnt];
5166 }
5167 boardp->adv_sgblkp = &sgp[0];
5168
5169 ASC_DBG(2, "advansys_detect: AdvInitAsc3550Driver()\n");
5170 warn_code = AdvInitAsc3550Driver(adv_dvc_varp);
5171 err_code = adv_dvc_varp->err_code;
5172
5173 if (warn_code || err_code) {
5174 ASC_PRINT3({ printk("advansys: "); printk(("AdvInitAsc3550Driver: board %d: error: warn %x, error %x\n"
), (boardp->id), (warn_code), (adv_dvc_varp->err_code))
; }
5175"AdvInitAsc3550Driver: board %d: error: warn %x, error %x\n",{ printk("advansys: "); printk(("AdvInitAsc3550Driver: board %d: error: warn %x, error %x\n"
), (boardp->id), (warn_code), (adv_dvc_varp->err_code))
; }
5176 boardp->id, warn_code, adv_dvc_varp->err_code){ printk("advansys: "); printk(("AdvInitAsc3550Driver: board %d: error: warn %x, error %x\n"
), (boardp->id), (warn_code), (adv_dvc_varp->err_code))
; }
;
5177 }
5178 }
5179 }
5180
5181 if (err_code != 0) {
5182 release_region(shp->io_port, shp->n_io_port);
5183 if (ASC_WIDE_BOARD(boardp)((boardp)->flags & 0x04)) {
5184#if LINUX_VERSION_CODE131108 >= ASC_LINUX_VERSION(1,3,0)(((1) * 65536) + ((3) * 256) + (0))
5185 iounmapvfree(boardp->ioremap_addr);
5186#endif /* version >= v1,3,0 */
5187 if (boardp->orig_reqp) {
5188 kfreelinux_kfree(boardp->orig_reqp);
5189 boardp->orig_reqp = boardp->adv_reqp = NULL((void *) 0);
5190 }
5191 if (boardp->orig_sgblkp) {
5192 kfreelinux_kfree(boardp->orig_sgblkp);
5193 boardp->orig_sgblkp = boardp->adv_sgblkp = NULL((void *) 0);
5194 }
5195 }
5196 if (shp->dma_channel != NO_ISA_DMA0xff) {
5197 free_dma(shp->dma_channel);
5198 }
5199#if LINUX_VERSION_CODE131108 >= ASC_LINUX_VERSION(1,3,0)(((1) * 65536) + ((3) * 256) + (0))
5200 kfreelinux_kfree(boardp->prtbuf);
5201#endif /* version >= v1.3.0 */
5202#if LINUX_VERSION_CODE131108 < ASC_LINUX_VERSION(1,3,70)(((1) * 65536) + ((3) * 256) + (70))
5203 free_irq(shp->irq);
5204#else /* version >= v1.3.70 */
5205 free_irq(shp->irq, boardp);
5206#endif /* version >= v1.3.70 */
5207 scsi_unregister(shp);
5208 asc_board_count--;
5209 continue;
5210 }
5211 ASC_DBG_PRT_SCSI_HOST(2, shp);
5212 }
5213 }
5214 ASC_DBG1(1, "advansys_detect: done: asc_board_count %d\n", asc_board_count);
5215 return asc_board_count;
5216}
5217
5218/*
5219 * advansys_release()
5220 *
5221 * Release resources allocated for a single AdvanSys adapter.
5222 */
5223int
5224advansys_release(struct Scsi_Host *shp)
5225{
5226 asc_board_t *boardp;
5227
5228 ASC_DBG(1, "advansys_release: begin\n");
5229 boardp = ASC_BOARDP(shp)((asc_board_t *) &((shp)->hostdata));
5230#if LINUX_VERSION_CODE131108 < ASC_LINUX_VERSION(1,3,70)(((1) * 65536) + ((3) * 256) + (70))
5231 free_irq(shp->irq);
5232#else /* version >= v1.3.70 */
5233 free_irq(shp->irq, boardp);
5234#endif /* version >= v1.3.70 */
5235 if (shp->dma_channel != NO_ISA_DMA0xff) {
5236 ASC_DBG(1, "advansys_release: free_dma()\n");
5237 free_dma(shp->dma_channel);
5238 }
5239 release_region(shp->io_port, shp->n_io_port);
5240 if (ASC_WIDE_BOARD(boardp)((boardp)->flags & 0x04)) {
5241#if LINUX_VERSION_CODE131108 >= ASC_LINUX_VERSION(1,3,0)(((1) * 65536) + ((3) * 256) + (0))
5242 iounmapvfree(boardp->ioremap_addr);
5243#endif /* version >= v1,3,0 */
5244 if (boardp->orig_reqp) {
5245 kfreelinux_kfree(boardp->orig_reqp);
5246 boardp->orig_reqp = boardp->adv_reqp = NULL((void *) 0);
5247 }
5248 if (boardp->orig_sgblkp) {
5249 kfreelinux_kfree(boardp->orig_sgblkp);
5250 boardp->orig_sgblkp = boardp->adv_sgblkp = NULL((void *) 0);
5251 }
5252 }
5253#if LINUX_VERSION_CODE131108 >= ASC_LINUX_VERSION(1,3,0)(((1) * 65536) + ((3) * 256) + (0))
5254 ASC_ASSERT(boardp->prtbuf != NULL){ if (!(boardp->prtbuf != ((void *) 0))) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 5254); } }
;
5255 kfreelinux_kfree(boardp->prtbuf);
5256#endif /* version >= v1.3.0 */
5257 scsi_unregister(shp);
5258 ASC_DBG(1, "advansys_release: end\n");
5259 return 0;
5260}
5261
5262/*
5263 * advansys_info()
5264 *
5265 * Return suitable for printing on the console with the argument
5266 * adapter's configuration information.
5267 *
5268 * Note: The information line should not exceed ASC_INFO_SIZE bytes,
5269 * otherwise the static 'info' array will be overrun.
5270 */
5271const char *
5272advansys_info(struct Scsi_Host *shp)
5273{
5274 static char info[ASC_INFO_SIZE128];
5275 asc_board_t *boardp;
5276 ASC_DVC_VAR *asc_dvc_varp;
5277 ADV_DVC_VAR *adv_dvc_varp;
5278 char *busname;
5279
5280 boardp = ASC_BOARDP(shp)((asc_board_t *) &((shp)->hostdata));
5281 if (ASC_NARROW_BOARD(boardp)(((boardp)->flags & 0x04) == 0)) {
5282 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
5283 ASC_DBG(1, "advansys_info: begin\n");
5284 if (asc_dvc_varp->bus_type & ASC_IS_ISA(0x0001)) {
5285 if ((asc_dvc_varp->bus_type & ASC_IS_ISAPNP(0x0081)) == ASC_IS_ISAPNP(0x0081)) {
5286 busname = "ISA PnP";
5287 } else {
5288 busname = "ISA";
5289 }
5290 sprintflinux_sprintf(info,
5291#if LINUX_VERSION_CODE131108 < ASC_LINUX_VERSION(2,1,92)(((2) * 65536) + ((1) * 256) + (92))
5292"AdvanSys SCSI %s: %s %u CDB: BIOS %X, IO %X/%X, IRQ %u, DMA %u",
5293#else /* version >= v2.1.92 */
5294"AdvanSys SCSI %s: %s %u CDB: BIOS %X, IO %lX/%X, IRQ %u, DMA %u",
5295#endif /* version >= v2.1.92 */
5296 ASC_VERSION"3.1E", busname, asc_dvc_varp->max_total_qng,
5297 (unsigned) shp->base,
5298 shp->io_port, shp->n_io_port - 1,
5299 shp->irq, shp->dma_channel);
5300 } else if (asc_dvc_varp->bus_type & ASC_IS_PCI(0x0004)) {
5301 if ((asc_dvc_varp->bus_type & ASC_IS_PCI_ULTRA(0x0104))
5302 == ASC_IS_PCI_ULTRA(0x0104)) {
5303 busname = "PCI Ultra";
5304 } else {
5305 busname = "PCI";
5306 }
5307 sprintflinux_sprintf(info,
5308#if LINUX_VERSION_CODE131108 < ASC_LINUX_VERSION(2,1,92)(((2) * 65536) + ((1) * 256) + (92))
5309 "AdvanSys SCSI %s: %s %u CDB: IO %X/%X, IRQ %u",
5310#else /* version >= v2.1.92 */
5311 "AdvanSys SCSI %s: %s %u CDB: IO %lX/%X, IRQ %u",
5312#endif /* version >= v2.1.92 */
5313 ASC_VERSION"3.1E", busname, asc_dvc_varp->max_total_qng,
5314 shp->io_port, shp->n_io_port - 1, shp->irq);
5315 } else {
5316 if (asc_dvc_varp->bus_type & ASC_IS_VL(0x0040)) {
5317 busname = "VL";
5318 } else if (asc_dvc_varp->bus_type & ASC_IS_EISA(0x0002)) {
5319 busname = "EISA";
5320 } else {
5321 busname = "?";
5322 ASC_PRINT2({ printk("advansys: "); printk(("advansys_info: board %d: unknown bus type %d\n"
), (boardp->id), (asc_dvc_varp->bus_type)); }
5323 "advansys_info: board %d: unknown bus type %d\n",{ printk("advansys: "); printk(("advansys_info: board %d: unknown bus type %d\n"
), (boardp->id), (asc_dvc_varp->bus_type)); }
5324 boardp->id, asc_dvc_varp->bus_type){ printk("advansys: "); printk(("advansys_info: board %d: unknown bus type %d\n"
), (boardp->id), (asc_dvc_varp->bus_type)); }
;
5325 }
5326 sprintflinux_sprintf(info,
5327#if LINUX_VERSION_CODE131108 < ASC_LINUX_VERSION(2,1,92)(((2) * 65536) + ((1) * 256) + (92))
5328 "AdvanSys SCSI %s: %s %u CDB: BIOS %X, IO %X/%X, IRQ %u",
5329#else /* version >= v2.1.92 */
5330 "AdvanSys SCSI %s: %s %u CDB: BIOS %X, IO %lX/%X, IRQ %u",
5331#endif /* version >= v2.1.92 */
5332 ASC_VERSION"3.1E", busname, asc_dvc_varp->max_total_qng,
5333 (unsigned) shp->base, shp->io_port - 1,
5334 shp->n_io_port, shp->irq);
5335 }
5336 } else {
5337 /*
5338 * Wide Adapter Information
5339 *
5340 * Memory-mapped I/O is used instead of I/O space to access
5341 * the adapter, but display the I/O Port range. The Memory
5342 * I/O address is displayed through the driver /proc file.
5343 */
5344 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
5345 if (boardp->bios_signature == 0x55AA) {
5346 sprintflinux_sprintf(info,
5347"AdvanSys SCSI %s: PCI Ultra-Wide: BIOS %X/%X, IO %X/%X, IRQ %u",
5348 ASC_VERSION"3.1E",
5349 boardp->bios_codeseg << 4,
5350 boardp->bios_codelen > 0 ?
5351 (boardp->bios_codelen << 9) - 1 : 0,
5352 (unsigned) boardp->ioport, ADV_CONDOR_IOLEN0x40 - 1,
5353 shp->irq);
5354 } else {
5355 sprintflinux_sprintf(info,
5356"AdvanSys SCSI %s: PCI Ultra-Wide: IO %X/%X, IRQ %u",
5357 ASC_VERSION"3.1E",
5358 (unsigned) boardp->ioport,
5359 (ADV_CONDOR_IOLEN0x40 - 1),
5360 shp->irq);
5361 }
5362 }
5363 ASC_ASSERT(strlen(info) < ASC_INFO_SIZE){ if (!(strlen(info) < 128)) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 5363); } }
;
5364 ASC_DBG(1, "advansys_info: end\n");
5365 return info;
5366}
5367
5368/*
5369 * advansys_command() - polled I/O entrypoint.
5370 *
5371 * Apparently host drivers shouldn't return until the command
5372 * is finished.
5373 *
5374 * Note: This is an old interface that is no longer used by the SCSI
5375 * mid-level driver. The new interface, advansys_queuecommand(),
5376 * currently handles all requests.
5377 */
5378int
5379advansys_command(Scsi_Cmnd *scp)
5380{
5381 ASC_DBG1(1, "advansys_command: scp %x\n", (unsigned) scp);
5382 ASC_STATS(scp->host, command)(((asc_board_t *) &((scp->host)->hostdata))->asc_stats
.command++)
;
5383 scp->SCp.Status = 0; /* Set to a known state */
5384 advansys_queuecommand(scp, advansys_command_done);
5385 while (scp->SCp.Status == 0) {
5386 continue;
5387 }
5388 ASC_DBG1(1, "advansys_command: result %x\n", scp->result);
5389 return scp->result;
5390}
5391
5392/*
5393 * advansys_queuecommand() - interrupt-driven I/O entrypoint.
5394 *
5395 * This function always returns 0. Command return status is saved
5396 * in the 'scp' result field.
5397 */
5398int
5399advansys_queuecommand(Scsi_Cmnd *scp, void (*done)(Scsi_Cmnd *))
5400{
5401 struct Scsi_Host *shp;
5402 asc_board_t *boardp;
5403 long flags;
5404 Scsi_Cmnd *done_scp;
5405
5406 shp = scp->host;
5407 boardp = ASC_BOARDP(shp)((asc_board_t *) &((shp)->hostdata));
5408 ASC_STATS(shp, queuecommand)(((asc_board_t *) &((shp)->hostdata))->asc_stats.queuecommand
++)
;
5409
5410 /*
5411 * Disable interrupts to preserve request ordering and provide
5412 * mutually exclusive access to global structures used to initiate
5413 * a request.
5414 */
5415 save_flags(flags)__asm__ __volatile__("pushf ; pop %0" : "=r" (flags): :"memory"
)
;
5416 cli()__asm__ __volatile__ ("cli": : :"memory");
5417
5418 /*
5419 * Block new commands while handling a reset or abort request.
5420 */
5421 if (boardp->flags & (ASC_HOST_IN_RESET0x01 | ASC_HOST_IN_ABORT0x02)) {
5422 if (boardp->flags & ASC_HOST_IN_RESET0x01) {
5423 ASC_DBG1(1,
5424 "advansys_queuecommand: scp %x blocked for reset request\n",
5425 (unsigned) scp);
5426 scp->result = HOST_BYTE(DID_RESET)((0x08) << 16);
5427 } else {
5428 ASC_DBG1(1,
5429 "advansys_queuecommand: scp %x blocked for abort request\n",
5430 (unsigned) scp);
5431 scp->result = HOST_BYTE(DID_ABORT)((0x05) << 16);
5432 }
5433
5434 /*
5435 * Add blocked requests to the board's 'done' queue. The queued
5436 * requests will be completed at the end of the abort or reset
5437 * handling.
5438 */
5439 asc_enqueue(&boardp->done, scp, ASC_BACK2);
5440 restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory");
5441 return 0;
5442 }
5443
5444 /*
5445 * Attempt to execute any waiting commands for the board.
5446 */
5447 if (!ASC_QUEUE_EMPTY(&boardp->waiting)((&boardp->waiting)->q_tidmask == 0)) {
5448 ASC_DBG(1,
5449 "advansys_queuecommand: before asc_execute_queue() waiting\n");
5450 asc_execute_queue(&boardp->waiting);
5451 }
5452
5453 /*
5454 * Save the function pointer to Linux mid-level 'done' function
5455 * and attempt to execute the command.
5456 *
5457 * If ASC_ERROR is returned the request has been added to the
5458 * board's 'active' queue and will be completed by the interrupt
5459 * handler.
5460 *
5461 * If ASC_BUSY is returned add the request to the board's per
5462 * target waiting list.
5463 *
5464 * If an error occurred, the request will have been placed on the
5465 * board's 'done' queue and must be completed before returning.
5466 */
5467 scp->scsi_done = done;
5468 switch (asc_execute_scsi_cmnd(scp)) {
5469 case ASC_NOERROR1:
5470 break;
5471 case ASC_BUSY0:
5472 asc_enqueue(&boardp->waiting, scp, ASC_BACK2);
5473 break;
5474 case ASC_ERROR(-1):
5475 default:
5476 done_scp = asc_dequeue_list(&boardp->done, NULL((void *) 0), ASC_TID_ALL(-1));
5477 /* Interrupts could be enabled here. */
5478 asc_scsi_done_list(done_scp);
5479 break;
5480 }
5481
5482 restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory");
5483 return 0;
5484}
5485
5486/*
5487 * advansys_abort()
5488 *
5489 * Abort the command specified by 'scp'.
5490 */
5491int
5492advansys_abort(Scsi_Cmnd *scp)
5493{
5494 struct Scsi_Host *shp;
5495 asc_board_t *boardp;
5496 ASC_DVC_VAR *asc_dvc_varp;
5497 ADV_DVC_VAR *adv_dvc_varp;
5498 long flags;
5499 int do_scsi_done;
5500 int scp_found;
5501 Scsi_Cmnd *done_scp = NULL((void *) 0);
5502 int ret;
5503
5504 /* Save current flags and disable interrupts. */
5505 save_flags(flags)__asm__ __volatile__("pushf ; pop %0" : "=r" (flags): :"memory"
)
;
5506 cli()__asm__ __volatile__ ("cli": : :"memory");
5507
5508 ASC_DBG1(1, "advansys_abort: scp %x\n", (unsigned) scp);
5509
5510#ifdef ADVANSYS_STATS
5511 if (scp->host != NULL((void *) 0)) {
5512 ASC_STATS(scp->host, abort)(((asc_board_t *) &((scp->host)->hostdata))->asc_stats
.abort++)
;
5513 }
5514#endif /* ADVANSYS_STATS */
5515
5516#ifdef ADVANSYS_ASSERT
5517 do_scsi_done = ASC_ERROR(-1);
5518 scp_found = ASC_ERROR(-1);
5519 ret = ASC_ERROR(-1);
5520#endif /* ADVANSYS_ASSERT */
5521
5522#if LINUX_VERSION_CODE131108 >= ASC_LINUX_VERSION(1,3,89)(((1) * 65536) + ((3) * 256) + (89))
5523 if (scp->serial_number != scp->serial_number_at_timeout) {
5524 ASC_PRINT1({ printk("advansys: "); printk(("advansys_abort: timeout serial number changed for request %x\n"
), ((unsigned) scp)); }
5525"advansys_abort: timeout serial number changed for request %x\n",{ printk("advansys: "); printk(("advansys_abort: timeout serial number changed for request %x\n"
), ((unsigned) scp)); }
5526 (unsigned) scp){ printk("advansys: "); printk(("advansys_abort: timeout serial number changed for request %x\n"
), ((unsigned) scp)); }
;
5527 do_scsi_done = ASC_FALSE0;
5528 scp_found = ASC_FALSE0;
5529 ret = SCSI_ABORT_NOT_RUNNING4;
5530 } else
5531#endif /* version >= v1.3.89 */
5532 if ((shp = scp->host) == NULL((void *) 0)) {
5533 scp->result = HOST_BYTE(DID_ERROR)((0x07) << 16);
5534 do_scsi_done = ASC_TRUE1;
5535 scp_found = ASC_FALSE0;
5536 ret = SCSI_ABORT_ERROR5;
5537 } else if ((boardp = ASC_BOARDP(shp)((asc_board_t *) &((shp)->hostdata)))->flags &
5538 (ASC_HOST_IN_RESET0x01 | ASC_HOST_IN_ABORT0x02)) {
5539 ASC_PRINT2({ printk("advansys: "); printk(("advansys_abort: board %d: Nested host reset or abort, flags 0x%x\n"
), (boardp->id), (boardp->flags)); }
5540"advansys_abort: board %d: Nested host reset or abort, flags 0x%x\n",{ printk("advansys: "); printk(("advansys_abort: board %d: Nested host reset or abort, flags 0x%x\n"
), (boardp->id), (boardp->flags)); }
5541 boardp->id, boardp->flags){ printk("advansys: "); printk(("advansys_abort: board %d: Nested host reset or abort, flags 0x%x\n"
), (boardp->id), (boardp->flags)); }
;
5542 do_scsi_done = ASC_TRUE1;
5543 if ((asc_rmqueue(&boardp->active, scp) == ASC_TRUE1) ||
5544 (asc_rmqueue(&boardp->waiting, scp) == ASC_TRUE1)) {
5545 scp_found = ASC_TRUE1;
5546 } else {
5547 scp_found = ASC_FALSE0;
5548 }
5549 scp->result = HOST_BYTE(DID_ERROR)((0x07) << 16);
5550 ret = SCSI_ABORT_ERROR5;
5551 } else {
5552 /* Set abort flag to avoid nested reset or abort requests. */
5553 boardp->flags |= ASC_HOST_IN_ABORT0x02;
5554
5555 do_scsi_done = ASC_TRUE1;
5556 if (asc_rmqueue(&boardp->waiting, scp) == ASC_TRUE1) {
5557 /*
5558 * If asc_rmqueue() found the command on the waiting
5559 * queue, it had not been sent to the device. After
5560 * the queue is removed, no other handling is required.
5561 */
5562 ASC_DBG1(1, "advansys_abort: scp %x found on waiting queue\n",
5563 (unsigned) scp);
5564 scp_found = ASC_TRUE1;
5565 scp->result = HOST_BYTE(DID_ABORT)((0x05) << 16);
5566 ret = SCSI_ABORT_SUCCESS1;
5567 } else if (asc_isqueued(&boardp->active, scp) == ASC_TRUE1) {
5568 /*
5569 * If asc_isqueued() found the command on the active
5570 * queue, it has been sent to the device. The command
5571 * will be returned through the interrupt handler after
5572 * it has been aborted.
5573 */
5574
5575 if (ASC_NARROW_BOARD(boardp)(((boardp)->flags & 0x04) == 0)) {
5576 /*
5577 * Narrow Board
5578 */
5579 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
5580 scp->result = HOST_BYTE(DID_ABORT)((0x05) << 16);
5581
5582 sti()__asm__ __volatile__ ("sti": : :"memory"); /* Enable interrupts for AscAbortSRB(). */
5583 ASC_DBG1(1, "advansys_abort: before AscAbortSRB(), scp %x\n",
5584 (unsigned) scp);
5585 switch (AscAbortSRB(asc_dvc_varp, (ulong) scp)) {
5586 case ASC_TRUE1:
5587 /* asc_isr_callback() will be called */
5588 ASC_DBG(1, "advansys_abort: AscAbortSRB() TRUE\n");
5589 ret = SCSI_ABORT_PENDING2;
5590 break;
5591 case ASC_FALSE0:
5592 /* Request has apparently already completed. */
5593 ASC_DBG(1, "advansys_abort: AscAbortSRB() FALSE\n");
5594 ret = SCSI_ABORT_NOT_RUNNING4;
5595 break;
5596 case ASC_ERROR(-1):
5597 default:
5598 ASC_DBG(1, "advansys_abort: AscAbortSRB() ERROR\n");
5599 ret = SCSI_ABORT_ERROR5;
5600 break;
5601 }
5602 cli()__asm__ __volatile__ ("cli": : :"memory");
5603 } else {
5604 /*
5605 * Wide Board
5606 */
5607 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
5608 scp->result = HOST_BYTE(DID_ABORT)((0x05) << 16);
5609
5610 ASC_DBG1(1, "advansys_abort: before AdvAbortSRB(), scp %x\n",
5611 (unsigned) scp);
5612 switch (AdvAbortSRB(adv_dvc_varp, (ulong) scp)AdvSendIdleCmd((adv_dvc_varp), (ushort) 0x0008, (ulong) ((ulong
) scp), 0)
) {
5613 case ASC_TRUE1:
5614 /* asc_isr_callback() will be called */
5615 ASC_DBG(1, "advansys_abort: AdvAbortSRB() TRUE\n");
5616 ret = SCSI_ABORT_PENDING2;
5617 break;
5618 case ASC_FALSE0:
5619 /* Request has apparently already completed. */
5620 ASC_DBG(1, "advansys_abort: AdvAbortSRB() FALSE\n");
5621 ret = SCSI_ABORT_NOT_RUNNING4;
5622 break;
5623 case ASC_ERROR(-1):
5624 default:
5625 ASC_DBG(1, "advansys_abort: AdvAbortSRB() ERROR\n");
5626 ret = SCSI_ABORT_ERROR5;
5627 break;
5628 }
5629 /*
5630 * Ensure all requests completed by the microcode have
5631 * been processed by calling AdvISR().
5632 */
5633 (void) AdvISR(adv_dvc_varp);
5634 }
5635
5636 /*
5637 * The request will either still be on the active queue
5638 * or have been added to the board's done queue.
5639 */
5640 if (asc_rmqueue(&boardp->active, scp) == ASC_TRUE1) {
5641 scp->result = HOST_BYTE(DID_ABORT)((0x05) << 16);
5642 scp_found = ASC_TRUE1;
5643 } else {
5644 scp_found = asc_rmqueue(&boardp->done, scp);
5645 ASC_ASSERT(scp_found == ASC_TRUE){ if (!(scp_found == 1)) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 5645); } }
;
5646 }
5647
5648 } else {
5649 /*
5650 * The command was not found on the active or waiting queues.
5651 */
5652 do_scsi_done = ASC_TRUE1;
5653 scp_found = ASC_FALSE0;
5654 ret = SCSI_ABORT_NOT_RUNNING4;
5655 }
5656
5657 /* Clear abort flag. */
5658 boardp->flags &= ~ASC_HOST_IN_ABORT0x02;
5659
5660 /*
5661 * Because the ASC_HOST_IN_ABORT flag causes both
5662 * 'advansys_interrupt' and 'asc_isr_callback' to
5663 * queue requests to the board's 'done' queue and
5664 * prevents waiting commands from being executed,
5665 * these queued requests must be handled here.
5666 */
5667 done_scp = asc_dequeue_list(&boardp->done, NULL((void *) 0), ASC_TID_ALL(-1));
5668
5669 /*
5670 * Start any waiting commands for the board.
5671 */
5672 if (!ASC_QUEUE_EMPTY(&boardp->waiting)((&boardp->waiting)->q_tidmask == 0)) {
5673 ASC_DBG(1, "advansys_interrupt: before asc_execute_queue()\n");
5674 asc_execute_queue(&boardp->waiting);
5675 }
5676 }
5677
5678 /* Interrupts could be enabled here. */
5679
5680 /*
5681 * Complete the request to be aborted, unless it has been
5682 * restarted as detected above, even if it was not found on
5683 * the device active or waiting queues.
5684 */
5685 ASC_ASSERT(do_scsi_done != ASC_ERROR){ if (!(do_scsi_done != (-1))) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 5685); } }
;
5686 ASC_ASSERT(scp_found != ASC_ERROR){ if (!(scp_found != (-1))) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 5686); } }
;
5687 if (do_scsi_done == ASC_TRUE1) {
5688 if (scp->scsi_done == NULL((void *) 0)) {
5689 ASC_PRINT1({ printk("advansys: "); printk(("advansys_abort: aborted request scsi_done() is NULL, %x\n"
), ((unsigned) scp)); }
5690"advansys_abort: aborted request scsi_done() is NULL, %x\n",{ printk("advansys: "); printk(("advansys_abort: aborted request scsi_done() is NULL, %x\n"
), ((unsigned) scp)); }
5691 (unsigned) scp){ printk("advansys: "); printk(("advansys_abort: aborted request scsi_done() is NULL, %x\n"
), ((unsigned) scp)); }
;
5692 } else {
5693 if (scp_found == ASC_FALSE0) {
5694 ASC_PRINT1({ printk("advansys: "); printk(("advansys_abort: abort request not active or waiting, completing anyway %x\n"
), ((unsigned) scp)); }
5695"advansys_abort: abort request not active or waiting, completing anyway %x\n",{ printk("advansys: "); printk(("advansys_abort: abort request not active or waiting, completing anyway %x\n"
), ((unsigned) scp)); }
5696 (unsigned) scp){ printk("advansys: "); printk(("advansys_abort: abort request not active or waiting, completing anyway %x\n"
), ((unsigned) scp)); }
;
5697 }
5698 ASC_STATS(scp->host, done)(((asc_board_t *) &((scp->host)->hostdata))->asc_stats
.done++)
;
5699 scp->scsi_done(scp);
5700 }
5701 }
5702
5703 /*
5704 * It is possible for the request done function to re-enable
5705 * interrupts without confusing the driver. But here interrupts
5706 * aren't enabled until all requests have been completed.
5707 */
5708 if (done_scp != NULL((void *) 0)) {
5709 asc_scsi_done_list(done_scp);
5710 }
5711
5712 ASC_DBG1(1, "advansys_abort: ret %d\n", ret);
5713
5714 /* Re-enable interrupts, if they were enabled on entry. */
5715 restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory");
5716
5717 ASC_ASSERT(ret != ASC_ERROR){ if (!(ret != (-1))) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 5717); } }
;
5718 return ret;
5719}
5720
5721/*
5722 * advansys_reset()
5723 *
5724 * Reset the device associated with the command 'scp'.
5725 */
5726int
5727#if LINUX_VERSION_CODE131108 < ASC_LINUX_VERSION(1,3,89)(((1) * 65536) + ((3) * 256) + (89))
5728advansys_reset(Scsi_Cmnd *scp)
5729#else /* version >= v1.3.89 */
5730advansys_reset(Scsi_Cmnd *scp, unsigned int reset_flags)
5731#endif /* version >= v1.3.89 */
5732{
5733 struct Scsi_Host *shp;
5734 asc_board_t *boardp;
5735 ASC_DVC_VAR *asc_dvc_varp;
5736 ADV_DVC_VAR *adv_dvc_varp;
5737 long flags;
5738 Scsi_Cmnd *done_scp = NULL((void *) 0), *last_scp = NULL((void *) 0);
5739 Scsi_Cmnd *tscp, *new_last_scp;
5740 int do_scsi_done;
5741 int scp_found;
5742 int status;
5743 int target;
5744 int ret;
5745 int device_reset = ASC_FALSE0;
5746
5747 /* Save current flags and disable interrupts. */
5748 save_flags(flags)__asm__ __volatile__("pushf ; pop %0" : "=r" (flags): :"memory"
)
;
5749 cli()__asm__ __volatile__ ("cli": : :"memory");
5750
5751 ASC_DBG1(1, "advansys_reset: %x\n", (unsigned) scp);
5752
5753#ifdef ADVANSYS_STATS
5754 if (scp->host != NULL((void *) 0)) {
5755 ASC_STATS(scp->host, reset)(((asc_board_t *) &((scp->host)->hostdata))->asc_stats
.reset++)
;
5756 }
5757#endif /* ADVANSYS_STATS */
5758
5759#if LINUX_VERSION_CODE131108 >= ASC_LINUX_VERSION(1,3,89)(((1) * 65536) + ((3) * 256) + (89))
5760 if ((reset_flags & SCSI_RESET_ASYNCHRONOUS0x02) &&
5761 (scp->serial_number != scp->serial_number_at_timeout)) {
5762 ASC_PRINT1({ printk("advansys: "); printk(("advansys_reset: timeout serial number changed for request %x\n"
), ((unsigned) scp)); }
5763"advansys_reset: timeout serial number changed for request %x\n",{ printk("advansys: "); printk(("advansys_reset: timeout serial number changed for request %x\n"
), ((unsigned) scp)); }
5764 (unsigned) scp){ printk("advansys: "); printk(("advansys_reset: timeout serial number changed for request %x\n"
), ((unsigned) scp)); }
;
5765 do_scsi_done = ASC_FALSE0;
5766 scp_found = ASC_FALSE0;
5767 ret = SCSI_RESET_NOT_RUNNING5;
5768 } else
5769#endif /* version >= v1.3.89 */
5770 if ((shp = scp->host) == NULL((void *) 0)) {
5771 scp->result = HOST_BYTE(DID_ERROR)((0x07) << 16);
5772 do_scsi_done = ASC_TRUE1;
5773 scp_found = ASC_FALSE0;
5774 ret = SCSI_RESET_ERROR6;
5775 } else if ((boardp = ASC_BOARDP(shp)((asc_board_t *) &((shp)->hostdata)))->flags &
5776 (ASC_HOST_IN_RESET0x01 | ASC_HOST_IN_ABORT0x02)) {
5777 ASC_PRINT2({ printk("advansys: "); printk(("advansys_reset: board %d: Nested host reset or abort, flags 0x%x\n"
), (boardp->id), (boardp->flags)); }
5778"advansys_reset: board %d: Nested host reset or abort, flags 0x%x\n",{ printk("advansys: "); printk(("advansys_reset: board %d: Nested host reset or abort, flags 0x%x\n"
), (boardp->id), (boardp->flags)); }
5779 boardp->id, boardp->flags){ printk("advansys: "); printk(("advansys_reset: board %d: Nested host reset or abort, flags 0x%x\n"
), (boardp->id), (boardp->flags)); }
;
5780 do_scsi_done = ASC_TRUE1;
5781 if ((asc_rmqueue(&boardp->active, scp) == ASC_TRUE1) ||
5782 (asc_rmqueue(&boardp->waiting, scp) == ASC_TRUE1)) {
5783 scp_found = ASC_TRUE1;
5784 } else {
5785 scp_found = ASC_FALSE0;
5786 }
5787 scp->result = HOST_BYTE(DID_ERROR)((0x07) << 16);
5788 ret = SCSI_RESET_ERROR6;
5789 } else if (jiffies >= boardp->last_reset &&
5790 jiffies < (boardp->last_reset + (10 * HZ100))) {
5791 /*
5792 * Don't allow a reset to be attempted within 10 seconds
5793 * of the last reset.
5794 *
5795 * If 'jiffies' wrapping occurs, the reset request will go
5796 * through, because a wrapped 'jiffies' would not pass the
5797 * test above.
5798 */
5799 ASC_DBG(1,
5800 "advansys_reset: reset within 10 sec of last reset ignored\n");
5801 do_scsi_done = ASC_TRUE1;
5802 if ((asc_rmqueue(&boardp->active, scp) == ASC_TRUE1) ||
5803 (asc_rmqueue(&boardp->waiting, scp) == ASC_TRUE1)) {
5804 scp_found = ASC_TRUE1;
5805 } else {
5806 scp_found = ASC_FALSE0;
5807 }
5808 scp->result = HOST_BYTE(DID_ERROR)((0x07) << 16);
5809 ret = SCSI_RESET_ERROR6;
5810 } else {
5811 do_scsi_done = ASC_TRUE1;
5812
5813 /* Set reset flag to avoid nested reset or abort requests. */
5814 boardp->flags |= ASC_HOST_IN_RESET0x01;
5815
5816 /*
5817 * If the request is on the target waiting or active queue
5818 * or the board done queue, then remove it and note that it
5819 * was found.
5820 */
5821 if (asc_rmqueue(&boardp->active, scp) == ASC_TRUE1) {
5822 ASC_DBG(1, "advansys_reset: active scp_found = TRUE\n");
5823 scp_found = ASC_TRUE1;
5824 } else if (asc_rmqueue(&boardp->waiting, scp) == ASC_TRUE1) {
5825 ASC_DBG(1, "advansys_reset: waiting scp_found = TRUE\n");
5826 scp_found = ASC_TRUE1;
5827 } else if (asc_rmqueue(&boardp->done, scp) == ASC_TRUE1) {
5828 scp_found = ASC_TRUE1;
5829 } else {
5830 scp_found = ASC_FALSE0;
5831 }
5832
5833
5834 if (ASC_NARROW_BOARD(boardp)(((boardp)->flags & 0x04) == 0)) {
5835 /*
5836 * Narrow Board
5837 *
5838 * If the suggest reset bus flags are set, then reset the bus.
5839 * Otherwise only reset the device.
5840 */
5841 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
5842#if LINUX_VERSION_CODE131108 >= ASC_LINUX_VERSION(1,3,89)(((1) * 65536) + ((3) * 256) + (89))
5843 if (reset_flags &
5844 (SCSI_RESET_SUGGEST_BUS_RESET0x04 |
5845 SCSI_RESET_SUGGEST_HOST_RESET0x08)) {
5846#endif /* version >= v1.3.89 */
5847
5848 /*
5849 * Reset the target's SCSI bus.
5850 */
5851 ASC_DBG(1, "advansys_reset: before AscResetSB()\n");
5852 sti()__asm__ __volatile__ ("sti": : :"memory"); /* Enable interrupts for AscResetSB(). */
5853 status = AscResetSB(asc_dvc_varp);
5854 cli()__asm__ __volatile__ ("cli": : :"memory");
5855 switch (status) {
5856 case ASC_TRUE1:
5857 ASC_DBG(1, "advansys_reset: AscResetSB() success\n");
5858 ret = SCSI_RESET_SUCCESS2;
5859 break;
5860 case ASC_ERROR(-1):
5861 default:
5862 ASC_DBG(1, "advansys_reset: AscResetSB() failed\n");
5863 ret = SCSI_RESET_ERROR6;
5864 break;
5865 }
5866
5867#if LINUX_VERSION_CODE131108 >= ASC_LINUX_VERSION(1,3,89)(((1) * 65536) + ((3) * 256) + (89))
5868 } else {
5869 /*
5870 * Reset the specified device. If the device reset fails,
5871 * then reset the SCSI bus.
5872 */
5873
5874 ASC_DBG1(1,
5875 "advansys_reset: before AscResetDevice(), target %d\n",
5876 scp->target);
5877 sti()__asm__ __volatile__ ("sti": : :"memory"); /* Enable interrupts for AscResetDevice(). */
5878 status = AscResetDevice(asc_dvc_varp, scp->target);
5879 cli()__asm__ __volatile__ ("cli": : :"memory");
5880
5881 switch (status) {
5882 case ASC_TRUE1:
5883 ASC_DBG(1, "advansys_reset: AscResetDevice() success\n");
5884 device_reset = ASC_TRUE1;
5885 ret = SCSI_RESET_SUCCESS2;
5886 break;
5887 case ASC_ERROR(-1):
5888 default:
5889 ASC_DBG(1,
5890"advansys_reset: AscResetDevice() failed; Calling AscResetSB()\n");
5891 sti()__asm__ __volatile__ ("sti": : :"memory"); /* Enable interrupts for AscResetSB(). */
5892 status = AscResetSB(asc_dvc_varp);
5893 cli()__asm__ __volatile__ ("cli": : :"memory");
5894 switch (status) {
5895 case ASC_TRUE1:
5896 ASC_DBG(1, "advansys_reset: AscResetSB() TRUE\n");
5897 ret = SCSI_RESET_SUCCESS2;
5898 break;
5899 case ASC_ERROR(-1):
5900 default:
5901 ASC_DBG(1, "advansys_reset: AscResetSB() ERROR\n");
5902 ret = SCSI_RESET_ERROR6;
5903 break;
5904 }
5905 break;
5906 }
5907 }
5908#endif /* version >= v1.3.89 */
5909 } else {
5910 /*
5911 * Wide Board
5912 *
5913 * If the suggest reset bus flags are set, then reset the bus.
5914 * Otherwise only reset the device.
5915 */
5916 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
5917#if LINUX_VERSION_CODE131108 >= ASC_LINUX_VERSION(1,3,89)(((1) * 65536) + ((3) * 256) + (89))
5918 if (reset_flags &
5919 (SCSI_RESET_SUGGEST_BUS_RESET0x04 |
5920 SCSI_RESET_SUGGEST_HOST_RESET0x08)) {
5921#endif /* version >= v1.3.89 */
5922
5923 /*
5924 * Reset the target's SCSI bus.
5925 */
5926 ASC_DBG(1, "advansys_reset: before AdvResetSB()\n");
5927 switch (AdvResetSB(adv_dvc_varp)) {
5928 case ASC_TRUE1:
5929 ASC_DBG(1, "advansys_reset: AdvResetSB() success\n");
5930 ret = SCSI_RESET_SUCCESS2;
5931 break;
5932 case ASC_FALSE0:
5933 default:
5934 ASC_DBG(1, "advansys_reset: AdvResetSB() failed\n");
5935 ret = SCSI_RESET_ERROR6;
5936 break;
5937 }
5938 /*
5939 * Ensure all requests completed by the microcode have
5940 * been processed by calling AdvISR().
5941 */
5942 (void) AdvISR(adv_dvc_varp);
5943#if LINUX_VERSION_CODE131108 >= ASC_LINUX_VERSION(1,3,89)(((1) * 65536) + ((3) * 256) + (89))
5944 } else {
5945 /*
5946 * Reset the specified device. If the device reset fails,
5947 * then reset the SCSI bus.
5948 */
5949
5950 ASC_DBG1(1,
5951 "advansys_reset: before AdvResetDevice(), target %d\n",
5952 scp->target);
5953
5954 switch (AdvResetDevice(adv_dvc_varp, scp->target)AdvSendIdleCmd((adv_dvc_varp), (ushort) 0x0010, (ulong) (scp->
target), 0)
) {
5955 case ASC_TRUE1:
5956 ASC_DBG(1, "advansys_reset: AdvResetDevice() success\n");
5957 device_reset = ASC_TRUE1;
5958 ret = SCSI_RESET_SUCCESS2;
5959 break;
5960 case ASC_FALSE0:
5961 default:
5962 ASC_DBG(1,
5963"advansys_reset: AdvResetDevice() failed; Calling AdvResetSB()\n");
5964
5965 switch (AdvResetSB(adv_dvc_varp)) {
5966 case ASC_TRUE1:
5967 ASC_DBG(1, "advansys_reset: AdvResetSB() TRUE\n");
5968 ret = SCSI_RESET_SUCCESS2;
5969 break;
5970 case ASC_FALSE0:
5971 default:
5972 ASC_DBG(1, "advansys_reset: AdvResetSB() ERROR\n");
5973 ret = SCSI_RESET_ERROR6;
5974 break;
5975 }
5976 break;
5977 }
5978 /*
5979 * Ensure all requests completed by the microcode have
5980 * been processed by calling AdvISR().
5981 */
5982 (void) AdvISR(adv_dvc_varp);
5983 }
5984#endif /* version >= v1.3.89 */
5985 }
5986
5987 /*
5988 * Because the ASC_HOST_IN_RESET flag causes both
5989 * 'advansys_interrupt' and 'asc_isr_callback' to
5990 * queue requests to the board's 'done' queue and
5991 * prevents waiting commands from being executed,
5992 * these queued requests must be handled here.
5993 */
5994 done_scp = asc_dequeue_list(&boardp->done, &last_scp,
5995 ASC_TID_ALL(-1));
5996
5997 /*
5998 * If a device reset was performed dequeue all waiting
5999 * and active requests for the device and set the request
6000 * status to DID_RESET.
6001 *
6002 * If a SCSI bus reset was performed dequeue all waiting
6003 * and active requests for all devices and set the request
6004 * status to DID_RESET.
6005 */
6006 if (device_reset == ASC_TRUE1) {
6007 target = scp->target;
6008 } else {
6009 target = ASC_TID_ALL(-1);
6010 }
6011
6012 /*
6013 * Add active requests to 'done_scp' and set the request status
6014 * to DID_RESET.
6015 */
6016 if (done_scp == NULL((void *) 0)) {
6017 done_scp = asc_dequeue_list(&boardp->active, &last_scp, target);
6018 for (tscp = done_scp; tscp; tscp = (REQP) REQPNEXT(tscp)((tscp)->host_scribble)) {
6019 tscp->result = HOST_BYTE(DID_RESET)((0x08) << 16);
6020 }
6021 } else {
6022 ASC_ASSERT(last_scp != NULL){ if (!(last_scp != ((void *) 0))) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 6022); } }
;
6023 REQPNEXT(last_scp)((last_scp)->host_scribble) =
6024 (unsigned char *) asc_dequeue_list(&boardp->active,
6025 &new_last_scp, target);
6026 if (new_last_scp != (Scsi_Cmnd *) NULL((void *) 0)) {
6027 ASC_ASSERT((REQP) REQPNEXT(last_scp) != NULL){ if (!((REQP) ((last_scp)->host_scribble) != ((void *) 0)
)) { printk("ASC_ASSERT() Failure: file %s, line %d\n", "../linux/src/drivers/scsi/advansys.c"
, 6027); } }
;
6028 for (tscp = (Scsi_Cmnd *) REQPNEXT(last_scp)((last_scp)->host_scribble);
6029 tscp;
6030 tscp = (Scsi_Cmnd *) REQPNEXT(tscp)((tscp)->host_scribble)) {
6031 tscp->result = HOST_BYTE(DID_RESET)((0x08) << 16);
6032 }
6033 last_scp = new_last_scp;
6034 }
6035 }
6036
6037 /*
6038 * Add waiting requests to 'done_scp' and set the request status
6039 * to DID_RESET.
6040 */
6041 if (done_scp == NULL((void *) 0)) {
6042 done_scp = asc_dequeue_list(&boardp->waiting, &last_scp, target);
6043 for (tscp = done_scp; tscp; tscp = (REQP) REQPNEXT(tscp)((tscp)->host_scribble)) {
6044 tscp->result = HOST_BYTE(DID_RESET)((0x08) << 16);
6045 }
6046 } else {
6047 ASC_ASSERT(last_scp != NULL){ if (!(last_scp != ((void *) 0))) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 6047); } }
;
6048 REQPNEXT(last_scp)((last_scp)->host_scribble) =
6049 (unsigned char *) asc_dequeue_list(&boardp->waiting,
6050 &new_last_scp, target);
6051 if (new_last_scp != NULL((void *) 0)) {
6052 ASC_ASSERT((REQP) REQPNEXT(last_scp) != NULL){ if (!((REQP) ((last_scp)->host_scribble) != ((void *) 0)
)) { printk("ASC_ASSERT() Failure: file %s, line %d\n", "../linux/src/drivers/scsi/advansys.c"
, 6052); } }
;
6053 for (tscp = (REQP) REQPNEXT(last_scp)((last_scp)->host_scribble);
6054 tscp;
6055 tscp = (REQP) REQPNEXT(tscp)((tscp)->host_scribble)) {
6056 tscp->result = HOST_BYTE(DID_RESET)((0x08) << 16);
6057 }
6058 last_scp = new_last_scp;
6059 }
6060 }
6061
6062 /* Save the time of the most recently completed reset. */
6063 boardp->last_reset = jiffies;
6064
6065 /* Clear reset flag. */
6066 boardp->flags &= ~ASC_HOST_IN_RESET0x01;
6067
6068 /*
6069 * Start any waiting commands for the board.
6070 */
6071 if (!ASC_QUEUE_EMPTY(&boardp->waiting)((&boardp->waiting)->q_tidmask == 0)) {
6072 ASC_DBG(1, "advansys_interrupt: before asc_execute_queue()\n");
6073 asc_execute_queue(&boardp->waiting);
6074 }
6075 ret = SCSI_RESET_SUCCESS2;
6076 }
6077
6078 /* Interrupts could be enabled here. */
6079
6080 ASC_ASSERT(do_scsi_done != ASC_ERROR){ if (!(do_scsi_done != (-1))) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 6080); } }
;
6081 ASC_ASSERT(scp_found != ASC_ERROR){ if (!(scp_found != (-1))) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 6081); } }
;
6082 if (do_scsi_done == ASC_TRUE1) {
6083 if (scp->scsi_done == NULL((void *) 0)) {
6084 ASC_PRINT1({ printk("advansys: "); printk(("advansys_reset: reset request scsi_done() is NULL, %x\n"
), ((unsigned) scp)); }
6085"advansys_reset: reset request scsi_done() is NULL, %x\n",{ printk("advansys: "); printk(("advansys_reset: reset request scsi_done() is NULL, %x\n"
), ((unsigned) scp)); }
6086 (unsigned) scp){ printk("advansys: "); printk(("advansys_reset: reset request scsi_done() is NULL, %x\n"
), ((unsigned) scp)); }
;
6087 } else {
6088 if (scp_found == ASC_FALSE0) {
6089 ASC_PRINT1({ printk("advansys: "); printk(("advansys_reset: reset request not active or waiting, completing anyway %x\n"
), ((unsigned) scp)); }
6090"advansys_reset: reset request not active or waiting, completing anyway %x\n",{ printk("advansys: "); printk(("advansys_reset: reset request not active or waiting, completing anyway %x\n"
), ((unsigned) scp)); }
6091 (unsigned) scp){ printk("advansys: "); printk(("advansys_reset: reset request not active or waiting, completing anyway %x\n"
), ((unsigned) scp)); }
;
6092 }
6093 ASC_STATS(scp->host, done)(((asc_board_t *) &((scp->host)->hostdata))->asc_stats
.done++)
;
6094 scp->scsi_done(scp);
6095 }
6096 }
6097
6098 /*
6099 * It is possible for the request done function to re-enable
6100 * interrupts without confusing the driver. But here interrupts
6101 * aren't enabled until requests have been completed.
6102 */
6103 if (done_scp != NULL((void *) 0)) {
6104 asc_scsi_done_list(done_scp);
6105 }
6106
6107 ASC_DBG1(1, "advansys_reset: ret %d\n", ret);
6108
6109 /* Re-enable interrupts, if they were enabled on entry. */
6110 restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory");
6111
6112 ASC_ASSERT(ret != ASC_ERROR){ if (!(ret != (-1))) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 6112); } }
;
6113 return ret;
6114}
6115
6116/*
6117 * advansys_biosparam()
6118 *
6119 * Translate disk drive geometry if the "BIOS greater than 1 GB"
6120 * support is enabled for a drive.
6121 *
6122 * ip (information pointer) is an int array with the following definition:
6123 * ip[0]: heads
6124 * ip[1]: sectors
6125 * ip[2]: cylinders
6126 */
6127int
6128#if LINUX_VERSION_CODE131108 < ASC_LINUX_VERSION(1,3,0)(((1) * 65536) + ((3) * 256) + (0))
6129advansys_biosparam(Disk *dp, int dep, int ip[])
6130#else /* version >= v1.3.0 */
6131advansys_biosparam(Disk *dp, kdev_t dep, int ip[])
6132#endif /* version >= v1.3.0 */
6133{
6134 asc_board_t *boardp;
6135
6136 ASC_DBG(1, "advansys_biosparam: begin\n");
6137 ASC_STATS(dp->device->host, biosparam)(((asc_board_t *) &((dp->device->host)->hostdata
))->asc_stats.biosparam++)
;
6138 boardp = ASC_BOARDP(dp->device->host)((asc_board_t *) &((dp->device->host)->hostdata)
)
;
6139 if (ASC_NARROW_BOARD(boardp)(((boardp)->flags & 0x04) == 0)) {
6140 if ((boardp->dvc_var.asc_dvc_var.dvc_cntl &
6141 ASC_CNTL_BIOS_GT_1GB(ushort)0x0002) && dp->capacity > 0x200000) {
6142 ip[0] = 255;
6143 ip[1] = 63;
6144 } else {
6145 ip[0] = 64;
6146 ip[1] = 32;
6147 }
6148 } else {
6149 if ((boardp->dvc_var.adv_dvc_var.bios_ctrl &
6150 BIOS_CTRL_EXTENDED_XLAT0x0002) && dp->capacity > 0x200000) {
6151 ip[0] = 255;
6152 ip[1] = 63;
6153 } else {
6154 ip[0] = 64;
6155 ip[1] = 32;
6156 }
6157 }
6158 ip[2] = dp->capacity / (ip[0] * ip[1]);
6159 ASC_DBG(1, "advansys_biosparam: end\n");
6160 return 0;
6161}
6162
6163/*
6164 * advansys_setup()
6165 *
6166 * This function is called from init/main.c at boot time.
6167 * It it passed LILO parameters that can be set from the
6168 * LILO command line or in /etc/lilo.conf.
6169 *
6170 * It is used by the AdvanSys driver to either disable I/O
6171 * port scanning or to limit scanning to 1 - 4 I/O ports.
6172 * Regardless of the option setting EISA and PCI boards
6173 * will still be searched for and detected. This option
6174 * only affects searching for ISA and VL boards.
6175 *
6176 * If ADVANSYS_DEBUG is defined the driver debug level may
6177 * be set using the 5th (ASC_NUM_IOPORT_PROBE + 1) I/O Port.
6178 *
6179 * Examples:
6180 * 1. Eliminate I/O port scanning:
6181 * boot: linux advansys=
6182 * or
6183 * boot: linux advansys=0x0
6184 * 2. Limit I/O port scanning to one I/O port:
6185 * boot: linux advansys=0x110
6186 * 3. Limit I/O port scanning to four I/O ports:
6187 * boot: linux advansys=0x110,0x210,0x230,0x330
6188 * 4. If ADVANSYS_DEBUG, limit I/O port scanning to four I/O ports and
6189 * set the driver debug level to 2.
6190 * boot: linux advansys=0x110,0x210,0x230,0x330,0xdeb2
6191 *
6192 * ints[0] - number of arguments
6193 * ints[1] - first argument
6194 * ints[2] - second argument
6195 * ...
6196 */
6197ASC_INITFUNC(void advansys_setup(char *str, int *ints)
6198voidvoid advansys_setup(char *str, int *ints)
6199advansys_setup(char *str, int *ints)void advansys_setup(char *str, int *ints)
6200)void advansys_setup(char *str, int *ints)
6201{
6202 int i;
6203
6204 if (asc_iopflag == ASC_TRUE1) {
6205 printk("AdvanSys SCSI: 'advansys' LILO option may appear only once\n");
6206 return;
6207 }
6208
6209 asc_iopflag = ASC_TRUE1;
6210
6211 if (ints[0] > ASC_NUM_IOPORT_PROBE4) {
6212#ifdef ADVANSYS_DEBUG
6213 if ((ints[0] == ASC_NUM_IOPORT_PROBE4 + 1) &&
6214 (ints[ASC_NUM_IOPORT_PROBE4 + 1] >> 4 == 0xdeb)) {
6215 asc_dbglvl = ints[ASC_NUM_IOPORT_PROBE4 + 1] & 0xf;
6216 } else {
6217#endif /* ADVANSYS_DEBUG */
6218 printk("AdvanSys SCSI: only %d I/O ports accepted\n",
6219 ASC_NUM_IOPORT_PROBE4);
6220#ifdef ADVANSYS_DEBUG
6221 }
6222#endif /* ADVANSYS_DEBUG */
6223 }
6224
6225#ifdef ADVANSYS_DEBUG
6226 ASC_DBG1(1, "advansys_setup: ints[0] %d\n", ints[0]);
6227 for (i = 1; i < ints[0]; i++) {
6228 ASC_DBG2(1, " ints[%d] %x", i, ints[i]);
6229 }
6230 ASC_DBG(1, "\n");
6231#endif /* ADVANSYS_DEBUG */
6232
6233 for (i = 1; i <= ints[0] && i <= ASC_NUM_IOPORT_PROBE4; i++) {
6234 asc_ioport[i-1] = ints[i];
6235 ASC_DBG2(1, "advansys_setup: asc_ioport[%d] %x\n",
6236 i - 1, asc_ioport[i-1]);
6237 }
6238}
6239
6240
6241/*
6242 * --- Loadable Driver Support
6243 */
6244
6245#ifdef MODULE
6246Scsi_Host_Template driver_template = ADVANSYS{ ((void *) 0), ((void *) 0), &proc_scsi_advansys, advansys_proc_info
, "advansys", advansys_detect, advansys_release, advansys_info
, advansys_command, advansys_queuecommand, advansys_abort, advansys_reset
, ((void *) 0), advansys_biosparam, 0, 0, 0, 0, 0, 1, 1, }
;
6247# include "scsi_module.c"
6248#endif /* MODULE */
6249
6250
6251/*
6252 * --- Miscellaneous Driver Functions
6253 */
6254
6255/*
6256 * First-level interrupt handler.
6257 *
6258 * For versions > v1.3.70, 'dev_id' is a pointer to the interrupting
6259 * adapter's asc_board_t. Because all boards are currently checked
6260 * for interrupts on each interrupt, 'dev_id' is not referenced. 'dev_id'
6261 * could be used to identify an interrupt passed to the AdvanSys driver,
6262 * which is for a device sharing an interrupt with an AdvanSys adapter.
6263 */
6264STATICstatic void
6265#if LINUX_VERSION_CODE131108 < ASC_LINUX_VERSION(1,3,70)(((1) * 65536) + ((3) * 256) + (70))
6266advansys_interrupt(int irq, struct pt_regs *regs)
6267#else /* version >= v1.3.70 */
6268advansys_interrupt(int irq, void *dev_id, struct pt_regs *regs)
6269#endif /* version >= v1.3.70 */
6270{
6271#if LINUX_VERSION_CODE131108 < ASC_LINUX_VERSION(2,1,95)(((2) * 65536) + ((1) * 256) + (95))
6272 long flags;
6273#else /* version >= v2.1.95 */
6274 unsigned long flags;
6275#endif /* version >= v2.1.95 */
6276 int i;
6277 asc_board_t *boardp;
6278 Scsi_Cmnd *done_scp = NULL((void *) 0), *last_scp = NULL((void *) 0);
6279 Scsi_Cmnd *new_last_scp;
6280
6281#if LINUX_VERSION_CODE131108 < ASC_LINUX_VERSION(2,1,95)(((2) * 65536) + ((1) * 256) + (95))
6282 /* Disable interrupts, if they aren't already disabled. */
6283 save_flags(flags)__asm__ __volatile__("pushf ; pop %0" : "=r" (flags): :"memory"
)
;
6284 cli()__asm__ __volatile__ ("cli": : :"memory");
6285#else /* version >= v2.1.95 */
6286 /*
6287 * Disable interrupts, if they aren't already disabled and acquire
6288 * the I/O spinlock.
6289 */
6290 spin_lock_irqsave(&io_request_lock, flags);
6291#endif /* version >= v2.1.95 */
6292
6293 ASC_DBG(1, "advansys_interrupt: begin\n");
6294
6295 /*
6296 * Check for interrupts on all boards.
6297 * AscISR() will call asc_isr_callback().
6298 */
6299 for (i = 0; i < asc_board_count; i++) {
6300 boardp = ASC_BOARDP(asc_host[i])((asc_board_t *) &((asc_host[i])->hostdata));
6301 ASC_DBG2(2, "advansys_interrupt: i %d, boardp %lx\n",
6302 i, (ulong) boardp)
6303 if (ASC_NARROW_BOARD(boardp)(((boardp)->flags & 0x04) == 0)) {
6304 /*
6305 * Narrow Board
6306 */
6307 if (AscIsIntPending(asc_host[i]->io_port)((unsigned short)((__builtin_constant_p(((asc_host[i]->io_port
)+(0x0E))) && ((asc_host[i]->io_port)+(0x0E)) <
256) ? __inwc((asc_host[i]->io_port)+(0x0E)) : __inw((asc_host
[i]->io_port)+(0x0E))) & ((unsigned short)0x0001 | (unsigned
short)0x0002))
) {
6308 ASC_STATS(asc_host[i], interrupt)(((asc_board_t *) &((asc_host[i])->hostdata))->asc_stats
.interrupt++)
;
6309 ASC_DBG(1, "advansys_interrupt: before AscISR()\n");
6310 AscISR(&boardp->dvc_var.asc_dvc_var);
6311 }
6312 } else {
6313 /*
6314 * Wide Board
6315 */
6316 ASC_DBG(1, "advansys_interrupt: before AdvISR()\n");
6317 if (AdvISR(&boardp->dvc_var.adv_dvc_var)) {
6318 ASC_STATS(asc_host[i], interrupt)(((asc_board_t *) &((asc_host[i])->hostdata))->asc_stats
.interrupt++)
;
6319 }
6320 }
6321
6322 /*
6323 * Start waiting requests and create a list of completed requests.
6324 *
6325 * If a reset or abort request is being performed for the board,
6326 * the reset or abort handler will complete pending requests after
6327 * it has completed.
6328 */
6329 if ((boardp->flags & (ASC_HOST_IN_RESET0x01 | ASC_HOST_IN_ABORT0x02)) == 0) {
6330 ASC_DBG2(1, "advansys_interrupt: done_scp %lx, last_scp %lx\n",
6331 (ulong) done_scp, (ulong) last_scp);
6332
6333 /* Start any waiting commands for the board. */
6334 if (!ASC_QUEUE_EMPTY(&boardp->waiting)((&boardp->waiting)->q_tidmask == 0)) {
6335 ASC_DBG(1, "advansys_interrupt: before asc_execute_queue()\n");
6336 asc_execute_queue(&boardp->waiting);
6337 }
6338
6339 /*
6340 * Add to the list of requests that must be completed.
6341 *
6342 * 'done_scp' will always be NULL on the first iteration
6343 * of this loop. 'last_scp' is set at the same time as
6344 * 'done_scp'.
6345 */
6346 if (done_scp == NULL((void *) 0)) {
6347 done_scp = asc_dequeue_list(&boardp->done, &last_scp,
6348 ASC_TID_ALL(-1));
6349 } else {
6350 ASC_ASSERT(last_scp != NULL){ if (!(last_scp != ((void *) 0))) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 6350); } }
;
6351 REQPNEXT(last_scp)((last_scp)->host_scribble) =
6352 (unsigned char *) asc_dequeue_list(&boardp->done,
6353 &new_last_scp,
6354 ASC_TID_ALL(-1));
6355 if (new_last_scp != NULL((void *) 0)) {
6356 ASC_ASSERT(REQPNEXT(last_scp) != NULL){ if (!(((last_scp)->host_scribble) != ((void *) 0))) { printk
("ASC_ASSERT() Failure: file %s, line %d\n", "../linux/src/drivers/scsi/advansys.c"
, 6356); } }
;
6357 last_scp = new_last_scp;
6358 }
6359 }
6360 }
6361 }
6362
6363 /* Interrupts could be enabled here. */
6364
6365 /*
6366 * It is possible for the request done function to re-enable
6367 * interrupts without confusing the driver. But here the
6368 * original flags aren't restored until all requests have been
6369 * completed.
6370 */
6371 asc_scsi_done_list(done_scp);
6372
6373#if LINUX_VERSION_CODE131108 < ASC_LINUX_VERSION(2,1,95)(((2) * 65536) + ((1) * 256) + (95))
6374 /*
6375 * Restore the original flags which will enable interrupts
6376 * if and only if they were enabled on entry.
6377 */
6378 restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory");
6379#else /* version >= v2.1.95 */
6380 /*
6381 * Release the I/O spinlock and restore the original flags
6382 * which will enable interrupts if and only if they were
6383 * enabled on entry.
6384 */
6385 spin_unlock_irqrestore(&io_request_lock, flags);
6386#endif /* version >= v2.1.95 */
6387
6388 ASC_DBG(1, "advansys_interrupt: end\n");
6389 return;
6390}
6391
6392#if LINUX_VERSION_CODE131108 >= ASC_LINUX_VERSION(1,3,89)(((1) * 65536) + ((3) * 256) + (89))
6393/*
6394 * Set the number of commands to queue per device for the
6395 * specified host adapter.
6396 */
6397STATICstatic void
6398advansys_select_queue_depths(struct Scsi_Host *shp, Scsi_Device *devicelist)
6399{
6400 Scsi_Device *device;
6401 asc_board_t *boardp;
6402
6403 boardp = ASC_BOARDP(shp)((asc_board_t *) &((shp)->hostdata));
6404 boardp->flags |= ASC_SELECT_QUEUE_DEPTHS0x08;
6405 for (device = devicelist; device != NULL((void *) 0); device = device->next) {
6406 if (device->host != shp) {
6407 continue;
6408 }
6409 /*
6410 * Save a pointer to the device and set its initial/maximum
6411 * queue depth.
6412 */
6413 boardp->device[device->id] = device;
6414 if (ASC_NARROW_BOARD(boardp)(((boardp)->flags & 0x04) == 0)) {
6415 device->queue_depth =
6416 boardp->dvc_var.asc_dvc_var.max_dvc_qng[device->id];
6417 } else {
6418 device->queue_depth =
6419 boardp->dvc_var.adv_dvc_var.max_dvc_qng;
6420 }
6421 ASC_DBG3(1, "advansys_select_queue_depths: shp %x, id %d, depth %d\n",
6422 (unsigned) shp, device->id, device->queue_depth);
6423 }
6424}
6425#endif /* version >= v1.3.89 */
6426
6427/*
6428 * Function used only with polled I/O requests that are initiated by
6429 * advansys_command().
6430 */
6431STATICstatic void
6432advansys_command_done(Scsi_Cmnd *scp)
6433{
6434 ASC_DBG1(1, "advansys_command_done: scp %x\n", (unsigned) scp);
6435 scp->SCp.Status = 1;
6436}
6437
6438/*
6439 * Complete all requests on the singly linked list pointed
6440 * to by 'scp'.
6441 *
6442 * Interrupts can be enabled on entry.
6443 */
6444STATICstatic void
6445asc_scsi_done_list(Scsi_Cmnd *scp)
6446{
6447 Scsi_Cmnd *tscp;
6448
6449 ASC_DBG(2, "asc_scsi_done_list: begin\n");
6450 while (scp != NULL((void *) 0)) {
6451 ASC_DBG1(3, "asc_scsi_done_list: scp %x\n", (unsigned) scp);
6452 tscp = (REQP) REQPNEXT(scp)((scp)->host_scribble);
6453 REQPNEXT(scp)((scp)->host_scribble) = NULL((void *) 0);
6454 ASC_STATS(scp->host, done)(((asc_board_t *) &((scp->host)->hostdata))->asc_stats
.done++)
;
6455 ASC_ASSERT(scp->scsi_done != NULL){ if (!(scp->scsi_done != ((void *) 0))) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 6455); } }
;
6456 scp->scsi_done(scp);
6457 scp = tscp;
6458 }
6459 ASC_DBG(2, "asc_scsi_done_list: done\n");
6460 return;
6461}
6462
6463/*
6464 * Execute a single 'Scsi_Cmnd'.
6465 *
6466 * The function 'done' is called when the request has been completed.
6467 *
6468 * Scsi_Cmnd:
6469 *
6470 * host - board controlling device
6471 * device - device to send command
6472 * target - target of device
6473 * lun - lun of device
6474 * cmd_len - length of SCSI CDB
6475 * cmnd - buffer for SCSI 8, 10, or 12 byte CDB
6476 * use_sg - if non-zero indicates scatter-gather request with use_sg elements
6477 *
6478 * if (use_sg == 0) {
6479 * request_buffer - buffer address for request
6480 * request_bufflen - length of request buffer
6481 * } else {
6482 * request_buffer - pointer to scatterlist structure
6483 * }
6484 *
6485 * sense_buffer - sense command buffer
6486 *
6487 * result (4 bytes of an int):
6488 * Byte Meaning
6489 * 0 SCSI Status Byte Code
6490 * 1 SCSI One Byte Message Code
6491 * 2 Host Error Code
6492 * 3 Mid-Level Error Code
6493 *
6494 * host driver fields:
6495 * SCp - Scsi_Pointer used for command processing status
6496 * scsi_done - used to save caller's done function
6497 * host_scribble - used for pointer to another Scsi_Cmnd
6498 *
6499 * If this function returns ASC_NOERROR or ASC_ERROR the request
6500 * has been enqueued on the board's 'done' queue and must be
6501 * completed by the caller.
6502 *
6503 * If ASC_BUSY is returned the request must be enqueued by the
6504 * caller and re-tried later.
6505 */
6506STATICstatic int
6507asc_execute_scsi_cmnd(Scsi_Cmnd *scp)
6508{
6509 asc_board_t *boardp;
6510 ASC_DVC_VAR *asc_dvc_varp;
6511 ADV_DVC_VAR *adv_dvc_varp;
6512 ADV_SCSI_REQ_Q *adv_scsiqp;
6513 Scsi_Device *device;
6514 int ret;
6515
6516 ASC_ASSERT(interrupts_enabled() == ASC_FALSE){ if (!(interrupts_enabled() == 0)) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 6516); } }
;
6517 ASC_DBG2(1, "asc_execute_scsi_cmnd: scp %x, done %x\n",
6518 (unsigned) scp, (unsigned) scp->scsi_done);
6519
6520 boardp = ASC_BOARDP(scp->host)((asc_board_t *) &((scp->host)->hostdata));
6521 device = boardp->device[scp->target];
6522
6523 if (ASC_NARROW_BOARD(boardp)(((boardp)->flags & 0x04) == 0)) {
6524 /*
6525 * Build and execute Narrow Board request.
6526 */
6527
6528 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
6529
6530 /*
6531 * Build Asc Library request structure using the
6532 * global structures 'asc_scsi_req' and 'asc_sg_head'.
6533 *
6534 * asc_build_req() can not return ASC_BUSY.
6535 */
6536 if (asc_build_req(boardp, scp) == ASC_ERROR(-1)) {
6537 ASC_STATS(scp->host, build_error)(((asc_board_t *) &((scp->host)->hostdata))->asc_stats
.build_error++)
;
6538 return ASC_ERROR(-1);
6539 }
6540
6541 /*
6542 * Execute the command. If there is no error, add the command
6543 * to the active queue.
6544 */
6545 switch (ret = AscExeScsiQueue(asc_dvc_varp, &asc_scsi_q)) {
6546 case ASC_NOERROR1:
6547 ASC_STATS(scp->host, exe_noerror)(((asc_board_t *) &((scp->host)->hostdata))->asc_stats
.exe_noerror++)
;
6548 /*
6549 * Increment monotonically increasing per device successful
6550 * request counter. Wrapping doesn't matter.
6551 */
6552 boardp->reqcnt[scp->target]++;
6553
6554#if ASC_QUEUE_FLOW_CONTROL
6555 /*
6556 * Conditionally increment the device queue depth.
6557 *
6558 * If no error occurred and there have been 100 consecutive
6559 * successful requests and the current queue depth is less
6560 * than the maximum queue depth, then increment the current
6561 * queue depth.
6562 */
6563 if (boardp->nerrcnt[scp->target]++ > 100) {
6564 boardp->nerrcnt[scp->target] = 0;
6565 if (device != NULL((void *) 0) &&
6566 (device->queue_curr_depth < device->queue_depth) &&
6567 (!(boardp->queue_full &
6568 ADV_TID_TO_TIDMASK(scp->target)(0x01 << ((scp->target) & 15))) ||
6569 (boardp->queue_full_cnt[scp->target] >
6570 device->queue_curr_depth))) {
6571 device->queue_curr_depth++;
6572 }
6573 }
6574#endif /* ASC_QUEUE_FLOW_CONTROL */
6575 asc_enqueue(&boardp->active, scp, ASC_BACK2);
6576 ASC_DBG(1,
6577 "asc_execute_scsi_cmnd: AscExeScsiQueue(), ASC_NOERROR\n");
6578 break;
6579 case ASC_BUSY0:
6580 /* Caller must enqueue request and retry later. */
6581 ASC_STATS(scp->host, exe_busy)(((asc_board_t *) &((scp->host)->hostdata))->asc_stats
.exe_busy++)
;
6582#if ASC_QUEUE_FLOW_CONTROL
6583 /*
6584 * Clear consecutive no error counter and if possible decrement
6585 * queue depth.
6586 */
6587 boardp->nerrcnt[scp->target] = 0;
6588 if (device != NULL((void *) 0) && device->queue_curr_depth > 1) {
6589 device->queue_curr_depth--;
6590 }
6591#endif /* ASC_QUEUE_FLOW_CONTROL */
6592 break;
6593 case ASC_ERROR(-1):
6594 ASC_PRINT2({ printk("advansys: "); printk(("asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() ASC_ERROR, err_code %x\n"
), (boardp->id), (asc_dvc_varp->err_code)); }
6595"asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() ASC_ERROR, err_code %x\n",{ printk("advansys: "); printk(("asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() ASC_ERROR, err_code %x\n"
), (boardp->id), (asc_dvc_varp->err_code)); }
6596 boardp->id, asc_dvc_varp->err_code){ printk("advansys: "); printk(("asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() ASC_ERROR, err_code %x\n"
), (boardp->id), (asc_dvc_varp->err_code)); }
;
6597 ASC_STATS(scp->host, exe_error)(((asc_board_t *) &((scp->host)->hostdata))->asc_stats
.exe_error++)
;
6598#if ASC_QUEUE_FLOW_CONTROL
6599 /* Clear consecutive no error counter. */
6600 boardp->nerrcnt[scp->target] = 0;
6601#endif /* ASC_QUEUE_FLOW_CONTROL */
6602 scp->result = HOST_BYTE(DID_ERROR)((0x07) << 16);
6603 asc_enqueue(&boardp->done, scp, ASC_BACK2);
6604 break;
6605 default:
6606 ASC_PRINT2({ printk("advansys: "); printk(("asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() unknown, err_code %x\n"
), (boardp->id), (asc_dvc_varp->err_code)); }
6607"asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() unknown, err_code %x\n",{ printk("advansys: "); printk(("asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() unknown, err_code %x\n"
), (boardp->id), (asc_dvc_varp->err_code)); }
6608 boardp->id, asc_dvc_varp->err_code){ printk("advansys: "); printk(("asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() unknown, err_code %x\n"
), (boardp->id), (asc_dvc_varp->err_code)); }
;
6609 ASC_STATS(scp->host, exe_unknown)(((asc_board_t *) &((scp->host)->hostdata))->asc_stats
.exe_unknown++)
;
6610#if ASC_QUEUE_FLOW_CONTROL
6611 /* Clear consecutive no error counter. */
6612 boardp->nerrcnt[scp->target] = 0;
6613#endif /* ASC_QUEUE_FLOW_CONTROL */
6614 scp->result = HOST_BYTE(DID_ERROR)((0x07) << 16);
6615 asc_enqueue(&boardp->done, scp, ASC_BACK2);
6616 break;
6617 }
6618 } else {
6619 /*
6620 * Build and execute Wide Board request.
6621 */
6622 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
6623
6624 /*
6625 * Build and get a pointer to an Adv Library request structure.
6626 *
6627 * If the request is successfully built then send it below,
6628 * otherwise return with an error.
6629 */
6630 switch (adv_build_req(boardp, scp, &adv_scsiqp)) {
6631 case ASC_NOERROR1:
6632 ASC_DBG(3, "asc_execute_scsi_cmnd: adv_build_req ASC_NOERROR\n");
6633 break;
6634 case ASC_BUSY0:
6635 ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req ASC_BUSY\n");
6636 return ASC_BUSY0;
6637 case ASC_ERROR(-1):
6638 default:
6639 ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req ASC_ERROR\n");
6640 ASC_STATS(scp->host, build_error)(((asc_board_t *) &((scp->host)->hostdata))->asc_stats
.build_error++)
;
6641 return ASC_ERROR(-1);
6642 }
6643
6644 /*
6645 * Execute the command. If there is no error, add the command
6646 * to the active queue.
6647 */
6648 switch (ret = AdvExeScsiQueue(adv_dvc_varp, adv_scsiqp)) {
6649 case ASC_NOERROR1:
6650 ASC_STATS(scp->host, exe_noerror)(((asc_board_t *) &((scp->host)->hostdata))->asc_stats
.exe_noerror++)
;
6651 /*
6652 * Increment monotonically increasing per device successful
6653 * request counter. Wrapping doesn't matter.
6654 */
6655 boardp->reqcnt[scp->target]++;
6656 asc_enqueue(&boardp->active, scp, ASC_BACK2);
6657 ASC_DBG(1,
6658 "asc_execute_scsi_cmnd: AdvExeScsiQueue(), ASC_NOERROR\n");
6659 break;
6660 case ASC_BUSY0:
6661 /* Caller must enqueue request and retry later. */
6662 ASC_STATS(scp->host, exe_busy)(((asc_board_t *) &((scp->host)->hostdata))->asc_stats
.exe_busy++)
;
6663 break;
6664 case ASC_ERROR(-1):
6665 ASC_PRINT2({ printk("advansys: "); printk(("asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() ASC_ERROR, err_code %x\n"
), (boardp->id), (adv_dvc_varp->err_code)); }
6666"asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() ASC_ERROR, err_code %x\n",{ printk("advansys: "); printk(("asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() ASC_ERROR, err_code %x\n"
), (boardp->id), (adv_dvc_varp->err_code)); }
6667 boardp->id, adv_dvc_varp->err_code){ printk("advansys: "); printk(("asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() ASC_ERROR, err_code %x\n"
), (boardp->id), (adv_dvc_varp->err_code)); }
;
6668 ASC_STATS(scp->host, exe_error)(((asc_board_t *) &((scp->host)->hostdata))->asc_stats
.exe_error++)
;
6669 scp->result = HOST_BYTE(DID_ERROR)((0x07) << 16);
6670 asc_enqueue(&boardp->done, scp, ASC_BACK2);
6671 break;
6672 default:
6673 ASC_PRINT2({ printk("advansys: "); printk(("asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() unknown, err_code %x\n"
), (boardp->id), (adv_dvc_varp->err_code)); }
6674"asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() unknown, err_code %x\n",{ printk("advansys: "); printk(("asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() unknown, err_code %x\n"
), (boardp->id), (adv_dvc_varp->err_code)); }
6675 boardp->id, adv_dvc_varp->err_code){ printk("advansys: "); printk(("asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() unknown, err_code %x\n"
), (boardp->id), (adv_dvc_varp->err_code)); }
;
6676 ASC_STATS(scp->host, exe_unknown)(((asc_board_t *) &((scp->host)->hostdata))->asc_stats
.exe_unknown++)
;
6677 scp->result = HOST_BYTE(DID_ERROR)((0x07) << 16);
6678 asc_enqueue(&boardp->done, scp, ASC_BACK2);
6679 break;
6680 }
6681 }
6682
6683 ASC_DBG(1, "asc_execute_scsi_cmnd: end\n");
6684 ASC_ASSERT(interrupts_enabled() == ASC_FALSE){ if (!(interrupts_enabled() == 0)) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 6684); } }
;
6685 return ret;
6686}
6687
6688/*
6689 * Build a request structure for the Asc Library (Narrow Board).
6690 *
6691 * The global structures 'asc_scsi_q' and 'asc_sg_head' are
6692 * used to build the request.
6693 *
6694 * If an error occurs, then return ASC_ERROR.
6695 */
6696STATICstatic int
6697asc_build_req(asc_board_t *boardp, Scsi_Cmnd *scp)
6698{
6699 /*
6700 * Mutually exclusive access is required to 'asc_scsi_q' and
6701 * 'asc_sg_head' until after the request is started.
6702 */
6703 memset(&asc_scsi_q, 0, sizeof(ASC_SCSI_Q))(__builtin_constant_p(0) ? (__builtin_constant_p((sizeof(ASC_SCSI_Q
))) ? __constant_c_and_count_memset(((&asc_scsi_q)),((0x01010101UL
*(unsigned char)(0))),((sizeof(ASC_SCSI_Q)))) : __constant_c_memset
(((&asc_scsi_q)),((0x01010101UL*(unsigned char)(0))),((sizeof
(ASC_SCSI_Q))))) : (__builtin_constant_p((sizeof(ASC_SCSI_Q))
) ? __memset_generic((((&asc_scsi_q))),(((0))),(((sizeof(
ASC_SCSI_Q))))) : __memset_generic(((&asc_scsi_q)),((0)),
((sizeof(ASC_SCSI_Q))))))
;
6704
6705 /*
6706 * Point the ASC_SCSI_Q to the 'Scsi_Cmnd'.
6707 */
6708 asc_scsi_q.q2.srb_ptr = (ulong) scp;
6709
6710 /*
6711 * Build the ASC_SCSI_Q request.
6712 */
6713 ASC_ASSERT(scp->cmd_len <= ASC_MAX_CDB_LEN){ if (!(scp->cmd_len <= 12)) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 6713); } }
;
6714 if (scp->cmd_len > ASC_MAX_CDB_LEN12) {
6715 scp->cmd_len = ASC_MAX_CDB_LEN12;
6716 }
6717 asc_scsi_q.cdbptr = &scp->cmnd[0];
6718 asc_scsi_q.q2.cdb_len = scp->cmd_len;
6719 asc_scsi_q.q1.target_id = ASC_TID_TO_TARGET_ID(scp->target)(uchar)(0x01 << (scp->target));
6720 asc_scsi_q.q1.target_lun = scp->lun;
6721 asc_scsi_q.q2.target_ix = ASC_TIDLUN_TO_IX(scp->target, scp->lun)(uchar)((scp->target) + ((scp->lun)<<3));
6722#if LINUX_VERSION_CODE131108 < ASC_LINUX_VERSION(2,0,0)(((2) * 65536) + ((0) * 256) + (0))
6723 asc_scsi_q.q1.sense_addr = (ulong) &scp->sense_buffer[0];
6724#else /* version >= v2.0.0 */
6725 asc_scsi_q.q1.sense_addr = virt_to_busvirt_to_phys(&scp->sense_buffer[0]);
6726#endif /* version >= v2.0.0 */
6727 asc_scsi_q.q1.sense_len = sizeof(scp->sense_buffer);
6728
6729 /*
6730 * If there are any outstanding requests for the current target,
6731 * then every 255th request send an ORDERED request. This heuristic
6732 * tries to retain the benefit of request sorting while preventing
6733 * request starvation. 255 is the max number of tags or pending commands
6734 * a device may have outstanding.
6735 *
6736 * The request count is incremented below for every successfully
6737 * started request.
6738 *
6739 */
6740 if ((boardp->dvc_var.asc_dvc_var.cur_dvc_qng[scp->target] > 0) &&
6741 (boardp->reqcnt[scp->target] % 255) == 0) {
6742 asc_scsi_q.q2.tag_code = M2_QTAG_MSG_ORDERED0x22;
6743 } else {
6744 asc_scsi_q.q2.tag_code = M2_QTAG_MSG_SIMPLE0x20;
6745 }
6746
6747 /*
6748 * Build ASC_SCSI_Q for a contiguous buffer or a scatter-gather
6749 * buffer command.
6750 */
6751 if (scp->use_sg == 0) {
6752 /*
6753 * CDB request of single contiguous buffer.
6754 */
6755 ASC_STATS(scp->host, cont_cnt)(((asc_board_t *) &((scp->host)->hostdata))->asc_stats
.cont_cnt++)
;
6756#if LINUX_VERSION_CODE131108 < ASC_LINUX_VERSION(2,0,0)(((2) * 65536) + ((0) * 256) + (0))
6757 asc_scsi_q.q1.data_addr = (ulong) scp->request_buffer;
6758#else /* version >= v2.0.0 */
6759 asc_scsi_q.q1.data_addr = virt_to_busvirt_to_phys(scp->request_buffer);
6760#endif /* version >= v2.0.0 */
6761 asc_scsi_q.q1.data_cnt = scp->request_bufflen;
6762 ASC_STATS_ADD(scp->host, cont_xfer,(((asc_board_t *) &((scp->host)->hostdata))->asc_stats
.cont_xfer += ((((scp->request_bufflen) + ((512) - 1))/(512
))))
6763 ASC_CEILING(scp->request_bufflen, 512))(((asc_board_t *) &((scp->host)->hostdata))->asc_stats
.cont_xfer += ((((scp->request_bufflen) + ((512) - 1))/(512
))))
;
6764 asc_scsi_q.q1.sg_queue_cnt = 0;
6765 asc_scsi_q.sg_head = NULL((void *) 0);
6766 } else {
6767 /*
6768 * CDB scatter-gather request list.
6769 */
6770 int sgcnt;
6771 struct scatterlist *slp;
6772
6773 if (scp->use_sg > scp->host->sg_tablesize) {
6774 ASC_PRINT3({ printk("advansys: "); printk(("asc_build_req: board %d: use_sg %d > sg_tablesize %d\n"
), (boardp->id), (scp->use_sg), (scp->host->sg_tablesize
)); }
6775"asc_build_req: board %d: use_sg %d > sg_tablesize %d\n",{ printk("advansys: "); printk(("asc_build_req: board %d: use_sg %d > sg_tablesize %d\n"
), (boardp->id), (scp->use_sg), (scp->host->sg_tablesize
)); }
6776 boardp->id, scp->use_sg, scp->host->sg_tablesize){ printk("advansys: "); printk(("asc_build_req: board %d: use_sg %d > sg_tablesize %d\n"
), (boardp->id), (scp->use_sg), (scp->host->sg_tablesize
)); }
;
6777 scp->result = HOST_BYTE(DID_ERROR)((0x07) << 16);
6778 asc_enqueue(&boardp->done, scp, ASC_BACK2);
6779 return ASC_ERROR(-1);
6780 }
6781
6782 ASC_STATS(scp->host, sg_cnt)(((asc_board_t *) &((scp->host)->hostdata))->asc_stats
.sg_cnt++)
;
6783
6784 /*
6785 * Use global ASC_SG_HEAD structure and set the ASC_SCSI_Q
6786 * structure to point to it.
6787 */
6788 memset(&asc_sg_head, 0, sizeof(ASC_SG_HEAD))(__builtin_constant_p(0) ? (__builtin_constant_p((sizeof(ASC_SG_HEAD
))) ? __constant_c_and_count_memset(((&asc_sg_head)),((0x01010101UL
*(unsigned char)(0))),((sizeof(ASC_SG_HEAD)))) : __constant_c_memset
(((&asc_sg_head)),((0x01010101UL*(unsigned char)(0))),((sizeof
(ASC_SG_HEAD))))) : (__builtin_constant_p((sizeof(ASC_SG_HEAD
))) ? __memset_generic((((&asc_sg_head))),(((0))),(((sizeof
(ASC_SG_HEAD))))) : __memset_generic(((&asc_sg_head)),((0
)),((sizeof(ASC_SG_HEAD))))))
;
6789
6790 asc_scsi_q.q1.cntl |= QC_SG_HEAD0x04;
6791 asc_scsi_q.sg_head = &asc_sg_head;
6792 asc_scsi_q.q1.data_cnt = 0;
6793 asc_scsi_q.q1.data_addr = 0;
6794 asc_sg_head.entry_cnt = asc_scsi_q.q1.sg_queue_cnt = scp->use_sg;
6795 ASC_STATS_ADD(scp->host, sg_elem, asc_sg_head.entry_cnt)(((asc_board_t *) &((scp->host)->hostdata))->asc_stats
.sg_elem += (asc_sg_head.entry_cnt))
;
6796
6797 /*
6798 * Convert scatter-gather list into ASC_SG_HEAD list.
6799 */
6800 slp = (struct scatterlist *) scp->request_buffer;
6801 for (sgcnt = 0; sgcnt < scp->use_sg; sgcnt++, slp++) {
6802#if LINUX_VERSION_CODE131108 < ASC_LINUX_VERSION(2,0,0)(((2) * 65536) + ((0) * 256) + (0))
6803 asc_sg_head.sg_list[sgcnt].addr = (ulong) slp->address;
6804#else /* version >= v2.0.0 */
6805 asc_sg_head.sg_list[sgcnt].addr = virt_to_busvirt_to_phys(slp->address);
6806#endif /* version >= v2.0.0 */
6807 asc_sg_head.sg_list[sgcnt].bytes = slp->length;
6808 ASC_STATS_ADD(scp->host, sg_xfer, ASC_CEILING(slp->length, 512))(((asc_board_t *) &((scp->host)->hostdata))->asc_stats
.sg_xfer += ((((slp->length) + ((512) - 1))/(512))))
;
6809 }
6810 }
6811
6812 ASC_DBG_PRT_ASC_SCSI_Q(2, &asc_scsi_q);
6813 ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
6814
6815 return ASC_NOERROR1;
6816}
6817
6818/*
6819 * Build a request structure for the Adv Library (Wide Board).
6820 *
6821 * If an adv_req_t can not be allocated to issue the request,
6822 * then return ASC_BUSY. If an error occurs, then return ASC_ERROR.
6823 */
6824STATICstatic int
6825adv_build_req(asc_board_t *boardp, Scsi_Cmnd *scp,
6826 ADV_SCSI_REQ_Q **adv_scsiqpp)
6827{
6828 adv_req_t *reqp;
6829 ADV_SCSI_REQ_Q *scsiqp;
6830 int i;
6831
6832 /*
6833 * Allocate an adv_req_t structure from the board to execute
6834 * the command.
6835 */
6836 if (boardp->adv_reqp == NULL((void *) 0)) {
6837 ASC_DBG(1, "adv_build_req: no free adv_req_t\n");
6838 ASC_STATS(scp->host, adv_build_noreq)(((asc_board_t *) &((scp->host)->hostdata))->asc_stats
.adv_build_noreq++)
;
6839 return ASC_BUSY0;
6840 } else {
6841 reqp = boardp->adv_reqp;
6842 boardp->adv_reqp = reqp->next_reqp;
6843 reqp->next_reqp = NULL((void *) 0);
6844 }
6845
6846 /*
6847 * Get 4-byte aligned ADV_SCSI_REQ_Q and ADV_SG_BLOCK pointers.
6848 */
6849 scsiqp = (ADV_SCSI_REQ_Q *) ADV_DWALIGN(&reqp->scsi_req_q)(((ulong) (&reqp->scsi_req_q) + 0x3) & ~0x3);
6850 memset(scsiqp, 0, sizeof(ADV_SCSI_REQ_Q))(__builtin_constant_p(0) ? (__builtin_constant_p((sizeof(ADV_SCSI_REQ_Q
))) ? __constant_c_and_count_memset(((scsiqp)),((0x01010101UL
*(unsigned char)(0))),((sizeof(ADV_SCSI_REQ_Q)))) : __constant_c_memset
(((scsiqp)),((0x01010101UL*(unsigned char)(0))),((sizeof(ADV_SCSI_REQ_Q
))))) : (__builtin_constant_p((sizeof(ADV_SCSI_REQ_Q))) ? __memset_generic
((((scsiqp))),(((0))),(((sizeof(ADV_SCSI_REQ_Q))))) : __memset_generic
(((scsiqp)),((0)),((sizeof(ADV_SCSI_REQ_Q))))))
;
6851
6852 /*
6853 * Set the ADV_SCSI_REQ_Q 'srb_ptr' to point to the adv_req_t structure.
6854 */
6855 scsiqp->srb_ptr = (ulong) reqp;
6856
6857 /*
6858 * Set the adv_req_t 'cmndp' to point to the Scsi_Cmnd structure.
6859 */
6860 reqp->cmndp = scp;
6861
6862 /*
6863 * Build the ADV_SCSI_REQ_Q request.
6864 */
6865
6866 /*
6867 * Set CDB length and copy it to the request structure.
6868 */
6869 ASC_ASSERT(scp->cmd_len <= ASC_MAX_CDB_LEN){ if (!(scp->cmd_len <= 12)) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 6869); } }
;
6870 if (scp->cmd_len > ASC_MAX_CDB_LEN12) {
6871 scp->cmd_len = ASC_MAX_CDB_LEN12;
6872 }
6873 scsiqp->cdb_len = scp->cmd_len;
6874 for (i = 0; i < scp->cmd_len; i++) {
6875 scsiqp->cdb[i] = scp->cmnd[i];
6876 }
6877
6878 scsiqp->target_id = scp->target;
6879 scsiqp->target_lun = scp->lun;
6880
6881 scsiqp->vsense_addr = (ulong) &scp->sense_buffer[0];
6882#if LINUX_VERSION_CODE131108 < ASC_LINUX_VERSION(2,0,0)(((2) * 65536) + ((0) * 256) + (0))
6883 scsiqp->sense_addr = (ulong) &scp->sense_buffer[0];
6884#else /* version >= v2.0.0 */
6885 scsiqp->sense_addr = virt_to_busvirt_to_phys(&scp->sense_buffer[0]);
6886#endif /* version >= v2.0.0 */
6887 scsiqp->sense_len = sizeof(scp->sense_buffer);
6888
6889 /*
6890 * Build ADV_SCSI_REQ_Q for a contiguous buffer or a scatter-gather
6891 * buffer command.
6892 */
6893 scsiqp->data_cnt = scp->request_bufflen;
6894 scsiqp->vdata_addr = (ulong) scp->request_buffer;
6895#if LINUX_VERSION_CODE131108 < ASC_LINUX_VERSION(2,0,0)(((2) * 65536) + ((0) * 256) + (0))
6896 scsiqp->data_addr = (ulong) scp->request_buffer;
6897#else /* version >= v2.0.0 */
6898 scsiqp->data_addr = virt_to_busvirt_to_phys(scp->request_buffer);
6899#endif /* version >= v2.0.0 */
6900
6901 if (scp->use_sg == 0) {
6902 /*
6903 * CDB request of single contiguous buffer.
6904 */
6905 reqp->sgblkp = NULL((void *) 0);
6906 scsiqp->sg_list_ptr = NULL((void *) 0);
6907 ASC_STATS(scp->host, cont_cnt)(((asc_board_t *) &((scp->host)->hostdata))->asc_stats
.cont_cnt++)
;
6908 ASC_STATS_ADD(scp->host, cont_xfer,(((asc_board_t *) &((scp->host)->hostdata))->asc_stats
.cont_xfer += ((((scp->request_bufflen) + ((512) - 1))/(512
))))
6909 ASC_CEILING(scp->request_bufflen, 512))(((asc_board_t *) &((scp->host)->hostdata))->asc_stats
.cont_xfer += ((((scp->request_bufflen) + ((512) - 1))/(512
))))
;
6910 } else {
6911 /*
6912 * CDB scatter-gather request list.
6913 */
6914 if (scp->use_sg > ADV_MAX_SG_LIST64) {
6915 ASC_PRINT3({ printk("advansys: "); printk(("adv_build_req: board %d: use_sg %d > ADV_MAX_SG_LIST %d\n"
), (boardp->id), (scp->use_sg), (scp->host->sg_tablesize
)); }
6916"adv_build_req: board %d: use_sg %d > ADV_MAX_SG_LIST %d\n",{ printk("advansys: "); printk(("adv_build_req: board %d: use_sg %d > ADV_MAX_SG_LIST %d\n"
), (boardp->id), (scp->use_sg), (scp->host->sg_tablesize
)); }
6917 boardp->id, scp->use_sg, scp->host->sg_tablesize){ printk("advansys: "); printk(("adv_build_req: board %d: use_sg %d > ADV_MAX_SG_LIST %d\n"
), (boardp->id), (scp->use_sg), (scp->host->sg_tablesize
)); }
;
6918 scp->result = HOST_BYTE(DID_ERROR)((0x07) << 16);
6919 asc_enqueue(&boardp->done, scp, ASC_BACK2);
6920
6921 /*
6922 * Free the 'adv_req_t' structure by adding it back to the
6923 * board free list.
6924 */
6925 reqp->next_reqp = boardp->adv_reqp;
6926 boardp->adv_reqp = reqp;
6927
6928 return ASC_ERROR(-1);
6929 }
6930
6931 /*
6932 * Allocate an 'adv_sgblk_t' structure from the board to
6933 * execute the command.
6934 */
6935 if (boardp->adv_sgblkp == NULL((void *) 0)) {
6936 ASC_DBG(1, "adv_build_req: no free adv_sgblk_t\n");
6937 ASC_STATS(scp->host, adv_build_nosg)(((asc_board_t *) &((scp->host)->hostdata))->asc_stats
.adv_build_nosg++)
;
6938 /*
6939 * Free the 'adv_req_t' structure by adding it back to the
6940 * board free list.
6941 */
6942 reqp->next_reqp = boardp->adv_reqp;
6943 boardp->adv_reqp = reqp;
6944 return ASC_BUSY0;
6945 } else {
6946 reqp->sgblkp = boardp->adv_sgblkp;
6947 boardp->adv_sgblkp = reqp->sgblkp->next_sgblkp;
6948 reqp->sgblkp->next_sgblkp = NULL((void *) 0);
6949 }
6950
6951 /*
6952 * Build scatter-gather list.
6953 */
6954 scsiqp->sg_list_ptr = (ADV_SG_BLOCK *)
6955 ADV_DWALIGN(&reqp->sgblkp->sg_block[0])(((ulong) (&reqp->sgblkp->sg_block[0]) + 0x3) &
~0x3)
;
6956
6957 memset(scsiqp->sg_list_ptr, 0, sizeof(ADV_SG_BLOCK) *(__builtin_constant_p(0) ? (__builtin_constant_p((sizeof(ADV_SG_BLOCK
) * (((64 + (15 - 1))/15) + (((sizeof(ADV_SG_BLOCK) * ((64 + (
15 - 1))/15)) + ((1 << 12) - 1))/(1 << 12))))) ? __constant_c_and_count_memset
(((scsiqp->sg_list_ptr)),((0x01010101UL*(unsigned char)(0)
)),((sizeof(ADV_SG_BLOCK) * (((64 + (15 - 1))/15) + (((sizeof
(ADV_SG_BLOCK) * ((64 + (15 - 1))/15)) + ((1 << 12) - 1
))/(1 << 12)))))) : __constant_c_memset(((scsiqp->sg_list_ptr
)),((0x01010101UL*(unsigned char)(0))),((sizeof(ADV_SG_BLOCK)
* (((64 + (15 - 1))/15) + (((sizeof(ADV_SG_BLOCK) * ((64 + (
15 - 1))/15)) + ((1 << 12) - 1))/(1 << 12))))))) :
(__builtin_constant_p((sizeof(ADV_SG_BLOCK) * (((64 + (15 - 1
))/15) + (((sizeof(ADV_SG_BLOCK) * ((64 + (15 - 1))/15)) + ((
1 << 12) - 1))/(1 << 12))))) ? __memset_generic((
((scsiqp->sg_list_ptr))),(((0))),(((sizeof(ADV_SG_BLOCK) *
(((64 + (15 - 1))/15) + (((sizeof(ADV_SG_BLOCK) * ((64 + (15
- 1))/15)) + ((1 << 12) - 1))/(1 << 12))))))) : __memset_generic
(((scsiqp->sg_list_ptr)),((0)),((sizeof(ADV_SG_BLOCK) * ((
(64 + (15 - 1))/15) + (((sizeof(ADV_SG_BLOCK) * ((64 + (15 - 1
))/15)) + ((1 << 12) - 1))/(1 << 12))))))))
6958 (ADV_NUM_SG_BLOCK + ADV_NUM_PAGE_CROSSING))(__builtin_constant_p(0) ? (__builtin_constant_p((sizeof(ADV_SG_BLOCK
) * (((64 + (15 - 1))/15) + (((sizeof(ADV_SG_BLOCK) * ((64 + (
15 - 1))/15)) + ((1 << 12) - 1))/(1 << 12))))) ? __constant_c_and_count_memset
(((scsiqp->sg_list_ptr)),((0x01010101UL*(unsigned char)(0)
)),((sizeof(ADV_SG_BLOCK) * (((64 + (15 - 1))/15) + (((sizeof
(ADV_SG_BLOCK) * ((64 + (15 - 1))/15)) + ((1 << 12) - 1
))/(1 << 12)))))) : __constant_c_memset(((scsiqp->sg_list_ptr
)),((0x01010101UL*(unsigned char)(0))),((sizeof(ADV_SG_BLOCK)
* (((64 + (15 - 1))/15) + (((sizeof(ADV_SG_BLOCK) * ((64 + (
15 - 1))/15)) + ((1 << 12) - 1))/(1 << 12))))))) :
(__builtin_constant_p((sizeof(ADV_SG_BLOCK) * (((64 + (15 - 1
))/15) + (((sizeof(ADV_SG_BLOCK) * ((64 + (15 - 1))/15)) + ((
1 << 12) - 1))/(1 << 12))))) ? __memset_generic((
((scsiqp->sg_list_ptr))),(((0))),(((sizeof(ADV_SG_BLOCK) *
(((64 + (15 - 1))/15) + (((sizeof(ADV_SG_BLOCK) * ((64 + (15
- 1))/15)) + ((1 << 12) - 1))/(1 << 12))))))) : __memset_generic
(((scsiqp->sg_list_ptr)),((0)),((sizeof(ADV_SG_BLOCK) * ((
(64 + (15 - 1))/15) + (((sizeof(ADV_SG_BLOCK) * ((64 + (15 - 1
))/15)) + ((1 << 12) - 1))/(1 << 12))))))))
;
6959
6960 if (adv_get_sglist(&boardp->dvc_var.adv_dvc_var, scsiqp, scp) ==
6961 ADV_ERROR(-1)) {
6962
6963 /*
6964 * Free the adv_sgblk_t structure, if any, by adding it back
6965 * to the board free list.
6966 */
6967 ASC_ASSERT(reqp->sgblkp != NULL){ if (!(reqp->sgblkp != ((void *) 0))) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 6967); } }
;
6968 reqp->sgblkp->next_sgblkp = boardp->adv_sgblkp;
6969 boardp->adv_sgblkp = reqp->sgblkp;
6970
6971 /*
6972 * Free the adv_req_t structure by adding it back to the
6973 * board free list.
6974 */
6975 reqp->next_reqp = boardp->adv_reqp;
6976 boardp->adv_reqp = reqp;
6977
6978 return ADV_ERROR(-1);
6979 }
6980
6981 ASC_STATS(scp->host, sg_cnt)(((asc_board_t *) &((scp->host)->hostdata))->asc_stats
.sg_cnt++)
;
6982 ASC_STATS_ADD(scp->host, sg_elem, scp->use_sg)(((asc_board_t *) &((scp->host)->hostdata))->asc_stats
.sg_elem += (scp->use_sg))
;
6983 }
6984
6985 ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
6986 ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
6987
6988 *adv_scsiqpp = scsiqp;
6989
6990 return ASC_NOERROR1;
6991}
6992
6993/*
6994 * Build scatter-gather list for Adv Library (Wide Board).
6995 *
6996 * Return:
6997 * ADV_SUCCESS(1) - SG List successfully created
6998 * ADV_ERROR(-1) - SG List creation failed
6999 */
7000STATICstatic int
7001adv_get_sglist(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp,
7002 Scsi_Cmnd *scp)
7003{
7004 ADV_SG_BLOCK *sg_block; /* virtual address of a SG */
7005 ulong sg_block_next_addr; /* block and its next */
7006 ulong sg_block_physical_addr;
7007 int sg_block_index, i; /* how many SG entries */
7008 struct scatterlist *slp;
7009 int sg_elem_cnt;
7010
7011 slp = (struct scatterlist *) scp->request_buffer;
7012 sg_elem_cnt = scp->use_sg;
7013
7014 sg_block = scsiqp->sg_list_ptr;
7015 sg_block_next_addr = (ulong) sg_block; /* allow math operation */
7016 sg_block_physical_addr =
7017#if LINUX_VERSION_CODE131108 < ASC_LINUX_VERSION(2,0,0)(((2) * 65536) + ((0) * 256) + (0))
7018 (ulong) scsiqp->sg_list_ptr;
7019#else /* version >= v2.0.0 */
7020 virt_to_busvirt_to_phys(scsiqp->sg_list_ptr);
7021#endif /* version >= v2.0.0 */
7022 ADV_ASSERT(ADV_DWALIGN(sg_block_physical_addr) =={ if (!((((ulong) (sg_block_physical_addr) + 0x3) & ~0x3)
== sg_block_physical_addr)) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 7023); } }
7023 sg_block_physical_addr){ if (!((((ulong) (sg_block_physical_addr) + 0x3) & ~0x3)
== sg_block_physical_addr)) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 7023); } }
;
7024 scsiqp->sg_real_addr = sg_block_physical_addr;
7025
7026 sg_block_index = 0;
7027 do
7028 {
7029 sg_block->first_entry_no = sg_block_index;
7030 for (i = 0; i < NO_OF_SG_PER_BLOCK15; i++)
7031 {
7032 sg_block->sg_list[i].sg_addr =
7033#if LINUX_VERSION_CODE131108 < ASC_LINUX_VERSION(2,0,0)(((2) * 65536) + ((0) * 256) + (0))
7034 (ulong) slp->address;
7035#else /* version >= v2.0.0 */
7036 virt_to_busvirt_to_phys(slp->address);
7037#endif /* version >= v2.0.0 */
7038 sg_block->sg_list[i].sg_count = slp->length;
7039 ASC_STATS_ADD(scp->host, sg_xfer, ASC_CEILING(slp->length, 512))(((asc_board_t *) &((scp->host)->hostdata))->asc_stats
.sg_xfer += ((((slp->length) + ((512) - 1))/(512))))
;
7040
7041 if (--sg_elem_cnt == 0)
7042 { /* last entry, get out */
7043 scsiqp->sg_entry_cnt = sg_block_index + i + 1;
7044 sg_block->last_entry_no = sg_block_index + i;
7045 sg_block->sg_ptr = 0L; /* next link = NULL */
7046 return ADV_SUCCESS1;
7047 }
7048 slp++;
7049 }
7050 sg_block_next_addr += sizeof(ADV_SG_BLOCK);
7051 sg_block_physical_addr += sizeof(ADV_SG_BLOCK);
7052 ADV_ASSERT(ADV_DWALIGN(sg_block_physical_addr) =={ if (!((((ulong) (sg_block_physical_addr) + 0x3) & ~0x3)
== sg_block_physical_addr)) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 7053); } }
7053 sg_block_physical_addr){ if (!((((ulong) (sg_block_physical_addr) + 0x3) & ~0x3)
== sg_block_physical_addr)) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 7053); } }
;
7054
7055 sg_block_index += NO_OF_SG_PER_BLOCK15;
7056 sg_block->sg_ptr = (ADV_SG_BLOCK *) sg_block_physical_addr;
7057 sg_block->last_entry_no = sg_block_index - 1;
7058 sg_block = (ADV_SG_BLOCK *) sg_block_next_addr; /* virtual addr */
7059 }
7060 while (1);
7061 /* NOTREACHED */
7062}
7063
7064/*
7065 * asc_isr_callback() - Second Level Interrupt Handler called by AscISR().
7066 *
7067 * Interrupt callback function for the Narrow SCSI Asc Library.
7068 */
7069STATICstatic void
7070asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
7071{
7072 asc_board_t *boardp;
7073 Scsi_Cmnd *scp;
7074 struct Scsi_Host *shp;
7075 int underrun = ASC_FALSE0;
7076 int i;
7077
7078 ASC_ASSERT(interrupts_enabled() == ASC_FALSE){ if (!(interrupts_enabled() == 0)) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 7078); } }
;
7079 ASC_DBG2(1, "asc_isr_callback: asc_dvc_varp %x, qdonep %x\n",
7080 (unsigned) asc_dvc_varp, (unsigned) qdonep);
7081 ASC_DBG_PRT_ASC_QDONE_INFO(2, qdonep);
7082
7083 /*
7084 * Get the Scsi_Cmnd structure and Scsi_Host structure for the
7085 * command that has been completed.
7086 */
7087 scp = (Scsi_Cmnd *) qdonep->d2.srb_ptr;
7088 ASC_DBG1(1, "asc_isr_callback: scp %x\n", (unsigned) scp);
7089
7090 if (scp == NULL((void *) 0)) {
7091 ASC_PRINT("asc_isr_callback: scp is NULL\n"){ printk("advansys: "); printk("asc_isr_callback: scp is NULL\n"
); }
;
7092 return;
7093 }
7094 ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
7095
7096 /*
7097 * If the request's host pointer is not valid, display a
7098 * message and return.
7099 */
7100 shp = scp->host;
7101 for (i = 0; i < asc_board_count; i++) {
7102 if (asc_host[i] == shp) {
7103 break;
7104 }
7105 }
7106 if (i == asc_board_count) {
7107 ASC_PRINT2("asc_isr_callback: scp %x has bad host pointer, host %x\n",{ printk("advansys: "); printk(("asc_isr_callback: scp %x has bad host pointer, host %x\n"
), ((unsigned) scp), ((unsigned) shp)); }
7108 (unsigned) scp, (unsigned) shp){ printk("advansys: "); printk(("asc_isr_callback: scp %x has bad host pointer, host %x\n"
), ((unsigned) scp), ((unsigned) shp)); }
;
7109 return;
7110 }
7111
7112 ASC_STATS(shp, callback)(((asc_board_t *) &((shp)->hostdata))->asc_stats.callback
++)
;
7113 ASC_DBG1(1, "asc_isr_callback: shp %x\n", (unsigned) shp);
7114
7115 /*
7116 * If the request isn't found on the active queue, it may
7117 * have been removed to handle a reset or abort request.
7118 * Display a message and return.
7119 */
7120 boardp = ASC_BOARDP(shp)((asc_board_t *) &((shp)->hostdata));
7121 ASC_ASSERT(asc_dvc_varp == &boardp->dvc_var.asc_dvc_var){ if (!(asc_dvc_varp == &boardp->dvc_var.asc_dvc_var))
{ printk("ASC_ASSERT() Failure: file %s, line %d\n", "../linux/src/drivers/scsi/advansys.c"
, 7121); } }
;
7122 if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE0) {
7123 ASC_PRINT2("asc_isr_callback: board %d: scp %x not on active queue\n",{ printk("advansys: "); printk(("asc_isr_callback: board %d: scp %x not on active queue\n"
), (boardp->id), ((unsigned) scp)); }
7124 boardp->id, (unsigned) scp){ printk("advansys: "); printk(("asc_isr_callback: board %d: scp %x not on active queue\n"
), (boardp->id), ((unsigned) scp)); }
;
7125 return;
7126 }
7127
7128 /*
7129 * Check for an underrun condition.
7130 */
7131 if (scp->request_bufflen != 0 && qdonep->remain_bytes != 0 &&
7132 qdonep->remain_bytes <= scp->request_bufflen != 0) {
7133 ASC_DBG1(1, "asc_isr_callback: underrun condition %u bytes\n",
7134 (unsigned) qdonep->remain_bytes);
7135 underrun = ASC_TRUE1;
7136 }
7137
7138 /*
7139 * 'qdonep' contains the command's ending status.
7140 */
7141 switch (qdonep->d3.done_stat) {
7142 case QD_NO_ERROR0x01:
7143 ASC_DBG(2, "asc_isr_callback: QD_NO_ERROR\n");
7144 switch (qdonep->d3.host_stat) {
7145 case QHSTA_NO_ERROR0x00:
7146 scp->result = 0;
7147 break;
7148 default:
7149 /* QHSTA error occurred */
7150 scp->result = HOST_BYTE(DID_ERROR)((0x07) << 16);
7151 break;
7152 }
7153
7154 /*
7155 * If an INQUIRY command completed successfully, then call
7156 * the AscInquiryHandling() function to set-up the device.
7157 */
7158 if (scp->cmnd[0] == SCSICMD_Inquiry0x12 && scp->lun == 0 &&
7159 (scp->request_bufflen - qdonep->remain_bytes) >= 8)
7160 {
7161 AscInquiryHandling(asc_dvc_varp, scp->target & 0x7,
7162 (ASC_SCSI_INQUIRY *) scp->request_buffer);
7163 }
7164
7165 /*
7166 * If there was an underrun without any other error,
7167 * set DID_ERROR to indicate the underrun error.
7168 *
7169 * Note: There is no way yet to indicate the number
7170 * of underrun bytes.
7171 */
7172 if (scp->result == 0 && underrun == ASC_TRUE1) {
7173 scp->result = HOST_BYTE(DID_UNDERRUN)((0) << 16);
7174 }
7175 break;
7176
7177 case QD_WITH_ERROR0x04:
7178 ASC_DBG(2, "asc_isr_callback: QD_WITH_ERROR\n");
7179 switch (qdonep->d3.host_stat) {
7180 case QHSTA_NO_ERROR0x00:
7181 if (qdonep->d3.scsi_stat == SS_CHK_CONDITION0x02) {
7182 ASC_DBG(2, "asc_isr_callback: SS_CHK_CONDITION\n");
7183 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
7184 sizeof(scp->sense_buffer));
7185 /*
7186 * Note: The 'status_byte()' macro used by target drivers
7187 * defined in scsi.h shifts the status byte returned by
7188 * host drivers right by 1 bit. This is why target drivers
7189 * also use right shifted status byte definitions. For
7190 * instance target drivers use CHECK_CONDITION, defined to
7191 * 0x1, instead of the SCSI defined check condition value
7192 * of 0x2. Host drivers are supposed to return the status
7193 * byte as it is defined by SCSI.
7194 */
7195 scp->result = DRIVER_BYTE(DRIVER_SENSE)((0x08) << 24) |
7196 STATUS_BYTE(qdonep->d3.scsi_stat)(qdonep->d3.scsi_stat);
7197 } else {
7198 scp->result = STATUS_BYTE(qdonep->d3.scsi_stat)(qdonep->d3.scsi_stat);
7199 }
7200 break;
7201
7202 default:
7203 /* QHSTA error occurred */
7204 ASC_DBG1(1, "asc_isr_callback: host_stat %x\n",
7205 qdonep->d3.host_stat);
7206 scp->result = HOST_BYTE(DID_BAD_TARGET)((0x04) << 16);
7207 break;
7208 }
7209 break;
7210
7211 case QD_ABORTED_BY_HOST0x02:
7212 ASC_DBG(1, "asc_isr_callback: QD_ABORTED_BY_HOST\n");
7213 scp->result = HOST_BYTE(DID_ABORT)((0x05) << 16) | MSG_BYTE(qdonep->d3.scsi_msg)((qdonep->d3.scsi_msg) << 8) |
7214 STATUS_BYTE(qdonep->d3.scsi_stat)(qdonep->d3.scsi_stat);
7215 break;
7216
7217 default:
7218 ASC_DBG1(1, "asc_isr_callback: done_stat %x\n", qdonep->d3.done_stat);
7219 scp->result = HOST_BYTE(DID_ERROR)((0x07) << 16) | MSG_BYTE(qdonep->d3.scsi_msg)((qdonep->d3.scsi_msg) << 8) |
7220 STATUS_BYTE(qdonep->d3.scsi_stat)(qdonep->d3.scsi_stat);
7221 break;
7222 }
7223
7224 /*
7225 * If the 'init_tidmask' bit isn't already set for the target and the
7226 * current request finished normally, then set the bit for the target
7227 * to indicate that a device is present.
7228 */
7229 if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->target)(0x01 << ((scp->target) & 15))) == 0 &&
7230 qdonep->d3.done_stat == QD_NO_ERROR0x01 &&
7231 qdonep->d3.host_stat == QHSTA_NO_ERROR0x00) {
7232 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->target)(0x01 << ((scp->target) & 15));
7233 }
7234
7235 /*
7236 * Because interrupts may be enabled by the 'Scsi_Cmnd' done
7237 * function, add the command to the end of the board's done queue.
7238 * The done function for the command will be called from
7239 * advansys_interrupt().
7240 */
7241 asc_enqueue(&boardp->done, scp, ASC_BACK2);
7242
7243 return;
7244}
7245
7246/*
7247 * adv_isr_callback() - Second Level Interrupt Handler called by AdvISR().
7248 *
7249 * Callback function for the Wide SCSI Adv Library.
7250 */
7251STATICstatic void
7252adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp)
7253{
7254 asc_board_t *boardp;
7255 adv_req_t *reqp;
7256 Scsi_Cmnd *scp;
7257 struct Scsi_Host *shp;
7258 int underrun = ASC_FALSE0;
7259 int i;
7260
7261 ASC_ASSERT(interrupts_enabled() == ASC_FALSE){ if (!(interrupts_enabled() == 0)) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 7261); } }
;
7262 ASC_DBG2(1, "adv_isr_callback: adv_dvc_varp %x, scsiqp %x\n",
7263 (unsigned) adv_dvc_varp, (unsigned) scsiqp);
7264 ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
7265
7266 /*
7267 * Get the adv_req_t structure for the command that has been
7268 * completed. The adv_req_t structure actually contains the
7269 * completed ADV_SCSI_REQ_Q structure.
7270 */
7271 reqp = (adv_req_t *) scsiqp->srb_ptr;
7272 ASC_DBG1(1, "adv_isr_callback: reqp %x\n", (unsigned) reqp);
7273 if (reqp == NULL((void *) 0)) {
7274 ASC_PRINT("adv_isr_callback: reqp is NULL\n"){ printk("advansys: "); printk("adv_isr_callback: reqp is NULL\n"
); }
;
7275 return;
7276 }
7277
7278 /*
7279 * Get the Scsi_Cmnd structure and Scsi_Host structure for the
7280 * command that has been completed.
7281 *
7282 * Note: The adv_req_t request structure and adv_sgblk_t structure,
7283 * if any, * dropped, because a board structure pointer can not be
7284 * determined.
7285 */
7286 scp = reqp->cmndp;
7287 ASC_DBG1(1, "adv_isr_callback: scp %x\n", (unsigned) scp);
7288 if (scp == NULL((void *) 0)) {
7289 ASC_PRINT("adv_isr_callback: scp is NULL; adv_req_t dropped.\n"){ printk("advansys: "); printk("adv_isr_callback: scp is NULL; adv_req_t dropped.\n"
); }
;
7290 return;
7291 }
7292 ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
7293
7294 /*
7295 * If the request's host pointer is not valid, display a message
7296 * and return.
7297 */
7298 shp = scp->host;
7299 for (i = 0; i < asc_board_count; i++) {
7300 if (asc_host[i] == shp) {
7301 break;
7302 }
7303 }
7304 /*
7305 * Note: If the host structure is not found, the adv_req_t request
7306 * structure and adv_sgblk_t structure, if any, is dropped.
7307 */
7308 if (i == asc_board_count) {
7309 ASC_PRINT2("adv_isr_callback: scp %x has bad host pointer, host %x\n",{ printk("advansys: "); printk(("adv_isr_callback: scp %x has bad host pointer, host %x\n"
), ((unsigned) scp), ((unsigned) shp)); }
7310 (unsigned) scp, (unsigned) shp){ printk("advansys: "); printk(("adv_isr_callback: scp %x has bad host pointer, host %x\n"
), ((unsigned) scp), ((unsigned) shp)); }
;
7311 return;
7312 }
7313
7314 ASC_STATS(shp, callback)(((asc_board_t *) &((shp)->hostdata))->asc_stats.callback
++)
;
7315 ASC_DBG1(1, "adv_isr_callback: shp %x\n", (unsigned) shp);
7316
7317 /*
7318 * If the request isn't found on the active queue, it may have been
7319 * removed to handle a reset or abort request. Display a message and
7320 * return.
7321 *
7322 * Note: Because the structure may still be in use don't attempt
7323 * to free the adv_req_t and adv_sgblk_t, if any, structures.
7324 */
7325 boardp = ASC_BOARDP(shp)((asc_board_t *) &((shp)->hostdata));
7326 ASC_ASSERT(adv_dvc_varp == &boardp->dvc_var.adv_dvc_var){ if (!(adv_dvc_varp == &boardp->dvc_var.adv_dvc_var))
{ printk("ASC_ASSERT() Failure: file %s, line %d\n", "../linux/src/drivers/scsi/advansys.c"
, 7326); } }
;
7327 if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE0) {
7328 ASC_PRINT2("adv_isr_callback: board %d: scp %x not on active queue\n",{ printk("advansys: "); printk(("adv_isr_callback: board %d: scp %x not on active queue\n"
), (boardp->id), ((unsigned) scp)); }
7329 boardp->id, (unsigned) scp){ printk("advansys: "); printk(("adv_isr_callback: board %d: scp %x not on active queue\n"
), (boardp->id), ((unsigned) scp)); }
;
7330 return;
7331 }
7332
7333 /*
7334 * Check for an underrun condition.
7335 */
7336 if (scp->request_bufflen != 0 && scsiqp->data_cnt != 0) {
7337 ASC_DBG1(1, "adv_isr_callback: underrun condition %lu bytes\n",
7338 scsiqp->data_cnt);
7339 underrun = ASC_TRUE1;
7340 }
7341
7342 /*
7343 * 'done_status' contains the command's ending status.
7344 */
7345 switch (scsiqp->done_status) {
7346 case QD_NO_ERROR0x01:
7347 ASC_DBG(2, "adv_isr_callback: QD_NO_ERROR\n");
7348 switch (scsiqp->host_status) {
7349 case QHSTA_NO_ERROR0x00:
7350 scp->result = 0;
7351 break;
7352 default:
7353 /* QHSTA error occurred. */
7354 ASC_DBG1(2, "adv_isr_callback: host_status %x\n",
7355 scsiqp->host_status);
7356 scp->result = HOST_BYTE(DID_ERROR)((0x07) << 16);
7357 break;
7358 }
7359 /*
7360 * If there was an underrun without any other error,
7361 * set DID_ERROR to indicate the underrun error.
7362 *
7363 * Note: There is no way yet to indicate the number
7364 * of underrun bytes.
7365 */
7366 if (scp->result == 0 && underrun == ASC_TRUE1) {
7367 scp->result = HOST_BYTE(DID_UNDERRUN)((0) << 16);
7368 }
7369 break;
7370
7371 case QD_WITH_ERROR0x04:
7372 ASC_DBG(2, "adv_isr_callback: QD_WITH_ERROR\n");
7373 switch (scsiqp->host_status) {
7374 case QHSTA_NO_ERROR0x00:
7375 if (scsiqp->scsi_status == SS_CHK_CONDITION0x02) {
7376 ASC_DBG(2, "adv_isr_callback: SS_CHK_CONDITION\n");
7377 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
7378 sizeof(scp->sense_buffer));
7379 /*
7380 * Note: The 'status_byte()' macro used by target drivers
7381 * defined in scsi.h shifts the status byte returned by
7382 * host drivers right by 1 bit. This is why target drivers
7383 * also use right shifted status byte definitions. For
7384 * instance target drivers use CHECK_CONDITION, defined to
7385 * 0x1, instead of the SCSI defined check condition value
7386 * of 0x2. Host drivers are supposed to return the status
7387 * byte as it is defined by SCSI.
7388 */
7389 scp->result = DRIVER_BYTE(DRIVER_SENSE)((0x08) << 24) |
7390 STATUS_BYTE(scsiqp->scsi_status)(scsiqp->scsi_status);
7391 } else {
7392 scp->result = STATUS_BYTE(scsiqp->scsi_status)(scsiqp->scsi_status);
7393 }
7394 break;
7395
7396 default:
7397 /* Some other QHSTA error occurred. */
7398 ASC_DBG1(1, "adv_isr_callback: host_status %x\n",
7399 scsiqp->host_status);
7400 scp->result = HOST_BYTE(DID_BAD_TARGET)((0x04) << 16);
7401 break;
7402 }
7403 break;
7404
7405 case QD_ABORTED_BY_HOST0x02:
7406 ASC_DBG(1, "adv_isr_callback: QD_ABORTED_BY_HOST\n");
7407 scp->result = HOST_BYTE(DID_ABORT)((0x05) << 16) | STATUS_BYTE(scsiqp->scsi_status)(scsiqp->scsi_status);
7408 break;
7409
7410 default:
7411 ASC_DBG1(1, "adv_isr_callback: done_status %x\n", scsiqp->done_status);
7412 scp->result = HOST_BYTE(DID_ERROR)((0x07) << 16) | STATUS_BYTE(scsiqp->scsi_status)(scsiqp->scsi_status);
7413 break;
7414 }
7415
7416 /*
7417 * If the 'init_tidmask' bit isn't already set for the target and the
7418 * current request finished normally, then set the bit for the target
7419 * to indicate that a device is present.
7420 */
7421 if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->target)(0x01 << ((scp->target) & 15))) == 0 &&
7422 scsiqp->done_status == QD_NO_ERROR0x01 &&
7423 scsiqp->host_status == QHSTA_NO_ERROR0x00) {
7424 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->target)(0x01 << ((scp->target) & 15));
7425 }
7426
7427 /*
7428 * Because interrupts may be enabled by the 'Scsi_Cmnd' done
7429 * function, add the command to the end of the board's done queue.
7430 * The done function for the command will be called from
7431 * advansys_interrupt().
7432 */
7433 asc_enqueue(&boardp->done, scp, ASC_BACK2);
7434
7435 /*
7436 * Free the adv_sgblk_t structure, if any, by adding it back
7437 * to the board free list.
7438 */
7439 if (reqp->sgblkp != NULL((void *) 0)) {
7440 reqp->sgblkp->next_sgblkp = boardp->adv_sgblkp;
7441 boardp->adv_sgblkp = reqp->sgblkp;
7442 }
7443
7444 /*
7445 * Free the adv_req_t structure used with the command by adding
7446 * it back to the board free list.
7447 */
7448 reqp->next_reqp = boardp->adv_reqp;
7449 boardp->adv_reqp = reqp;
7450
7451 ASC_DBG(1, "adv_isr_callback: done\n");
7452
7453 return;
7454}
7455
7456#if LINUX_VERSION_CODE131108 < ASC_LINUX_VERSION(2,1,93)(((2) * 65536) + ((1) * 256) + (93))
7457#ifdef ASC_CONFIG_PCI
7458/*
7459 * Search for an AdvanSys PCI device in the PCI configuration space.
7460 */
7461ASC_INITFUNC(static int asc_srch_pci_dev(PCI_DEVICE *pciDevice)
7462STATIC intstatic int asc_srch_pci_dev(PCI_DEVICE *pciDevice)
7463asc_srch_pci_dev(PCI_DEVICE *pciDevice)static int asc_srch_pci_dev(PCI_DEVICE *pciDevice)
7464)static int asc_srch_pci_dev(PCI_DEVICE *pciDevice)
7465{
7466 int ret = PCI_DEVICE_NOT_FOUND0xffff;
7467
7468 ASC_DBG(2, "asc_srch_pci_dev: begin\n");
7469
7470 if (pci_scan_method == -1) {
7471 pci_scan_method = asc_scan_method();
7472 }
7473 pciDevice->type = pci_scan_method;
7474 ASC_DBG1(2, "asc_srch_pci_dev: type %d\n", pciDevice->type);
7475
7476 ret = asc_pci_find_dev(pciDevice);
7477 ASC_DBG1(2, "asc_srch_pci_dev: asc_pci_find_dev() return %d\n", ret);
7478 if (ret == PCI_DEVICE_FOUND0x0000) {
7479 pciDevice->slotNumber = pciDevice->slotFound + 1;
7480 pciDevice->startSlot = pciDevice->slotFound + 1;
7481 } else {
7482 if (pciDevice->bridge > pciDevice->busNumber) {
7483 ASC_DBG2(2, "asc_srch_pci_dev: bridge %x, busNumber %x\n",
7484 pciDevice->bridge, pciDevice->busNumber);
7485 pciDevice->busNumber++;
7486 pciDevice->slotNumber = 0;
7487 pciDevice->startSlot = 0;
7488 pciDevice->endSlot = 0x0f;
7489 ret = asc_srch_pci_dev(pciDevice);
7490 ASC_DBG1(2, "asc_srch_pci_dev: recursive call return %d\n", ret);
7491 }
7492 }
7493
7494 ASC_DBG1(2, "asc_srch_pci_dev: return %d\n", ret);
7495 return ret;
7496}
7497
7498/*
7499 * Determine the access method to be used for 'pciDevice'.
7500 */
7501ASC_INITFUNC(static uchar asc_scan_method(void)
7502STATIC ucharstatic uchar asc_scan_method(void)
7503asc_scan_method(void)static uchar asc_scan_method(void)
7504)static uchar asc_scan_method(void)
7505{
7506 ushort data;
7507 PCI_DATA pciData;
7508 uchar type;
7509 uchar slot;
7510
7511 ASC_DBG(2, "asc_scan_method: begin\n");
7512 memset(&pciData, 0, sizeof(pciData))(__builtin_constant_p(0) ? (__builtin_constant_p((sizeof(pciData
))) ? __constant_c_and_count_memset(((&pciData)),((0x01010101UL
*(unsigned char)(0))),((sizeof(pciData)))) : __constant_c_memset
(((&pciData)),((0x01010101UL*(unsigned char)(0))),((sizeof
(pciData))))) : (__builtin_constant_p((sizeof(pciData))) ? __memset_generic
((((&pciData))),(((0))),(((sizeof(pciData))))) : __memset_generic
(((&pciData)),((0)),((sizeof(pciData))))))
;
7513 for (type = 1; type < 3; type++) {
7514 pciData.type = type;
7515 for (slot = 0; slot < PCI_MAX_SLOT0x1F; slot++) {
7516 pciData.slot = slot;
7517 data = asc_get_cfg_word(&pciData);
7518 if ((data != 0xFFFF) && (data != 0x0000)) {
7519 ASC_DBG2(4, "asc_scan_method: data %x, type %d\n", data, type);
7520 return (type);
7521 }
7522 }
7523 }
7524 ASC_DBG1(4, "asc_scan_method: type %d\n", type);
7525 return (type);
7526}
7527
7528/*
7529 * Check for an AdvanSys PCI device in 'pciDevice'.
7530 *
7531 * Return PCI_DEVICE_FOUND if found, otherwise return PCI_DEVICE_NOT_FOUND.
7532 */
7533ASC_INITFUNC(static int asc_pci_find_dev(PCI_DEVICE *pciDevice)
7534STATIC intstatic int asc_pci_find_dev(PCI_DEVICE *pciDevice)
7535asc_pci_find_dev(PCI_DEVICE *pciDevice)static int asc_pci_find_dev(PCI_DEVICE *pciDevice)
7536)static int asc_pci_find_dev(PCI_DEVICE *pciDevice)
7537{
7538 PCI_DATA pciData;
7539 ushort vendorid, deviceid;
7540 uchar classcode, subclass;
7541 uchar lslot;
7542
7543 ASC_DBG(3, "asc_pci_find_dev: begin\n");
7544 pciData.type = pciDevice->type;
7545 pciData.bus = pciDevice->busNumber;
7546 pciData.func = pciDevice->devFunc;
7547 lslot = pciDevice->startSlot;
7548 for (; lslot < pciDevice->endSlot; lslot++) {
7549 pciData.slot = lslot;
7550 pciData.offset = VENDORID_OFFSET0x00;
7551 vendorid = asc_get_cfg_word(&pciData);
7552 ASC_DBG1(3, "asc_pci_find_dev: vendorid %x\n", vendorid);
7553 if (vendorid != 0xffff) {
7554 pciData.offset = DEVICEID_OFFSET0x02;
7555 deviceid = asc_get_cfg_word(&pciData);
7556 ASC_DBG1(3, "asc_pci_find_dev: deviceid %x\n", deviceid);
7557 if ((vendorid == ASC_PCI_VENDORID0x10CD) &&
7558 ((deviceid == ASC_PCI_DEVICE_ID_11000x1100) ||
7559 (deviceid == ASC_PCI_DEVICE_ID_12000x1200) ||
7560 (deviceid == ASC_PCI_DEVICE_ID_13000x1300) ||
7561 (deviceid == ASC_PCI_DEVICE_ID_23000x2300))) {
7562 pciDevice->slotFound = lslot;
7563 ASC_DBG(3, "asc_pci_find_dev: PCI_DEVICE_FOUND\n");
7564 return PCI_DEVICE_FOUND0x0000;
7565 } else {
7566 pciData.offset = SUBCLASS_OFFSET0x0A;
7567 subclass = asc_get_cfg_byte(&pciData);
7568 pciData.offset = CLASSCODE_OFFSET0x0B;
7569 classcode = asc_get_cfg_byte(&pciData);
7570 if ((classcode & PCI_BASE_CLASS_BRIDGE_DEVICE0x06) &&
7571 (subclass & PCI_SUB_CLASS_PCI_TO_PCI_BRIDGE_CONTROLLER0x04)) {
7572 pciDevice->bridge++;
7573 }
7574 ASC_DBG2(3, "asc_pci_find_dev: subclass %x, classcode %x\n",
7575 subclass, classcode);
7576 }
7577 }
7578 }
7579 return PCI_DEVICE_NOT_FOUND0xffff;
7580}
7581
7582/*
7583 * Read PCI configuration data into 'pciConfig'.
7584 */
7585ASC_INITFUNC(static void asc_get_pci_cfg(PCI_DEVICE *pciDevice, PCI_CONFIG_SPACE
*pciConfig)
7586STATIC voidstatic void asc_get_pci_cfg(PCI_DEVICE *pciDevice, PCI_CONFIG_SPACE
*pciConfig)
7587asc_get_pci_cfg(PCI_DEVICE *pciDevice, PCI_CONFIG_SPACE *pciConfig)static void asc_get_pci_cfg(PCI_DEVICE *pciDevice, PCI_CONFIG_SPACE
*pciConfig)
7588)static void asc_get_pci_cfg(PCI_DEVICE *pciDevice, PCI_CONFIG_SPACE
*pciConfig)
7589{
7590 PCI_DATA pciData;
7591 uchar counter;
7592 uchar *localConfig;
7593
7594 ASC_DBG1(4, "asc_get_pci_cfg: slotFound %d\n ",
7595 pciDevice->slotFound);
7596
7597 pciData.type = pciDevice->type;
7598 pciData.bus = pciDevice->busNumber;
7599 pciData.slot = pciDevice->slotFound;
7600 pciData.func = pciDevice->devFunc;
7601 localConfig = (uchar *) pciConfig;
7602
7603 for (counter = 0; counter < sizeof(PCI_CONFIG_SPACE); counter++) {
7604 pciData.offset = counter;
7605 *localConfig = asc_get_cfg_byte(&pciData);
7606 ASC_DBG1(4, "asc_get_pci_cfg: byte %x\n", *localConfig);
7607 localConfig++;
7608 }
7609 ASC_DBG1(4, "asc_get_pci_cfg: counter %d\n", counter);
7610}
7611
7612/*
7613 * Read a word (16 bits) from the PCI configuration space.
7614 *
7615 * The configuration mechanism is checked for the correct access method.
7616 */
7617ASC_INITFUNC(static ushort asc_get_cfg_word(PCI_DATA *pciData)
7618STATIC ushortstatic ushort asc_get_cfg_word(PCI_DATA *pciData)
7619asc_get_cfg_word(PCI_DATA *pciData)static ushort asc_get_cfg_word(PCI_DATA *pciData)
7620)static ushort asc_get_cfg_word(PCI_DATA *pciData)
7621{
7622 ushort tmp;
7623 ulong address;
7624 ulong lbus = pciData->bus;
7625 ulong lslot = pciData->slot;
7626 ulong lfunc = pciData->func;
7627 uchar t2CFA, t2CF8;
7628 ulong t1CF8, t1CFC;
7629
7630 ASC_DBG4(4, "asc_get_cfg_word: type %d, bus %lu, slot %lu, func %lu\n",
7631 pciData->type, lbus, lslot, lfunc);
7632
7633 /*
7634 * Check type of configuration mechanism.
7635 */
7636 if (pciData->type == 2) {
7637 /*
7638 * Save registers to be restored later.
7639 */
7640 t2CFA = inp(0xCFA)((__builtin_constant_p((0xCFA)) && (0xCFA) < 256) ?
__inbc(0xCFA) : __inb(0xCFA))
; /* save PCI bus register */
7641 t2CF8 = inp(0xCF8)((__builtin_constant_p((0xCF8)) && (0xCF8) < 256) ?
__inbc(0xCF8) : __inb(0xCF8))
; /* save config space enable register */
7642
7643 /*
7644 * Write the bus and enable registers.
7645 */
7646 /* set for type 1 cycle, if needed */
7647 outp(0xCFA, pciData->bus)((__builtin_constant_p(((0xCFA))) && ((0xCFA)) < 256
) ? __outbc(((pciData->bus)),((0xCFA))) : __outb(((pciData
->bus)),((0xCFA))))
;
7648 /* set the function number */
7649 outp(0xCF8, 0x10 | (pciData->func << 1))((__builtin_constant_p(((0xCF8))) && ((0xCF8)) < 256
) ? __outbc(((0x10 | (pciData->func << 1))),((0xCF8)
)) : __outb(((0x10 | (pciData->func << 1))),((0xCF8)
)))
;
7650
7651 /*
7652 * Read the configuration space type 2 locations.
7653 */
7654 tmp = (ushort) inpw(0xC000 | ((pciData->slot << 8) + pciData->offset))((__builtin_constant_p((0xC000 | ((pciData->slot << 8
) + pciData->offset))) && (0xC000 | ((pciData->
slot << 8) + pciData->offset)) < 256) ? __inwc(0xC000
| ((pciData->slot << 8) + pciData->offset)) : __inw
(0xC000 | ((pciData->slot << 8) + pciData->offset
)))
;
7655
7656 outp(0xCFA, t2CFA)((__builtin_constant_p(((0xCFA))) && ((0xCFA)) < 256
) ? __outbc(((t2CFA)),((0xCFA))) : __outb(((t2CFA)),((0xCFA))
))
; /* save PCI bus register */
7657 outp(0xCF8, t2CF8)((__builtin_constant_p(((0xCF8))) && ((0xCF8)) < 256
) ? __outbc(((t2CF8)),((0xCF8))) : __outb(((t2CF8)),((0xCF8))
))
; /* save config space enable register */
7658 } else {
7659 /*
7660 * Type 1 or 3 configuration mechanism.
7661 *
7662 * Save the CONFIG_ADDRESS and CONFIG_DATA register values.
7663 */
7664 t1CF8 = inpl(0xCF8)((__builtin_constant_p((0xCF8)) && (0xCF8) < 256) ?
__inlc(0xCF8) : __inl(0xCF8))
;
7665 t1CFC = inpl(0xCFC)((__builtin_constant_p((0xCFC)) && (0xCFC) < 256) ?
__inlc(0xCFC) : __inl(0xCFC))
;
7666
7667 /*
7668 * enable <31>, bus = <23:16>, slot = <15:11>,
7669 * func = <10:8>, reg = <7:2>
7670 */
7671 address = (ulong) ((lbus << 16) | (lslot << 11) |
7672 (lfunc << 8) | (pciData->offset & 0xFC) | 0x80000000L);
7673
7674 /*
7675 * Write out the address to CONFIG_ADDRESS.
7676 */
7677 outpl(0xCF8, address)((__builtin_constant_p(((0xCF8))) && ((0xCF8)) < 256
) ? __outlc(((address)),((0xCF8))) : __outl(((address)),((0xCF8
))))
;
7678
7679 /*
7680 * Read in word from CONFIG_DATA.
7681 */
7682 tmp = (ushort) ((inpl(0xCFC)((__builtin_constant_p((0xCFC)) && (0xCFC) < 256) ?
__inlc(0xCFC) : __inl(0xCFC))
>>
7683 ((pciData->offset & 2) * 8)) & 0xFFFF);
7684
7685 /*
7686 * Restore registers.
7687 */
7688 outpl(0xCF8, t1CF8)((__builtin_constant_p(((0xCF8))) && ((0xCF8)) < 256
) ? __outlc(((t1CF8)),((0xCF8))) : __outl(((t1CF8)),((0xCF8))
))
;
7689 outpl(0xCFC, t1CFC)((__builtin_constant_p(((0xCFC))) && ((0xCFC)) < 256
) ? __outlc(((t1CFC)),((0xCFC))) : __outl(((t1CFC)),((0xCFC))
))
;
7690 }
7691 ASC_DBG1(4, "asc_get_cfg_word: config data: %x\n", tmp);
7692 return tmp;
7693}
7694
7695/*
7696 * Reads a byte from the PCI configuration space.
7697 *
7698 * The configuration mechanism is checked for the correct access method.
7699 */
7700ASC_INITFUNC(static uchar asc_get_cfg_byte(PCI_DATA *pciData)
7701STATIC ucharstatic uchar asc_get_cfg_byte(PCI_DATA *pciData)
7702asc_get_cfg_byte(PCI_DATA *pciData)static uchar asc_get_cfg_byte(PCI_DATA *pciData)
7703)static uchar asc_get_cfg_byte(PCI_DATA *pciData)
7704{
7705 uchar tmp;
7706 ulong address;
7707 ulong lbus = pciData->bus, lslot = pciData->slot, lfunc = pciData->func;
7708 uchar t2CFA, t2CF8;
7709 ulong t1CF8, t1CFC;
7710
7711 ASC_DBG1(4, "asc_get_cfg_byte: type: %d\n", pciData->type);
7712
7713 /*
7714 * Check type of configuration mechanism.
7715 */
7716 if (pciData->type == 2) {
7717 /*
7718 * Save registers to be restored later.
7719 */
7720 t2CFA = inp(0xCFA)((__builtin_constant_p((0xCFA)) && (0xCFA) < 256) ?
__inbc(0xCFA) : __inb(0xCFA))
; /* save PCI bus register */
7721 t2CF8 = inp(0xCF8)((__builtin_constant_p((0xCF8)) && (0xCF8) < 256) ?
__inbc(0xCF8) : __inb(0xCF8))
; /* save config space enable register */
7722
7723 /*
7724 * Write the bus and enable registers.
7725 */
7726 /* set for type 1 cycle, if needed */
7727 outp(0xCFA, pciData->bus)((__builtin_constant_p(((0xCFA))) && ((0xCFA)) < 256
) ? __outbc(((pciData->bus)),((0xCFA))) : __outb(((pciData
->bus)),((0xCFA))))
;
7728 /* set the function number */
7729 outp(0xCF8, 0x10 | (pciData->func << 1))((__builtin_constant_p(((0xCF8))) && ((0xCF8)) < 256
) ? __outbc(((0x10 | (pciData->func << 1))),((0xCF8)
)) : __outb(((0x10 | (pciData->func << 1))),((0xCF8)
)))
;
7730
7731 /*
7732 * Read configuration space type 2 locations.
7733 */
7734 tmp = inp(0xC000 | ((pciData->slot << 8) + pciData->offset))((__builtin_constant_p((0xC000 | ((pciData->slot << 8
) + pciData->offset))) && (0xC000 | ((pciData->
slot << 8) + pciData->offset)) < 256) ? __inbc(0xC000
| ((pciData->slot << 8) + pciData->offset)) : __inb
(0xC000 | ((pciData->slot << 8) + pciData->offset
)))
;
7735
7736 /*
7737 * Restore registers.
7738 */
7739 outp(0xCF8, t2CF8)((__builtin_constant_p(((0xCF8))) && ((0xCF8)) < 256
) ? __outbc(((t2CF8)),((0xCF8))) : __outb(((t2CF8)),((0xCF8))
))
; /* restore the enable register */
7740 outp(0xCFA, t2CFA)((__builtin_constant_p(((0xCFA))) && ((0xCFA)) < 256
) ? __outbc(((t2CFA)),((0xCFA))) : __outb(((t2CFA)),((0xCFA))
))
; /* restore PCI bus register */
7741 } else {
7742 /*
7743 * Type 1 or 3 configuration mechanism.
7744 *
7745 * Save CONFIG_ADDRESS and CONFIG_DATA register values.
7746 */
7747 t1CF8 = inpl(0xCF8)((__builtin_constant_p((0xCF8)) && (0xCF8) < 256) ?
__inlc(0xCF8) : __inl(0xCF8))
;
7748 t1CFC = inpl(0xCFC)((__builtin_constant_p((0xCFC)) && (0xCFC) < 256) ?
__inlc(0xCFC) : __inl(0xCFC))
;
7749
7750 /*
7751 * enable <31>, bus = <23:16>, slot = <15:11>, func = <10:8>,
7752 * reg = <7:2>
7753 */
7754 address = (ulong) ((lbus << 16) | (lslot << 11) |
7755 (lfunc << 8) | (pciData->offset & 0xFC) | 0x80000000L);
7756
7757 /*
7758 * Write out address to CONFIG_ADDRESS.
7759 */
7760 outpl(0xCF8, address)((__builtin_constant_p(((0xCF8))) && ((0xCF8)) < 256
) ? __outlc(((address)),((0xCF8))) : __outl(((address)),((0xCF8
))))
;
7761
7762 /*
7763 * Read in word from CONFIG_DATA.
7764 */
7765 tmp = (uchar) ((inpl(0xCFC)((__builtin_constant_p((0xCFC)) && (0xCFC) < 256) ?
__inlc(0xCFC) : __inl(0xCFC))
>> ((pciData->offset & 3) * 8)) & 0xFF);
7766
7767 /*
7768 * Restore registers.
7769 */
7770 outpl(0xCF8, t1CF8)((__builtin_constant_p(((0xCF8))) && ((0xCF8)) < 256
) ? __outlc(((t1CF8)),((0xCF8))) : __outl(((t1CF8)),((0xCF8))
))
;
7771 outpl(0xCFC, t1CFC)((__builtin_constant_p(((0xCFC))) && ((0xCFC)) < 256
) ? __outlc(((t1CFC)),((0xCFC))) : __outl(((t1CFC)),((0xCFC))
))
;
7772 }
7773 ASC_DBG1(4, "asc_get_cfg_byte: config data: %x\n", tmp);
7774 return tmp;
7775}
7776
7777/*
7778 * Write a byte to the PCI configuration space.
7779 */
7780ASC_INITFUNC(static void asc_put_cfg_byte(PCI_DATA *pciData, uchar byte_data
)
7781STATIC voidstatic void asc_put_cfg_byte(PCI_DATA *pciData, uchar byte_data
)
7782asc_put_cfg_byte(PCI_DATA *pciData, uchar byte_data)static void asc_put_cfg_byte(PCI_DATA *pciData, uchar byte_data
)
7783)static void asc_put_cfg_byte(PCI_DATA *pciData, uchar byte_data
)
7784{
7785 ulong tmpl;
7786 ulong address;
7787 ulong lbus = pciData->bus, lslot = pciData->slot, lfunc = pciData->func;
7788 uchar t2CFA, t2CF8;
7789 ulong t1CF8, t1CFC;
7790
7791 ASC_DBG2(4, "asc_put_cfg_byte: type: %d, byte_data %x\n",
7792 pciData->type, byte_data);
7793
7794 /*
7795 * Check type of configuration mechanism.
7796 */
7797 if (pciData->type == 2) {
7798
7799 /*
7800 * Save registers to be restored later.
7801 */
7802 t2CFA = inp(0xCFA)((__builtin_constant_p((0xCFA)) && (0xCFA) < 256) ?
__inbc(0xCFA) : __inb(0xCFA))
; /* save PCI bus register */
7803 t2CF8 = inp(0xCF8)((__builtin_constant_p((0xCF8)) && (0xCF8) < 256) ?
__inbc(0xCF8) : __inb(0xCF8))
; /* save config space enable register */
7804
7805 /*
7806 * Write bus and enable registers.
7807 */
7808 outp(0xCFA, pciData->bus)((__builtin_constant_p(((0xCFA))) && ((0xCFA)) < 256
) ? __outbc(((pciData->bus)),((0xCFA))) : __outb(((pciData
->bus)),((0xCFA))))
;
7809
7810 /*
7811 * Set the function number.
7812 */
7813 outp(0xCF8, 0x10 | (pciData->func << 1))((__builtin_constant_p(((0xCF8))) && ((0xCF8)) < 256
) ? __outbc(((0x10 | (pciData->func << 1))),((0xCF8)
)) : __outb(((0x10 | (pciData->func << 1))),((0xCF8)
)))
;
7814
7815 /*
7816 * Write the configuration space type 2 locations.
7817 */
7818 outp(0xC000 | ((pciData->slot << 8) + pciData->offset), byte_data)((__builtin_constant_p(((0xC000 | ((pciData->slot <<
8) + pciData->offset)))) && ((0xC000 | ((pciData->
slot << 8) + pciData->offset))) < 256) ? __outbc(
((byte_data)),((0xC000 | ((pciData->slot << 8) + pciData
->offset)))) : __outb(((byte_data)),((0xC000 | ((pciData->
slot << 8) + pciData->offset)))))
;
7819
7820 /*
7821 * Restore registers.
7822 */
7823 outp(0xCF8, t2CF8)((__builtin_constant_p(((0xCF8))) && ((0xCF8)) < 256
) ? __outbc(((t2CF8)),((0xCF8))) : __outb(((t2CF8)),((0xCF8))
))
; /* restore the enable register */
7824 outp(0xCFA, t2CFA)((__builtin_constant_p(((0xCFA))) && ((0xCFA)) < 256
) ? __outbc(((t2CFA)),((0xCFA))) : __outb(((t2CFA)),((0xCFA))
))
; /* restore PCI bus register */
7825 } else {
7826
7827 /*
7828 * Type 1 or 3 configuration mechanism.
7829 *
7830 * Save the CONFIG_ADDRESS and CONFIG_DATA register values.
7831 */
7832 t1CF8 = inpl(0xCF8)((__builtin_constant_p((0xCF8)) && (0xCF8) < 256) ?
__inlc(0xCF8) : __inl(0xCF8))
;
7833 t1CFC = inpl(0xCFC)((__builtin_constant_p((0xCFC)) && (0xCFC) < 256) ?
__inlc(0xCFC) : __inl(0xCFC))
;
7834
7835 /*
7836 * enable <31>, bus = <23:16>, slot = <15:11>, func = <10:8>,
7837 * reg = <7:2>
7838 */
7839 address = (ulong) ((lbus << 16) | (lslot << 11) | (lfunc << 8) |
7840 (pciData->offset & 0xFC) | 0x80000000L);
7841 /*
7842 * Write out address to CONFIG_ADDRESS.
7843 */
7844 outpl(0xCF8, address)((__builtin_constant_p(((0xCF8))) && ((0xCF8)) < 256
) ? __outlc(((address)),((0xCF8))) : __outl(((address)),((0xCF8
))))
;
7845
7846 /*
7847 * Write double word to CONFIG_DATA preserving the bytes
7848 * in the double not written.
7849 */
7850 tmpl = inpl(0xCFC)((__builtin_constant_p((0xCFC)) && (0xCFC) < 256) ?
__inlc(0xCFC) : __inl(0xCFC))
& ~(0xFF << ((pciData->offset & 3) * 8));
7851 outpl(0xCFC, tmpl | (byte_data << ((pciData->offset & 3) * 8)))((__builtin_constant_p(((0xCFC))) && ((0xCFC)) < 256
) ? __outlc(((tmpl | (byte_data << ((pciData->offset
& 3) * 8)))),((0xCFC))) : __outl(((tmpl | (byte_data <<
((pciData->offset & 3) * 8)))),((0xCFC))))
;
7852
7853 /*
7854 * Restore registers.
7855 */
7856 outpl(0xCF8, t1CF8)((__builtin_constant_p(((0xCF8))) && ((0xCF8)) < 256
) ? __outlc(((t1CF8)),((0xCF8))) : __outl(((t1CF8)),((0xCF8))
))
;
7857 outpl(0xCFC, t1CFC)((__builtin_constant_p(((0xCFC))) && ((0xCFC)) < 256
) ? __outlc(((t1CFC)),((0xCFC))) : __outl(((t1CFC)),((0xCFC))
))
;
7858 }
7859 ASC_DBG(4, "asc_put_cfg_byte: end\n");
7860}
7861#endif /* ASC_CONFIG_PCI */
7862#endif /* version < v2.1.93 */
7863
7864/*
7865 * Add a 'REQP' to the end of specified queue. Set 'tidmask'
7866 * to indicate a command is queued for the device.
7867 *
7868 * 'flag' may be either ASC_FRONT or ASC_BACK.
7869 *
7870 * 'REQPNEXT(reqp)' returns reqp's next pointer.
7871 */
7872STATICstatic void
7873asc_enqueue(asc_queue_t *ascq, REQP reqp, int flag)
7874{
7875 int tid;
7876
7877 ASC_DBG3(3, "asc_enqueue: ascq %x, reqp %x, flag %d\n",
7878 (unsigned) ascq, (unsigned) reqp, flag);
7879 ASC_ASSERT(interrupts_enabled() == ASC_FALSE){ if (!(interrupts_enabled() == 0)) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 7879); } }
;
7880 ASC_ASSERT(reqp != NULL){ if (!(reqp != ((void *) 0))) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 7880); } }
;
7881 ASC_ASSERT(flag == ASC_FRONT || flag == ASC_BACK){ if (!(flag == 1 || flag == 2)) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 7881); } }
;
7882 tid = REQPTID(reqp)((reqp)->target);
7883 ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID){ if (!(tid >= 0 && tid <= 15)) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 7883); } }
;
7884 if (flag == ASC_FRONT1) {
7885 REQPNEXT(reqp)((reqp)->host_scribble) = (unsigned char *) ascq->q_first[tid];
7886 ascq->q_first[tid] = reqp;
7887 /* If the queue was empty, set the last pointer. */
7888 if (ascq->q_last[tid] == NULL((void *) 0)) {
7889 ascq->q_last[tid] = reqp;
7890 }
7891 } else { /* ASC_BACK */
7892 if (ascq->q_last[tid] != NULL((void *) 0)) {
7893 REQPNEXT(ascq->q_last[tid])((ascq->q_last[tid])->host_scribble) = (unsigned char *) reqp;
7894 }
7895 ascq->q_last[tid] = reqp;
7896 REQPNEXT(reqp)((reqp)->host_scribble) = NULL((void *) 0);
7897 /* If the queue was empty, set the first pointer. */
7898 if (ascq->q_first[tid] == NULL((void *) 0)) {
7899 ascq->q_first[tid] = reqp;
7900 }
7901 }
7902 /* The queue has at least one entry, set its bit. */
7903 ascq->q_tidmask |= ADV_TID_TO_TIDMASK(tid)(0x01 << ((tid) & 15));
7904#ifdef ADVANSYS_STATS
7905 /* Maintain request queue statistics. */
7906 ascq->q_tot_cnt[tid]++;
7907 ascq->q_cur_cnt[tid]++;
7908 if (ascq->q_cur_cnt[tid] > ascq->q_max_cnt[tid]) {
7909 ascq->q_max_cnt[tid] = ascq->q_cur_cnt[tid];
7910 ASC_DBG2(2, "asc_enqueue: new q_max_cnt[%d] %d\n",
7911 tid, ascq->q_max_cnt[tid]);
7912 }
7913 REQPTIME(reqp)((reqp)->SCp.this_residual) = REQTIMESTAMP()(jiffies);
7914#endif /* ADVANSYS_STATS */
7915 ASC_DBG1(3, "asc_enqueue: reqp %x\n", (unsigned) reqp);
7916 return;
7917}
7918
7919/*
7920 * Return first queued 'REQP' on the specified queue for
7921 * the specified target device. Clear the 'tidmask' bit for
7922 * the device if no more commands are left queued for it.
7923 *
7924 * 'REQPNEXT(reqp)' returns reqp's next pointer.
7925 */
7926STATICstatic REQP
7927asc_dequeue(asc_queue_t *ascq, int tid)
7928{
7929 REQP reqp;
7930
7931 ASC_DBG2(3, "asc_dequeue: ascq %x, tid %d\n", (unsigned) ascq, tid);
7932 ASC_ASSERT(interrupts_enabled() == ASC_FALSE){ if (!(interrupts_enabled() == 0)) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 7932); } }
;
7933 ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID){ if (!(tid >= 0 && tid <= 15)) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 7933); } }
;
7934 if ((reqp = ascq->q_first[tid]) != NULL((void *) 0)) {
7935 ASC_ASSERT(ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid)){ if (!(ascq->q_tidmask & (0x01 << ((tid) & 15
)))) { printk("ASC_ASSERT() Failure: file %s, line %d\n", "../linux/src/drivers/scsi/advansys.c"
, 7935); } }
;
7936 ascq->q_first[tid] = (REQP) REQPNEXT(reqp)((reqp)->host_scribble);
7937 /* If the queue is empty, clear its bit and the last pointer. */
7938 if (ascq->q_first[tid] == NULL((void *) 0)) {
7939 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid)(0x01 << ((tid) & 15));
7940 ASC_ASSERT(ascq->q_last[tid] == reqp){ if (!(ascq->q_last[tid] == reqp)) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 7940); } }
;
7941 ascq->q_last[tid] = NULL((void *) 0);
7942 }
7943#ifdef ADVANSYS_STATS
7944 /* Maintain request queue statistics. */
7945 ascq->q_cur_cnt[tid]--;
7946 ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0){ if (!(ascq->q_cur_cnt[tid] >= 0)) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 7946); } }
;
7947 REQTIMESTAT("asc_dequeue", ascq, reqp, tid){ if (((reqp)->SCp.this_residual) <= (jiffies)) { ((reqp
)->SCp.this_residual) = (jiffies) - ((reqp)->SCp.this_residual
); } else { { if (!(((reqp)->SCp.this_residual) <= (jiffies
))) { printk("ASC_ASSERT() Failure: file %s, line %d\n", "../linux/src/drivers/scsi/advansys.c"
, 7947); } }; ((reqp)->SCp.this_residual) = 0; } if (((ascq
)->q_tot_cnt[tid] == 1) || (((reqp)->SCp.this_residual)
< (ascq)->q_min_tim[tid])) { (ascq)->q_min_tim[tid]
= ((reqp)->SCp.this_residual); ; } if (((reqp)->SCp.this_residual
) > (ascq)->q_max_tim[tid]) { (ascq)->q_max_tim[tid]
= ((reqp)->SCp.this_residual); ; } (ascq)->q_tot_tim[tid
] += ((reqp)->SCp.this_residual); ((reqp)->SCp.this_residual
) = 0; }
;
7948#endif /* ADVANSYS_STATS */
7949 }
7950 ASC_DBG1(3, "asc_dequeue: reqp %x\n", (unsigned) reqp);
7951 return reqp;
7952}
7953
7954/*
7955 * Return a pointer to a singly linked list of all the requests queued
7956 * for 'tid' on the 'asc_queue_t' pointed to by 'ascq'.
7957 *
7958 * If 'lastpp' is not NULL, '*lastpp' will be set to point to the
7959 * the last request returned in the singly linked list.
7960 *
7961 * 'tid' should either be a valid target id or if it is ASC_TID_ALL,
7962 * then all queued requests are concatenated into one list and
7963 * returned.
7964 *
7965 * Note: If 'lastpp' is used to append a new list to the end of
7966 * an old list, only change the old list last pointer if '*lastpp'
7967 * (or the function return value) is not NULL, i.e. use a temporary
7968 * variable for 'lastpp' and check its value after the function return
7969 * before assigning it to the list last pointer.
7970 *
7971 * Unfortunately collecting queuing time statistics adds overhead to
7972 * the function that isn't inherent to the function's algorithm.
7973 */
7974STATICstatic REQP
7975asc_dequeue_list(asc_queue_t *ascq, REQP *lastpp, int tid)
7976{
7977 REQP firstp, lastp;
7978 int i;
7979
7980 ASC_DBG2(3, "asc_dequeue_list: ascq %x, tid %d\n", (unsigned) ascq, tid);
7981 ASC_ASSERT(interrupts_enabled() == ASC_FALSE){ if (!(interrupts_enabled() == 0)) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 7981); } }
;
7982 ASC_ASSERT((tid == ASC_TID_ALL) || (tid >= 0 && tid <= ADV_MAX_TID)){ if (!((tid == (-1)) || (tid >= 0 && tid <= 15
))) { printk("ASC_ASSERT() Failure: file %s, line %d\n", "../linux/src/drivers/scsi/advansys.c"
, 7982); } }
;
7983
7984 /*
7985 * If 'tid' is not ASC_TID_ALL, return requests only for
7986 * the specified 'tid'. If 'tid' is ASC_TID_ALL, return all
7987 * requests for all tids.
7988 */
7989 if (tid != ASC_TID_ALL(-1)) {
7990 /* Return all requests for the specified 'tid'. */
7991 if ((ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid)(0x01 << ((tid) & 15))) == 0) {
7992 /* List is empty; Set first and last return pointers to NULL. */
7993 firstp = lastp = NULL((void *) 0);
7994 } else {
7995 firstp = ascq->q_first[tid];
7996 lastp = ascq->q_last[tid];
7997 ascq->q_first[tid] = ascq->q_last[tid] = NULL((void *) 0);
7998 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid)(0x01 << ((tid) & 15));
7999#ifdef ADVANSYS_STATS
8000 {
8001 REQP reqp;
8002 ascq->q_cur_cnt[tid] = 0;
8003 for (reqp = firstp; reqp; reqp = (REQP) REQPNEXT(reqp)((reqp)->host_scribble)) {
8004 REQTIMESTAT("asc_dequeue_list", ascq, reqp, tid){ if (((reqp)->SCp.this_residual) <= (jiffies)) { ((reqp
)->SCp.this_residual) = (jiffies) - ((reqp)->SCp.this_residual
); } else { { if (!(((reqp)->SCp.this_residual) <= (jiffies
))) { printk("ASC_ASSERT() Failure: file %s, line %d\n", "../linux/src/drivers/scsi/advansys.c"
, 8004); } }; ((reqp)->SCp.this_residual) = 0; } if (((ascq
)->q_tot_cnt[tid] == 1) || (((reqp)->SCp.this_residual)
< (ascq)->q_min_tim[tid])) { (ascq)->q_min_tim[tid]
= ((reqp)->SCp.this_residual); ; } if (((reqp)->SCp.this_residual
) > (ascq)->q_max_tim[tid]) { (ascq)->q_max_tim[tid]
= ((reqp)->SCp.this_residual); ; } (ascq)->q_tot_tim[tid
] += ((reqp)->SCp.this_residual); ((reqp)->SCp.this_residual
) = 0; }
;
8005 }
8006 }
8007#endif /* ADVANSYS_STATS */
8008 }
8009 } else {
8010 /* Return all requests for all tids. */
8011 firstp = lastp = NULL((void *) 0);
8012 for (i = 0; i <= ADV_MAX_TID15; i++) {
8013 if (ascq->q_tidmask & ADV_TID_TO_TIDMASK(i)(0x01 << ((i) & 15))) {
8014 if (firstp == NULL((void *) 0)) {
8015 firstp = ascq->q_first[i];
8016 lastp = ascq->q_last[i];
8017 } else {
8018 ASC_ASSERT(lastp != NULL){ if (!(lastp != ((void *) 0))) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 8018); } }
;
8019 REQPNEXT(lastp)((lastp)->host_scribble) = (unsigned char *) ascq->q_first[i];
8020 lastp = ascq->q_last[i];
8021 }
8022 ascq->q_first[i] = ascq->q_last[i] = NULL((void *) 0);
8023 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(i)(0x01 << ((i) & 15));
8024#ifdef ADVANSYS_STATS
8025 ascq->q_cur_cnt[i] = 0;
8026#endif /* ADVANSYS_STATS */
8027 }
8028 }
8029#ifdef ADVANSYS_STATS
8030 {
8031 REQP reqp;
8032 for (reqp = firstp; reqp; reqp = (REQP) REQPNEXT(reqp)((reqp)->host_scribble)) {
8033 REQTIMESTAT("asc_dequeue_list", ascq, reqp, reqp->target){ if (((reqp)->SCp.this_residual) <= (jiffies)) { ((reqp
)->SCp.this_residual) = (jiffies) - ((reqp)->SCp.this_residual
); } else { { if (!(((reqp)->SCp.this_residual) <= (jiffies
))) { printk("ASC_ASSERT() Failure: file %s, line %d\n", "../linux/src/drivers/scsi/advansys.c"
, 8033); } }; ((reqp)->SCp.this_residual) = 0; } if (((ascq
)->q_tot_cnt[reqp->target] == 1) || (((reqp)->SCp.this_residual
) < (ascq)->q_min_tim[reqp->target])) { (ascq)->q_min_tim
[reqp->target] = ((reqp)->SCp.this_residual); ; } if ((
(reqp)->SCp.this_residual) > (ascq)->q_max_tim[reqp->
target]) { (ascq)->q_max_tim[reqp->target] = ((reqp)->
SCp.this_residual); ; } (ascq)->q_tot_tim[reqp->target]
+= ((reqp)->SCp.this_residual); ((reqp)->SCp.this_residual
) = 0; }
;
8034 }
8035 }
8036#endif /* ADVANSYS_STATS */
8037 }
8038 if (lastpp) {
8039 *lastpp = lastp;
8040 }
8041 ASC_DBG1(3, "asc_dequeue_list: firstp %x\n", (unsigned) firstp);
8042 return firstp;
8043}
8044
8045/*
8046 * Remove the specified 'REQP' from the specified queue for
8047 * the specified target device. Clear the 'tidmask' bit for the
8048 * device if no more commands are left queued for it.
8049 *
8050 * 'REQPNEXT(reqp)' returns reqp's the next pointer.
8051 *
8052 * Return ASC_TRUE if the command was found and removed,
8053 * otherwise return ASC_FALSE.
8054 */
8055STATICstatic int
8056asc_rmqueue(asc_queue_t *ascq, REQP reqp)
8057{
8058 REQP currp, prevp;
8059 int tid;
8060 int ret = ASC_FALSE0;
8061
8062 ASC_DBG2(3, "asc_rmqueue: ascq %x, reqp %x\n",
8063 (unsigned) ascq, (unsigned) reqp);
8064 ASC_ASSERT(interrupts_enabled() == ASC_FALSE){ if (!(interrupts_enabled() == 0)) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 8064); } }
;
8065 ASC_ASSERT(reqp != NULL){ if (!(reqp != ((void *) 0))) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 8065); } }
;
8066
8067 tid = REQPTID(reqp)((reqp)->target);
8068 ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID){ if (!(tid >= 0 && tid <= 15)) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 8068); } }
;
8069
8070 /*
8071 * Handle the common case of 'reqp' being the first
8072 * entry on the queue.
8073 */
8074 if (reqp == ascq->q_first[tid]) {
8075 ret = ASC_TRUE1;
8076 ascq->q_first[tid] = (REQP) REQPNEXT(reqp)((reqp)->host_scribble);
8077 /* If the queue is now empty, clear its bit and the last pointer. */
8078 if (ascq->q_first[tid] == NULL((void *) 0)) {
8079 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid)(0x01 << ((tid) & 15));
8080 ASC_ASSERT(ascq->q_last[tid] == reqp){ if (!(ascq->q_last[tid] == reqp)) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 8080); } }
;
8081 ascq->q_last[tid] = NULL((void *) 0);
8082 }
8083 } else if (ascq->q_first[tid] != NULL((void *) 0)) {
8084 ASC_ASSERT(ascq->q_last[tid] != NULL){ if (!(ascq->q_last[tid] != ((void *) 0))) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 8084); } }
;
8085 /*
8086 * Because the case of 'reqp' being the first entry has been
8087 * handled above and it is known the queue is not empty, if
8088 * 'reqp' is found on the queue it is guaranteed the queue will
8089 * not become empty and that 'q_first[tid]' will not be changed.
8090 *
8091 * Set 'prevp' to the first entry, 'currp' to the second entry,
8092 * and search for 'reqp'.
8093 */
8094 for (prevp = ascq->q_first[tid], currp = (REQP) REQPNEXT(prevp)((prevp)->host_scribble);
8095 currp; prevp = currp, currp = (REQP) REQPNEXT(currp)((currp)->host_scribble)) {
8096 if (currp == reqp) {
8097 ret = ASC_TRUE1;
8098 REQPNEXT(prevp)((prevp)->host_scribble) = REQPNEXT(currp)((currp)->host_scribble);
8099 REQPNEXT(reqp)((reqp)->host_scribble) = NULL((void *) 0);
8100 if (ascq->q_last[tid] == reqp) {
8101 ascq->q_last[tid] = prevp;
8102 }
8103 break;
8104 }
8105 }
8106 }
8107#ifdef ADVANSYS_STATS
8108 /* Maintain request queue statistics. */
8109 if (ret == ASC_TRUE1) {
8110 ascq->q_cur_cnt[tid]--;
8111 REQTIMESTAT("asc_rmqueue", ascq, reqp, tid){ if (((reqp)->SCp.this_residual) <= (jiffies)) { ((reqp
)->SCp.this_residual) = (jiffies) - ((reqp)->SCp.this_residual
); } else { { if (!(((reqp)->SCp.this_residual) <= (jiffies
))) { printk("ASC_ASSERT() Failure: file %s, line %d\n", "../linux/src/drivers/scsi/advansys.c"
, 8111); } }; ((reqp)->SCp.this_residual) = 0; } if (((ascq
)->q_tot_cnt[tid] == 1) || (((reqp)->SCp.this_residual)
< (ascq)->q_min_tim[tid])) { (ascq)->q_min_tim[tid]
= ((reqp)->SCp.this_residual); ; } if (((reqp)->SCp.this_residual
) > (ascq)->q_max_tim[tid]) { (ascq)->q_max_tim[tid]
= ((reqp)->SCp.this_residual); ; } (ascq)->q_tot_tim[tid
] += ((reqp)->SCp.this_residual); ((reqp)->SCp.this_residual
) = 0; }
;
8112 }
8113 ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0){ if (!(ascq->q_cur_cnt[tid] >= 0)) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 8113); } }
;
8114#endif /* ADVANSYS_STATS */
8115 ASC_DBG2(3, "asc_rmqueue: reqp %x, ret %d\n", (unsigned) reqp, ret);
8116 return ret;
8117}
8118
8119/*
8120 * If the specified 'REQP' is queued on the specified queue for
8121 * the specified target device, return ASC_TRUE.
8122 */
8123STATICstatic int
8124asc_isqueued(asc_queue_t *ascq, REQP reqp)
8125{
8126 REQP treqp;
8127 int tid;
8128 int ret = ASC_FALSE0;
8129
8130 ASC_DBG2(3, "asc_isqueued: ascq %x, reqp %x\n",
8131 (unsigned) ascq, (unsigned) reqp);
8132 ASC_ASSERT(interrupts_enabled() == ASC_FALSE){ if (!(interrupts_enabled() == 0)) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 8132); } }
;
8133 ASC_ASSERT(reqp != NULL){ if (!(reqp != ((void *) 0))) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 8133); } }
;
8134
8135 tid = REQPTID(reqp)((reqp)->target);
8136 ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID){ if (!(tid >= 0 && tid <= 15)) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 8136); } }
;
8137
8138 for (treqp = ascq->q_first[tid]; treqp; treqp = (REQP) REQPNEXT(treqp)((treqp)->host_scribble)) {
8139 ASC_ASSERT(ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid)){ if (!(ascq->q_tidmask & (0x01 << ((tid) & 15
)))) { printk("ASC_ASSERT() Failure: file %s, line %d\n", "../linux/src/drivers/scsi/advansys.c"
, 8139); } }
;
8140 if (treqp == reqp) {
8141 ret = ASC_TRUE1;
8142 break;
8143 }
8144 }
8145 ASC_DBG1(3, "asc_isqueued: ret %x\n", ret);
8146 return ret;
8147}
8148
8149/*
8150 * Execute as many queued requests as possible for the specified queue.
8151 *
8152 * Calls asc_execute_scsi_cmnd() to execute a REQP/Scsi_Cmnd.
8153 */
8154STATICstatic void
8155asc_execute_queue(asc_queue_t *ascq)
8156{
8157 ADV_SCSI_BIT_ID_TYPEushort scan_tidmask;
8158 REQP reqp;
8159 int i;
8160
8161 ASC_DBG1(1, "asc_execute_queue: ascq %x\n", (unsigned) ascq);
8162 ASC_ASSERT(interrupts_enabled() == ASC_FALSE){ if (!(interrupts_enabled() == 0)) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 8162); } }
;
8163 /*
8164 * Execute queued commands for devices attached to
8165 * the current board in round-robin fashion.
8166 */
8167 scan_tidmask = ascq->q_tidmask;
8168 do {
8169 for (i = 0; i <= ADV_MAX_TID15; i++) {
8170 if (scan_tidmask & ADV_TID_TO_TIDMASK(i)(0x01 << ((i) & 15))) {
8171 if ((reqp = asc_dequeue(ascq, i)) == NULL((void *) 0)) {
8172 scan_tidmask &= ~ADV_TID_TO_TIDMASK(i)(0x01 << ((i) & 15));
8173 } else if (asc_execute_scsi_cmnd((Scsi_Cmnd *) reqp)
8174 == ASC_BUSY0) {
8175 scan_tidmask &= ~ADV_TID_TO_TIDMASK(i)(0x01 << ((i) & 15));
8176 /* Put the request back at front of the list. */
8177 asc_enqueue(ascq, reqp, ASC_FRONT1);
8178 }
8179 }
8180 }
8181 } while (scan_tidmask);
8182 return;
8183}
8184
8185#if LINUX_VERSION_CODE131108 >= ASC_LINUX_VERSION(1,3,0)(((1) * 65536) + ((3) * 256) + (0))
8186/*
8187 * asc_prt_board_devices()
8188 *
8189 * Print driver information for devices attached to the board.
8190 *
8191 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
8192 * cf. asc_prt_line().
8193 *
8194 * Return the number of characters copied into 'cp'. No more than
8195 * 'cplen' characters will be copied to 'cp'.
8196 */
8197STATICstatic int
8198asc_prt_board_devices(struct Scsi_Host *shp, char *cp, int cplen)
8199{
8200 asc_board_t *boardp;
8201 int leftlen;
8202 int totlen;
8203 int len;
8204 int chip_scsi_id;
8205 int i;
8206
8207 boardp = ASC_BOARDP(shp)((asc_board_t *) &((shp)->hostdata));
8208 leftlen = cplen;
8209 totlen = len = 0;
8210
8211 len = asc_prt_line(cp, leftlen,
8212"\nDevice Information for AdvanSys SCSI Host %d:\n", shp->host_no);
8213 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8214
8215 if (ASC_NARROW_BOARD(boardp)(((boardp)->flags & 0x04) == 0)) {
8216 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
8217 } else {
8218 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
8219 }
8220
8221 len = asc_prt_line(cp, leftlen, "Target IDs Detected:");
8222 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8223 for (i = 0; i <= ADV_MAX_TID15; i++) {
8224 if (boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)(0x01 << ((i) & 15))) {
8225 len = asc_prt_line(cp, leftlen, " %X,", i);
8226 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8227 }
8228 }
8229 len = asc_prt_line(cp, leftlen, " (%X=Host Adapter)\n", chip_scsi_id);
8230 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8231
8232 return totlen;
8233}
8234
8235/*
8236 * Display Wide Board BIOS Information.
8237 */
8238STATICstatic int
8239asc_prt_adv_bios(struct Scsi_Host *shp, char *cp, int cplen)
8240{
8241 asc_board_t *boardp;
8242 int leftlen;
8243 int totlen;
8244 int len;
8245 int upgrade = ASC_FALSE0;
8246 ushort major, minor, letter;
8247
8248 boardp = ASC_BOARDP(shp)((asc_board_t *) &((shp)->hostdata));
8249 leftlen = cplen;
8250 totlen = len = 0;
8251
8252 len = asc_prt_line(cp, leftlen, "\nROM BIOS Version: ");
8253 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8254
8255 /*
8256 * If the BIOS saved a valid signature, then fill in
8257 * the BIOS code segment base address.
8258 */
8259 if (boardp->bios_signature != 0x55AA) {
8260 len = asc_prt_line(cp, leftlen, "Pre-3.1\n");
8261 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8262 upgrade = ASC_TRUE1;
8263 } else {
8264 major = (boardp->bios_version >> 12) & 0xF;
8265 minor = (boardp->bios_version >> 8) & 0xF;
8266 letter = (boardp->bios_version & 0xFF);
8267
8268 len = asc_prt_line(cp, leftlen, "%d.%d%c\n",
8269 major, minor, letter >= 26 ? '?' : letter + 'A');
8270 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8271
8272 /* Current available ROM BIOS release is 3.1C. */
8273 if (major < 3 || (major <= 3 && minor < 1) ||
8274 (major <= 3 && minor <= 1 && letter < ('C'- 'A'))) {
8275 upgrade = ASC_TRUE1;
8276 }
8277 }
8278 if (upgrade == ASC_TRUE1) {
8279 len = asc_prt_line(cp, leftlen,
8280"Newer version of ROM BIOS available: ftp://ftp.advansys.com/pub\n");
8281 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8282 }
8283
8284 return totlen;
8285}
8286
8287/*
8288 * Add serial number to information bar if signature AAh
8289 * is found in at bit 15-9 (7 bits) of word 1.
8290 *
8291 * Serial Number consists fo 12 alpha-numeric digits.
8292 *
8293 * 1 - Product type (A,B,C,D..) Word0: 15-13 (3 bits)
8294 * 2 - MFG Location (A,B,C,D..) Word0: 12-10 (3 bits)
8295 * 3-4 - Product ID (0-99) Word0: 9-0 (10 bits)
8296 * 5 - Product revision (A-J) Word0: " "
8297 *
8298 * Signature Word1: 15-9 (7 bits)
8299 * 6 - Year (0-9) Word1: 8-6 (3 bits) & Word2: 15 (1 bit)
8300 * 7-8 - Week of the year (1-52) Word1: 5-0 (6 bits)
8301 *
8302 * 9-12 - Serial Number (A001-Z999) Word2: 14-0 (15 bits)
8303 *
8304 * Note 1: Only production cards will have a serial number.
8305 *
8306 * Note 2: Signature is most significant 7 bits (0xFE).
8307 *
8308 * Returns ASC_TRUE if serial number found, otherwise returns ASC_FALSE.
8309 */
8310STATICstatic int
8311asc_get_eeprom_string(ushort *serialnum, uchar *cp)
8312{
8313 ushort w, num;
8314
8315 if ((serialnum[1] & 0xFE00) != ((ushort) 0xAA << 8)) {
8316 return ASC_FALSE0;
8317 } else {
8318 /*
8319 * First word - 6 digits.
8320 */
8321 w = serialnum[0];
8322
8323 /* Product type - 1st digit. */
8324 if ((*cp = 'A' + ((w & 0xE000) >> 13)) == 'H') {
8325 /* Product type is P=Prototype */
8326 *cp += 0x8;
8327 }
8328 cp++;
8329
8330 /* Manufacturing location - 2nd digit. */
8331 *cp++ = 'A' + ((w & 0x1C00) >> 10);
8332
8333 /* Product ID - 3rd, 4th digits. */
8334 num = w & 0x3FF;
8335 *cp++ = '0' + (num / 100);
8336 num %= 100;
8337 *cp++ = '0' + (num / 10);
8338
8339 /* Product revision - 5th digit. */
8340 *cp++ = 'A' + (num % 10);
8341
8342 /*
8343 * Second word
8344 */
8345 w = serialnum[1];
8346
8347 /*
8348 * Year - 6th digit.
8349 *
8350 * If bit 15 of third word is set, then the
8351 * last digit of the year is greater than 7.
8352 */
8353 if (serialnum[2] & 0x8000) {
8354 *cp++ = '8' + ((w & 0x1C0) >> 6);
8355 } else {
8356 *cp++ = '0' + ((w & 0x1C0) >> 6);
8357 }
8358
8359 /* Week of year - 7th, 8th digits. */
8360 num = w & 0x003F;
8361 *cp++ = '0' + num / 10;
8362 num %= 10;
8363 *cp++ = '0' + num;
8364
8365 /*
8366 * Third word
8367 */
8368 w = serialnum[2] & 0x7FFF;
8369
8370 /* Serial number - 9th digit. */
8371 *cp++ = 'A' + (w / 1000);
8372
8373 /* 10th, 11th, 12th digits. */
8374 num = w % 1000;
8375 *cp++ = '0' + num / 100;
8376 num %= 100;
8377 *cp++ = '0' + num / 10;
8378 num %= 10;
8379 *cp++ = '0' + num;
8380
8381 *cp = '\0'; /* Null Terminate the string. */
8382 return ASC_TRUE1;
8383 }
8384}
8385
8386/*
8387 * asc_prt_asc_board_eeprom()
8388 *
8389 * Print board EEPROM configuration.
8390 *
8391 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
8392 * cf. asc_prt_line().
8393 *
8394 * Return the number of characters copied into 'cp'. No more than
8395 * 'cplen' characters will be copied to 'cp'.
8396 */
8397STATICstatic int
8398asc_prt_asc_board_eeprom(struct Scsi_Host *shp, char *cp, int cplen)
8399{
8400 asc_board_t *boardp;
8401 ASC_DVC_VAR *asc_dvc_varp;
8402 int leftlen;
8403 int totlen;
8404 int len;
8405 ASCEEP_CONFIG *ep;
8406 int i;
8407 int isa_dma_speed[] = { 10, 8, 7, 6, 5, 4, 3, 2 };
8408 uchar serialstr[13];
8409
8410 boardp = ASC_BOARDP(shp)((asc_board_t *) &((shp)->hostdata));
8411 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
8412 ep = &boardp->eep_config.asc_eep;
8413
8414 leftlen = cplen;
8415 totlen = len = 0;
8416
8417 len = asc_prt_line(cp, leftlen,
8418"\nEEPROM Settings for AdvanSys SCSI Host %d:\n", shp->host_no);
8419 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8420
8421 if (asc_get_eeprom_string((ushort *) &ep->adapter_info[0], serialstr) ==
8422 ASC_TRUE1) {
8423 len = asc_prt_line(cp, leftlen, " Serial Number: %s\n", serialstr);
8424 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8425 } else {
8426 if (ep->adapter_info[5] == 0xBB) {
8427 len = asc_prt_line(cp, leftlen,
8428 " Default Settings Used for EEPROM-less Adapter.\n");
8429 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8430 } else {
8431 len = asc_prt_line(cp, leftlen,
8432 " Serial Number Signature Not Present.\n");
8433 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8434 }
8435 }
8436
8437 len = asc_prt_line(cp, leftlen,
8438" Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
8439 ep->chip_scsi_id, ep->max_total_qng, ep->max_tag_qng);
8440 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8441
8442 len = asc_prt_line(cp, leftlen,
8443" cntl %x, no_scam %x\n",
8444 ep->cntl, ep->no_scam);
8445 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8446
8447 len = asc_prt_line(cp, leftlen,
8448" Target ID: ");
8449 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8450 for (i = 0; i <= ASC_MAX_TID7; i++) {
8451 len = asc_prt_line(cp, leftlen, " %d", i);
8452 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8453 }
8454 len = asc_prt_line(cp, leftlen, "\n");
8455 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8456
8457 len = asc_prt_line(cp, leftlen,
8458" Disconnects: ");
8459 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8460 for (i = 0; i <= ASC_MAX_TID7; i++) {
8461 len = asc_prt_line(cp, leftlen, " %c",
8462 (ep->disc_enable & ADV_TID_TO_TIDMASK(i)(0x01 << ((i) & 15))) ? 'Y' : 'N');
8463 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8464 }
8465 len = asc_prt_line(cp, leftlen, "\n");
8466 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8467
8468 len = asc_prt_line(cp, leftlen,
8469" Command Queuing: ");
8470 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8471 for (i = 0; i <= ASC_MAX_TID7; i++) {
8472 len = asc_prt_line(cp, leftlen, " %c",
8473 (ep->use_cmd_qng & ADV_TID_TO_TIDMASK(i)(0x01 << ((i) & 15))) ? 'Y' : 'N');
8474 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8475 }
8476 len = asc_prt_line(cp, leftlen, "\n");
8477 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8478
8479 len = asc_prt_line(cp, leftlen,
8480" Start Motor: ");
8481 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8482 for (i = 0; i <= ASC_MAX_TID7; i++) {
8483 len = asc_prt_line(cp, leftlen, " %c",
8484 (ep->start_motor & ADV_TID_TO_TIDMASK(i)(0x01 << ((i) & 15))) ? 'Y' : 'N');
8485 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8486 }
8487 len = asc_prt_line(cp, leftlen, "\n");
8488 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8489
8490 len = asc_prt_line(cp, leftlen,
8491" Synchronous Transfer:");
8492 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8493 for (i = 0; i <= ASC_MAX_TID7; i++) {
8494 len = asc_prt_line(cp, leftlen, " %c",
8495 (ep->init_sdtr & ADV_TID_TO_TIDMASK(i)(0x01 << ((i) & 15))) ? 'Y' : 'N');
8496 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8497 }
8498 len = asc_prt_line(cp, leftlen, "\n");
8499 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8500
8501 if (asc_dvc_varp->bus_type & ASC_IS_ISA(0x0001)) {
8502 len = asc_prt_line(cp, leftlen,
8503" Host ISA DMA speed: %d MB/S\n",
8504 isa_dma_speed[ep->isa_dma_speed]);
8505 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8506 }
8507
8508 return totlen;
8509}
8510
8511/*
8512 * asc_prt_adv_board_eeprom()
8513 *
8514 * Print board EEPROM configuration.
8515 *
8516 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
8517 * cf. asc_prt_line().
8518 *
8519 * Return the number of characters copied into 'cp'. No more than
8520 * 'cplen' characters will be copied to 'cp'.
8521 */
8522STATICstatic int
8523asc_prt_adv_board_eeprom(struct Scsi_Host *shp, char *cp, int cplen)
8524{
8525 asc_board_t *boardp;
8526 ADV_DVC_VAR *adv_dvc_varp;
8527 int leftlen;
8528 int totlen;
8529 int len;
8530 int i;
8531 char *termstr;
8532 uchar serialstr[13];
8533 ADVEEP_CONFIG *ep;
8534
8535 boardp = ASC_BOARDP(shp)((asc_board_t *) &((shp)->hostdata));
8536 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
8537 ep = &boardp->eep_config.adv_eep;
8538
8539 leftlen = cplen;
8540 totlen = len = 0;
8541
8542 len = asc_prt_line(cp, leftlen,
8543"\nEEPROM Settings for AdvanSys SCSI Host %d:\n", shp->host_no);
8544 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8545
8546 if (asc_get_eeprom_string(&ep->serial_number_word1, serialstr) ==
8547 ASC_TRUE1) {
8548 len = asc_prt_line(cp, leftlen, " Serial Number: %s\n", serialstr);
8549 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8550 } else {
8551 len = asc_prt_line(cp, leftlen,
8552 " Serial Number Signature Not Present.\n");
8553 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8554 }
8555
8556 len = asc_prt_line(cp, leftlen,
8557" Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
8558 ep->adapter_scsi_id, ep->max_host_qng, ep->max_dvc_qng);
8559 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8560
8561 switch (ep->termination) {
8562 case 1:
8563 termstr = "Low Off/High Off";
8564 break;
8565 case 2:
8566 termstr = "Low Off/High On";
8567 break;
8568 case 3:
8569 termstr = "Low On/High On";
8570 break;
8571 default:
8572 case 0:
8573 termstr = "Automatic";
8574 break;
8575 }
8576
8577 len = asc_prt_line(cp, leftlen,
8578" termination: %u (%s), bios_ctrl: %x\n",
8579 ep->termination, termstr, ep->bios_ctrl);
8580 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8581
8582 len = asc_prt_line(cp, leftlen,
8583" Target ID: ");
8584 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8585 for (i = 0; i <= ADV_MAX_TID15; i++) {
8586 len = asc_prt_line(cp, leftlen, " %X", i);
8587 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8588 }
8589 len = asc_prt_line(cp, leftlen, "\n");
8590 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8591
8592 len = asc_prt_line(cp, leftlen,
8593" Disconnects: ");
8594 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8595 for (i = 0; i <= ADV_MAX_TID15; i++) {
8596 len = asc_prt_line(cp, leftlen, " %c",
8597 (ep->disc_enable & ADV_TID_TO_TIDMASK(i)(0x01 << ((i) & 15))) ? 'Y' : 'N');
8598 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8599 }
8600 len = asc_prt_line(cp, leftlen, "\n");
8601 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8602
8603 len = asc_prt_line(cp, leftlen,
8604" Command Queuing: ");
8605 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8606 for (i = 0; i <= ADV_MAX_TID15; i++) {
8607 len = asc_prt_line(cp, leftlen, " %c",
8608 (ep->tagqng_able & ADV_TID_TO_TIDMASK(i)(0x01 << ((i) & 15))) ? 'Y' : 'N');
8609 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8610 }
8611 len = asc_prt_line(cp, leftlen, "\n");
8612 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8613
8614 len = asc_prt_line(cp, leftlen,
8615" Start Motor: ");
8616 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8617 for (i = 0; i <= ADV_MAX_TID15; i++) {
8618 len = asc_prt_line(cp, leftlen, " %c",
8619 (ep->start_motor & ADV_TID_TO_TIDMASK(i)(0x01 << ((i) & 15))) ? 'Y' : 'N');
8620 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8621 }
8622 len = asc_prt_line(cp, leftlen, "\n");
8623 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8624
8625 len = asc_prt_line(cp, leftlen,
8626" Synchronous Transfer:");
8627 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8628 for (i = 0; i <= ADV_MAX_TID15; i++) {
8629 len = asc_prt_line(cp, leftlen, " %c",
8630 (ep->sdtr_able & ADV_TID_TO_TIDMASK(i)(0x01 << ((i) & 15))) ? 'Y' : 'N');
8631 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8632 }
8633 len = asc_prt_line(cp, leftlen, "\n");
8634 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8635
8636 len = asc_prt_line(cp, leftlen,
8637" Ultra Transfer: ");
8638 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8639 for (i = 0; i <= ADV_MAX_TID15; i++) {
8640 len = asc_prt_line(cp, leftlen, " %c",
8641 (ep->ultra_able & ADV_TID_TO_TIDMASK(i)(0x01 << ((i) & 15))) ? 'Y' : 'N');
8642 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8643 }
8644 len = asc_prt_line(cp, leftlen, "\n");
8645 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8646
8647 len = asc_prt_line(cp, leftlen,
8648" Wide Transfer: ");
8649 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8650 for (i = 0; i <= ADV_MAX_TID15; i++) {
8651 len = asc_prt_line(cp, leftlen, " %c",
8652 (ep->wdtr_able & ADV_TID_TO_TIDMASK(i)(0x01 << ((i) & 15))) ? 'Y' : 'N');
8653 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8654 }
8655 len = asc_prt_line(cp, leftlen, "\n");
8656 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8657
8658 return totlen;
8659}
8660
8661/*
8662 * asc_prt_driver_conf()
8663 *
8664 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
8665 * cf. asc_prt_line().
8666 *
8667 * Return the number of characters copied into 'cp'. No more than
8668 * 'cplen' characters will be copied to 'cp'.
8669 */
8670STATICstatic int
8671asc_prt_driver_conf(struct Scsi_Host *shp, char *cp, int cplen)
8672{
8673 asc_board_t *boardp;
8674 int leftlen;
8675 int totlen;
8676 int len;
8677 int chip_scsi_id;
8678#if LINUX_VERSION_CODE131108 >= ASC_LINUX_VERSION(1,3,89)(((1) * 65536) + ((3) * 256) + (89))
8679 int i;
8680#endif /* version >= v1.3.89 */
8681
8682 boardp = ASC_BOARDP(shp)((asc_board_t *) &((shp)->hostdata));
8683
8684 leftlen = cplen;
8685 totlen = len = 0;
8686
8687 len = asc_prt_line(cp, leftlen,
8688"\nLinux Driver Configuration and Information for AdvanSys SCSI Host %d:\n",
8689 shp->host_no);
8690 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8691
8692 len = asc_prt_line(cp, leftlen,
8693#if LINUX_VERSION_CODE131108 < ASC_LINUX_VERSION(1,3,89)(((1) * 65536) + ((3) * 256) + (89))
8694" host_busy %u, last_reset %u, max_id %u, max_lun %u\n",
8695 shp->host_busy, shp->last_reset, shp->max_id, shp->max_lun);
8696#else /* version >= v1.3.89 */
8697" host_busy %u, last_reset %u, max_id %u, max_lun %u, max_channel %u\n",
8698 shp->host_busy, shp->last_reset, shp->max_id, shp->max_lun,
8699 shp->max_channel);
8700#endif /* version >= v1.3.89 */
8701 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8702
8703 len = asc_prt_line(cp, leftlen,
8704#if LINUX_VERSION_CODE131108 < ASC_LINUX_VERSION(1,3,57)(((1) * 65536) + ((3) * 256) + (57))
8705" can_queue %d, this_id %d, sg_tablesize %u, cmd_per_lun %u\n",
8706 shp->can_queue, shp->this_id, shp->sg_tablesize, shp->cmd_per_lun);
8707#else /* version >= v1.3.57 */
8708" unique_id %d, can_queue %d, this_id %d, sg_tablesize %u, cmd_per_lun %u\n",
8709 shp->unique_id, shp->can_queue, shp->this_id, shp->sg_tablesize,
8710 shp->cmd_per_lun);
8711#endif /* version >= v1.3.57 */
8712 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8713
8714 len = asc_prt_line(cp, leftlen,
8715#if LINUX_VERSION_CODE131108 < ASC_LINUX_VERSION(1,3,57)(((1) * 65536) + ((3) * 256) + (57))
8716" unchecked_isa_dma %d, loaded_as_module %d\n",
8717 shp->unchecked_isa_dma, shp->loaded_as_module);
8718#else /* version >= v1.3.57 */
8719" unchecked_isa_dma %d, use_clustering %d, loaded_as_module %d\n",
8720 shp->unchecked_isa_dma, shp->use_clustering, shp->loaded_as_module);
8721#endif /* version >= v1.3.57 */
8722 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8723
8724 len = asc_prt_line(cp, leftlen, " flags %x, last_reset %x, jiffies %x\n",
8725 boardp->flags, boardp->last_reset, jiffies);
8726 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8727
8728 if (ASC_NARROW_BOARD(boardp)(((boardp)->flags & 0x04) == 0)) {
8729 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
8730 } else {
8731 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
8732 }
8733
8734#if LINUX_VERSION_CODE131108 >= ASC_LINUX_VERSION(1,3,89)(((1) * 65536) + ((3) * 256) + (89))
8735 if (boardp->flags & ASC_SELECT_QUEUE_DEPTHS0x08) {
8736 len = asc_prt_line(cp, leftlen, " queue_depth:");
8737 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8738 for (i = 0; i <= ADV_MAX_TID15; i++) {
8739 if ((chip_scsi_id == i) ||
8740 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)(0x01 << ((i) & 15))) == 0)) {
8741 continue;
8742 }
8743 if (boardp->device[i] == NULL((void *) 0)) {
8744 continue;
8745 }
8746 len = asc_prt_line(cp, leftlen, " %X:%d",
8747 i, boardp->device[i]->queue_depth);
8748 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8749 }
8750 len = asc_prt_line(cp, leftlen, "\n");
8751 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8752 }
8753#endif /* version >= v1.3.89 */
8754
8755#if ASC_QUEUE_FLOW_CONTROL
8756 if (ASC_NARROW_BOARD(boardp)(((boardp)->flags & 0x04) == 0)) {
8757 len = asc_prt_line(cp, leftlen, " queue_curr_depth:");
8758 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8759 /* Use ASC_MAX_TID for Narrow Board. */
8760 for (i = 0; i <= ASC_MAX_TID7; i++) {
8761 if ((boardp->asc_dvc_cfg.chip_scsi_id == i) ||
8762 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)(0x01 << ((i) & 15))) == 0)) {
8763 continue;
8764 }
8765 if (boardp->device[i] == NULL((void *) 0)) {
8766 continue;
8767 }
8768 len = asc_prt_line(cp, leftlen, " %d:%d",
8769 i, boardp->device[i]->queue_curr_depth);
8770 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8771 }
8772 len = asc_prt_line(cp, leftlen, "\n");
8773 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8774
8775 len = asc_prt_line(cp, leftlen, " queue_count:");
8776 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8777 /* Use ASC_MAX_TID for Narrow Board. */
8778 for (i = 0; i <= ASC_MAX_TID7; i++) {
8779 if ((boardp->asc_dvc_cfg.chip_scsi_id == i) ||
8780 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)(0x01 << ((i) & 15))) == 0)) {
8781 continue;
8782 }
8783 if (boardp->device[i] == NULL((void *) 0)) {
8784 continue;
8785 }
8786 len = asc_prt_line(cp, leftlen, " %d:%d",
8787 i, boardp->device[i]->queue_count);
8788 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8789 }
8790 len = asc_prt_line(cp, leftlen, "\n");
8791 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8792 }
8793#endif /* ASC_QUEUE_FLOW_CONTROL */
8794
8795 return totlen;
8796}
8797
8798/*
8799 * asc_prt_asc_board_info()
8800 *
8801 * Print dynamic board configuration information.
8802 *
8803 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
8804 * cf. asc_prt_line().
8805 *
8806 * Return the number of characters copied into 'cp'. No more than
8807 * 'cplen' characters will be copied to 'cp'.
8808 */
8809STATICstatic int
8810asc_prt_asc_board_info(struct Scsi_Host *shp, char *cp, int cplen)
8811{
8812 asc_board_t *boardp;
8813 int leftlen;
8814 int totlen;
8815 int len;
8816 ASC_DVC_VAR *v;
8817 ASC_DVC_CFG *c;
8818 int i;
8819
8820 boardp = ASC_BOARDP(shp)((asc_board_t *) &((shp)->hostdata));
8821 v = &boardp->dvc_var.asc_dvc_var;
8822 c = &boardp->dvc_cfg.asc_dvc_cfg;
8823
8824 leftlen = cplen;
8825 totlen = len = 0;
8826
8827 len = asc_prt_line(cp, leftlen,
8828"\nAsc Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
8829 shp->host_no);
8830 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8831
8832 len = asc_prt_line(cp, leftlen,
8833" chip_version %u, lib_version %x, lib_serial_no %u, mcode_date %x\n",
8834 c->chip_version, c->lib_version, c->lib_serial_no, c->mcode_date);
8835 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8836
8837 len = asc_prt_line(cp, leftlen,
8838" mcode_version %x, err_code %u\n",
8839 c->mcode_version, v->err_code);
8840 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8841
8842 /* Current number of commands waiting for the host. */
8843 len = asc_prt_line(cp, leftlen,
8844" Total Command Pending: %d\n", v->cur_total_qng);
8845 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8846
8847 len = asc_prt_line(cp, leftlen,
8848" Command Queuing:");
8849 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8850 for (i = 0; i <= ASC_MAX_TID7; i++) {
8851 if ((boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id == i) ||
8852 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)(0x01 << ((i) & 15))) == 0)) {
8853 continue;
8854 }
8855 len = asc_prt_line(cp, leftlen, " %d:%c",
8856 i, (v->use_tagged_qng & ADV_TID_TO_TIDMASK(i)(0x01 << ((i) & 15))) ? 'Y' : 'N');
8857 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8858 }
8859 len = asc_prt_line(cp, leftlen, "\n");
8860 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8861
8862 /* Current number of commands waiting for a device. */
8863 len = asc_prt_line(cp, leftlen,
8864" Command Queue Pending:");
8865 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8866 for (i = 0; i <= ASC_MAX_TID7; i++) {
8867 if ((boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id == i) ||
8868 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)(0x01 << ((i) & 15))) == 0)) {
8869 continue;
8870 }
8871 len = asc_prt_line(cp, leftlen, " %d:%u", i, v->cur_dvc_qng[i]);
8872 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8873 }
8874 len = asc_prt_line(cp, leftlen, "\n");
8875 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8876
8877 /* Current limit on number of commands that can be sent to a device. */
8878 len = asc_prt_line(cp, leftlen,
8879" Command Queue Limit:");
8880 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8881 for (i = 0; i <= ASC_MAX_TID7; i++) {
8882 if ((boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id == i) ||
8883 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)(0x01 << ((i) & 15))) == 0)) {
8884 continue;
8885 }
8886 len = asc_prt_line(cp, leftlen, " %d:%u", i, v->max_dvc_qng[i]);
8887 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8888 }
8889 len = asc_prt_line(cp, leftlen, "\n");
8890 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8891
8892 /* Indicate whether the device has returned queue full status. */
8893 len = asc_prt_line(cp, leftlen,
8894" Command Queue Full:");
8895 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8896 for (i = 0; i <= ASC_MAX_TID7; i++) {
8897 if ((boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id == i) ||
8898 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)(0x01 << ((i) & 15))) == 0)) {
8899 continue;
8900 }
8901 if (boardp->queue_full & ADV_TID_TO_TIDMASK(i)(0x01 << ((i) & 15))) {
8902 len = asc_prt_line(cp, leftlen, " %d:Y-%d",
8903 i, boardp->queue_full_cnt[i]);
8904 } else {
8905 len = asc_prt_line(cp, leftlen, " %d:N", i);
8906 }
8907 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8908 }
8909 len = asc_prt_line(cp, leftlen, "\n");
8910 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8911
8912 len = asc_prt_line(cp, leftlen,
8913" Synchronous Transfer:");
8914 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8915 for (i = 0; i <= ASC_MAX_TID7; i++) {
8916 if ((boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id == i) ||
8917 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)(0x01 << ((i) & 15))) == 0)) {
8918 continue;
8919 }
8920 len = asc_prt_line(cp, leftlen, " %d:%c",
8921 i, (v->sdtr_done & ADV_TID_TO_TIDMASK(i)(0x01 << ((i) & 15))) ? 'Y' : 'N');
8922 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8923 }
8924 len = asc_prt_line(cp, leftlen, "\n");
8925 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8926
8927 for (i = 0; i <= ASC_MAX_TID7; i++) {
8928 uchar syn_period_ix;
8929
8930 if ((boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id == i) ||
8931 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)(0x01 << ((i) & 15))) == 0)) {
8932 continue;
8933 }
8934 if ((v->sdtr_done & ADV_TID_TO_TIDMASK(i)(0x01 << ((i) & 15))) == 0) {
8935 continue;
8936 }
8937 syn_period_ix = (boardp->sdtr_data[i] >> 4) & (v->max_sdtr_index - 1);
8938 len = asc_prt_line(cp, leftlen, " %d:", i);
8939 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8940
8941 len = asc_prt_line(cp, leftlen,
8942 " Transfer Period Factor: %d (%d.%d Mhz),",
8943 v->sdtr_period_tbl[syn_period_ix],
8944 250 / v->sdtr_period_tbl[syn_period_ix],
8945 ASC_TENTHS(250, v->sdtr_period_tbl[syn_period_ix])(((10 * ((250)/(v->sdtr_period_tbl[syn_period_ix]))) > (
((250) * 10)/(v->sdtr_period_tbl[syn_period_ix]))) ? 0 : (
(((250) * 10)/(v->sdtr_period_tbl[syn_period_ix])) - (10 *
((250)/(v->sdtr_period_tbl[syn_period_ix])))))
);
8946 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8947
8948 len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d\n",
8949 boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET0x0F);
8950 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8951 }
8952
8953 return totlen;
8954}
8955
8956/*
8957 * asc_prt_adv_board_info()
8958 *
8959 * Print dynamic board configuration information.
8960 *
8961 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
8962 * cf. asc_prt_line().
8963 *
8964 * Return the number of characters copied into 'cp'. No more than
8965 * 'cplen' characters will be copied to 'cp'.
8966 */
8967STATICstatic int
8968asc_prt_adv_board_info(struct Scsi_Host *shp, char *cp, int cplen)
8969{
8970 asc_board_t *boardp;
8971 int leftlen;
8972 int totlen;
8973 int len;
8974 int i;
8975 ADV_DVC_VAR *v;
8976 ADV_DVC_CFG *c;
8977 AdvPortAddrunsigned long iop_base;
8978 ushort chip_scsi_id;
8979 ushort lramword;
8980 uchar lrambyte;
8981 ushort sdtr_able;
8982 ushort period;
8983
8984 boardp = ASC_BOARDP(shp)((asc_board_t *) &((shp)->hostdata));
8985 v = &boardp->dvc_var.adv_dvc_var;
8986 c = &boardp->dvc_cfg.adv_dvc_cfg;
8987 iop_base = v->iop_base;
8988 chip_scsi_id = v->chip_scsi_id;
8989
8990 leftlen = cplen;
8991 totlen = len = 0;
8992
8993 len = asc_prt_line(cp, leftlen,
8994"\nAdv Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
8995 shp->host_no);
8996 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
8997
8998 len = asc_prt_line(cp, leftlen,
8999" iop_base %lx, cable_detect: %X, err_code %u, idle_cmd_done %u\n",
9000 v->iop_base,
9001 AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1)((*(volatile unsigned short *) ((iop_base) + (0x0E)))) & CABLE_DETECT0x000F,
9002 v->err_code, v->idle_cmd_done);
9003 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
9004
9005 len = asc_prt_line(cp, leftlen,
9006" chip_version %u, lib_version %x, mcode_date %x, mcode_version %x\n",
9007 c->chip_version, c->lib_version, c->mcode_date, c->mcode_version);
9008 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
9009
9010 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, lramword)do { ((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((
0x00A0))); (lramword) = (*(volatile unsigned short *) ((iop_base
) + 0x06)); } while (0)
;
9011 len = asc_prt_line(cp, leftlen,
9012" Queuing Enabled:");
9013 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
9014 for (i = 0; i <= ADV_MAX_TID15; i++) {
9015 if ((chip_scsi_id == i) ||
9016 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)(0x01 << ((i) & 15))) == 0)) {
9017 continue;
9018 }
9019
9020 len = asc_prt_line(cp, leftlen, " %X:%c",
9021 i, (lramword & ADV_TID_TO_TIDMASK(i)(0x01 << ((i) & 15))) ? 'Y' : 'N');
9022 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
9023 }
9024 len = asc_prt_line(cp, leftlen, "\n");
9025 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
9026
9027 len = asc_prt_line(cp, leftlen,
9028" Queue Limit:");
9029 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
9030 for (i = 0; i <= ADV_MAX_TID15; i++) {
9031 if ((chip_scsi_id == i) ||
9032 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)(0x01 << ((i) & 15))) == 0)) {
9033 continue;
9034 }
9035
9036 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + i, lrambyte)do { ((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((
0x00D0 + i))); (lrambyte) = (*(volatile unsigned char *) ((iop_base
) + 0x06)); } while (0)
;
9037
9038 len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
9039 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
9040 }
9041 len = asc_prt_line(cp, leftlen, "\n");
9042 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
9043
9044 len = asc_prt_line(cp, leftlen,
9045" Command Pending:");
9046 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
9047 for (i = 0; i <= ADV_MAX_TID15; i++) {
9048 if ((chip_scsi_id == i) ||
9049 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)(0x01 << ((i) & 15))) == 0)) {
9050 continue;
9051 }
9052
9053 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_QUEUED_CMD + i, lrambyte)do { ((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((
0x00C0 + i))); (lrambyte) = (*(volatile unsigned char *) ((iop_base
) + 0x06)); } while (0)
;
9054
9055 len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
9056 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
9057 }
9058 len = asc_prt_line(cp, leftlen, "\n");
9059 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
9060
9061 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, lramword)do { ((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((
0x0120))); (lramword) = (*(volatile unsigned short *) ((iop_base
) + 0x06)); } while (0)
;
9062 len = asc_prt_line(cp, leftlen,
9063" Wide Enabled:");
9064 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
9065 for (i = 0; i <= ADV_MAX_TID15; i++) {
9066 if ((chip_scsi_id == i) ||
9067 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)(0x01 << ((i) & 15))) == 0)) {
9068 continue;
9069 }
9070
9071 len = asc_prt_line(cp, leftlen, " %X:%c",
9072 i, (lramword & ADV_TID_TO_TIDMASK(i)(0x01 << ((i) & 15))) ? 'Y' : 'N');
9073 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
9074 }
9075 len = asc_prt_line(cp, leftlen, "\n");
9076 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
9077
9078 len = asc_prt_line(cp, leftlen,
9079" Transfer Bit Width:");
9080 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
9081 for (i = 0; i <= ADV_MAX_TID15; i++) {
9082 if ((chip_scsi_id == i) ||
9083 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)(0x01 << ((i) & 15))) == 0)) {
9084 continue;
9085 }
9086
9087 AdvReadWordLram(iop_base, ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),do { ((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((
0x0100 + (2 * i)))); (lramword) = (*(volatile unsigned short *
) ((iop_base) + 0x06)); } while (0)
9088 lramword)do { ((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((
0x0100 + (2 * i)))); (lramword) = (*(volatile unsigned short *
) ((iop_base) + 0x06)); } while (0)
;
9089 len = asc_prt_line(cp, leftlen, " %X:%d",
9090 i, (lramword & 0x8000) ? 16 : 8);
9091 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
9092 }
9093 len = asc_prt_line(cp, leftlen, "\n");
9094 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
9095
9096 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able)do { ((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((
0x009E))); (sdtr_able) = (*(volatile unsigned short *) ((iop_base
) + 0x06)); } while (0)
;
9097 len = asc_prt_line(cp, leftlen,
9098" Synchronous Enabled:");
9099 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
9100 for (i = 0; i <= ADV_MAX_TID15; i++) {
9101 if ((chip_scsi_id == i) ||
9102 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)(0x01 << ((i) & 15))) == 0)) {
9103 continue;
9104 }
9105
9106 len = asc_prt_line(cp, leftlen, " %X:%c",
9107 i, (sdtr_able & ADV_TID_TO_TIDMASK(i)(0x01 << ((i) & 15))) ? 'Y' : 'N');
9108 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
9109 }
9110 len = asc_prt_line(cp, leftlen, "\n");
9111 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
9112
9113 for (i = 0; i <= ADV_MAX_TID15; i++) {
9114
9115 AdvReadWordLram(iop_base, ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),do { ((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((
0x0100 + (2 * i)))); (lramword) = (*(volatile unsigned short *
) ((iop_base) + 0x06)); } while (0)
9116 lramword)do { ((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((
0x0100 + (2 * i)))); (lramword) = (*(volatile unsigned short *
) ((iop_base) + 0x06)); } while (0)
;
9117 lramword &= ~0x8000;
9118
9119 if ((chip_scsi_id == i) ||
9120 ((sdtr_able & ADV_TID_TO_TIDMASK(i)(0x01 << ((i) & 15))) == 0) ||
9121 (lramword == 0)) {
9122 continue;
9123 }
9124
9125 len = asc_prt_line(cp, leftlen, " %X:", i);
9126 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
9127
9128 period = (((lramword >> 8) * 25) + 50)/4;
9129
9130 len = asc_prt_line(cp, leftlen,
9131 " Transfer Period Factor: %d (%d.%d Mhz),",
9132 period, 250/period, ASC_TENTHS(250, period)(((10 * ((250)/(period))) > (((250) * 10)/(period))) ? 0 :
((((250) * 10)/(period)) - (10 * ((250)/(period)))))
);
9133 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
9134
9135 len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d\n",
9136 lramword & 0x1F);
9137 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
9138 }
9139
9140 return totlen;
9141}
9142
9143/*
9144 * asc_proc_copy()
9145 *
9146 * Copy proc information to a read buffer taking into account the current
9147 * read offset in the file and the remaining space in the read buffer.
9148 */
9149STATICstatic int
9150asc_proc_copy(off_t advoffset, off_t offset, char *curbuf, int leftlen,
9151 char *cp, int cplen)
9152{
9153 int cnt = 0;
9154
9155 ASC_DBG3(2, "asc_proc_copy: offset %d, advoffset %d, cplen %d\n",
9156 (unsigned) offset, (unsigned) advoffset, cplen);
9157 if (offset <= advoffset) {
9158 /* Read offset below current offset, copy everything. */
9159 cnt = ASC_MIN(cplen, leftlen)(((cplen) < (leftlen)) ? (cplen) : (leftlen));
9160 ASC_DBG3(2, "asc_proc_copy: curbuf %x, cp %x, cnt %d\n",
9161 (unsigned) curbuf, (unsigned) cp, cnt);
9162 memcpy(curbuf, cp, cnt)(__builtin_constant_p(cnt) ? __constant_memcpy((curbuf),(cp),
(cnt)) : __memcpy((curbuf),(cp),(cnt)))
;
9163 } else if (offset < advoffset + cplen) {
9164 /* Read offset within current range, partial copy. */
9165 cnt = (advoffset + cplen) - offset;
9166 cp = (cp + cplen) - cnt;
9167 cnt = ASC_MIN(cnt, leftlen)(((cnt) < (leftlen)) ? (cnt) : (leftlen));
9168 ASC_DBG3(2, "asc_proc_copy: curbuf %x, cp %x, cnt %d\n",
9169 (unsigned) curbuf, (unsigned) cp, cnt);
9170 memcpy(curbuf, cp, cnt)(__builtin_constant_p(cnt) ? __constant_memcpy((curbuf),(cp),
(cnt)) : __memcpy((curbuf),(cp),(cnt)))
;
9171 }
9172 return cnt;
9173}
9174
9175/*
9176 * asc_prt_line()
9177 *
9178 * If 'cp' is NULL print to the console, otherwise print to a buffer.
9179 *
9180 * Return 0 if printing to the console, otherwise return the number of
9181 * bytes written to the buffer.
9182 *
9183 * Note: If any single line is greater than ASC_PRTLINE_SIZE bytes the stack
9184 * will be corrupted. 's[]' is defined to be ASC_PRTLINE_SIZE bytes.
9185 */
9186STATICstatic int
9187asc_prt_line(char *buf, int buflen, char *fmt, ...)
9188{
9189 va_list args;
9190 int ret;
9191 char s[ASC_PRTLINE_SIZE160];
9192
9193 va_start(args, fmt)__builtin_va_start(args,fmt);
9194 ret = vsprintflinux_vsprintf(s, fmt, args);
9195 ASC_ASSERT(ret < ASC_PRTLINE_SIZE){ if (!(ret < 160)) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 9195); } }
;
9196 if (buf == NULL((void *) 0)) {
9197 (void) printk("%s", s);
9198 ret = 0;
9199 } else {
9200 ret = ASC_MIN(buflen, ret)(((buflen) < (ret)) ? (buflen) : (ret));
9201 memcpy(buf, s, ret)(__builtin_constant_p(ret) ? __constant_memcpy((buf),(s),(ret
)) : __memcpy((buf),(s),(ret)))
;
9202 }
9203 va_end(args)__builtin_va_end(args);
9204 return ret;
9205}
9206#endif /* version >= v1.3.0 */
9207
9208
9209/*
9210 * --- Functions Required by the Asc Library
9211 */
9212
9213/*
9214 * Delay for 'n' milliseconds. Don't use the 'jiffies'
9215 * global variable which is incremented once every 5 ms
9216 * from a timer interrupt, because this function may be
9217 * called when interrupts are disabled.
9218 */
9219STATICstatic void
9220DvcSleepMilliSecond(ulong n)
9221{
9222 ulong i;
9223
9224 ASC_DBG1(4, "DvcSleepMilliSecond: %lu\n", n);
9225 for (i = 0; i < n; i++) {
9226 udelay(1000)(__builtin_constant_p(1000) ? __const_udelay((1000) * 0x10c6ul
) : __udelay(1000))
;
9227 }
9228}
9229
9230STATICstatic long
9231DvcEnterCritical(void)
9232{
9233 long flags;
9234
9235 save_flags(flags)__asm__ __volatile__("pushf ; pop %0" : "=r" (flags): :"memory"
)
;
9236 cli()__asm__ __volatile__ ("cli": : :"memory");
9237 return flags;
9238}
9239
9240STATICstatic void
9241DvcLeaveCritical(long flags)
9242{
9243 restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory");
9244}
9245
9246STATICstatic ulong
9247DvcGetSGList(ASC_DVC_VAR *asc_dvc_sg, uchar *buf_addr, ulong buf_len,
9248 ASC_SG_HEAD *asc_sg_head_ptr)
9249{
9250 ulong buf_size;
9251
9252 buf_size = buf_len;
9253 asc_sg_head_ptr->entry_cnt = 1;
9254#if LINUX_VERSION_CODE131108 < ASC_LINUX_VERSION(2,0,0)(((2) * 65536) + ((0) * 256) + (0))
9255 asc_sg_head_ptr->sg_list[0].addr = (ulong) buf_addr;
9256#else /* version >= v2.0.0 */
9257 asc_sg_head_ptr->sg_list[0].addr = virt_to_busvirt_to_phys(buf_addr);
9258#endif /* version >= v2.0.0 */
9259 asc_sg_head_ptr->sg_list[0].bytes = buf_size;
9260 return buf_size;
9261}
9262
9263/*
9264 * void
9265 * DvcPutScsiQ(PortAddr iop_base, ushort s_addr, ushort *outbuf, int words)
9266 *
9267 * Calling/Exit State:
9268 * none
9269 *
9270 * Description:
9271 * Output an ASC_SCSI_Q structure to the chip
9272 */
9273STATICstatic void
9274DvcPutScsiQ(PortAddrunsigned short iop_base, ushort s_addr, ushort *outbuf, int words)
9275{
9276 int i;
9277
9278 ASC_DBG_PRT_HEX(2, "DvcPutScsiQ", (uchar *) outbuf, 2 * words);
9279 AscSetChipLramAddr(iop_base, s_addr)((__builtin_constant_p((((unsigned short)((iop_base)+(0x0A)))
)) && (((unsigned short)((iop_base)+(0x0A)))) < 256
) ? __outwc(((s_addr)),(((unsigned short)((iop_base)+(0x0A)))
)) : __outw(((s_addr)),(((unsigned short)((iop_base)+(0x0A)))
)))
;
9280 for (i = 0; i < words; i++, outbuf++) {
9281 if (i == 2 || i == 10) {
9282 continue;
9283 }
9284 AscSetChipLramDataNoSwap(iop_base, *outbuf)((__builtin_constant_p((((iop_base)+(0x08)))) && (((iop_base
)+(0x08))) < 256) ? __outwc(((*outbuf)),(((iop_base)+(0x08
)))) : __outw(((*outbuf)),(((iop_base)+(0x08)))))
;
9285 }
9286}
9287
9288/*
9289 * void
9290 * DvcGetQinfo(PortAddr iop_base, ushort s_addr, ushort *inbuf, int words)
9291 *
9292 * Calling/Exit State:
9293 * none
9294 *
9295 * Description:
9296 * Input an ASC_QDONE_INFO structure from the chip
9297 */
9298STATICstatic void
9299DvcGetQinfo(PortAddrunsigned short iop_base, ushort s_addr, ushort *inbuf, int words)
9300{
9301 int i;
9302
9303 AscSetChipLramAddr(iop_base, s_addr)((__builtin_constant_p((((unsigned short)((iop_base)+(0x0A)))
)) && (((unsigned short)((iop_base)+(0x0A)))) < 256
) ? __outwc(((s_addr)),(((unsigned short)((iop_base)+(0x0A)))
)) : __outw(((s_addr)),(((unsigned short)((iop_base)+(0x0A)))
)))
;
9304 for (i = 0; i < words; i++, inbuf++) {
9305 if (i == 5) {
9306 continue;
9307 }
9308 *inbuf = AscGetChipLramDataNoSwap(iop_base)(ushort)((__builtin_constant_p(((iop_base)+(0x08))) &&
((iop_base)+(0x08)) < 256) ? __inwc((iop_base)+(0x08)) : __inw
((iop_base)+(0x08)))
;
9309 }
9310 ASC_DBG_PRT_HEX(2, "DvcGetQinfo", (uchar *) inbuf, 2 * words);
9311}
9312
9313/*
9314 * void DvcOutPortWords(ushort iop_base, ushort &outbuf, int words)
9315 *
9316 * Calling/Exit State:
9317 * none
9318 *
9319 * Description:
9320 * output a buffer to an i/o port address
9321 */
9322STATICstatic void
9323DvcOutPortWords(ushort iop_base, ushort *outbuf, int words)
9324{
9325 int i;
9326
9327 for (i = 0; i < words; i++, outbuf++)
9328 outpw(iop_base, *outbuf)((__builtin_constant_p(((iop_base))) && ((iop_base)) <
256) ? __outwc(((*outbuf)),((iop_base))) : __outw(((*outbuf)
),((iop_base))))
;
9329}
9330
9331/*
9332 * void DvcInPortWords(ushort iop_base, ushort &outbuf, int words)
9333 *
9334 * Calling/Exit State:
9335 * none
9336 *
9337 * Description:
9338 * input a buffer from an i/o port address
9339 */
9340STATICstatic void
9341DvcInPortWords(ushort iop_base, ushort *inbuf, int words)
9342{
9343 int i;
9344
9345 for (i = 0; i < words; i++, inbuf++)
9346 *inbuf = inpw(iop_base)((__builtin_constant_p((iop_base)) && (iop_base) <
256) ? __inwc(iop_base) : __inw(iop_base))
;
9347}
9348
9349/*
9350 * void DvcOutPortDWords(PortAddr port, ulong *pdw, int dwords)
9351 *
9352 * Calling/Exit State:
9353 * none
9354 *
9355 * Description:
9356 * output a buffer of 32-bit integers to an i/o port address in
9357 * 16 bit integer units
9358 */
9359STATICstatic void
9360DvcOutPortDWords(PortAddrunsigned short port, ulong *pdw, int dwords)
9361{
9362 int i;
9363 int words;
9364 ushort *pw;
9365
9366 pw = (ushort *) pdw;
9367 words = dwords << 1;
9368 for(i = 0; i < words; i++, pw++) {
9369 outpw(port, *pw)((__builtin_constant_p(((port))) && ((port)) < 256
) ? __outwc(((*pw)),((port))) : __outw(((*pw)),((port))))
;
9370 }
9371 return;
9372}
9373
9374/*
9375 * Read a PCI configuration byte.
9376 */
9377ASC_INITFUNC(static uchar DvcReadPCIConfigByte( ASC_DVC_VAR *asc_dvc, ushort
offset)
9378STATIC ucharstatic uchar DvcReadPCIConfigByte( ASC_DVC_VAR *asc_dvc, ushort
offset)
9379DvcReadPCIConfigByte(static uchar DvcReadPCIConfigByte( ASC_DVC_VAR *asc_dvc, ushort
offset)
9380 ASC_DVC_VAR asc_ptr_type *asc_dvc,static uchar DvcReadPCIConfigByte( ASC_DVC_VAR *asc_dvc, ushort
offset)
9381 ushort offset)static uchar DvcReadPCIConfigByte( ASC_DVC_VAR *asc_dvc, ushort
offset)
9382)static uchar DvcReadPCIConfigByte( ASC_DVC_VAR *asc_dvc, ushort
offset)
9383{
9384#if LINUX_VERSION_CODE131108 < ASC_LINUX_VERSION(2,1,93)(((2) * 65536) + ((1) * 256) + (93))
9385#ifdef ASC_CONFIG_PCI
9386 PCI_DATA pciData;
9387
9388 pciData.bus = ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info)((asc_dvc->cfg->pci_slot_info) & 0xFF);
9389 pciData.slot = ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info)(((asc_dvc->cfg->pci_slot_info) >> 11) & 0x1F
)
;
9390 pciData.func = ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info)(((asc_dvc->cfg->pci_slot_info) >> 8) & 0x7);
9391 pciData.offset = offset;
9392 pciData.type = pci_scan_method;
9393 return asc_get_cfg_byte(&pciData);
9394#else /* ASC_CONFIG_PCI */
9395 return 0;
9396#endif /* ASC_CONFIG_PCI */
9397#else /* version >= v2.1.93 */
9398#ifdef CONFIG_PCI1
9399 uchar byte_data;
9400 pcibios_read_config_byte(ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info)((asc_dvc->cfg->pci_slot_info) & 0xFF),
9401 PCI_DEVFN(ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info)(((asc_dvc->cfg->pci_slot_info) >> 11) & 0x1F
)
,
9402 ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info)(((asc_dvc->cfg->pci_slot_info) >> 8) & 0x7)),
9403 offset, &byte_data);
9404 return byte_data;
9405#else /* CONFIG_PCI */
9406 return 0;
9407#endif /* CONFIG_PCI */
9408#endif /* version >= v2.1.93 */
9409}
9410
9411/*
9412 * Write a PCI configuration byte.
9413 */
9414ASC_INITFUNC(static void DvcWritePCIConfigByte( ASC_DVC_VAR *asc_dvc, ushort
offset, uchar byte_data)
9415STATIC voidstatic void DvcWritePCIConfigByte( ASC_DVC_VAR *asc_dvc, ushort
offset, uchar byte_data)
9416DvcWritePCIConfigByte(static void DvcWritePCIConfigByte( ASC_DVC_VAR *asc_dvc, ushort
offset, uchar byte_data)
9417 ASC_DVC_VAR asc_ptr_type *asc_dvc,static void DvcWritePCIConfigByte( ASC_DVC_VAR *asc_dvc, ushort
offset, uchar byte_data)
9418 ushort offset,static void DvcWritePCIConfigByte( ASC_DVC_VAR *asc_dvc, ushort
offset, uchar byte_data)
9419 uchar byte_data)static void DvcWritePCIConfigByte( ASC_DVC_VAR *asc_dvc, ushort
offset, uchar byte_data)
9420)static void DvcWritePCIConfigByte( ASC_DVC_VAR *asc_dvc, ushort
offset, uchar byte_data)
9421{
9422#if LINUX_VERSION_CODE131108 < ASC_LINUX_VERSION(2,1,93)(((2) * 65536) + ((1) * 256) + (93))
9423#ifdef ASC_CONFIG_PCI
9424 PCI_DATA pciData;
9425
9426 pciData.bus = ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info)((asc_dvc->cfg->pci_slot_info) & 0xFF);
9427 pciData.slot = ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info)(((asc_dvc->cfg->pci_slot_info) >> 11) & 0x1F
)
;
9428 pciData.func = ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info)(((asc_dvc->cfg->pci_slot_info) >> 8) & 0x7);
9429 pciData.offset = offset;
9430 pciData.type = pci_scan_method;
9431 asc_put_cfg_byte(&pciData, byte_data);
9432#endif /* ASC_CONFIG_PCI */
9433#else /* version >= v2.1.93 */
9434#ifdef CONFIG_PCI1
9435 pcibios_write_config_byte(ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info)((asc_dvc->cfg->pci_slot_info) & 0xFF),
9436 PCI_DEVFN(ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info)(((asc_dvc->cfg->pci_slot_info) >> 11) & 0x1F
)
,
9437 ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info)(((asc_dvc->cfg->pci_slot_info) >> 8) & 0x7)),
9438 offset, byte_data);
9439#endif /* CONFIG_PCI */
9440#endif /* version >= v2.1.93 */
9441}
9442
9443/*
9444 * Return the BIOS address of the adapter at the specified
9445 * I/O port and with the specified bus type.
9446 */
9447ASC_INITFUNC(static ushort AscGetChipBiosAddress( unsigned short iop_base,
ushort bus_type)
9448STATIC ushortstatic ushort AscGetChipBiosAddress( unsigned short iop_base,
ushort bus_type)
9449AscGetChipBiosAddress(static ushort AscGetChipBiosAddress( unsigned short iop_base,
ushort bus_type)
9450 PortAddr iop_base,static ushort AscGetChipBiosAddress( unsigned short iop_base,
ushort bus_type)
9451 ushort bus_typestatic ushort AscGetChipBiosAddress( unsigned short iop_base,
ushort bus_type)
9452)static ushort AscGetChipBiosAddress( unsigned short iop_base,
ushort bus_type)
9453)static ushort AscGetChipBiosAddress( unsigned short iop_base,
ushort bus_type)
9454{
9455 ushort cfg_lsw ;
9456 ushort bios_addr ;
9457
9458 /*
9459 * The PCI BIOS is re-located by the motherboard BIOS. Because
9460 * of this the driver can not determine where a PCI BIOS is
9461 * loaded and executes.
9462 */
9463 if (bus_type & ASC_IS_PCI(0x0004))
9464 {
9465 return(0);
9466 }
9467
9468 if((bus_type & ASC_IS_EISA(0x0002)) != 0)
9469 {
9470 cfg_lsw = AscGetEisaChipCfg(iop_base) ;
9471 cfg_lsw &= 0x000F ;
9472 bios_addr = (ushort)(ASC_BIOS_MIN_ADDR0xC000 +
9473 (cfg_lsw * ASC_BIOS_BANK_SIZE0x0400)) ;
9474 return(bios_addr) ;
9475 }/* if */
9476
9477 cfg_lsw = AscGetChipCfgLsw(iop_base)(ushort)((__builtin_constant_p(((iop_base)+(0x02))) &&
((iop_base)+(0x02)) < 256) ? __inwc((iop_base)+(0x02)) : __inw
((iop_base)+(0x02)))
;
9478
9479 /*
9480 * ISA PnP uses the top bit as the 32K BIOS flag
9481 */
9482 if (bus_type == ASC_IS_ISAPNP(0x0081))
9483 {
9484 cfg_lsw &= 0x7FFF;
9485 }/* if */
9486
9487 bios_addr = (ushort)(((cfg_lsw >> 12) * ASC_BIOS_BANK_SIZE0x0400) +
9488 ASC_BIOS_MIN_ADDR0xC000) ;
9489 return(bios_addr) ;
9490}
9491
9492
9493/*
9494 * --- Functions Required by the Adv Library
9495 */
9496
9497/*
9498 * DvcGetPhyAddr()
9499 *
9500 * Return the physical address of 'vaddr' and set '*lenp' to the
9501 * number of physically contiguous bytes that follow 'vaddr'.
9502 * 'flag' indicates the type of structure whose physical address
9503 * is being translated.
9504 *
9505 * Note: Because Linux currently doesn't page the kernel and all
9506 * kernel buffers are physically contiguous, leave '*lenp' unchanged.
9507 */
9508ulong
9509DvcGetPhyAddr(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq,
9510 uchar *vaddr, long *lenp, int flag)
9511{
9512 ulong paddr;
9513
9514#if LINUX_VERSION_CODE131108 < ASC_LINUX_VERSION(2,0,0)(((2) * 65536) + ((0) * 256) + (0))
9515 paddr = (ulong) vaddr;
9516#else /* version >= v2.0.0 */
9517 paddr = virt_to_busvirt_to_phys(vaddr);
9518#endif /* version >= v2.0.0 */
9519
9520 ASC_DBG4(4,
9521 "DvcGetPhyAddr: vaddr 0x%lx, lenp 0x%lx *lenp %lu, paddr 0x%lx\n",
9522 (ulong) vaddr, (ulong) lenp, (ulong) *((ulong *) lenp), paddr);
9523
9524 return paddr;
9525}
9526
9527/*
9528 * Read a PCI configuration byte.
9529 */
9530ASC_INITFUNC(static uchar DvcAdvReadPCIConfigByte( ADV_DVC_VAR *asc_dvc, ushort
offset)
9531STATIC ucharstatic uchar DvcAdvReadPCIConfigByte( ADV_DVC_VAR *asc_dvc, ushort
offset)
9532DvcAdvReadPCIConfigByte(static uchar DvcAdvReadPCIConfigByte( ADV_DVC_VAR *asc_dvc, ushort
offset)
9533 ADV_DVC_VAR *asc_dvc,static uchar DvcAdvReadPCIConfigByte( ADV_DVC_VAR *asc_dvc, ushort
offset)
9534 ushort offset)static uchar DvcAdvReadPCIConfigByte( ADV_DVC_VAR *asc_dvc, ushort
offset)
9535)static uchar DvcAdvReadPCIConfigByte( ADV_DVC_VAR *asc_dvc, ushort
offset)
9536{
9537#if LINUX_VERSION_CODE131108 < ASC_LINUX_VERSION(2,1,93)(((2) * 65536) + ((1) * 256) + (93))
9538#ifdef ASC_CONFIG_PCI
9539 PCI_DATA pciData;
9540
9541 pciData.bus = ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info)((asc_dvc->cfg->pci_slot_info) & 0xFF);
9542 pciData.slot = ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info)(((asc_dvc->cfg->pci_slot_info) >> 11) & 0x1F
)
;
9543 pciData.func = ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info)(((asc_dvc->cfg->pci_slot_info) >> 8) & 0x7);
9544 pciData.offset = offset;
9545 pciData.type = pci_scan_method;
9546 return asc_get_cfg_byte(&pciData);
9547#else /* ASC_CONFIG_PCI */
9548 return 0;
9549#endif /* ASC_CONFIG_PCI */
9550#else /* version >= v2.1.93 */
9551#ifdef CONFIG_PCI1
9552 uchar byte_data;
9553 pcibios_read_config_byte(ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info)((asc_dvc->cfg->pci_slot_info) & 0xFF),
9554 PCI_DEVFN(ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info)(((asc_dvc->cfg->pci_slot_info) >> 11) & 0x1F
)
,
9555 ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info)(((asc_dvc->cfg->pci_slot_info) >> 8) & 0x7)),
9556 offset, &byte_data);
9557 return byte_data;
9558#else /* CONFIG_PCI */
9559 return 0;
9560#endif /* CONFIG_PCI */
9561#endif /* version >= v2.1.93 */
9562}
9563
9564/*
9565 * Write a PCI configuration byte.
9566 */
9567ASC_INITFUNC(static void DvcAdvWritePCIConfigByte( ADV_DVC_VAR *asc_dvc, ushort
offset, uchar byte_data)
9568STATIC voidstatic void DvcAdvWritePCIConfigByte( ADV_DVC_VAR *asc_dvc, ushort
offset, uchar byte_data)
9569DvcAdvWritePCIConfigByte(static void DvcAdvWritePCIConfigByte( ADV_DVC_VAR *asc_dvc, ushort
offset, uchar byte_data)
9570 ADV_DVC_VAR *asc_dvc,static void DvcAdvWritePCIConfigByte( ADV_DVC_VAR *asc_dvc, ushort
offset, uchar byte_data)
9571 ushort offset,static void DvcAdvWritePCIConfigByte( ADV_DVC_VAR *asc_dvc, ushort
offset, uchar byte_data)
9572 uchar byte_data)static void DvcAdvWritePCIConfigByte( ADV_DVC_VAR *asc_dvc, ushort
offset, uchar byte_data)
9573)static void DvcAdvWritePCIConfigByte( ADV_DVC_VAR *asc_dvc, ushort
offset, uchar byte_data)
9574{
9575#if LINUX_VERSION_CODE131108 < ASC_LINUX_VERSION(2,1,93)(((2) * 65536) + ((1) * 256) + (93))
9576#ifdef ASC_CONFIG_PCI
9577 PCI_DATA pciData;
9578
9579 pciData.bus = ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info)((asc_dvc->cfg->pci_slot_info) & 0xFF);
9580 pciData.slot = ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info)(((asc_dvc->cfg->pci_slot_info) >> 11) & 0x1F
)
;
9581 pciData.func = ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info)(((asc_dvc->cfg->pci_slot_info) >> 8) & 0x7);
9582 pciData.offset = offset;
9583 pciData.type = pci_scan_method;
9584 asc_put_cfg_byte(&pciData, byte_data);
9585#endif /* ASC_CONFIG_PCI */
9586#else /* version >= v2.1.93 */
9587#ifdef CONFIG_PCI1
9588 pcibios_write_config_byte(ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info)((asc_dvc->cfg->pci_slot_info) & 0xFF),
9589 PCI_DEVFN(ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info)(((asc_dvc->cfg->pci_slot_info) >> 11) & 0x1F
)
,
9590 ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info)(((asc_dvc->cfg->pci_slot_info) >> 8) & 0x7)),
9591 offset, byte_data);
9592#endif /* CONFIG_PCI */
9593#endif /* version >= v2.1.93 */
9594}
9595
9596/*
9597 * --- Tracing and Debugging Functions
9598 */
9599
9600#ifdef ADVANSYS_STATS
9601/*
9602 * asc_prt_board_stats()
9603 *
9604 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
9605 * cf. asc_prt_line().
9606 *
9607 * Return the number of characters copied into 'cp'. No more than
9608 * 'cplen' characters will be copied to 'cp'.
9609 */
9610STATICstatic int
9611asc_prt_board_stats(struct Scsi_Host *shp, char *cp, int cplen)
9612{
9613 int leftlen;
9614 int totlen;
9615 int len;
9616 struct asc_stats *s;
9617 int i;
9618 ushort chip_scsi_id;
9619 asc_board_t *boardp;
9620 asc_queue_t *active;
9621 asc_queue_t *waiting;
9622
9623 leftlen = cplen;
9624 totlen = len = 0;
9625
9626 boardp = ASC_BOARDP(shp)((asc_board_t *) &((shp)->hostdata));
9627 s = &boardp->asc_stats;
9628
9629 len = asc_prt_line(cp, leftlen,
9630"\nLinux Driver Statistics for AdvanSys SCSI Host %d:\n", shp->host_no);
9631 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
9632
9633 len = asc_prt_line(cp, leftlen,
9634" command %lu, queuecommand %lu, abort %lu, reset %lu, biosparam %lu\n",
9635 s->command, s->queuecommand, s->abort, s->reset, s->biosparam);
9636 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
9637
9638 len = asc_prt_line(cp, leftlen,
9639" interrupt %lu, callback %lu, done %lu\n",
9640 s->interrupt, s->callback, s->done);
9641 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
9642
9643 len = asc_prt_line(cp, leftlen,
9644" exe_noerror %lu, exe_busy %lu, exe_error %lu, exe_unknown %lu\n",
9645 s->exe_noerror, s->exe_busy, s->exe_error, s->exe_unknown);
9646 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
9647
9648 if (ASC_NARROW_BOARD(boardp)(((boardp)->flags & 0x04) == 0)) {
9649 len = asc_prt_line(cp, leftlen,
9650" build_error %lu\n",
9651 s->build_error);
9652 } else {
9653 len = asc_prt_line(cp, leftlen,
9654" build_error %lu, build_noreq %lu, build_nosg %lu\n",
9655 s->build_error, s->adv_build_noreq, s->adv_build_nosg);
9656 }
9657 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
9658
9659 /*
9660 * Display data transfer statistics.
9661 */
9662 if (s->cont_cnt > 0) {
9663 len = asc_prt_line(cp, leftlen, " cont_cnt %lu, ", s->cont_cnt);
9664 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
9665
9666 len = asc_prt_line(cp, leftlen, "cont_xfer %lu.%01lu kb ",
9667 s->cont_xfer/2,
9668 ASC_TENTHS(s->cont_xfer, 2)(((10 * ((s->cont_xfer)/(2))) > (((s->cont_xfer) * 10
)/(2))) ? 0 : ((((s->cont_xfer) * 10)/(2)) - (10 * ((s->
cont_xfer)/(2)))))
);
9669 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
9670
9671 /* Contiguous transfer average size */
9672 len = asc_prt_line(cp, leftlen, "avg_xfer %lu.%01lu kb\n",
9673 (s->cont_xfer/2)/s->cont_cnt,
9674 ASC_TENTHS((s->cont_xfer/2), s->cont_cnt)(((10 * (((s->cont_xfer/2))/(s->cont_cnt))) > ((((s->
cont_xfer/2)) * 10)/(s->cont_cnt))) ? 0 : (((((s->cont_xfer
/2)) * 10)/(s->cont_cnt)) - (10 * (((s->cont_xfer/2))/(
s->cont_cnt)))))
);
9675 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
9676 }
9677
9678 if (s->sg_cnt > 0) {
9679
9680 len = asc_prt_line(cp, leftlen, " sg_cnt %lu, sg_elem %lu, ",
9681 s->sg_cnt, s->sg_elem);
9682 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
9683
9684 len = asc_prt_line(cp, leftlen, "sg_xfer %lu.%01lu kb\n",
9685 s->sg_xfer/2,
9686 ASC_TENTHS(s->sg_xfer, 2)(((10 * ((s->sg_xfer)/(2))) > (((s->sg_xfer) * 10)/(
2))) ? 0 : ((((s->sg_xfer) * 10)/(2)) - (10 * ((s->sg_xfer
)/(2)))))
);
9687 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
9688
9689 /* Scatter gather transfer statistics */
9690 len = asc_prt_line(cp, leftlen, " avg_num_elem %lu.%01lu, ",
9691 s->sg_elem/s->sg_cnt,
9692 ASC_TENTHS(s->sg_elem, s->sg_cnt)(((10 * ((s->sg_elem)/(s->sg_cnt))) > (((s->sg_elem
) * 10)/(s->sg_cnt))) ? 0 : ((((s->sg_elem) * 10)/(s->
sg_cnt)) - (10 * ((s->sg_elem)/(s->sg_cnt)))))
);
9693 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
9694
9695 len = asc_prt_line(cp, leftlen, "avg_elem_size %lu.%01lu kb, ",
9696 (s->sg_xfer/2)/s->sg_elem,
9697 ASC_TENTHS((s->sg_xfer/2), s->sg_elem)(((10 * (((s->sg_xfer/2))/(s->sg_elem))) > ((((s->
sg_xfer/2)) * 10)/(s->sg_elem))) ? 0 : (((((s->sg_xfer/
2)) * 10)/(s->sg_elem)) - (10 * (((s->sg_xfer/2))/(s->
sg_elem)))))
);
9698 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
9699
9700 len = asc_prt_line(cp, leftlen, "avg_xfer_size %lu.%01lu kb\n",
9701 (s->sg_xfer/2)/s->sg_cnt,
9702 ASC_TENTHS((s->sg_xfer/2), s->sg_cnt)(((10 * (((s->sg_xfer/2))/(s->sg_cnt))) > ((((s->
sg_xfer/2)) * 10)/(s->sg_cnt))) ? 0 : (((((s->sg_xfer/2
)) * 10)/(s->sg_cnt)) - (10 * (((s->sg_xfer/2))/(s->
sg_cnt)))))
);
9703 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
9704 }
9705
9706 /*
9707 * Display request queuing statistics.
9708 */
9709 len = asc_prt_line(cp, leftlen,
9710" Active and Waiting Request Queues (Time Unit: %d HZ):\n", HZ100);
9711 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
9712
9713 active = &ASC_BOARDP(shp)((asc_board_t *) &((shp)->hostdata))->active;
9714 waiting = &ASC_BOARDP(shp)((asc_board_t *) &((shp)->hostdata))->waiting;
9715
9716 if (ASC_NARROW_BOARD(boardp)(((boardp)->flags & 0x04) == 0)) {
9717 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
9718 } else {
9719 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
9720 }
9721
9722 for (i = 0; i <= ADV_MAX_TID15; i++) {
9723
9724 if ((chip_scsi_id == i) ||
9725 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)(0x01 << ((i) & 15))) == 0)) {
9726 continue;
9727 }
9728
9729 if (active->q_tot_cnt[i] > 0 || waiting->q_tot_cnt[i] > 0) {
9730 len = asc_prt_line(cp, leftlen, " target %d\n", i);
9731 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
9732
9733 len = asc_prt_line(cp, leftlen,
9734" active: cnt [cur %d, max %d, tot %u], time [min %d, max %d, avg %lu.%01lu]\n",
9735 active->q_cur_cnt[i], active->q_max_cnt[i],
9736 active->q_tot_cnt[i],
9737 active->q_min_tim[i], active->q_max_tim[i],
9738 (active->q_tot_cnt[i] == 0) ? 0 :
9739 (active->q_tot_tim[i]/active->q_tot_cnt[i]),
9740 (active->q_tot_cnt[i] == 0) ? 0 :
9741 ASC_TENTHS(active->q_tot_tim[i], active->q_tot_cnt[i])(((10 * ((active->q_tot_tim[i])/(active->q_tot_cnt[i]))
) > (((active->q_tot_tim[i]) * 10)/(active->q_tot_cnt
[i]))) ? 0 : ((((active->q_tot_tim[i]) * 10)/(active->q_tot_cnt
[i])) - (10 * ((active->q_tot_tim[i])/(active->q_tot_cnt
[i])))))
);
9742 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
9743
9744 len = asc_prt_line(cp, leftlen,
9745" waiting: cnt [cur %d, max %d, tot %u], time [min %u, max %u, avg %lu.%01lu]\n",
9746 waiting->q_cur_cnt[i], waiting->q_max_cnt[i],
9747 waiting->q_tot_cnt[i],
9748 waiting->q_min_tim[i], waiting->q_max_tim[i],
9749 (waiting->q_tot_cnt[i] == 0) ? 0 :
9750 (waiting->q_tot_tim[i]/waiting->q_tot_cnt[i]),
9751 (waiting->q_tot_cnt[i] == 0) ? 0 :
9752 ASC_TENTHS(waiting->q_tot_tim[i], waiting->q_tot_cnt[i])(((10 * ((waiting->q_tot_tim[i])/(waiting->q_tot_cnt[i]
))) > (((waiting->q_tot_tim[i]) * 10)/(waiting->q_tot_cnt
[i]))) ? 0 : ((((waiting->q_tot_tim[i]) * 10)/(waiting->
q_tot_cnt[i])) - (10 * ((waiting->q_tot_tim[i])/(waiting->
q_tot_cnt[i])))))
);
9753 ASC_PRT_NEXT()if (cp) { totlen += len; leftlen -= len; if (leftlen == 0) { return
totlen; } cp += len; }
;
9754 }
9755 }
9756
9757 return totlen;
9758}
9759#endif /* ADVANSYS_STATS */
9760
9761#ifdef ADVANSYS_DEBUG
9762/*
9763 * asc_prt_scsi_host()
9764 */
9765STATICstatic void
9766asc_prt_scsi_host(struct Scsi_Host *s)
9767{
9768 asc_board_t *boardp;
9769
9770 boardp = ASC_BOARDP(s)((asc_board_t *) &((s)->hostdata));
9771
9772 printk("Scsi_Host at addr %x\n", (unsigned) s);
9773 printk(
9774" next %x, extra_bytes %u, host_busy %u, host_no %d, last_reset %d,\n",
9775 (unsigned) s->next, s->extra_bytes, s->host_busy, s->host_no,
9776 (unsigned) s->last_reset);
9777
9778 printk(
9779" host_wait %x, host_queue %x, hostt %x, block %x,\n",
9780 (unsigned) s->host_wait, (unsigned) s->host_queue,
9781 (unsigned) s->hostt, (unsigned) s->block);
9782
9783 printk(
9784" wish_block %d, base %x, io_port %d, n_io_port %d, irq %d, dma_channel %d,\n",
9785 s->wish_block, (unsigned) s->base, s->io_port, s->n_io_port,
9786 s->irq, s->dma_channel);
9787
9788 printk(
9789" this_id %d, can_queue %d,\n", s->this_id, s->can_queue);
9790
9791 printk(
9792" cmd_per_lun %d, sg_tablesize %d, unchecked_isa_dma %d, loaded_as_module %d\n",
9793 s->cmd_per_lun, s->sg_tablesize, s->unchecked_isa_dma,
9794 s->loaded_as_module);
9795
9796 if (ASC_NARROW_BOARD(boardp)(((boardp)->flags & 0x04) == 0)) {
9797 asc_prt_asc_dvc_var(&ASC_BOARDP(s)((asc_board_t *) &((s)->hostdata))->dvc_var.asc_dvc_var);
9798 asc_prt_asc_dvc_cfg(&ASC_BOARDP(s)((asc_board_t *) &((s)->hostdata))->dvc_cfg.asc_dvc_cfg);
9799 } else {
9800 asc_prt_adv_dvc_var(&ASC_BOARDP(s)((asc_board_t *) &((s)->hostdata))->dvc_var.adv_dvc_var);
9801 asc_prt_adv_dvc_cfg(&ASC_BOARDP(s)((asc_board_t *) &((s)->hostdata))->dvc_cfg.adv_dvc_cfg);
9802 }
9803}
9804
9805/*
9806 * asc_prt_scsi_cmnd()
9807 */
9808STATICstatic void
9809asc_prt_scsi_cmnd(Scsi_Cmnd *s)
9810{
9811 printk("Scsi_Cmnd at addr %x\n", (unsigned) s);
9812
9813#if LINUX_VERSION_CODE131108 < ASC_LINUX_VERSION(1,3,0)(((1) * 65536) + ((3) * 256) + (0))
9814 printk(
9815" host %x, device %x, target %u, lun %u\n",
9816 (unsigned) s->host, (unsigned) s->device, s->target, s->lun);
9817#else /* version >= v1.3.0 */
9818 printk(
9819" host %x, device %x, target %u, lun %u, channel %u,\n",
9820 (unsigned) s->host, (unsigned) s->device, s->target, s->lun,
9821 s->channel);
9822#endif /* version >= v1.3.0 */
9823
9824 asc_prt_hex(" CDB", s->cmnd, s->cmd_len);
9825
9826 printk(
9827" use_sg %u, sglist_len %u, abort_reason %x\n",
9828 s->use_sg, s->sglist_len, s->abort_reason);
9829
9830#if LINUX_VERSION_CODE131108 < ASC_LINUX_VERSION(1,3,89)(((1) * 65536) + ((3) * 256) + (89))
9831 printk(
9832" retries %d, allowed %d\n",
9833 s->retries, s->allowed);
9834#else /* version >= v1.3.89 */
9835 printk(
9836" serial_number %x, serial_number_at_timeout %x, retries %d, allowed %d\n",
9837 (unsigned) s->serial_number, (unsigned) s->serial_number_at_timeout,
9838 s->retries, s->allowed);
9839#endif /* version >= v1.3.89 */
9840
9841 printk(
9842" timeout_per_command %d, timeout_total %d, timeout %d\n",
9843 s->timeout_per_command, s->timeout_total, s->timeout);
9844
9845 printk(
9846" internal_timeout %u, flags %u, this_count %d\n",
9847 s->internal_timeout, s->flags, s->this_count);
9848
9849 printk(
9850" scsi_done %x, done %x, host_scribble %x, result %x\n",
9851 (unsigned) s->scsi_done, (unsigned) s->done,
9852 (unsigned) s->host_scribble, s->result);
9853
9854 printk(
9855" tag %u, pid %u\n",
9856 (unsigned) s->tag, (unsigned) s->pid);
9857}
9858
9859/*
9860 * asc_prt_asc_dvc_var()
9861 */
9862STATICstatic void
9863asc_prt_asc_dvc_var(ASC_DVC_VAR *h)
9864{
9865 printk("ASC_DVC_VAR at addr %x\n", (unsigned) h);
9866
9867 printk(
9868" iop_base %x, err_code %x, dvc_cntl %x, bug_fix_cntl %d,\n",
9869 h->iop_base, h->err_code, h->dvc_cntl, h->bug_fix_cntl);
9870
9871 printk(
9872" bus_type %d, isr_callback %x, exe_callback %x, init_sdtr %x,\n",
9873 h->bus_type, (unsigned) h->isr_callback, (unsigned) h->exe_callback,
9874 (unsigned) h->init_sdtr);
9875
9876 printk(
9877" sdtr_done %x, use_tagged_qng %x, unit_not_ready %x, chip_no %x,\n",
9878 (unsigned) h->sdtr_done, (unsigned) h->use_tagged_qng,
9879 (unsigned) h->unit_not_ready, (unsigned) h->chip_no);
9880
9881 printk(
9882" queue_full_or_busy %x, start_motor %x, scsi_reset_wait %x, irq_no %x,\n",
9883 (unsigned) h->queue_full_or_busy, (unsigned) h->start_motor,
9884 (unsigned) h->scsi_reset_wait, (unsigned) h->irq_no);
9885
9886 printk(
9887" is_in_int %x, max_total_qng %x, cur_total_qng %x, in_critical_cnt %x,\n",
9888 (unsigned) h->is_in_int, (unsigned) h->max_total_qng,
9889 (unsigned) h->cur_total_qng, (unsigned) h->in_critical_cnt);
9890
9891 printk(
9892" last_q_shortage %x, init_state %x, no_scam %x, pci_fix_asyn_xfer %x,\n",
9893 (unsigned) h->last_q_shortage, (unsigned) h->init_state,
9894 (unsigned) h->no_scam, (unsigned) h->pci_fix_asyn_xfer);
9895
9896 printk(
9897" cfg %x, saved_ptr2func %x\n",
9898 (unsigned) h->cfg, (unsigned) h->saved_ptr2func);
9899}
9900
9901/*
9902 * asc_prt_asc_dvc_cfg()
9903 */
9904STATICstatic void
9905asc_prt_asc_dvc_cfg(ASC_DVC_CFG *h)
9906{
9907 printk("ASC_DVC_CFG at addr %x\n", (unsigned) h);
9908
9909 printk(
9910" can_tagged_qng %x, cmd_qng_enabled %x, disc_enable %x, sdtr_enable %x,\n",
9911 h->can_tagged_qng, h->cmd_qng_enabled, h->disc_enable,
9912 h->sdtr_enable);
9913
9914 printk(
9915" chip_scsi_id %d, isa_dma_speed %d, isa_dma_channel %d, chip_version %d,\n",
9916 h->chip_scsi_id, h->isa_dma_speed, h->isa_dma_channel,
9917 h->chip_version);
9918
9919 printk(
9920" pci_device_id %d, lib_serial_no %x, lib_version %x, mcode_date %x,\n",
9921 h->pci_device_id, h->lib_serial_no, h->lib_version, h->mcode_date);
9922
9923 printk(
9924" mcode_version %d, overrun_buf %x\n",
9925 h->mcode_version, (unsigned) h->overrun_buf);
9926}
9927
9928/*
9929 * asc_prt_asc_scsi_q()
9930 */
9931STATICstatic void
9932asc_prt_asc_scsi_q(ASC_SCSI_Q *q)
9933{
9934 ASC_SG_HEAD *sgp;
9935 int i;
9936
9937 printk("ASC_SCSI_Q at addr %x\n", (unsigned) q);
9938
9939 printk(
9940" target_ix %u, target_lun %u, srb_ptr %x, tag_code %u,\n",
9941 q->q2.target_ix, q->q1.target_lun,
9942 (unsigned) q->q2.srb_ptr, q->q2.tag_code);
9943
9944 printk(
9945" data_addr %x, data_cnt %lu, sense_addr %x, sense_len %u,\n",
9946 (unsigned) q->q1.data_addr, q->q1.data_cnt,
9947 (unsigned) q->q1.sense_addr, q->q1.sense_len);
9948
9949 printk(
9950" cdbptr %x, cdb_len %u, sg_head %x, sg_queue_cnt %u\n",
9951 (unsigned) q->cdbptr, q->q2.cdb_len,
9952 (unsigned) q->sg_head, q->q1.sg_queue_cnt);
9953
9954 if (q->sg_head) {
9955 sgp = q->sg_head;
9956 printk("ASC_SG_HEAD at addr %x\n", (unsigned) sgp);
9957 printk(" entry_cnt %u, queue_cnt %u\n", sgp->entry_cnt, sgp->queue_cnt);
9958 for (i = 0; i < sgp->entry_cnt; i++) {
9959 printk(" [%u]: addr %x, bytes %lu\n",
9960 i, (unsigned) sgp->sg_list[i].addr, sgp->sg_list[i].bytes);
9961 }
9962
9963 }
9964}
9965
9966/*
9967 * asc_prt_asc_qdone_info()
9968 */
9969STATICstatic void
9970asc_prt_asc_qdone_info(ASC_QDONE_INFO *q)
9971{
9972 printk("ASC_QDONE_INFO at addr %x\n", (unsigned) q);
9973 printk(
9974" srb_ptr %x, target_ix %u, cdb_len %u, tag_code %u, done_stat %x\n",
9975 (unsigned) q->d2.srb_ptr, q->d2.target_ix, q->d2.cdb_len,
9976 q->d2.tag_code, q->d3.done_stat);
9977 printk(
9978" host_stat %x, scsi_stat %x, scsi_msg %x\n",
9979 q->d3.host_stat, q->d3.scsi_stat, q->d3.scsi_msg);
9980}
9981
9982/*
9983 * asc_prt_adv_dvc_var()
9984 *
9985 * Display an ADV_DVC_VAR structure.
9986 */
9987STATICstatic void
9988asc_prt_adv_dvc_var(ADV_DVC_VAR *h)
9989{
9990 printk(" ADV_DVC_VAR at addr 0x%lx\n", (ulong) h);
9991
9992 printk(
9993" iop_base 0x%lx, err_code 0x%x, ultra_able 0x%x\n",
9994 (ulong) h->iop_base, h->err_code, (unsigned) h->ultra_able);
9995
9996 printk(
9997" isr_callback 0x%x, sdtr_able 0x%x, wdtr_able 0x%x\n",
9998 (unsigned) h->isr_callback, (unsigned) h->wdtr_able,
9999 (unsigned) h->sdtr_able);
10000
10001 printk(
10002" start_motor 0x%x, scsi_reset_wait 0x%x, irq_no 0x%x,\n",
10003 (unsigned) h->start_motor,
10004 (unsigned) h->scsi_reset_wait, (unsigned) h->irq_no);
10005
10006 printk(
10007" max_host_qng 0x%x, cur_host_qng 0x%x, max_dvc_qng 0x%x\n",
10008 (unsigned) h->max_host_qng, (unsigned) h->cur_host_qng,
10009 (unsigned) h->max_dvc_qng);
10010
10011 printk(
10012" no_scam 0x%x, tagqng_able 0x%x, chip_scsi_id 0x%x, cfg 0x%lx\n",
10013 (unsigned) h->no_scam, (unsigned) h->tagqng_able,
10014 (unsigned) h->chip_scsi_id, (ulong) h->cfg);
10015
10016}
10017
10018/*
10019 * asc_prt_adv_dvc_cfg()
10020 *
10021 * Display an ADV_DVC_CFG structure.
10022 */
10023STATICstatic void
10024asc_prt_adv_dvc_cfg(ADV_DVC_CFG *h)
10025{
10026 printk(" ADV_DVC_CFG at addr 0x%lx\n", (ulong) h);
10027
10028 printk(
10029" disc_enable 0x%x, termination 0x%x\n",
10030 h->disc_enable, h->termination);
10031
10032 printk(
10033" chip_version 0x%x, mcode_date 0x%x\n",
10034 h->chip_version, h->mcode_date);
10035
10036 printk(
10037" mcode_version 0x%x, pci_device_id 0x%x, lib_version 0x%x\n",
10038 h->mcode_version, h->pci_device_id, h->lib_version);
10039
10040 printk(
10041" control_flag 0x%x, pci_slot_info 0x%x\n",
10042 h->control_flag, h->pci_slot_info);
10043}
10044
10045/*
10046 * asc_prt_adv_scsi_req_q()
10047 *
10048 * Display an ADV_SCSI_REQ_Q structure.
10049 */
10050STATICstatic void
10051asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *q)
10052{
10053 int i;
10054 struct asc_sg_block *sg_ptr;
10055
10056 printk("ADV_SCSI_REQ_Q at addr %x\n", (unsigned) q);
10057
10058 printk(
10059" target_id %u, target_lun %u, srb_ptr 0x%lx, a_flag 0x%x\n",
10060 q->target_id, q->target_lun, q->srb_ptr, q->a_flag);
10061
10062 printk(" cntl 0x%x, data_addr 0x%lx, vdata_addr 0x%lx\n",
10063 q->cntl, q->data_addr, q->vdata_addr);
10064
10065 printk(
10066" data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
10067 q->data_cnt, q->sense_addr, q->sense_len);
10068
10069 printk(
10070" cdb_len %u, done_status 0x%x, host_status 0x%x, scsi_status 0x%x\n",
10071 q->cdb_len, q->done_status, q->host_status, q->scsi_status);
10072
10073 printk(
10074" vsense_addr 0x%lx, scsiq_ptr 0x%lx, ux_wk_data_cnt %lu\n",
10075 (ulong) q->vsense_addr, (ulong) q->scsiq_ptr,
10076 (ulong) q->ux_wk_data_cnt);
10077
10078 printk(
10079" sg_list_ptr 0x%lx, sg_real_addr 0x%lx, sg_entry_cnt %u\n",
10080 (ulong) q->sg_list_ptr, (ulong) q->sg_real_addr, q->sg_entry_cnt);
10081
10082 printk(
10083" ux_sg_ix %u, orig_sense_len %u\n",
10084 q->ux_sg_ix, q->orig_sense_len);
10085
10086 /* Display the request's ADV_SG_BLOCK structures. */
10087 for (sg_ptr = q->sg_list_ptr, i = 0; sg_ptr != NULL((void *) 0);
10088 sg_ptr = sg_ptr->sg_ptr, i++) {
10089 /*
10090 * 'sg_ptr' is a physical address. Convert it to a virtual
10091 * address by indexing 'i' into the virtual address array
10092 * 'sg_list_ptr'.
10093 *
10094 * At the end of the each iteration of the loop 'sg_ptr' is
10095 * converted back into a physical address by setting 'sg_ptr'
10096 * to the next pointer 'sg_ptr->sg_ptr'.
10097 */
10098 sg_ptr = &(((ADV_SG_BLOCK *) (q->sg_list_ptr))[i]);
10099 asc_prt_adv_sgblock(i, sg_ptr);
10100 }
10101}
10102
10103/*
10104 * asc_prt_adv_sgblock()
10105 *
10106 * Display an ADV_SG_BLOCK structure.
10107 */
10108STATICstatic void
10109asc_prt_adv_sgblock(int sgblockno, ADV_SG_BLOCK *b)
10110{
10111 int i, s;
10112
10113 /* Calculate starting entry number for the current block. */
10114 s = sgblockno * NO_OF_SG_PER_BLOCK15;
10115
10116 printk(" ADV_SG_BLOCK at addr 0x%lx (sgblockno %lu)\n",
10117 (ulong) b, (ulong) sgblockno);
10118 printk(
10119" first_entry_no %lu, last_entry_no %lu, sg_ptr 0x%lx\n",
10120 (ulong) b->first_entry_no, (ulong) b->last_entry_no, (ulong) b->sg_ptr);
10121 ASC_ASSERT(b->first_entry_no - s >= 0){ if (!(b->first_entry_no - s >= 0)) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 10121); } }
;
10122 ASC_ASSERT(b->last_entry_no - s >= 0){ if (!(b->last_entry_no - s >= 0)) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 10122); } }
;
10123 ASC_ASSERT(b->last_entry_no - s <= NO_OF_SG_PER_BLOCK){ if (!(b->last_entry_no - s <= 15)) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 10123); } }
;
10124 ASC_ASSERT(b->first_entry_no - s <= NO_OF_SG_PER_BLOCK){ if (!(b->first_entry_no - s <= 15)) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 10124); } }
;
10125 ASC_ASSERT(b->first_entry_no - s <= NO_OF_SG_PER_BLOCK){ if (!(b->first_entry_no - s <= 15)) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 10125); } }
;
10126 ASC_ASSERT(b->first_entry_no - s <= b->last_entry_no - s){ if (!(b->first_entry_no - s <= b->last_entry_no - s
)) { printk("ASC_ASSERT() Failure: file %s, line %d\n", "../linux/src/drivers/scsi/advansys.c"
, 10126); } }
;
10127 for (i = b->first_entry_no - s; i <= b->last_entry_no - s; i++) {
10128 printk(" [%lu]: sg_addr 0x%lx, sg_count 0x%lx\n",
10129 (ulong) i, (ulong) b->sg_list[i].sg_addr,
10130 (ulong) b->sg_list[i].sg_count);
10131 }
10132}
10133
10134/*
10135 * asc_prt_hex()
10136 *
10137 * Print hexadecimal output in 4 byte groupings 32 bytes
10138 * or 8 double-words per line.
10139 */
10140STATICstatic void
10141asc_prt_hex(char *f, uchar *s, int l)
10142{
10143 int i;
10144 int j;
10145 int k;
10146 int m;
10147
10148 printk("%s: (%d bytes)\n", f, l);
10149
10150 for (i = 0; i < l; i += 32) {
10151
10152 /* Display a maximum of 8 double-words per line. */
10153 if ((k = (l - i) / 4) >= 8) {
10154 k = 8;
10155 m = 0;
10156 } else {
10157 m = (l - i) % 4 ;
10158 }
10159
10160 for (j = 0; j < k; j++) {
10161 printk(" %2.2X%2.2X%2.2X%2.2X",
10162 (unsigned) s[i+(j*4)], (unsigned) s[i+(j*4)+1],
10163 (unsigned) s[i+(j*4)+2], (unsigned) s[i+(j*4)+3]);
10164 }
10165
10166 switch (m) {
10167 case 0:
10168 default:
10169 break;
10170 case 1:
10171 printk(" %2.2X",
10172 (unsigned) s[i+(j*4)]);
10173 break;
10174 case 2:
10175 printk(" %2.2X%2.2X",
10176 (unsigned) s[i+(j*4)],
10177 (unsigned) s[i+(j*4)+1]);
10178 break;
10179 case 3:
10180 printk(" %2.2X%2.2X%2.2X",
10181 (unsigned) s[i+(j*4)+1],
10182 (unsigned) s[i+(j*4)+2],
10183 (unsigned) s[i+(j*4)+3]);
10184 break;
10185 }
10186
10187 printk("\n");
10188 }
10189}
10190#endif /* ADVANSYS_DEBUG */
10191
10192#ifdef ADVANSYS_ASSERT
10193/*
10194 * interrupts_enabled()
10195 *
10196 * Return 1 if interrupts are enabled, otherwise return 0.
10197 */
10198STATICstatic int
10199interrupts_enabled(void)
10200{
10201 long flags;
10202
10203 save_flags(flags)__asm__ __volatile__("pushf ; pop %0" : "=r" (flags): :"memory"
)
;
10204 if (flags & 0x0200) {
10205 return ASC_TRUE1;
10206 } else {
10207 return ASC_FALSE0;
10208 }
10209}
10210#endif /* ADVANSYS_ASSERT */
10211
10212
10213/*
10214 * --- Asc Library Functions
10215 */
10216
10217ASC_INITFUNC(static ushort AscGetEisaChipCfg( unsigned short iop_base)
10218STATIC ushortstatic ushort AscGetEisaChipCfg( unsigned short iop_base)
10219AscGetEisaChipCfg(static ushort AscGetEisaChipCfg( unsigned short iop_base)
10220 PortAddr iop_basestatic ushort AscGetEisaChipCfg( unsigned short iop_base)
10221)static ushort AscGetEisaChipCfg( unsigned short iop_base)
10222)static ushort AscGetEisaChipCfg( unsigned short iop_base)
10223{
10224 PortAddrunsigned short eisa_cfg_iop;
10225
10226 eisa_cfg_iop = (PortAddrunsigned short) ASC_GET_EISA_SLOT(iop_base)(unsigned short)((iop_base) & 0xF000) |
10227 (PortAddrunsigned short) (ASC_EISA_CFG_IOP_MASK(0x0C86));
10228 return (inpw(eisa_cfg_iop)((__builtin_constant_p((eisa_cfg_iop)) && (eisa_cfg_iop
) < 256) ? __inwc(eisa_cfg_iop) : __inw(eisa_cfg_iop))
);
10229}
10230
10231ASC_INITFUNC(static uchar AscSetChipScsiID( unsigned short iop_base, uchar
new_host_id)
10232STATIC ucharstatic uchar AscSetChipScsiID( unsigned short iop_base, uchar
new_host_id)
10233AscSetChipScsiID(static uchar AscSetChipScsiID( unsigned short iop_base, uchar
new_host_id)
10234 PortAddr iop_base,static uchar AscSetChipScsiID( unsigned short iop_base, uchar
new_host_id)
10235 uchar new_host_idstatic uchar AscSetChipScsiID( unsigned short iop_base, uchar
new_host_id)
10236)static uchar AscSetChipScsiID( unsigned short iop_base, uchar
new_host_id)
10237)static uchar AscSetChipScsiID( unsigned short iop_base, uchar
new_host_id)
10238{
10239 ushort cfg_lsw;
10240
10241 if (AscGetChipScsiID(iop_base)(((ushort)((__builtin_constant_p(((iop_base)+(0x02))) &&
((iop_base)+(0x02)) < 256) ? __inwc((iop_base)+(0x02)) : __inw
((iop_base)+(0x02))) >> 8) & 7)
== new_host_id) {
10242 return (new_host_id);
10243 }
10244 cfg_lsw = AscGetChipCfgLsw(iop_base)(ushort)((__builtin_constant_p(((iop_base)+(0x02))) &&
((iop_base)+(0x02)) < 256) ? __inwc((iop_base)+(0x02)) : __inw
((iop_base)+(0x02)))
;
10245 cfg_lsw &= 0xF8FF;
10246 cfg_lsw |= (ushort) ((new_host_id & ASC_MAX_TID7) << 8);
10247 AscSetChipCfgLsw(iop_base, cfg_lsw)((__builtin_constant_p((((iop_base)+(0x02)))) && (((iop_base
)+(0x02))) < 256) ? __outwc(((cfg_lsw)),(((iop_base)+(0x02
)))) : __outw(((cfg_lsw)),(((iop_base)+(0x02)))))
;
10248 return (AscGetChipScsiID(iop_base)(((ushort)((__builtin_constant_p(((iop_base)+(0x02))) &&
((iop_base)+(0x02)) < 256) ? __inwc((iop_base)+(0x02)) : __inw
((iop_base)+(0x02))) >> 8) & 7)
);
10249}
10250
10251ASC_INITFUNC(static uchar AscGetChipScsiCtrl( unsigned short iop_base)
10252STATIC ucharstatic uchar AscGetChipScsiCtrl( unsigned short iop_base)
10253AscGetChipScsiCtrl(static uchar AscGetChipScsiCtrl( unsigned short iop_base)
10254 PortAddr iop_basestatic uchar AscGetChipScsiCtrl( unsigned short iop_base)
10255)static uchar AscGetChipScsiCtrl( unsigned short iop_base)
10256)static uchar AscGetChipScsiCtrl( unsigned short iop_base)
10257{
10258 uchar sc;
10259
10260 AscSetBank(iop_base, 1);
10261 sc = inp(iop_base + IOP_REG_SC)((__builtin_constant_p((iop_base + (0x09))) && (iop_base
+ (0x09)) < 256) ? __inbc(iop_base + (0x09)) : __inb(iop_base
+ (0x09)))
;
10262 AscSetBank(iop_base, 0);
10263 return (sc);
10264}
10265
10266ASC_INITFUNC(static uchar AscGetChipVersion( unsigned short iop_base, ushort
bus_type)
10267STATIC ucharstatic uchar AscGetChipVersion( unsigned short iop_base, ushort
bus_type)
10268AscGetChipVersion(static uchar AscGetChipVersion( unsigned short iop_base, ushort
bus_type)
10269 PortAddr iop_base,static uchar AscGetChipVersion( unsigned short iop_base, ushort
bus_type)
10270 ushort bus_typestatic uchar AscGetChipVersion( unsigned short iop_base, ushort
bus_type)
10271)static uchar AscGetChipVersion( unsigned short iop_base, ushort
bus_type)
10272)static uchar AscGetChipVersion( unsigned short iop_base, ushort
bus_type)
10273{
10274 if ((bus_type & ASC_IS_EISA(0x0002)) != 0) {
10275 PortAddrunsigned short eisa_iop;
10276 uchar revision;
10277 eisa_iop = (PortAddrunsigned short) ASC_GET_EISA_SLOT(iop_base)(unsigned short)((iop_base) & 0xF000) |
10278 (PortAddrunsigned short) ASC_EISA_REV_IOP_MASK(0x0C83);
10279 revision = inp(eisa_iop)((__builtin_constant_p((eisa_iop)) && (eisa_iop) <
256) ? __inbc(eisa_iop) : __inb(eisa_iop))
;
10280 return ((uchar) ((ASC_CHIP_MIN_VER_EISA(0x41) - 1) + revision));
10281 }
10282 return (AscGetChipVerNo(iop_base)(uchar)((__builtin_constant_p(((iop_base)+(0x03))) &&
((iop_base)+(0x03)) < 256) ? __inbc((iop_base)+(0x03)) : __inb
((iop_base)+(0x03)))
);
10283}
10284
10285ASC_INITFUNC(static ushort AscGetChipBusType( unsigned short iop_base)
10286STATIC ushortstatic ushort AscGetChipBusType( unsigned short iop_base)
10287AscGetChipBusType(static ushort AscGetChipBusType( unsigned short iop_base)
10288 PortAddr iop_basestatic ushort AscGetChipBusType( unsigned short iop_base)
10289)static ushort AscGetChipBusType( unsigned short iop_base)
10290)static ushort AscGetChipBusType( unsigned short iop_base)
10291{
10292 ushort chip_ver;
10293
10294 chip_ver = AscGetChipVerNo(iop_base)(uchar)((__builtin_constant_p(((iop_base)+(0x03))) &&
((iop_base)+(0x03)) < 256) ? __inbc((iop_base)+(0x03)) : __inb
((iop_base)+(0x03)))
;
10295 if (
10296 (chip_ver >= ASC_CHIP_MIN_VER_VL(0x01))
10297 && (chip_ver <= ASC_CHIP_MAX_VER_VL(0x07))
10298) {
10299 if (
10300 ((iop_base & 0x0C30) == 0x0C30)
10301 || ((iop_base & 0x0C50) == 0x0C50)
10302) {
10303 return (ASC_IS_EISA(0x0002));
10304 }
10305 return (ASC_IS_VL(0x0040));
10306 }
10307 if ((chip_ver >= ASC_CHIP_MIN_VER_ISA(0x11)) &&
10308 (chip_ver <= ASC_CHIP_MAX_VER_ISA(0x27))) {
10309 if (chip_ver >= ASC_CHIP_MIN_VER_ISA_PNP(0x21)) {
10310 return (ASC_IS_ISAPNP(0x0081));
10311 }
10312 return (ASC_IS_ISA(0x0001));
10313 } else if ((chip_ver >= ASC_CHIP_MIN_VER_PCI(0x09)) &&
10314 (chip_ver <= ASC_CHIP_MAX_VER_PCI(0x0F))) {
10315 return (ASC_IS_PCI(0x0004));
10316 }
10317 return (0);
10318}
10319
10320ASC_INITFUNC(static ulong AscLoadMicroCode( unsigned short iop_base, ushort
s_addr, ushort *mcode_buf, ushort mcode_size)
10321STATIC ulongstatic ulong AscLoadMicroCode( unsigned short iop_base, ushort
s_addr, ushort *mcode_buf, ushort mcode_size)
10322AscLoadMicroCode(static ulong AscLoadMicroCode( unsigned short iop_base, ushort
s_addr, ushort *mcode_buf, ushort mcode_size)
10323 PortAddr iop_base,static ulong AscLoadMicroCode( unsigned short iop_base, ushort
s_addr, ushort *mcode_buf, ushort mcode_size)
10324 ushort s_addr,static ulong AscLoadMicroCode( unsigned short iop_base, ushort
s_addr, ushort *mcode_buf, ushort mcode_size)
10325 ushort *mcode_buf,static ulong AscLoadMicroCode( unsigned short iop_base, ushort
s_addr, ushort *mcode_buf, ushort mcode_size)
10326 ushort mcode_sizestatic ulong AscLoadMicroCode( unsigned short iop_base, ushort
s_addr, ushort *mcode_buf, ushort mcode_size)
10327)static ulong AscLoadMicroCode( unsigned short iop_base, ushort
s_addr, ushort *mcode_buf, ushort mcode_size)
10328)static ulong AscLoadMicroCode( unsigned short iop_base, ushort
s_addr, ushort *mcode_buf, ushort mcode_size)
10329{
10330 ulong chksum;
10331 ushort mcode_word_size;
10332 ushort mcode_chksum;
10333
10334 mcode_word_size = (ushort) (mcode_size >> 1);
10335 AscMemWordSetLram(iop_base, s_addr, 0, mcode_word_size);
10336 AscMemWordCopyToLram(iop_base, s_addr, mcode_buf, mcode_word_size);
10337 chksum = AscMemSumLramWord(iop_base, s_addr, mcode_word_size);
10338 mcode_chksum = (ushort) AscMemSumLramWord(iop_base,
10339 (ushort) ASC_CODE_SEC_BEG(ushort)0x0080,
10340 (ushort) ((mcode_size - s_addr - (ushort) ASC_CODE_SEC_BEG(ushort)0x0080) / 2));
10341 AscWriteLramWord(iop_base, ASCV_MCODE_CHKSUM_W(ushort)0x0032, mcode_chksum);
10342 AscWriteLramWord(iop_base, ASCV_MCODE_SIZE_W(ushort)0x0034, mcode_size);
10343 return (chksum);
10344}
10345
10346ASC_INITFUNC(static int AscFindSignature( unsigned short iop_base)
10347STATIC intstatic int AscFindSignature( unsigned short iop_base)
10348AscFindSignature(static int AscFindSignature( unsigned short iop_base)
10349 PortAddr iop_basestatic int AscFindSignature( unsigned short iop_base)
10350)static int AscFindSignature( unsigned short iop_base)
10351)static int AscFindSignature( unsigned short iop_base)
10352{
10353 ushort sig_word;
10354
10355 if (AscGetChipSignatureByte(iop_base)(uchar)((__builtin_constant_p(((iop_base)+(0x01))) &&
((iop_base)+(0x01)) < 256) ? __inbc((iop_base)+(0x01)) : __inb
((iop_base)+(0x01)))
== (uchar) ASC_1000_ID1B0x25) {
10356 sig_word = AscGetChipSignatureWord(iop_base)(ushort)((__builtin_constant_p(((iop_base)+(0x00))) &&
((iop_base)+(0x00)) < 256) ? __inwc((iop_base)+(0x00)) : __inw
((iop_base)+(0x00)))
;
10357 if ((sig_word == (ushort) ASC_1000_ID0W0x04C1) ||
10358 (sig_word == (ushort) ASC_1000_ID0W_FIX0x00C1)) {
10359 return (1);
10360 }
10361 }
10362 return (0);
10363}
10364
10365STATICstatic uchar _isa_pnp_inited ASC_INITDATA = 0;
10366STATICstatic PortAddrunsigned short _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX11] ASC_INITDATA =
10367{
10368 0x100, ASC_IOADR_1(unsigned short)0x0110, 0x120, ASC_IOADR_2(unsigned short)0x0130, 0x140, ASC_IOADR_3(unsigned short)0x0150, ASC_IOADR_4(unsigned short)0x0190,
10369 ASC_IOADR_5(unsigned short)0x0210, ASC_IOADR_6(unsigned short)0x0230, ASC_IOADR_7(unsigned short)0x0250, ASC_IOADR_8(unsigned short)0x0330
10370};
10371
10372ASC_INITFUNC(static unsigned short AscSearchIOPortAddr( unsigned short iop_beg
, ushort bus_type)
10373STATIC PortAddrstatic unsigned short AscSearchIOPortAddr( unsigned short iop_beg
, ushort bus_type)
10374AscSearchIOPortAddr(static unsigned short AscSearchIOPortAddr( unsigned short iop_beg
, ushort bus_type)
10375 PortAddr iop_beg,static unsigned short AscSearchIOPortAddr( unsigned short iop_beg
, ushort bus_type)
10376 ushort bus_typestatic unsigned short AscSearchIOPortAddr( unsigned short iop_beg
, ushort bus_type)
10377)static unsigned short AscSearchIOPortAddr( unsigned short iop_beg
, ushort bus_type)
10378)static unsigned short AscSearchIOPortAddr( unsigned short iop_beg
, ushort bus_type)
10379{
10380 if (bus_type & ASC_IS_VL(0x0040)) {
10381 while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) {
10382 if (AscGetChipVersion(iop_beg, bus_type) <= ASC_CHIP_MAX_VER_VL(0x07)) {
10383 return (iop_beg);
10384 }
10385 }
10386 return (0);
10387 }
10388 if (bus_type & ASC_IS_ISA(0x0001)) {
10389 if (_isa_pnp_inited == 0) {
10390 AscSetISAPNPWaitForKey();
10391 _isa_pnp_inited++;
10392 }
10393 while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) {
10394 if ((AscGetChipVersion(iop_beg, bus_type) & ASC_CHIP_VER_ISA_BIT(0x30)) != 0) {
10395 return (iop_beg);
10396 }
10397 }
10398 return (0);
10399 }
10400 if (bus_type & ASC_IS_EISA(0x0002)) {
10401 if ((iop_beg = AscSearchIOPortAddrEISA(iop_beg)) != 0) {
10402 return (iop_beg);
10403 }
10404 return (0);
10405 }
10406 return (0);
10407}
10408
10409ASC_INITFUNC(static unsigned short AscSearchIOPortAddr11( unsigned short s_addr
)
10410STATIC PortAddrstatic unsigned short AscSearchIOPortAddr11( unsigned short s_addr
)
10411AscSearchIOPortAddr11(static unsigned short AscSearchIOPortAddr11( unsigned short s_addr
)
10412 PortAddr s_addrstatic unsigned short AscSearchIOPortAddr11( unsigned short s_addr
)
10413)static unsigned short AscSearchIOPortAddr11( unsigned short s_addr
)
10414)static unsigned short AscSearchIOPortAddr11( unsigned short s_addr
)
10415{
10416 int i;
10417 PortAddrunsigned short iop_base;
10418
10419 for (i = 0; i < ASC_IOADR_TABLE_MAX_IX11; i++) {
10420 if (_asc_def_iop_base[i] > s_addr) {
10421 break;
10422 }
10423 }
10424 for (; i < ASC_IOADR_TABLE_MAX_IX11; i++) {
10425 iop_base = _asc_def_iop_base[i];
10426 if (check_region(iop_base, ASC_IOADR_GAP0x10) != 0) {
10427 ASC_DBG1(1,
10428 "AscSearchIOPortAddr11: check_region() failed I/O port %x\n",
10429 iop_base);
10430 continue;
10431 }
10432 ASC_DBG1(1, "AscSearchIOPortAddr11: probing I/O port %x\n", iop_base);
10433 if (AscFindSignature(iop_base)) {
10434 return (iop_base);
10435 }
10436 }
10437 return (0);
10438}
10439
10440ASC_INITFUNC(static void AscToggleIRQAct( unsigned short iop_base)
10441STATIC voidstatic void AscToggleIRQAct( unsigned short iop_base)
10442AscToggleIRQAct(static void AscToggleIRQAct( unsigned short iop_base)
10443 PortAddr iop_basestatic void AscToggleIRQAct( unsigned short iop_base)
10444)static void AscToggleIRQAct( unsigned short iop_base)
10445)static void AscToggleIRQAct( unsigned short iop_base)
10446{
10447 AscSetChipStatus(iop_base, CIW_IRQ_ACT)((__builtin_constant_p((((iop_base)+(0x0E)))) && (((iop_base
)+(0x0E))) < 256) ? __outwc((((unsigned short)0x1000)),(((
iop_base)+(0x0E)))) : __outw((((unsigned short)0x1000)),(((iop_base
)+(0x0E)))))
;
10448 AscSetChipStatus(iop_base, 0)((__builtin_constant_p((((iop_base)+(0x0E)))) && (((iop_base
)+(0x0E))) < 256) ? __outwc(((0)),(((iop_base)+(0x0E)))) :
__outw(((0)),(((iop_base)+(0x0E)))))
;
10449 return;
10450}
10451
10452ASC_INITFUNC(static void AscSetISAPNPWaitForKey( void)
10453STATIC voidstatic void AscSetISAPNPWaitForKey( void)
10454AscSetISAPNPWaitForKey(static void AscSetISAPNPWaitForKey( void)
10455 void)static void AscSetISAPNPWaitForKey( void)
10456)static void AscSetISAPNPWaitForKey( void)
10457{
10458 outp(ASC_ISA_PNP_PORT_ADDR, 0x02)((__builtin_constant_p((((0x279)))) && (((0x279))) <
256) ? __outbc(((0x02)),(((0x279)))) : __outb(((0x02)),(((0x279
)))))
;
10459 outp(ASC_ISA_PNP_PORT_WRITE, 0x02)((__builtin_constant_p(((((0x279)+0x800)))) && ((((0x279
)+0x800))) < 256) ? __outbc(((0x02)),((((0x279)+0x800)))) :
__outb(((0x02)),((((0x279)+0x800)))))
;
10460 return;
10461}
10462
10463ASC_INITFUNC(static uchar AscGetChipIRQ( unsigned short iop_base, ushort bus_type
)
10464STATIC ucharstatic uchar AscGetChipIRQ( unsigned short iop_base, ushort bus_type
)
10465AscGetChipIRQ(static uchar AscGetChipIRQ( unsigned short iop_base, ushort bus_type
)
10466 PortAddr iop_base,static uchar AscGetChipIRQ( unsigned short iop_base, ushort bus_type
)
10467 ushort bus_typestatic uchar AscGetChipIRQ( unsigned short iop_base, ushort bus_type
)
10468)static uchar AscGetChipIRQ( unsigned short iop_base, ushort bus_type
)
10469)static uchar AscGetChipIRQ( unsigned short iop_base, ushort bus_type
)
10470{
10471 ushort cfg_lsw;
10472 uchar chip_irq;
10473
10474 if ((bus_type & ASC_IS_EISA(0x0002)) != 0) {
10475 cfg_lsw = AscGetEisaChipCfg(iop_base);
10476 chip_irq = (uchar) (((cfg_lsw >> 8) & 0x07) + 10);
10477 if ((chip_irq == 13) || (chip_irq > 15)) {
10478 return (0);
10479 }
10480 return (chip_irq);
10481 }
10482 if ((bus_type & ASC_IS_VL(0x0040)) != 0) {
10483 cfg_lsw = AscGetChipCfgLsw(iop_base)(ushort)((__builtin_constant_p(((iop_base)+(0x02))) &&
((iop_base)+(0x02)) < 256) ? __inwc((iop_base)+(0x02)) : __inw
((iop_base)+(0x02)))
;
10484 chip_irq = (uchar) (((cfg_lsw >> 2) & 0x07));
10485 if ((chip_irq == 0) ||
10486 (chip_irq == 4) ||
10487 (chip_irq == 7)) {
10488 return (0);
10489 }
10490 return ((uchar) (chip_irq + (ASC_MIN_IRQ_NO10 - 1)));
10491 }
10492 cfg_lsw = AscGetChipCfgLsw(iop_base)(ushort)((__builtin_constant_p(((iop_base)+(0x02))) &&
((iop_base)+(0x02)) < 256) ? __inwc((iop_base)+(0x02)) : __inw
((iop_base)+(0x02)))
;
10493 chip_irq = (uchar) (((cfg_lsw >> 2) & 0x03));
10494 if (chip_irq == 3)
10495 chip_irq += (uchar) 2;
10496 return ((uchar) (chip_irq + ASC_MIN_IRQ_NO10));
10497}
10498
10499ASC_INITFUNC(static uchar AscSetChipIRQ( unsigned short iop_base, uchar irq_no
, ushort bus_type)
10500STATIC ucharstatic uchar AscSetChipIRQ( unsigned short iop_base, uchar irq_no
, ushort bus_type)
10501AscSetChipIRQ(static uchar AscSetChipIRQ( unsigned short iop_base, uchar irq_no
, ushort bus_type)
10502 PortAddr iop_base,static uchar AscSetChipIRQ( unsigned short iop_base, uchar irq_no
, ushort bus_type)
10503 uchar irq_no,static uchar AscSetChipIRQ( unsigned short iop_base, uchar irq_no
, ushort bus_type)
10504 ushort bus_typestatic uchar AscSetChipIRQ( unsigned short iop_base, uchar irq_no
, ushort bus_type)
10505)static uchar AscSetChipIRQ( unsigned short iop_base, uchar irq_no
, ushort bus_type)
10506)static uchar AscSetChipIRQ( unsigned short iop_base, uchar irq_no
, ushort bus_type)
10507{
10508 ushort cfg_lsw;
10509
10510 if ((bus_type & ASC_IS_VL(0x0040)) != 0) {
10511 if (irq_no != 0) {
10512 if ((irq_no < ASC_MIN_IRQ_NO10) || (irq_no > ASC_MAX_IRQ_NO15)) {
10513 irq_no = 0;
10514 } else {
10515 irq_no -= (uchar) ((ASC_MIN_IRQ_NO10 - 1));
10516 }
10517 }
10518 cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base)(ushort)((__builtin_constant_p(((iop_base)+(0x02))) &&
((iop_base)+(0x02)) < 256) ? __inwc((iop_base)+(0x02)) : __inw
((iop_base)+(0x02)))
& 0xFFE3);
10519 cfg_lsw |= (ushort) 0x0010;
10520 AscSetChipCfgLsw(iop_base, cfg_lsw)((__builtin_constant_p((((iop_base)+(0x02)))) && (((iop_base
)+(0x02))) < 256) ? __outwc(((cfg_lsw)),(((iop_base)+(0x02
)))) : __outw(((cfg_lsw)),(((iop_base)+(0x02)))))
;
10521 AscToggleIRQAct(iop_base);
10522 cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base)(ushort)((__builtin_constant_p(((iop_base)+(0x02))) &&
((iop_base)+(0x02)) < 256) ? __inwc((iop_base)+(0x02)) : __inw
((iop_base)+(0x02)))
& 0xFFE0);
10523 cfg_lsw |= (ushort) ((irq_no & 0x07) << 2);
10524 AscSetChipCfgLsw(iop_base, cfg_lsw)((__builtin_constant_p((((iop_base)+(0x02)))) && (((iop_base
)+(0x02))) < 256) ? __outwc(((cfg_lsw)),(((iop_base)+(0x02
)))) : __outw(((cfg_lsw)),(((iop_base)+(0x02)))))
;
10525 AscToggleIRQAct(iop_base);
10526 return (AscGetChipIRQ(iop_base, bus_type));
10527 }
10528 if ((bus_type & (ASC_IS_ISA(0x0001))) != 0) {
10529 if (irq_no == 15)
10530 irq_no -= (uchar) 2;
10531 irq_no -= (uchar) ASC_MIN_IRQ_NO10;
10532 cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base)(ushort)((__builtin_constant_p(((iop_base)+(0x02))) &&
((iop_base)+(0x02)) < 256) ? __inwc((iop_base)+(0x02)) : __inw
((iop_base)+(0x02)))
& 0xFFF3);
10533 cfg_lsw |= (ushort) ((irq_no & 0x03) << 2);
10534 AscSetChipCfgLsw(iop_base, cfg_lsw)((__builtin_constant_p((((iop_base)+(0x02)))) && (((iop_base
)+(0x02))) < 256) ? __outwc(((cfg_lsw)),(((iop_base)+(0x02
)))) : __outw(((cfg_lsw)),(((iop_base)+(0x02)))))
;
10535 return (AscGetChipIRQ(iop_base, bus_type));
10536 }
10537 return (0);
10538}
10539
10540ASC_INITFUNC(static void AscEnableIsaDma( uchar dma_channel)
10541STATIC voidstatic void AscEnableIsaDma( uchar dma_channel)
10542AscEnableIsaDma(static void AscEnableIsaDma( uchar dma_channel)
10543 uchar dma_channelstatic void AscEnableIsaDma( uchar dma_channel)
10544)static void AscEnableIsaDma( uchar dma_channel)
10545)static void AscEnableIsaDma( uchar dma_channel)
10546{
10547 if (dma_channel < 4) {
10548 outp(0x000B, (ushort) (0xC0 | dma_channel))((__builtin_constant_p(((0x000B))) && ((0x000B)) <
256) ? __outbc((((ushort) (0xC0 | dma_channel))),((0x000B)))
: __outb((((ushort) (0xC0 | dma_channel))),((0x000B))))
;
10549 outp(0x000A, dma_channel)((__builtin_constant_p(((0x000A))) && ((0x000A)) <
256) ? __outbc(((dma_channel)),((0x000A))) : __outb(((dma_channel
)),((0x000A))))
;
10550 } else if (dma_channel < 8) {
10551 outp(0x00D6, (ushort) (0xC0 | (dma_channel - 4)))((__builtin_constant_p(((0x00D6))) && ((0x00D6)) <
256) ? __outbc((((ushort) (0xC0 | (dma_channel - 4)))),((0x00D6
))) : __outb((((ushort) (0xC0 | (dma_channel - 4)))),((0x00D6
))))
;
10552 outp(0x00D4, (ushort) (dma_channel - 4))((__builtin_constant_p(((0x00D4))) && ((0x00D4)) <
256) ? __outbc((((ushort) (dma_channel - 4))),((0x00D4))) : __outb
((((ushort) (dma_channel - 4))),((0x00D4))))
;
10553 }
10554 return;
10555}
10556
10557STATICstatic int
10558AscIsrChipHalted(
10559 REGregister ASC_DVC_VAR asc_ptr_type * asc_dvc
10560)
10561{
10562 EXT_MSG ext_msg;
10563 EXT_MSG out_msg;
10564 ushort halt_q_addr;
10565 int sdtr_accept;
10566 ushort int_halt_code;
10567 ASC_SCSI_BIT_ID_TYPEuchar scsi_busy;
10568 ASC_SCSI_BIT_ID_TYPEuchar target_id;
10569 PortAddrunsigned short iop_base;
10570 uchar tag_code;
10571 uchar q_status;
10572 uchar halt_qp;
10573 uchar sdtr_data;
10574 uchar target_ix;
10575 uchar q_cntl, tid_no;
10576 uchar cur_dvc_qng;
10577 uchar asyn_sdtr;
10578 uchar scsi_status;
10579 asc_board_t *boardp;
10580
10581 ASC_ASSERT(asc_dvc->drv_ptr != 0){ if (!(asc_dvc->drv_ptr != 0)) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 10581); } }
;
10582 boardp = (asc_board_t *) asc_dvc->drv_ptr;
10583
10584 iop_base = asc_dvc->iop_base;
10585 int_halt_code = AscReadLramWord(iop_base, ASCV_HALTCODE_W(ushort)0x0040);
10586
10587 halt_qp = AscReadLramByte(iop_base, ASCV_CURCDB_B(ushort)0x004D);
10588 halt_q_addr = ASC_QNO_TO_QADDR(halt_qp)(((0x4000))+((int)(halt_qp) << 6));
10589 target_ix = AscReadLramByte(iop_base,
10590 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TARGET_IX26));
10591 q_cntl = AscReadLramByte(iop_base,
10592 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL4));
10593 tid_no = ASC_TIX_TO_TID(target_ix)((target_ix) & 7);
10594 target_id = (uchar) ASC_TID_TO_TARGET_ID(tid_no)(uchar)(0x01 << (tid_no));
10595 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
10596
10597 asyn_sdtr = ASYN_SDTR_DATA_FIX_PCI_REV_AB0x41;
10598 } else {
10599 asyn_sdtr = 0;
10600 }
10601 if (int_halt_code == ASC_HALT_DISABLE_ASYN_USE_SYN_FIX(ushort)0x8300) {
10602 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
10603 AscSetChipSDTR(iop_base, 0, tid_no);
10604 boardp->sdtr_data[tid_no] = 0;
10605 }
10606 AscWriteLramWord(iop_base, ASCV_HALTCODE_W(ushort)0x0040, 0);
10607 return (0);
10608 } else if (int_halt_code == ASC_HALT_ENABLE_ASYN_USE_SYN_FIX(ushort)0x8400) {
10609 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
10610 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
10611 boardp->sdtr_data[tid_no] = asyn_sdtr;
10612 }
10613 AscWriteLramWord(iop_base, ASCV_HALTCODE_W(ushort)0x0040, 0);
10614 return (0);
10615 } else if (int_halt_code == ASC_HALT_EXTMSG_IN(ushort)0x8000) {
10616
10617 AscMemWordCopyFromLram(iop_base,
10618 ASCV_MSGIN_BEG(0x0000 +8),
10619 (ushort *) & ext_msg,
10620 (ushort) (sizeof (EXT_MSG) >> 1));
10621
10622 if (ext_msg.msg_type == MS_EXTEND0x01 &&
10623 ext_msg.msg_req == MS_SDTR_CODE0x01 &&
10624 ext_msg.msg_len == MS_SDTR_LEN0x03) {
10625 sdtr_accept = TRUE1;
10626 if ((ext_msg.req_ack_offsetu_ext_msg.sdtr.sdtr_req_ack_offset > ASC_SYN_MAX_OFFSET0x0F)) {
10627
10628 sdtr_accept = FALSE0;
10629 ext_msg.req_ack_offsetu_ext_msg.sdtr.sdtr_req_ack_offset = ASC_SYN_MAX_OFFSET0x0F;
10630 }
10631 if ((ext_msg.xfer_periodu_ext_msg.sdtr.sdtr_xfer_period <
10632 asc_dvc->sdtr_period_tbl[asc_dvc->host_init_sdtr_index]) ||
10633 (ext_msg.xfer_periodu_ext_msg.sdtr.sdtr_xfer_period >
10634 asc_dvc->sdtr_period_tbl[asc_dvc->max_sdtr_index])) {
10635 sdtr_accept = FALSE0;
10636 ext_msg.xfer_periodu_ext_msg.sdtr.sdtr_xfer_period =
10637 asc_dvc->sdtr_period_tbl[asc_dvc->host_init_sdtr_index];
10638 }
10639 if (sdtr_accept) {
10640 sdtr_data = AscCalSDTRData(asc_dvc, ext_msg.xfer_periodu_ext_msg.sdtr.sdtr_xfer_period,
10641 ext_msg.req_ack_offsetu_ext_msg.sdtr.sdtr_req_ack_offset);
10642 if ((sdtr_data == 0xFF)) {
10643
10644 q_cntl |= QC_MSG_OUT0x40;
10645 asc_dvc->init_sdtr &= ~target_id;
10646 asc_dvc->sdtr_done &= ~target_id;
10647 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
10648 boardp->sdtr_data[tid_no] = asyn_sdtr;
10649 }
10650 }
10651 if (ext_msg.req_ack_offsetu_ext_msg.sdtr.sdtr_req_ack_offset == 0) {
10652
10653 q_cntl &= ~QC_MSG_OUT0x40;
10654 asc_dvc->init_sdtr &= ~target_id;
10655 asc_dvc->sdtr_done &= ~target_id;
10656 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
10657 } else {
10658 if (sdtr_accept && (q_cntl & QC_MSG_OUT0x40)) {
10659
10660 q_cntl &= ~QC_MSG_OUT0x40;
10661 asc_dvc->sdtr_done |= target_id;
10662 asc_dvc->init_sdtr |= target_id;
10663 asc_dvc->pci_fix_asyn_xfer &= ~target_id;
10664 sdtr_data = AscCalSDTRData(asc_dvc, ext_msg.xfer_periodu_ext_msg.sdtr.sdtr_xfer_period,
10665 ext_msg.req_ack_offsetu_ext_msg.sdtr.sdtr_req_ack_offset);
10666 AscSetChipSDTR(iop_base, sdtr_data, tid_no);
10667 boardp->sdtr_data[tid_no] = sdtr_data;
10668 } else {
10669
10670 q_cntl |= QC_MSG_OUT0x40;
10671 AscMsgOutSDTR(asc_dvc,
10672 ext_msg.xfer_periodu_ext_msg.sdtr.sdtr_xfer_period,
10673 ext_msg.req_ack_offsetu_ext_msg.sdtr.sdtr_req_ack_offset);
10674 asc_dvc->pci_fix_asyn_xfer &= ~target_id;
10675 sdtr_data = AscCalSDTRData(asc_dvc, ext_msg.xfer_periodu_ext_msg.sdtr.sdtr_xfer_period,
10676 ext_msg.req_ack_offsetu_ext_msg.sdtr.sdtr_req_ack_offset);
10677 AscSetChipSDTR(iop_base, sdtr_data, tid_no);
10678 boardp->sdtr_data[tid_no] = sdtr_data;
10679 asc_dvc->sdtr_done |= target_id;
10680 asc_dvc->init_sdtr |= target_id;
10681 }
10682 }
10683
10684 AscWriteLramByte(iop_base,
10685 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL4),
10686 q_cntl);
10687 AscWriteLramWord(iop_base, ASCV_HALTCODE_W(ushort)0x0040, 0);
10688 return (0);
10689 } else if (ext_msg.msg_type == MS_EXTEND0x01 &&
10690 ext_msg.msg_req == MS_WDTR_CODE0x03 &&
10691 ext_msg.msg_len == MS_WDTR_LEN0x02) {
10692
10693 ext_msg.wdtr_widthu_ext_msg.wdtr.wdtr_width = 0;
10694 AscMemWordCopyToLram(iop_base,
10695 ASCV_MSGOUT_BEG0x0000,
10696 (ushort *) & ext_msg,
10697 (ushort) (sizeof (EXT_MSG) >> 1));
10698 q_cntl |= QC_MSG_OUT0x40;
10699 AscWriteLramByte(iop_base,
10700 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL4),
10701 q_cntl);
10702 AscWriteLramWord(iop_base, ASCV_HALTCODE_W(ushort)0x0040, 0);
10703 return (0);
10704 } else {
10705
10706 ext_msg.msg_type = M1_MSG_REJECT0x07;
10707 AscMemWordCopyToLram(iop_base,
10708 ASCV_MSGOUT_BEG0x0000,
10709 (ushort *) & ext_msg,
10710 (ushort) (sizeof (EXT_MSG) >> 1));
10711 q_cntl |= QC_MSG_OUT0x40;
10712 AscWriteLramByte(iop_base,
10713 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL4),
10714 q_cntl);
10715 AscWriteLramWord(iop_base, ASCV_HALTCODE_W(ushort)0x0040, 0);
10716 return (0);
10717 }
10718 } else if (int_halt_code == ASC_HALT_CHK_CONDITION(ushort)0x8100) {
10719
10720 q_cntl |= QC_REQ_SENSE0x80;
10721
10722 if ((asc_dvc->init_sdtr & target_id) != 0) {
10723
10724 asc_dvc->sdtr_done &= ~target_id;
10725
10726 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no)AscReadLramByte((iop_base), (ushort)((ushort)((0x0000 +8)+8)+
(ushort)tid_no)) ;
;
10727 q_cntl |= QC_MSG_OUT0x40;
10728 AscMsgOutSDTR(asc_dvc,
10729 asc_dvc->sdtr_period_tbl[(sdtr_data >> 4) &
10730 (uchar) (asc_dvc->max_sdtr_index - 1)],
10731 (uchar) (sdtr_data & (uchar) ASC_SYN_MAX_OFFSET0x0F));
10732 }
10733
10734 AscWriteLramByte(iop_base,
10735 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL4),
10736 q_cntl);
10737
10738 tag_code = AscReadLramByte(iop_base,
10739 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TAG_CODE29));
10740 tag_code &= 0xDC;
10741 if (
10742 (asc_dvc->pci_fix_asyn_xfer & target_id)
10743 && !(asc_dvc->pci_fix_asyn_xfer_always & target_id)
10744) {
10745
10746 tag_code |= (ASC_TAG_FLAG_DISABLE_DISCONNECT0x04
10747 | ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX0x08);
10748
10749 }
10750 AscWriteLramByte(iop_base,
10751 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TAG_CODE29),
10752 tag_code);
10753
10754 q_status = AscReadLramByte(iop_base,
10755 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_STATUS2));
10756 q_status |= (QS_READY0x01 | QS_BUSY0x08);
10757 AscWriteLramByte(iop_base,
10758 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_STATUS2),
10759 q_status);
10760
10761 scsi_busy = AscReadLramByte(iop_base,
10762 (ushort) ASCV_SCSIBUSY_B(ushort)0x004B);
10763 scsi_busy &= ~target_id;
10764 AscWriteLramByte(iop_base, (ushort) ASCV_SCSIBUSY_B(ushort)0x004B, scsi_busy);
10765
10766 AscWriteLramWord(iop_base, ASCV_HALTCODE_W(ushort)0x0040, 0);
10767 return (0);
10768 } else if (int_halt_code == ASC_HALT_SDTR_REJECTED(ushort)0x4000) {
10769
10770 AscMemWordCopyFromLram(iop_base,
10771 ASCV_MSGOUT_BEG0x0000,
10772 (ushort *) & out_msg,
10773 (ushort) (sizeof (EXT_MSG) >> 1));
10774
10775 if ((out_msg.msg_type == MS_EXTEND0x01) &&
10776 (out_msg.msg_len == MS_SDTR_LEN0x03) &&
10777 (out_msg.msg_req == MS_SDTR_CODE0x01)) {
10778
10779 asc_dvc->init_sdtr &= ~target_id;
10780 asc_dvc->sdtr_done &= ~target_id;
10781 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
10782 boardp->sdtr_data[tid_no] = asyn_sdtr;
10783 }
10784 q_cntl &= ~QC_MSG_OUT0x40;
10785 AscWriteLramByte(iop_base,
10786 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL4),
10787 q_cntl);
10788 AscWriteLramWord(iop_base, ASCV_HALTCODE_W(ushort)0x0040, 0);
10789 return (0);
10790 } else if (int_halt_code == ASC_HALT_SS_QUEUE_FULL(ushort)0x8200) {
10791
10792 scsi_status = AscReadLramByte(iop_base,
10793 (ushort) ((ushort) halt_q_addr + (ushort) ASC_SCSIQ_SCSI_STATUS34));
10794 cur_dvc_qng = AscReadLramByte(iop_base,
10795 (ushort) ((ushort) ASC_QADR_BEG(0x4000) + (ushort) target_ix));
10796 if ((cur_dvc_qng > 0) &&
10797 (asc_dvc->cur_dvc_qng[tid_no] > 0)) {
10798
10799 scsi_busy = AscReadLramByte(iop_base,
10800 (ushort) ASCV_SCSIBUSY_B(ushort)0x004B);
10801 scsi_busy |= target_id;
10802 AscWriteLramByte(iop_base,
10803 (ushort) ASCV_SCSIBUSY_B(ushort)0x004B, scsi_busy);
10804 asc_dvc->queue_full_or_busy |= target_id;
10805
10806 if (scsi_status == SS_QUEUE_FULL0x28) {
10807 if (cur_dvc_qng > ASC_MIN_TAGGED_CMD7) {
10808 cur_dvc_qng -= 1;
10809 asc_dvc->max_dvc_qng[tid_no] = cur_dvc_qng;
10810
10811 AscWriteLramByte(iop_base,
10812 (ushort) ((ushort) ASCV_MAX_DVC_QNG_BEG(ushort)0x0020 +
10813 (ushort) tid_no),
10814 cur_dvc_qng);
10815
10816 /*
10817 * Set the device queue depth to the number of
10818 * active requests when the QUEUE FULL condition
10819 * was encountered.
10820 */
10821 boardp->queue_full |= target_id;
10822 boardp->queue_full_cnt[tid_no] = cur_dvc_qng;
10823#if ASC_QUEUE_FLOW_CONTROL
10824 if (boardp->device[tid_no] != NULL((void *) 0) &&
10825 boardp->device[tid_no]->queue_curr_depth >
10826 cur_dvc_qng) {
10827 boardp->device[tid_no]->queue_curr_depth =
10828 cur_dvc_qng;
10829 }
10830#endif /* ASC_QUEUE_FLOW_CONTROL */
10831 }
10832 }
10833 }
10834 AscWriteLramWord(iop_base, ASCV_HALTCODE_W(ushort)0x0040, 0);
10835 return (0);
10836 }
10837 return (0);
10838}
10839
10840STATICstatic uchar
10841_AscCopyLramScsiDoneQ(
10842 PortAddrunsigned short iop_base,
10843 ushort q_addr,
10844 REGregister ASC_QDONE_INFO * scsiq,
10845 ulong max_dma_count
10846)
10847{
10848 ushort _val;
10849 uchar sg_queue_cnt;
10850
10851 DvcGetQinfo(iop_base,
10852 (ushort) (q_addr + (ushort) ASC_SCSIQ_DONE_INFO_BEG22),
10853 (ushort *) scsiq,
10854 (ushort) ((sizeof (ASC_SCSIQ_2) + sizeof (ASC_SCSIQ_3)) / 2));
10855 _val = AscReadLramWord(iop_base,
10856 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS2));
10857 scsiq->q_status = (uchar) _val;
10858 scsiq->q_no = (uchar) (_val >> 8);
10859 _val = AscReadLramWord(iop_base,
10860 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_CNTL4));
10861 scsiq->cntl = (uchar) _val;
10862 sg_queue_cnt = (uchar) (_val >> 8);
10863 _val = AscReadLramWord(iop_base,
10864 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_SENSE_LEN20));
10865 scsiq->sense_len = (uchar) _val;
10866 scsiq->extra_bytes = (uchar) (_val >> 8);
10867 scsiq->remain_bytes = AscReadLramWord(iop_base,
10868 (ushort) (q_addr + (ushort) ASC_SCSIQ_DW_REMAIN_XFER_CNT60));
10869 scsiq->remain_bytes &= max_dma_count;
10870 return (sg_queue_cnt);
10871}
10872
10873STATICstatic int
10874AscIsrQDone(
10875 REGregister ASC_DVC_VAR asc_ptr_type * asc_dvc
10876)
10877{
10878 uchar next_qp;
10879 uchar n_q_used;
10880 uchar sg_list_qp;
10881 uchar sg_queue_cnt;
10882 uchar q_cnt;
10883 uchar done_q_tail;
10884 uchar tid_no;
10885 ASC_SCSI_BIT_ID_TYPEuchar scsi_busy;
10886 ASC_SCSI_BIT_ID_TYPEuchar target_id;
10887 PortAddrunsigned short iop_base;
10888 ushort q_addr;
10889 ushort sg_q_addr;
10890 uchar cur_target_qng;
10891 ASC_QDONE_INFO scsiq_buf;
10892 REGregister ASC_QDONE_INFO *scsiq;
10893 int false_overrun;
10894 ASC_ISR_CALLBACK asc_isr_callback;
10895
10896 iop_base = asc_dvc->iop_base;
10897 asc_isr_callback = (ASC_ISR_CALLBACK) asc_dvc->isr_callback;
10898 n_q_used = 1;
10899 scsiq = (ASC_QDONE_INFO *) & scsiq_buf;
10900 done_q_tail = (uchar) AscGetVarDoneQTail(iop_base)AscReadLramWord((iop_base), (ushort)0x005A);
10901 q_addr = ASC_QNO_TO_QADDR(done_q_tail)(((0x4000))+((int)(done_q_tail) << 6));
10902 next_qp = AscReadLramByte(iop_base,
10903 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_FWD0));
10904 if (next_qp != ASC_QLINK_END0xFF) {
10905 AscPutVarDoneQTail(iop_base, next_qp)AscWriteLramWord((iop_base), (ushort)0x005A, next_qp);
10906 q_addr = ASC_QNO_TO_QADDR(next_qp)(((0x4000))+((int)(next_qp) << 6));
10907 sg_queue_cnt = _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq,
10908 asc_dvc->max_dma_count);
10909 AscWriteLramByte(iop_base,
10910 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS2),
10911 (uchar) (scsiq->q_status & (uchar) ~ (QS_READY0x01 | QS_ABORTED0x40)));
10912 tid_no = ASC_TIX_TO_TID(scsiq->d2.target_ix)((scsiq->d2.target_ix) & 7);
10913 target_id = ASC_TIX_TO_TARGET_ID(scsiq->d2.target_ix)(0x01 << ((scsiq->d2.target_ix) & 7));
10914 if ((scsiq->cntl & QC_SG_HEAD0x04) != 0) {
10915 sg_q_addr = q_addr;
10916 sg_list_qp = next_qp;
10917 for (q_cnt = 0; q_cnt < sg_queue_cnt; q_cnt++) {
10918 sg_list_qp = AscReadLramByte(iop_base,
10919 (ushort) (sg_q_addr + (ushort) ASC_SCSIQ_B_FWD0));
10920 sg_q_addr = ASC_QNO_TO_QADDR(sg_list_qp)(((0x4000))+((int)(sg_list_qp) << 6));
10921 if (sg_list_qp == ASC_QLINK_END0xFF) {
10922 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SG_Q_LINKS0x18);
10923 scsiq->d3.done_stat = QD_WITH_ERROR0x04;
10924 scsiq->d3.host_stat = QHSTA_D_QDONE_SG_LIST_CORRUPTED0x21;
10925 goto FATAL_ERR_QDONE;
10926 }
10927 AscWriteLramByte(iop_base,
10928 (ushort) (sg_q_addr + (ushort) ASC_SCSIQ_B_STATUS2),
10929 QS_FREE0x00);
10930 }
10931 n_q_used = sg_queue_cnt + 1;
10932 AscPutVarDoneQTail(iop_base, sg_list_qp)AscWriteLramWord((iop_base), (ushort)0x005A, sg_list_qp);
10933 }
10934 if (asc_dvc->queue_full_or_busy & target_id) {
10935 cur_target_qng = AscReadLramByte(iop_base,
10936 (ushort) ((ushort) ASC_QADR_BEG(0x4000) + (ushort) scsiq->d2.target_ix));
10937 if (cur_target_qng < asc_dvc->max_dvc_qng[tid_no]) {
10938 scsi_busy = AscReadLramByte(iop_base,
10939 (ushort) ASCV_SCSIBUSY_B(ushort)0x004B);
10940 scsi_busy &= ~target_id;
10941 AscWriteLramByte(iop_base,
10942 (ushort) ASCV_SCSIBUSY_B(ushort)0x004B, scsi_busy);
10943 asc_dvc->queue_full_or_busy &= ~target_id;
10944 }
10945 }
10946 if (asc_dvc->cur_total_qng >= n_q_used) {
10947 asc_dvc->cur_total_qng -= n_q_used;
10948 if (asc_dvc->cur_dvc_qng[tid_no] != 0) {
10949 asc_dvc->cur_dvc_qng[tid_no]--;
10950 }
10951 } else {
10952 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CUR_QNG0x17);
10953 scsiq->d3.done_stat = QD_WITH_ERROR0x04;
10954 goto FATAL_ERR_QDONE;
10955 }
10956 if ((scsiq->d2.srb_ptr == 0UL) ||
10957 ((scsiq->q_status & QS_ABORTED0x40) != 0)) {
10958 return (0x11);
10959 } else if (scsiq->q_status == QS_DONE0x80) {
10960 false_overrun = FALSE0;
10961 if (scsiq->extra_bytes != 0) {
10962 scsiq->remain_bytes += (ulong) scsiq->extra_bytes;
10963 }
10964 if (scsiq->d3.done_stat == QD_WITH_ERROR0x04) {
10965 if (scsiq->d3.host_stat == QHSTA_M_DATA_OVER_RUN0x12) {
10966 if ((scsiq->cntl & (QC_DATA_IN0x08 | QC_DATA_OUT0x10)) == 0) {
10967 scsiq->d3.done_stat = QD_NO_ERROR0x01;
10968 scsiq->d3.host_stat = QHSTA_NO_ERROR0x00;
10969 } else if (false_overrun) {
10970 scsiq->d3.done_stat = QD_NO_ERROR0x01;
10971 scsiq->d3.host_stat = QHSTA_NO_ERROR0x00;
10972 }
10973 } else if (scsiq->d3.host_stat ==
10974 QHSTA_M_HUNG_REQ_SCSI_BUS_RESET0x48) {
10975 AscStopChip(iop_base);
10976 AscSetChipControl(iop_base,((__builtin_constant_p((((iop_base)+(0x0F)))) && (((iop_base
)+(0x0F))) < 256) ? __outbc((((uchar) ((uchar)0x40 | (uchar
)0x20))),(((iop_base)+(0x0F)))) : __outb((((uchar) ((uchar)0x40
| (uchar)0x20))),(((iop_base)+(0x0F)))))
10977 (uchar) (CC_SCSI_RESET | CC_HALT))((__builtin_constant_p((((iop_base)+(0x0F)))) && (((iop_base
)+(0x0F))) < 256) ? __outbc((((uchar) ((uchar)0x40 | (uchar
)0x20))),(((iop_base)+(0x0F)))) : __outb((((uchar) ((uchar)0x40
| (uchar)0x20))),(((iop_base)+(0x0F)))))
;
10978 DvcDelayNanoSecond(asc_dvc, 60000);
10979 AscSetChipControl(iop_base, CC_HALT)((__builtin_constant_p((((iop_base)+(0x0F)))) && (((iop_base
)+(0x0F))) < 256) ? __outbc((((uchar)0x20)),(((iop_base)+(
0x0F)))) : __outb((((uchar)0x20)),(((iop_base)+(0x0F)))))
;
10980 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT)((__builtin_constant_p((((iop_base)+(0x0E)))) && (((iop_base
)+(0x0E))) < 256) ? __outwc((((unsigned short)0x1000)),(((
iop_base)+(0x0E)))) : __outw((((unsigned short)0x1000)),(((iop_base
)+(0x0E)))))
;
10981 AscSetChipStatus(iop_base, 0)((__builtin_constant_p((((iop_base)+(0x0E)))) && (((iop_base
)+(0x0E))) < 256) ? __outwc(((0)),(((iop_base)+(0x0E)))) :
__outw(((0)),(((iop_base)+(0x0E)))))
;
10982 AscSetChipControl(iop_base, 0)((__builtin_constant_p((((iop_base)+(0x0F)))) && (((iop_base
)+(0x0F))) < 256) ? __outbc(((0)),(((iop_base)+(0x0F)))) :
__outb(((0)),(((iop_base)+(0x0F)))))
;
10983 }
10984 }
10985 if ((scsiq->cntl & QC_NO_CALLBACK0x01) == 0) {
10986 (*asc_isr_callback) (asc_dvc, scsiq);
10987 } else {
10988 if ((AscReadLramByte(iop_base,
10989 (ushort) (q_addr + (ushort) ASC_SCSIQ_CDB_BEG36)) ==
10990 SCSICMD_StartStopUnit0x1B)) {
10991 asc_dvc->unit_not_ready &= ~target_id;
10992 if (scsiq->d3.done_stat != QD_NO_ERROR0x01) {
10993 asc_dvc->start_motor &= ~target_id;
10994 }
10995 }
10996 }
10997 return (1);
10998 } else {
10999 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_Q_STATUS0x0D);
11000 FATAL_ERR_QDONE:
11001 if ((scsiq->cntl & QC_NO_CALLBACK0x01) == 0) {
11002 (*asc_isr_callback) (asc_dvc, scsiq);
11003 }
11004 return (0x80);
11005 }
11006 }
11007 return (0);
11008}
11009
11010STATICstatic int
11011AscISR(
11012 REGregister ASC_DVC_VAR asc_ptr_type * asc_dvc
11013)
11014{
11015 ASC_CS_TYPEunsigned short chipstat;
11016 PortAddrunsigned short iop_base;
11017 ushort saved_ram_addr;
11018 uchar ctrl_reg;
11019 uchar saved_ctrl_reg;
11020 int int_pending;
11021 int status;
11022 uchar host_flag;
11023
11024 iop_base = asc_dvc->iop_base;
11025 int_pending = FALSE0;
11026 if (((asc_dvc->init_state & ASC_INIT_STATE_END_LOAD_MC0x0020) == 0)
11027 || (asc_dvc->isr_callback == 0)
11028) {
11029 return (ERR(-1));
11030 }
11031 if (asc_dvc->in_critical_cnt != 0) {
11032 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_ON_CRITICAL0x1C);
11033 return (ERR(-1));
11034 }
11035 if (asc_dvc->is_in_int) {
11036 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_RE_ENTRY0x1A);
11037 return (ERR(-1));
11038 }
11039 asc_dvc->is_in_int = TRUE1;
11040 ctrl_reg = AscGetChipControl(iop_base)(uchar)((__builtin_constant_p(((iop_base)+(0x0F))) &&
((iop_base)+(0x0F)) < 256) ? __inbc((iop_base)+(0x0F)) : __inb
((iop_base)+(0x0F)))
;
11041 saved_ctrl_reg = ctrl_reg & (~(CC_SCSI_RESET(uchar)0x40 | CC_CHIP_RESET(uchar)0x80 |
11042 CC_SINGLE_STEP(uchar)0x10 | CC_DIAG(uchar)0x01 | CC_TEST(uchar)0x04));
11043 chipstat = AscGetChipStatus(iop_base)(unsigned short)((__builtin_constant_p(((iop_base)+(0x0E))) &&
((iop_base)+(0x0E)) < 256) ? __inwc((iop_base)+(0x0E)) : __inw
((iop_base)+(0x0E)))
;
11044 if (chipstat & CSW_SCSI_RESET_LATCH(unsigned short)0x0002) {
11045 if (!(asc_dvc->bus_type & (ASC_IS_VL(0x0040) | ASC_IS_EISA(0x0002)))) {
11046 int_pending = TRUE1;
11047 asc_dvc->sdtr_done = 0;
11048 saved_ctrl_reg &= (uchar) (~CC_HALT(uchar)0x20);
11049 while (AscGetChipStatus(iop_base)(unsigned short)((__builtin_constant_p(((iop_base)+(0x0E))) &&
((iop_base)+(0x0E)) < 256) ? __inwc((iop_base)+(0x0E)) : __inw
((iop_base)+(0x0E)))
& CSW_SCSI_RESET_ACTIVE(unsigned short)0x0008) ;
11050 AscSetChipControl(iop_base, (CC_CHIP_RESET | CC_HALT))((__builtin_constant_p((((iop_base)+(0x0F)))) && (((iop_base
)+(0x0F))) < 256) ? __outbc(((((uchar)0x80 | (uchar)0x20))
),(((iop_base)+(0x0F)))) : __outb(((((uchar)0x80 | (uchar)0x20
))),(((iop_base)+(0x0F)))))
;
11051 AscSetChipControl(iop_base, CC_HALT)((__builtin_constant_p((((iop_base)+(0x0F)))) && (((iop_base
)+(0x0F))) < 256) ? __outbc((((uchar)0x20)),(((iop_base)+(
0x0F)))) : __outb((((uchar)0x20)),(((iop_base)+(0x0F)))))
;
11052 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT)((__builtin_constant_p((((iop_base)+(0x0E)))) && (((iop_base
)+(0x0E))) < 256) ? __outwc((((unsigned short)0x1000)),(((
iop_base)+(0x0E)))) : __outw((((unsigned short)0x1000)),(((iop_base
)+(0x0E)))))
;
11053 AscSetChipStatus(iop_base, 0)((__builtin_constant_p((((iop_base)+(0x0E)))) && (((iop_base
)+(0x0E))) < 256) ? __outwc(((0)),(((iop_base)+(0x0E)))) :
__outw(((0)),(((iop_base)+(0x0E)))))
;
11054 chipstat = AscGetChipStatus(iop_base)(unsigned short)((__builtin_constant_p(((iop_base)+(0x0E))) &&
((iop_base)+(0x0E)) < 256) ? __inwc((iop_base)+(0x0E)) : __inw
((iop_base)+(0x0E)))
;
11055 }
11056 }
11057 saved_ram_addr = AscGetChipLramAddr(iop_base)(ushort)((__builtin_constant_p(((unsigned short)((iop_base)+(
0x0A)))) && ((unsigned short)((iop_base)+(0x0A))) <
256) ? __inwc((unsigned short)((iop_base)+(0x0A))) : __inw((
unsigned short)((iop_base)+(0x0A))))
;
11058 host_flag = AscReadLramByte(iop_base,
11059 ASCV_HOST_FLAG_B(ushort)0x005D) & (uchar) (~ASC_HOST_FLAG_IN_ISR0x01);
11060 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B(ushort)0x005D,
11061 (uchar) (host_flag | (uchar) ASC_HOST_FLAG_IN_ISR0x01));
11062 if ((chipstat & CSW_INT_PENDING(unsigned short)0x0001)
11063 || (int_pending)
11064) {
11065 AscAckInterrupt(iop_base);
11066 int_pending = TRUE1;
11067 if ((chipstat & CSW_HALTED(unsigned short)0x0010) &&
11068 (ctrl_reg & CC_SINGLE_STEP(uchar)0x10)) {
11069 if (AscIsrChipHalted(asc_dvc) == ERR(-1)) {
11070 goto ISR_REPORT_QDONE_FATAL_ERROR;
11071 } else {
11072 saved_ctrl_reg &= (uchar) (~CC_HALT(uchar)0x20);
11073 }
11074 } else {
11075 ISR_REPORT_QDONE_FATAL_ERROR:
11076 if ((asc_dvc->dvc_cntl & ASC_CNTL_INT_MULTI_Q(ushort)0x0080) != 0) {
11077 while (((status = AscIsrQDone(asc_dvc)) & 0x01) != 0) {
11078 }
11079 } else {
11080 do {
11081 if ((status = AscIsrQDone(asc_dvc)) == 1) {
11082 break;
11083 }
11084 } while (status == 0x11);
11085 }
11086 if ((status & 0x80) != 0)
11087 int_pending = ERR(-1);
11088 }
11089 }
11090 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B(ushort)0x005D, host_flag);
11091 AscSetChipLramAddr(iop_base, saved_ram_addr)((__builtin_constant_p((((unsigned short)((iop_base)+(0x0A)))
)) && (((unsigned short)((iop_base)+(0x0A)))) < 256
) ? __outwc(((saved_ram_addr)),(((unsigned short)((iop_base)+
(0x0A))))) : __outw(((saved_ram_addr)),(((unsigned short)((iop_base
)+(0x0A))))))
;
11092 AscSetChipControl(iop_base, saved_ctrl_reg)((__builtin_constant_p((((iop_base)+(0x0F)))) && (((iop_base
)+(0x0F))) < 256) ? __outbc(((saved_ctrl_reg)),(((iop_base
)+(0x0F)))) : __outb(((saved_ctrl_reg)),(((iop_base)+(0x0F)))
))
;
11093 asc_dvc->is_in_int = FALSE0;
11094 return (int_pending);
11095}
11096
11097STATICstatic uchar _asc_mcode_buf[] ASC_INITDATA =
11098{
11099 0x01, 0x03, 0x01, 0x19, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11100 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11101 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11102 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11103 0x00, 0x00, 0x00, 0x00, 0x91, 0x10, 0x0A, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00,
11104 0x00, 0x00, 0x00, 0x00, 0xFF, 0x80, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11105 0x00, 0x00, 0x00, 0x23, 0x00, 0x24, 0x00, 0x00, 0x00, 0x07, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00,
11106 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE2, 0x88, 0x00, 0x00, 0x00, 0x00,
11107 0x80, 0x73, 0x48, 0x04, 0x36, 0x00, 0x00, 0xA2, 0xC2, 0x00, 0x80, 0x73, 0x03, 0x23, 0x36, 0x40,
11108 0xB6, 0x00, 0x36, 0x00, 0x05, 0xD6, 0x0C, 0xD2, 0x12, 0xDA, 0x00, 0xA2, 0xC2, 0x00, 0x92, 0x80,
11109 0x1E, 0x98, 0x50, 0x00, 0xF5, 0x00, 0x48, 0x98, 0xDF, 0x23, 0x36, 0x60, 0xB6, 0x00, 0x92, 0x80,
11110 0x4F, 0x00, 0xF5, 0x00, 0x48, 0x98, 0xEF, 0x23, 0x36, 0x60, 0xB6, 0x00, 0x92, 0x80, 0x80, 0x62,
11111 0x92, 0x80, 0x00, 0x46, 0x17, 0xEE, 0x13, 0xEA, 0x02, 0x01, 0x09, 0xD8, 0xCD, 0x04, 0x4D, 0x00,
11112 0x00, 0xA3, 0xD6, 0x00, 0xA6, 0x97, 0x7F, 0x23, 0x04, 0x61, 0x84, 0x01, 0xE6, 0x84, 0xD2, 0xC1,
11113 0x80, 0x73, 0xCD, 0x04, 0x4D, 0x00, 0x00, 0xA3, 0xE2, 0x01, 0xA6, 0x97, 0xCE, 0x81, 0x00, 0x33,
11114 0x02, 0x00, 0xC0, 0x88, 0x80, 0x73, 0x80, 0x77, 0x00, 0x01, 0x01, 0xA1, 0x02, 0x01, 0x4F, 0x00,
11115 0x84, 0x97, 0x07, 0xA6, 0x0C, 0x01, 0x00, 0x33, 0x03, 0x00, 0xC0, 0x88, 0x03, 0x03, 0x03, 0xDE,
11116 0x00, 0x33, 0x05, 0x00, 0xC0, 0x88, 0xCE, 0x00, 0x69, 0x60, 0xCE, 0x00, 0x02, 0x03, 0x4A, 0x60,
11117 0x00, 0xA2, 0x80, 0x01, 0x80, 0x63, 0x07, 0xA6, 0x2C, 0x01, 0x80, 0x81, 0x03, 0x03, 0x80, 0x63,
11118 0xE2, 0x00, 0x07, 0xA6, 0x3C, 0x01, 0x00, 0x33, 0x04, 0x00, 0xC0, 0x88, 0x03, 0x07, 0x02, 0x01,
11119 0x04, 0xCA, 0x0D, 0x23, 0x68, 0x98, 0x4D, 0x04, 0x04, 0x85, 0x05, 0xD8, 0x0D, 0x23, 0x68, 0x98,
11120 0xCD, 0x04, 0x15, 0x23, 0xF6, 0x88, 0xFB, 0x23, 0x02, 0x61, 0x82, 0x01, 0x80, 0x63, 0x02, 0x03,
11121 0x06, 0xA3, 0x6A, 0x01, 0x00, 0x33, 0x0A, 0x00, 0xC0, 0x88, 0x4E, 0x00, 0x07, 0xA3, 0x76, 0x01,
11122 0x00, 0x33, 0x0B, 0x00, 0xC0, 0x88, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33, 0x1A, 0x00, 0xC0, 0x88,
11123 0x50, 0x04, 0x90, 0x81, 0x06, 0xAB, 0x8A, 0x01, 0x90, 0x81, 0x4E, 0x00, 0x07, 0xA3, 0x9A, 0x01,
11124 0x50, 0x00, 0x00, 0xA3, 0x44, 0x01, 0x00, 0x05, 0x84, 0x81, 0x46, 0x97, 0x02, 0x01, 0x05, 0xC6,
11125 0x04, 0x23, 0xA0, 0x01, 0x15, 0x23, 0xA1, 0x01, 0xC6, 0x81, 0xFD, 0x23, 0x02, 0x61, 0x82, 0x01,
11126 0x0A, 0xDA, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA0, 0xBC, 0x01, 0x80, 0x63, 0xCD, 0x04, 0x36, 0x2D,
11127 0x00, 0x33, 0x1B, 0x00, 0xC0, 0x88, 0x06, 0x23, 0x68, 0x98, 0xCD, 0x04, 0xE6, 0x84, 0x06, 0x01,
11128 0x00, 0xA2, 0xDC, 0x01, 0x57, 0x60, 0x00, 0xA0, 0xE2, 0x01, 0xE6, 0x84, 0x80, 0x23, 0xA0, 0x01,
11129 0xE6, 0x84, 0x80, 0x73, 0x4B, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x08, 0x02, 0x04, 0x01, 0x0C, 0xDE,
11130 0x02, 0x01, 0x03, 0xCC, 0x4F, 0x00, 0x84, 0x97, 0x04, 0x82, 0x08, 0x23, 0x02, 0x41, 0x82, 0x01,
11131 0x4F, 0x00, 0x62, 0x97, 0x48, 0x04, 0x84, 0x80, 0xF0, 0x97, 0x00, 0x46, 0x56, 0x00, 0x03, 0xC0,
11132 0x01, 0x23, 0xE8, 0x00, 0x81, 0x73, 0x06, 0x29, 0x03, 0x42, 0x06, 0xE2, 0x03, 0xEE, 0x67, 0xEB,
11133 0x11, 0x23, 0xF6, 0x88, 0x04, 0x98, 0xF4, 0x80, 0x80, 0x73, 0x80, 0x77, 0x07, 0xA4, 0x32, 0x02,
11134 0x7C, 0x95, 0x06, 0xA6, 0x3C, 0x02, 0x03, 0xA6, 0x4C, 0x04, 0xC0, 0x88, 0x04, 0x01, 0x03, 0xD8,
11135 0xB2, 0x98, 0x6A, 0x96, 0x4E, 0x82, 0xFE, 0x95, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0xB6, 0x2D,
11136 0x02, 0xA6, 0x78, 0x02, 0x07, 0xA6, 0x66, 0x02, 0x06, 0xA6, 0x6A, 0x02, 0x03, 0xA6, 0x6E, 0x02,
11137 0x00, 0x33, 0x10, 0x00, 0xC0, 0x88, 0x7C, 0x95, 0x50, 0x82, 0x60, 0x96, 0x50, 0x82, 0x04, 0x23,
11138 0xA0, 0x01, 0x14, 0x23, 0xA1, 0x01, 0x3C, 0x84, 0x04, 0x01, 0x0C, 0xDC, 0xE0, 0x23, 0x25, 0x61,
11139 0xEF, 0x00, 0x14, 0x01, 0x4F, 0x04, 0xA8, 0x01, 0x6F, 0x00, 0xA5, 0x01, 0x03, 0x23, 0xA4, 0x01,
11140 0x06, 0x23, 0x9C, 0x01, 0x24, 0x2B, 0x1C, 0x01, 0x02, 0xA6, 0xB6, 0x02, 0x07, 0xA6, 0x66, 0x02,
11141 0x06, 0xA6, 0x6A, 0x02, 0x03, 0xA6, 0x20, 0x04, 0x01, 0xA6, 0xC0, 0x02, 0x00, 0xA6, 0xC0, 0x02,
11142 0x00, 0x33, 0x12, 0x00, 0xC0, 0x88, 0x00, 0x0E, 0x80, 0x63, 0x00, 0x43, 0x00, 0xA0, 0x98, 0x02,
11143 0x4D, 0x04, 0x04, 0x01, 0x0B, 0xDC, 0xE7, 0x23, 0x04, 0x61, 0x84, 0x01, 0x10, 0x31, 0x12, 0x35,
11144 0x14, 0x01, 0xEC, 0x00, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00, 0xF6, 0x82, 0x18, 0x23, 0x04, 0x61,
11145 0x18, 0xA0, 0xEE, 0x02, 0x04, 0x01, 0x9C, 0xC8, 0x00, 0x33, 0x1F, 0x00, 0xC0, 0x88, 0x08, 0x31,
11146 0x0A, 0x35, 0x0C, 0x39, 0x0E, 0x3D, 0x7E, 0x98, 0xB6, 0x2D, 0x01, 0xA6, 0x20, 0x03, 0x00, 0xA6,
11147 0x20, 0x03, 0x07, 0xA6, 0x18, 0x03, 0x06, 0xA6, 0x1C, 0x03, 0x03, 0xA6, 0x20, 0x04, 0x02, 0xA6,
11148 0x78, 0x02, 0x00, 0x33, 0x33, 0x00, 0xC0, 0x88, 0x7C, 0x95, 0xFA, 0x82, 0x60, 0x96, 0xFA, 0x82,
11149 0x82, 0x98, 0x80, 0x42, 0x7E, 0x98, 0x60, 0xE4, 0x04, 0x01, 0x29, 0xC8, 0x31, 0x05, 0x07, 0x01,
11150 0x00, 0xA2, 0x60, 0x03, 0x00, 0x43, 0x87, 0x01, 0x05, 0x05, 0x86, 0x98, 0x7E, 0x98, 0x00, 0xA6,
11151 0x22, 0x03, 0x07, 0xA6, 0x58, 0x03, 0x03, 0xA6, 0x3C, 0x04, 0x06, 0xA6, 0x5C, 0x03, 0x01, 0xA6,
11152 0x22, 0x03, 0x00, 0x33, 0x25, 0x00, 0xC0, 0x88, 0x7C, 0x95, 0x3E, 0x83, 0x60, 0x96, 0x3E, 0x83,
11153 0x04, 0x01, 0x0C, 0xCE, 0x03, 0xC8, 0x00, 0x33, 0x42, 0x00, 0xC0, 0x88, 0x00, 0x01, 0x05, 0x05,
11154 0xFF, 0xA2, 0x7E, 0x03, 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x3A, 0x83, 0x05, 0x05, 0x15, 0x01,
11155 0x00, 0xA2, 0x9E, 0x03, 0xEC, 0x00, 0x6E, 0x00, 0x95, 0x01, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00,
11156 0x01, 0xA6, 0x9A, 0x03, 0x00, 0xA6, 0x9A, 0x03, 0x12, 0x84, 0x80, 0x42, 0x7E, 0x98, 0x01, 0xA6,
11157 0xA8, 0x03, 0x00, 0xA6, 0xC0, 0x03, 0x12, 0x84, 0xA6, 0x98, 0x80, 0x42, 0x01, 0xA6, 0xA8, 0x03,
11158 0x07, 0xA6, 0xB6, 0x03, 0xD8, 0x83, 0x7C, 0x95, 0xAC, 0x83, 0x00, 0x33, 0x2F, 0x00, 0xC0, 0x88,
11159 0xA6, 0x98, 0x80, 0x42, 0x00, 0xA6, 0xC0, 0x03, 0x07, 0xA6, 0xCE, 0x03, 0xD8, 0x83, 0x7C, 0x95,
11160 0xC4, 0x83, 0x00, 0x33, 0x26, 0x00, 0xC0, 0x88, 0x38, 0x2B, 0x80, 0x32, 0x80, 0x36, 0x04, 0x23,
11161 0xA0, 0x01, 0x12, 0x23, 0xA1, 0x01, 0x12, 0x84, 0x06, 0xF0, 0x06, 0xA4, 0xF6, 0x03, 0x80, 0x6B,
11162 0x05, 0x23, 0x83, 0x03, 0x80, 0x63, 0x03, 0xA6, 0x10, 0x04, 0x07, 0xA6, 0x08, 0x04, 0x06, 0xA6,
11163 0x0C, 0x04, 0x00, 0x33, 0x17, 0x00, 0xC0, 0x88, 0x7C, 0x95, 0xF6, 0x83, 0x60, 0x96, 0xF6, 0x83,
11164 0x20, 0x84, 0x06, 0xF0, 0x06, 0xA4, 0x20, 0x04, 0x80, 0x6B, 0x05, 0x23, 0x83, 0x03, 0x80, 0x63,
11165 0xB6, 0x2D, 0x03, 0xA6, 0x3C, 0x04, 0x07, 0xA6, 0x34, 0x04, 0x06, 0xA6, 0x38, 0x04, 0x00, 0x33,
11166 0x30, 0x00, 0xC0, 0x88, 0x7C, 0x95, 0x20, 0x84, 0x60, 0x96, 0x20, 0x84, 0x1D, 0x01, 0x06, 0xCC,
11167 0x00, 0x33, 0x00, 0x84, 0xC0, 0x20, 0x00, 0x23, 0xEA, 0x00, 0x81, 0x62, 0xA2, 0x0D, 0x80, 0x63,
11168 0x07, 0xA6, 0x5A, 0x04, 0x00, 0x33, 0x18, 0x00, 0xC0, 0x88, 0x03, 0x03, 0x80, 0x63, 0xA3, 0x01,
11169 0x07, 0xA4, 0x64, 0x04, 0x23, 0x01, 0x00, 0xA2, 0x86, 0x04, 0x0A, 0xA0, 0x76, 0x04, 0xE0, 0x00,
11170 0x00, 0x33, 0x1D, 0x00, 0xC0, 0x88, 0x0B, 0xA0, 0x82, 0x04, 0xE0, 0x00, 0x00, 0x33, 0x1E, 0x00,
11171 0xC0, 0x88, 0x42, 0x23, 0xF6, 0x88, 0x00, 0x23, 0x22, 0xA3, 0xE6, 0x04, 0x08, 0x23, 0x22, 0xA3,
11172 0xA2, 0x04, 0x28, 0x23, 0x22, 0xA3, 0xAE, 0x04, 0x02, 0x23, 0x22, 0xA3, 0xC4, 0x04, 0x42, 0x23,
11173 0xF6, 0x88, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA0, 0xAE, 0x04, 0x45, 0x23, 0xF6, 0x88, 0x04, 0x98,
11174 0x00, 0xA2, 0xC0, 0x04, 0xB2, 0x98, 0x00, 0x33, 0x00, 0x82, 0xC0, 0x20, 0x81, 0x62, 0xF0, 0x81,
11175 0x47, 0x23, 0xF6, 0x88, 0x04, 0x01, 0x0B, 0xDE, 0x04, 0x98, 0xB2, 0x98, 0x00, 0x33, 0x00, 0x81,
11176 0xC0, 0x20, 0x81, 0x62, 0x14, 0x01, 0x00, 0xA0, 0x08, 0x02, 0x43, 0x23, 0xF6, 0x88, 0x04, 0x23,
11177 0xA0, 0x01, 0x44, 0x23, 0xA1, 0x01, 0x80, 0x73, 0x4D, 0x00, 0x03, 0xA3, 0xF4, 0x04, 0x00, 0x33,
11178 0x27, 0x00, 0xC0, 0x88, 0x04, 0x01, 0x04, 0xDC, 0x02, 0x23, 0xA2, 0x01, 0x04, 0x23, 0xA0, 0x01,
11179 0x04, 0x98, 0x26, 0x95, 0x4B, 0x00, 0xF6, 0x00, 0x4F, 0x04, 0x4F, 0x00, 0x00, 0xA3, 0x22, 0x05,
11180 0x00, 0x05, 0x76, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x1C, 0x05, 0x0A, 0x85, 0x46, 0x97, 0xCD, 0x04,
11181 0x24, 0x85, 0x48, 0x04, 0x84, 0x80, 0x02, 0x01, 0x03, 0xDA, 0x80, 0x23, 0x82, 0x01, 0x34, 0x85,
11182 0x02, 0x23, 0xA0, 0x01, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x40, 0x05, 0x1D, 0x01, 0x04, 0xD6,
11183 0xFF, 0x23, 0x86, 0x41, 0x4B, 0x60, 0xCB, 0x00, 0xFF, 0x23, 0x80, 0x01, 0x49, 0x00, 0x81, 0x01,
11184 0x04, 0x01, 0x02, 0xC8, 0x30, 0x01, 0x80, 0x01, 0xF7, 0x04, 0x03, 0x01, 0x49, 0x04, 0x80, 0x01,
11185 0xC9, 0x00, 0x00, 0x05, 0x00, 0x01, 0xFF, 0xA0, 0x60, 0x05, 0x77, 0x04, 0x01, 0x23, 0xEA, 0x00,
11186 0x5D, 0x00, 0xFE, 0xC7, 0x00, 0x62, 0x00, 0x23, 0xEA, 0x00, 0x00, 0x63, 0x07, 0xA4, 0xF8, 0x05,
11187 0x03, 0x03, 0x02, 0xA0, 0x8E, 0x05, 0xF4, 0x85, 0x00, 0x33, 0x2D, 0x00, 0xC0, 0x88, 0x04, 0xA0,
11188 0xB8, 0x05, 0x80, 0x63, 0x00, 0x23, 0xDF, 0x00, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0xA4, 0x05,
11189 0x1D, 0x01, 0x06, 0xD6, 0x02, 0x23, 0x02, 0x41, 0x82, 0x01, 0x50, 0x00, 0x62, 0x97, 0x04, 0x85,
11190 0x04, 0x23, 0x02, 0x41, 0x82, 0x01, 0x04, 0x85, 0x08, 0xA0, 0xBE, 0x05, 0xF4, 0x85, 0x03, 0xA0,
11191 0xC4, 0x05, 0xF4, 0x85, 0x01, 0xA0, 0xCE, 0x05, 0x88, 0x00, 0x80, 0x63, 0xCC, 0x86, 0x07, 0xA0,
11192 0xEE, 0x05, 0x5F, 0x00, 0x00, 0x2B, 0xDF, 0x08, 0x00, 0xA2, 0xE6, 0x05, 0x80, 0x67, 0x80, 0x63,
11193 0x01, 0xA2, 0x7A, 0x06, 0x7C, 0x85, 0x06, 0x23, 0x68, 0x98, 0x48, 0x23, 0xF6, 0x88, 0x07, 0x23,
11194 0x80, 0x00, 0x06, 0x87, 0x80, 0x63, 0x7C, 0x85, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63, 0x4A, 0x00,
11195 0x06, 0x61, 0x00, 0xA2, 0x36, 0x06, 0x1D, 0x01, 0x16, 0xD4, 0xC0, 0x23, 0x07, 0x41, 0x83, 0x03,
11196 0x80, 0x63, 0x06, 0xA6, 0x1C, 0x06, 0x00, 0x33, 0x37, 0x00, 0xC0, 0x88, 0x1D, 0x01, 0x01, 0xD6,
11197 0x20, 0x23, 0x63, 0x60, 0x83, 0x03, 0x80, 0x63, 0x02, 0x23, 0xDF, 0x00, 0x07, 0xA6, 0x7C, 0x05,
11198 0xEF, 0x04, 0x6F, 0x00, 0x00, 0x63, 0x4B, 0x00, 0x06, 0x41, 0xCB, 0x00, 0x52, 0x00, 0x06, 0x61,
11199 0x00, 0xA2, 0x4E, 0x06, 0x1D, 0x01, 0x03, 0xCA, 0xC0, 0x23, 0x07, 0x41, 0x00, 0x63, 0x1D, 0x01,
11200 0x04, 0xCC, 0x00, 0x33, 0x00, 0x83, 0xC0, 0x20, 0x81, 0x62, 0x80, 0x23, 0x07, 0x41, 0x00, 0x63,
11201 0x80, 0x67, 0x08, 0x23, 0x83, 0x03, 0x80, 0x63, 0x00, 0x63, 0x01, 0x23, 0xDF, 0x00, 0x06, 0xA6,
11202 0x84, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67, 0x80, 0x63, 0x00, 0x33, 0x00, 0x40, 0xC0, 0x20,
11203 0x81, 0x62, 0x00, 0x63, 0x00, 0x00, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6, 0x94, 0x06,
11204 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x00, 0x01, 0xA0, 0x14, 0x07, 0x00, 0x2B, 0x40, 0x0E, 0x80, 0x63,
11205 0x01, 0x00, 0x06, 0xA6, 0xAA, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x40, 0x0E, 0x80, 0x63, 0x00, 0x43,
11206 0x00, 0xA0, 0xA2, 0x06, 0x06, 0xA6, 0xBC, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67, 0x40, 0x0E,
11207 0x80, 0x63, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63, 0x07, 0xA6, 0xD6, 0x06,
11208 0x00, 0x33, 0x2A, 0x00, 0xC0, 0x88, 0x03, 0x03, 0x80, 0x63, 0x89, 0x00, 0x0A, 0x2B, 0x07, 0xA6,
11209 0xE8, 0x06, 0x00, 0x33, 0x29, 0x00, 0xC0, 0x88, 0x00, 0x43, 0x00, 0xA2, 0xF4, 0x06, 0xC0, 0x0E,
11210 0x80, 0x63, 0xDE, 0x86, 0xC0, 0x0E, 0x00, 0x33, 0x00, 0x80, 0xC0, 0x20, 0x81, 0x62, 0x04, 0x01,
11211 0x02, 0xDA, 0x80, 0x63, 0x7C, 0x85, 0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6, 0x8C, 0x06, 0x00, 0x33,
11212 0x2C, 0x00, 0xC0, 0x88, 0x0C, 0xA2, 0x2E, 0x07, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6,
11213 0x2C, 0x07, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x33, 0x3D, 0x00, 0xC0, 0x88, 0x00, 0x00, 0x80, 0x67,
11214 0x83, 0x03, 0x80, 0x63, 0x0C, 0xA0, 0x44, 0x07, 0x07, 0xA6, 0x7C, 0x05, 0xBF, 0x23, 0x04, 0x61,
11215 0x84, 0x01, 0xE6, 0x84, 0x00, 0x63, 0xF0, 0x04, 0x01, 0x01, 0xF1, 0x00, 0x00, 0x01, 0xF2, 0x00,
11216 0x01, 0x05, 0x80, 0x01, 0x72, 0x04, 0x71, 0x00, 0x81, 0x01, 0x70, 0x04, 0x80, 0x05, 0x81, 0x05,
11217 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x01, 0x01, 0xF1, 0x00, 0x70, 0x00, 0x81, 0x01,
11218 0x70, 0x04, 0x71, 0x00, 0x81, 0x01, 0x72, 0x00, 0x80, 0x01, 0x71, 0x04, 0x70, 0x00, 0x80, 0x01,
11219 0x70, 0x04, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x00, 0x01, 0xF1, 0x00, 0x70, 0x00,
11220 0x80, 0x01, 0x70, 0x04, 0x71, 0x00, 0x80, 0x01, 0x72, 0x00, 0x81, 0x01, 0x71, 0x04, 0x70, 0x00,
11221 0x81, 0x01, 0x70, 0x04, 0x00, 0x63, 0x00, 0x23, 0xB3, 0x01, 0x83, 0x05, 0xA3, 0x01, 0xA2, 0x01,
11222 0xA1, 0x01, 0x01, 0x23, 0xA0, 0x01, 0x00, 0x01, 0xC8, 0x00, 0x03, 0xA1, 0xC4, 0x07, 0x00, 0x33,
11223 0x07, 0x00, 0xC0, 0x88, 0x80, 0x05, 0x81, 0x05, 0x04, 0x01, 0x11, 0xC8, 0x48, 0x00, 0xB0, 0x01,
11224 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x05, 0x01, 0x48, 0x04, 0x00, 0x43, 0x00, 0xA2, 0xE4, 0x07,
11225 0x00, 0x05, 0xDA, 0x87, 0x00, 0x01, 0xC8, 0x00, 0xFF, 0x23, 0x80, 0x01, 0x05, 0x05, 0x00, 0x63,
11226 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, 0x00, 0x02, 0x80, 0x43, 0x76, 0x08, 0x80, 0x02,
11227 0x77, 0x04, 0x00, 0x63, 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, 0x00, 0x02, 0x00, 0xA0,
11228 0x14, 0x08, 0x16, 0x88, 0x00, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04, 0x00, 0x63, 0xF3, 0x04,
11229 0x00, 0x23, 0xF4, 0x00, 0x74, 0x00, 0x80, 0x43, 0xF4, 0x00, 0xCF, 0x40, 0x00, 0xA2, 0x44, 0x08,
11230 0x74, 0x04, 0x02, 0x01, 0xF7, 0xC9, 0xF6, 0xD9, 0x00, 0x01, 0x01, 0xA1, 0x24, 0x08, 0x04, 0x98,
11231 0x26, 0x95, 0x24, 0x88, 0x73, 0x04, 0x00, 0x63, 0xF3, 0x04, 0x75, 0x04, 0x5A, 0x88, 0x02, 0x01,
11232 0x04, 0xD8, 0x46, 0x97, 0x04, 0x98, 0x26, 0x95, 0x4A, 0x88, 0x75, 0x00, 0x00, 0xA3, 0x64, 0x08,
11233 0x00, 0x05, 0x4E, 0x88, 0x73, 0x04, 0x00, 0x63, 0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6, 0x76, 0x08,
11234 0x00, 0x33, 0x3E, 0x00, 0xC0, 0x88, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0x00, 0x63, 0x38, 0x2B,
11235 0x9C, 0x88, 0x38, 0x2B, 0x92, 0x88, 0x32, 0x09, 0x31, 0x05, 0x92, 0x98, 0x05, 0x05, 0xB2, 0x09,
11236 0x00, 0x63, 0x00, 0x32, 0x00, 0x36, 0x00, 0x3A, 0x00, 0x3E, 0x00, 0x63, 0x80, 0x32, 0x80, 0x36,
11237 0x80, 0x3A, 0x80, 0x3E, 0x00, 0x63, 0x38, 0x2B, 0x40, 0x32, 0x40, 0x36, 0x40, 0x3A, 0x40, 0x3E,
11238 0x00, 0x63, 0x5A, 0x20, 0xC9, 0x40, 0x00, 0xA0, 0xB2, 0x08, 0x5D, 0x00, 0xFE, 0xC3, 0x00, 0x63,
11239 0x80, 0x73, 0xE6, 0x20, 0x02, 0x23, 0xE8, 0x00, 0x82, 0x73, 0xFF, 0xFD, 0x80, 0x73, 0x13, 0x23,
11240 0xF6, 0x88, 0x66, 0x20, 0xC0, 0x20, 0x04, 0x23, 0xA0, 0x01, 0xA1, 0x23, 0xA1, 0x01, 0x81, 0x62,
11241 0xE0, 0x88, 0x80, 0x73, 0x80, 0x77, 0x68, 0x00, 0x00, 0xA2, 0x80, 0x00, 0x03, 0xC2, 0xF1, 0xC7,
11242 0x41, 0x23, 0xF6, 0x88, 0x11, 0x23, 0xA1, 0x01, 0x04, 0x23, 0xA0, 0x01, 0xE6, 0x84,
11243};
11244
11245STATICstatic ushort _asc_mcode_size ASC_INITDATA = sizeof(_asc_mcode_buf);
11246STATICstatic ulong _asc_mcode_chksum ASC_INITDATA = 0x012B5442UL;
11247
11248#define ASC_SYN_OFFSET_ONE_DISABLE_LIST16 16
11249STATICstatic uchar _syn_offset_one_disable_cmd[ASC_SYN_OFFSET_ONE_DISABLE_LIST16] =
11250{
11251 SCSICMD_Inquiry0x12,
11252 SCSICMD_RequestSense0x03,
11253 SCSICMD_ReadCapacity0x25,
11254 SCSICMD_ReadTOC0x43,
11255 SCSICMD_ModeSelect60x15,
11256 SCSICMD_ModeSense60x1A,
11257 SCSICMD_ModeSelect100x55,
11258 SCSICMD_ModeSense100x5A,
11259 0xFF,
11260 0xFF,
11261 0xFF,
11262 0xFF,
11263 0xFF,
11264 0xFF,
11265 0xFF,
11266 0xFF
11267};
11268
11269STATICstatic int
11270AscExeScsiQueue(
11271 REGregister ASC_DVC_VAR asc_ptr_type * asc_dvc,
11272 REGregister ASC_SCSI_Q * scsiq
11273)
11274{
11275 PortAddrunsigned short iop_base;
11276 int last_int_level;
11277 int sta;
11278 int n_q_required;
11279 int disable_syn_offset_one_fix;
11280 int i;
11281 ulong addr;
11282 ASC_EXE_CALLBACK asc_exe_callback;
11283 ushort sg_entry_cnt = 0;
11284 ushort sg_entry_cnt_minus_one = 0;
11285 uchar target_ix;
11286 uchar tid_no;
11287 uchar sdtr_data;
11288 uchar extra_bytes;
11289 uchar scsi_cmd;
11290 uchar disable_cmd;
11291 ASC_SG_HEAD *sg_head;
11292 ulong data_cnt;
11293
11294 iop_base = asc_dvc->iop_base;
11295 sg_head = scsiq->sg_head;
11296 asc_exe_callback = (ASC_EXE_CALLBACK) asc_dvc->exe_callback;
11297 if (asc_dvc->err_code != 0)
11298 return (ERR(-1));
11299 if (scsiq == (ASC_SCSI_Q *) 0L) {
11300 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SCSIQ_NULL_PTR0x1F);
11301 return (ERR(-1));
11302 }
11303 scsiq->q1.q_no = 0;
11304 if ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES0x10) == 0) {
11305 scsiq->q1.extra_bytes = 0;
11306 }
11307 sta = 0;
11308 target_ix = scsiq->q2.target_ix;
11309 tid_no = ASC_TIX_TO_TID(target_ix)((target_ix) & 7);
11310 n_q_required = 1;
11311 if (scsiq->cdbptr[0] == SCSICMD_RequestSense0x03) {
11312 if ((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) {
11313 asc_dvc->sdtr_done &= ~scsiq->q1.target_id ;
11314 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no)AscReadLramByte((iop_base), (ushort)((ushort)((0x0000 +8)+8)+
(ushort)tid_no)) ;
;
11315 AscMsgOutSDTR(asc_dvc,
11316 asc_dvc->sdtr_period_tbl[(sdtr_data >> 4) &
11317 (uchar) (asc_dvc->max_sdtr_index - 1)],
11318 (uchar) (sdtr_data & (uchar) ASC_SYN_MAX_OFFSET0x0F));
11319 scsiq->q1.cntl |= (QC_MSG_OUT0x40 | QC_URGENT0x20);
11320 }
11321 }
11322 last_int_level = DvcEnterCritical();
11323 if (asc_dvc->in_critical_cnt != 0) {
11324 DvcLeaveCritical(last_int_level);
11325 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CRITICAL_RE_ENTRY0x1B);
11326 return (ERR(-1));
11327 }
11328 asc_dvc->in_critical_cnt++;
11329 if ((scsiq->q1.cntl & QC_SG_HEAD0x04) != 0) {
11330 if ((sg_entry_cnt = sg_head->entry_cnt) == 0) {
11331 asc_dvc->in_critical_cnt--;
11332 DvcLeaveCritical(last_int_level);
11333 return (ERR(-1));
11334 }
11335 if (sg_entry_cnt > ASC_MAX_SG_LIST0xff) {
11336 return (ERR(-1));
11337 }
11338 if (sg_entry_cnt == 1) {
11339 scsiq->q1.data_addr = sg_head->sg_list[0].addr;
11340 scsiq->q1.data_cnt = sg_head->sg_list[0].bytes;
11341 scsiq->q1.cntl &= ~(QC_SG_HEAD0x04 | QC_SG_SWAP_QUEUE0x02);
11342 }
11343 sg_entry_cnt_minus_one = sg_entry_cnt - 1;
11344 }
11345 scsi_cmd = scsiq->cdbptr[0];
11346 disable_syn_offset_one_fix = FALSE0;
11347 if ((asc_dvc->pci_fix_asyn_xfer & scsiq->q1.target_id) &&
11348 !(asc_dvc->pci_fix_asyn_xfer_always & scsiq->q1.target_id)) {
11349 if (scsiq->q1.cntl & QC_SG_HEAD0x04) {
11350 data_cnt = 0;
11351 for (i = 0; i < sg_entry_cnt; i++) {
11352 data_cnt += sg_head->sg_list[i].bytes;
11353 }
11354 } else {
11355 data_cnt = scsiq->q1.data_cnt;
11356 }
11357 if (data_cnt != 0UL) {
11358 if (data_cnt < 512UL) {
11359 disable_syn_offset_one_fix = TRUE1;
11360 } else {
11361 for (i = 0; i < ASC_SYN_OFFSET_ONE_DISABLE_LIST16; i++) {
11362 disable_cmd = _syn_offset_one_disable_cmd[i];
11363 if (disable_cmd == 0xFF) {
11364 break;
11365 }
11366 if (scsi_cmd == disable_cmd) {
11367 disable_syn_offset_one_fix = TRUE1;
11368 break;
11369 }
11370 }
11371 }
11372 }
11373 }
11374 if (disable_syn_offset_one_fix) {
11375 scsiq->q2.tag_code &= ~M2_QTAG_MSG_SIMPLE0x20;
11376 scsiq->q2.tag_code |= (ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX0x08 |
11377 ASC_TAG_FLAG_DISABLE_DISCONNECT0x04);
11378 } else {
11379 scsiq->q2.tag_code &= 0x23;
11380 }
11381 if ((scsiq->q1.cntl & QC_SG_HEAD0x04) != 0) {
11382 if (asc_dvc->bug_fix_cntl) {
11383 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB0x0001) {
11384 if ((scsi_cmd == SCSICMD_Read60x08) ||
11385 (scsi_cmd == SCSICMD_Read100x28)) {
11386 addr = sg_head->sg_list[sg_entry_cnt_minus_one].addr +
11387 sg_head->sg_list[sg_entry_cnt_minus_one].bytes;
11388 extra_bytes = (uchar) ((ushort) addr & 0x0003);
11389 if ((extra_bytes != 0) &&
11390 ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES0x10)
11391 == 0)) {
11392 scsiq->q2.tag_code |= ASC_TAG_FLAG_EXTRA_BYTES0x10;
11393 scsiq->q1.extra_bytes = extra_bytes;
11394 sg_head->sg_list[sg_entry_cnt_minus_one].bytes -=
11395 (ulong) extra_bytes;
11396 }
11397 }
11398 }
11399 }
11400 sg_head->entry_to_copy = sg_head->entry_cnt;
11401 n_q_required = AscSgListToQueue(sg_entry_cnt);
11402 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, n_q_required) >=
11403 (uint) n_q_required) || ((scsiq->q1.cntl & QC_URGENT0x20) != 0)) {
11404 if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
11405 n_q_required)) == 1) {
11406 asc_dvc->in_critical_cnt--;
11407 if (asc_exe_callback != 0) {
11408 (*asc_exe_callback) (asc_dvc, scsiq);
11409 }
11410 DvcLeaveCritical(last_int_level);
11411 return (sta);
11412 }
11413 }
11414 } else {
11415 if (asc_dvc->bug_fix_cntl) {
11416 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB0x0001) {
11417 if ((scsi_cmd == SCSICMD_Read60x08) ||
11418 (scsi_cmd == SCSICMD_Read100x28)) {
11419 addr = scsiq->q1.data_addr + scsiq->q1.data_cnt;
11420 extra_bytes = (uchar) ((ushort) addr & 0x0003);
11421 if ((extra_bytes != 0) &&
11422 ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES0x10)
11423 == 0)) {
11424 if (((ushort) scsiq->q1.data_cnt & 0x01FF) == 0) {
11425 scsiq->q2.tag_code |= ASC_TAG_FLAG_EXTRA_BYTES0x10;
11426 scsiq->q1.data_cnt -= (ulong) extra_bytes;
11427 scsiq->q1.extra_bytes = extra_bytes;
11428 }
11429 }
11430 }
11431 }
11432 }
11433 n_q_required = 1;
11434 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, 1) >= 1) ||
11435 ((scsiq->q1.cntl & QC_URGENT0x20) != 0)) {
11436 if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
11437 n_q_required)) == 1) {
11438 asc_dvc->in_critical_cnt--;
11439 if (asc_exe_callback != 0) {
11440 (*asc_exe_callback) (asc_dvc, scsiq);
11441 }
11442 DvcLeaveCritical(last_int_level);
11443 return (sta);
11444 }
11445 }
11446 }
11447 asc_dvc->in_critical_cnt--;
11448 DvcLeaveCritical(last_int_level);
11449 return (sta);
11450}
11451
11452STATICstatic int
11453AscSendScsiQueue(
11454 REGregister ASC_DVC_VAR asc_ptr_type * asc_dvc,
11455 REGregister ASC_SCSI_Q * scsiq,
11456 uchar n_q_required
11457)
11458{
11459 PortAddrunsigned short iop_base;
11460 uchar free_q_head;
11461 uchar next_qp;
11462 uchar tid_no;
11463 uchar target_ix;
11464 int sta;
11465
11466 iop_base = asc_dvc->iop_base;
11467 target_ix = scsiq->q2.target_ix;
11468 tid_no = ASC_TIX_TO_TID(target_ix)((target_ix) & 7);
11469 sta = 0;
11470 free_q_head = (uchar) AscGetVarFreeQHead(iop_base)AscReadLramWord((iop_base), (ushort)0x0058);
11471 if (n_q_required > 1) {
11472 if ((next_qp = AscAllocMultipleFreeQueue(iop_base,
11473 free_q_head, (uchar) (n_q_required)))
11474 != (uchar) ASC_QLINK_END0xFF) {
11475 asc_dvc->last_q_shortage = 0;
11476 scsiq->sg_head->queue_cnt = n_q_required - 1;
11477 scsiq->q1.q_no = free_q_head;
11478 if ((sta = AscPutReadySgListQueue(asc_dvc, scsiq,
11479 free_q_head)) == 1) {
11480 AscPutVarFreeQHead(iop_base, next_qp)AscWriteLramWord((iop_base), (ushort)0x0058, next_qp);
11481 asc_dvc->cur_total_qng += (uchar) (n_q_required);
11482 asc_dvc->cur_dvc_qng[tid_no]++;
11483 }
11484 return (sta);
11485 }
11486 } else if (n_q_required == 1) {
11487 if ((next_qp = AscAllocFreeQueue(iop_base,
11488 free_q_head)) != ASC_QLINK_END0xFF) {
11489 scsiq->q1.q_no = free_q_head;
11490 if ((sta = AscPutReadyQueue(asc_dvc, scsiq,
11491 free_q_head)) == 1) {
11492 AscPutVarFreeQHead(iop_base, next_qp)AscWriteLramWord((iop_base), (ushort)0x0058, next_qp);
11493 asc_dvc->cur_total_qng++;
11494 asc_dvc->cur_dvc_qng[tid_no]++;
11495 }
11496 return (sta);
11497 }
11498 }
11499 return (sta);
11500}
11501
11502STATICstatic int
11503AscSgListToQueue(
11504 int sg_list
11505)
11506{
11507 int n_sg_list_qs;
11508
11509 n_sg_list_qs = ((sg_list - 1) / ASC_SG_LIST_PER_Q7);
11510 if (((sg_list - 1) % ASC_SG_LIST_PER_Q7) != 0)
11511 n_sg_list_qs++;
11512 return (n_sg_list_qs + 1);
11513}
11514
11515
11516STATICstatic uint
11517AscGetNumOfFreeQueue(
11518 REGregister ASC_DVC_VAR asc_ptr_type * asc_dvc,
11519 uchar target_ix,
11520 uchar n_qs
11521)
11522{
11523 uint cur_used_qs;
11524 uint cur_free_qs;
11525 ASC_SCSI_BIT_ID_TYPEuchar target_id;
11526 uchar tid_no;
11527
11528 target_id = ASC_TIX_TO_TARGET_ID(target_ix)(0x01 << ((target_ix) & 7));
11529 tid_no = ASC_TIX_TO_TID(target_ix)((target_ix) & 7);
11530 if ((asc_dvc->unit_not_ready & target_id) ||
11531 (asc_dvc->queue_full_or_busy & target_id)) {
11532 return (0);
11533 }
11534 if (n_qs == 1) {
11535 cur_used_qs = (uint) asc_dvc->cur_total_qng +
11536 (uint) asc_dvc->last_q_shortage +
11537 (uint) ASC_MIN_FREE_Q(0x02);
11538 } else {
11539 cur_used_qs = (uint) asc_dvc->cur_total_qng +
11540 (uint) ASC_MIN_FREE_Q(0x02);
11541 }
11542 if ((uint) (cur_used_qs + n_qs) <= (uint) asc_dvc->max_total_qng) {
11543 cur_free_qs = (uint) asc_dvc->max_total_qng - cur_used_qs;
11544 if (asc_dvc->cur_dvc_qng[tid_no] >=
11545 asc_dvc->max_dvc_qng[tid_no]) {
11546 return (0);
11547 }
11548 return (cur_free_qs);
11549 }
11550 if (n_qs > 1) {
11551 if ((n_qs > asc_dvc->last_q_shortage) && (n_qs <= (asc_dvc->max_total_qng - ASC_MIN_FREE_Q(0x02)))) {
11552 asc_dvc->last_q_shortage = n_qs;
11553 }
11554 }
11555 return (0);
11556}
11557
11558STATICstatic int
11559AscPutReadyQueue(
11560 REGregister ASC_DVC_VAR asc_ptr_type * asc_dvc,
11561 REGregister ASC_SCSI_Q * scsiq,
11562 uchar q_no
11563)
11564{
11565 ushort q_addr;
11566 uchar tid_no;
11567 uchar sdtr_data;
11568 uchar syn_period_ix;
11569 uchar syn_offset;
11570 PortAddrunsigned short iop_base;
11571
11572 iop_base = asc_dvc->iop_base;
11573 if (((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) &&
11574 ((asc_dvc->sdtr_done & scsiq->q1.target_id) == 0)) {
11575 tid_no = ASC_TIX_TO_TID(scsiq->q2.target_ix)((scsiq->q2.target_ix) & 7);
11576 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no)AscReadLramByte((iop_base), (ushort)((ushort)((0x0000 +8)+8)+
(ushort)tid_no)) ;
;
11577 syn_period_ix = (sdtr_data >> 4) & (asc_dvc->max_sdtr_index - 1);
11578 syn_offset = sdtr_data & ASC_SYN_MAX_OFFSET0x0F;
11579 AscMsgOutSDTR(asc_dvc,
11580 asc_dvc->sdtr_period_tbl[syn_period_ix],
11581 syn_offset);
11582 scsiq->q1.cntl |= QC_MSG_OUT0x40;
11583 }
11584 q_addr = ASC_QNO_TO_QADDR(q_no)(((0x4000))+((int)(q_no) << 6));
11585 if ((scsiq->q1.target_id & asc_dvc->use_tagged_qng) == 0) {
11586 scsiq->q2.tag_code &= ~M2_QTAG_MSG_SIMPLE0x20;
11587 }
11588 scsiq->q1.status = QS_FREE0x00;
11589 AscMemWordCopyToLram(iop_base,
11590 (ushort) (q_addr + (ushort) ASC_SCSIQ_CDB_BEG36),
11591 (ushort *) scsiq->cdbptr,
11592 (ushort) ((ushort) scsiq->q2.cdb_len >> 1));
11593 DvcPutScsiQ(iop_base,
11594 (ushort) (q_addr + (ushort) ASC_SCSIQ_CPY_BEG4),
11595 (ushort *) & scsiq->q1.cntl,
11596 (ushort) ((((sizeof (ASC_SCSIQ_1) + sizeof (ASC_SCSIQ_2)) / 2) - 1)));
11597 AscWriteLramWord(iop_base,
11598 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS2),
11599 (ushort) (((ushort) scsiq->q1.q_no << 8) | (ushort) QS_READY0x01));
11600 return (1);
11601}
11602
11603STATICstatic int
11604AscPutReadySgListQueue(
11605 REGregister ASC_DVC_VAR asc_ptr_type * asc_dvc,
11606 REGregister ASC_SCSI_Q * scsiq,
11607 uchar q_no
11608)
11609{
11610 int sta;
11611 int i;
11612 ASC_SG_HEAD *sg_head;
11613 ASC_SG_LIST_Q scsi_sg_q;
11614 ulong saved_data_addr;
11615 ulong saved_data_cnt;
11616 PortAddrunsigned short iop_base;
11617 ushort sg_list_dwords;
11618 ushort sg_index;
11619 ushort sg_entry_cnt;
11620 ushort q_addr;
11621 uchar next_qp;
11622
11623 iop_base = asc_dvc->iop_base;
11624 sg_head = scsiq->sg_head;
11625 saved_data_addr = scsiq->q1.data_addr;
11626 saved_data_cnt = scsiq->q1.data_cnt;
11627 scsiq->q1.data_addr = sg_head->sg_list[0].addr;
11628 scsiq->q1.data_cnt = sg_head->sg_list[0].bytes;
11629 sg_entry_cnt = sg_head->entry_cnt - 1;
11630 if (sg_entry_cnt != 0) {
11631 scsiq->q1.cntl |= QC_SG_HEAD0x04;
11632 q_addr = ASC_QNO_TO_QADDR(q_no)(((0x4000))+((int)(q_no) << 6));
11633 sg_index = 1;
11634 scsiq->q1.sg_queue_cnt = sg_head->queue_cnt;
11635 scsi_sg_q.sg_head_qp = q_no;
11636 scsi_sg_q.cntl = QCSG_SG_XFER_LIST0x02;
11637 for (i = 0; i < sg_head->queue_cnt; i++) {
11638 scsi_sg_q.seq_no = i + 1;
11639 if (sg_entry_cnt > ASC_SG_LIST_PER_Q7) {
11640 sg_list_dwords = (uchar) (ASC_SG_LIST_PER_Q7 * 2);
11641 sg_entry_cnt -= ASC_SG_LIST_PER_Q7;
11642 if (i == 0) {
11643 scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q7;
11644 scsi_sg_q.sg_cur_list_cnt = ASC_SG_LIST_PER_Q7;
11645 } else {
11646 scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q7 - 1;
11647 scsi_sg_q.sg_cur_list_cnt = ASC_SG_LIST_PER_Q7 - 1;
11648 }
11649 } else {
11650 scsi_sg_q.cntl |= QCSG_SG_XFER_END0x08;
11651 sg_list_dwords = sg_entry_cnt << 1;
11652 if (i == 0) {
11653 scsi_sg_q.sg_list_cnt = sg_entry_cnt;
11654 scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt;
11655 } else {
11656 scsi_sg_q.sg_list_cnt = sg_entry_cnt - 1;
11657 scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt - 1;
11658 }
11659 sg_entry_cnt = 0;
11660 }
11661 next_qp = AscReadLramByte(iop_base,
11662 (ushort) (q_addr + ASC_SCSIQ_B_FWD0));
11663 scsi_sg_q.q_no = next_qp;
11664 q_addr = ASC_QNO_TO_QADDR(next_qp)(((0x4000))+((int)(next_qp) << 6));
11665 AscMemWordCopyToLram(iop_base,
11666 (ushort) (q_addr + ASC_SCSIQ_SGHD_CPY_BEG2),
11667 (ushort *) & scsi_sg_q,
11668 (ushort) (sizeof (ASC_SG_LIST_Q) >> 1));
11669 AscMemDWordCopyToLram(iop_base,
11670 (ushort) (q_addr + ASC_SGQ_LIST_BEG8),
11671 (ulong *) & sg_head->sg_list[sg_index],
11672 (ushort) sg_list_dwords);
11673 sg_index += ASC_SG_LIST_PER_Q7;
11674 }
11675 } else {
11676 scsiq->q1.cntl &= ~QC_SG_HEAD0x04;
11677 }
11678 sta = AscPutReadyQueue(asc_dvc, scsiq, q_no);
11679 scsiq->q1.data_addr = saved_data_addr;
11680 scsiq->q1.data_cnt = saved_data_cnt;
11681 return (sta);
11682}
11683
11684STATICstatic int
11685AscAbortSRB(
11686 REGregister ASC_DVC_VAR asc_ptr_type * asc_dvc,
11687 ulong srb_ptr
11688)
11689{
11690 int sta;
11691 ASC_SCSI_BIT_ID_TYPEuchar saved_unit_not_ready;
11692 PortAddrunsigned short iop_base;
11693
11694 iop_base = asc_dvc->iop_base;
11695 sta = ERR(-1);
11696 saved_unit_not_ready = asc_dvc->unit_not_ready;
11697 asc_dvc->unit_not_ready = 0xFF;
11698 AscWaitISRDone(asc_dvc);
11699 if (AscStopQueueExe(iop_base) == 1) {
11700 if (AscRiscHaltedAbortSRB(asc_dvc, srb_ptr) == 1) {
11701 sta = 1;
11702 AscCleanUpBusyQueue(iop_base);
11703 AscStartQueueExe(iop_base);
11704 } else {
11705 sta = 0;
11706 AscStartQueueExe(iop_base);
11707 }
11708 }
11709 asc_dvc->unit_not_ready = saved_unit_not_ready;
11710 return (sta);
11711}
11712
11713#if LINUX_VERSION_CODE131108 >= ASC_LINUX_VERSION(1,3,89)(((1) * 65536) + ((3) * 256) + (89))
11714STATICstatic int
11715AscResetDevice(
11716 REGregister ASC_DVC_VAR asc_ptr_type * asc_dvc,
11717 uchar target_ix
11718)
11719{
11720 PortAddrunsigned short iop_base;
11721 int sta;
11722 uchar tid_no;
11723
11724 ASC_SCSI_BIT_ID_TYPEuchar target_id;
11725 int i;
11726 ASC_SCSI_REQ_Q scsiq_buf;
11727 ASC_SCSI_REQ_Q *scsiq;
11728 uchar *buf;
11729 ASC_SCSI_BIT_ID_TYPEuchar saved_unit_not_ready;
11730 iop_base = asc_dvc->iop_base;
11731 tid_no = ASC_TIX_TO_TID(target_ix)((target_ix) & 7);
11732 target_id = ASC_TID_TO_TARGET_ID(tid_no)(uchar)(0x01 << (tid_no));
11733 saved_unit_not_ready = asc_dvc->unit_not_ready;
11734 asc_dvc->unit_not_ready = target_id;
11735 sta = ERR(-1);
11736 AscWaitTixISRDone(asc_dvc, target_ix);
11737 if (AscStopQueueExe(iop_base) == 1) {
11738 if (AscRiscHaltedAbortTIX(asc_dvc, target_ix) == 1) {
11739 AscCleanUpBusyQueue(iop_base);
11740 AscStartQueueExe(iop_base);
11741 AscWaitTixISRDone(asc_dvc, target_ix);
11742 sta = TRUE1;
11743 scsiq = (ASC_SCSI_REQ_Q *) & scsiq_buf;
11744 buf = (uchar *) & scsiq_buf;
11745 for (i = 0; i < sizeof (ASC_SCSI_REQ_Q); i++) {
11746 *buf++ = 0x00;
11747 }
11748 scsiq->r1.status = (uchar) QS_READY0x01;
11749 scsiq->r2.cdb_len = 6;
11750 scsiq->r2.tag_code = M2_QTAG_MSG_SIMPLE0x20;
11751 scsiq->r1.target_id = target_id;
11752 scsiq->r2.target_ix = ASC_TIDLUN_TO_IX(tid_no, 0)(uchar)((tid_no) + ((0)<<3));
11753 scsiq->cdbptr = (uchar *) scsiq->cdb;
11754 scsiq->r1.cntl = QC_NO_CALLBACK0x01 | QC_MSG_OUT0x40 | QC_URGENT0x20;
11755 AscWriteLramByte(asc_dvc->iop_base, ASCV_MSGOUT_BEG0x0000,
11756 M1_BUS_DVC_RESET0x0C);
11757 asc_dvc->unit_not_ready &= ~target_id;
11758 asc_dvc->sdtr_done |= target_id;
11759 if (AscExeScsiQueue(asc_dvc, (ASC_SCSI_Q *) scsiq)
11760 == 1) {
11761 asc_dvc->unit_not_ready = target_id;
11762 DvcSleepMilliSecond(1000);
11763 _AscWaitQDone(iop_base, (ASC_SCSI_Q *) scsiq);
11764 if (AscStopQueueExe(iop_base) == 1) {
11765 AscCleanUpDiscQueue(iop_base);
11766 AscStartQueueExe(iop_base);
11767 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
11768 AscSetRunChipSynRegAtID(iop_base, tid_no,
11769 ASYN_SDTR_DATA_FIX_PCI_REV_AB0x41);
11770 }
11771 AscWaitTixISRDone(asc_dvc, target_ix);
11772 }
11773 } else {
11774 sta = 0;
11775 }
11776 asc_dvc->sdtr_done &= ~target_id;
11777 } else {
11778 sta = ERR(-1);
11779 AscStartQueueExe(iop_base);
11780 }
11781 }
11782 asc_dvc->unit_not_ready = saved_unit_not_ready;
11783 return (sta);
11784}
11785#endif /* version >= v1.3.89 */
11786
11787STATICstatic int
11788AscResetSB(
11789 REGregister ASC_DVC_VAR asc_ptr_type * asc_dvc
11790)
11791{
11792 int sta;
11793 int i;
11794 PortAddrunsigned short iop_base;
11795
11796 iop_base = asc_dvc->iop_base;
11797 asc_dvc->unit_not_ready = 0xFF;
11798 sta = TRUE1;
11799 AscWaitISRDone(asc_dvc);
11800 AscStopQueueExe(iop_base);
11801 asc_dvc->sdtr_done = 0;
11802 AscResetChipAndScsiBus(asc_dvc);
11803 DvcSleepMilliSecond((ulong) ((ushort) asc_dvc->scsi_reset_wait * 1000));
11804 AscReInitLram(asc_dvc);
11805 for (i = 0; i <= ASC_MAX_TID7; i++) {
11806 asc_dvc->cur_dvc_qng[i] = 0;
11807 if (asc_dvc->pci_fix_asyn_xfer & (ASC_SCSI_BIT_ID_TYPEuchar) (0x01 << i)) {
11808 AscSetChipSynRegAtID(iop_base, i, ASYN_SDTR_DATA_FIX_PCI_REV_AB0x41);
11809 }
11810 }
11811 asc_dvc->err_code = 0;
11812 AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR)((__builtin_constant_p((((iop_base)+(0x0C)))) && (((iop_base
)+(0x0C))) < 256) ? __outwc(((0x0080)),(((iop_base)+(0x0C)
))) : __outw(((0x0080)),(((iop_base)+(0x0C)))))
;
11813 if (AscGetPCAddr(iop_base)(ushort)((__builtin_constant_p(((iop_base)+(0x0C))) &&
((iop_base)+(0x0C)) < 256) ? __inwc((iop_base)+(0x0C)) : __inw
((iop_base)+(0x0C)))
!= ASC_MCODE_START_ADDR0x0080) {
11814 sta = ERR(-1);
11815 }
11816 if (AscStartChip(iop_base) == 0) {
11817 sta = ERR(-1);
11818 }
11819 AscStartQueueExe(iop_base);
11820 asc_dvc->unit_not_ready = 0;
11821 asc_dvc->queue_full_or_busy = 0;
11822 return (sta);
11823}
11824
11825STATICstatic int
11826AscSetRunChipSynRegAtID(
11827 PortAddrunsigned short iop_base,
11828 uchar tid_no,
11829 uchar sdtr_data
11830)
11831{
11832 int sta = FALSE0;
11833
11834 if (AscHostReqRiscHalt(iop_base)) {
11835 sta = AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
11836 AscStartChip(iop_base);
11837 return (sta);
11838 }
11839 return (sta);
11840}
11841
11842STATICstatic int
11843AscSetChipSynRegAtID(
11844 PortAddrunsigned short iop_base,
11845 uchar id,
11846 uchar sdtr_data
11847)
11848{
11849 ASC_SCSI_BIT_ID_TYPEuchar org_id;
11850 int i;
11851 int sta = TRUE1;
11852
11853 AscSetBank(iop_base, 1);
11854 org_id = AscReadChipDvcID(iop_base)(uchar)((__builtin_constant_p(((iop_base)+(0x05))) &&
((iop_base)+(0x05)) < 256) ? __inbc((iop_base)+(0x05)) : __inb
((iop_base)+(0x05)))
;
11855 for (i = 0; i <= ASC_MAX_TID7; i++) {
11856 if (org_id == (0x01 << i))
11857 break;
11858 }
11859 org_id = i;
11860 AscWriteChipDvcID(iop_base, id)((__builtin_constant_p((((iop_base)+(0x05)))) && (((iop_base
)+(0x05))) < 256) ? __outbc(((id)),(((iop_base)+(0x05)))) :
__outb(((id)),(((iop_base)+(0x05)))))
;
11861 if (AscReadChipDvcID(iop_base)(uchar)((__builtin_constant_p(((iop_base)+(0x05))) &&
((iop_base)+(0x05)) < 256) ? __inbc((iop_base)+(0x05)) : __inb
((iop_base)+(0x05)))
== (0x01 << id)) {
11862 AscSetBank(iop_base, 0);
11863 AscSetChipSyn(iop_base, sdtr_data)((__builtin_constant_p((((iop_base)+(0x0B)))) && (((iop_base
)+(0x0B))) < 256) ? __outbc(((sdtr_data)),(((iop_base)+(0x0B
)))) : __outb(((sdtr_data)),(((iop_base)+(0x0B)))))
;
11864 if (AscGetChipSyn(iop_base)(uchar)((__builtin_constant_p(((iop_base)+(0x0B))) &&
((iop_base)+(0x0B)) < 256) ? __inbc((iop_base)+(0x0B)) : __inb
((iop_base)+(0x0B)))
!= sdtr_data) {
11865 sta = FALSE0;
11866 }
11867 } else {
11868 sta = FALSE0;
11869 }
11870 AscSetBank(iop_base, 1);
11871 AscWriteChipDvcID(iop_base, org_id)((__builtin_constant_p((((iop_base)+(0x05)))) && (((iop_base
)+(0x05))) < 256) ? __outbc(((org_id)),(((iop_base)+(0x05)
))) : __outb(((org_id)),(((iop_base)+(0x05)))))
;
11872 AscSetBank(iop_base, 0);
11873 return (sta);
11874}
11875
11876STATICstatic int
11877AscReInitLram(
11878 REGregister ASC_DVC_VAR asc_ptr_type * asc_dvc
11879)
11880{
11881 AscInitLram(asc_dvc);
11882 AscInitQLinkVar(asc_dvc);
11883 return (0);
11884}
11885
11886STATICstatic ushort
11887AscInitLram(
11888 REGregister ASC_DVC_VAR asc_ptr_type * asc_dvc
11889)
11890{
11891 uchar i;
11892 ushort s_addr;
11893 PortAddrunsigned short iop_base;
11894 ushort warn_code;
11895
11896 iop_base = asc_dvc->iop_base;
11897 warn_code = 0;
11898 AscMemWordSetLram(iop_base, ASC_QADR_BEG(0x4000), 0,
11899 (ushort) (((int) (asc_dvc->max_total_qng + 2 + 1) * 64) >> 1)
11900);
11901 i = ASC_MIN_ACTIVE_QNO0x01;
11902 s_addr = ASC_QADR_BEG(0x4000) + ASC_QBLK_SIZE0x40;
11903 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_FWD0),
11904 (uchar) (i + 1));
11905 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_BWD1),
11906 (uchar) (asc_dvc->max_total_qng));
11907 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_QNO3),
11908 (uchar) i);
11909 i++;
11910 s_addr += ASC_QBLK_SIZE0x40;
11911 for (; i < asc_dvc->max_total_qng; i++, s_addr += ASC_QBLK_SIZE0x40) {
11912 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_FWD0),
11913 (uchar) (i + 1));
11914 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_BWD1),
11915 (uchar) (i - 1));
11916 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_QNO3),
11917 (uchar) i);
11918 }
11919 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_FWD0),
11920 (uchar) ASC_QLINK_END0xFF);
11921 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_BWD1),
11922 (uchar) (asc_dvc->max_total_qng - 1));
11923 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_QNO3),
11924 (uchar) asc_dvc->max_total_qng);
11925 i++;
11926 s_addr += ASC_QBLK_SIZE0x40;
11927 for (; i <= (uchar) (asc_dvc->max_total_qng + 3);
11928 i++, s_addr += ASC_QBLK_SIZE0x40) {
11929 AscWriteLramByte(iop_base,
11930 (ushort) (s_addr + (ushort) ASC_SCSIQ_B_FWD0), i);
11931 AscWriteLramByte(iop_base,
11932 (ushort) (s_addr + (ushort) ASC_SCSIQ_B_BWD1), i);
11933 AscWriteLramByte(iop_base,
11934 (ushort) (s_addr + (ushort) ASC_SCSIQ_B_QNO3), i);
11935 }
11936 return (warn_code);
11937}
11938
11939STATICstatic ushort
11940AscInitQLinkVar(
11941 REGregister ASC_DVC_VAR asc_ptr_type * asc_dvc
11942)
11943{
11944 PortAddrunsigned short iop_base;
11945 int i;
11946 ushort lram_addr;
11947
11948 iop_base = asc_dvc->iop_base;
11949 AscPutRiscVarFreeQHead(iop_base, 1)AscWriteLramByte((iop_base), (ushort)0x0048, 1);
11950 AscPutRiscVarDoneQTail(iop_base, asc_dvc->max_total_qng)AscWriteLramByte((iop_base), (ushort)0x0049, asc_dvc->max_total_qng
)
;
11951 AscPutVarFreeQHead(iop_base, 1)AscWriteLramWord((iop_base), (ushort)0x0058, 1);
11952 AscPutVarDoneQTail(iop_base, asc_dvc->max_total_qng)AscWriteLramWord((iop_base), (ushort)0x005A, asc_dvc->max_total_qng
)
;
11953 AscWriteLramByte(iop_base, ASCV_BUSY_QHEAD_B(ushort)0x004F,
11954 (uchar) ((int) asc_dvc->max_total_qng + 1));
11955 AscWriteLramByte(iop_base, ASCV_DISC1_QHEAD_B(ushort)0x0050,
11956 (uchar) ((int) asc_dvc->max_total_qng + 2));
11957 AscWriteLramByte(iop_base, (ushort) ASCV_TOTAL_READY_Q_B(ushort)0x0064,
11958 asc_dvc->max_total_qng);
11959 AscWriteLramWord(iop_base, ASCV_ASCDVC_ERR_CODE_W(ushort)0x0030, 0);
11960 AscWriteLramWord(iop_base, ASCV_HALTCODE_W(ushort)0x0040, 0);
11961 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B(ushort)0x0036, 0);
11962 AscWriteLramByte(iop_base, ASCV_SCSIBUSY_B(ushort)0x004B, 0);
11963 AscWriteLramByte(iop_base, ASCV_WTM_FLAG_B(ushort)0x0068, 0);
11964 AscPutQDoneInProgress(iop_base, 0)AscWriteLramByte((iop_base), (ushort)0x004C, 0);
11965 lram_addr = ASC_QADR_BEG(0x4000);
11966 for (i = 0; i < 32; i++, lram_addr += 2) {
11967 AscWriteLramWord(iop_base, lram_addr, 0);
11968 }
11969 return (0);
11970}
11971
11972STATICstatic int
11973AscSetLibErrorCode(
11974 REGregister ASC_DVC_VAR asc_ptr_type * asc_dvc,
11975 ushort err_code
11976)
11977{
11978 if (asc_dvc->err_code == 0) {
11979 asc_dvc->err_code = err_code;
11980 AscWriteLramWord(asc_dvc->iop_base, ASCV_ASCDVC_ERR_CODE_W(ushort)0x0030,
11981 err_code);
11982 }
11983 return (err_code);
11984}
11985
11986
11987#if LINUX_VERSION_CODE131108 >= ASC_LINUX_VERSION(1,3,89)(((1) * 65536) + ((3) * 256) + (89))
11988STATICstatic int
11989_AscWaitQDone(
11990 PortAddrunsigned short iop_base,
11991 REGregister ASC_SCSI_Q * scsiq
11992)
11993{
11994 ushort q_addr;
11995 uchar q_status;
11996 int count = 0;
11997
11998 while (scsiq->q1.q_no == 0) ;
11999 q_addr = ASC_QNO_TO_QADDR(scsiq->q1.q_no)(((0x4000))+((int)(scsiq->q1.q_no) << 6));
12000 do {
12001 q_status = AscReadLramByte(iop_base, q_addr + ASC_SCSIQ_B_STATUS2);
12002 DvcSleepMilliSecond(100L);
12003 if (count++ > 30) {
12004 return (0);
12005 }
12006 } while ((q_status & QS_READY0x01) != 0);
12007 return (1);
12008}
12009#endif /* version >= v1.3.89 */
12010
12011STATICstatic uchar
12012AscMsgOutSDTR(
12013 REGregister ASC_DVC_VAR asc_ptr_type * asc_dvc,
12014 uchar sdtr_period,
12015 uchar sdtr_offset
12016)
12017{
12018 EXT_MSG sdtr_buf;
12019 uchar sdtr_period_index;
12020 PortAddrunsigned short iop_base;
12021
12022 iop_base = asc_dvc->iop_base;
12023 sdtr_buf.msg_type = MS_EXTEND0x01;
12024 sdtr_buf.msg_len = MS_SDTR_LEN0x03;
12025 sdtr_buf.msg_req = MS_SDTR_CODE0x01;
12026 sdtr_buf.xfer_periodu_ext_msg.sdtr.sdtr_xfer_period = sdtr_period;
12027 sdtr_offset &= ASC_SYN_MAX_OFFSET0x0F;
12028 sdtr_buf.req_ack_offsetu_ext_msg.sdtr.sdtr_req_ack_offset = sdtr_offset;
12029 if ((sdtr_period_index =
12030 AscGetSynPeriodIndex(asc_dvc, sdtr_period)) <=
12031 asc_dvc->max_sdtr_index) {
12032 AscMemWordCopyToLram(iop_base,
12033 ASCV_MSGOUT_BEG0x0000,
12034 (ushort *) & sdtr_buf,
12035 (ushort) (sizeof (EXT_MSG) >> 1));
12036 return ((sdtr_period_index << 4) | sdtr_offset);
12037 } else {
12038
12039 sdtr_buf.req_ack_offsetu_ext_msg.sdtr.sdtr_req_ack_offset = 0;
12040 AscMemWordCopyToLram(iop_base,
12041 ASCV_MSGOUT_BEG0x0000,
12042 (ushort *) & sdtr_buf,
12043 (ushort) (sizeof (EXT_MSG) >> 1));
12044 return (0);
12045 }
12046}
12047
12048STATICstatic uchar
12049AscCalSDTRData(
12050 REGregister ASC_DVC_VAR asc_ptr_type * asc_dvc,
12051 uchar sdtr_period,
12052 uchar syn_offset
12053)
12054{
12055 uchar byte;
12056 uchar sdtr_period_ix;
12057
12058 sdtr_period_ix = AscGetSynPeriodIndex(asc_dvc, sdtr_period);
12059 if (
12060 (sdtr_period_ix > asc_dvc->max_sdtr_index)
12061) {
12062 return (0xFF);
12063 }
12064 byte = (sdtr_period_ix << 4) | (syn_offset & ASC_SYN_MAX_OFFSET0x0F);
12065 return (byte);
12066}
12067
12068STATICstatic void
12069AscSetChipSDTR(
12070 PortAddrunsigned short iop_base,
12071 uchar sdtr_data,
12072 uchar tid_no
12073)
12074{
12075 AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
12076 AscPutMCodeSDTRDoneAtID(iop_base, tid_no, sdtr_data)AscWriteLramByte((iop_base), (ushort)((ushort)(((0x0000 +8)+8
)+8)+(ushort)tid_no), (sdtr_data)) ;
;
12077 return;
12078}
12079
12080STATICstatic uchar
12081AscGetSynPeriodIndex(
12082 ASC_DVC_VAR asc_ptr_type * asc_dvc,
12083 rucharregister __u8 syn_time
12084)
12085{
12086 rucharregister __u8 *period_table;
12087 int max_index;
12088 int min_index;
12089 int i;
12090
12091 period_table = asc_dvc->sdtr_period_tbl;
12092 max_index = (int) asc_dvc->max_sdtr_index;
12093 min_index = (int)asc_dvc->host_init_sdtr_index ;
12094 if ((syn_time <= period_table[max_index])) {
12095 for (i = min_index; i < (max_index - 1); i++) {
12096 if (syn_time <= period_table[i]) {
12097 return ((uchar) i);
12098 }
12099 }
12100 return ((uchar) max_index);
12101 } else {
12102 return ((uchar) (max_index + 1));
12103 }
12104}
12105
12106STATICstatic uchar
12107AscAllocFreeQueue(
12108 PortAddrunsigned short iop_base,
12109 uchar free_q_head
12110)
12111{
12112 ushort q_addr;
12113 uchar next_qp;
12114 uchar q_status;
12115
12116 q_addr = ASC_QNO_TO_QADDR(free_q_head)(((0x4000))+((int)(free_q_head) << 6));
12117 q_status = (uchar) AscReadLramByte(iop_base,
12118 (ushort) (q_addr + ASC_SCSIQ_B_STATUS2));
12119 next_qp = AscReadLramByte(iop_base,
12120 (ushort) (q_addr + ASC_SCSIQ_B_FWD0));
12121 if (((q_status & QS_READY0x01) == 0) && (next_qp != ASC_QLINK_END0xFF)) {
12122 return (next_qp);
12123 }
12124 return (ASC_QLINK_END0xFF);
12125}
12126
12127STATICstatic uchar
12128AscAllocMultipleFreeQueue(
12129 PortAddrunsigned short iop_base,
12130 uchar free_q_head,
12131 uchar n_free_q
12132)
12133{
12134 uchar i;
12135
12136 for (i = 0; i < n_free_q; i++) {
12137 if ((free_q_head = AscAllocFreeQueue(iop_base, free_q_head))
12138 == ASC_QLINK_END0xFF) {
12139 return (ASC_QLINK_END0xFF);
12140 }
12141 }
12142 return (free_q_head);
12143}
12144
12145STATICstatic int
12146AscRiscHaltedAbortSRB(
12147 REGregister ASC_DVC_VAR asc_ptr_type * asc_dvc,
12148 ulong srb_ptr
12149)
12150{
12151 PortAddrunsigned short iop_base;
12152 ushort q_addr;
12153 uchar q_no;
12154 ASC_QDONE_INFO scsiq_buf;
12155 ASC_QDONE_INFO *scsiq;
12156 ASC_ISR_CALLBACK asc_isr_callback;
12157 int last_int_level;
12158
12159 iop_base = asc_dvc->iop_base;
12160 asc_isr_callback = (ASC_ISR_CALLBACK) asc_dvc->isr_callback;
12161 last_int_level = DvcEnterCritical();
12162 scsiq = (ASC_QDONE_INFO *) & scsiq_buf;
12163 for (q_no = ASC_MIN_ACTIVE_QNO0x01; q_no <= asc_dvc->max_total_qng;
12164 q_no++) {
12165 q_addr = ASC_QNO_TO_QADDR(q_no)(((0x4000))+((int)(q_no) << 6));
12166 scsiq->d2.srb_ptr = AscReadLramDWord(iop_base,
12167 (ushort) (q_addr + (ushort) ASC_SCSIQ_D_SRBPTR22));
12168 if (scsiq->d2.srb_ptr == srb_ptr) {
12169 _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq, asc_dvc->max_dma_count);
12170 if (((scsiq->q_status & QS_READY0x01) != 0)
12171 && ((scsiq->q_status & QS_ABORTED0x40) == 0)
12172 && ((scsiq->cntl & QCSG_SG_XFER_LIST0x02) == 0)) {
12173 scsiq->q_status |= QS_ABORTED0x40;
12174 scsiq->d3.done_stat = QD_ABORTED_BY_HOST0x02;
12175 AscWriteLramDWord(iop_base,
12176 (ushort) (q_addr + (ushort) ASC_SCSIQ_D_SRBPTR22),
12177 0L);
12178 AscWriteLramByte(iop_base,
12179 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS2),
12180 scsiq->q_status);
12181 (*asc_isr_callback) (asc_dvc, scsiq);
12182 return (1);
12183 }
12184 }
12185 }
12186 DvcLeaveCritical(last_int_level);
12187 return (0);
12188}
12189
12190#if LINUX_VERSION_CODE131108 >= ASC_LINUX_VERSION(1,3,89)(((1) * 65536) + ((3) * 256) + (89))
12191STATICstatic int
12192AscRiscHaltedAbortTIX(
12193 REGregister ASC_DVC_VAR asc_ptr_type * asc_dvc,
12194 uchar target_ix
12195)
12196{
12197 PortAddrunsigned short iop_base;
12198 ushort q_addr;
12199 uchar q_no;
12200 ASC_QDONE_INFO scsiq_buf;
12201 ASC_QDONE_INFO *scsiq;
12202 ASC_ISR_CALLBACK asc_isr_callback;
12203 int last_int_level;
12204
12205 iop_base = asc_dvc->iop_base;
12206 asc_isr_callback = (ASC_ISR_CALLBACK) asc_dvc->isr_callback;
12207 last_int_level = DvcEnterCritical();
12208 scsiq = (ASC_QDONE_INFO *) & scsiq_buf;
12209 for (q_no = ASC_MIN_ACTIVE_QNO0x01; q_no <= asc_dvc->max_total_qng;
12210 q_no++) {
12211 q_addr = ASC_QNO_TO_QADDR(q_no)(((0x4000))+((int)(q_no) << 6));
12212 _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq, asc_dvc->max_dma_count);
12213 if (((scsiq->q_status & QS_READY0x01) != 0) &&
12214 ((scsiq->q_status & QS_ABORTED0x40) == 0) &&
12215 ((scsiq->cntl & QCSG_SG_XFER_LIST0x02) == 0)) {
12216 if (scsiq->d2.target_ix == target_ix) {
12217 scsiq->q_status |= QS_ABORTED0x40;
12218 scsiq->d3.done_stat = QD_ABORTED_BY_HOST0x02;
12219 AscWriteLramDWord(iop_base,
12220 (ushort) (q_addr + (ushort) ASC_SCSIQ_D_SRBPTR22),
12221 0L);
12222 AscWriteLramByte(iop_base,
12223 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS2),
12224 scsiq->q_status);
12225 (*asc_isr_callback) (asc_dvc, scsiq);
12226 }
12227 }
12228 }
12229 DvcLeaveCritical(last_int_level);
12230 return (1);
12231}
12232#endif /* version >= v1.3.89 */
12233
12234STATICstatic int
12235AscHostReqRiscHalt(
12236 PortAddrunsigned short iop_base
12237)
12238{
12239 int count = 0;
12240 int sta = 0;
12241 uchar saved_stop_code;
12242
12243 if (AscIsChipHalted(iop_base))
12244 return (1);
12245 saved_stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B(ushort)0x0036);
12246 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B(ushort)0x0036,
12247 ASC_STOP_HOST_REQ_RISC_HALT0x40 | ASC_STOP_REQ_RISC_STOP0x01
12248);
12249 do {
12250 if (AscIsChipHalted(iop_base)) {
12251 sta = 1;
12252 break;
12253 }
12254 DvcSleepMilliSecond(100);
12255 } while (count++ < 20);
12256 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B(ushort)0x0036, saved_stop_code);
12257 return (sta);
12258}
12259
12260STATICstatic int
12261AscStopQueueExe(
12262 PortAddrunsigned short iop_base
12263)
12264{
12265 int count = 0;
12266
12267 if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B(ushort)0x0036) == 0) {
12268 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B(ushort)0x0036,
12269 ASC_STOP_REQ_RISC_STOP0x01);
12270 do {
12271 if (
12272 AscReadLramByte(iop_base, ASCV_STOP_CODE_B(ushort)0x0036) &
12273 ASC_STOP_ACK_RISC_STOP0x03) {
12274 return (1);
12275 }
12276 DvcSleepMilliSecond(100);
12277 } while (count++ < 20);
12278 }
12279 return (0);
12280}
12281
12282STATICstatic int
12283AscStartQueueExe(
12284 PortAddrunsigned short iop_base
12285)
12286{
12287 if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B(ushort)0x0036) != 0) {
12288 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B(ushort)0x0036, 0);
12289 }
12290 return (1);
12291}
12292
12293STATICstatic int
12294AscCleanUpBusyQueue(
12295 PortAddrunsigned short iop_base
12296)
12297{
12298 int count;
12299 uchar stop_code;
12300
12301 count = 0;
12302 if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B(ushort)0x0036) != 0) {
12303 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B(ushort)0x0036,
12304 ASC_STOP_CLEAN_UP_BUSY_Q0x10);
12305 do {
12306 stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B(ushort)0x0036);
12307 if ((stop_code & ASC_STOP_CLEAN_UP_BUSY_Q0x10) == 0)
12308 break;
12309 DvcSleepMilliSecond(100);
12310 } while (count++ < 20);
12311 }
12312 return (1);
12313}
12314
12315#if LINUX_VERSION_CODE131108 >= ASC_LINUX_VERSION(1,3,89)(((1) * 65536) + ((3) * 256) + (89))
12316STATICstatic int
12317AscCleanUpDiscQueue(
12318 PortAddrunsigned short iop_base
12319)
12320{
12321 int count;
12322 uchar stop_code;
12323
12324 count = 0;
12325 if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B(ushort)0x0036) != 0) {
12326 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B(ushort)0x0036,
12327 ASC_STOP_CLEAN_UP_DISC_Q0x20);
12328 do {
12329 stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B(ushort)0x0036);
12330 if ((stop_code & ASC_STOP_CLEAN_UP_DISC_Q0x20) == 0)
12331 break;
12332 DvcSleepMilliSecond(100);
12333 } while (count++ < 20);
12334 }
12335 return (1);
12336}
12337#endif /* version >= v1.3.89 */
12338
12339STATICstatic int
12340AscWaitTixISRDone(
12341 ASC_DVC_VAR asc_ptr_type * asc_dvc,
12342 uchar target_ix
12343)
12344{
12345 uchar cur_req;
12346 uchar tid_no;
12347 int i = 0;
12348
12349 tid_no = ASC_TIX_TO_TID(target_ix)((target_ix) & 7);
12350 while (i++ < 10) {
12351 if ((cur_req = asc_dvc->cur_dvc_qng[tid_no]) == 0) {
12352 break;
12353 }
12354 DvcSleepMilliSecond(1000L);
12355 if (asc_dvc->cur_dvc_qng[tid_no] == cur_req) {
12356 break;
12357 }
12358 }
12359 return (1);
12360}
12361
12362STATICstatic int
12363AscWaitISRDone(
12364 REGregister ASC_DVC_VAR asc_ptr_type * asc_dvc
12365)
12366{
12367 int tid;
12368
12369 for (tid = 0; tid <= ASC_MAX_TID7; tid++) {
12370 AscWaitTixISRDone(asc_dvc, ASC_TID_TO_TIX(tid)((tid) & 7));
12371 }
12372 return (1);
12373}
12374
12375STATICstatic ulong
12376AscGetOnePhyAddr(
12377 REGregister ASC_DVC_VAR asc_ptr_type * asc_dvc,
12378 uchar * buf_addr,
12379 ulong buf_size
12380)
12381{
12382 ASC_MIN_SG_HEAD sg_head;
12383
12384 sg_head.entry_cnt = ASC_MIN_SG_LIST2;
12385 if (DvcGetSGList(asc_dvc, (uchar *) buf_addr,
12386 buf_size, (ASC_SG_HEAD *) & sg_head) != buf_size) {
12387 return (0L);
12388 }
12389 if (sg_head.entry_cnt > 1) {
12390 return (0L);
12391 }
12392 return (sg_head.sg_list[0].addr);
12393}
12394
12395STATICstatic void
12396DvcDelayMicroSecond(ADV_DVC_VAR *asc_dvc, ushort micro_sec)
12397{
12398 udelay(micro_sec)(__builtin_constant_p(micro_sec) ? __const_udelay((micro_sec)
* 0x10c6ul) : __udelay(micro_sec))
;
12399}
12400
12401STATICstatic void
12402DvcDelayNanoSecond(ASC_DVC_VAR asc_ptr_type * asc_dvc, ulong nano_sec)
12403{
12404 udelay((nano_sec + 999)/1000)(__builtin_constant_p((nano_sec + 999)/1000) ? __const_udelay
(((nano_sec + 999)/1000) * 0x10c6ul) : __udelay((nano_sec + 999
)/1000))
;
12405}
12406
12407ASC_INITFUNC(static ulong AscGetEisaProductID( unsigned short iop_base)
12408STATIC ulongstatic ulong AscGetEisaProductID( unsigned short iop_base)
12409AscGetEisaProductID(static ulong AscGetEisaProductID( unsigned short iop_base)
12410 PortAddr iop_basestatic ulong AscGetEisaProductID( unsigned short iop_base)
12411)static ulong AscGetEisaProductID( unsigned short iop_base)
12412)static ulong AscGetEisaProductID( unsigned short iop_base)
12413{
12414 PortAddrunsigned short eisa_iop;
12415 ushort product_id_high, product_id_low;
12416 ulong product_id;
12417
12418 eisa_iop = ASC_GET_EISA_SLOT(iop_base)(unsigned short)((iop_base) & 0xF000) | ASC_EISA_PID_IOP_MASK(0x0C80);
12419 product_id_low = inpw(eisa_iop)((__builtin_constant_p((eisa_iop)) && (eisa_iop) <
256) ? __inwc(eisa_iop) : __inw(eisa_iop))
;
12420 product_id_high = inpw(eisa_iop + 2)((__builtin_constant_p((eisa_iop + 2)) && (eisa_iop +
2) < 256) ? __inwc(eisa_iop + 2) : __inw(eisa_iop + 2))
;
12421 product_id = ((ulong) product_id_high << 16) | (ulong) product_id_low;
12422 return (product_id);
12423}
12424
12425ASC_INITFUNC(static unsigned short AscSearchIOPortAddrEISA( unsigned short
iop_base)
12426STATIC PortAddrstatic unsigned short AscSearchIOPortAddrEISA( unsigned short
iop_base)
12427AscSearchIOPortAddrEISA(static unsigned short AscSearchIOPortAddrEISA( unsigned short
iop_base)
12428 PortAddr iop_basestatic unsigned short AscSearchIOPortAddrEISA( unsigned short
iop_base)
12429)static unsigned short AscSearchIOPortAddrEISA( unsigned short
iop_base)
12430)static unsigned short AscSearchIOPortAddrEISA( unsigned short
iop_base)
12431{
12432 ulong eisa_product_id;
12433
12434 if (iop_base == 0) {
12435 iop_base = ASC_EISA_MIN_IOP_ADDR(0x0C30);
12436 } else {
12437 if (iop_base == ASC_EISA_MAX_IOP_ADDR(0xFC50))
12438 return (0);
12439 if ((iop_base & 0x0050) == 0x0050) {
12440 iop_base += ASC_EISA_BIG_IOP_GAP(0x1C30 -0x0C50);
12441 } else {
12442 iop_base += ASC_EISA_SMALL_IOP_GAP(0x0020);
12443 }
12444 }
12445 while (iop_base <= ASC_EISA_MAX_IOP_ADDR(0xFC50)) {
12446 eisa_product_id = AscGetEisaProductID(iop_base);
12447 if ((eisa_product_id == ASC_EISA_ID_7400x01745004UL) ||
12448 (eisa_product_id == ASC_EISA_ID_7500x01755004UL)) {
12449 if (AscFindSignature(iop_base)) {
12450 inpw(iop_base + 4)((__builtin_constant_p((iop_base + 4)) && (iop_base +
4) < 256) ? __inwc(iop_base + 4) : __inw(iop_base + 4))
;
12451 return (iop_base);
12452 }
12453 }
12454 if (iop_base == ASC_EISA_MAX_IOP_ADDR(0xFC50))
12455 return (0);
12456 if ((iop_base & 0x0050) == 0x0050) {
12457 iop_base += ASC_EISA_BIG_IOP_GAP(0x1C30 -0x0C50);
12458 } else {
12459 iop_base += ASC_EISA_SMALL_IOP_GAP(0x0020);
12460 }
12461 }
12462 return (0);
12463}
12464
12465STATICstatic int
12466AscStartChip(
12467 PortAddrunsigned short iop_base
12468)
12469{
12470 AscSetChipControl(iop_base, 0)((__builtin_constant_p((((iop_base)+(0x0F)))) && (((iop_base
)+(0x0F))) < 256) ? __outbc(((0)),(((iop_base)+(0x0F)))) :
__outb(((0)),(((iop_base)+(0x0F)))))
;
12471 if ((AscGetChipStatus(iop_base)(unsigned short)((__builtin_constant_p(((iop_base)+(0x0E))) &&
((iop_base)+(0x0E)) < 256) ? __inwc((iop_base)+(0x0E)) : __inw
((iop_base)+(0x0E)))
& CSW_HALTED(unsigned short)0x0010) != 0) {
12472 return (0);
12473 }
12474 return (1);
12475}
12476
12477STATICstatic int
12478AscStopChip(
12479 PortAddrunsigned short iop_base
12480)
12481{
12482 uchar cc_val;
12483
12484 cc_val = AscGetChipControl(iop_base)(uchar)((__builtin_constant_p(((iop_base)+(0x0F))) &&
((iop_base)+(0x0F)) < 256) ? __inbc((iop_base)+(0x0F)) : __inb
((iop_base)+(0x0F)))
& (~(CC_SINGLE_STEP(uchar)0x10 | CC_TEST(uchar)0x04 | CC_DIAG(uchar)0x01));
12485 AscSetChipControl(iop_base, (uchar) (cc_val | CC_HALT))((__builtin_constant_p((((iop_base)+(0x0F)))) && (((iop_base
)+(0x0F))) < 256) ? __outbc((((uchar) (cc_val | (uchar)0x20
))),(((iop_base)+(0x0F)))) : __outb((((uchar) (cc_val | (uchar
)0x20))),(((iop_base)+(0x0F)))))
;
12486 AscSetChipIH(iop_base, INS_HALT(ushort)0x6280);
12487 AscSetChipIH(iop_base, INS_RFLAG_WTM(ushort)0x7380);
12488 if ((AscGetChipStatus(iop_base)(unsigned short)((__builtin_constant_p(((iop_base)+(0x0E))) &&
((iop_base)+(0x0E)) < 256) ? __inwc((iop_base)+(0x0E)) : __inw
((iop_base)+(0x0E)))
& CSW_HALTED(unsigned short)0x0010) == 0) {
12489 return (0);
12490 }
12491 return (1);
12492}
12493
12494STATICstatic int
12495AscIsChipHalted(
12496 PortAddrunsigned short iop_base
12497)
12498{
12499 if ((AscGetChipStatus(iop_base)(unsigned short)((__builtin_constant_p(((iop_base)+(0x0E))) &&
((iop_base)+(0x0E)) < 256) ? __inwc((iop_base)+(0x0E)) : __inw
((iop_base)+(0x0E)))
& CSW_HALTED(unsigned short)0x0010) != 0) {
12500 if ((AscGetChipControl(iop_base)(uchar)((__builtin_constant_p(((iop_base)+(0x0F))) &&
((iop_base)+(0x0F)) < 256) ? __inbc((iop_base)+(0x0F)) : __inb
((iop_base)+(0x0F)))
& CC_HALT(uchar)0x20) != 0) {
12501 return (1);
12502 }
12503 }
12504 return (0);
12505}
12506
12507STATICstatic void
12508AscSetChipIH(
12509 PortAddrunsigned short iop_base,
12510 ushort ins_code
12511)
12512{
12513 AscSetBank(iop_base, 1);
12514 AscWriteChipIH(iop_base, ins_code)((__builtin_constant_p((((iop_base)+(0x02)))) && (((iop_base
)+(0x02))) < 256) ? __outwc(((ins_code)),(((iop_base)+(0x02
)))) : __outw(((ins_code)),(((iop_base)+(0x02)))))
;
12515 AscSetBank(iop_base, 0);
12516 return;
12517}
12518
12519STATICstatic void
12520AscAckInterrupt(
12521 PortAddrunsigned short iop_base
12522)
12523{
12524 uchar host_flag;
12525 uchar risc_flag;
12526 ushort loop;
12527
12528 loop = 0;
12529 do {
12530 risc_flag = AscReadLramByte(iop_base, ASCV_RISC_FLAG_B(ushort)0x006A);
12531 if (loop++ > 0x7FFF) {
12532 break;
12533 }
12534 } while ((risc_flag & ASC_RISC_FLAG_GEN_INT0x01) != 0);
12535 host_flag = AscReadLramByte(iop_base, ASCV_HOST_FLAG_B(ushort)0x005D) & (~ASC_HOST_FLAG_ACK_INT0x02);
12536 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B(ushort)0x005D,
12537 (uchar) (host_flag | ASC_HOST_FLAG_ACK_INT0x02));
12538 AscSetChipStatus(iop_base, CIW_INT_ACK)((__builtin_constant_p((((iop_base)+(0x0E)))) && (((iop_base
)+(0x0E))) < 256) ? __outwc((((unsigned short)0x0100)),(((
iop_base)+(0x0E)))) : __outw((((unsigned short)0x0100)),(((iop_base
)+(0x0E)))))
;
12539 loop = 0;
12540 while (AscGetChipStatus(iop_base)(unsigned short)((__builtin_constant_p(((iop_base)+(0x0E))) &&
((iop_base)+(0x0E)) < 256) ? __inwc((iop_base)+(0x0E)) : __inw
((iop_base)+(0x0E)))
& CSW_INT_PENDING(unsigned short)0x0001) {
12541 AscSetChipStatus(iop_base, CIW_INT_ACK)((__builtin_constant_p((((iop_base)+(0x0E)))) && (((iop_base
)+(0x0E))) < 256) ? __outwc((((unsigned short)0x0100)),(((
iop_base)+(0x0E)))) : __outw((((unsigned short)0x0100)),(((iop_base
)+(0x0E)))))
;
12542 if (loop++ > 3) {
12543 break;
12544 }
12545 }
12546 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B(ushort)0x005D, host_flag);
12547 return;
12548}
12549
12550STATICstatic void
12551AscDisableInterrupt(
12552 PortAddrunsigned short iop_base
12553)
12554{
12555 ushort cfg;
12556
12557 cfg = AscGetChipCfgLsw(iop_base)(ushort)((__builtin_constant_p(((iop_base)+(0x02))) &&
((iop_base)+(0x02)) < 256) ? __inwc((iop_base)+(0x02)) : __inw
((iop_base)+(0x02)))
;
12558 AscSetChipCfgLsw(iop_base, cfg & (~ASC_CFG0_HOST_INT_ON))((__builtin_constant_p((((iop_base)+(0x02)))) && (((iop_base
)+(0x02))) < 256) ? __outwc(((cfg & (~0x0020))),(((iop_base
)+(0x02)))) : __outw(((cfg & (~0x0020))),(((iop_base)+(0x02
)))))
;
12559 return;
12560}
12561
12562STATICstatic void
12563AscEnableInterrupt(
12564 PortAddrunsigned short iop_base
12565)
12566{
12567 ushort cfg;
12568
12569 cfg = AscGetChipCfgLsw(iop_base)(ushort)((__builtin_constant_p(((iop_base)+(0x02))) &&
((iop_base)+(0x02)) < 256) ? __inwc((iop_base)+(0x02)) : __inw
((iop_base)+(0x02)))
;
12570 AscSetChipCfgLsw(iop_base, cfg | ASC_CFG0_HOST_INT_ON)((__builtin_constant_p((((iop_base)+(0x02)))) && (((iop_base
)+(0x02))) < 256) ? __outwc(((cfg | 0x0020)),(((iop_base)+
(0x02)))) : __outw(((cfg | 0x0020)),(((iop_base)+(0x02)))))
;
12571 return;
12572}
12573
12574
12575
12576STATICstatic void
12577AscSetBank(
12578 PortAddrunsigned short iop_base,
12579 uchar bank
12580)
12581{
12582 uchar val;
12583
12584 val = AscGetChipControl(iop_base)(uchar)((__builtin_constant_p(((iop_base)+(0x0F))) &&
((iop_base)+(0x0F)) < 256) ? __inbc((iop_base)+(0x0F)) : __inb
((iop_base)+(0x0F)))
&
12585 (~(CC_SINGLE_STEP(uchar)0x10 | CC_TEST(uchar)0x04 | CC_DIAG(uchar)0x01 | CC_SCSI_RESET(uchar)0x40 | CC_CHIP_RESET(uchar)0x80));
12586 if (bank == 1) {
12587 val |= CC_BANK_ONE(uchar)0x02;
12588 } else if (bank == 2) {
12589 val |= CC_DIAG(uchar)0x01 | CC_BANK_ONE(uchar)0x02;
12590 } else {
12591 val &= ~CC_BANK_ONE(uchar)0x02;
12592 }
12593 AscSetChipControl(iop_base, val)((__builtin_constant_p((((iop_base)+(0x0F)))) && (((iop_base
)+(0x0F))) < 256) ? __outbc(((val)),(((iop_base)+(0x0F))))
: __outb(((val)),(((iop_base)+(0x0F)))))
;
12594 return;
12595}
12596
12597STATICstatic int
12598AscResetChipAndScsiBus(
12599 ASC_DVC_VAR *asc_dvc
12600)
12601{
12602 PortAddrunsigned short iop_base;
12603
12604 iop_base = asc_dvc->iop_base;
12605 while (AscGetChipStatus(iop_base)(unsigned short)((__builtin_constant_p(((iop_base)+(0x0E))) &&
((iop_base)+(0x0E)) < 256) ? __inwc((iop_base)+(0x0E)) : __inw
((iop_base)+(0x0E)))
& CSW_SCSI_RESET_ACTIVE(unsigned short)0x0008) ;
12606 AscStopChip(iop_base);
12607 AscSetChipControl(iop_base, CC_CHIP_RESET | CC_SCSI_RESET | CC_HALT)((__builtin_constant_p((((iop_base)+(0x0F)))) && (((iop_base
)+(0x0F))) < 256) ? __outbc((((uchar)0x80 | (uchar)0x40 | (
uchar)0x20)),(((iop_base)+(0x0F)))) : __outb((((uchar)0x80 | (
uchar)0x40 | (uchar)0x20)),(((iop_base)+(0x0F)))))
;
12608 DvcDelayNanoSecond(asc_dvc, 60000);
12609 AscSetChipIH(iop_base, INS_RFLAG_WTM(ushort)0x7380);
12610 AscSetChipIH(iop_base, INS_HALT(ushort)0x6280);
12611 AscSetChipControl(iop_base, CC_CHIP_RESET | CC_HALT)((__builtin_constant_p((((iop_base)+(0x0F)))) && (((iop_base
)+(0x0F))) < 256) ? __outbc((((uchar)0x80 | (uchar)0x20)),
(((iop_base)+(0x0F)))) : __outb((((uchar)0x80 | (uchar)0x20))
,(((iop_base)+(0x0F)))))
;
12612 AscSetChipControl(iop_base, CC_HALT)((__builtin_constant_p((((iop_base)+(0x0F)))) && (((iop_base
)+(0x0F))) < 256) ? __outbc((((uchar)0x20)),(((iop_base)+(
0x0F)))) : __outb((((uchar)0x20)),(((iop_base)+(0x0F)))))
;
12613 DvcSleepMilliSecond(200);
12614 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT)((__builtin_constant_p((((iop_base)+(0x0E)))) && (((iop_base
)+(0x0E))) < 256) ? __outwc((((unsigned short)0x1000)),(((
iop_base)+(0x0E)))) : __outw((((unsigned short)0x1000)),(((iop_base
)+(0x0E)))))
;
12615 AscSetChipStatus(iop_base, 0)((__builtin_constant_p((((iop_base)+(0x0E)))) && (((iop_base
)+(0x0E))) < 256) ? __outwc(((0)),(((iop_base)+(0x0E)))) :
__outw(((0)),(((iop_base)+(0x0E)))))
;
12616 return (AscIsChipHalted(iop_base));
12617}
12618
12619ASC_INITFUNC(static ulong AscGetMaxDmaCount( ushort bus_type)
12620STATIC ulongstatic ulong AscGetMaxDmaCount( ushort bus_type)
12621AscGetMaxDmaCount(static ulong AscGetMaxDmaCount( ushort bus_type)
12622 ushort bus_typestatic ulong AscGetMaxDmaCount( ushort bus_type)
12623)static ulong AscGetMaxDmaCount( ushort bus_type)
12624)static ulong AscGetMaxDmaCount( ushort bus_type)
12625{
12626 if (bus_type & ASC_IS_ISA(0x0001))
12627 return (ASC_MAX_ISA_DMA_COUNT(0x00FFFFFFL));
12628 else if (bus_type & (ASC_IS_EISA(0x0002) | ASC_IS_VL(0x0040)))
12629 return (ASC_MAX_VL_DMA_COUNT(0x07FFFFFFL));
12630 return (ASC_MAX_PCI_DMA_COUNT(0xFFFFFFFFL));
12631}
12632
12633ASC_INITFUNC(static ushort AscGetIsaDmaChannel( unsigned short iop_base)
12634STATIC ushortstatic ushort AscGetIsaDmaChannel( unsigned short iop_base)
12635AscGetIsaDmaChannel(static ushort AscGetIsaDmaChannel( unsigned short iop_base)
12636 PortAddr iop_basestatic ushort AscGetIsaDmaChannel( unsigned short iop_base)
12637)static ushort AscGetIsaDmaChannel( unsigned short iop_base)
12638)static ushort AscGetIsaDmaChannel( unsigned short iop_base)
12639{
12640 ushort channel;
12641
12642 channel = AscGetChipCfgLsw(iop_base)(ushort)((__builtin_constant_p(((iop_base)+(0x02))) &&
((iop_base)+(0x02)) < 256) ? __inwc((iop_base)+(0x02)) : __inw
((iop_base)+(0x02)))
& 0x0003;
12643 if (channel == 0x03)
12644 return (0);
12645 else if (channel == 0x00)
12646 return (7);
12647 return (channel + 4);
12648}
12649
12650ASC_INITFUNC(static ushort AscSetIsaDmaChannel( unsigned short iop_base, ushort
dma_channel)
12651STATIC ushortstatic ushort AscSetIsaDmaChannel( unsigned short iop_base, ushort
dma_channel)
12652AscSetIsaDmaChannel(static ushort AscSetIsaDmaChannel( unsigned short iop_base, ushort
dma_channel)
12653 PortAddr iop_base,static ushort AscSetIsaDmaChannel( unsigned short iop_base, ushort
dma_channel)
12654 ushort dma_channelstatic ushort AscSetIsaDmaChannel( unsigned short iop_base, ushort
dma_channel)
12655)static ushort AscSetIsaDmaChannel( unsigned short iop_base, ushort
dma_channel)
12656)static ushort AscSetIsaDmaChannel( unsigned short iop_base, ushort
dma_channel)
12657{
12658 ushort cfg_lsw;
12659 uchar value;
12660
12661 if ((dma_channel >= 5) && (dma_channel <= 7)) {
12662 if (dma_channel == 7)
12663 value = 0x00;
12664 else
12665 value = dma_channel - 4;
12666 cfg_lsw = AscGetChipCfgLsw(iop_base)(ushort)((__builtin_constant_p(((iop_base)+(0x02))) &&
((iop_base)+(0x02)) < 256) ? __inwc((iop_base)+(0x02)) : __inw
((iop_base)+(0x02)))
& 0xFFFC;
12667 cfg_lsw |= value;
12668 AscSetChipCfgLsw(iop_base, cfg_lsw)((__builtin_constant_p((((iop_base)+(0x02)))) && (((iop_base
)+(0x02))) < 256) ? __outwc(((cfg_lsw)),(((iop_base)+(0x02
)))) : __outw(((cfg_lsw)),(((iop_base)+(0x02)))))
;
12669 return (AscGetIsaDmaChannel(iop_base));
12670 }
12671 return (0);
12672}
12673
12674ASC_INITFUNC(static uchar AscSetIsaDmaSpeed( unsigned short iop_base, uchar
speed_value)
12675STATIC ucharstatic uchar AscSetIsaDmaSpeed( unsigned short iop_base, uchar
speed_value)
12676AscSetIsaDmaSpeed(static uchar AscSetIsaDmaSpeed( unsigned short iop_base, uchar
speed_value)
12677 PortAddr iop_base,static uchar AscSetIsaDmaSpeed( unsigned short iop_base, uchar
speed_value)
12678 uchar speed_valuestatic uchar AscSetIsaDmaSpeed( unsigned short iop_base, uchar
speed_value)
12679)static uchar AscSetIsaDmaSpeed( unsigned short iop_base, uchar
speed_value)
12680)static uchar AscSetIsaDmaSpeed( unsigned short iop_base, uchar
speed_value)
12681{
12682 speed_value &= 0x07;
12683 AscSetBank(iop_base, 1);
12684 AscWriteChipDmaSpeed(iop_base, speed_value)((__builtin_constant_p((((iop_base)+(0x07)))) && (((iop_base
)+(0x07))) < 256) ? __outbc(((speed_value)),(((iop_base)+(
0x07)))) : __outb(((speed_value)),(((iop_base)+(0x07)))))
;
12685 AscSetBank(iop_base, 0);
12686 return (AscGetIsaDmaSpeed(iop_base));
12687}
12688
12689ASC_INITFUNC(static uchar AscGetIsaDmaSpeed( unsigned short iop_base)
12690STATIC ucharstatic uchar AscGetIsaDmaSpeed( unsigned short iop_base)
12691AscGetIsaDmaSpeed(static uchar AscGetIsaDmaSpeed( unsigned short iop_base)
12692 PortAddr iop_basestatic uchar AscGetIsaDmaSpeed( unsigned short iop_base)
12693)static uchar AscGetIsaDmaSpeed( unsigned short iop_base)
12694)static uchar AscGetIsaDmaSpeed( unsigned short iop_base)
12695{
12696 uchar speed_value;
12697
12698 AscSetBank(iop_base, 1);
12699 speed_value = AscReadChipDmaSpeed(iop_base)(uchar)((__builtin_constant_p(((iop_base)+(0x07))) &&
((iop_base)+(0x07)) < 256) ? __inbc((iop_base)+(0x07)) : __inb
((iop_base)+(0x07)))
;
12700 speed_value &= 0x07;
12701 AscSetBank(iop_base, 0);
12702 return (speed_value);
12703}
12704
12705ASC_INITFUNC(static ushort AscReadPCIConfigWord( ASC_DVC_VAR *asc_dvc, ushort
pci_config_offset)
12706STATIC ushortstatic ushort AscReadPCIConfigWord( ASC_DVC_VAR *asc_dvc, ushort
pci_config_offset)
12707AscReadPCIConfigWord(static ushort AscReadPCIConfigWord( ASC_DVC_VAR *asc_dvc, ushort
pci_config_offset)
12708 ASC_DVC_VAR asc_ptr_type *asc_dvc,static ushort AscReadPCIConfigWord( ASC_DVC_VAR *asc_dvc, ushort
pci_config_offset)
12709 ushort pci_config_offset)static ushort AscReadPCIConfigWord( ASC_DVC_VAR *asc_dvc, ushort
pci_config_offset)
12710)static ushort AscReadPCIConfigWord( ASC_DVC_VAR *asc_dvc, ushort
pci_config_offset)
12711{
12712 uchar lsb, msb;
12713
12714 lsb = DvcReadPCIConfigByte(asc_dvc, pci_config_offset);
12715 msb = DvcReadPCIConfigByte(asc_dvc, pci_config_offset + 1);
12716 return ((ushort) ((msb << 8) | lsb));
12717}
12718
12719ASC_INITFUNC(static ushort AscInitGetConfig( ASC_DVC_VAR * asc_dvc)
12720STATIC ushortstatic ushort AscInitGetConfig( ASC_DVC_VAR * asc_dvc)
12721AscInitGetConfig(static ushort AscInitGetConfig( ASC_DVC_VAR * asc_dvc)
12722 ASC_DVC_VAR asc_ptr_type * asc_dvcstatic ushort AscInitGetConfig( ASC_DVC_VAR * asc_dvc)
12723)static ushort AscInitGetConfig( ASC_DVC_VAR * asc_dvc)
12724)static ushort AscInitGetConfig( ASC_DVC_VAR * asc_dvc)
12725{
12726 ushort warn_code;
12727 PortAddrunsigned short iop_base;
12728 ushort PCIDeviceID;
12729 ushort PCIVendorID;
12730 uchar PCIRevisionID;
12731 uchar prevCmdRegBits;
12732
12733 warn_code = 0;
12734 iop_base = asc_dvc->iop_base;
12735 asc_dvc->init_state = ASC_INIT_STATE_BEG_GET_CFG0x0001;
12736 if (asc_dvc->err_code != 0) {
12737 return (UW_ERR(uint)(0xFFFF));
12738 }
12739 if (asc_dvc->bus_type == ASC_IS_PCI(0x0004)) {
12740 PCIVendorID = AscReadPCIConfigWord(asc_dvc,
12741 AscPCIConfigVendorIDRegister0x0000);
12742
12743 PCIDeviceID = AscReadPCIConfigWord(asc_dvc,
12744 AscPCIConfigDeviceIDRegister0x0002);
12745
12746 PCIRevisionID = DvcReadPCIConfigByte(asc_dvc,
Value stored to 'PCIRevisionID' is never read
12747 AscPCIConfigRevisionIDRegister0x0008);
12748
12749 if (PCIVendorID != ASC_PCI_VENDORID0x10CD) {
12750 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE0x0080;
12751 }
12752 prevCmdRegBits = DvcReadPCIConfigByte(asc_dvc,
12753 AscPCIConfigCommandRegister0x0004);
12754
12755 if ((prevCmdRegBits & AscPCICmdRegBits_IOMemBusMaster0x0007) !=
12756 AscPCICmdRegBits_IOMemBusMaster0x0007) {
12757 DvcWritePCIConfigByte(asc_dvc,
12758 AscPCIConfigCommandRegister0x0004,
12759 (prevCmdRegBits |
12760 AscPCICmdRegBits_IOMemBusMaster0x0007));
12761
12762 if ((DvcReadPCIConfigByte(asc_dvc,
12763 AscPCIConfigCommandRegister0x0004)
12764 & AscPCICmdRegBits_IOMemBusMaster0x0007)
12765 != AscPCICmdRegBits_IOMemBusMaster0x0007) {
12766 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE0x0080;
12767 }
12768 }
12769 if ((PCIDeviceID == ASC_PCI_DEVICEID_1200A0x1100) ||
12770 (PCIDeviceID == ASC_PCI_DEVICEID_1200B0x1200)) {
12771 DvcWritePCIConfigByte(asc_dvc,
12772 AscPCIConfigLatencyTimer0x000D, 0x00);
12773 if (DvcReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer0x000D)
12774 != 0x00) {
12775 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE0x0080;
12776 }
12777 } else if (PCIDeviceID == ASC_PCI_DEVICEID_ULTRA0x1300) {
12778 if (DvcReadPCIConfigByte(asc_dvc,
12779 AscPCIConfigLatencyTimer0x000D) < 0x20) {
12780 DvcWritePCIConfigByte(asc_dvc,
12781 AscPCIConfigLatencyTimer0x000D, 0x20);
12782
12783 if (DvcReadPCIConfigByte(asc_dvc,
12784 AscPCIConfigLatencyTimer0x000D) < 0x20) {
12785 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE0x0080;
12786 }
12787 }
12788 }
12789 }
12790
12791 if (AscFindSignature(iop_base)) {
12792 warn_code |= AscInitAscDvcVar(asc_dvc);
12793 warn_code |= AscInitFromEEP(asc_dvc);
12794 asc_dvc->init_state |= ASC_INIT_STATE_END_GET_CFG0x0002;
12795 if (asc_dvc->scsi_reset_wait > ASC_MAX_SCSI_RESET_WAIT30) {
12796 asc_dvc->scsi_reset_wait = ASC_MAX_SCSI_RESET_WAIT30;
12797 }
12798 } else {
12799 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE0x0200;
12800 }
12801 return(warn_code);
12802}
12803
12804ASC_INITFUNC(static ushort AscInitSetConfig( ASC_DVC_VAR * asc_dvc)
12805STATIC ushortstatic ushort AscInitSetConfig( ASC_DVC_VAR * asc_dvc)
12806AscInitSetConfig(static ushort AscInitSetConfig( ASC_DVC_VAR * asc_dvc)
12807 ASC_DVC_VAR asc_ptr_type * asc_dvcstatic ushort AscInitSetConfig( ASC_DVC_VAR * asc_dvc)
12808)static ushort AscInitSetConfig( ASC_DVC_VAR * asc_dvc)
12809)static ushort AscInitSetConfig( ASC_DVC_VAR * asc_dvc)
12810{
12811 ushort warn_code = 0;
12812
12813 asc_dvc->init_state |= ASC_INIT_STATE_BEG_SET_CFG0x0004;
12814 if (asc_dvc->err_code != 0)
12815 return (UW_ERR(uint)(0xFFFF));
12816 if (AscFindSignature(asc_dvc->iop_base)) {
12817 warn_code |= AscInitFromAscDvcVar(asc_dvc);
12818 asc_dvc->init_state |= ASC_INIT_STATE_END_SET_CFG0x0008;
12819 } else {
12820 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE0x0200;
12821 }
12822 return (warn_code);
12823}
12824
12825ASC_INITFUNC(static ushort AscInitFromAscDvcVar( ASC_DVC_VAR * asc_dvc)
12826STATIC ushortstatic ushort AscInitFromAscDvcVar( ASC_DVC_VAR * asc_dvc)
12827AscInitFromAscDvcVar(static ushort AscInitFromAscDvcVar( ASC_DVC_VAR * asc_dvc)
12828 ASC_DVC_VAR asc_ptr_type * asc_dvcstatic ushort AscInitFromAscDvcVar( ASC_DVC_VAR * asc_dvc)
12829)static ushort AscInitFromAscDvcVar( ASC_DVC_VAR * asc_dvc)
12830)static ushort AscInitFromAscDvcVar( ASC_DVC_VAR * asc_dvc)
12831{
12832 PortAddrunsigned short iop_base;
12833 ushort cfg_msw;
12834 ushort warn_code;
12835 ushort pci_device_id;
12836
12837 iop_base = asc_dvc->iop_base;
12838 pci_device_id = asc_dvc->cfg->pci_device_id;
12839 warn_code = 0;
12840 cfg_msw = AscGetChipCfgMsw(iop_base)(ushort)((__builtin_constant_p(((iop_base)+(0x04))) &&
((iop_base)+(0x04)) < 256) ? __inwc((iop_base)+(0x04)) : __inw
((iop_base)+(0x04)))
;
12841 if ((cfg_msw & ASC_CFG_MSW_CLR_MASK0x3080) != 0) {
12842 cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK0x3080));
12843 warn_code |= ASC_WARN_CFG_MSW_RECOVER0x0040;
12844 AscSetChipCfgMsw(iop_base, cfg_msw)((__builtin_constant_p((((iop_base)+(0x04)))) && (((iop_base
)+(0x04))) < 256) ? __outwc(((cfg_msw)),(((iop_base)+(0x04
)))) : __outw(((cfg_msw)),(((iop_base)+(0x04)))))
;
12845 }
12846 if ((asc_dvc->cfg->cmd_qng_enabled & asc_dvc->cfg->disc_enable) !=
12847 asc_dvc->cfg->cmd_qng_enabled) {
12848 asc_dvc->cfg->disc_enable = asc_dvc->cfg->cmd_qng_enabled;
12849 warn_code |= ASC_WARN_CMD_QNG_CONFLICT0x0010;
12850 }
12851 if (AscGetChipStatus(iop_base)(unsigned short)((__builtin_constant_p(((iop_base)+(0x0E))) &&
((iop_base)+(0x0E)) < 256) ? __inwc((iop_base)+(0x0E)) : __inw
((iop_base)+(0x0E)))
& CSW_AUTO_CONFIG(unsigned short)0x4000) {
12852 warn_code |= ASC_WARN_AUTO_CONFIG0x0008;
12853 }
12854 if ((asc_dvc->bus_type & (ASC_IS_ISA(0x0001) | ASC_IS_VL(0x0040))) != 0) {
12855 if (AscSetChipIRQ(iop_base, asc_dvc->irq_no, asc_dvc->bus_type)
12856 != asc_dvc->irq_no) {
12857 asc_dvc->err_code |= ASC_IERR_SET_IRQ_NO0x0020;
12858 }
12859 }
12860 if (asc_dvc->bus_type & ASC_IS_PCI(0x0004)) {
12861 cfg_msw &= 0xFFC0;
12862 AscSetChipCfgMsw(iop_base, cfg_msw)((__builtin_constant_p((((iop_base)+(0x04)))) && (((iop_base
)+(0x04))) < 256) ? __outwc(((cfg_msw)),(((iop_base)+(0x04
)))) : __outw(((cfg_msw)),(((iop_base)+(0x04)))))
;
12863 if ((asc_dvc->bus_type & ASC_IS_PCI_ULTRA(0x0104)) == ASC_IS_PCI_ULTRA(0x0104)) {
12864 } else {
12865 if ((pci_device_id == ASC_PCI_DEVICE_ID_REV_A0x1100) ||
12866 (pci_device_id == ASC_PCI_DEVICE_ID_REV_B0x1200)) {
12867 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_IF_NOT_DWB0x0001;
12868 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN0x0002;
12869 }
12870 }
12871 } else if (asc_dvc->bus_type == ASC_IS_ISAPNP(0x0081)) {
12872 if (AscGetChipVersion(iop_base, asc_dvc->bus_type)
12873 == ASC_CHIP_VER_ASYN_BUG(0x21)) {
12874 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN0x0002;
12875 }
12876 }
12877 if (AscSetChipScsiID(iop_base, asc_dvc->cfg->chip_scsi_id) !=
12878 asc_dvc->cfg->chip_scsi_id) {
12879 asc_dvc->err_code |= ASC_IERR_SET_SCSI_ID0x0080;
12880 }
12881 if (asc_dvc->bus_type & ASC_IS_ISA(0x0001)) {
12882 AscSetIsaDmaChannel(iop_base, asc_dvc->cfg->isa_dma_channel);
12883 AscSetIsaDmaSpeed(iop_base, asc_dvc->cfg->isa_dma_speed);
12884 }
12885 return (warn_code);
12886}
12887
12888ASC_INITFUNC(static ushort AscInitAsc1000Driver( ASC_DVC_VAR * asc_dvc)
12889STATIC ushortstatic ushort AscInitAsc1000Driver( ASC_DVC_VAR * asc_dvc)
12890AscInitAsc1000Driver(static ushort AscInitAsc1000Driver( ASC_DVC_VAR * asc_dvc)
12891 ASC_DVC_VAR asc_ptr_type * asc_dvcstatic ushort AscInitAsc1000Driver( ASC_DVC_VAR * asc_dvc)
12892)static ushort AscInitAsc1000Driver( ASC_DVC_VAR * asc_dvc)
12893)static ushort AscInitAsc1000Driver( ASC_DVC_VAR * asc_dvc)
12894{
12895 ushort warn_code;
12896 PortAddrunsigned short iop_base;
12897 extern ushort _asc_mcode_size;
12898 extern ulong _asc_mcode_chksum;
12899 extern uchar _asc_mcode_buf[];
12900
12901 iop_base = asc_dvc->iop_base;
12902 warn_code = 0;
12903 if ((asc_dvc->dvc_cntl & ASC_CNTL_RESET_SCSI(ushort)0x0200) &&
12904 !(asc_dvc->init_state & ASC_INIT_RESET_SCSI_DONE0x0100)) {
12905 AscResetChipAndScsiBus(asc_dvc);
12906 DvcSleepMilliSecond((ulong) ((ushort) asc_dvc->scsi_reset_wait * 1000));
12907 }
12908 asc_dvc->init_state |= ASC_INIT_STATE_BEG_LOAD_MC0x0010;
12909 if (asc_dvc->err_code != 0)
12910 return (UW_ERR(uint)(0xFFFF));
12911 if (!AscFindSignature(asc_dvc->iop_base)) {
12912 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE0x0200;
12913 return (warn_code);
12914 }
12915 AscDisableInterrupt(iop_base);
12916 warn_code |= AscInitLram(asc_dvc);
12917 if (asc_dvc->err_code != 0)
12918 return (UW_ERR(uint)(0xFFFF));
12919 if (AscLoadMicroCode(iop_base, 0, (ushort *) _asc_mcode_buf,
12920 _asc_mcode_size) != _asc_mcode_chksum) {
12921 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM0x0002;
12922 return (warn_code);
12923 }
12924 warn_code |= AscInitMicroCodeVar(asc_dvc);
12925 asc_dvc->init_state |= ASC_INIT_STATE_END_LOAD_MC0x0020;
12926 AscEnableInterrupt(iop_base);
12927 return (warn_code);
12928}
12929
12930ASC_INITFUNC(static ushort AscInitAscDvcVar( ASC_DVC_VAR * asc_dvc)
12931STATIC ushortstatic ushort AscInitAscDvcVar( ASC_DVC_VAR * asc_dvc)
12932AscInitAscDvcVar(static ushort AscInitAscDvcVar( ASC_DVC_VAR * asc_dvc)
12933 ASC_DVC_VAR asc_ptr_type * asc_dvcstatic ushort AscInitAscDvcVar( ASC_DVC_VAR * asc_dvc)
12934)static ushort AscInitAscDvcVar( ASC_DVC_VAR * asc_dvc)
12935)static ushort AscInitAscDvcVar( ASC_DVC_VAR * asc_dvc)
12936{
12937 int i;
12938 PortAddrunsigned short iop_base;
12939 ushort warn_code;
12940 uchar chip_version;
12941
12942 iop_base = asc_dvc->iop_base;
12943 warn_code = 0;
12944 asc_dvc->err_code = 0;
12945 if ((asc_dvc->bus_type &
12946 (ASC_IS_ISA(0x0001) | ASC_IS_PCI(0x0004) | ASC_IS_EISA(0x0002) | ASC_IS_VL(0x0040))) == 0) {
12947 asc_dvc->err_code |= ASC_IERR_NO_BUS_TYPE0x0400;
12948 }
12949 AscSetChipControl(iop_base, CC_HALT)((__builtin_constant_p((((iop_base)+(0x0F)))) && (((iop_base
)+(0x0F))) < 256) ? __outbc((((uchar)0x20)),(((iop_base)+(
0x0F)))) : __outb((((uchar)0x20)),(((iop_base)+(0x0F)))))
;
12950 AscSetChipStatus(iop_base, 0)((__builtin_constant_p((((iop_base)+(0x0E)))) && (((iop_base
)+(0x0E))) < 256) ? __outwc(((0)),(((iop_base)+(0x0E)))) :
__outw(((0)),(((iop_base)+(0x0E)))))
;
12951 asc_dvc->bug_fix_cntl = 0;
12952 asc_dvc->pci_fix_asyn_xfer = 0;
12953 asc_dvc->pci_fix_asyn_xfer_always = 0;
12954 asc_dvc->init_state = 0;
12955 asc_dvc->sdtr_done = 0;
12956 asc_dvc->cur_total_qng = 0;
12957 asc_dvc->is_in_int = 0;
12958 asc_dvc->in_critical_cnt = 0;
12959 asc_dvc->last_q_shortage = 0;
12960 asc_dvc->use_tagged_qng = 0;
12961 asc_dvc->no_scam = 0;
12962 asc_dvc->unit_not_ready = 0;
12963 asc_dvc->queue_full_or_busy = 0;
12964 asc_dvc->redo_scam = 0 ;
12965 asc_dvc->res2 = 0 ;
12966 asc_dvc->host_init_sdtr_index = 0 ;
12967 asc_dvc->res7 = 0 ;
12968 asc_dvc->res8 = 0 ;
12969 asc_dvc->cfg->can_tagged_qng = 0 ;
12970 asc_dvc->cfg->cmd_qng_enabled = 0;
12971 asc_dvc->dvc_cntl = ASC_DEF_DVC_CNTL0xFFFF;
12972 asc_dvc->init_sdtr = 0;
12973 asc_dvc->max_total_qng = ASC_DEF_MAX_TOTAL_QNG(0xF0);
12974 asc_dvc->scsi_reset_wait = 3;
12975 asc_dvc->start_motor = ASC_SCSI_WIDTH_BIT_SET0xFF;
12976 asc_dvc->max_dma_count = AscGetMaxDmaCount(asc_dvc->bus_type);
12977 asc_dvc->cfg->sdtr_enable = ASC_SCSI_WIDTH_BIT_SET0xFF;
12978 asc_dvc->cfg->disc_enable = ASC_SCSI_WIDTH_BIT_SET0xFF;
12979 asc_dvc->cfg->chip_scsi_id = ASC_DEF_CHIP_SCSI_ID7;
12980 asc_dvc->cfg->lib_serial_no = ASC_LIB_SERIAL_NUMBER113;
12981 asc_dvc->cfg->lib_version = (ASC_LIB_VERSION_MAJOR1 << 8) |
12982 ASC_LIB_VERSION_MINOR22;
12983 chip_version = AscGetChipVersion(iop_base, asc_dvc->bus_type);
12984 asc_dvc->cfg->chip_version = chip_version;
12985 asc_dvc->sdtr_period_tbl[0] = SYN_XFER_NS_025;
12986 asc_dvc->sdtr_period_tbl[1] = SYN_XFER_NS_130;
12987 asc_dvc->sdtr_period_tbl[2] = SYN_XFER_NS_235;
12988 asc_dvc->sdtr_period_tbl[3] = SYN_XFER_NS_340;
12989 asc_dvc->sdtr_period_tbl[4] = SYN_XFER_NS_450;
12990 asc_dvc->sdtr_period_tbl[5] = SYN_XFER_NS_560;
12991 asc_dvc->sdtr_period_tbl[6] = SYN_XFER_NS_670;
12992 asc_dvc->sdtr_period_tbl[7] = SYN_XFER_NS_785;
12993 asc_dvc->max_sdtr_index = 7;
12994 if ((asc_dvc->bus_type & ASC_IS_PCI(0x0004)) &&
12995 (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3150(0x08 | 0x02))) {
12996 asc_dvc->bus_type = ASC_IS_PCI_ULTRA(0x0104);
12997 asc_dvc->sdtr_period_tbl[0] = SYN_ULTRA_XFER_NS_012;
12998 asc_dvc->sdtr_period_tbl[1] = SYN_ULTRA_XFER_NS_119;
12999 asc_dvc->sdtr_period_tbl[2] = SYN_ULTRA_XFER_NS_225;
13000 asc_dvc->sdtr_period_tbl[3] = SYN_ULTRA_XFER_NS_332;
13001 asc_dvc->sdtr_period_tbl[4] = SYN_ULTRA_XFER_NS_438;
13002 asc_dvc->sdtr_period_tbl[5] = SYN_ULTRA_XFER_NS_544;
13003 asc_dvc->sdtr_period_tbl[6] = SYN_ULTRA_XFER_NS_650;
13004 asc_dvc->sdtr_period_tbl[7] = SYN_ULTRA_XFER_NS_757;
13005 asc_dvc->sdtr_period_tbl[8] = SYN_ULTRA_XFER_NS_863;
13006 asc_dvc->sdtr_period_tbl[9] = SYN_ULTRA_XFER_NS_969;
13007 asc_dvc->sdtr_period_tbl[10] = SYN_ULTRA_XFER_NS_1075;
13008 asc_dvc->sdtr_period_tbl[11] = SYN_ULTRA_XFER_NS_1182;
13009 asc_dvc->sdtr_period_tbl[12] = SYN_ULTRA_XFER_NS_1288;
13010 asc_dvc->sdtr_period_tbl[13] = SYN_ULTRA_XFER_NS_1394;
13011 asc_dvc->sdtr_period_tbl[14] = SYN_ULTRA_XFER_NS_14100;
13012 asc_dvc->sdtr_period_tbl[15] = SYN_ULTRA_XFER_NS_15107;
13013 asc_dvc->max_sdtr_index = 15;
13014 if (chip_version == ASC_CHIP_VER_PCI_ULTRA_3150(0x08 | 0x02))
13015 {
13016 AscSetExtraControl(iop_base,((__builtin_constant_p((((iop_base)+(0x0D)))) && (((iop_base
)+(0x0D))) < 256) ? __outbc(((((uchar)(0x40) | (uchar)(0x20
)))),(((iop_base)+(0x0D)))) : __outb(((((uchar)(0x40) | (uchar
)(0x20)))),(((iop_base)+(0x0D)))))
13017 (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE))((__builtin_constant_p((((iop_base)+(0x0D)))) && (((iop_base
)+(0x0D))) < 256) ? __outbc(((((uchar)(0x40) | (uchar)(0x20
)))),(((iop_base)+(0x0D)))) : __outb(((((uchar)(0x40) | (uchar
)(0x20)))),(((iop_base)+(0x0D)))))
;
13018 } else if (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3050(0x08 | 0x03)) {
13019 AscSetExtraControl(iop_base,((__builtin_constant_p((((iop_base)+(0x0D)))) && (((iop_base
)+(0x0D))) < 256) ? __outbc(((((uchar)(0x40) | (uchar)(0x10
)))),(((iop_base)+(0x0D)))) : __outb(((((uchar)(0x40) | (uchar
)(0x10)))),(((iop_base)+(0x0D)))))
13020 (SEC_ACTIVE_NEGATE | SEC_ENABLE_FILTER))((__builtin_constant_p((((iop_base)+(0x0D)))) && (((iop_base
)+(0x0D))) < 256) ? __outbc(((((uchar)(0x40) | (uchar)(0x10
)))),(((iop_base)+(0x0D)))) : __outb(((((uchar)(0x40) | (uchar
)(0x10)))),(((iop_base)+(0x0D)))))
;
13021 }
13022 }
13023 if (asc_dvc->bus_type == ASC_IS_PCI(0x0004)) {
13024 AscSetExtraControl(iop_base, (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE))((__builtin_constant_p((((iop_base)+(0x0D)))) && (((iop_base
)+(0x0D))) < 256) ? __outbc(((((uchar)(0x40) | (uchar)(0x20
)))),(((iop_base)+(0x0D)))) : __outb(((((uchar)(0x40) | (uchar
)(0x20)))),(((iop_base)+(0x0D)))))
;
13025 }
13026
13027 asc_dvc->cfg->isa_dma_speed = ASC_DEF_ISA_DMA_SPEED4;
13028 if (AscGetChipBusType(iop_base) == ASC_IS_ISAPNP(0x0081)) {
13029 AscSetChipIFC(iop_base, IFC_INIT_DEFAULT)((__builtin_constant_p((((iop_base)+(0x0D)))) && (((iop_base
)+(0x0D))) < 256) ? __outbc(((((0x40) | (0x09)))),(((iop_base
)+(0x0D)))) : __outb(((((0x40) | (0x09)))),(((iop_base)+(0x0D
)))))
;
13030 asc_dvc->bus_type = ASC_IS_ISAPNP(0x0081);
13031 }
13032 if ((asc_dvc->bus_type & ASC_IS_ISA(0x0001)) != 0) {
13033 asc_dvc->cfg->isa_dma_channel = (uchar) AscGetIsaDmaChannel(iop_base);
13034 }
13035 for (i = 0; i <= ASC_MAX_TID7; i++) {
13036 asc_dvc->cur_dvc_qng[i] = 0;
13037 asc_dvc->max_dvc_qng[i] = ASC_MAX_SCSI1_QNG4;
13038 asc_dvc->scsiq_busy_head[i] = (ASC_SCSI_Q *) 0L;
13039 asc_dvc->scsiq_busy_tail[i] = (ASC_SCSI_Q *) 0L;
13040 asc_dvc->cfg->max_tag_qng[i] = ASC_MAX_INRAM_TAG_QNG16;
13041 }
13042 return (warn_code);
13043}
13044
13045ASC_INITFUNC(static ushort AscInitFromEEP( ASC_DVC_VAR * asc_dvc)
13046STATIC ushortstatic ushort AscInitFromEEP( ASC_DVC_VAR * asc_dvc)
13047AscInitFromEEP(static ushort AscInitFromEEP( ASC_DVC_VAR * asc_dvc)
13048 ASC_DVC_VAR asc_ptr_type * asc_dvcstatic ushort AscInitFromEEP( ASC_DVC_VAR * asc_dvc)
13049)static ushort AscInitFromEEP( ASC_DVC_VAR * asc_dvc)
13050)static ushort AscInitFromEEP( ASC_DVC_VAR * asc_dvc)
13051{
13052 ASCEEP_CONFIG eep_config_buf;
13053 ASCEEP_CONFIG *eep_config;
13054 PortAddrunsigned short iop_base;
13055 ushort chksum;
13056 ushort warn_code;
13057 ushort cfg_msw, cfg_lsw;
13058 int i;
13059 int write_eep = 0;
13060
13061 iop_base = asc_dvc->iop_base;
13062 warn_code = 0;
13063 AscWriteLramWord(iop_base, ASCV_HALTCODE_W(ushort)0x0040, 0x00FE);
13064 AscStopQueueExe(iop_base);
13065 if ((AscStopChip(iop_base) == FALSE0) ||
13066 (AscGetChipScsiCtrl(iop_base) != 0)) {
13067 asc_dvc->init_state |= ASC_INIT_RESET_SCSI_DONE0x0100;
13068 AscResetChipAndScsiBus(asc_dvc);
13069 DvcSleepMilliSecond((ulong) ((ushort) asc_dvc->scsi_reset_wait * 1000));
13070 }
13071 if (AscIsChipHalted(iop_base) == FALSE0) {
13072 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP0x0008;
13073 return (warn_code);
13074 }
13075 AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR)((__builtin_constant_p((((iop_base)+(0x0C)))) && (((iop_base
)+(0x0C))) < 256) ? __outwc(((0x0080)),(((iop_base)+(0x0C)
))) : __outw(((0x0080)),(((iop_base)+(0x0C)))))
;
13076 if (AscGetPCAddr(iop_base)(ushort)((__builtin_constant_p(((iop_base)+(0x0C))) &&
((iop_base)+(0x0C)) < 256) ? __inwc((iop_base)+(0x0C)) : __inw
((iop_base)+(0x0C)))
!= ASC_MCODE_START_ADDR0x0080) {
13077 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR0x0004;
13078 return (warn_code);
13079 }
13080 eep_config = (ASCEEP_CONFIG *) & eep_config_buf;
13081 cfg_msw = AscGetChipCfgMsw(iop_base)(ushort)((__builtin_constant_p(((iop_base)+(0x04))) &&
((iop_base)+(0x04)) < 256) ? __inwc((iop_base)+(0x04)) : __inw
((iop_base)+(0x04)))
;
13082 cfg_lsw = AscGetChipCfgLsw(iop_base)(ushort)((__builtin_constant_p(((iop_base)+(0x02))) &&
((iop_base)+(0x02)) < 256) ? __inwc((iop_base)+(0x02)) : __inw
((iop_base)+(0x02)))
;
13083 if ((cfg_msw & ASC_CFG_MSW_CLR_MASK0x3080) != 0) {
13084 cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK0x3080));
13085 warn_code |= ASC_WARN_CFG_MSW_RECOVER0x0040;
13086 AscSetChipCfgMsw(iop_base, cfg_msw)((__builtin_constant_p((((iop_base)+(0x04)))) && (((iop_base
)+(0x04))) < 256) ? __outwc(((cfg_msw)),(((iop_base)+(0x04
)))) : __outw(((cfg_msw)),(((iop_base)+(0x04)))))
;
13087 }
13088 chksum = AscGetEEPConfig(iop_base, eep_config, asc_dvc->bus_type);
13089 if (chksum == 0) {
13090 chksum = 0xaa55;
13091 }
13092 if (AscGetChipStatus(iop_base)(unsigned short)((__builtin_constant_p(((iop_base)+(0x0E))) &&
((iop_base)+(0x0E)) < 256) ? __inwc((iop_base)+(0x0E)) : __inw
((iop_base)+(0x0E)))
& CSW_AUTO_CONFIG(unsigned short)0x4000) {
13093 warn_code |= ASC_WARN_AUTO_CONFIG0x0008;
13094 if (asc_dvc->cfg->chip_version == 3) {
13095 if (eep_config->cfg_lsw != cfg_lsw) {
13096 warn_code |= ASC_WARN_EEPROM_RECOVER0x0020;
13097 eep_config->cfg_lsw = AscGetChipCfgLsw(iop_base)(ushort)((__builtin_constant_p(((iop_base)+(0x02))) &&
((iop_base)+(0x02)) < 256) ? __inwc((iop_base)+(0x02)) : __inw
((iop_base)+(0x02)))
;
13098 }
13099 if (eep_config->cfg_msw != cfg_msw) {
13100 warn_code |= ASC_WARN_EEPROM_RECOVER0x0020;
13101 eep_config->cfg_msw = AscGetChipCfgMsw(iop_base)(ushort)((__builtin_constant_p(((iop_base)+(0x04))) &&
((iop_base)+(0x04)) < 256) ? __inwc((iop_base)+(0x04)) : __inw
((iop_base)+(0x04)))
;
13102 }
13103 }
13104 }
13105 eep_config->cfg_msw &= ~ASC_CFG_MSW_CLR_MASK0x3080;
13106 eep_config->cfg_lsw |= ASC_CFG0_HOST_INT_ON0x0020;
13107 if (chksum != eep_config->chksum) {
13108 if (AscGetChipVersion(iop_base, asc_dvc->bus_type) ==
13109 ASC_CHIP_VER_PCI_ULTRA_3050(0x08 | 0x03) )
13110 {
13111 eep_config->init_sdtr = 0xFF;
13112 eep_config->disc_enable = 0xFF;
13113 eep_config->start_motor = 0xFF;
13114 eep_config->use_cmd_qng = 0;
13115 eep_config->max_total_qng = 0xF0;
13116 eep_config->max_tag_qng = 0x20;
13117 eep_config->cntl = 0xBFFF;
13118 eep_config->chip_scsi_id = 7;
13119 eep_config->no_scam = 0;
13120 eep_config->adapter_info[0] = 0;
13121 eep_config->adapter_info[1] = 0;
13122 eep_config->adapter_info[2] = 0;
13123 eep_config->adapter_info[3] = 0;
13124 eep_config->adapter_info[4] = 0;
13125 /* Indicate EEPROM-less board. */
13126 eep_config->adapter_info[5] = 0xBB;
13127 } else {
13128 write_eep = 1 ;
13129 warn_code |= ASC_WARN_EEPROM_CHKSUM0x0002 ;
13130 }
13131 }
13132 asc_dvc->cfg->sdtr_enable = eep_config->init_sdtr ;
13133 asc_dvc->cfg->disc_enable = eep_config->disc_enable;
13134 asc_dvc->cfg->cmd_qng_enabled = eep_config->use_cmd_qng;
13135 asc_dvc->cfg->isa_dma_speed = eep_config->isa_dma_speed;
13136 asc_dvc->start_motor = eep_config->start_motor;
13137 asc_dvc->dvc_cntl = eep_config->cntl;
13138 asc_dvc->no_scam = eep_config->no_scam;
13139 asc_dvc->cfg->adapter_info[0] = eep_config->adapter_info[0];
13140 asc_dvc->cfg->adapter_info[1] = eep_config->adapter_info[1];
13141 asc_dvc->cfg->adapter_info[2] = eep_config->adapter_info[2];
13142 asc_dvc->cfg->adapter_info[3] = eep_config->adapter_info[3];
13143 asc_dvc->cfg->adapter_info[4] = eep_config->adapter_info[4];
13144 asc_dvc->cfg->adapter_info[5] = eep_config->adapter_info[5];
13145 if (!AscTestExternalLram(asc_dvc)) {
13146 if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA(0x0104)) == ASC_IS_PCI_ULTRA(0x0104))) {
13147 eep_config->max_total_qng = ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG16;
13148 eep_config->max_tag_qng = ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG8;
13149 } else {
13150 eep_config->cfg_msw |= 0x0800;
13151 cfg_msw |= 0x0800;
13152 AscSetChipCfgMsw(iop_base, cfg_msw)((__builtin_constant_p((((iop_base)+(0x04)))) && (((iop_base
)+(0x04))) < 256) ? __outwc(((cfg_msw)),(((iop_base)+(0x04
)))) : __outw(((cfg_msw)),(((iop_base)+(0x04)))))
;
13153 eep_config->max_total_qng = ASC_MAX_PCI_INRAM_TOTAL_QNG20;
13154 eep_config->max_tag_qng = ASC_MAX_INRAM_TAG_QNG16;
13155 }
13156 } else {
13157 }
13158 if (eep_config->max_total_qng < ASC_MIN_TOTAL_QNG((7)+((0x02)))) {
13159 eep_config->max_total_qng = ASC_MIN_TOTAL_QNG((7)+((0x02)));
13160 }
13161 if (eep_config->max_total_qng > ASC_MAX_TOTAL_QNG240) {
13162 eep_config->max_total_qng = ASC_MAX_TOTAL_QNG240;
13163 }
13164 if (eep_config->max_tag_qng > eep_config->max_total_qng) {
13165 eep_config->max_tag_qng = eep_config->max_total_qng;
13166 }
13167 if (eep_config->max_tag_qng < ASC_MIN_TAG_Q_PER_DVC(0x04)) {
13168 eep_config->max_tag_qng = ASC_MIN_TAG_Q_PER_DVC(0x04);
13169 }
13170 asc_dvc->max_total_qng = eep_config->max_total_qng;
13171 if ((eep_config->use_cmd_qng & eep_config->disc_enable) !=
13172 eep_config->use_cmd_qng) {
13173 eep_config->disc_enable = eep_config->use_cmd_qng;
13174 warn_code |= ASC_WARN_CMD_QNG_CONFLICT0x0010;
13175 }
13176 if (asc_dvc->bus_type & (ASC_IS_ISA(0x0001) | ASC_IS_VL(0x0040) | ASC_IS_EISA(0x0002))) {
13177 asc_dvc->irq_no = AscGetChipIRQ(iop_base, asc_dvc->bus_type);
13178 }
13179 eep_config->chip_scsi_id &= ASC_MAX_TID7;
13180 asc_dvc->cfg->chip_scsi_id = eep_config->chip_scsi_id;
13181 if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA(0x0104)) == ASC_IS_PCI_ULTRA(0x0104)) &&
13182 !(asc_dvc->dvc_cntl & ASC_CNTL_SDTR_ENABLE_ULTRA(ushort)0x4000)) {
13183 asc_dvc->host_init_sdtr_index = ASC_SDTR_ULTRA_PCI_10MB_INDEX0x02;
13184 }
13185
13186 for (i = 0; i <= ASC_MAX_TID7; i++) {
13187 asc_dvc->dos_int13_table[i] = eep_config->dos_int13_table[i];
13188 asc_dvc->cfg->max_tag_qng[i] = eep_config->max_tag_qng;
13189 asc_dvc->cfg->sdtr_period_offset[i] =
13190 (uchar) (ASC_DEF_SDTR_OFFSET0x0F |
13191 (asc_dvc->host_init_sdtr_index << 4));
13192 }
13193 eep_config->cfg_msw = AscGetChipCfgMsw(iop_base)(ushort)((__builtin_constant_p(((iop_base)+(0x04))) &&
((iop_base)+(0x04)) < 256) ? __inwc((iop_base)+(0x04)) : __inw
((iop_base)+(0x04)))
;
13194 if (write_eep) {
13195 (void) AscSetEEPConfig(iop_base, eep_config, asc_dvc->bus_type);
13196 }
13197 return (warn_code);
13198}
13199
13200ASC_INITFUNC(static ushort AscInitMicroCodeVar( ASC_DVC_VAR * asc_dvc)
13201STATIC ushortstatic ushort AscInitMicroCodeVar( ASC_DVC_VAR * asc_dvc)
13202AscInitMicroCodeVar(static ushort AscInitMicroCodeVar( ASC_DVC_VAR * asc_dvc)
13203 ASC_DVC_VAR asc_ptr_type * asc_dvcstatic ushort AscInitMicroCodeVar( ASC_DVC_VAR * asc_dvc)
13204)static ushort AscInitMicroCodeVar( ASC_DVC_VAR * asc_dvc)
13205)static ushort AscInitMicroCodeVar( ASC_DVC_VAR * asc_dvc)
13206{
13207 int i;
13208 ushort warn_code;
13209 PortAddrunsigned short iop_base;
13210 ulong phy_addr;
13211
13212 iop_base = asc_dvc->iop_base;
13213 warn_code = 0;
13214 for (i = 0; i <= ASC_MAX_TID7; i++) {
13215 AscPutMCodeInitSDTRAtID(iop_base, i,AscWriteLramByte((iop_base), (ushort)((ushort)((0x0000 +8)+8)
+(ushort)i), asc_dvc->cfg->sdtr_period_offset[i]) ;
13216 asc_dvc->cfg->sdtr_period_offset[i]AscWriteLramByte((iop_base), (ushort)((ushort)((0x0000 +8)+8)
+(ushort)i), asc_dvc->cfg->sdtr_period_offset[i]) ;
13217)AscWriteLramByte((iop_base), (ushort)((ushort)((0x0000 +8)+8)
+(ushort)i), asc_dvc->cfg->sdtr_period_offset[i]) ;
;
13218 }
13219 AscInitQLinkVar(asc_dvc);
13220 AscWriteLramByte(iop_base, ASCV_DISC_ENABLE_B(ushort)0x0052,
13221 asc_dvc->cfg->disc_enable);
13222 AscWriteLramByte(iop_base, ASCV_HOSTSCSI_ID_B(ushort)0x0055,
13223 ASC_TID_TO_TARGET_ID(asc_dvc->cfg->chip_scsi_id)(uchar)(0x01 << (asc_dvc->cfg->chip_scsi_id)));
13224 if ((phy_addr = AscGetOnePhyAddr(asc_dvc,
13225 (uchar *) asc_dvc->cfg->overrun_buf,
13226 ASC_OVERRUN_BSIZE0x00000048UL)) == 0L) {
13227 asc_dvc->err_code |= ASC_IERR_GET_PHY_ADDR0x0100;
13228 } else {
13229 phy_addr = (phy_addr & 0xFFFFFFF8UL) + 8;
13230 AscWriteLramDWord(iop_base, ASCV_OVERRUN_PADDR_D(ushort)0x0038, phy_addr);
13231 AscWriteLramDWord(iop_base, ASCV_OVERRUN_BSIZE_D(ushort)0x003C,
13232 ASC_OVERRUN_BSIZE0x00000048UL - 8);
13233 }
13234 asc_dvc->cfg->mcode_date = AscReadLramWord(iop_base,
13235 (ushort) ASCV_MC_DATE_W(ushort)0x0044);
13236 asc_dvc->cfg->mcode_version = AscReadLramWord(iop_base,
13237 (ushort) ASCV_MC_VER_W(ushort)0x0046);
13238 AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR)((__builtin_constant_p((((iop_base)+(0x0C)))) && (((iop_base
)+(0x0C))) < 256) ? __outwc(((0x0080)),(((iop_base)+(0x0C)
))) : __outw(((0x0080)),(((iop_base)+(0x0C)))))
;
13239 if (AscGetPCAddr(iop_base)(ushort)((__builtin_constant_p(((iop_base)+(0x0C))) &&
((iop_base)+(0x0C)) < 256) ? __inwc((iop_base)+(0x0C)) : __inw
((iop_base)+(0x0C)))
!= ASC_MCODE_START_ADDR0x0080) {
13240 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR0x0004;
13241 return (warn_code);
13242 }
13243 if (AscStartChip(iop_base) != 1) {
13244 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP0x0008;
13245 return (warn_code);
13246 }
13247 return (warn_code);
13248}
13249
13250ASC_INITFUNC(static int AscTestExternalLram( ASC_DVC_VAR * asc_dvc)
13251STATIC intstatic int AscTestExternalLram( ASC_DVC_VAR * asc_dvc)
13252AscTestExternalLram(static int AscTestExternalLram( ASC_DVC_VAR * asc_dvc)
13253 ASC_DVC_VAR asc_ptr_type * asc_dvcstatic int AscTestExternalLram( ASC_DVC_VAR * asc_dvc)
13254)static int AscTestExternalLram( ASC_DVC_VAR * asc_dvc)
13255)static int AscTestExternalLram( ASC_DVC_VAR * asc_dvc)
13256{
13257 PortAddrunsigned short iop_base;
13258 ushort q_addr;
13259 ushort saved_word;
13260 int sta;
13261
13262 iop_base = asc_dvc->iop_base;
13263 sta = 0;
13264 q_addr = ASC_QNO_TO_QADDR(241)(((0x4000))+((int)(241) << 6));
13265 saved_word = AscReadLramWord(iop_base, q_addr);
13266 AscSetChipLramAddr(iop_base, q_addr)((__builtin_constant_p((((unsigned short)((iop_base)+(0x0A)))
)) && (((unsigned short)((iop_base)+(0x0A)))) < 256
) ? __outwc(((q_addr)),(((unsigned short)((iop_base)+(0x0A)))
)) : __outw(((q_addr)),(((unsigned short)((iop_base)+(0x0A)))
)))
;
13267 AscSetChipLramData(iop_base, 0x55AA)((__builtin_constant_p((((iop_base)+(0x08)))) && (((iop_base
)+(0x08))) < 256) ? __outwc(((0x55AA)),(((iop_base)+(0x08)
))) : __outw(((0x55AA)),(((iop_base)+(0x08)))))
;
13268 DvcSleepMilliSecond(10);
13269 AscSetChipLramAddr(iop_base, q_addr)((__builtin_constant_p((((unsigned short)((iop_base)+(0x0A)))
)) && (((unsigned short)((iop_base)+(0x0A)))) < 256
) ? __outwc(((q_addr)),(((unsigned short)((iop_base)+(0x0A)))
)) : __outw(((q_addr)),(((unsigned short)((iop_base)+(0x0A)))
)))
;
13270 if (AscGetChipLramData(iop_base)(ushort)((__builtin_constant_p(((iop_base)+(0x08))) &&
((iop_base)+(0x08)) < 256) ? __inwc((iop_base)+(0x08)) : __inw
((iop_base)+(0x08)))
== 0x55AA) {
13271 sta = 1;
13272 AscWriteLramWord(iop_base, q_addr, saved_word);
13273 }
13274 return (sta);
13275}
13276
13277ASC_INITFUNC(static int AscWriteEEPCmdReg( unsigned short iop_base, uchar cmd_reg
)
13278STATIC intstatic int AscWriteEEPCmdReg( unsigned short iop_base, uchar cmd_reg
)
13279AscWriteEEPCmdReg(static int AscWriteEEPCmdReg( unsigned short iop_base, uchar cmd_reg
)
13280 PortAddr iop_base,static int AscWriteEEPCmdReg( unsigned short iop_base, uchar cmd_reg
)
13281 uchar cmd_regstatic int AscWriteEEPCmdReg( unsigned short iop_base, uchar cmd_reg
)
13282)static int AscWriteEEPCmdReg( unsigned short iop_base, uchar cmd_reg
)
13283)static int AscWriteEEPCmdReg( unsigned short iop_base, uchar cmd_reg
)
13284{
13285 uchar read_back;
13286 int retry;
13287
13288 retry = 0;
13289 while (TRUE1) {
13290 AscSetChipEEPCmd(iop_base, cmd_reg)((__builtin_constant_p((((iop_base)+(0x07)))) && (((iop_base
)+(0x07))) < 256) ? __outbc(((cmd_reg)),(((iop_base)+(0x07
)))) : __outb(((cmd_reg)),(((iop_base)+(0x07)))))
;
13291 DvcSleepMilliSecond(1);
13292 read_back = AscGetChipEEPCmd(iop_base)(uchar)((__builtin_constant_p(((iop_base)+(0x07))) &&
((iop_base)+(0x07)) < 256) ? __inbc((iop_base)+(0x07)) : __inb
((iop_base)+(0x07)))
;
13293 if (read_back == cmd_reg) {
13294 return (1);
13295 }
13296 if (retry++ > ASC_EEP_MAX_RETRY20) {
13297 return (0);
13298 }
13299 }
13300}
13301
13302ASC_INITFUNC(static int AscWriteEEPDataReg( unsigned short iop_base, ushort
data_reg)
13303STATIC intstatic int AscWriteEEPDataReg( unsigned short iop_base, ushort
data_reg)
13304AscWriteEEPDataReg(static int AscWriteEEPDataReg( unsigned short iop_base, ushort
data_reg)
13305 PortAddr iop_base,static int AscWriteEEPDataReg( unsigned short iop_base, ushort
data_reg)
13306 ushort data_regstatic int AscWriteEEPDataReg( unsigned short iop_base, ushort
data_reg)
13307)static int AscWriteEEPDataReg( unsigned short iop_base, ushort
data_reg)
13308)static int AscWriteEEPDataReg( unsigned short iop_base, ushort
data_reg)
13309{
13310 ushort read_back;
13311 int retry;
13312
13313 retry = 0;
13314 while (TRUE1) {
13315 AscSetChipEEPData(iop_base, data_reg)((__builtin_constant_p((((iop_base)+(0x06)))) && (((iop_base
)+(0x06))) < 256) ? __outwc(((data_reg)),(((iop_base)+(0x06
)))) : __outw(((data_reg)),(((iop_base)+(0x06)))))
;
13316 DvcSleepMilliSecond(1);
13317 read_back = AscGetChipEEPData(iop_base)(ushort)((__builtin_constant_p(((iop_base)+(0x06))) &&
((iop_base)+(0x06)) < 256) ? __inwc((iop_base)+(0x06)) : __inw
((iop_base)+(0x06)))
;
13318 if (read_back == data_reg) {
13319 return (1);
13320 }
13321 if (retry++ > ASC_EEP_MAX_RETRY20) {
13322 return (0);
13323 }
13324 }
13325}
13326
13327ASC_INITFUNC(static void AscWaitEEPRead( void)
13328STATIC voidstatic void AscWaitEEPRead( void)
13329AscWaitEEPRead(static void AscWaitEEPRead( void)
13330 voidstatic void AscWaitEEPRead( void)
13331)static void AscWaitEEPRead( void)
13332)static void AscWaitEEPRead( void)
13333{
13334 DvcSleepMilliSecond(1);
13335 return;
13336}
13337
13338ASC_INITFUNC(static void AscWaitEEPWrite( void)
13339STATIC voidstatic void AscWaitEEPWrite( void)
13340AscWaitEEPWrite(static void AscWaitEEPWrite( void)
13341 voidstatic void AscWaitEEPWrite( void)
13342)static void AscWaitEEPWrite( void)
13343)static void AscWaitEEPWrite( void)
13344{
13345 DvcSleepMilliSecond(20);
13346 return;
13347}
13348
13349ASC_INITFUNC(static ushort AscReadEEPWord( unsigned short iop_base, uchar addr
)
13350STATIC ushortstatic ushort AscReadEEPWord( unsigned short iop_base, uchar addr
)
13351AscReadEEPWord(static ushort AscReadEEPWord( unsigned short iop_base, uchar addr
)
13352 PortAddr iop_base,static ushort AscReadEEPWord( unsigned short iop_base, uchar addr
)
13353 uchar addrstatic ushort AscReadEEPWord( unsigned short iop_base, uchar addr
)
13354)static ushort AscReadEEPWord( unsigned short iop_base, uchar addr
)
13355)static ushort AscReadEEPWord( unsigned short iop_base, uchar addr
)
13356{
13357 ushort read_wval;
13358 uchar cmd_reg;
13359
13360 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE0x00);
13361 AscWaitEEPRead();
13362 cmd_reg = addr | ASC_EEP_CMD_READ0x80;
13363 AscWriteEEPCmdReg(iop_base, cmd_reg);
13364 AscWaitEEPRead();
13365 read_wval = AscGetChipEEPData(iop_base)(ushort)((__builtin_constant_p(((iop_base)+(0x06))) &&
((iop_base)+(0x06)) < 256) ? __inwc((iop_base)+(0x06)) : __inw
((iop_base)+(0x06)))
;
13366 AscWaitEEPRead();
13367 return (read_wval);
13368}
13369
13370ASC_INITFUNC(static ushort AscWriteEEPWord( unsigned short iop_base, uchar
addr, ushort word_val)
13371STATIC ushortstatic ushort AscWriteEEPWord( unsigned short iop_base, uchar
addr, ushort word_val)
13372AscWriteEEPWord(static ushort AscWriteEEPWord( unsigned short iop_base, uchar
addr, ushort word_val)
13373 PortAddr iop_base,static ushort AscWriteEEPWord( unsigned short iop_base, uchar
addr, ushort word_val)
13374 uchar addr,static ushort AscWriteEEPWord( unsigned short iop_base, uchar
addr, ushort word_val)
13375 ushort word_valstatic ushort AscWriteEEPWord( unsigned short iop_base, uchar
addr, ushort word_val)
13376)static ushort AscWriteEEPWord( unsigned short iop_base, uchar
addr, ushort word_val)
13377)static ushort AscWriteEEPWord( unsigned short iop_base, uchar
addr, ushort word_val)
13378{
13379 ushort read_wval;
13380
13381 read_wval = AscReadEEPWord(iop_base, addr);
13382 if (read_wval != word_val) {
13383 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_ABLE0x30);
13384 AscWaitEEPRead();
13385 AscWriteEEPDataReg(iop_base, word_val);
13386 AscWaitEEPRead();
13387 AscWriteEEPCmdReg(iop_base,
13388 (uchar) ((uchar) ASC_EEP_CMD_WRITE0x40 | addr));
13389 AscWaitEEPWrite();
13390 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE0x00);
13391 AscWaitEEPRead();
13392 return (AscReadEEPWord(iop_base, addr));
13393 }
13394 return (read_wval);
13395}
13396
13397ASC_INITFUNC(static ushort AscGetEEPConfig( unsigned short iop_base, ASCEEP_CONFIG
* cfg_buf, ushort bus_type)
13398STATIC ushortstatic ushort AscGetEEPConfig( unsigned short iop_base, ASCEEP_CONFIG
* cfg_buf, ushort bus_type)
13399AscGetEEPConfig(static ushort AscGetEEPConfig( unsigned short iop_base, ASCEEP_CONFIG
* cfg_buf, ushort bus_type)
13400 PortAddr iop_base,static ushort AscGetEEPConfig( unsigned short iop_base, ASCEEP_CONFIG
* cfg_buf, ushort bus_type)
13401 ASCEEP_CONFIG * cfg_buf, ushort bus_typestatic ushort AscGetEEPConfig( unsigned short iop_base, ASCEEP_CONFIG
* cfg_buf, ushort bus_type)
13402)static ushort AscGetEEPConfig( unsigned short iop_base, ASCEEP_CONFIG
* cfg_buf, ushort bus_type)
13403)static ushort AscGetEEPConfig( unsigned short iop_base, ASCEEP_CONFIG
* cfg_buf, ushort bus_type)
13404{
13405 ushort wval;
13406 ushort sum;
13407 ushort *wbuf;
13408 int cfg_beg;
13409 int cfg_end;
13410 int s_addr;
13411 int isa_pnp_wsize;
13412
13413 wbuf = (ushort *) cfg_buf;
13414 sum = 0;
13415 isa_pnp_wsize = 0;
13416 for (s_addr = 0; s_addr < (2 + isa_pnp_wsize); s_addr++, wbuf++) {
13417 wval = AscReadEEPWord(iop_base, (uchar) s_addr);
13418 sum += wval;
13419 *wbuf = wval;
13420 }
13421 if (bus_type & ASC_IS_VL(0x0040)) {
13422 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL2;
13423 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL15;
13424 } else {
13425 cfg_beg = ASC_EEP_DVC_CFG_BEG32;
13426 cfg_end = ASC_EEP_MAX_DVC_ADDR45;
13427 }
13428 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1);
13429 s_addr++, wbuf++) {
13430 wval = AscReadEEPWord(iop_base, (uchar) s_addr);
13431 sum += wval;
13432 *wbuf = wval;
13433 }
13434 *wbuf = AscReadEEPWord(iop_base, (uchar) s_addr);
13435 return (sum);
13436}
13437
13438ASC_INITFUNC(static int AscSetEEPConfigOnce( unsigned short iop_base, ASCEEP_CONFIG
* cfg_buf, ushort bus_type)
13439STATIC intstatic int AscSetEEPConfigOnce( unsigned short iop_base, ASCEEP_CONFIG
* cfg_buf, ushort bus_type)
13440AscSetEEPConfigOnce(static int AscSetEEPConfigOnce( unsigned short iop_base, ASCEEP_CONFIG
* cfg_buf, ushort bus_type)
13441 PortAddr iop_base,static int AscSetEEPConfigOnce( unsigned short iop_base, ASCEEP_CONFIG
* cfg_buf, ushort bus_type)
13442 ASCEEP_CONFIG * cfg_buf, ushort bus_typestatic int AscSetEEPConfigOnce( unsigned short iop_base, ASCEEP_CONFIG
* cfg_buf, ushort bus_type)
13443)static int AscSetEEPConfigOnce( unsigned short iop_base, ASCEEP_CONFIG
* cfg_buf, ushort bus_type)
13444)static int AscSetEEPConfigOnce( unsigned short iop_base, ASCEEP_CONFIG
* cfg_buf, ushort bus_type)
13445{
13446 int n_error;
13447 ushort *wbuf;
13448 ushort sum;
13449 int s_addr;
13450 int cfg_beg;
13451 int cfg_end;
13452
13453 wbuf = (ushort *) cfg_buf;
13454 n_error = 0;
13455 sum = 0;
13456 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
13457 sum += *wbuf;
13458 if (*wbuf != AscWriteEEPWord(iop_base, (uchar) s_addr, *wbuf)) {
13459 n_error++;
13460 }
13461 }
13462 if (bus_type & ASC_IS_VL(0x0040)) {
13463 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL2;
13464 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL15;
13465 } else {
13466 cfg_beg = ASC_EEP_DVC_CFG_BEG32;
13467 cfg_end = ASC_EEP_MAX_DVC_ADDR45;
13468 }
13469 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1);
13470 s_addr++, wbuf++) {
13471 sum += *wbuf;
13472 if (*wbuf != AscWriteEEPWord(iop_base, (uchar) s_addr, *wbuf)) {
13473 n_error++;
13474 }
13475 }
13476 *wbuf = sum;
13477 if (sum != AscWriteEEPWord(iop_base, (uchar) s_addr, sum)) {
13478 n_error++;
13479 }
13480 wbuf = (ushort *) cfg_buf;
13481 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
13482 if (*wbuf != AscReadEEPWord(iop_base, (uchar) s_addr)) {
13483 n_error++;
13484 }
13485 }
13486 for (s_addr = cfg_beg; s_addr <= cfg_end;
13487 s_addr++, wbuf++) {
13488 if (*wbuf != AscReadEEPWord(iop_base, (uchar) s_addr)) {
13489 n_error++;
13490 }
13491 }
13492 return (n_error);
13493}
13494
13495ASC_INITFUNC(static int AscSetEEPConfig( unsigned short iop_base, ASCEEP_CONFIG
* cfg_buf, ushort bus_type)
13496STATIC intstatic int AscSetEEPConfig( unsigned short iop_base, ASCEEP_CONFIG
* cfg_buf, ushort bus_type)
13497AscSetEEPConfig(static int AscSetEEPConfig( unsigned short iop_base, ASCEEP_CONFIG
* cfg_buf, ushort bus_type)
13498 PortAddr iop_base,static int AscSetEEPConfig( unsigned short iop_base, ASCEEP_CONFIG
* cfg_buf, ushort bus_type)
13499 ASCEEP_CONFIG * cfg_buf, ushort bus_typestatic int AscSetEEPConfig( unsigned short iop_base, ASCEEP_CONFIG
* cfg_buf, ushort bus_type)
13500)static int AscSetEEPConfig( unsigned short iop_base, ASCEEP_CONFIG
* cfg_buf, ushort bus_type)
13501)static int AscSetEEPConfig( unsigned short iop_base, ASCEEP_CONFIG
* cfg_buf, ushort bus_type)
13502{
13503 int retry;
13504 int n_error;
13505
13506 retry = 0;
13507 while (TRUE1) {
13508 if ((n_error = AscSetEEPConfigOnce(iop_base, cfg_buf,
13509 bus_type)) == 0) {
13510 break;
13511 }
13512 if (++retry > ASC_EEP_MAX_RETRY20) {
13513 break;
13514 }
13515 }
13516 return (n_error);
13517}
13518
13519STATICstatic void
13520AscAsyncFix(
13521 ASC_DVC_VAR asc_ptr_type *asc_dvc,
13522 uchar tid_no,
13523 ASC_SCSI_INQUIRY *inq)
13524{
13525 uchar dvc_type;
13526 ASC_SCSI_BIT_ID_TYPEuchar tid_bits;
13527
13528 dvc_type = inq->byte0.peri_dvc_type;
13529 tid_bits = ASC_TIX_TO_TARGET_ID(tid_no)(0x01 << ((tid_no) & 7));
13530
13531 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ASYN_USE_SYN0x0002) {
13532 if (!(asc_dvc->init_sdtr & tid_bits)) {
13533 if ((dvc_type == SCSI_TYPE_CDROM0x05) &&
13534 (AscCompareString((uchar *) inq->vendor_id,
13535 (uchar *) "HP ", 3) == 0)) {
13536 asc_dvc->pci_fix_asyn_xfer_always |= tid_bits;
13537 }
13538 asc_dvc->pci_fix_asyn_xfer |= tid_bits;
13539 if ((dvc_type == SCSI_TYPE_PROC0x03) ||
13540 (dvc_type == SCSI_TYPE_SCANNER0x06)) {
13541 asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
13542 }
13543 if ((dvc_type == SCSI_TYPE_SASD0x01) &&
13544 (AscCompareString((uchar *) inq->vendor_id,
13545 (uchar *) "TANDBERG", 8) == 0) &&
13546 (AscCompareString((uchar *) inq->product_id,
13547 (uchar *) " TDC 36", 7) == 0)) {
13548 asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
13549 }
13550 if ((dvc_type == SCSI_TYPE_SASD0x01) &&
13551 (AscCompareString((uchar *) inq->vendor_id,
13552 (uchar *) "WANGTEK ", 8) == 0)) {
13553 asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
13554 }
13555
13556 if ((dvc_type == SCSI_TYPE_CDROM0x05) &&
13557 (AscCompareString((uchar *) inq->vendor_id,
13558 (uchar *) "NEC ", 8) == 0) &&
13559 (AscCompareString((uchar *) inq->product_id,
13560 (uchar *) "CD-ROM DRIVE ", 16) == 0)) {
13561 asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
13562 }
13563
13564 if ((dvc_type == SCSI_TYPE_CDROM0x05) &&
13565 (AscCompareString((uchar *) inq->vendor_id,
13566 (uchar *) "YAMAHA", 6) == 0) &&
13567 (AscCompareString((uchar *) inq->product_id,
13568 (uchar *) "CDR400", 6) == 0)) {
13569 asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
13570 }
13571 if (asc_dvc->pci_fix_asyn_xfer & tid_bits) {
13572 AscSetRunChipSynRegAtID(asc_dvc->iop_base, tid_no,
13573 ASYN_SDTR_DATA_FIX_PCI_REV_AB0x41);
13574 }
13575 }
13576 }
13577 return;
13578}
13579
13580STATICstatic int
13581AscTagQueuingSafe(ASC_SCSI_INQUIRY *inq)
13582{
13583 if ((inq->add_len >= 32) &&
13584 (AscCompareString((uchar *) inq->vendor_id,
13585 (uchar *) "QUANTUM XP34301", 15) == 0) &&
13586 (AscCompareString((uchar *) inq->product_rev_level,
13587 (uchar *) "1071", 4) == 0))
13588 {
13589 return 0;
13590 }
13591 return 1;
13592}
13593
13594STATICstatic void
13595AscInquiryHandling(ASC_DVC_VAR asc_ptr_type *asc_dvc,
13596 uchar tid_no, ASC_SCSI_INQUIRY *inq)
13597{
13598 ASC_SCSI_BIT_ID_TYPEuchar tid_bit = ASC_TIX_TO_TARGET_ID(tid_no)(0x01 << ((tid_no) & 7));
13599 ASC_SCSI_BIT_ID_TYPEuchar orig_init_sdtr, orig_use_tagged_qng;
13600
13601 orig_init_sdtr = asc_dvc->init_sdtr;
13602 orig_use_tagged_qng = asc_dvc->use_tagged_qng;
13603
13604 asc_dvc->init_sdtr &= ~tid_bit;
13605 asc_dvc->cfg->can_tagged_qng &= ~tid_bit;
13606 asc_dvc->use_tagged_qng &= ~tid_bit;
13607
13608 if (inq->byte3.rsp_data_fmt >= 2 || inq->byte2.ansi_apr_ver >= 2) {
13609 if ((asc_dvc->cfg->sdtr_enable & tid_bit) && inq->byte7.Sync) {
13610 asc_dvc->init_sdtr |= tid_bit;
13611 }
13612 if ((asc_dvc->cfg->cmd_qng_enabled & tid_bit) && inq->byte7.CmdQue) {
13613 if (AscTagQueuingSafe(inq)) {
13614 asc_dvc->use_tagged_qng |= tid_bit;
13615 asc_dvc->cfg->can_tagged_qng |= tid_bit;
13616 }
13617 }
13618 }
13619 if (orig_use_tagged_qng != asc_dvc->use_tagged_qng) {
13620 AscWriteLramByte(asc_dvc->iop_base, ASCV_DISC_ENABLE_B(ushort)0x0052,
13621 asc_dvc->cfg->disc_enable);
13622 AscWriteLramByte(asc_dvc->iop_base, ASCV_USE_TAGGED_QNG_B(ushort)0x004A,
13623 asc_dvc->use_tagged_qng);
13624 AscWriteLramByte(asc_dvc->iop_base, ASCV_CAN_TAGGED_QNG_B(ushort)0x0053,
13625 asc_dvc->cfg->can_tagged_qng);
13626
13627 asc_dvc->max_dvc_qng[tid_no] =
13628 asc_dvc->cfg->max_tag_qng[tid_no];
13629 AscWriteLramByte(asc_dvc->iop_base,
13630 (ushort) (ASCV_MAX_DVC_QNG_BEG(ushort)0x0020 + tid_no),
13631 asc_dvc->max_dvc_qng[tid_no]);
13632 }
13633 if (orig_init_sdtr != asc_dvc->init_sdtr) {
13634 AscAsyncFix(asc_dvc, tid_no, inq);
13635 }
13636 return;
13637}
13638
13639STATICstatic int
13640AscCompareString(
13641 rucharregister __u8 * str1,
13642 rucharregister __u8 * str2,
13643 int len
13644)
13645{
13646 int i;
13647 int diff;
13648
13649 for (i = 0; i < len; i++) {
13650 diff = (int) (str1[i] - str2[i]);
13651 if (diff != 0)
13652 return (diff);
13653 }
13654 return (0);
13655}
13656
13657STATICstatic uchar
13658AscReadLramByte(
13659 PortAddrunsigned short iop_base,
13660 ushort addr
13661)
13662{
13663 uchar byte_data;
13664 ushort word_data;
13665
13666 if (isodd_word(addr)((((uint)addr) & (uint)0x0001) != 0)) {
13667 AscSetChipLramAddr(iop_base, addr - 1)((__builtin_constant_p((((unsigned short)((iop_base)+(0x0A)))
)) && (((unsigned short)((iop_base)+(0x0A)))) < 256
) ? __outwc(((addr - 1)),(((unsigned short)((iop_base)+(0x0A)
)))) : __outw(((addr - 1)),(((unsigned short)((iop_base)+(0x0A
))))))
;
13668 word_data = AscGetChipLramData(iop_base)(ushort)((__builtin_constant_p(((iop_base)+(0x08))) &&
((iop_base)+(0x08)) < 256) ? __inwc((iop_base)+(0x08)) : __inw
((iop_base)+(0x08)))
;
13669 byte_data = (uchar) ((word_data >> 8) & 0xFF);
13670 } else {
13671 AscSetChipLramAddr(iop_base, addr)((__builtin_constant_p((((unsigned short)((iop_base)+(0x0A)))
)) && (((unsigned short)((iop_base)+(0x0A)))) < 256
) ? __outwc(((addr)),(((unsigned short)((iop_base)+(0x0A)))))
: __outw(((addr)),(((unsigned short)((iop_base)+(0x0A))))))
;
13672 word_data = AscGetChipLramData(iop_base)(ushort)((__builtin_constant_p(((iop_base)+(0x08))) &&
((iop_base)+(0x08)) < 256) ? __inwc((iop_base)+(0x08)) : __inw
((iop_base)+(0x08)))
;
13673 byte_data = (uchar) (word_data & 0xFF);
13674 }
13675 return (byte_data);
13676}
13677
13678STATICstatic ushort
13679AscReadLramWord(
13680 PortAddrunsigned short iop_base,
13681 ushort addr
13682)
13683{
13684 ushort word_data;
13685
13686 AscSetChipLramAddr(iop_base, addr)((__builtin_constant_p((((unsigned short)((iop_base)+(0x0A)))
)) && (((unsigned short)((iop_base)+(0x0A)))) < 256
) ? __outwc(((addr)),(((unsigned short)((iop_base)+(0x0A)))))
: __outw(((addr)),(((unsigned short)((iop_base)+(0x0A))))))
;
13687 word_data = AscGetChipLramData(iop_base)(ushort)((__builtin_constant_p(((iop_base)+(0x08))) &&
((iop_base)+(0x08)) < 256) ? __inwc((iop_base)+(0x08)) : __inw
((iop_base)+(0x08)))
;
13688 return (word_data);
13689}
13690
13691STATICstatic ulong
13692AscReadLramDWord(
13693 PortAddrunsigned short iop_base,
13694 ushort addr
13695)
13696{
13697 ushort val_low, val_high;
13698 ulong dword_data;
13699
13700 AscSetChipLramAddr(iop_base, addr)((__builtin_constant_p((((unsigned short)((iop_base)+(0x0A)))
)) && (((unsigned short)((iop_base)+(0x0A)))) < 256
) ? __outwc(((addr)),(((unsigned short)((iop_base)+(0x0A)))))
: __outw(((addr)),(((unsigned short)((iop_base)+(0x0A))))))
;
13701 val_low = AscGetChipLramData(iop_base)(ushort)((__builtin_constant_p(((iop_base)+(0x08))) &&
((iop_base)+(0x08)) < 256) ? __inwc((iop_base)+(0x08)) : __inw
((iop_base)+(0x08)))
;
13702 val_high = AscGetChipLramData(iop_base)(ushort)((__builtin_constant_p(((iop_base)+(0x08))) &&
((iop_base)+(0x08)) < 256) ? __inwc((iop_base)+(0x08)) : __inw
((iop_base)+(0x08)))
;
13703 dword_data = ((ulong) val_high << 16) | (ulong) val_low;
13704 return (dword_data);
13705}
13706
13707STATICstatic void
13708AscWriteLramWord(
13709 PortAddrunsigned short iop_base,
13710 ushort addr,
13711 ushort word_val
13712)
13713{
13714 AscSetChipLramAddr(iop_base, addr)((__builtin_constant_p((((unsigned short)((iop_base)+(0x0A)))
)) && (((unsigned short)((iop_base)+(0x0A)))) < 256
) ? __outwc(((addr)),(((unsigned short)((iop_base)+(0x0A)))))
: __outw(((addr)),(((unsigned short)((iop_base)+(0x0A))))))
;
13715 AscSetChipLramData(iop_base, word_val)((__builtin_constant_p((((iop_base)+(0x08)))) && (((iop_base
)+(0x08))) < 256) ? __outwc(((word_val)),(((iop_base)+(0x08
)))) : __outw(((word_val)),(((iop_base)+(0x08)))))
;
13716 return;
13717}
13718
13719STATICstatic void
13720AscWriteLramDWord(
13721 PortAddrunsigned short iop_base,
13722 ushort addr,
13723 ulong dword_val
13724)
13725{
13726 ushort word_val;
13727
13728 AscSetChipLramAddr(iop_base, addr)((__builtin_constant_p((((unsigned short)((iop_base)+(0x0A)))
)) && (((unsigned short)((iop_base)+(0x0A)))) < 256
) ? __outwc(((addr)),(((unsigned short)((iop_base)+(0x0A)))))
: __outw(((addr)),(((unsigned short)((iop_base)+(0x0A))))))
;
13729 word_val = (ushort) dword_val;
13730 AscSetChipLramData(iop_base, word_val)((__builtin_constant_p((((iop_base)+(0x08)))) && (((iop_base
)+(0x08))) < 256) ? __outwc(((word_val)),(((iop_base)+(0x08
)))) : __outw(((word_val)),(((iop_base)+(0x08)))))
;
13731 word_val = (ushort) (dword_val >> 16);
13732 AscSetChipLramData(iop_base, word_val)((__builtin_constant_p((((iop_base)+(0x08)))) && (((iop_base
)+(0x08))) < 256) ? __outwc(((word_val)),(((iop_base)+(0x08
)))) : __outw(((word_val)),(((iop_base)+(0x08)))))
;
13733 return;
13734}
13735
13736STATICstatic void
13737AscWriteLramByte(
13738 PortAddrunsigned short iop_base,
13739 ushort addr,
13740 uchar byte_val
13741)
13742{
13743 ushort word_data;
13744
13745 if (isodd_word(addr)((((uint)addr) & (uint)0x0001) != 0)) {
13746 addr--;
13747 word_data = AscReadLramWord(iop_base, addr);
13748 word_data &= 0x00FF;
13749 word_data |= (((ushort) byte_val << 8) & 0xFF00);
13750 } else {
13751 word_data = AscReadLramWord(iop_base, addr);
13752 word_data &= 0xFF00;
13753 word_data |= ((ushort) byte_val & 0x00FF);
13754 }
13755 AscWriteLramWord(iop_base, addr, word_data);
13756 return;
13757}
13758
13759STATICstatic void
13760AscMemWordCopyToLram(
13761 PortAddrunsigned short iop_base,
13762 ushort s_addr,
13763 ushort * s_buffer,
13764 int words
13765)
13766{
13767 AscSetChipLramAddr(iop_base, s_addr)((__builtin_constant_p((((unsigned short)((iop_base)+(0x0A)))
)) && (((unsigned short)((iop_base)+(0x0A)))) < 256
) ? __outwc(((s_addr)),(((unsigned short)((iop_base)+(0x0A)))
)) : __outw(((s_addr)),(((unsigned short)((iop_base)+(0x0A)))
)))
;
13768 DvcOutPortWords(iop_base + IOP_RAM_DATA(0x08), s_buffer, words);
13769 return;
13770}
13771
13772STATICstatic void
13773AscMemDWordCopyToLram(
13774 PortAddrunsigned short iop_base,
13775 ushort s_addr,
13776 ulong * s_buffer,
13777 int dwords
13778)
13779{
13780 AscSetChipLramAddr(iop_base, s_addr)((__builtin_constant_p((((unsigned short)((iop_base)+(0x0A)))
)) && (((unsigned short)((iop_base)+(0x0A)))) < 256
) ? __outwc(((s_addr)),(((unsigned short)((iop_base)+(0x0A)))
)) : __outw(((s_addr)),(((unsigned short)((iop_base)+(0x0A)))
)))
;
13781 DvcOutPortDWords(iop_base + IOP_RAM_DATA(0x08), s_buffer, dwords);
13782 return;
13783}
13784
13785STATICstatic void
13786AscMemWordCopyFromLram(
13787 PortAddrunsigned short iop_base,
13788 ushort s_addr,
13789 ushort * d_buffer,
13790 int words
13791)
13792{
13793 AscSetChipLramAddr(iop_base, s_addr)((__builtin_constant_p((((unsigned short)((iop_base)+(0x0A)))
)) && (((unsigned short)((iop_base)+(0x0A)))) < 256
) ? __outwc(((s_addr)),(((unsigned short)((iop_base)+(0x0A)))
)) : __outw(((s_addr)),(((unsigned short)((iop_base)+(0x0A)))
)))
;
13794 DvcInPortWords(iop_base + IOP_RAM_DATA(0x08), d_buffer, words);
13795 return;
13796}
13797
13798STATICstatic ulong
13799AscMemSumLramWord(
13800 PortAddrunsigned short iop_base,
13801 ushort s_addr,
13802 rintregister __s32 words
13803)
13804{
13805 ulong sum;
13806 int i;
13807
13808 sum = 0L;
13809 for (i = 0; i < words; i++, s_addr += 2) {
13810 sum += AscReadLramWord(iop_base, s_addr);
13811 }
13812 return (sum);
13813}
13814
13815STATICstatic void
13816AscMemWordSetLram(
13817 PortAddrunsigned short iop_base,
13818 ushort s_addr,
13819 ushort set_wval,
13820 rintregister __s32 words
13821)
13822{
13823 rintregister __s32 i;
13824
13825 AscSetChipLramAddr(iop_base, s_addr)((__builtin_constant_p((((unsigned short)((iop_base)+(0x0A)))
)) && (((unsigned short)((iop_base)+(0x0A)))) < 256
) ? __outwc(((s_addr)),(((unsigned short)((iop_base)+(0x0A)))
)) : __outw(((s_addr)),(((unsigned short)((iop_base)+(0x0A)))
)))
;
13826 for (i = 0; i < words; i++) {
13827 AscSetChipLramData(iop_base, set_wval)((__builtin_constant_p((((iop_base)+(0x08)))) && (((iop_base
)+(0x08))) < 256) ? __outwc(((set_wval)),(((iop_base)+(0x08
)))) : __outw(((set_wval)),(((iop_base)+(0x08)))))
;
13828 }
13829 return;
13830}
13831
13832
13833/*
13834 * --- Adv Library Functions
13835 */
13836
13837/* a_qswap.h */
13838STATICstatic unsigned char _adv_mcode_buf[] ASC_INITDATA = {
13839 0x9C, 0xF0, 0x80, 0x01, 0x00, 0xF0, 0x44, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
13840 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
13841 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x72, 0x01, 0xD6, 0x11, 0x00, 0x00, 0x70, 0x01,
13842 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x10, 0x2D, 0x03, 0x00, 0x00, 0x00, 0x00,
13843 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
13844 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
13845 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
13846 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
13847 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
13848 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
13849 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
13850 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
13851 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
13852 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
13853 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
13854 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
13855 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
13856 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
13857 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x56, 0x34, 0x12,
13858 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
13859 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
13860 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
13861 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
13862 0x00, 0x00, 0x04, 0xF7, 0x70, 0x01, 0x0C, 0x1C, 0x06, 0xF7, 0x02, 0x00, 0x00, 0xF2, 0xD6, 0x0A,
13863 0x04, 0xF7, 0x70, 0x01, 0x06, 0xF7, 0x02, 0x00, 0x3E, 0x57, 0x3C, 0x56, 0x0C, 0x1C, 0x00, 0xFC,
13864 0xA6, 0x00, 0x01, 0x58, 0xAA, 0x13, 0x20, 0xF0, 0xA6, 0x03, 0x06, 0xEC, 0xB9, 0x00, 0x0E, 0x47,
13865 0x03, 0xE6, 0x10, 0x00, 0xCE, 0x45, 0x02, 0x13, 0x3E, 0x57, 0x06, 0xEA, 0xB9, 0x00, 0x47, 0x4B,
13866 0x03, 0xF6, 0xE0, 0x00, 0x00, 0xF2, 0x68, 0x0A, 0x01, 0x48, 0x4E, 0x12, 0x03, 0xF6, 0xC0, 0x00,
13867 0x00, 0xF2, 0x68, 0x0A, 0x41, 0x58, 0x03, 0xF6, 0xD0, 0x00, 0x00, 0xF2, 0x68, 0x0A, 0x49, 0x44,
13868 0x59, 0xF0, 0x0A, 0x02, 0x03, 0xF6, 0xE0, 0x00, 0x00, 0xF2, 0x68, 0x0A, 0x44, 0x58, 0x00, 0xF2,
13869 0xE2, 0x0D, 0x02, 0xCC, 0x4A, 0xE4, 0x01, 0x00, 0x55, 0xF0, 0x08, 0x03, 0x45, 0xF4, 0x02, 0x00,
13870 0x83, 0x5A, 0x04, 0xCC, 0x01, 0x4A, 0x12, 0x12, 0x00, 0xF2, 0xE2, 0x0D, 0x00, 0xCD, 0x48, 0xE4,
13871 0x01, 0x00, 0xE9, 0x13, 0x00, 0xF2, 0xC6, 0x0F, 0xFA, 0x10, 0x0E, 0x47, 0x03, 0xE6, 0x10, 0x00,
13872 0xCE, 0x45, 0x02, 0x13, 0x3E, 0x57, 0xCE, 0x47, 0x97, 0x13, 0x04, 0xEC, 0xB4, 0x00, 0x00, 0xF2,
13873 0xE2, 0x0D, 0x00, 0xCD, 0x48, 0xE4, 0x00, 0x00, 0x12, 0x12, 0x3E, 0x57, 0x06, 0xCC, 0x45, 0xF4,
13874 0x02, 0x00, 0x83, 0x5A, 0x00, 0xCC, 0x00, 0xEA, 0xB4, 0x00, 0x92, 0x10, 0x00, 0xF0, 0x8C, 0x01,
13875 0x43, 0xF0, 0x5C, 0x02, 0x44, 0xF0, 0x60, 0x02, 0x45, 0xF0, 0x64, 0x02, 0x46, 0xF0, 0x68, 0x02,
13876 0x47, 0xF0, 0x6E, 0x02, 0x48, 0xF0, 0x9E, 0x02, 0xB9, 0x54, 0x62, 0x10, 0x00, 0x1C, 0x5A, 0x10,
13877 0x02, 0x1C, 0x56, 0x10, 0x1E, 0x1C, 0x52, 0x10, 0x00, 0xF2, 0x1E, 0x11, 0x50, 0x10, 0x06, 0xFC,
13878 0xA8, 0x00, 0x03, 0xF6, 0xBE, 0x00, 0x00, 0xF2, 0x4E, 0x0A, 0x8C, 0x10, 0x01, 0xF6, 0x01, 0x00,
13879 0x01, 0xFA, 0xA8, 0x00, 0x00, 0xF2, 0x2C, 0x0B, 0x06, 0x10, 0xB9, 0x54, 0x01, 0xFA, 0xA8, 0x00,
13880 0x03, 0xF6, 0xBE, 0x00, 0x00, 0xF2, 0x58, 0x0A, 0x01, 0xFC, 0xA8, 0x00, 0x20, 0x10, 0x58, 0x1C,
13881 0x00, 0xF2, 0x1C, 0x0B, 0x5A, 0x1C, 0x01, 0xF6, 0x01, 0x00, 0x38, 0x54, 0x00, 0xFA, 0xA6, 0x00,
13882 0x01, 0xFA, 0xA8, 0x00, 0x20, 0x1C, 0x00, 0xF0, 0x72, 0x01, 0x01, 0xF6, 0x01, 0x00, 0x38, 0x54,
13883 0x00, 0xFA, 0xA6, 0x00, 0x01, 0xFA, 0xA8, 0x00, 0x20, 0x1C, 0x00, 0xF0, 0x80, 0x01, 0x03, 0xF6,
13884 0xE0, 0x00, 0x00, 0xF2, 0x68, 0x0A, 0x01, 0x48, 0x0A, 0x13, 0x00, 0xF2, 0x38, 0x10, 0x00, 0xF2,
13885 0x54, 0x0F, 0x24, 0x10, 0x03, 0xF6, 0xC0, 0x00, 0x00, 0xF2, 0x68, 0x0A, 0x02, 0xF6, 0xD0, 0x00,
13886 0x02, 0x57, 0x03, 0x59, 0x01, 0xCC, 0x49, 0x44, 0x5B, 0xF0, 0x04, 0x03, 0x00, 0xF2, 0x9C, 0x0F,
13887 0x00, 0xF0, 0x80, 0x01, 0x00, 0xF2, 0x14, 0x10, 0x0C, 0x1C, 0x02, 0x4B, 0xBF, 0x57, 0x9E, 0x43,
13888 0x77, 0x57, 0x07, 0x4B, 0x20, 0xF0, 0xA6, 0x03, 0x40, 0x1C, 0x1E, 0xF0, 0x30, 0x03, 0x26, 0xF0,
13889 0x2C, 0x03, 0xA0, 0xF0, 0x1A, 0x03, 0x11, 0xF0, 0xA6, 0x03, 0x12, 0x10, 0x9F, 0xF0, 0x3E, 0x03,
13890 0x46, 0x1C, 0x82, 0xE7, 0x05, 0x00, 0x9E, 0xE7, 0x11, 0x00, 0x00, 0xF0, 0x06, 0x0A, 0x0C, 0x1C,
13891 0x48, 0x1C, 0x46, 0x1C, 0x38, 0x54, 0x00, 0xEC, 0xBA, 0x00, 0x08, 0x44, 0x00, 0xEA, 0xBA, 0x00,
13892 0x03, 0xF6, 0xC0, 0x00, 0x00, 0xF2, 0x68, 0x0A, 0x08, 0x44, 0x00, 0x4C, 0x82, 0xE7, 0x02, 0x00,
13893 0x00, 0xF2, 0x12, 0x11, 0x00, 0xF2, 0x12, 0x11, 0x85, 0xF0, 0x70, 0x03, 0x00, 0xF2, 0x60, 0x0B,
13894 0x06, 0xF0, 0x80, 0x03, 0x09, 0xF0, 0x24, 0x09, 0x1E, 0xF0, 0xFC, 0x09, 0x00, 0xF0, 0x02, 0x0A,
13895 0x00, 0xFC, 0xBE, 0x00, 0x98, 0x57, 0x55, 0xF0, 0xAC, 0x04, 0x01, 0xE6, 0x0C, 0x00, 0x00, 0xF2,
13896 0x4E, 0x0D, 0x00, 0xF2, 0x12, 0x11, 0x00, 0xF2, 0xBC, 0x11, 0x00, 0xF2, 0xC8, 0x11, 0x01, 0xF0,
13897 0x7C, 0x02, 0x00, 0xF0, 0x8A, 0x02, 0x46, 0x1C, 0x0C, 0x1C, 0x67, 0x1B, 0xBF, 0x57, 0x77, 0x57,
13898 0x02, 0x4B, 0x48, 0x1C, 0x32, 0x1C, 0x00, 0xF2, 0x92, 0x0D, 0x30, 0x1C, 0x96, 0xF0, 0xBC, 0x03,
13899 0xB1, 0xF0, 0xC0, 0x03, 0x1E, 0xF0, 0xFC, 0x09, 0x85, 0xF0, 0x02, 0x0A, 0x00, 0xFC, 0xBE, 0x00,
13900 0x98, 0x57, 0x14, 0x12, 0x01, 0xE6, 0x0C, 0x00, 0x00, 0xF2, 0x4E, 0x0D, 0x00, 0xF2, 0x12, 0x11,
13901 0x01, 0xF0, 0x7C, 0x02, 0x00, 0xF0, 0x8A, 0x02, 0x03, 0xF6, 0xE0, 0x00, 0x00, 0xF2, 0x68, 0x0A,
13902 0x01, 0x48, 0x55, 0xF0, 0x98, 0x04, 0x03, 0x82, 0x03, 0xFC, 0xA0, 0x00, 0x9B, 0x57, 0x40, 0x12,
13903 0x69, 0x18, 0x00, 0xF2, 0x12, 0x11, 0x85, 0xF0, 0x42, 0x04, 0x69, 0x08, 0x00, 0xF2, 0x12, 0x11,
13904 0x85, 0xF0, 0x02, 0x0A, 0x68, 0x08, 0x4C, 0x44, 0x28, 0x12, 0x44, 0x48, 0x03, 0xF6, 0xE0, 0x00,
13905 0x00, 0xF2, 0x68, 0x0A, 0x45, 0x58, 0x00, 0xF2, 0xF6, 0x0D, 0x00, 0xCC, 0x01, 0x48, 0x55, 0xF0,
13906 0x98, 0x04, 0x4C, 0x44, 0xEF, 0x13, 0x00, 0xF2, 0xC6, 0x0F, 0x00, 0xF2, 0x14, 0x10, 0x08, 0x10,
13907 0x68, 0x18, 0x45, 0x5A, 0x00, 0xF2, 0xF6, 0x0D, 0x04, 0x80, 0x18, 0xE4, 0x10, 0x00, 0x28, 0x12,
13908 0x01, 0xE6, 0x06, 0x00, 0x04, 0x80, 0x18, 0xE4, 0x01, 0x00, 0x04, 0x12, 0x01, 0xE6, 0x0D, 0x00,
13909 0x00, 0xF2, 0x4E, 0x0D, 0x00, 0xF2, 0x12, 0x11, 0x04, 0xE6, 0x02, 0x00, 0x9E, 0xE7, 0x15, 0x00,
13910 0x01, 0xF0, 0x1C, 0x0A, 0x00, 0xF0, 0x02, 0x0A, 0x69, 0x08, 0x05, 0x80, 0x48, 0xE4, 0x00, 0x00,
13911 0x0C, 0x12, 0x00, 0xE6, 0x11, 0x00, 0x00, 0xEA, 0xB8, 0x00, 0x00, 0xF2, 0xB6, 0x10, 0x82, 0xE7,
13912 0x02, 0x00, 0x1C, 0x90, 0x40, 0x5C, 0x00, 0x16, 0x01, 0xE6, 0x06, 0x00, 0x00, 0xF2, 0x4E, 0x0D,
13913 0x01, 0xF0, 0x80, 0x01, 0x1E, 0xF0, 0x80, 0x01, 0x00, 0xF0, 0xA0, 0x04, 0x42, 0x5B, 0x06, 0xF7,
13914 0x03, 0x00, 0x46, 0x59, 0xBF, 0x57, 0x77, 0x57, 0x01, 0xE6, 0x80, 0x00, 0x07, 0x80, 0x31, 0x44,
13915 0x04, 0x80, 0x18, 0xE4, 0x20, 0x00, 0x56, 0x13, 0x20, 0x80, 0x48, 0xE4, 0x03, 0x00, 0x4E, 0x12,
13916 0x00, 0xFC, 0xA2, 0x00, 0x98, 0x57, 0x55, 0xF0, 0x1C, 0x05, 0x31, 0xE4, 0x40, 0x00, 0x00, 0xFC,
13917 0xA0, 0x00, 0x98, 0x57, 0x36, 0x12, 0x4C, 0x1C, 0x00, 0xF2, 0x12, 0x11, 0x89, 0x48, 0x00, 0xF2,
13918 0x12, 0x11, 0x86, 0xF0, 0x2E, 0x05, 0x82, 0xE7, 0x06, 0x00, 0x1B, 0x80, 0x48, 0xE4, 0x22, 0x00,
13919 0x5B, 0xF0, 0x0C, 0x05, 0x48, 0xE4, 0x20, 0x00, 0x59, 0xF0, 0x10, 0x05, 0x00, 0xE6, 0x20, 0x00,
13920 0x09, 0x48, 0x00, 0xF2, 0x12, 0x11, 0x86, 0xF0, 0x2E, 0x05, 0x83, 0x80, 0x04, 0x10, 0x00, 0xF2,
13921 0xA2, 0x0D, 0x00, 0xE6, 0x01, 0x00, 0x00, 0xEA, 0x26, 0x01, 0x01, 0xEA, 0x27, 0x01, 0x04, 0x80,
13922 0x18, 0xE4, 0x10, 0x00, 0x36, 0x12, 0xB9, 0x54, 0x00, 0xF2, 0xF6, 0x0E, 0x01, 0xE6, 0x06, 0x00,
13923 0x04, 0x80, 0x18, 0xE4, 0x01, 0x00, 0x04, 0x12, 0x01, 0xE6, 0x0D, 0x00, 0x00, 0xF2, 0x4E, 0x0D,
13924 0x00, 0xF2, 0x12, 0x11, 0x00, 0xF2, 0xBC, 0x11, 0x00, 0xF2, 0xC8, 0x11, 0x04, 0xE6, 0x02, 0x00,
13925 0x9E, 0xE7, 0x15, 0x00, 0x01, 0xF0, 0x1C, 0x0A, 0x00, 0xF0, 0x02, 0x0A, 0x00, 0xFC, 0x20, 0x01,
13926 0x98, 0x57, 0x34, 0x12, 0x00, 0xFC, 0x24, 0x01, 0x98, 0x57, 0x2C, 0x13, 0xB9, 0x54, 0x00, 0xF2,
13927 0xF6, 0x0E, 0x86, 0xF0, 0xA8, 0x05, 0x03, 0xF6, 0x01, 0x00, 0x00, 0xF2, 0x8C, 0x0E, 0x85, 0xF0,
13928 0x9E, 0x05, 0x82, 0xE7, 0x03, 0x00, 0x00, 0xF2, 0x60, 0x0B, 0x82, 0xE7, 0x02, 0x00, 0x00, 0xFC,
13929 0x24, 0x01, 0xB0, 0x57, 0x00, 0xFA, 0x24, 0x01, 0x00, 0xFC, 0x9E, 0x00, 0x98, 0x57, 0x5A, 0x12,
13930 0x00, 0xFC, 0xB6, 0x00, 0x98, 0x57, 0x52, 0x13, 0x03, 0xE6, 0x0C, 0x00, 0x00, 0xFC, 0x9C, 0x00,
13931 0x98, 0x57, 0x04, 0x13, 0x03, 0xE6, 0x19, 0x00, 0x05, 0xE6, 0x08, 0x00, 0x00, 0xF6, 0x00, 0x01,
13932 0x00, 0x57, 0x00, 0x57, 0x03, 0x58, 0x00, 0xDC, 0x18, 0xF4, 0x00, 0x80, 0x04, 0x13, 0x05, 0xE6,
13933 0x0F, 0x00, 0xB9, 0x54, 0x00, 0xF2, 0xF6, 0x0E, 0x86, 0xF0, 0x0A, 0x06, 0x00, 0xF2, 0xBA, 0x0E,
13934 0x85, 0xF0, 0x00, 0x06, 0x82, 0xE7, 0x03, 0x00, 0x00, 0xF2, 0x60, 0x0B, 0x82, 0xE7, 0x02, 0x00,
13935 0x00, 0xFC, 0xB6, 0x00, 0xB0, 0x57, 0x00, 0xFA, 0xB6, 0x00, 0x01, 0xF6, 0x01, 0x00, 0x00, 0xF2,
13936 0xF6, 0x0E, 0x9C, 0x32, 0x4E, 0x1C, 0x32, 0x1C, 0x00, 0xF2, 0x92, 0x0D, 0x30, 0x1C, 0x82, 0xE7,
13937 0x04, 0x00, 0xB1, 0xF0, 0x22, 0x06, 0x0A, 0xF0, 0x3E, 0x06, 0x05, 0xF0, 0xD6, 0x06, 0x06, 0xF0,
13938 0xDC, 0x06, 0x09, 0xF0, 0x24, 0x09, 0x1E, 0xF0, 0xFC, 0x09, 0x00, 0xF0, 0x02, 0x0A, 0x04, 0x80,
13939 0x18, 0xE4, 0x20, 0x00, 0x30, 0x12, 0x09, 0xE7, 0x03, 0x00, 0x00, 0xF2, 0x12, 0x11, 0x21, 0x80,
13940 0x18, 0xE4, 0xE0, 0x00, 0x09, 0x48, 0x00, 0xF2, 0x12, 0x11, 0x09, 0xE7, 0x00, 0x00, 0x00, 0xF2,
13941 0x12, 0x11, 0x09, 0xE7, 0x00, 0x00, 0x00, 0xF2, 0x12, 0x11, 0x99, 0xA4, 0x00, 0xF2, 0x12, 0x11,
13942 0x09, 0xE7, 0x00, 0x00, 0x9A, 0x10, 0x04, 0x80, 0x18, 0xE4, 0x02, 0x00, 0x34, 0x12, 0x09, 0xE7,
13943 0x1B, 0x00, 0x00, 0xF2, 0x12, 0x11, 0x21, 0x80, 0x18, 0xE4, 0xE0, 0x00, 0x09, 0x48, 0x00, 0xF2,
13944 0x12, 0x11, 0x09, 0xE7, 0x00, 0x00, 0x00, 0xF2, 0x12, 0x11, 0x09, 0xE7, 0x00, 0x00, 0x00, 0xF2,
13945 0x12, 0x11, 0x09, 0xE7, 0x01, 0x00, 0x00, 0xF2, 0x12, 0x11, 0x09, 0xE7, 0x00, 0x00, 0x00, 0xF0,
13946 0x0C, 0x09, 0xBB, 0x55, 0x9A, 0x81, 0x03, 0xF7, 0x20, 0x00, 0x09, 0x6F, 0x93, 0x45, 0x55, 0xF0,
13947 0xE2, 0x06, 0xB1, 0xF0, 0xC2, 0x06, 0x0A, 0xF0, 0xBA, 0x06, 0x09, 0xF0, 0x24, 0x09, 0x1E, 0xF0,
13948 0xFC, 0x09, 0x00, 0xF0, 0x02, 0x0A, 0x00, 0xF2, 0x60, 0x0B, 0x47, 0x10, 0x09, 0xE7, 0x08, 0x00,
13949 0x41, 0x10, 0x05, 0x80, 0x48, 0xE4, 0x00, 0x00, 0x1E, 0x12, 0x00, 0xE6, 0x11, 0x00, 0x00, 0xEA,
13950 0xB8, 0x00, 0x00, 0xF2, 0xB6, 0x10, 0x2C, 0x90, 0xAE, 0x90, 0x08, 0x50, 0x8A, 0x50, 0x38, 0x54,
13951 0x1F, 0x40, 0x00, 0xF2, 0xB4, 0x0D, 0x08, 0x10, 0x08, 0x90, 0x8A, 0x90, 0x30, 0x50, 0xB2, 0x50,
13952 0x9C, 0x32, 0x0C, 0x92, 0x8E, 0x92, 0x38, 0x54, 0x04, 0x80, 0x30, 0xE4, 0x08, 0x00, 0x04, 0x40,
13953 0x0C, 0x1C, 0x00, 0xF6, 0x03, 0x00, 0xB1, 0xF0, 0x26, 0x07, 0x9E, 0xF0, 0x3A, 0x07, 0x01, 0x48,
13954 0x55, 0xF0, 0xFC, 0x09, 0x0C, 0x1C, 0x10, 0x44, 0xED, 0x10, 0x0B, 0xF0, 0x5E, 0x07, 0x0C, 0xF0,
13955 0x62, 0x07, 0x05, 0xF0, 0x52, 0x07, 0x06, 0xF0, 0x58, 0x07, 0x09, 0xF0, 0x24, 0x09, 0x00, 0xF0,
13956 0x02, 0x0A, 0x00, 0xF2, 0x60, 0x0B, 0xCF, 0x10, 0x09, 0xE7, 0x08, 0x00, 0xC9, 0x10, 0x2E, 0x1C,
13957 0x02, 0x10, 0x2C, 0x1C, 0xAA, 0xF0, 0x64, 0x07, 0xAC, 0xF0, 0x72, 0x07, 0x40, 0x10, 0x34, 0x1C,
13958 0xF3, 0x10, 0xAD, 0xF0, 0x7C, 0x07, 0xC8, 0x10, 0x36, 0x1C, 0xE9, 0x10, 0x2B, 0xF0, 0x82, 0x08,
13959 0x6B, 0x18, 0x18, 0xF4, 0x00, 0xFE, 0x20, 0x12, 0x01, 0x58, 0xD2, 0xF0, 0x82, 0x08, 0x76, 0x18,
13960 0x18, 0xF4, 0x03, 0x00, 0xEC, 0x12, 0x00, 0xFC, 0x22, 0x01, 0x18, 0xF4, 0x01, 0x00, 0xE2, 0x12,
13961 0x0B, 0xF0, 0x64, 0x07, 0x0C, 0xF0, 0x64, 0x07, 0x36, 0x1C, 0x34, 0x1C, 0xB7, 0x10, 0x38, 0x54,
13962 0xB9, 0x54, 0x84, 0x80, 0x19, 0xE4, 0x20, 0x00, 0xB2, 0x13, 0x85, 0x80, 0x81, 0x48, 0x66, 0x12,
13963 0x04, 0x80, 0x18, 0xE4, 0x08, 0x00, 0x58, 0x13, 0x1F, 0x80, 0x08, 0x44, 0xC8, 0x44, 0x9F, 0x12,
13964 0x1F, 0x40, 0x34, 0x91, 0xB6, 0x91, 0x44, 0x55, 0xE5, 0x55, 0x02, 0xEC, 0xB8, 0x00, 0x02, 0x49,
13965 0xBB, 0x55, 0x82, 0x81, 0xC0, 0x55, 0x48, 0xF4, 0x0F, 0x00, 0x5A, 0xF0, 0x1A, 0x08, 0x4A, 0xE4,
13966 0x17, 0x00, 0xD5, 0xF0, 0xFA, 0x07, 0x02, 0xF6, 0x0F, 0x00, 0x02, 0xF4, 0x02, 0x00, 0x02, 0xEA,
13967 0xB8, 0x00, 0x04, 0x91, 0x86, 0x91, 0x02, 0x4B, 0x2C, 0x90, 0x08, 0x50, 0x2E, 0x90, 0x0A, 0x50,
13968 0x2C, 0x51, 0xAE, 0x51, 0x00, 0xF2, 0xB6, 0x10, 0x38, 0x54, 0x00, 0xF2, 0xB4, 0x0D, 0x56, 0x10,
13969 0x34, 0x91, 0xB6, 0x91, 0x0C, 0x10, 0x04, 0x80, 0x18, 0xE4, 0x08, 0x00, 0x41, 0x12, 0x0C, 0x91,
13970 0x8E, 0x91, 0x04, 0x80, 0x18, 0xE4, 0xF7, 0x00, 0x04, 0x40, 0x30, 0x90, 0xB2, 0x90, 0x36, 0x10,
13971 0x02, 0x80, 0x48, 0xE4, 0x10, 0x00, 0x31, 0x12, 0x82, 0xE7, 0x10, 0x00, 0x84, 0x80, 0x19, 0xE4,
13972 0x20, 0x00, 0x10, 0x13, 0x0C, 0x90, 0x8E, 0x90, 0x5D, 0xF0, 0x78, 0x07, 0x0C, 0x58, 0x8D, 0x58,
13973 0x00, 0xF0, 0x64, 0x07, 0x38, 0x54, 0xB9, 0x54, 0x19, 0x80, 0xF1, 0x10, 0x3A, 0x55, 0x19, 0x81,
13974 0xBB, 0x55, 0x10, 0x90, 0x92, 0x90, 0x10, 0x58, 0x91, 0x58, 0x14, 0x59, 0x95, 0x59, 0x00, 0xF0,
13975 0x64, 0x07, 0x04, 0x80, 0x18, 0xE4, 0x20, 0x00, 0x06, 0x12, 0x6C, 0x19, 0x19, 0x41, 0x7C, 0x10,
13976 0x6C, 0x19, 0x0C, 0x51, 0xED, 0x19, 0x8E, 0x51, 0x6B, 0x18, 0x18, 0xF4, 0x00, 0xFF, 0x02, 0x13,
13977 0x6A, 0x10, 0x01, 0x58, 0xD2, 0xF0, 0xC0, 0x08, 0x76, 0x18, 0x18, 0xF4, 0x03, 0x00, 0x0A, 0x12,
13978 0x00, 0xFC, 0x22, 0x01, 0x18, 0xF4, 0x01, 0x00, 0x06, 0x13, 0x9E, 0xE7, 0x16, 0x00, 0x4C, 0x10,
13979 0xD1, 0xF0, 0xCA, 0x08, 0x9E, 0xE7, 0x17, 0x00, 0x42, 0x10, 0xD0, 0xF0, 0xD4, 0x08, 0x9E, 0xE7,
13980 0x19, 0x00, 0x38, 0x10, 0xCF, 0xF0, 0xDE, 0x08, 0x9E, 0xE7, 0x20, 0x00, 0x2E, 0x10, 0xCE, 0xF0,
13981 0xE8, 0x08, 0x9E, 0xE7, 0x21, 0x00, 0x24, 0x10, 0xCD, 0xF0, 0xF2, 0x08, 0x9E, 0xE7, 0x22, 0x00,
13982 0x1A, 0x10, 0xCC, 0xF0, 0x04, 0x09, 0x84, 0x80, 0x19, 0xE4, 0x04, 0x00, 0x06, 0x12, 0x9E, 0xE7,
13983 0x12, 0x00, 0x08, 0x10, 0xCB, 0xF0, 0x0C, 0x09, 0x9E, 0xE7, 0x24, 0x00, 0xB1, 0xF0, 0x0C, 0x09,
13984 0x05, 0xF0, 0x1E, 0x09, 0x09, 0xF0, 0x24, 0x09, 0x1E, 0xF0, 0xFC, 0x09, 0xE4, 0x10, 0x00, 0xF2,
13985 0x60, 0x0B, 0xE9, 0x10, 0x9C, 0x32, 0x82, 0xE7, 0x20, 0x00, 0x32, 0x1C, 0xE9, 0x09, 0x00, 0xF2,
13986 0x12, 0x11, 0x85, 0xF0, 0x02, 0x0A, 0x69, 0x08, 0x01, 0xF0, 0x44, 0x09, 0x1E, 0xF0, 0xFC, 0x09,
13987 0x00, 0xF0, 0x38, 0x09, 0x30, 0x44, 0x06, 0x12, 0x9E, 0xE7, 0x42, 0x00, 0xB8, 0x10, 0x04, 0xF6,
13988 0x01, 0x00, 0xB3, 0x45, 0x74, 0x12, 0x04, 0x80, 0x18, 0xE4, 0x20, 0x00, 0x22, 0x13, 0x4B, 0xE4,
13989 0x02, 0x00, 0x36, 0x12, 0x4B, 0xE4, 0x28, 0x00, 0xAC, 0x13, 0x00, 0xF2, 0xBC, 0x11, 0x00, 0xF2,
13990 0xC8, 0x11, 0x03, 0xF6, 0xD0, 0x00, 0xFA, 0x14, 0x82, 0xE7, 0x01, 0x00, 0x00, 0xF0, 0x80, 0x01,
13991 0x9E, 0xE7, 0x44, 0x00, 0x4B, 0xE4, 0x02, 0x00, 0x06, 0x12, 0x03, 0xE6, 0x02, 0x00, 0x76, 0x10,
13992 0x00, 0xF2, 0xA2, 0x0D, 0x03, 0xE6, 0x02, 0x00, 0x6C, 0x10, 0x00, 0xF2, 0xA2, 0x0D, 0x19, 0x82,
13993 0x34, 0x46, 0x0A, 0x13, 0x03, 0xE6, 0x02, 0x00, 0x9E, 0xE7, 0x43, 0x00, 0x68, 0x10, 0x04, 0x80,
13994 0x30, 0xE4, 0x20, 0x00, 0x04, 0x40, 0x00, 0xF2, 0xBC, 0x11, 0x00, 0xF2, 0xC8, 0x11, 0x82, 0xE7,
13995 0x01, 0x00, 0x06, 0xF7, 0x02, 0x00, 0x00, 0xF0, 0x08, 0x03, 0x04, 0x80, 0x18, 0xE4, 0x20, 0x00,
13996 0x06, 0x12, 0x03, 0xE6, 0x02, 0x00, 0x3E, 0x10, 0x04, 0x80, 0x18, 0xE4, 0x02, 0x00, 0x3A, 0x12,
13997 0x04, 0x80, 0x18, 0xE4, 0xFD, 0x00, 0x04, 0x40, 0x1C, 0x1C, 0x9D, 0xF0, 0xEA, 0x09, 0x1C, 0x1C,
13998 0x9D, 0xF0, 0xF0, 0x09, 0xC1, 0x10, 0x9E, 0xE7, 0x13, 0x00, 0x0A, 0x10, 0x9E, 0xE7, 0x41, 0x00,
13999 0x04, 0x10, 0x9E, 0xE7, 0x24, 0x00, 0x00, 0xFC, 0xBE, 0x00, 0x98, 0x57, 0xD5, 0xF0, 0x8A, 0x02,
14000 0x04, 0xE6, 0x04, 0x00, 0x06, 0x10, 0x04, 0xE6, 0x04, 0x00, 0x9D, 0x41, 0x1C, 0x42, 0x9F, 0xE7,
14001 0x00, 0x00, 0x06, 0xF7, 0x02, 0x00, 0x03, 0xF6, 0xE0, 0x00, 0x3C, 0x14, 0x44, 0x58, 0x45, 0x58,
14002 0x00, 0xF2, 0xF6, 0x0D, 0x00, 0xF2, 0x7E, 0x10, 0x00, 0xF2, 0xC6, 0x0F, 0x3C, 0x14, 0x1E, 0x1C,
14003 0x00, 0xF0, 0x80, 0x01, 0x12, 0x1C, 0x22, 0x1C, 0xD2, 0x14, 0x00, 0xF0, 0x72, 0x01, 0x83, 0x59,
14004 0x03, 0xDC, 0x73, 0x57, 0x80, 0x5D, 0x00, 0x16, 0x83, 0x59, 0x03, 0xDC, 0x38, 0x54, 0x70, 0x57,
14005 0x33, 0x54, 0x3B, 0x54, 0x80, 0x5D, 0x00, 0x16, 0x03, 0x57, 0x83, 0x59, 0x38, 0x54, 0x00, 0xCC,
14006 0x00, 0x16, 0x03, 0x57, 0x83, 0x59, 0x00, 0x4C, 0x00, 0x16, 0x02, 0x80, 0x48, 0xE4, 0x01, 0x00,
14007 0x0E, 0x12, 0x48, 0xE4, 0x05, 0x00, 0x08, 0x12, 0x00, 0xF2, 0xBC, 0x11, 0x00, 0xF2, 0xC8, 0x11,
14008 0xC1, 0x5A, 0x3A, 0x55, 0x02, 0xEC, 0xB5, 0x00, 0x45, 0x59, 0x00, 0xF2, 0xF6, 0x0D, 0x83, 0x58,
14009 0x30, 0xE7, 0x00, 0x00, 0x10, 0x4D, 0x30, 0xE7, 0x40, 0x00, 0x10, 0x4F, 0x38, 0x90, 0xBA, 0x90,
14010 0x10, 0x5C, 0x80, 0x5C, 0x83, 0x5A, 0x10, 0x4E, 0x04, 0xEA, 0xB5, 0x00, 0x43, 0x5B, 0x03, 0xF4,
14011 0xE0, 0x00, 0x83, 0x59, 0x04, 0xCC, 0x01, 0x4A, 0x0A, 0x12, 0x45, 0x5A, 0x00, 0xF2, 0xF6, 0x0D,
14012 0x00, 0xF2, 0x38, 0x10, 0x00, 0x16, 0x08, 0x1C, 0x00, 0xFC, 0xAC, 0x00, 0x06, 0x58, 0x67, 0x18,
14013 0x18, 0xF4, 0x8F, 0xE1, 0x01, 0xFC, 0xAE, 0x00, 0x19, 0xF4, 0x70, 0x1E, 0xB0, 0x54, 0x07, 0x58,
14014 0x00, 0xFC, 0xB0, 0x00, 0x08, 0x58, 0x00, 0xFC, 0xB2, 0x00, 0x09, 0x58, 0x0A, 0x1C, 0x00, 0xE6,
14015 0x0F, 0x00, 0x00, 0xEA, 0xB9, 0x00, 0x38, 0x54, 0x00, 0xFA, 0x24, 0x01, 0x00, 0xFA, 0xB6, 0x00,
14016 0x18, 0x1C, 0x14, 0x1C, 0x10, 0x1C, 0x32, 0x1C, 0x12, 0x1C, 0x00, 0x16, 0x3E, 0x57, 0x0C, 0x14,
14017 0x0E, 0x47, 0x07, 0xE6, 0x10, 0x00, 0xCE, 0x47, 0xF5, 0x13, 0x00, 0x16, 0x00, 0xF2, 0xA2, 0x0D,
14018 0x02, 0x4B, 0x03, 0xF6, 0xE0, 0x00, 0x00, 0xF2, 0x68, 0x0A, 0x01, 0x48, 0x20, 0x12, 0x44, 0x58,
14019 0x45, 0x58, 0x9E, 0xE7, 0x15, 0x00, 0x9C, 0xE7, 0x04, 0x00, 0x00, 0xF2, 0xF6, 0x0D, 0x00, 0xF2,
14020 0x7E, 0x10, 0x00, 0xF2, 0xC6, 0x0F, 0x00, 0xF2, 0x7A, 0x0A, 0x1E, 0x1C, 0xD5, 0x10, 0x00, 0x16,
14021 0x69, 0x08, 0x48, 0xE4, 0x04, 0x00, 0x64, 0x12, 0x48, 0xE4, 0x02, 0x00, 0x20, 0x12, 0x48, 0xE4,
14022 0x03, 0x00, 0x1A, 0x12, 0x48, 0xE4, 0x08, 0x00, 0x14, 0x12, 0x48, 0xE4, 0x01, 0x00, 0xF0, 0x12,
14023 0x48, 0xE4, 0x07, 0x00, 0x12, 0x12, 0x01, 0xE6, 0x07, 0x00, 0x00, 0xF2, 0x4E, 0x0D, 0x00, 0xF2,
14024 0x12, 0x11, 0x05, 0xF0, 0x60, 0x0B, 0x00, 0x16, 0x00, 0xE6, 0x01, 0x00, 0x00, 0xEA, 0x99, 0x00,
14025 0x02, 0x80, 0x48, 0xE4, 0x03, 0x00, 0xE7, 0x12, 0x48, 0xE4, 0x06, 0x00, 0xE1, 0x12, 0x01, 0xE6,
14026 0x06, 0x00, 0x00, 0xF2, 0x4E, 0x0D, 0x00, 0xF2, 0x12, 0x11, 0x04, 0xE6, 0x02, 0x00, 0x9E, 0xE7,
14027 0x15, 0x00, 0x01, 0xF0, 0x1C, 0x0A, 0x00, 0xF0, 0x02, 0x0A, 0x00, 0x16, 0x02, 0x80, 0x48, 0xE4,
14028 0x10, 0x00, 0x1C, 0x12, 0x82, 0xE7, 0x08, 0x00, 0x3C, 0x56, 0x03, 0x82, 0x00, 0xF2, 0xE2, 0x0D,
14029 0x30, 0xE7, 0x08, 0x00, 0x04, 0xF7, 0x70, 0x01, 0x06, 0xF7, 0x02, 0x00, 0x00, 0xF0, 0x80, 0x01,
14030 0x6C, 0x19, 0xED, 0x19, 0x5D, 0xF0, 0xD4, 0x0B, 0x44, 0x55, 0xE5, 0x55, 0x59, 0xF0, 0x52, 0x0C,
14031 0x04, 0x55, 0xA5, 0x55, 0x1F, 0x80, 0x01, 0xEC, 0xB8, 0x00, 0x82, 0x48, 0x82, 0x80, 0x49, 0x44,
14032 0x2E, 0x13, 0x01, 0xEC, 0xB8, 0x00, 0x41, 0xE4, 0x02, 0x00, 0x01, 0xEA, 0xB8, 0x00, 0x49, 0xE4,
14033 0x11, 0x00, 0x59, 0xF0, 0x2E, 0x0C, 0x01, 0xE6, 0x17, 0x00, 0x01, 0xEA, 0xB8, 0x00, 0x02, 0x4B,
14034 0x88, 0x90, 0xAC, 0x50, 0x8A, 0x90, 0xAE, 0x50, 0x01, 0xEC, 0xB8, 0x00, 0x82, 0x48, 0x82, 0x80,
14035 0x10, 0x44, 0x02, 0x4B, 0x1F, 0x40, 0xC0, 0x44, 0x00, 0xF2, 0xB4, 0x0D, 0x04, 0x55, 0xA5, 0x55,
14036 0x9F, 0x10, 0x0C, 0x51, 0x8E, 0x51, 0x30, 0x90, 0xB2, 0x90, 0x00, 0x56, 0xA1, 0x56, 0x30, 0x50,
14037 0xB2, 0x50, 0x34, 0x90, 0xB6, 0x90, 0x40, 0x56, 0xE1, 0x56, 0x34, 0x50, 0xB6, 0x50, 0x65, 0x10,
14038 0xB1, 0xF0, 0x70, 0x0C, 0x85, 0xF0, 0xCA, 0x0B, 0xE9, 0x09, 0x4B, 0xE4, 0x03, 0x00, 0x78, 0x12,
14039 0x4B, 0xE4, 0x02, 0x00, 0x01, 0x13, 0xB1, 0xF0, 0x86, 0x0C, 0x85, 0xF0, 0xCA, 0x0B, 0x69, 0x08,
14040 0x48, 0xE4, 0x03, 0x00, 0xD5, 0xF0, 0x86, 0x0B, 0x00, 0xF2, 0x12, 0x11, 0x85, 0xF0, 0xCA, 0x0B,
14041 0xE8, 0x09, 0x3C, 0x56, 0x00, 0xFC, 0x20, 0x01, 0x98, 0x57, 0x02, 0x13, 0xBB, 0x45, 0x4B, 0xE4,
14042 0x00, 0x00, 0x08, 0x12, 0x03, 0xE6, 0x01, 0x00, 0x04, 0xF6, 0x00, 0x80, 0xA8, 0x14, 0xD2, 0x14,
14043 0x30, 0x1C, 0x02, 0x80, 0x48, 0xE4, 0x03, 0x00, 0x10, 0x13, 0x00, 0xFC, 0xB6, 0x00, 0x98, 0x57,
14044 0x02, 0x13, 0x4C, 0x1C, 0x3E, 0x1C, 0x00, 0xF0, 0x8E, 0x0B, 0x00, 0xFC, 0x24, 0x01, 0xB0, 0x57,
14045 0x00, 0xFA, 0x24, 0x01, 0x4C, 0x1C, 0x3E, 0x1C, 0x00, 0xF2, 0x12, 0x11, 0x86, 0xF0, 0x8E, 0x0B,
14046 0x00, 0xF2, 0x8C, 0x0E, 0x00, 0xF0, 0x8E, 0x0B, 0xB1, 0xF0, 0xF8, 0x0C, 0x85, 0xF0, 0x86, 0x0B,
14047 0x69, 0x08, 0x48, 0xE4, 0x01, 0x00, 0xD5, 0xF0, 0x86, 0x0B, 0xFC, 0x14, 0x42, 0x58, 0x6C, 0x14,
14048 0x80, 0x14, 0x30, 0x1C, 0x4A, 0xF4, 0x02, 0x00, 0x55, 0xF0, 0x86, 0x0B, 0x4A, 0xF4, 0x01, 0x00,
14049 0x0E, 0x12, 0x02, 0x80, 0x48, 0xE4, 0x03, 0x00, 0x06, 0x13, 0x3E, 0x1C, 0x00, 0xF0, 0x8E, 0x0B,
14050 0x00, 0xFC, 0xB6, 0x00, 0xB0, 0x57, 0x00, 0xFA, 0xB6, 0x00, 0x4C, 0x1C, 0x3E, 0x1C, 0x00, 0xF2,
14051 0x12, 0x11, 0x86, 0xF0, 0x8E, 0x0B, 0x00, 0xF2, 0xBA, 0x0E, 0x00, 0xF0, 0x8E, 0x0B, 0x4C, 0x1C,
14052 0xB1, 0xF0, 0x50, 0x0D, 0x85, 0xF0, 0x5C, 0x0D, 0x69, 0x08, 0xF3, 0x10, 0x86, 0xF0, 0x64, 0x0D,
14053 0x4E, 0x1C, 0x89, 0x48, 0x00, 0x16, 0x00, 0xF6, 0x00, 0x01, 0x00, 0x57, 0x00, 0x57, 0x03, 0x58,
14054 0x00, 0xDC, 0x18, 0xF4, 0xFF, 0x7F, 0x30, 0x56, 0x00, 0x5C, 0x00, 0x16, 0x00, 0xF6, 0x00, 0x01,
14055 0x00, 0x57, 0x00, 0x57, 0x03, 0x58, 0x00, 0xDC, 0x18, 0xF4, 0x00, 0x80, 0x30, 0x56, 0x00, 0x5C,
14056 0x00, 0x16, 0x00, 0xF6, 0x00, 0x01, 0x00, 0x57, 0x00, 0x57, 0x03, 0x58, 0x00, 0xDC, 0x0B, 0x58,
14057 0x00, 0x16, 0x03, 0xF6, 0x24, 0x01, 0x00, 0xF2, 0x58, 0x0A, 0x03, 0xF6, 0xB6, 0x00, 0x00, 0xF2,
14058 0x58, 0x0A, 0x00, 0x16, 0x02, 0xEC, 0xB8, 0x00, 0x02, 0x49, 0x18, 0xF4, 0xFF, 0x00, 0x00, 0x54,
14059 0x00, 0x54, 0x00, 0x54, 0x00, 0xF4, 0x08, 0x00, 0xE1, 0x18, 0x80, 0x54, 0x03, 0x58, 0x00, 0xDD,
14060 0x01, 0xDD, 0x02, 0xDD, 0x03, 0xDC, 0x02, 0x4B, 0x30, 0x50, 0xB2, 0x50, 0x34, 0x51, 0xB6, 0x51,
14061 0x00, 0x16, 0x45, 0x5A, 0x1D, 0xF4, 0xFF, 0x00, 0x85, 0x56, 0x85, 0x56, 0x85, 0x56, 0x05, 0xF4,
14062 0x02, 0x12, 0x83, 0x5A, 0x00, 0x16, 0x1D, 0xF4, 0xFF, 0x00, 0x85, 0x56, 0x85, 0x56, 0x85, 0x56,
14063 0x05, 0xF4, 0x00, 0x12, 0x83, 0x5A, 0x00, 0x16, 0x38, 0x54, 0xBB, 0x55, 0x3C, 0x56, 0xBD, 0x56,
14064 0x00, 0xF2, 0x12, 0x11, 0x85, 0xF0, 0x82, 0x0E, 0xE9, 0x09, 0xC1, 0x59, 0x00, 0xF2, 0x12, 0x11,
14065 0x85, 0xF0, 0x82, 0x0E, 0xE8, 0x0A, 0x83, 0x55, 0x83, 0x55, 0x4B, 0xF4, 0x90, 0x01, 0x5C, 0xF0,
14066 0x36, 0x0E, 0xBD, 0x56, 0x40, 0x10, 0x4B, 0xF4, 0x30, 0x00, 0x59, 0xF0, 0x48, 0x0E, 0x01, 0xF6,
14067 0x0C, 0x00, 0x00, 0xF6, 0x01, 0x00, 0x2E, 0x10, 0x02, 0xFC, 0x9C, 0x00, 0x9A, 0x57, 0x14, 0x13,
14068 0x4B, 0xF4, 0x64, 0x00, 0x59, 0xF0, 0x64, 0x0E, 0x03, 0xF6, 0x64, 0x00, 0x01, 0xF6, 0x19, 0x00,
14069 0x00, 0xF6, 0x01, 0x00, 0x43, 0xF4, 0x33, 0x00, 0x56, 0xF0, 0x76, 0x0E, 0x04, 0xF4, 0x00, 0x01,
14070 0x43, 0xF4, 0x19, 0x00, 0xF3, 0x10, 0xB4, 0x56, 0xC3, 0x58, 0x02, 0xFC, 0x9E, 0x00, 0x9A, 0x57,
14071 0x08, 0x13, 0x3C, 0x56, 0x00, 0xF6, 0x02, 0x00, 0x00, 0x16, 0x00, 0x16, 0x09, 0xE7, 0x01, 0x00,
14072 0x00, 0xF2, 0x12, 0x11, 0x86, 0xF0, 0xB8, 0x0E, 0x09, 0xE7, 0x02, 0x00, 0x00, 0xF2, 0x12, 0x11,
14073 0x86, 0xF0, 0xB8, 0x0E, 0x09, 0xE7, 0x03, 0x00, 0x00, 0xF2, 0x12, 0x11, 0x86, 0xF0, 0xB8, 0x0E,
14074 0x4E, 0x1C, 0x89, 0x49, 0x00, 0xF2, 0x12, 0x11, 0x00, 0x16, 0x09, 0xE7, 0x01, 0x00, 0x00, 0xF2,
14075 0x12, 0x11, 0x86, 0xF0, 0xF2, 0x0E, 0x09, 0xE7, 0x03, 0x00, 0x00, 0xF2, 0x12, 0x11, 0x86, 0xF0,
14076 0xF2, 0x0E, 0x09, 0xE7, 0x01, 0x00, 0x00, 0xF2, 0x12, 0x11, 0x86, 0xF0, 0xF2, 0x0E, 0x89, 0x49,
14077 0x00, 0xF2, 0x12, 0x11, 0x86, 0xF0, 0xF2, 0x0E, 0x4E, 0x1C, 0x89, 0x4A, 0x00, 0xF2, 0x12, 0x11,
14078 0x00, 0x16, 0x3C, 0x56, 0x00, 0x16, 0x00, 0xEC, 0x26, 0x01, 0x48, 0xE4, 0x01, 0x00, 0x1E, 0x13,
14079 0x38, 0x44, 0x00, 0xEA, 0x26, 0x01, 0x49, 0xF4, 0x00, 0x00, 0x04, 0x12, 0x4E, 0x1C, 0x02, 0x10,
14080 0x4C, 0x1C, 0x01, 0xEC, 0x27, 0x01, 0x89, 0x48, 0x00, 0xF2, 0x12, 0x11, 0x02, 0x14, 0x00, 0x16,
14081 0x85, 0xF0, 0x52, 0x0F, 0x38, 0x54, 0x00, 0xEA, 0x99, 0x00, 0x00, 0xF2, 0x60, 0x0B, 0x02, 0x80,
14082 0x48, 0xE4, 0x06, 0x00, 0x1C, 0x13, 0x00, 0xEC, 0x99, 0x00, 0x48, 0xE4, 0x01, 0x00, 0x0A, 0x12,
14083 0x04, 0x80, 0x30, 0xE4, 0x01, 0x00, 0x04, 0x40, 0x08, 0x10, 0x04, 0x80, 0x18, 0xE4, 0xFE, 0x00,
14084 0x04, 0x40, 0x00, 0x16, 0x02, 0xF6, 0xE0, 0x00, 0x02, 0x57, 0x03, 0x59, 0x01, 0xCC, 0x81, 0x48,
14085 0x22, 0x12, 0x00, 0x4E, 0x83, 0x5A, 0x90, 0x4C, 0x20, 0xE7, 0x00, 0x00, 0xC3, 0x58, 0x1B, 0xF4,
14086 0xFF, 0x00, 0x83, 0x55, 0x83, 0x55, 0x83, 0x55, 0x03, 0xF4, 0x00, 0x12, 0x8B, 0x55, 0x83, 0x59,
14087 0x00, 0x4E, 0x00, 0x16, 0x00, 0x4E, 0x02, 0xF6, 0xF0, 0x00, 0x02, 0x57, 0x03, 0x59, 0x00, 0x4E,
14088 0x83, 0x5A, 0x30, 0xE7, 0x00, 0x00, 0x20, 0xE7, 0x00, 0x00, 0x00, 0x16, 0x02, 0xF6, 0xF0, 0x00,
14089 0x02, 0x57, 0x03, 0x59, 0x01, 0xCC, 0x00, 0x4E, 0x83, 0x5A, 0x30, 0xE7, 0x00, 0x00, 0x80, 0x4C,
14090 0xC3, 0x58, 0x1B, 0xF4, 0xFF, 0x00, 0x83, 0x55, 0x83, 0x55, 0x83, 0x55, 0x03, 0xF4, 0x00, 0x12,
14091 0x83, 0x59, 0x00, 0x4E, 0x00, 0x16, 0x03, 0xF6, 0xE0, 0x00, 0x03, 0x57, 0x83, 0x59, 0x3A, 0x55,
14092 0x02, 0xCC, 0x45, 0x5A, 0x00, 0xF2, 0xF6, 0x0D, 0xC0, 0x5A, 0x40, 0x5C, 0x38, 0x54, 0x00, 0xCD,
14093 0x01, 0xCC, 0x4A, 0x46, 0x0A, 0x13, 0x83, 0x59, 0x00, 0x4C, 0x01, 0x48, 0x16, 0x13, 0x0C, 0x10,
14094 0xC5, 0x58, 0x00, 0xF2, 0xF6, 0x0D, 0x00, 0x4C, 0x01, 0x48, 0x08, 0x13, 0x05, 0xF6, 0xF0, 0x00,
14095 0x05, 0x57, 0x08, 0x10, 0x45, 0x58, 0x00, 0xF2, 0xF6, 0x0D, 0x8D, 0x56, 0x83, 0x5A, 0x80, 0x4C,
14096 0x05, 0x17, 0x00, 0x16, 0x02, 0x4B, 0x06, 0xF7, 0x04, 0x00, 0x62, 0x0B, 0x03, 0x82, 0x00, 0xF2,
14097 0xE2, 0x0D, 0x02, 0x80, 0x00, 0x4C, 0x45, 0xF4, 0x02, 0x00, 0x52, 0x14, 0x06, 0xF7, 0x02, 0x00,
14098 0x06, 0x14, 0x00, 0xF2, 0x54, 0x0F, 0x00, 0x16, 0x02, 0x4B, 0x01, 0xF6, 0xFF, 0x00, 0x38, 0x1C,
14099 0x05, 0xF4, 0x04, 0x00, 0x83, 0x5A, 0x18, 0xDF, 0x19, 0xDF, 0x1D, 0xF7, 0x3C, 0x00, 0xB8, 0xF0,
14100 0x4E, 0x10, 0x9C, 0x14, 0x01, 0x48, 0x1C, 0x13, 0x0E, 0xF7, 0x3C, 0x00, 0x03, 0xF7, 0x04, 0x00,
14101 0xAF, 0x19, 0x03, 0x42, 0x45, 0xF4, 0x02, 0x00, 0x83, 0x5A, 0x02, 0xCC, 0x02, 0x41, 0x45, 0xF4,
14102 0x02, 0x00, 0x00, 0x16, 0x91, 0x44, 0xD5, 0xF0, 0x3E, 0x10, 0x00, 0xF0, 0x9E, 0x02, 0x01, 0xF6,
14103 0xFF, 0x00, 0x38, 0x1C, 0x05, 0xF4, 0x04, 0x00, 0x83, 0x5A, 0x18, 0xDF, 0x19, 0xDF, 0x0E, 0xF7,
14104 0x3C, 0x00, 0x03, 0xF7, 0x04, 0x00, 0x0F, 0x79, 0x1C, 0xF7, 0x3C, 0x00, 0xB8, 0xF0, 0x9C, 0x10,
14105 0x4E, 0x14, 0x01, 0x48, 0x06, 0x13, 0x45, 0xF4, 0x04, 0x00, 0x00, 0x16, 0x91, 0x44, 0xD5, 0xF0,
14106 0x82, 0x10, 0x00, 0xF0, 0x9E, 0x02, 0x02, 0xF6, 0xFF, 0x00, 0x38, 0x1C, 0x2C, 0xBC, 0xAE, 0xBC,
14107 0xE2, 0x08, 0x00, 0xEC, 0xB8, 0x00, 0x02, 0x48, 0x1D, 0xF7, 0x80, 0x00, 0xB8, 0xF0, 0xCC, 0x10,
14108 0x1E, 0x14, 0x01, 0x48, 0x0E, 0x13, 0x0E, 0xF7, 0x80, 0x00, 0x38, 0x54, 0x03, 0x58, 0xAF, 0x19,
14109 0x82, 0x48, 0x00, 0x16, 0x82, 0x48, 0x12, 0x45, 0xD5, 0xF0, 0xBA, 0x10, 0x00, 0xF0, 0x9E, 0x02,
14110 0x39, 0xF0, 0xF8, 0x10, 0x38, 0x44, 0x00, 0x16, 0x7E, 0x18, 0x18, 0xF4, 0x03, 0x00, 0x04, 0x13,
14111 0x61, 0x18, 0x00, 0x16, 0x38, 0x1C, 0x00, 0xFC, 0x22, 0x01, 0x18, 0xF4, 0x01, 0x00, 0xF1, 0x12,
14112 0xE3, 0x10, 0x30, 0x44, 0x30, 0x44, 0x30, 0x44, 0xB1, 0xF0, 0x18, 0x11, 0x00, 0x16, 0x3E, 0x57,
14113 0x03, 0xF6, 0xE0, 0x00, 0x03, 0x57, 0x83, 0x59, 0x04, 0xCC, 0x01, 0x4A, 0x6A, 0x12, 0x45, 0x5A,
14114 0x00, 0xF2, 0xF6, 0x0D, 0x02, 0x4B, 0x70, 0x14, 0x34, 0x13, 0x02, 0x80, 0x48, 0xE4, 0x08, 0x00,
14115 0x18, 0x12, 0x9C, 0xE7, 0x02, 0x00, 0x9E, 0xE7, 0x15, 0x00, 0x00, 0xF2, 0xC6, 0x0F, 0x00, 0xF2,
14116 0x7A, 0x0A, 0x1E, 0x1C, 0x01, 0xF6, 0x01, 0x00, 0x00, 0x16, 0x30, 0xE4, 0x10, 0x00, 0x04, 0x40,
14117 0x00, 0xF2, 0xE2, 0x0D, 0x20, 0xE7, 0x01, 0x00, 0x01, 0xF6, 0x01, 0x00, 0x00, 0x16, 0x04, 0xDC,
14118 0x01, 0x4A, 0x24, 0x12, 0x45, 0x5A, 0x00, 0xF2, 0xF6, 0x0D, 0x43, 0x5B, 0x06, 0xEC, 0x98, 0x00,
14119 0x00, 0xF2, 0x38, 0x10, 0xC6, 0x59, 0x20, 0x14, 0x0A, 0x13, 0x00, 0xF2, 0xC6, 0x0F, 0x00, 0xF2,
14120 0x14, 0x10, 0xA7, 0x10, 0x83, 0x5A, 0xD7, 0x10, 0x0E, 0x47, 0x07, 0xE6, 0x10, 0x00, 0xCE, 0x47,
14121 0x5A, 0xF0, 0x20, 0x11, 0xB9, 0x54, 0x00, 0x16, 0x14, 0x90, 0x96, 0x90, 0x02, 0xFC, 0xA8, 0x00,
14122 0x03, 0xFC, 0xAA, 0x00, 0x48, 0x55, 0x02, 0x13, 0xC9, 0x55, 0x00, 0x16, 0x00, 0xEC, 0xBA, 0x00,
14123 0x10, 0x44, 0x00, 0xEA, 0xBA, 0x00, 0x00, 0x16, 0x03, 0xF6, 0xC0, 0x00, 0x00, 0xF2, 0x68, 0x0A,
14124 0x10, 0x44, 0x00, 0x4C, 0x00, 0x16
14125};
14126
14127unsigned short _adv_mcode_size ASC_INITDATA =
14128 sizeof(_adv_mcode_buf); /* 0x11D6 */
14129unsigned long _adv_mcode_chksum ASC_INITDATA = 0x03494981UL;
14130
14131/* a_init.c */
14132/*
14133 * EEPROM Configuration.
14134 *
14135 * All drivers should use this structure to set the default EEPROM
14136 * configuration. The BIOS now uses this structure when it is built.
14137 * Additional structure information can be found in a_condor.h where
14138 * the structure is defined.
14139 */
14140STATICstatic ADVEEP_CONFIG
14141Default_EEPROM_Config ASC_INITDATA = {
14142 ADV_EEPROM_BIOS_ENABLE0x4000, /* cfg_msw */
14143 0x0000, /* cfg_lsw */
14144 0xFFFF, /* disc_enable */
14145 0xFFFF, /* wdtr_able */
14146 0xFFFF, /* sdtr_able */
14147 0xFFFF, /* start_motor */
14148 0xFFFF, /* tagqng_able */
14149 0xFFFF, /* bios_scan */
14150 0, /* scam_tolerant */
14151 7, /* adapter_scsi_id */
14152 0, /* bios_boot_delay */
14153 3, /* scsi_reset_delay */
14154 0, /* bios_id_lun */
14155 0, /* termination */
14156 0, /* reserved1 */
14157 0xFFEF, /* bios_ctrl */
14158 0xFFFF, /* ultra_able */
14159 0, /* reserved2 */
14160 ASC_DEF_MAX_HOST_QNG0xFD, /* max_host_qng */
14161 ASC_DEF_MAX_DVC_QNG0x3F, /* max_dvc_qng */
14162 0, /* dvc_cntl */
14163 0, /* bug_fix */
14164 0, /* serial_number_word1 */
14165 0, /* serial_number_word2 */
14166 0, /* serial_number_word3 */
14167 0, /* check_sum */
14168 { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, /* oem_name[16] */
14169 0, /* dvc_err_code */
14170 0, /* adv_err_code */
14171 0, /* adv_err_addr */
14172 0, /* saved_dvc_err_code */
14173 0, /* saved_adv_err_code */
14174 0, /* saved_adv_err_addr */
14175 0 /* num_of_err */
14176};
14177
14178/*
14179 * Initialize the ADV_DVC_VAR structure.
14180 *
14181 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
14182 *
14183 * For a non-fatal error return a warning code. If there are no warnings
14184 * then 0 is returned.
14185 */
14186ASC_INITFUNC(int AdvInitGetConfig(ADV_DVC_VAR *asc_dvc)
14187intint AdvInitGetConfig(ADV_DVC_VAR *asc_dvc)
14188AdvInitGetConfig(ADV_DVC_VAR *asc_dvc)int AdvInitGetConfig(ADV_DVC_VAR *asc_dvc)
14189)int AdvInitGetConfig(ADV_DVC_VAR *asc_dvc)
14190{
14191 ushort warn_code;
14192 AdvPortAddrunsigned long iop_base;
14193 uchar pci_cmd_reg;
14194 int status;
14195
14196 warn_code = 0;
14197 asc_dvc->err_code = 0;
14198 iop_base = asc_dvc->iop_base;
14199
14200 /*
14201 * PCI Command Register
14202 */
14203
14204 if (((pci_cmd_reg = DvcAdvReadPCIConfigByte(asc_dvc,
14205 AscPCIConfigCommandRegister0x0004))
14206 & AscPCICmdRegBits_BusMastering0x0007)
14207 != AscPCICmdRegBits_BusMastering0x0007)
14208 {
14209 pci_cmd_reg |= AscPCICmdRegBits_BusMastering0x0007;
14210
14211 DvcAdvWritePCIConfigByte(asc_dvc,
14212 AscPCIConfigCommandRegister0x0004, pci_cmd_reg);
14213
14214 if (((DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigCommandRegister0x0004))
14215 & AscPCICmdRegBits_BusMastering0x0007)
14216 != AscPCICmdRegBits_BusMastering0x0007)
14217 {
14218 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE0x0080;
14219 }
14220 }
14221
14222 /*
14223 * PCI Latency Timer
14224 *
14225 * If the "latency timer" register is 0x20 or above, then we don't need
14226 * to change it. Otherwise, set it to 0x20 (i.e. set it to 0x20 if it
14227 * comes up less than 0x20).
14228 */
14229 if (DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer0x000D) < 0x20) {
14230 DvcAdvWritePCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer0x000D, 0x20);
14231 if (DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer0x000D) < 0x20)
14232 {
14233 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE0x0080;
14234 }
14235 }
14236
14237 /*
14238 * Save the state of the PCI Configuration Command Register
14239 * "Parity Error Response Control" Bit. If the bit is clear (0),
14240 * in AdvInitAsc3550Driver() tell the microcode to ignore DMA
14241 * parity errors.
14242 */
14243 asc_dvc->cfg->control_flag = 0;
14244 if (((DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigCommandRegister0x0004)
14245 & AscPCICmdRegBits_ParErrRespCtrl0x0040)) == 0)
14246 {
14247 asc_dvc->cfg->control_flag |= CONTROL_FLAG_IGNORE_PERR0x0001;
14248 }
14249
14250 asc_dvc->cur_host_qng = 0;
14251
14252 asc_dvc->cfg->lib_version = (ADV_LIB_VERSION_MAJOR3 << 8) |
14253 ADV_LIB_VERSION_MINOR45;
14254 asc_dvc->cfg->chip_version =
14255 AdvGetChipVersion(iop_base, asc_dvc->bus_type)((*(volatile unsigned char *) (((iop_base)) + (0x03))));
14256
14257 /*
14258 * Reset the chip to start and allow register writes.
14259 */
14260 if (AdvFindSignature(iop_base)(((((*(volatile unsigned char *) (((iop_base)) + (0x01)))) ==
0x25) && (((*(volatile unsigned short *) (((iop_base
)) + (0x00)))) == 0x04C1)) ? 1 : 0)
== 0)
14261 {
14262 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE0x0200;
14263 return ADV_ERROR(-1);
14264 }
14265 else {
14266
14267 AdvResetChip(asc_dvc);
14268
14269 if ((status = AdvInitFromEEP(asc_dvc)) == ADV_ERROR(-1))
14270 {
14271 return ADV_ERROR(-1);
14272 }
14273 warn_code |= status;
14274
14275 /*
14276 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
14277 * Resets should be performed.
14278 */
14279 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS0x0200)
14280 {
14281 AdvResetSCSIBus(asc_dvc);
14282 }
14283 }
14284
14285 return warn_code;
14286}
14287
14288/*
14289 * Initialize the ASC3550.
14290 *
14291 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
14292 *
14293 * For a non-fatal error return a warning code. If there are no warnings
14294 * then 0 is returned.
14295 */
14296ASC_INITFUNC(int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
14297intint AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
14298AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
14299)int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
14300{
14301 AdvPortAddrunsigned long iop_base;
14302 ushort warn_code;
14303 ulong sum;
14304 int begin_addr;
14305 int end_addr;
14306 int code_sum;
14307 int word;
14308 int rql_addr; /* RISC Queue List address */
14309 int i;
14310 ushort scsi_cfg1;
14311 uchar biosmem[ASC_MC_BIOSLEN0x0050]; /* BIOS RISC Memory 0x40-0x8F. */
14312
14313 /* If there is already an error, don't continue. */
14314 if (asc_dvc->err_code != 0)
14315 {
14316 return ADV_ERROR(-1);
14317 }
14318
14319 warn_code = 0;
14320 iop_base = asc_dvc->iop_base;
14321
14322 /*
14323 * Save the RISC memory BIOS region before writing the microcode.
14324 * The BIOS may already be loaded and using its RISC LRAM region
14325 * so its region must be saved and restored.
14326 *
14327 * Note: This code makes the assumption, which is currently true,
14328 * that a chip reset does not clear RISC LRAM.
14329 */
14330 for (i = 0; i < ASC_MC_BIOSLEN0x0050; i++)
14331 {
14332 AdvReadByteLram(iop_base, ASC_MC_BIOSMEM + i, biosmem[i])do { ((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((
0x0040 + i))); (biosmem[i]) = (*(volatile unsigned char *) ((
iop_base) + 0x06)); } while (0)
;
14333 }
14334
14335 /*
14336 * Load the Microcode
14337 *
14338 * Write the microcode image to RISC memory starting at address 0.
14339 */
14340 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0)(((*(volatile unsigned short *) ((iop_base) + (0x04))) = ((0)
)))
;
14341 for (word = 0; word < _adv_mcode_size; word += 2)
14342 {
14343 AdvWriteWordAutoIncLram(iop_base,(((*(volatile unsigned short *) ((iop_base) + 0x06)) = ((*((ushort
*) (&_adv_mcode_buf[word]))))))
14344 *((ushort *) (&_adv_mcode_buf[word])))(((*(volatile unsigned short *) ((iop_base) + 0x06)) = ((*((ushort
*) (&_adv_mcode_buf[word]))))))
;
14345 }
14346
14347 /*
14348 * Clear the rest of Condor's Internal RAM (8KB).
14349 */
14350 for (; word < ADV_CONDOR_MEMSIZE0x2000; word += 2)
14351 {
14352 AdvWriteWordAutoIncLram(iop_base, 0)(((*(volatile unsigned short *) ((iop_base) + 0x06)) = ((0)))
)
;
14353 }
14354
14355 /*
14356 * Verify the microcode checksum.
14357 */
14358 sum = 0;
14359 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0)(((*(volatile unsigned short *) ((iop_base) + (0x04))) = ((0)
)))
;
14360 for (word = 0; word < _adv_mcode_size; word += 2)
14361 {
14362 sum += AdvReadWordAutoIncLram(iop_base)((*(volatile unsigned short *) ((iop_base) + 0x06)));
14363 }
14364
14365 if (sum != _adv_mcode_chksum)
14366 {
14367 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM0x0002;
14368 return ADV_ERROR(-1);
14369 }
14370
14371 /*
14372 * Restore the RISC memory BIOS region.
14373 */
14374 for (i = 0; i < ASC_MC_BIOSLEN0x0050; i++)
14375 {
14376 AdvWriteByteLram(iop_base, ASC_MC_BIOSMEM + i, biosmem[i])(((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((0x0040
+ i))), ((*(volatile unsigned char *) ((iop_base) + 0x06)) =
((biosmem[i]))))
;
14377 }
14378
14379 /*
14380 * Calculate and write the microcode code checksum to the microcode
14381 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
14382 */
14383 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr)do { ((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((
0x0028))); (begin_addr) = (*(volatile unsigned short *) ((iop_base
) + 0x06)); } while (0)
;
14384 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr)do { ((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((
0x002A))); (end_addr) = (*(volatile unsigned short *) ((iop_base
) + 0x06)); } while (0)
;
14385 code_sum = 0;
14386 for (word = begin_addr; word < end_addr; word += 2)
14387 {
14388 code_sum += *((ushort *) (&_adv_mcode_buf[word]));
14389 }
14390 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum)(((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((0x002C
))), ((*(volatile unsigned short *) ((iop_base) + 0x06)) = ((
code_sum))))
;
14391
14392 /*
14393 * Read microcode version and date.
14394 */
14395 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE, asc_dvc->cfg->mcode_date)do { ((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((
0x0038))); (asc_dvc->cfg->mcode_date) = (*(volatile unsigned
short *) ((iop_base) + 0x06)); } while (0)
;
14396 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM, asc_dvc->cfg->mcode_version)do { ((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((
0x003A))); (asc_dvc->cfg->mcode_version) = (*(volatile unsigned
short *) ((iop_base) + 0x06)); } while (0)
;
14397
14398 /*
14399 * Initialize microcode operating variables
14400 */
14401 AdvWriteWordLram(iop_base, ASC_MC_ADAPTER_SCSI_ID,(((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((0x0098
))), ((*(volatile unsigned short *) ((iop_base) + 0x06)) = ((
asc_dvc->chip_scsi_id))))
14402 asc_dvc->chip_scsi_id)(((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((0x0098
))), ((*(volatile unsigned short *) ((iop_base) + 0x06)) = ((
asc_dvc->chip_scsi_id))))
;
14403
14404 /*
14405 * If the PCI Configuration Command Register "Parity Error Response
14406 * Control" Bit was clear (0), then set the microcode variable
14407 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
14408 * to ignore DMA parity errors.
14409 */
14410 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR0x0001)
14411 {
14412 /*
14413 * Note: Don't remove the use of a temporary variable in
14414 * the following code, otherwise the Microsoft C compiler
14415 * will turn the following lines into a no-op.
14416 */
14417 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word)do { ((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((
0x0122))); (word) = (*(volatile unsigned short *) ((iop_base)
+ 0x06)); } while (0)
;
14418 word |= CONTROL_FLAG_IGNORE_PERR0x0001;
14419 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word)(((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((0x0122
))), ((*(volatile unsigned short *) ((iop_base) + 0x06)) = ((
word))))
;
14420 }
14421
14422 /*
14423 * Set default microcode operating variables for WDTR, SDTR, and
14424 * command tag queuing based on the EEPROM configuration values.
14425 *
14426 * These ADV_DVC_VAR fields and the microcode variables will be
14427 * changed in AdvInquiryHandling() if it is found a device is
14428 * incapable of a particular feature.
14429 */
14430
14431 /*
14432 * Set the microcode ULTRA target mask from EEPROM value. The
14433 * SDTR target mask overrides the ULTRA target mask in the
14434 * microcode so it is safe to set this value without determining
14435 * whether the device supports SDTR.
14436 *
14437 * Note: There is no way to know whether a device supports ULTRA
14438 * speed without attempting a SDTR ULTRA speed negotiation with
14439 * the device. The device will reject the speed if it does not
14440 * support it by responding with an SDTR message containing a
14441 * slower speed.
14442 */
14443 AdvWriteWordLram(iop_base, ASC_MC_ULTRA_ABLE, asc_dvc->ultra_able)(((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((0x009C
))), ((*(volatile unsigned short *) ((iop_base) + 0x06)) = ((
asc_dvc->ultra_able))))
;
14444 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE, asc_dvc->cfg->disc_enable)(((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((0x00A2
))), ((*(volatile unsigned short *) ((iop_base) + 0x06)) = ((
asc_dvc->cfg->disc_enable))))
;
14445
14446
14447 /*
14448 * Set SCSI_CFG0 Microcode Default Value.
14449 *
14450 * The microcode will set the SCSI_CFG0 register using this value
14451 * after it is started below.
14452 */
14453 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,(((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((0x00AC
))), ((*(volatile unsigned short *) ((iop_base) + 0x06)) = ((
0x2000 | 0x0040 | 0x0010 | asc_dvc->chip_scsi_id))))
14454 PARITY_EN | SEL_TMO_LONG | OUR_ID_EN | asc_dvc->chip_scsi_id)(((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((0x00AC
))), ((*(volatile unsigned short *) ((iop_base) + 0x06)) = ((
0x2000 | 0x0040 | 0x0010 | asc_dvc->chip_scsi_id))))
;
14455
14456 /*
14457 * Determine SCSI_CFG1 Microcode Default Value.
14458 *
14459 * The microcode will set the SCSI_CFG1 register using this value
14460 * after it is started below.
14461 */
14462
14463 /* Read current SCSI_CFG1 Register value. */
14464 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1)((*(volatile unsigned short *) ((iop_base) + (0x0E))));
14465
14466 /*
14467 * If all three connectors are in use, return an error.
14468 */
14469 if ((scsi_cfg1 & CABLE_ILLEGAL_A0x7) == 0 ||
14470 (scsi_cfg1 & CABLE_ILLEGAL_B0xB) == 0)
14471 {
14472 asc_dvc->err_code |= ASC_IERR_ILLEGAL_CONNECTION0x0400;
14473 return ADV_ERROR(-1);
14474 }
14475
14476 /*
14477 * If the internal narrow cable is reversed all of the SCSI_CTRL
14478 * register signals will be set. Check for and return an error if
14479 * this condition is found.
14480 */
14481 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL)((*(volatile unsigned short *) ((iop_base) + (0x34)))) & 0x3F07) == 0x3F07)
14482 {
14483 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE0x1000;
14484 return ADV_ERROR(-1);
14485 }
14486
14487 /*
14488 * If this is a differential board and a single-ended device
14489 * is attached to one of the connectors, return an error.
14490 */
14491 if ((scsi_cfg1 & DIFF_MODE0x0100) && (scsi_cfg1 & DIFF_SENSE0x0080) == 0)
14492 {
14493 asc_dvc->err_code |= ASC_IERR_SINGLE_END_DEVICE0x0800;
14494 return ADV_ERROR(-1);
14495 }
14496
14497 /*
14498 * If automatic termination control is enabled, then set the
14499 * termination value based on a table listed in a_condor.h.
14500 *
14501 * If manual termination was specified with an EEPROM setting
14502 * then 'termination' was set-up in AdvInitFromEEP() and
14503 * is ready to be 'ored' into SCSI_CFG1.
14504 */
14505 if (asc_dvc->cfg->termination == 0)
14506 {
14507 /*
14508 * The software always controls termination by setting TERM_CTL_SEL.
14509 * If TERM_CTL_SEL were set to 0, the hardware would set termination.
14510 */
14511 asc_dvc->cfg->termination |= TERM_CTL_SEL0x0040;
14512
14513 switch(scsi_cfg1 & CABLE_DETECT0x000F)
14514 {
14515 /* TERM_CTL_H: on, TERM_CTL_L: on */
14516 case 0x3: case 0x7: case 0xB: case 0xD: case 0xE: case 0xF:
14517 asc_dvc->cfg->termination |= (TERM_CTL_H0x0020 | TERM_CTL_L0x0010);
14518 break;
14519
14520 /* TERM_CTL_H: on, TERM_CTL_L: off */
14521 case 0x1: case 0x5: case 0x9: case 0xA: case 0xC:
14522 asc_dvc->cfg->termination |= TERM_CTL_H0x0020;
14523 break;
14524
14525 /* TERM_CTL_H: off, TERM_CTL_L: off */
14526 case 0x2: case 0x6:
14527 break;
14528 }
14529 }
14530
14531 /*
14532 * Clear any set TERM_CTL_H and TERM_CTL_L bits.
14533 */
14534 scsi_cfg1 &= ~TERM_CTL0x0030;
14535
14536 /*
14537 * Invert the TERM_CTL_H and TERM_CTL_L bits and then
14538 * set 'scsi_cfg1'. The TERM_POL bit does not need to be
14539 * referenced, because the hardware internally inverts
14540 * the Termination High and Low bits if TERM_POL is set.
14541 */
14542 scsi_cfg1 |= (TERM_CTL_SEL0x0040 | (~asc_dvc->cfg->termination & TERM_CTL0x0030));
14543
14544 /*
14545 * Set SCSI_CFG1 Microcode Default Value
14546 *
14547 * Set filter value and possibly modified termination control
14548 * bits in the Microcode SCSI_CFG1 Register Value.
14549 *
14550 * The microcode will set the SCSI_CFG1 register using this value
14551 * after it is started below.
14552 */
14553 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1,(((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((0x00AE
))), ((*(volatile unsigned short *) ((iop_base) + 0x06)) = ((
0x0800 | scsi_cfg1))))
14554 FLTR_11_TO_20NS | scsi_cfg1)(((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((0x00AE
))), ((*(volatile unsigned short *) ((iop_base) + 0x06)) = ((
0x0800 | scsi_cfg1))))
;
14555
14556 /*
14557 * Set SEL_MASK Microcode Default Value
14558 *
14559 * The microcode will set the SEL_MASK register using this value
14560 * after it is started below.
14561 */
14562 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,(((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((0x00B2
))), ((*(volatile unsigned short *) ((iop_base) + 0x06)) = ((
(0x01 << ((asc_dvc->chip_scsi_id) & 15))))))
14563 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id))(((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((0x00B2
))), ((*(volatile unsigned short *) ((iop_base) + 0x06)) = ((
(0x01 << ((asc_dvc->chip_scsi_id) & 15))))))
;
14564
14565 /*
14566 * Link all the RISC Queue Lists together in a doubly-linked
14567 * NULL terminated list.
14568 *
14569 * Skip the NULL (0) queue which is not used.
14570 */
14571 for (i = 1, rql_addr = ASC_MC_RISC_Q_LIST_BASE0x1200 + ASC_MC_RISC_Q_LIST_SIZE0x0008;
14572 i < ASC_MC_RISC_Q_TOTAL_CNT0x00FF;
14573 i++, rql_addr += ASC_MC_RISC_Q_LIST_SIZE0x0008)
14574 {
14575 /*
14576 * Set the current RISC Queue List's RQL_FWD and RQL_BWD pointers
14577 * in a one word write and set the state (RQL_STATE) to free.
14578 */
14579 AdvWriteWordLram(iop_base, rql_addr, ((i + 1) + ((i - 1) << 8)))(((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((rql_addr
))), ((*(volatile unsigned short *) ((iop_base) + 0x06)) = ((
((i + 1) + ((i - 1) << 8))))))
;
14580 AdvWriteByteLram(iop_base, rql_addr + RQL_STATE, ASC_MC_QS_FREE)(((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((rql_addr
+ 2))), ((*(volatile unsigned char *) ((iop_base) + 0x06)) =
((0x00))))
;
14581 }
14582
14583 /*
14584 * Set the Host and RISC Queue List pointers.
14585 *
14586 * Both sets of pointers are initialized with the same values:
14587 * ASC_MC_RISC_Q_FIRST(0x01) and ASC_MC_RISC_Q_LAST (0xFF).
14588 */
14589 AdvWriteByteLram(iop_base, ASC_MC_HOST_NEXT_READY, ASC_MC_RISC_Q_FIRST)(((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((0x0128
))), ((*(volatile unsigned char *) ((iop_base) + 0x06)) = ((0x0001
))))
;
14590 AdvWriteByteLram(iop_base, ASC_MC_HOST_NEXT_DONE, ASC_MC_RISC_Q_LAST)(((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((0x0129
))), ((*(volatile unsigned char *) ((iop_base) + 0x06)) = ((0x00FF
))))
;
14591
14592 AdvWriteByteLram(iop_base, ASC_MC_RISC_NEXT_READY, ASC_MC_RISC_Q_FIRST)(((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((0x00B4
))), ((*(volatile unsigned char *) ((iop_base) + 0x06)) = ((0x0001
))))
;
14593 AdvWriteByteLram(iop_base, ASC_MC_RISC_NEXT_DONE, ASC_MC_RISC_Q_LAST)(((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((0x00B5
))), ((*(volatile unsigned char *) ((iop_base) + 0x06)) = ((0x00FF
))))
;
14594
14595 /*
14596 * Finally, set up the last RISC Queue List (255) with
14597 * a NULL forward pointer.
14598 */
14599 AdvWriteWordLram(iop_base, rql_addr, (ASC_MC_NULL_Q + ((i - 1) << 8)))(((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((rql_addr
))), ((*(volatile unsigned short *) ((iop_base) + 0x06)) = ((
(0x00 + ((i - 1) << 8))))))
;
14600 AdvWriteByteLram(iop_base, rql_addr + RQL_STATE, ASC_MC_QS_FREE)(((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((rql_addr
+ 2))), ((*(volatile unsigned char *) ((iop_base) + 0x06)) =
((0x00))))
;
14601
14602 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,(((*(volatile unsigned char *) ((iop_base) + (0x02))) = (((0x01
| 0x80)))))
14603 (ADV_INTR_ENABLE_HOST_INTR | ADV_INTR_ENABLE_GLOBAL_INTR))(((*(volatile unsigned char *) ((iop_base) + (0x02))) = (((0x01
| 0x80)))))
;
14604
14605 /*
14606 * Note: Don't remove the use of a temporary variable in
14607 * the following code, otherwise the Microsoft C compiler
14608 * will turn the following lines into a no-op.
14609 */
14610 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word)do { ((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((
0x0028))); (word) = (*(volatile unsigned short *) ((iop_base)
+ 0x06)); } while (0)
;
14611 AdvWriteWordRegister(iop_base, IOPW_PC, word)(((*(volatile unsigned short *) ((iop_base) + (0x2A))) = ((word
))))
;
14612
14613 /* finally, finally, gentlemen, start your engine */
14614 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN)(((*(volatile unsigned short *) ((iop_base) + (0x0A))) = (((0x4000
)))))
;
14615
14616 return warn_code;
14617}
14618
14619/*
14620 * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
14621 * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
14622 * all of this is done.
14623 *
14624 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
14625 *
14626 * For a non-fatal error return a warning code. If there are no warnings
14627 * then 0 is returned.
14628 *
14629 * Note: Chip is stopped on entry.
14630 */
14631ASC_INITFUNC(static int AdvInitFromEEP(ADV_DVC_VAR *asc_dvc)
14632STATIC intstatic int AdvInitFromEEP(ADV_DVC_VAR *asc_dvc)
14633AdvInitFromEEP(ADV_DVC_VAR *asc_dvc)static int AdvInitFromEEP(ADV_DVC_VAR *asc_dvc)
14634)static int AdvInitFromEEP(ADV_DVC_VAR *asc_dvc)
14635{
14636 AdvPortAddrunsigned long iop_base;
14637 ushort warn_code;
14638 ADVEEP_CONFIG eep_config;
14639 int i;
14640
14641 iop_base = asc_dvc->iop_base;
14642
14643 warn_code = 0;
14644
14645 /*
14646 * Read the board's EEPROM configuration.
14647 *
14648 * Set default values if a bad checksum is found.
14649 */
14650 if (AdvGetEEPConfig(iop_base, &eep_config) != eep_config.check_sum)
14651 {
14652 warn_code |= ASC_WARN_EEPROM_CHKSUM0x0002;
14653
14654 /*
14655 * Set EEPROM default values.
14656 */
14657 for (i = 0; i < sizeof(ADVEEP_CONFIG); i++)
14658 {
14659 *((uchar *) &eep_config + i) =
14660 *((uchar *) &Default_EEPROM_Config + i);
14661 }
14662
14663 /*
14664 * Assume the 6 byte board serial number that was read
14665 * from EEPROM is correct even if the EEPROM checksum
14666 * failed.
14667 */
14668 eep_config.serial_number_word3 =
14669 AdvReadEEPWord(iop_base, ASC_EEP_DVC_CFG_END(0x15) - 1);
14670 eep_config.serial_number_word2 =
14671 AdvReadEEPWord(iop_base, ASC_EEP_DVC_CFG_END(0x15) - 2);
14672 eep_config.serial_number_word1 =
14673 AdvReadEEPWord(iop_base, ASC_EEP_DVC_CFG_END(0x15) - 3);
14674 AdvSetEEPConfig(iop_base, &eep_config);
14675 }
14676
14677 /*
14678 * Set ADV_DVC_VAR and ADV_DVC_CFG variables from the
14679 * EEPROM configuration that was read.
14680 *
14681 * This is the mapping of EEPROM fields to Adv Library fields.
14682 */
14683 asc_dvc->wdtr_able = eep_config.wdtr_able;
14684 asc_dvc->sdtr_able = eep_config.sdtr_able;
14685 asc_dvc->ultra_able = eep_config.ultra_able;
14686 asc_dvc->tagqng_able = eep_config.tagqng_able;
14687 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
14688 asc_dvc->max_host_qng = eep_config.max_host_qng;
14689 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
14690 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID15);
14691 asc_dvc->start_motor = eep_config.start_motor;
14692 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
14693 asc_dvc->cfg->bios_boot_wait = eep_config.bios_boot_delay;
14694 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
14695 asc_dvc->no_scam = eep_config.scam_tolerant;
14696 asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
14697 asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
14698 asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
14699
14700 /*
14701 * Set the host maximum queuing (max. 253, min. 16) and the per device
14702 * maximum queuing (max. 63, min. 4).
14703 */
14704 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG0xFD)
14705 {
14706 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG0xFD;
14707 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG0x10)
14708 {
14709 /* If the value is zero, assume it is uninitialized. */
14710 if (eep_config.max_host_qng == 0)
14711 {
14712 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG0xFD;
14713 } else
14714 {
14715 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG0x10;
14716 }
14717 }
14718
14719 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG0x3F)
14720 {
14721 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG0x3F;
14722 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG0x04)
14723 {
14724 /* If the value is zero, assume it is uninitialized. */
14725 if (eep_config.max_dvc_qng == 0)
14726 {
14727 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG0x3F;
14728 } else
14729 {
14730 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG0x04;
14731 }
14732 }
14733
14734 /*
14735 * If 'max_dvc_qng' is greater than 'max_host_qng', then
14736 * set 'max_dvc_qng' to 'max_host_qng'.
14737 */
14738 if (eep_config.max_dvc_qng > eep_config.max_host_qng)
14739 {
14740 eep_config.max_dvc_qng = eep_config.max_host_qng;
14741 }
14742
14743 /*
14744 * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_CFG 'max_dvc_qng'
14745 * values based on possibly adjusted EEPROM values.
14746 */
14747 asc_dvc->max_host_qng = eep_config.max_host_qng;
14748 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
14749
14750
14751 /*
14752 * If the EEPROM 'termination' field is set to automatic (0), then set
14753 * the ADV_DVC_CFG 'termination' field to automatic also.
14754 *
14755 * If the termination is specified with a non-zero 'termination'
14756 * value check that a legal value is set and set the ADV_DVC_CFG
14757 * 'termination' field appropriately.
14758 */
14759 if (eep_config.termination == 0)
14760 {
14761 asc_dvc->cfg->termination = 0; /* auto termination */
14762 } else
14763 {
14764 /* Enable manual control with low off / high off. */
14765 if (eep_config.termination == 1)
14766 {
14767 asc_dvc->cfg->termination = TERM_CTL_SEL0x0040;
14768
14769 /* Enable manual control with low off / high on. */
14770 } else if (eep_config.termination == 2)
14771 {
14772 asc_dvc->cfg->termination = TERM_CTL_SEL0x0040 | TERM_CTL_H0x0020;
14773
14774 /* Enable manual control with low on / high on. */
14775 } else if (eep_config.termination == 3)
14776 {
14777 asc_dvc->cfg->termination = TERM_CTL_SEL0x0040 | TERM_CTL_H0x0020 | TERM_CTL_L0x0010;
14778 } else
14779 {
14780 /*
14781 * The EEPROM 'termination' field contains a bad value. Use
14782 * automatic termination instead.
14783 */
14784 asc_dvc->cfg->termination = 0;
14785 warn_code |= ASC_WARN_EEPROM_TERMINATION0x0004;
14786 }
14787 }
14788
14789 return warn_code;
14790}
14791
14792/*
14793 * Read EEPROM configuration into the specified buffer.
14794 *
14795 * Return a checksum based on the EEPROM configuration read.
14796 */
14797ASC_INITFUNC(static ushort AdvGetEEPConfig(unsigned long iop_base, ADVEEP_CONFIG
*cfg_buf)
14798STATIC ushortstatic ushort AdvGetEEPConfig(unsigned long iop_base, ADVEEP_CONFIG
*cfg_buf)
14799AdvGetEEPConfig(AdvPortAddr iop_base, ADVEEP_CONFIG *cfg_buf)static ushort AdvGetEEPConfig(unsigned long iop_base, ADVEEP_CONFIG
*cfg_buf)
14800)static ushort AdvGetEEPConfig(unsigned long iop_base, ADVEEP_CONFIG
*cfg_buf)
14801{
14802 ushort wval, chksum;
14803 ushort *wbuf;
14804 int eep_addr;
14805
14806 wbuf = (ushort *) cfg_buf;
14807 chksum = 0;
14808
14809 for (eep_addr = ASC_EEP_DVC_CFG_BEGIN(0x00);
14810 eep_addr < ASC_EEP_DVC_CFG_END(0x15);
14811 eep_addr++, wbuf++)
14812 {
14813 wval = AdvReadEEPWord(iop_base, eep_addr);
14814 chksum += wval;
14815 *wbuf = wval;
14816 }
14817 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
14818 wbuf++;
14819 for (eep_addr = ASC_EEP_DVC_CTL_BEGIN(0x16);
14820 eep_addr < ASC_EEP_MAX_WORD_ADDR(0x1E);
14821 eep_addr++, wbuf++)
14822 {
14823 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
14824 }
14825 return chksum;
14826}
14827
14828/*
14829 * Read the EEPROM from specified location
14830 */
14831ASC_INITFUNC(static ushort AdvReadEEPWord(unsigned long iop_base, int eep_word_addr
)
14832STATIC ushortstatic ushort AdvReadEEPWord(unsigned long iop_base, int eep_word_addr
)
14833AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr)static ushort AdvReadEEPWord(unsigned long iop_base, int eep_word_addr
)
14834)static ushort AdvReadEEPWord(unsigned long iop_base, int eep_word_addr
)
14835{
14836 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,(((*(volatile unsigned short *) ((iop_base) + (0x1A))) = ((0x80
| eep_word_addr))))
14837 ASC_EEP_CMD_READ | eep_word_addr)(((*(volatile unsigned short *) ((iop_base) + (0x1A))) = ((0x80
| eep_word_addr))))
;
14838 AdvWaitEEPCmd(iop_base);
14839 return AdvReadWordRegister(iop_base, IOPW_EE_DATA)((*(volatile unsigned short *) ((iop_base) + (0x1C))));
14840}
14841
14842/*
14843 * Wait for EEPROM command to complete
14844 */
14845ASC_INITFUNC(static void AdvWaitEEPCmd(unsigned long iop_base)
14846STATIC voidstatic void AdvWaitEEPCmd(unsigned long iop_base)
14847AdvWaitEEPCmd(AdvPortAddr iop_base)static void AdvWaitEEPCmd(unsigned long iop_base)
14848)static void AdvWaitEEPCmd(unsigned long iop_base)
14849{
14850 int eep_delay_ms;
14851
14852 for (eep_delay_ms = 0; eep_delay_ms < ASC_EEP_DELAY_MS100; eep_delay_ms++)
14853 {
14854 if (AdvReadWordRegister(iop_base, IOPW_EE_CMD)((*(volatile unsigned short *) ((iop_base) + (0x1A)))) & ASC_EEP_CMD_DONE0x0200)
14855 {
14856 break;
14857 }
14858 DvcSleepMilliSecond(1);
14859 }
14860 if ((AdvReadWordRegister(iop_base, IOPW_EE_CMD)((*(volatile unsigned short *) ((iop_base) + (0x1A)))) & ASC_EEP_CMD_DONE0x0200) == 0)
14861 {
14862 ADV_ASSERT(0){ if (!(0)) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 14862); } }
;
14863 }
14864 return;
14865}
14866
14867/*
14868 * Write the EEPROM from 'cfg_buf'.
14869 */
14870ASC_INITFUNC(static void AdvSetEEPConfig(unsigned long iop_base, ADVEEP_CONFIG
*cfg_buf)
14871STATIC voidstatic void AdvSetEEPConfig(unsigned long iop_base, ADVEEP_CONFIG
*cfg_buf)
14872AdvSetEEPConfig(AdvPortAddr iop_base, ADVEEP_CONFIG *cfg_buf)static void AdvSetEEPConfig(unsigned long iop_base, ADVEEP_CONFIG
*cfg_buf)
14873)static void AdvSetEEPConfig(unsigned long iop_base, ADVEEP_CONFIG
*cfg_buf)
14874{
14875 ushort *wbuf;
14876 ushort addr, chksum;
14877
14878 wbuf = (ushort *) cfg_buf;
14879 chksum = 0;
14880
14881 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE)(((*(volatile unsigned short *) ((iop_base) + (0x1A))) = ((0x30
))))
;
14882 AdvWaitEEPCmd(iop_base);
14883
14884 /*
14885 * Write EEPROM from word 0 to word 15
14886 */
14887 for (addr = ASC_EEP_DVC_CFG_BEGIN(0x00);
14888 addr < ASC_EEP_DVC_CFG_END(0x15); addr++, wbuf++)
14889 {
14890 chksum += *wbuf;
14891 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, *wbuf)(((*(volatile unsigned short *) ((iop_base) + (0x1C))) = ((*wbuf
))))
;
14892 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr)(((*(volatile unsigned short *) ((iop_base) + (0x1A))) = ((0x40
| addr))))
;
14893 AdvWaitEEPCmd(iop_base);
14894 DvcSleepMilliSecond(ASC_EEP_DELAY_MS100);
14895 }
14896
14897 /*
14898 * Write EEPROM checksum at word 18
14899 */
14900 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum)(((*(volatile unsigned short *) ((iop_base) + (0x1C))) = ((chksum
))))
;
14901 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr)(((*(volatile unsigned short *) ((iop_base) + (0x1A))) = ((0x40
| addr))))
;
14902 AdvWaitEEPCmd(iop_base);
14903 wbuf++; /* skip over check_sum */
14904
14905 /*
14906 * Write EEPROM OEM name at words 19 to 26
14907 */
14908 for (addr = ASC_EEP_DVC_CTL_BEGIN(0x16);
14909 addr < ASC_EEP_MAX_WORD_ADDR(0x1E); addr++, wbuf++)
14910 {
14911 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, *wbuf)(((*(volatile unsigned short *) ((iop_base) + (0x1C))) = ((*wbuf
))))
;
14912 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr)(((*(volatile unsigned short *) ((iop_base) + (0x1A))) = ((0x40
| addr))))
;
14913 AdvWaitEEPCmd(iop_base);
14914 }
14915 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE)(((*(volatile unsigned short *) ((iop_base) + (0x1A))) = ((0x00
))))
;
14916 AdvWaitEEPCmd(iop_base);
14917 return;
14918}
14919
14920/*
14921 * This function resets the chip and SCSI bus
14922 *
14923 * It is up to the caller to add a delay to let the bus settle after
14924 * calling this function.
14925 *
14926 * The SCSI_CFG0, SCSI_CFG1, and MEM_CFG registers are set-up in
14927 * AdvInitAsc3550Driver(). Here when doing a write to one of these
14928 * registers read first and then write.
14929 *
14930 * Note: A SCSI Bus Reset can not be done until after the EEPROM
14931 * configuration is read to determine whether SCSI Bus Resets
14932 * should be performed.
14933 */
14934ASC_INITFUNC(static void AdvResetChip(ADV_DVC_VAR *asc_dvc)
14935STATIC voidstatic void AdvResetChip(ADV_DVC_VAR *asc_dvc)
14936AdvResetChip(ADV_DVC_VAR *asc_dvc)static void AdvResetChip(ADV_DVC_VAR *asc_dvc)
14937)static void AdvResetChip(ADV_DVC_VAR *asc_dvc)
14938{
14939 AdvPortAddrunsigned long iop_base;
14940 ushort word;
14941 uchar byte;
14942
14943 iop_base = asc_dvc->iop_base;
14944
14945 /*
14946 * Reset Chip.
14947 */
14948 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_RESET)(((*(volatile unsigned short *) ((iop_base) + (0x02))) = ((0x00C6
))))
;
14949 DvcSleepMilliSecond(100);
14950 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_WR_IO_REG)(((*(volatile unsigned short *) ((iop_base) + (0x02))) = ((0x00C5
))))
;
14951
14952 /*
14953 * Initialize Chip registers.
14954 *
14955 * Note: Don't remove the use of a temporary variable in the following
14956 * code, otherwise the Microsoft C compiler will turn the following lines
14957 * into a no-op.
14958 */
14959 byte = AdvReadByteRegister(iop_base, IOPB_MEM_CFG)((*(volatile unsigned char *) ((iop_base) + (0x10))));
14960 byte |= RAM_SZ_8KB0x08;
14961 AdvWriteByteRegister(iop_base, IOPB_MEM_CFG, byte)(((*(volatile unsigned char *) ((iop_base) + (0x10))) = ((byte
))))
;
14962
14963 word = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1)((*(volatile unsigned short *) ((iop_base) + (0x0E))));
14964 word &= ~BIG_ENDIAN0x8000;
14965 AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1, word)(((*(volatile unsigned short *) ((iop_base) + (0x0E))) = ((word
))))
;
14966
14967 /*
14968 * Setting the START_CTL_EMFU 3:2 bits sets a FIFO threshold
14969 * of 128 bytes. This register is only accessible to the host.
14970 */
14971 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,(((*(volatile unsigned char *) ((iop_base) + (0x20))) = ((0x0C
| 0x03))))
14972 START_CTL_EMFU | READ_CMD_MRM)(((*(volatile unsigned char *) ((iop_base) + (0x20))) = ((0x0C
| 0x03))))
;
14973}
14974
14975/* a_advlib.c */
14976/*
14977 * Description:
14978 * Send a SCSI request to the ASC3550 chip
14979 *
14980 * If there is no SG list for the request, set 'sg_entry_cnt' to 0.
14981 *
14982 * If 'sg_real_addr' is non-zero on entry, AscGetSGList() will not be
14983 * called. It is assumed the caller has already initialized 'sg_real_addr'.
14984 *
14985 * Return:
14986 * ADV_SUCCESS(1) - the request is in the mailbox
14987 * ADV_BUSY(0) - total request count > 253, try later
14988 * ADV_ERROR(-1) - invalid scsi request Q
14989 */
14990STATICstatic int
14991AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc,
14992 ADV_SCSI_REQ_Q *scsiq)
14993{
14994 if (scsiq == (ADV_SCSI_REQ_Q *) 0L)
14995 {
14996 /* 'scsiq' should never be NULL. */
14997 ADV_ASSERT(0){ if (!(0)) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 14997); } }
;
14998 return ADV_ERROR(-1);
14999 }
15000
15001 return AdvSendScsiCmd(asc_dvc, scsiq);
15002}
15003
15004/*
15005 * Reset SCSI Bus and purge all outstanding requests.
15006 *
15007 * Return Value:
15008 * ADV_TRUE(1) - All requests are purged and SCSI Bus is reset.
15009 *
15010 * Note: Should always return ADV_TRUE.
15011 */
15012STATICstatic int
15013AdvResetSB(ADV_DVC_VAR *asc_dvc)
15014{
15015 int status;
15016
15017 status = AdvSendIdleCmd(asc_dvc, (ushort) IDLE_CMD_SCSI_RESET0x0020, 0L, 0);
15018
15019 AdvResetSCSIBus(asc_dvc);
15020
15021 return status;
15022}
15023
15024/*
15025 * Reset SCSI Bus and delay.
15026 */
15027STATICstatic void
15028AdvResetSCSIBus(ADV_DVC_VAR *asc_dvc)
15029{
15030 AdvPortAddrunsigned long iop_base;
15031 ushort scsi_ctrl;
15032
15033 iop_base = asc_dvc->iop_base;
15034
15035 /*
15036 * The microcode currently sets the SCSI Bus Reset signal while
15037 * handling the AscSendIdleCmd() IDLE_CMD_SCSI_RESET command above.
15038 * But the SCSI Bus Reset Hold Time in the microcode is not deterministic
15039 * (it may in fact be for less than the SCSI Spec. minimum of 25 us).
15040 * Therefore on return the Adv Library sets the SCSI Bus Reset signal
15041 * for ASC_SCSI_RESET_HOLD_TIME_US, which is defined to be greater
15042 * than 25 us.
15043 */
15044 scsi_ctrl = AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL)((*(volatile unsigned short *) ((iop_base) + (0x34))));
15045 AdvWriteWordRegister(iop_base, IOPW_SCSI_CTRL,(((*(volatile unsigned short *) ((iop_base) + (0x34))) = ((scsi_ctrl
| 0x2000))))
15046 scsi_ctrl | ADV_SCSI_CTRL_RSTOUT)(((*(volatile unsigned short *) ((iop_base) + (0x34))) = ((scsi_ctrl
| 0x2000))))
;
15047 DvcDelayMicroSecond(asc_dvc, (ushort) ASC_SCSI_RESET_HOLD_TIME_US60);
15048 AdvWriteWordRegister(iop_base, IOPW_SCSI_CTRL,(((*(volatile unsigned short *) ((iop_base) + (0x34))) = ((scsi_ctrl
& ~0x2000))))
15049 scsi_ctrl & ~ADV_SCSI_CTRL_RSTOUT)(((*(volatile unsigned short *) ((iop_base) + (0x34))) = ((scsi_ctrl
& ~0x2000))))
;
15050
15051 DvcSleepMilliSecond((ulong) asc_dvc->scsi_reset_wait * 1000);
15052}
15053
15054
15055/*
15056 * Adv Library Interrupt Service Routine
15057 *
15058 * This function is called by a driver's interrupt service routine.
15059 * The function disables and re-enables interrupts.
15060 *
15061 * When a microcode idle command is completed, the ADV_DVC_VAR
15062 * 'idle_cmd_done' field is set to ADV_TRUE.
15063 *
15064 * Note: AdvISR() can be called when interrupts are disabled or even
15065 * when there is no hardware interrupt condition present. It will
15066 * always check for completed idle commands and microcode requests.
15067 * This is an important feature that shouldn't be changed because it
15068 * allows commands to be completed from polling mode loops.
15069 *
15070 * Return:
15071 * ADV_TRUE(1) - interrupt was pending
15072 * ADV_FALSE(0) - no interrupt was pending
15073 */
15074STATICstatic int
15075AdvISR(ADV_DVC_VAR *asc_dvc)
15076{
15077 AdvPortAddrunsigned long iop_base;
15078 uchar int_stat;
15079 ushort next_done_loc, target_bit;
15080 int completed_q;
15081 long flags;
15082 ADV_SCSI_REQ_Q *scsiq;
15083 ASC_REQ_SENSE *sense_data;
15084 int ret;
15085
15086 flags = DvcEnterCritical();
15087 iop_base = asc_dvc->iop_base;
15088
15089 if (AdvIsIntPending(iop_base)(((*(volatile unsigned short *) ((iop_base) + (0x02)))) &
0x0100)
)
15090 {
15091 ret = ADV_TRUE1;
15092 } else
15093 {
15094 ret = ADV_FALSE0;
15095 }
15096
15097 /* Reading the register clears the interrupt. */
15098 int_stat = AdvReadByteRegister(iop_base, IOPB_INTR_STATUS_REG)((*(volatile unsigned char *) ((iop_base) + (0x00))));
15099
15100 if (int_stat & ADV_INTR_STATUS_INTRB0x02)
15101 {
15102 asc_dvc->idle_cmd_done = ADV_TRUE1;
15103 }
15104
15105 /*
15106 * Notify the driver of a hardware detected SCSI Bus Reset.
15107 */
15108 if (int_stat & ADV_INTR_STATUS_INTRC0x04)
15109 {
15110 if (asc_dvc->sbreset_callback != 0)
15111 {
15112 (*(ADV_SBRESET_CALLBACK) asc_dvc->sbreset_callback)(asc_dvc);
15113 }
15114 }
15115
15116 /*
15117 * ASC_MC_HOST_NEXT_DONE (0x129) is actually the last completed RISC
15118 * Queue List request. Its forward pointer (RQL_FWD) points to the
15119 * current completed RISC Queue List request.
15120 */
15121 AdvReadByteLram(iop_base, ASC_MC_HOST_NEXT_DONE, next_done_loc)do { ((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((
0x0129))); (next_done_loc) = (*(volatile unsigned char *) ((iop_base
) + 0x06)); } while (0)
;
15122 next_done_loc = ASC_MC_RISC_Q_LIST_BASE0x1200 +
15123 (next_done_loc * ASC_MC_RISC_Q_LIST_SIZE0x0008) + RQL_FWD0;
15124
15125 AdvReadByteLram(iop_base, next_done_loc, completed_q)do { ((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((
next_done_loc))); (completed_q) = (*(volatile unsigned char *
) ((iop_base) + 0x06)); } while (0)
;
15126
15127 /* Loop until all completed Q's are processed. */
15128 while (completed_q != ASC_MC_NULL_Q0x00)
15129 {
15130 AdvWriteByteLram(iop_base, ASC_MC_HOST_NEXT_DONE, completed_q)(((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((0x0129
))), ((*(volatile unsigned char *) ((iop_base) + 0x06)) = ((completed_q
))))
;
15131
15132 next_done_loc = ASC_MC_RISC_Q_LIST_BASE0x1200 +
15133 (completed_q * ASC_MC_RISC_Q_LIST_SIZE0x0008);
15134
15135 /*
15136 * Read the ADV_SCSI_REQ_Q virtual address pointer from
15137 * the RISC list entry. The microcode has changed the
15138 * ADV_SCSI_REQ_Q physical address to its virtual address.
15139 *
15140 * Refer to comments at the end of AdvSendScsiCmd() for
15141 * more information on the RISC list structure.
15142 */
15143 {
15144 ushort lsw, msw;
15145 AdvReadWordLram(iop_base, next_done_loc + RQL_PHYADDR, lsw)do { ((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((
next_done_loc + 4))); (lsw) = (*(volatile unsigned short *) (
(iop_base) + 0x06)); } while (0)
;
15146 AdvReadWordLram(iop_base, next_done_loc + RQL_PHYADDR + 2, msw)do { ((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((
next_done_loc + 4 + 2))); (msw) = (*(volatile unsigned short *
) ((iop_base) + 0x06)); } while (0)
;
15147
15148 scsiq = (ADV_SCSI_REQ_Q *) (((ulong) msw << 16) | lsw);
15149 }
15150 ADV_ASSERT(scsiq != NULL){ if (!(scsiq != ((void *) 0))) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 15150); } }
;
15151
15152 target_bit = ADV_TID_TO_TIDMASK(scsiq->target_id)(0x01 << ((scsiq->target_id) & 15));
15153
15154 /*
15155 * Clear request microcode control flag.
15156 */
15157 scsiq->cntl = 0;
15158
15159 /*
15160 * Check Condition handling
15161 */
15162 if ((scsiq->done_status == QD_WITH_ERROR0x04) &&
15163 (scsiq->scsi_status == SS_CHK_CONDITION0x02) &&
15164 (sense_data = (ASC_REQ_SENSE *) scsiq->vsense_addr) != 0 &&
15165 (scsiq->orig_sense_len - scsiq->sense_len) >= ASC_MIN_SENSE_LEN14)
15166 {
15167 /*
15168 * Command returned with a check condition and valid
15169 * sense data.
15170 */
15171 }
15172 /*
15173 * If the command that completed was a SCSI INQUIRY and
15174 * LUN 0 was sent the command, then process the INQUIRY
15175 * command information for the device.
15176 */
15177 else if (scsiq->done_status == QD_NO_ERROR0x01 &&
15178 scsiq->cdb[0] == SCSICMD_Inquiry0x12 &&
15179 scsiq->target_lun == 0)
15180 {
15181 AdvInquiryHandling(asc_dvc, scsiq);
15182 }
15183
15184
15185 /* Change the RISC Queue List state to free. */
15186 AdvWriteByteLram(iop_base, next_done_loc + RQL_STATE, ASC_MC_QS_FREE)(((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((next_done_loc
+ 2))), ((*(volatile unsigned char *) ((iop_base) + 0x06)) =
((0x00))))
;
15187
15188 /* Get the RISC Queue List forward pointer. */
15189 AdvReadByteLram(iop_base, next_done_loc + RQL_FWD, completed_q)do { ((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((
next_done_loc + 0))); (completed_q) = (*(volatile unsigned char
*) ((iop_base) + 0x06)); } while (0)
;
15190
15191 /*
15192 * Notify the driver of the completed request by passing
15193 * the ADV_SCSI_REQ_Q pointer to its callback function.
15194 */
15195 ADV_ASSERT(asc_dvc->cur_host_qng > 0){ if (!(asc_dvc->cur_host_qng > 0)) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 15195); } }
;
15196 asc_dvc->cur_host_qng--;
15197 scsiq->a_flag |= ADV_SCSIQ_DONE0x02;
15198 (*(ADV_ISR_CALLBACK) asc_dvc->isr_callback)(asc_dvc, scsiq);
15199 /*
15200 * Note: After the driver callback function is called, 'scsiq'
15201 * can no longer be referenced.
15202 *
15203 * Fall through and continue processing other completed
15204 * requests...
15205 */
15206
15207 /*
15208 * Disable interrupts again in case the driver inadvertently
15209 * enabled interrupts in its callback function.
15210 *
15211 * The DvcEnterCritical() return value is ignored, because
15212 * the 'flags' saved when AdvISR() was first entered will be
15213 * used to restore the interrupt flag on exit.
15214 */
15215 (void) DvcEnterCritical();
15216 }
15217 DvcLeaveCritical(flags);
15218 return ret;
15219}
15220
15221/*
15222 * Send an idle command to the chip and wait for completion.
15223 *
15224 * Interrupts do not have to be enabled on entry.
15225 *
15226 * Return Values:
15227 * ADV_TRUE - command completed successfully
15228 * ADV_FALSE - command failed
15229 */
15230STATICstatic int
15231AdvSendIdleCmd(ADV_DVC_VAR *asc_dvc,
15232 ushort idle_cmd,
15233 ulong idle_cmd_parameter,
15234 int flags)
15235{
15236 int last_int_level;
15237 ulong i;
15238 AdvPortAddrunsigned long iop_base;
15239 int ret;
15240
15241 asc_dvc->idle_cmd_done = 0;
15242
15243 last_int_level = DvcEnterCritical();
15244 iop_base = asc_dvc->iop_base;
15245
15246 /*
15247 * Write the idle command value after the idle command parameter
15248 * has been written to avoid a race condition. If the order is not
15249 * followed, the microcode may process the idle command before the
15250 * parameters have been written to LRAM.
15251 */
15252 AdvWriteDWordLram(iop_base, ASC_MC_IDLE_PARA_STAT, idle_cmd_parameter)((((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((0x00A8
))), ((*(volatile unsigned short *) ((iop_base) + 0x06)) = ((
ushort) ((idle_cmd_parameter) & 0xFFFF)))), (((*(volatile
unsigned short *) ((iop_base) + 0x04)) = ((0x00A8) + 2)), ((
*(volatile unsigned short *) ((iop_base) + 0x06)) = ((ushort)
((idle_cmd_parameter >> 16) & 0xFFFF)))))
;
15253 AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD, idle_cmd)(((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((0x00A6
))), ((*(volatile unsigned short *) ((iop_base) + 0x06)) = ((
idle_cmd))))
;
15254 DvcLeaveCritical(last_int_level);
15255
15256 /*
15257 * If the 'flags' argument contains the ADV_NOWAIT flag, then
15258 * return with success.
15259 */
15260 if (flags & ADV_NOWAIT0x01)
15261 {
15262 return ADV_TRUE1;
15263 }
15264
15265 for (i = 0; i < SCSI_WAIT_10_SEC10 * SCSI_MS_PER_SEC1000; i++)
15266 {
15267 /*
15268 * 'idle_cmd_done' is set by AdvISR().
15269 */
15270 if (asc_dvc->idle_cmd_done)
15271 {
15272 break;
15273 }
15274 DvcSleepMilliSecond(1);
15275
15276 /*
15277 * If interrupts were disabled on entry to AdvSendIdleCmd(),
15278 * then they will still be disabled here. Call AdvISR() to
15279 * check for the idle command completion.
15280 */
15281 (void) AdvISR(asc_dvc);
15282 }
15283
15284 last_int_level = DvcEnterCritical();
15285
15286 if (asc_dvc->idle_cmd_done == ADV_FALSE0)
15287 {
15288 ADV_ASSERT(0){ if (!(0)) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 15288); } }
; /* The idle command should never timeout. */
15289 return ADV_FALSE0;
15290 } else
15291 {
15292 AdvReadWordLram(iop_base, ASC_MC_IDLE_PARA_STAT, ret)do { ((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((
0x00A8))); (ret) = (*(volatile unsigned short *) ((iop_base) +
0x06)); } while (0)
;
15293 return ret;
15294 }
15295}
15296
15297/*
15298 * Send the SCSI request block to the adapter
15299 *
15300 * Each of the 255 Adv Library/Microcode RISC Lists or mailboxes has the
15301 * following structure:
15302 *
15303 * 0: RQL_FWD - RISC list forward pointer (1 byte)
15304 * 1: RQL_BWD - RISC list backward pointer (1 byte)
15305 * 2: RQL_STATE - RISC list state byte - free, ready, done, aborted (1 byte)
15306 * 3: RQL_TID - request target id (1 byte)
15307 * 4: RQL_PHYADDR - ADV_SCSI_REQ_Q physical pointer (4 bytes)
15308 *
15309 * Return:
15310 * ADV_SUCCESS(1) - the request is in the mailbox
15311 * ADV_BUSY(0) - total request count > 253, try later
15312 */
15313STATICstatic int
15314AdvSendScsiCmd(
15315 ADV_DVC_VAR *asc_dvc,
15316 ADV_SCSI_REQ_Q *scsiq)
15317{
15318 ushort next_ready_loc;
15319 uchar next_ready_loc_fwd;
15320 int last_int_level;
15321 AdvPortAddrunsigned long iop_base;
15322 long req_size;
15323 ulong q_phy_addr;
15324
15325 /*
15326 * The ADV_SCSI_REQ_Q 'target_id' field should never be equal
15327 * to the host adapter ID or exceed ADV_MAX_TID.
15328 */
15329 if (scsiq->target_id == asc_dvc->chip_scsi_id ||
15330 scsiq->target_id > ADV_MAX_TID15)
15331 {
15332 scsiq->host_status = QHSTA_M_INVALID_DEVICE0x45;
15333 scsiq->done_status = QD_WITH_ERROR0x04;
15334 return ADV_ERROR(-1);
15335 }
15336
15337 iop_base = asc_dvc->iop_base;
15338
15339 last_int_level = DvcEnterCritical();
15340
15341 if (asc_dvc->cur_host_qng >= asc_dvc->max_host_qng)
15342 {
15343 DvcLeaveCritical(last_int_level);
15344 return ADV_BUSY0;
15345 } else
15346 {
15347 ADV_ASSERT(asc_dvc->cur_host_qng < ASC_MC_RISC_Q_TOTAL_CNT){ if (!(asc_dvc->cur_host_qng < 0x00FF)) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 15347); } }
;
15348 asc_dvc->cur_host_qng++;
15349 }
15350
15351 /*
15352 * Clear the ADV_SCSI_REQ_Q done flag.
15353 */
15354 scsiq->a_flag &= ~ADV_SCSIQ_DONE0x02;
15355
15356 /*
15357 * Save the original sense buffer length.
15358 *
15359 * After the request completes 'sense_len' will be set to the residual
15360 * byte count of the Auto-Request Sense if a command returns CHECK
15361 * CONDITION and the Sense Data is valid indicated by 'host_status' not
15362 * being set to QHSTA_M_AUTO_REQ_SENSE_FAIL. To determine the valid
15363 * Sense Data Length subtract 'sense_len' from 'orig_sense_len'.
15364 */
15365 scsiq->orig_sense_len = scsiq->sense_len;
15366
15367 AdvReadByteLram(iop_base, ASC_MC_HOST_NEXT_READY, next_ready_loc)do { ((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((
0x0128))); (next_ready_loc) = (*(volatile unsigned char *) ((
iop_base) + 0x06)); } while (0)
;
15368 next_ready_loc = ASC_MC_RISC_Q_LIST_BASE0x1200 +
15369 (next_ready_loc * ASC_MC_RISC_Q_LIST_SIZE0x0008);
15370
15371 /*
15372 * Write the physical address of the Q to the mailbox.
15373 * We need to skip the first four bytes, because the microcode
15374 * uses them internally for linking Q's together.
15375 */
15376 req_size = sizeof(ADV_SCSI_REQ_Q);
15377 q_phy_addr = DvcGetPhyAddr(asc_dvc, scsiq,
15378 (uchar *) scsiq, &req_size,
15379 ADV_IS_SCSIQ_FLAG0x01);
15380 ADV_ASSERT(ADV_DWALIGN(q_phy_addr) == q_phy_addr){ if (!((((ulong) (q_phy_addr) + 0x3) & ~0x3) == q_phy_addr
)) { printk("ASC_ASSERT() Failure: file %s, line %d\n", "../linux/src/drivers/scsi/advansys.c"
, 15380); } }
;
15381 ADV_ASSERT(req_size >= sizeof(ADV_SCSI_REQ_Q)){ if (!(req_size >= sizeof(ADV_SCSI_REQ_Q))) { printk("ASC_ASSERT() Failure: file %s, line %d\n"
, "../linux/src/drivers/scsi/advansys.c", 15381); } }
;
15382
15383 scsiq->scsiq_ptr = (ADV_SCSI_REQ_Q *) scsiq;
15384
15385 /*
15386 * The RISC list structure, which 'next_ready_loc' is a pointer
15387 * to in microcode LRAM, has the format detailed in the comment
15388 * header for this function.
15389 *
15390 * Write the ADV_SCSI_REQ_Q physical pointer to 'next_ready_loc' request.
15391 */
15392 AdvWriteDWordLram(iop_base, next_ready_loc + RQL_PHYADDR, q_phy_addr)((((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((next_ready_loc
+ 4))), ((*(volatile unsigned short *) ((iop_base) + 0x06)) =
((ushort) ((q_phy_addr) & 0xFFFF)))), (((*(volatile unsigned
short *) ((iop_base) + 0x04)) = ((next_ready_loc + 4) + 2)),
((*(volatile unsigned short *) ((iop_base) + 0x06)) = ((ushort
) ((q_phy_addr >> 16) & 0xFFFF)))))
;
15393
15394 /* Write target_id to 'next_ready_loc' request. */
15395 AdvWriteByteLram(iop_base, next_ready_loc + RQL_TID, scsiq->target_id)(((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((next_ready_loc
+ 3))), ((*(volatile unsigned char *) ((iop_base) + 0x06)) =
((scsiq->target_id))))
;
15396
15397 /*
15398 * Set the ASC_MC_HOST_NEXT_READY (0x128) microcode variable to
15399 * the 'next_ready_loc' request forward pointer.
15400 *
15401 * Do this *before* changing the 'next_ready_loc' queue to QS_READY.
15402 * After the state is changed to QS_READY 'RQL_FWD' will be changed
15403 * by the microcode.
15404 *
15405 * NOTE: The temporary variable 'next_ready_loc_fwd' is required to
15406 * prevent some compilers from optimizing out 'AdvReadByteLram()' if
15407 * it were used as the 3rd argument to 'AdvWriteByteLram()'.
15408 */
15409 AdvReadByteLram(iop_base, next_ready_loc + RQL_FWD, next_ready_loc_fwd)do { ((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((
next_ready_loc + 0))); (next_ready_loc_fwd) = (*(volatile unsigned
char *) ((iop_base) + 0x06)); } while (0)
;
15410 AdvWriteByteLram(iop_base, ASC_MC_HOST_NEXT_READY, next_ready_loc_fwd)(((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((0x0128
))), ((*(volatile unsigned char *) ((iop_base) + 0x06)) = ((next_ready_loc_fwd
))))
;
15411
15412 /*
15413 * Change the state of 'next_ready_loc' request from QS_FREE to
15414 * QS_READY which will cause the microcode to pick it up and
15415 * execute it.
15416 *
15417 * Can't reference 'next_ready_loc' after changing the request
15418 * state to QS_READY. The microcode now owns the request.
15419 */
15420 AdvWriteByteLram(iop_base, next_ready_loc + RQL_STATE, ASC_MC_QS_READY)(((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((next_ready_loc
+ 2))), ((*(volatile unsigned char *) ((iop_base) + 0x06)) =
((0x01))))
;
15421
15422 DvcLeaveCritical(last_int_level);
15423 return ADV_SUCCESS1;
15424}
15425
15426/*
15427 * Inquiry Information Byte 7 Handling
15428 *
15429 * Handle SCSI Inquiry Command information for a device by setting
15430 * microcode operating variables that affect WDTR, SDTR, and Tag
15431 * Queuing.
15432 */
15433STATICstatic void
15434AdvInquiryHandling(
15435 ADV_DVC_VAR *asc_dvc,
15436 ADV_SCSI_REQ_Q *scsiq)
15437{
15438 AdvPortAddrunsigned long iop_base;
15439 uchar tid;
15440 ASC_SCSI_INQUIRY *inq;
15441 ushort tidmask;
15442 ushort cfg_word;
15443
15444 /*
15445 * AdvInquiryHandling() requires up to INQUIRY information Byte 7
15446 * to be available.
15447 *
15448 * If less than 8 bytes of INQUIRY information were requested or less
15449 * than 8 bytes were transferred, then return. cdb[4] is the request
15450 * length and the ADV_SCSI_REQ_Q 'data_cnt' field is set by the
15451 * microcode to the transfer residual count.
15452 */
15453 if (scsiq->cdb[4] < 8 || (scsiq->cdb[4] - scsiq->data_cnt) < 8)
15454 {
15455 return;
15456 }
15457
15458 iop_base = asc_dvc->iop_base;
15459 tid = scsiq->target_id;
15460 inq = (ASC_SCSI_INQUIRY *) scsiq->vdata_addr;
15461
15462 /*
15463 * WDTR, SDTR, and Tag Queuing cannot be enabled for old devices.
15464 */
15465 if (inq->byte3.rsp_data_fmt < 2 && inq->byte2.ansi_apr_ver < 2)
15466 {
15467 return;
15468 } else
15469 {
15470 /*
15471 * INQUIRY Byte 7 Handling
15472 *
15473 * Use a device's INQUIRY byte 7 to determine whether it
15474 * supports WDTR, SDTR, and Tag Queuing. If the feature
15475 * is enabled in the EEPROM and the device supports the
15476 * feature, then enable it in the microcode.
15477 */
15478
15479 tidmask = ADV_TID_TO_TIDMASK(tid)(0x01 << ((tid) & 15));
15480
15481 /*
15482 * Wide Transfers
15483 *
15484 * If the EEPROM enabled WDTR for the device and the device
15485 * supports wide bus (16 bit) transfers, then turn on the
15486 * device's 'wdtr_able' bit and write the new value to the
15487 * microcode.
15488 */
15489 if ((asc_dvc->wdtr_able & tidmask) && inq->byte7.WBus16)
15490 {
15491 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word)do { ((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((
0x0120))); (cfg_word) = (*(volatile unsigned short *) ((iop_base
) + 0x06)); } while (0)
;
15492 if ((cfg_word & tidmask) == 0)
15493 {
15494 cfg_word |= tidmask;
15495 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word)(((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((0x0120
))), ((*(volatile unsigned short *) ((iop_base) + 0x06)) = ((
cfg_word))))
;
15496
15497 /*
15498 * Clear the microcode "WDTR negotiation" done indicator
15499 * for the target to cause it to negotiate with the new
15500 * setting set above.
15501 */
15502 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word)do { ((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((
0x0124))); (cfg_word) = (*(volatile unsigned short *) ((iop_base
) + 0x06)); } while (0)
;
15503 cfg_word &= ~tidmask;
15504 AdvWriteWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word)(((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((0x0124
))), ((*(volatile unsigned short *) ((iop_base) + 0x06)) = ((
cfg_word))))
;
15505 }
15506 }
15507
15508 /*
15509 * Synchronous Transfers
15510 *
15511 * If the EEPROM enabled SDTR for the device and the device
15512 * supports synchronous transfers, then turn on the device's
15513 * 'sdtr_able' bit. Write the new value to the microcode.
15514 */
15515 if ((asc_dvc->sdtr_able & tidmask) && inq->byte7.Sync)
15516 {
15517 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word)do { ((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((
0x009E))); (cfg_word) = (*(volatile unsigned short *) ((iop_base
) + 0x06)); } while (0)
;
15518 if ((cfg_word & tidmask) == 0)
15519 {
15520 cfg_word |= tidmask;
15521 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word)(((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((0x009E
))), ((*(volatile unsigned short *) ((iop_base) + 0x06)) = ((
cfg_word))))
;
15522
15523 /*
15524 * Clear the microcode "SDTR negotiation" done indicator
15525 * for the target to cause it to negotiate with the new
15526 * setting set above.
15527 */
15528 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word)do { ((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((
0x00B6))); (cfg_word) = (*(volatile unsigned short *) ((iop_base
) + 0x06)); } while (0)
;
15529 cfg_word &= ~tidmask;
15530 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word)(((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((0x00B6
))), ((*(volatile unsigned short *) ((iop_base) + 0x06)) = ((
cfg_word))))
;
15531 }
15532 }
15533
15534 /*
15535 * If the EEPROM enabled Tag Queuing for device and the
15536 * device supports Tag Queuing, then turn on the device's
15537 * 'tagqng_enable' bit in the microcode and set the microcode
15538 * maximum command count to the ADV_DVC_VAR 'max_dvc_qng'
15539 * value.
15540 *
15541 * Tag Queuing is disabled for the BIOS which runs in polled
15542 * mode and would see no benefit from Tag Queuing. Also by
15543 * disabling Tag Queuing in the BIOS devices with Tag Queuing
15544 * bugs will at least work with the BIOS.
15545 */
15546 if ((asc_dvc->tagqng_able & tidmask) && inq->byte7.CmdQue)
15547 {
15548 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word)do { ((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((
0x00A0))); (cfg_word) = (*(volatile unsigned short *) ((iop_base
) + 0x06)); } while (0)
;
15549 cfg_word |= tidmask;
15550 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word)(((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((0x00A0
))), ((*(volatile unsigned short *) ((iop_base) + 0x06)) = ((
cfg_word))))
;
15551 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,(((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((0x00D0
+ tid))), ((*(volatile unsigned char *) ((iop_base) + 0x06))
= ((asc_dvc->max_dvc_qng))))
15552 asc_dvc->max_dvc_qng)(((*(volatile unsigned short *) ((iop_base) + 0x04)) = ((0x00D0
+ tid))), ((*(volatile unsigned char *) ((iop_base) + 0x06))
= ((asc_dvc->max_dvc_qng))))
;
15553 }
15554 }
15555}