File: /usr/src/linux/drivers/scsi/advansys.c

1     #define ASC_VERSION "3.3G"    /* AdvanSys Driver Version */
2     
3     /*
4      * advansys.c - Linux Host Driver for AdvanSys SCSI Adapters
5      *
6      * Copyright (c) 1995-2000 Advanced System Products, Inc.
7      * Copyright (c) 2000-2001 ConnectCom Solutions, Inc.
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      * As of March 8, 2000 Advanced System Products, Inc. (AdvanSys)
16      * changed its name to ConnectCom Solutions, Inc.
17      *
18      * There is an AdvanSys Linux WWW page at:
19      *  http://www.connectcom.net/downloads/software/os/linux.html
20      *  http://www.advansys.com/linux.html
21      *
22      * The latest released version of the AdvanSys driver is available at:
23      *  ftp://ftp.advansys.com/pub/linux/linux.tgz
24      *  ftp://ftp.connectcom.net/pub/linux/linux.tgz
25      *
26      * Please send questions, comments, bug reports to:
27      *  support@connectcom.net
28      */
29     
30     /*
31     
32       Documentation for the AdvanSys Driver
33     
34       A. Linux Kernels Supported by this Driver
35       B. Adapters Supported by this Driver
36       C. Linux source files modified by AdvanSys Driver
37       D. Source Comments
38       E. Driver Compile Time Options and Debugging
39       F. Driver LILO Option
40       G. Tests to run before releasing new driver
41       H. Release History
42       I. Known Problems/Fix List
43       J. Credits (Chronological Order)
44       K. ConnectCom (AdvanSys) Contact Information
45     
46       A. Linux Kernels Supported by this Driver
47     
48          This driver has been tested in the following Linux kernels: v2.2.18
49          v2.4.0. The driver is supported on v2.2 and v2.4 kernels and on x86,
50          alpha, and PowerPC platforms.
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          Laptop Products:
68             ABP-480 - Bus-Master CardBus (16 CDB) (2.4 kernel and greater)
69     
70          Connectivity Products:
71             ABP510/5150 - Bus-Master ISA (240 CDB)
72             ABP5140 - Bus-Master ISA PnP (16 CDB)
73             ABP5142 - Bus-Master ISA PnP with floppy (16 CDB)
74             ABP902/3902 - Bus-Master PCI (16 CDB)
75             ABP3905 - Bus-Master PCI (16 CDB)
76             ABP915 - Bus-Master PCI (16 CDB)
77             ABP920 - Bus-Master PCI (16 CDB)
78             ABP3922 - Bus-Master PCI (16 CDB)
79             ABP3925 - Bus-Master PCI (16 CDB)
80             ABP930 - Bus-Master PCI (16 CDB)
81             ABP930U - Bus-Master PCI Ultra (16 CDB)
82             ABP930UA - Bus-Master PCI Ultra (16 CDB)
83             ABP960 - Bus-Master PCI MAC/PC (16 CDB)
84             ABP960U - Bus-Master PCI MAC/PC Ultra (16 CDB)
85     
86          Single Channel Products:
87             ABP542 - Bus-Master ISA with floppy (240 CDB)
88             ABP742 - Bus-Master EISA (240 CDB)
89             ABP842 - Bus-Master VL (240 CDB)
90             ABP940 - Bus-Master PCI (240 CDB)
91             ABP940U - Bus-Master PCI Ultra (240 CDB)
92             ABP940UA/3940UA - Bus-Master PCI Ultra (240 CDB)
93             ABP970 - Bus-Master PCI MAC/PC (240 CDB)
94             ABP970U - Bus-Master PCI MAC/PC Ultra (240 CDB)
95             ABP3960UA - Bus-Master PCI MAC/PC Ultra (240 CDB)
96             ABP940UW/3940UW - Bus-Master PCI Ultra-Wide (253 CDB)
97             ABP970UW - Bus-Master PCI MAC/PC Ultra-Wide (253 CDB)
98             ABP3940U2W - Bus-Master PCI LVD/Ultra2-Wide (253 CDB)
99     
100          Multi-Channel Products:
101             ABP752 - Dual Channel Bus-Master EISA (240 CDB Per Channel)
102             ABP852 - Dual Channel Bus-Master VL (240 CDB Per Channel)
103             ABP950 - Dual Channel Bus-Master PCI (240 CDB Per Channel)
104             ABP950UW - Dual Channel Bus-Master PCI Ultra-Wide (253 CDB Per Channel)
105             ABP980 - Four Channel Bus-Master PCI (240 CDB Per Channel)
106             ABP980U - Four Channel Bus-Master PCI Ultra (240 CDB Per Channel)
107             ABP980UA/3980UA - Four Channel Bus-Master PCI Ultra (16 CDB Per Chan.)
108             ABP3950U2W - Bus-Master PCI LVD/Ultra2-Wide and Ultra-Wide (253 CDB)
109             ABP3950U3W - Bus-Master PCI Dual LVD2/Ultra3-Wide (253 CDB)
110     
111       C. Linux source files modified by AdvanSys Driver
112     
113          This section for historical purposes documents the changes
114          originally made to the Linux kernel source to add the advansys
115          driver. As Linux has changed some of these files have also
116          been modified.
117     
118          1. linux/arch/i386/config.in:
119     
120               bool 'AdvanSys SCSI support' CONFIG_SCSI_ADVANSYS y
121     
122          2. linux/drivers/scsi/hosts.c:
123     
124               #ifdef CONFIG_SCSI_ADVANSYS
125               #include "advansys.h"
126               #endif
127     
128             and after "static Scsi_Host_Template builtin_scsi_hosts[] =":
129     
130               #ifdef CONFIG_SCSI_ADVANSYS
131               ADVANSYS,
132               #endif
133     
134          3. linux/drivers/scsi/Makefile:
135     
136               ifdef CONFIG_SCSI_ADVANSYS
137               SCSI_SRCS := $(SCSI_SRCS) advansys.c
138               SCSI_OBJS := $(SCSI_OBJS) advansys.o
139               else
140               SCSI_MODULE_OBJS := $(SCSI_MODULE_OBJS) advansys.o
141               endif
142     
143          4. linux/init/main.c:
144     
145               extern void advansys_setup(char *str, int *ints);
146     
147             and add the following lines to the bootsetups[] array.
148     
149               #ifdef CONFIG_SCSI_ADVANSYS
150                  { "advansys=", advansys_setup },
151               #endif
152     
153       D. Source Comments
154     
155          1. Use tab stops set to 4 for the source files. For vi use 'se tabstops=4'.
156     
157          2. This driver should be maintained in multiple files. But to make
158             it easier to include with Linux and to follow Linux conventions,
159             the whole driver is maintained in the source files advansys.h and
160             advansys.c. In this file logical sections of the driver begin with
161             a comment that contains '---'. The following are the logical sections
162             of the driver below.
163     
164                --- Linux Version
165                --- Linux Include File
166                --- Driver Options
167                --- Debugging Header
168                --- Asc Library Constants and Macros
169                --- Adv Library Constants and Macros
170                --- Driver Constants and Macros
171                --- Driver Structures
172                --- Driver Data
173                --- Driver Function Prototypes
174                --- Linux 'Scsi_Host_Template' and advansys_setup() Functions
175                --- Loadable Driver Support
176                --- Miscellaneous Driver Functions
177                --- Functions Required by the Asc Library
178                --- Functions Required by the Adv Library
179                --- Tracing and Debugging Functions
180                --- Asc Library Functions
181                --- Adv Library Functions
182     
183          3. The string 'XXX' is used to flag code that needs to be re-written
184             or that contains a problem that needs to be addressed.
185     
186          4. I have stripped comments from and reformatted the source for the
187             Asc Library and Adv Library to reduce the size of this file. This
188             source can be found under the following headings. The Asc Library
189             is used to support Narrow Boards. The Adv Library is used to
190             support Wide Boards.
191     
192                --- Asc Library Constants and Macros
193                --- Adv Library Constants and Macros
194                --- Asc Library Functions
195                --- Adv Library Functions
196     
197       E. Driver Compile Time Options and Debugging
198     
199          In this source file the following constants can be defined. They are
200          defined in the source below. Both of these options are enabled by
201          default.
202     
203          1. ADVANSYS_ASSERT - Enable driver assertions (Def: Enabled)
204     
205             Enabling this option adds assertion logic statements to the
206             driver. If an assertion fails a message will be displayed to
207             the console, but the system will continue to operate. Any
208             assertions encountered should be reported to the person
209             responsible for the driver. Assertion statements may proactively
210             detect problems with the driver and facilitate fixing these
211             problems. Enabling assertions will add a small overhead to the
212             execution of the driver.
213     
214          2. ADVANSYS_DEBUG - Enable driver debugging (Def: Disabled)
215     
216             Enabling this option adds tracing functions to the driver and
217             the ability to set a driver tracing level at boot time. This
218             option will also export symbols not required outside the driver to
219             the kernel name space. This option is very useful for debugging
220             the driver, but it will add to the size of the driver execution
221             image and add overhead to the execution of the driver.
222     
223             The amount of debugging output can be controlled with the global
224             variable 'asc_dbglvl'. The higher the number the more output. By
225             default the debug level is 0.
226     
227             If the driver is loaded at boot time and the LILO Driver Option
228             is included in the system, the debug level can be changed by
229             specifying a 5th (ASC_NUM_IOPORT_PROBE + 1) I/O Port. The
230             first three hex digits of the pseudo I/O Port must be set to
231             'deb' and the fourth hex digit specifies the debug level: 0 - F.
232             The following command line will look for an adapter at 0x330
233             and set the debug level to 2.
234     
235                linux advansys=0x330,0,0,0,0xdeb2
236     
237             If the driver is built as a loadable module this variable can be
238             defined when the driver is loaded. The following insmod command
239             will set the debug level to one.
240     
241                insmod advansys.o asc_dbglvl=1
242     
243             Debugging Message Levels:
244                0: Errors Only
245                1: High-Level Tracing
246                2-N: Verbose Tracing
247     
248             To enable debug output to console, please make sure that:
249     
250             a. System and kernel logging is enabled (syslogd, klogd running).
251             b. Kernel messages are routed to console output. Check
252                /etc/syslog.conf for an entry similar to this:
253     
254                     kern.*                  /dev/console
255     
256             c. klogd is started with the appropriate -c parameter
257                (e.g. klogd -c 8)
258     
259             This will cause printk() messages to be be displayed on the
260             current console. Refer to the klogd(8) and syslogd(8) man pages
261             for details.
262     
263             Alternatively you can enable printk() to console with this
264             program. However, this is not the 'official' way to do this.
265             Debug output is logged in /var/log/messages.
266     
267               main()
268               {
269                       syscall(103, 7, 0, 0);
270               }
271     
272             Increasing LOG_BUF_LEN in kernel/printk.c to something like
273             40960 allows more debug messages to be buffered in the kernel
274             and written to the console or log file.
275     
276          3. ADVANSYS_STATS - Enable statistics (Def: Enabled >= v1.3.0)
277     
278             Enabling this option adds statistics collection and display
279             through /proc to the driver. The information is useful for
280             monitoring driver and device performance. It will add to the
281             size of the driver execution image and add minor overhead to
282             the execution of the driver.
283     
284             Statistics are maintained on a per adapter basis. Driver entry
285             point call counts and transfer size counts are maintained.
286             Statistics are only available for kernels greater than or equal
287             to v1.3.0 with the CONFIG_PROC_FS (/proc) file system configured.
288     
289             AdvanSys SCSI adapter files have the following path name format:
290     
291                /proc/scsi/advansys/[0-(ASC_NUM_BOARD_SUPPORTED-1)]
292     
293             This information can be displayed with cat. For example:
294     
295                cat /proc/scsi/advansys/0
296     
297             When ADVANSYS_STATS is not defined the AdvanSys /proc files only
298             contain adapter and device configuration information.
299     
300       F. Driver LILO Option
301     
302          If init/main.c is modified as described in the 'Directions for Adding
303          the AdvanSys Driver to Linux' section (B.4.) above, the driver will
304          recognize the 'advansys' LILO command line and /etc/lilo.conf option.
305          This option can be used to either disable I/O port scanning or to limit
306          scanning to 1 - 4 I/O ports. Regardless of the option setting EISA and
307          PCI boards will still be searched for and detected. This option only
308          affects searching for ISA and VL boards.
309     
310          Examples:
311            1. Eliminate I/O port scanning:
312                 boot: linux advansys=
313                   or
314                 boot: linux advansys=0x0
315            2. Limit I/O port scanning to one I/O port:
316                 boot: linux advansys=0x110
317            3. Limit I/O port scanning to four I/O ports:
318                 boot: linux advansys=0x110,0x210,0x230,0x330
319     
320          For a loadable module the same effect can be achieved by setting
321          the 'asc_iopflag' variable and 'asc_ioport' array when loading
322          the driver, e.g.
323     
324                insmod advansys.o asc_iopflag=1 asc_ioport=0x110,0x330
325     
326          If ADVANSYS_DEBUG is defined a 5th (ASC_NUM_IOPORT_PROBE + 1)
327          I/O Port may be added to specify the driver debug level. Refer to
328          the 'Driver Compile Time Options and Debugging' section above for
329          more information.
330     
331       G. Tests to run before releasing new driver
332     
333          1. In the supported kernels verify there are no warning or compile
334             errors when the kernel is built as both a driver and as a module
335             and with the following options:
336     
337             ADVANSYS_DEBUG - enabled and disabled
338             CONFIG_SMP - enabled and disabled
339             CONFIG_PROC_FS - enabled and disabled
340     
341          2. Run tests on an x86, alpha, and PowerPC with at least one narrow
342             card and one wide card attached to a hard disk and CD-ROM drive:
343             fdisk, mkfs, fsck, bonnie, copy/compare test from the
344             CD-ROM to the hard drive.
345     
346       H. Release History
347     
348          BETA-1.0 (12/23/95):
349              First Release
350     
351          BETA-1.1 (12/28/95):
352              1. Prevent advansys_detect() from being called twice.
353              2. Add LILO 0xdeb[0-f] option to set 'asc_dbglvl'.
354     
355          1.2 (1/12/96):
356              1. Prevent re-entrancy in the interrupt handler which
357                 resulted in the driver hanging Linux.
358              2. Fix problem that prevented ABP-940 cards from being
359                 recognized on some PCI motherboards.
360              3. Add support for the ABP-5140 PnP ISA card.
361              4. Fix check condition return status.
362              5. Add conditionally compiled code for Linux v1.3.X.
363     
364          1.3 (2/23/96):
365              1. Fix problem in advansys_biosparam() that resulted in the
366                 wrong drive geometry being returned for drives > 1GB with
367                 extended translation enabled.
368              2. Add additional tracing during device initialization.
369              3. Change code that only applies to ISA PnP adapter.
370              4. Eliminate 'make dep' warning.
371              5. Try to fix problem with handling resets by increasing their
372                 timeout value.
373     
374          1.4 (5/8/96):
375              1. Change definitions to eliminate conflicts with other subsystems.
376              2. Add versioning code for the shared interrupt changes.
377              3. Eliminate problem in asc_rmqueue() with iterating after removing
378                 a request.
379              4. Remove reset request loop problem from the "Known Problems or
380                 Issues" section. This problem was isolated and fixed in the
381                 mid-level SCSI driver.
382     
383          1.5 (8/8/96):
384              1. Add support for ABP-940U (PCI Ultra) adapter.
385              2. Add support for IRQ sharing by setting the SA_SHIRQ flag for
386                 request_irq and supplying a dev_id pointer to both request_irq()
387                 and free_irq().
388              3. In AscSearchIOPortAddr11() restore a call to check_region() which
389                 should be used before I/O port probing.
390              4. Fix bug in asc_prt_hex() which resulted in the displaying
391                 the wrong data.
392              5. Incorporate miscellaneous Asc Library bug fixes and new microcode.
393              6. Change driver versioning to be specific to each Linux sub-level.
394              7. Change statistics gathering to be per adapter instead of global
395                 to the driver.
396              8. Add more information and statistics to the adapter /proc file:
397                 /proc/scsi/advansys[0...].
398              9. Remove 'cmd_per_lun' from the "Known Problems or Issues" list.
399                 This problem has been addressed with the SCSI mid-level changes
400                 made in v1.3.89. The advansys_select_queue_depths() function
401                 was added for the v1.3.89 changes.
402     
403          1.6 (9/10/96):
404              1. Incorporate miscellaneous Asc Library bug fixes and new microcode.
405     
406          1.7 (9/25/96):
407              1. Enable clustering and optimize the setting of the maximum number
408                 of scatter gather elements for any particular board. Clustering
409                 increases CPU utilization, but results in a relatively larger
410                 increase in I/O throughput.
411              2. Improve the performance of the request queuing functions by
412                 adding a last pointer to the queue structure.
413              3. Correct problems with reset and abort request handling that
414                 could have hung or crashed Linux.
415              4. Add more information to the adapter /proc file:
416                 /proc/scsi/advansys[0...].
417              5. Remove the request timeout issue form the driver issues list.
418              6. Miscellaneous documentation additions and changes.
419     
420          1.8 (10/4/96):
421              1. Make changes to handle the new v2.1.0 kernel memory mapping
422                 in which a kernel virtual address may not be equivalent to its
423                 bus or DMA memory address.
424              2. Change abort and reset request handling to make it yet even
425                 more robust.
426              3. Try to mitigate request starvation by sending ordered requests
427                 to heavily loaded, tag queuing enabled devices.
428              4. Maintain statistics on request response time.
429              5. Add request response time statistics and other information to
430                 the adapter /proc file: /proc/scsi/advansys[0...].
431     
432          1.9 (10/21/96):
433              1. Add conditionally compiled code (ASC_QUEUE_FLOW_CONTROL) to
434                 make use of mid-level SCSI driver device queue depth flow
435                 control mechanism. This will eliminate aborts caused by a
436                 device being unable to keep up with requests and eliminate
437                 repeat busy or QUEUE FULL status returned by a device.
438              2. Incorporate miscellaneous Asc Library bug fixes.
439              3. To allow the driver to work in kernels with broken module
440                 support set 'cmd_per_lun' if the driver is compiled as a
441                 module. This change affects kernels v1.3.89 to present.
442              4. Remove PCI BIOS address from the driver banner. The PCI BIOS
443                 is relocated by the motherboard BIOS and its new address can
444                 not be determined by the driver.
445              5. Add mid-level SCSI queue depth information to the adapter
446                 /proc file: /proc/scsi/advansys[0...].
447     
448          2.0 (11/14/96):
449              1. Change allocation of global structures used for device
450                 initialization to guarantee they are in DMA-able memory.
451                 Previously when the driver was loaded as a module these
452                 structures might not have been in DMA-able memory, causing
453                 device initialization to fail.
454     
455          2.1 (12/30/96):
456              1. In advansys_reset(), if the request is a synchronous reset
457                 request, even if the request serial number has changed, then
458                 complete the request.
459              2. Add Asc Library bug fixes including new microcode.
460              3. Clear inquiry buffer before using it.
461              4. Correct ifdef typo.
462     
463          2.2 (1/15/97):
464              1. Add Asc Library bug fixes including new microcode.
465              2. Add synchronous data transfer rate information to the
466                 adapter /proc file: /proc/scsi/advansys[0...].
467              3. Change ADVANSYS_DEBUG to be disabled by default. This
468                 will reduce the size of the driver image, eliminate execution
469                 overhead, and remove unneeded symbols from the kernel symbol
470                 space that were previously added by the driver.
471              4. Add new compile-time option ADVANSYS_ASSERT for assertion
472                 code that used to be defined within ADVANSYS_DEBUG. This
473                 option is enabled by default.
474     
475          2.8 (5/26/97):
476              1. Change version number to 2.8 to synchronize the Linux driver
477                 version numbering with other AdvanSys drivers.
478              2. Reformat source files without tabs to present the same view
479                 of the file to everyone regardless of the editor tab setting
480                 being used.
481              3. Add Asc Library bug fixes.
482     
483          3.1A (1/8/98):
484              1. Change version number to 3.1 to indicate that support for
485                 Ultra-Wide adapters (ABP-940UW) is included in this release.
486              2. Add Asc Library (Narrow Board) bug fixes.
487              3. Report an underrun condition with the host status byte set
488                 to DID_UNDERRUN. Currently DID_UNDERRUN is defined to 0 which
489                 causes the underrun condition to be ignored. When Linux defines
490                 its own DID_UNDERRUN the constant defined in this file can be
491                 removed.
492              4. Add patch to AscWaitTixISRDone().
493              5. Add support for up to 16 different AdvanSys host adapter SCSI
494                 channels in one system. This allows four cards with four channels
495                 to be used in one system.
496     
497          3.1B (1/9/98):
498              1. Handle that PCI register base addresses are not always page
499                 aligned even though ioremap() requires that the address argument
500                 be page aligned.
501     
502          3.1C (1/10/98):
503              1. Update latest BIOS version checked for from the /proc file.
504              2. Don't set microcode SDTR variable at initialization. Instead
505                 wait until device capabilities have been detected from an Inquiry
506                 command.
507     
508          3.1D (1/21/98):
509              1. Improve performance when the driver is compiled as module by
510                 allowing up to 64 scatter-gather elements instead of 8.
511     
512          3.1E (5/1/98):
513              1. Set time delay in AscWaitTixISRDone() to 1000 ms.
514              2. Include SMP locking changes.
515              3. For v2.1.93 and newer kernels use CONFIG_PCI and new PCI BIOS
516                 access functions.
517              4. Update board serial number printing.
518              5. Try allocating an IRQ both with and without the SA_INTERRUPT
519                 flag set to allow IRQ sharing with drivers that do not set
520                 the SA_INTERRUPT flag. Also display a more descriptive error
521                 message if request_irq() fails.
522              6. Update to latest Asc and Adv Libraries.
523     
524          3.2A (7/22/99):
525              1. Update Adv Library to 4.16 which includes support for
526                 the ASC38C0800 (Ultra2/LVD) IC.
527     
528          3.2B (8/23/99):
529              1. Correct PCI compile time option for v2.1.93 and greater
530                 kernels, advansys_info() string, and debug compile time
531                 option.
532              2. Correct DvcSleepMilliSecond() for v2.1.0 and greater
533                 kernels. This caused an LVD detection/BIST problem problem
534                 among other things.
535              3. Sort PCI cards by PCI Bus, Slot, Function ascending order
536                 to be consistent with the BIOS.
537              4. Update to Asc Library S121 and Adv Library 5.2.
538     
539          3.2C (8/24/99):
540              1. Correct PCI card detection bug introduced in 3.2B that
541                 prevented PCI cards from being detected in kernels older
542                 than v2.1.93.
543     
544          3.2D (8/26/99):
545              1. Correct /proc device synchronous speed information display.
546                 Also when re-negotiation is pending for a target device
547                 note this condition with an * and footnote.
548              2. Correct initialization problem with Ultra-Wide cards that
549                 have a pre-3.2 BIOS. A microcode variable changed locations
550                 in 3.2 and greater BIOSes which caused WDTR to be attempted
551                 erroneously with drives that don't support WDTR.
552     
553          3.2E (8/30/99):
554              1. Fix compile error caused by v2.3.13 PCI structure change.
555              2. Remove field from ASCEEP_CONFIG that resulted in an EEPROM
556                 checksum error for ISA cards.
557              3. Remove ASC_QUEUE_FLOW_CONTROL conditional code. The mid-level
558                 SCSI changes that it depended on were never included in Linux.
559     
560          3.2F (9/3/99):
561              1. Handle new initial function code added in v2.3.16 for all
562                 driver versions.
563     
564          3.2G (9/8/99):
565              1. Fix PCI board detection in v2.3.13 and greater kernels.
566              2. Fix comiple errors in v2.3.X with debugging enabled.
567     
568          3.2H (9/13/99):
569              1. Add 64-bit address, long support for Alpha and UltraSPARC.
570                 The driver has been verified to work on an Alpha system.
571              2. Add partial byte order handling support for Power PC and
572                 other big-endian platforms. This support has not yet been
573                 completed or verified.
574              3. For wide boards replace block zeroing of request and
575                 scatter-gather structures with individual field initialization
576                 to improve performance.
577              4. Correct and clarify ROM BIOS version detection.
578     
579          3.2I (10/8/99):
580              1. Update to Adv Library 5.4.
581              2. Add v2.3.19 underrun reporting to asc_isr_callback() and
582                 adv_isr_callback().  Remove DID_UNDERRUN constant and other
583                 no longer needed code that previously documented the lack
584                 of underrun handling.
585     
586          3.2J (10/14/99):
587              1. Eliminate compile errors for v2.0 and earlier kernels.
588     
589          3.2K (11/15/99):
590              1. Correct debug compile error in asc_prt_adv_scsi_req_q().
591              2. Update Adv Library to 5.5.
592              3. Add ifdef handling for /proc changes added in v2.3.28.
593              4. Increase Wide board scatter-gather list maximum length to
594                 255 when the driver is compiled into the kernel.
595     
596          3.2L (11/18/99):
597              1. Fix bug in adv_get_sglist() that caused an assertion failure
598                 at line 7475. The reqp->sgblkp pointer must be initialized
599                 to NULL in adv_get_sglist().
600     
601          3.2M (11/29/99):
602              1. Really fix bug in adv_get_sglist().
603              2. Incorporate v2.3.29 changes into driver.
604     
605          3.2N (4/1/00):
606              1. Add CONFIG_ISA ifdef code.
607              2. Include advansys_interrupts_enabled name change patch.
608              3. For >= v2.3.28 use new SCSI error handling with new function
609                 advansys_eh_bus_reset(). Don't include an abort function
610                 because of base library limitations.
611              4. For >= v2.3.28 use per board lock instead of io_request_lock.
612              5. For >= v2.3.28 eliminate advansys_command() and
613                 advansys_command_done().
614              6. Add some changes for PowerPC (Big Endian) support, but it isn't
615                 working yet.
616              7. Fix "nonexistent resource free" problem that occurred on a module
617                 unload for boards with an I/O space >= 255. The 'n_io_port' field
618                 is only one byte and can not be used to hold an ioport length more
619                 than 255.
620     
621          3.3A (4/4/00):
622              1. Update to Adv Library 5.8.
623              2. For wide cards add support for CDBs up to 16 bytes.
624              3. Eliminate warnings when CONFIG_PROC_FS is not defined.
625     
626          3.3B (5/1/00):
627              1. Support for PowerPC (Big Endian) wide cards. Narrow cards
628                 still need work.
629              2. Change bitfields to shift and mask access for endian
630                 portability.
631     
632          3.3C (10/13/00):
633              1. Update for latest 2.4 kernel.
634              2. Test ABP-480 CardBus support in 2.4 kernel - works!
635              3. Update to Asc Library S123.
636              4. Update to Adv Library 5.12.
637     
638          3.3D (11/22/00):
639              1. Update for latest 2.4 kernel.
640              2. Create patches for 2.2 and 2.4 kernels.
641     
642          3.3E (1/9/01):
643              1. Now that 2.4 is released remove ifdef code for kernel versions
644                 less than 2.2. The driver is now only supported in kernels 2.2,
645                 2.4, and greater.
646              2. Add code to release and acquire the io_request_lock in
647                 the driver entrypoint functions: advansys_detect and
648                 advansys_queuecommand. In kernel 2.4 the SCSI mid-level driver
649                 still holds the io_request_lock on entry to SCSI low-level drivers.
650                 This was supposed to be removed before 2.4 was released but never
651                 happened. When the mid-level SCSI driver is changed all references
652                 to the io_request_lock should be removed from the driver.
653              3. Simplify error handling by removing advansys_abort(),
654                 AscAbortSRB(), AscResetDevice(). SCSI bus reset requests are
655                 now handled by resetting the SCSI bus and fully re-initializing
656                 the chip. This simple method of error recovery has proven to work
657                 most reliably after attempts at different methods. Also now only
658                 support the "new" error handling method and remove the obsolete
659                 error handling interface.
660              4. Fix debug build errors.
661     
662          3.3F (1/24/01):
663              1. Merge with ConnectCom version from Andy Kellner which
664                 updates Adv Library to 5.14.
665              2. Make PowerPC (Big Endian) work for narrow cards and
666                 fix problems writing EEPROM for wide cards.
667              3. Remove interrupts_enabled assertion function.
668     
669          3.3G (2/16/01):
670              1. Return an error from narrow boards if passed a 16 byte
671                 CDB. The wide board can already handle 16 byte CDBs.
672     
673       I. Known Problems/Fix List (XXX)
674     
675          1. Need to add memory mapping workaround. Test the memory mapping.
676             If it doesn't work revert to I/O port access. Can a test be done
677             safely?
678          2. Handle an interrupt not working. Keep an interrupt counter in
679             the interrupt handler. In the timeout function if the interrupt
680             has not occurred then print a message and run in polled mode.
681          3. Allow bus type scanning order to be changed.
682          4. Need to add support for target mode commands, cf. CAM XPT.
683     
684       J. Credits (Chronological Order)
685     
686          Bob Frey <bfrey@turbolinux.com.cn> wrote the AdvanSys SCSI driver
687          and maintained it up to 3.3F. He continues to answer questions
688          and help maintain the driver.
689     
690          Nathan Hartwell <mage@cdc3.cdc.net> provided the directions and
691          basis for the Linux v1.3.X changes which were included in the
692          1.2 release.
693     
694          Thomas E Zerucha <zerucha@shell.portal.com> pointed out a bug
695          in advansys_biosparam() which was fixed in the 1.3 release.
696     
697          Erik Ratcliffe <erik@caldera.com> has done testing of the
698          AdvanSys driver in the Caldera releases.
699     
700          Rik van Riel <H.H.vanRiel@fys.ruu.nl> provided a patch to
701          AscWaitTixISRDone() which he found necessary to make the
702          driver work with a SCSI-1 disk.
703     
704          Mark Moran <mmoran@mmoran.com> has helped test Ultra-Wide
705          support in the 3.1A driver.
706     
707          Doug Gilbert <dgilbert@interlog.com> has made changes and
708          suggestions to improve the driver and done a lot of testing.
709     
710          Ken Mort <ken@mort.net> reported a DEBUG compile bug fixed
711          in 3.2K.
712     
713          Tom Rini <trini@kernel.crashing.org> provided the CONFIG_ISA
714          patch and helped with PowerPC wide and narrow board support.
715     
716          Philip Blundell <philip.blundell@pobox.com> provided an
717          advansys_interrupts_enabled patch.
718     
719          Dave Jones <dave@denial.force9.co.uk> reported the compiler
720          warnings generated when CONFIG_PROC_FS was not defined in
721          the 3.2M driver.
722     
723          Jerry Quinn <jlquinn@us.ibm.com> fixed PowerPC support (endian
724          problems) for wide cards.
725     
726          Bryan Henderson <bryanh@giraffe-data.com> helped debug narrow
727          card error handling.
728     
729          Manuel Veloso <veloso@pobox.com> worked hard on PowerPC narrow
730          board support and fixed a bug in AscGetEEPConfig().
731     
732          Arnaldo Carvalho de Melo <acme@conectiva.com.br> made
733          save_flags/restore_flags changes.
734     
735          Andy Kellner <AKellner@connectcom.net> continues the Advansys SCSI
736          driver development for ConnectCom (Version > 3.3F).
737     
738       K. ConnectCom (AdvanSys) Contact Information
739     
740          Mail:                   ConnectCom Solutions, Inc.
741                                  1150 Ringwood Court
742                                  San Jose, CA 95131
743          Operator/Sales:         1-408-383-9400
744          FAX:                    1-408-383-9612
745          Tech Support:           1-408-467-2930
746          Tech Support E-Mail:    linux@connectcom.net
747          FTP Site:               ftp.connectcom.net (login: anonymous)
748          Web Site:               http://www.connectcom.net
749     
750     */
751     
752     
753     /*
754      * --- Linux Version
755      */
756     
757     #ifndef LINUX_VERSION_CODE
758     #include <linux/version.h>
759     #endif /* LINUX_VERSION_CODE */
760     
761     /* Convert Linux Version, Patch-level, Sub-level to LINUX_VERSION_CODE. */
762     #define ASC_LINUX_VERSION(V, P, S)    (((V) * 65536) + ((P) * 256) + (S))
763     #define ASC_LINUX_KERNEL22 (LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,4,0))
764     #define ASC_LINUX_KERNEL24 (LINUX_VERSION_CODE >= ASC_LINUX_VERSION(2,4,0))
765     
766     /* Driver supported only in version 2.2 and version >= 2.4. */
767     #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,2,0) || \
768         (LINUX_VERSION_CODE > ASC_LINUX_VERSION(2,3,0) && \
769          LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,4,0))
770     #error "AdvanSys driver supported only in 2.2 and 2.4 or greater kernels."
771     #endif
772     
773     /*
774      * --- Linux Include Files
775      */
776     
777     #include <linux/config.h>
778     #ifdef MODULE
779     #include <linux/module.h>
780     #endif /* MODULE */
781     
782     #if defined(CONFIG_X86) && !defined(CONFIG_ISA)
783     #define CONFIG_ISA
784     #endif /* CONFIG_X86 && !CONFIG_ISA */
785     
786     #include <linux/string.h>
787     #include <linux/sched.h>
788     #include <linux/kernel.h>
789     #include <linux/types.h>
790     #include <linux/ioport.h>
791     #include <linux/delay.h>
792     #include <linux/slab.h>
793     #include <linux/mm.h>
794     #include <linux/proc_fs.h>
795     #include <linux/init.h>
796     #include <asm/io.h>
797     #include <asm/system.h>
798     #include <asm/dma.h>
799     #include <linux/blk.h>
800     #include <linux/stat.h>
801     #if ASC_LINUX_KERNEL24
802     #include <linux/spinlock.h>
803     #elif ASC_LINUX_KERNEL22
804     #include <asm/spinlock.h>
805     #endif
806     #include "scsi.h"
807     #include "hosts.h"
808     #include "sd.h"
809     #include "advansys.h"
810     #ifdef CONFIG_PCI
811     #include <linux/pci.h>
812     #endif /* CONFIG_PCI */
813     
814     
815     /*
816      * --- Driver Options
817      */
818     
819     /* Enable driver assertions. */
820     #define ADVANSYS_ASSERT
821     
822     /* Enable driver /proc statistics. */
823     #define ADVANSYS_STATS
824     
825     /* Enable driver tracing. */
826     /* #define ADVANSYS_DEBUG */
827     
828     
829     /*
830      * --- Debugging Header
831      */
832     
833     #ifdef ADVANSYS_DEBUG
834     #define STATIC
835     #else /* ADVANSYS_DEBUG */
836     #define STATIC static
837     #endif /* ADVANSYS_DEBUG */
838     
839     
840     /*
841      * --- Asc Library Constants and Macros
842      */
843     
844     #define ASC_LIB_VERSION_MAJOR  1
845     #define ASC_LIB_VERSION_MINOR  24
846     #define ASC_LIB_SERIAL_NUMBER  123
847     
848     /*
849      * Portable Data Types
850      *
851      * Any instance where a 32-bit long or pointer type is assumed
852      * for precision or HW defined structures, the following define
853      * types must be used. In Linux the char, short, and int types
854      * are all consistent at 8, 16, and 32 bits respectively. Pointers
855      * and long types are 64 bits on Alpha and UltraSPARC.
856      */
857     #define ASC_PADDR __u32         /* Physical/Bus address data type. */
858     #define ASC_VADDR __u32         /* Virtual address data type. */
859     #define ASC_DCNT  __u32         /* Unsigned Data count type. */
860     #define ASC_SDCNT __s32         /* Signed Data count type. */
861     
862     /*
863      * These macros are used to convert a virtual address to a
864      * 32-bit value. This currently can be used on Linux Alpha
865      * which uses 64-bit virtual address but a 32-bit bus address.
866      * This is likely to break in the future, but doing this now
867      * will give us time to change the HW and FW to handle 64-bit
868      * addresses.
869      */
870     #define ASC_VADDR_TO_U32   virt_to_bus
871     #define ASC_U32_TO_VADDR   bus_to_virt
872     
873     typedef unsigned char uchar;
874     
875     #ifndef NULL
876     #define NULL     (0)
877     #endif
878     #ifndef TRUE
879     #define TRUE     (1)
880     #endif
881     #ifndef FALSE
882     #define FALSE    (0)
883     #endif
884     
885     #define EOF      (-1)
886     #define ERR      (-1)
887     #define UW_ERR   (uint)(0xFFFF)
888     #define isodd_word(val)   ((((uint)val) & (uint)0x0001) != 0)
889     #define AscPCIConfigVendorIDRegister      0x0000
890     #define AscPCIConfigDeviceIDRegister      0x0002
891     #define AscPCIConfigCommandRegister       0x0004
892     #define AscPCIConfigStatusRegister        0x0006
893     #define AscPCIConfigRevisionIDRegister    0x0008
894     #define AscPCIConfigCacheSize             0x000C
895     #define AscPCIConfigLatencyTimer          0x000D
896     #define AscPCIIOBaseRegister              0x0010
897     #define AscPCICmdRegBits_IOMemBusMaster   0x0007
898     #define ASC_PCI_ID2BUS(id)    ((id) & 0xFF)
899     #define ASC_PCI_ID2DEV(id)    (((id) >> 11) & 0x1F)
900     #define ASC_PCI_ID2FUNC(id)   (((id) >> 8) & 0x7)
901     #define ASC_PCI_MKID(bus, dev, func) ((((dev) & 0x1F) << 11) | (((func) & 0x7) << 8) | ((bus) & 0xFF))
902     #define ASC_PCI_VENDORID                  0x10CD
903     #define ASC_PCI_DEVICEID_1200A            0x1100
904     #define ASC_PCI_DEVICEID_1200B            0x1200
905     #define ASC_PCI_DEVICEID_ULTRA            0x1300
906     #define ASC_PCI_REVISION_3150             0x02
907     #define ASC_PCI_REVISION_3050             0x03
908     
909     #define  ASC_DVCLIB_CALL_DONE     (1)
910     #define  ASC_DVCLIB_CALL_FAILED   (0)
911     #define  ASC_DVCLIB_CALL_ERROR    (-1)
912     
913     /*
914      * Enable CC_VERY_LONG_SG_LIST to support up to 64K element SG lists.
915      * The SRB structure will have to be changed and the ASC_SRB2SCSIQ()
916      * macro re-defined to be able to obtain a ASC_SCSI_Q pointer from the
917      * SRB structure.
918      */
919     #define CC_VERY_LONG_SG_LIST 0
920     #define ASC_SRB2SCSIQ(srb_ptr)  (srb_ptr)
921     
922     #define PortAddr                 unsigned short    /* port address size  */
923     #define inp(port)                inb(port)
924     #define outp(port, byte)         outb((byte), (port))
925     
926     #define inpw(port)               inw(port)
927     #define outpw(port, word)        outw((word), (port))
928     
929     #define ASC_MAX_SG_QUEUE    7
930     #define ASC_MAX_SG_LIST     255
931     
932     #define ASC_CS_TYPE  unsigned short
933     
934     #define ASC_IS_ISA          (0x0001)
935     #define ASC_IS_ISAPNP       (0x0081)
936     #define ASC_IS_EISA         (0x0002)
937     #define ASC_IS_PCI          (0x0004)
938     #define ASC_IS_PCI_ULTRA    (0x0104)
939     #define ASC_IS_PCMCIA       (0x0008)
940     #define ASC_IS_MCA          (0x0020)
941     #define ASC_IS_VL           (0x0040)
942     #define ASC_ISA_PNP_PORT_ADDR  (0x279)
943     #define ASC_ISA_PNP_PORT_WRITE (ASC_ISA_PNP_PORT_ADDR+0x800)
944     #define ASC_IS_WIDESCSI_16  (0x0100)
945     #define ASC_IS_WIDESCSI_32  (0x0200)
946     #define ASC_IS_BIG_ENDIAN   (0x8000)
947     #define ASC_CHIP_MIN_VER_VL      (0x01)
948     #define ASC_CHIP_MAX_VER_VL      (0x07)
949     #define ASC_CHIP_MIN_VER_PCI     (0x09)
950     #define ASC_CHIP_MAX_VER_PCI     (0x0F)
951     #define ASC_CHIP_VER_PCI_BIT     (0x08)
952     #define ASC_CHIP_MIN_VER_ISA     (0x11)
953     #define ASC_CHIP_MIN_VER_ISA_PNP (0x21)
954     #define ASC_CHIP_MAX_VER_ISA     (0x27)
955     #define ASC_CHIP_VER_ISA_BIT     (0x30)
956     #define ASC_CHIP_VER_ISAPNP_BIT  (0x20)
957     #define ASC_CHIP_VER_ASYN_BUG    (0x21)
958     #define ASC_CHIP_VER_PCI             0x08
959     #define ASC_CHIP_VER_PCI_ULTRA_3150  (ASC_CHIP_VER_PCI | 0x02)
960     #define ASC_CHIP_VER_PCI_ULTRA_3050  (ASC_CHIP_VER_PCI | 0x03)
961     #define ASC_CHIP_MIN_VER_EISA (0x41)
962     #define ASC_CHIP_MAX_VER_EISA (0x47)
963     #define ASC_CHIP_VER_EISA_BIT (0x40)
964     #define ASC_CHIP_LATEST_VER_EISA   ((ASC_CHIP_MIN_VER_EISA - 1) + 3)
965     #define ASC_MAX_LIB_SUPPORTED_ISA_CHIP_VER   0x21
966     #define ASC_MAX_LIB_SUPPORTED_PCI_CHIP_VER   0x0A
967     #define ASC_MAX_VL_DMA_ADDR     (0x07FFFFFFL)
968     #define ASC_MAX_VL_DMA_COUNT    (0x07FFFFFFL)
969     #define ASC_MAX_PCI_DMA_ADDR    (0xFFFFFFFFL)
970     #define ASC_MAX_PCI_DMA_COUNT   (0xFFFFFFFFL)
971     #define ASC_MAX_ISA_DMA_ADDR    (0x00FFFFFFL)
972     #define ASC_MAX_ISA_DMA_COUNT   (0x00FFFFFFL)
973     #define ASC_MAX_EISA_DMA_ADDR   (0x07FFFFFFL)
974     #define ASC_MAX_EISA_DMA_COUNT  (0x07FFFFFFL)
975     
976     #define ASC_SCSI_ID_BITS  3
977     #define ASC_SCSI_TIX_TYPE     uchar
978     #define ASC_ALL_DEVICE_BIT_SET  0xFF
979     #define ASC_SCSI_BIT_ID_TYPE  uchar
980     #define ASC_MAX_TID       7
981     #define ASC_MAX_LUN       7
982     #define ASC_SCSI_WIDTH_BIT_SET  0xFF
983     #define ASC_MAX_SENSE_LEN   32
984     #define ASC_MIN_SENSE_LEN   14
985     #define ASC_MAX_CDB_LEN     12
986     #define ASC_SCSI_RESET_HOLD_TIME_US  60
987     #define SCSICMD_TestUnitReady     0x00
988     #define SCSICMD_Rewind            0x01
989     #define SCSICMD_Rezero            0x01
990     #define SCSICMD_RequestSense      0x03
991     #define SCSICMD_Format            0x04
992     #define SCSICMD_FormatUnit        0x04
993     #define SCSICMD_Read6             0x08
994     #define SCSICMD_Write6            0x0A
995     #define SCSICMD_Seek6             0x0B
996     #define SCSICMD_Inquiry           0x12
997     #define SCSICMD_Verify6           0x13
998     #define SCSICMD_ModeSelect6       0x15
999     #define SCSICMD_ModeSense6        0x1A
1000     #define SCSICMD_StartStopUnit     0x1B
1001     #define SCSICMD_LoadUnloadTape    0x1B
1002     #define SCSICMD_ReadCapacity      0x25
1003     #define SCSICMD_Read10            0x28
1004     #define SCSICMD_Write10           0x2A
1005     #define SCSICMD_Seek10            0x2B
1006     #define SCSICMD_Erase10           0x2C
1007     #define SCSICMD_WriteAndVerify10  0x2E
1008     #define SCSICMD_Verify10          0x2F
1009     #define SCSICMD_WriteBuffer       0x3B
1010     #define SCSICMD_ReadBuffer        0x3C
1011     #define SCSICMD_ReadLong          0x3E
1012     #define SCSICMD_WriteLong         0x3F
1013     #define SCSICMD_ReadTOC           0x43
1014     #define SCSICMD_ReadHeader        0x44
1015     #define SCSICMD_ModeSelect10      0x55
1016     #define SCSICMD_ModeSense10       0x5A
1017     
1018     /* Inquiry Data Peripheral Device Types */
1019     #define SCSI_TYPE_DASD     0x00
1020     #define SCSI_TYPE_SASD     0x01
1021     #define SCSI_TYPE_PRN      0x02
1022     #define SCSI_TYPE_PROC     0x03
1023     #define SCSI_TYPE_WORM     0x04
1024     #define SCSI_TYPE_CDROM    0x05
1025     #define SCSI_TYPE_SCANNER  0x06
1026     #define SCSI_TYPE_OPTMEM   0x07
1027     #define SCSI_TYPE_MED_CHG  0x08
1028     #define SCSI_TYPE_COMM     0x09
1029     #define SCSI_TYPE_UNKNOWN  0x1F
1030     
1031     #define ADV_INQ_CLOCKING_ST_ONLY    0x0
1032     #define ADV_INQ_CLOCKING_DT_ONLY    0x1
1033     #define ADV_INQ_CLOCKING_ST_AND_DT  0x3
1034     
1035     /*
1036      * Inquiry SPC-2 SPI Byte 1 EVPD (Enable Vital Product Data)
1037      * and CmdDt (Command Support Data) field bit definitions.
1038      */
1039     #define ADV_INQ_RTN_VPD_AND_CMDDT           0x3
1040     #define ADV_INQ_RTN_CMDDT_FOR_OP_CODE       0x2
1041     #define ADV_INQ_RTN_VPD_FOR_PG_CODE         0x1
1042     #define ADV_INQ_RTN_STD_INQUIRY_DATA        0x0
1043     
1044     #define ASC_SCSIDIR_NOCHK    0x00
1045     #define ASC_SCSIDIR_T2H      0x08
1046     #define ASC_SCSIDIR_H2T      0x10
1047     #define ASC_SCSIDIR_NODATA   0x18
1048     #define SCSI_SENKEY_NO_SENSE      0x00
1049     #define SCSI_SENKEY_UNDEFINED     0x01
1050     #define SCSI_SENKEY_NOT_READY     0x02
1051     #define SCSI_SENKEY_MEDIUM_ERR    0x03
1052     #define SCSI_SENKEY_HW_ERR        0x04
1053     #define SCSI_SENKEY_ILLEGAL       0x05
1054     #define SCSI_SENKEY_ATTENTION     0x06
1055     #define SCSI_SENKEY_PROTECTED     0x07
1056     #define SCSI_SENKEY_BLANK         0x08
1057     #define SCSI_SENKEY_V_UNIQUE      0x09
1058     #define SCSI_SENKEY_CPY_ABORT     0x0A
1059     #define SCSI_SENKEY_ABORT         0x0B
1060     #define SCSI_SENKEY_EQUAL         0x0C
1061     #define SCSI_SENKEY_VOL_OVERFLOW  0x0D
1062     #define SCSI_SENKEY_MISCOMP       0x0E
1063     #define SCSI_SENKEY_RESERVED      0x0F
1064     #define SCSI_ASC_NOMEDIA          0x3A
1065     #define ASC_SRB_HOST(x)  ((uchar)((uchar)(x) >> 4))
1066     #define ASC_SRB_TID(x)   ((uchar)((uchar)(x) & (uchar)0x0F))
1067     #define ASC_SRB_LUN(x)   ((uchar)((uint)(x) >> 13))
1068     #define PUT_CDB1(x)   ((uchar)((uint)(x) >> 8))
1069     #define SS_GOOD              0x00
1070     #define SS_CHK_CONDITION     0x02
1071     #define SS_CONDITION_MET     0x04
1072     #define SS_TARGET_BUSY       0x08
1073     #define SS_INTERMID          0x10
1074     #define SS_INTERMID_COND_MET 0x14
1075     #define SS_RSERV_CONFLICT    0x18
1076     #define SS_CMD_TERMINATED    0x22
1077     #define SS_QUEUE_FULL        0x28
1078     #define MS_CMD_DONE    0x00
1079     #define MS_EXTEND      0x01
1080     #define MS_SDTR_LEN    0x03
1081     #define MS_SDTR_CODE   0x01
1082     #define MS_WDTR_LEN    0x02
1083     #define MS_WDTR_CODE   0x03
1084     #define MS_MDP_LEN    0x05
1085     #define MS_MDP_CODE   0x00
1086     #define M1_SAVE_DATA_PTR        0x02
1087     #define M1_RESTORE_PTRS         0x03
1088     #define M1_DISCONNECT           0x04
1089     #define M1_INIT_DETECTED_ERR    0x05
1090     #define M1_ABORT                0x06
1091     #define M1_MSG_REJECT           0x07
1092     #define M1_NO_OP                0x08
1093     #define M1_MSG_PARITY_ERR       0x09
1094     #define M1_LINK_CMD_DONE        0x0A
1095     #define M1_LINK_CMD_DONE_WFLAG  0x0B
1096     #define M1_BUS_DVC_RESET        0x0C
1097     #define M1_ABORT_TAG            0x0D
1098     #define M1_CLR_QUEUE            0x0E
1099     #define M1_INIT_RECOVERY        0x0F
1100     #define M1_RELEASE_RECOVERY     0x10
1101     #define M1_KILL_IO_PROC         0x11
1102     #define M2_QTAG_MSG_SIMPLE      0x20
1103     #define M2_QTAG_MSG_HEAD        0x21
1104     #define M2_QTAG_MSG_ORDERED     0x22
1105     #define M2_IGNORE_WIDE_RESIDUE  0x23
1106     
1107     /*
1108      * Inquiry data structure and bitfield macros
1109      *
1110      * Only quantities of more than 1 bit are shifted, since the others are
1111      * just tested for true or false. C bitfields aren't portable between big
1112      * and little-endian platforms so they are not used.
1113      */
1114     
1115     #define ASC_INQ_DVC_TYPE(inq)       ((inq)->periph & 0x1f)
1116     #define ASC_INQ_QUALIFIER(inq)      (((inq)->periph & 0xe0) >> 5)
1117     #define ASC_INQ_DVC_TYPE_MOD(inq)   ((inq)->devtype & 0x7f)
1118     #define ASC_INQ_REMOVABLE(inq)      ((inq)->devtype & 0x80)
1119     #define ASC_INQ_ANSI_VER(inq)       ((inq)->ver & 0x07)
1120     #define ASC_INQ_ECMA_VER(inq)       (((inq)->ver & 0x38) >> 3)
1121     #define ASC_INQ_ISO_VER(inq)        (((inq)->ver & 0xc0) >> 6)
1122     #define ASC_INQ_RESPONSE_FMT(inq)   ((inq)->byte3 & 0x0f)
1123     #define ASC_INQ_TERM_IO(inq)        ((inq)->byte3 & 0x40)
1124     #define ASC_INQ_ASYNC_NOTIF(inq)    ((inq)->byte3 & 0x80)
1125     #define ASC_INQ_SOFT_RESET(inq)     ((inq)->flags & 0x01)
1126     #define ASC_INQ_CMD_QUEUE(inq)      ((inq)->flags & 0x02)
1127     #define ASC_INQ_LINK_CMD(inq)       ((inq)->flags & 0x08)
1128     #define ASC_INQ_SYNC(inq)           ((inq)->flags & 0x10)
1129     #define ASC_INQ_WIDE16(inq)         ((inq)->flags & 0x20)
1130     #define ASC_INQ_WIDE32(inq)         ((inq)->flags & 0x40)
1131     #define ASC_INQ_REL_ADDR(inq)       ((inq)->flags & 0x80)
1132     #define ASC_INQ_INFO_UNIT(inq)      ((inq)->info & 0x01)
1133     #define ASC_INQ_QUICK_ARB(inq)      ((inq)->info & 0x02)
1134     #define ASC_INQ_CLOCKING(inq)       (((inq)->info & 0x0c) >> 2)
1135     
1136     typedef struct {
1137         uchar               periph;
1138         uchar               devtype;
1139         uchar               ver;
1140         uchar               byte3;
1141         uchar               add_len;
1142         uchar               res1;
1143         uchar               res2;
1144         uchar               flags;
1145         uchar               vendor_id[8];
1146         uchar               product_id[16];
1147         uchar               product_rev_level[4];
1148     } ASC_SCSI_INQUIRY;
1149     
1150     #define ASC_SG_LIST_PER_Q   7
1151     #define QS_FREE        0x00
1152     #define QS_READY       0x01
1153     #define QS_DISC1       0x02
1154     #define QS_DISC2       0x04
1155     #define QS_BUSY        0x08
1156     #define QS_ABORTED     0x40
1157     #define QS_DONE        0x80
1158     #define QC_NO_CALLBACK   0x01
1159     #define QC_SG_SWAP_QUEUE 0x02
1160     #define QC_SG_HEAD       0x04
1161     #define QC_DATA_IN       0x08
1162     #define QC_DATA_OUT      0x10
1163     #define QC_URGENT        0x20
1164     #define QC_MSG_OUT       0x40
1165     #define QC_REQ_SENSE     0x80
1166     #define QCSG_SG_XFER_LIST  0x02
1167     #define QCSG_SG_XFER_MORE  0x04
1168     #define QCSG_SG_XFER_END   0x08
1169     #define QD_IN_PROGRESS       0x00
1170     #define QD_NO_ERROR          0x01
1171     #define QD_ABORTED_BY_HOST   0x02
1172     #define QD_WITH_ERROR        0x04
1173     #define QD_INVALID_REQUEST   0x80
1174     #define QD_INVALID_HOST_NUM  0x81
1175     #define QD_INVALID_DEVICE    0x82
1176     #define QD_ERR_INTERNAL      0xFF
1177     #define QHSTA_NO_ERROR               0x00
1178     #define QHSTA_M_SEL_TIMEOUT          0x11
1179     #define QHSTA_M_DATA_OVER_RUN        0x12
1180     #define QHSTA_M_DATA_UNDER_RUN       0x12
1181     #define QHSTA_M_UNEXPECTED_BUS_FREE  0x13
1182     #define QHSTA_M_BAD_BUS_PHASE_SEQ    0x14
1183     #define QHSTA_D_QDONE_SG_LIST_CORRUPTED 0x21
1184     #define QHSTA_D_ASC_DVC_ERROR_CODE_SET  0x22
1185     #define QHSTA_D_HOST_ABORT_FAILED       0x23
1186     #define QHSTA_D_EXE_SCSI_Q_FAILED       0x24
1187     #define QHSTA_D_EXE_SCSI_Q_BUSY_TIMEOUT 0x25
1188     #define QHSTA_D_ASPI_NO_BUF_POOL        0x26
1189     #define QHSTA_M_WTM_TIMEOUT         0x41
1190     #define QHSTA_M_BAD_CMPL_STATUS_IN  0x42
1191     #define QHSTA_M_NO_AUTO_REQ_SENSE   0x43
1192     #define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
1193     #define QHSTA_M_TARGET_STATUS_BUSY  0x45
1194     #define QHSTA_M_BAD_TAG_CODE        0x46
1195     #define QHSTA_M_BAD_QUEUE_FULL_OR_BUSY  0x47
1196     #define QHSTA_M_HUNG_REQ_SCSI_BUS_RESET 0x48
1197     #define QHSTA_D_LRAM_CMP_ERROR        0x81
1198     #define QHSTA_M_MICRO_CODE_ERROR_HALT 0xA1
1199     #define ASC_FLAG_SCSIQ_REQ        0x01
1200     #define ASC_FLAG_BIOS_SCSIQ_REQ   0x02
1201     #define ASC_FLAG_BIOS_ASYNC_IO    0x04
1202     #define ASC_FLAG_SRB_LINEAR_ADDR  0x08
1203     #define ASC_FLAG_WIN16            0x10
1204     #define ASC_FLAG_WIN32            0x20
1205     #define ASC_FLAG_ISA_OVER_16MB    0x40
1206     #define ASC_FLAG_DOS_VM_CALLBACK  0x80
1207     #define ASC_TAG_FLAG_EXTRA_BYTES               0x10
1208     #define ASC_TAG_FLAG_DISABLE_DISCONNECT        0x04
1209     #define ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX  0x08
1210     #define ASC_TAG_FLAG_DISABLE_CHK_COND_INT_HOST 0x40
1211     #define ASC_SCSIQ_CPY_BEG              4
1212     #define ASC_SCSIQ_SGHD_CPY_BEG         2
1213     #define ASC_SCSIQ_B_FWD                0
1214     #define ASC_SCSIQ_B_BWD                1
1215     #define ASC_SCSIQ_B_STATUS             2
1216     #define ASC_SCSIQ_B_QNO                3
1217     #define ASC_SCSIQ_B_CNTL               4
1218     #define ASC_SCSIQ_B_SG_QUEUE_CNT       5
1219     #define ASC_SCSIQ_D_DATA_ADDR          8
1220     #define ASC_SCSIQ_D_DATA_CNT          12
1221     #define ASC_SCSIQ_B_SENSE_LEN         20
1222     #define ASC_SCSIQ_DONE_INFO_BEG       22
1223     #define ASC_SCSIQ_D_SRBPTR            22
1224     #define ASC_SCSIQ_B_TARGET_IX         26
1225     #define ASC_SCSIQ_B_CDB_LEN           28
1226     #define ASC_SCSIQ_B_TAG_CODE          29
1227     #define ASC_SCSIQ_W_VM_ID             30
1228     #define ASC_SCSIQ_DONE_STATUS         32
1229     #define ASC_SCSIQ_HOST_STATUS         33
1230     #define ASC_SCSIQ_SCSI_STATUS         34
1231     #define ASC_SCSIQ_CDB_BEG             36
1232     #define ASC_SCSIQ_DW_REMAIN_XFER_ADDR 56
1233     #define ASC_SCSIQ_DW_REMAIN_XFER_CNT  60
1234     #define ASC_SCSIQ_B_FIRST_SG_WK_QP    48
1235     #define ASC_SCSIQ_B_SG_WK_QP          49
1236     #define ASC_SCSIQ_B_SG_WK_IX          50
1237     #define ASC_SCSIQ_W_ALT_DC1           52
1238     #define ASC_SCSIQ_B_LIST_CNT          6
1239     #define ASC_SCSIQ_B_CUR_LIST_CNT      7
1240     #define ASC_SGQ_B_SG_CNTL             4
1241     #define ASC_SGQ_B_SG_HEAD_QP          5
1242     #define ASC_SGQ_B_SG_LIST_CNT         6
1243     #define ASC_SGQ_B_SG_CUR_LIST_CNT     7
1244     #define ASC_SGQ_LIST_BEG              8
1245     #define ASC_DEF_SCSI1_QNG    4
1246     #define ASC_MAX_SCSI1_QNG    4
1247     #define ASC_DEF_SCSI2_QNG    16
1248     #define ASC_MAX_SCSI2_QNG    32
1249     #define ASC_TAG_CODE_MASK    0x23
1250     #define ASC_STOP_REQ_RISC_STOP      0x01
1251     #define ASC_STOP_ACK_RISC_STOP      0x03
1252     #define ASC_STOP_CLEAN_UP_BUSY_Q    0x10
1253     #define ASC_STOP_CLEAN_UP_DISC_Q    0x20
1254     #define ASC_STOP_HOST_REQ_RISC_HALT 0x40
1255     #define ASC_TIDLUN_TO_IX(tid, lun)  (ASC_SCSI_TIX_TYPE)((tid) + ((lun)<<ASC_SCSI_ID_BITS))
1256     #define ASC_TID_TO_TARGET_ID(tid)   (ASC_SCSI_BIT_ID_TYPE)(0x01 << (tid))
1257     #define ASC_TIX_TO_TARGET_ID(tix)   (0x01 << ((tix) & ASC_MAX_TID))
1258     #define ASC_TIX_TO_TID(tix)         ((tix) & ASC_MAX_TID)
1259     #define ASC_TID_TO_TIX(tid)         ((tid) & ASC_MAX_TID)
1260     #define ASC_TIX_TO_LUN(tix)         (((tix) >> ASC_SCSI_ID_BITS) & ASC_MAX_LUN)
1261     #define ASC_QNO_TO_QADDR(q_no)      ((ASC_QADR_BEG)+((int)(q_no) << 6))
1262     
1263     typedef struct asc_scsiq_1 {
1264         uchar               status;
1265         uchar               q_no;
1266         uchar               cntl;
1267         uchar               sg_queue_cnt;
1268         uchar               target_id;
1269         uchar               target_lun;
1270         ASC_PADDR           data_addr;
1271         ASC_DCNT            data_cnt;
1272         ASC_PADDR           sense_addr;
1273         uchar               sense_len;
1274         uchar               extra_bytes;
1275     } ASC_SCSIQ_1;
1276     
1277     typedef struct asc_scsiq_2 {
1278         ASC_VADDR           srb_ptr;
1279         uchar               target_ix;
1280         uchar               flag;
1281         uchar               cdb_len;
1282         uchar               tag_code;
1283         ushort              vm_id;
1284     } ASC_SCSIQ_2;
1285     
1286     typedef struct asc_scsiq_3 {
1287         uchar               done_stat;
1288         uchar               host_stat;
1289         uchar               scsi_stat;
1290         uchar               scsi_msg;
1291     } ASC_SCSIQ_3;
1292     
1293     typedef struct asc_scsiq_4 {
1294         uchar               cdb[ASC_MAX_CDB_LEN];
1295         uchar               y_first_sg_list_qp;
1296         uchar               y_working_sg_qp;
1297         uchar               y_working_sg_ix;
1298         uchar               y_res;
1299         ushort              x_req_count;
1300         ushort              x_reconnect_rtn;
1301         ASC_PADDR           x_saved_data_addr;
1302         ASC_DCNT            x_saved_data_cnt;
1303     } ASC_SCSIQ_4;
1304     
1305     typedef struct asc_q_done_info {
1306         ASC_SCSIQ_2         d2;
1307         ASC_SCSIQ_3         d3;
1308         uchar               q_status;
1309         uchar               q_no;
1310         uchar               cntl;
1311         uchar               sense_len;
1312         uchar               extra_bytes;
1313         uchar               res;
1314         ASC_DCNT            remain_bytes;
1315     } ASC_QDONE_INFO;
1316     
1317     typedef struct asc_sg_list {
1318         ASC_PADDR           addr;
1319         ASC_DCNT            bytes;
1320     } ASC_SG_LIST;
1321     
1322     typedef struct asc_sg_head {
1323         ushort              entry_cnt;
1324         ushort              queue_cnt;
1325         ushort              entry_to_copy;
1326         ushort              res;
1327         ASC_SG_LIST         sg_list[ASC_MAX_SG_LIST];
1328     } ASC_SG_HEAD;
1329     
1330     #define ASC_MIN_SG_LIST   2
1331     
1332     typedef struct asc_min_sg_head {
1333         ushort              entry_cnt;
1334         ushort              queue_cnt;
1335         ushort              entry_to_copy;
1336         ushort              res;
1337         ASC_SG_LIST         sg_list[ASC_MIN_SG_LIST];
1338     } ASC_MIN_SG_HEAD;
1339     
1340     #define QCX_SORT        (0x0001)
1341     #define QCX_COALEASE    (0x0002)
1342     
1343     typedef struct asc_scsi_q {
1344         ASC_SCSIQ_1         q1;
1345         ASC_SCSIQ_2         q2;
1346         uchar               *cdbptr;
1347         ASC_SG_HEAD         *sg_head;
1348         ushort              remain_sg_entry_cnt;
1349         ushort              next_sg_index;
1350     } ASC_SCSI_Q;
1351     
1352     typedef struct asc_scsi_req_q {
1353         ASC_SCSIQ_1         r1;
1354         ASC_SCSIQ_2         r2;
1355         uchar               *cdbptr;
1356         ASC_SG_HEAD         *sg_head;
1357         uchar               *sense_ptr;
1358         ASC_SCSIQ_3         r3;
1359         uchar               cdb[ASC_MAX_CDB_LEN];
1360         uchar               sense[ASC_MIN_SENSE_LEN];
1361     } ASC_SCSI_REQ_Q;
1362     
1363     typedef struct asc_scsi_bios_req_q {
1364         ASC_SCSIQ_1         r1;
1365         ASC_SCSIQ_2         r2;
1366         uchar               *cdbptr;
1367         ASC_SG_HEAD         *sg_head;
1368         uchar               *sense_ptr;
1369         ASC_SCSIQ_3         r3;
1370         uchar               cdb[ASC_MAX_CDB_LEN];
1371         uchar               sense[ASC_MIN_SENSE_LEN];
1372     } ASC_SCSI_BIOS_REQ_Q;
1373     
1374     typedef struct asc_risc_q {
1375         uchar               fwd;
1376         uchar               bwd;
1377         ASC_SCSIQ_1         i1;
1378         ASC_SCSIQ_2         i2;
1379         ASC_SCSIQ_3         i3;
1380         ASC_SCSIQ_4         i4;
1381     } ASC_RISC_Q;
1382     
1383     typedef struct asc_sg_list_q {
1384         uchar               seq_no;
1385         uchar               q_no;
1386         uchar               cntl;
1387         uchar               sg_head_qp;
1388         uchar               sg_list_cnt;
1389         uchar               sg_cur_list_cnt;
1390     } ASC_SG_LIST_Q;
1391     
1392     typedef struct asc_risc_sg_list_q {
1393         uchar               fwd;
1394         uchar               bwd;
1395         ASC_SG_LIST_Q       sg;
1396         ASC_SG_LIST         sg_list[7];
1397     } ASC_RISC_SG_LIST_Q;
1398     
1399     #define ASC_EXE_SCSI_IO_MAX_IDLE_LOOP  0x1000000UL
1400     #define ASC_EXE_SCSI_IO_MAX_WAIT_LOOP  1024
1401     #define ASCQ_ERR_NO_ERROR             0
1402     #define ASCQ_ERR_IO_NOT_FOUND         1
1403     #define ASCQ_ERR_LOCAL_MEM            2
1404     #define ASCQ_ERR_CHKSUM               3
1405     #define ASCQ_ERR_START_CHIP           4
1406     #define ASCQ_ERR_INT_TARGET_ID        5
1407     #define ASCQ_ERR_INT_LOCAL_MEM        6
1408     #define ASCQ_ERR_HALT_RISC            7
1409     #define ASCQ_ERR_GET_ASPI_ENTRY       8
1410     #define ASCQ_ERR_CLOSE_ASPI           9
1411     #define ASCQ_ERR_HOST_INQUIRY         0x0A
1412     #define ASCQ_ERR_SAVED_SRB_BAD        0x0B
1413     #define ASCQ_ERR_QCNTL_SG_LIST        0x0C
1414     #define ASCQ_ERR_Q_STATUS             0x0D
1415     #define ASCQ_ERR_WR_SCSIQ             0x0E
1416     #define ASCQ_ERR_PC_ADDR              0x0F
1417     #define ASCQ_ERR_SYN_OFFSET           0x10
1418     #define ASCQ_ERR_SYN_XFER_TIME        0x11
1419     #define ASCQ_ERR_LOCK_DMA             0x12
1420     #define ASCQ_ERR_UNLOCK_DMA           0x13
1421     #define ASCQ_ERR_VDS_CHK_INSTALL      0x14
1422     #define ASCQ_ERR_MICRO_CODE_HALT      0x15
1423     #define ASCQ_ERR_SET_LRAM_ADDR        0x16
1424     #define ASCQ_ERR_CUR_QNG              0x17
1425     #define ASCQ_ERR_SG_Q_LINKS           0x18
1426     #define ASCQ_ERR_SCSIQ_PTR            0x19
1427     #define ASCQ_ERR_ISR_RE_ENTRY         0x1A
1428     #define ASCQ_ERR_CRITICAL_RE_ENTRY    0x1B
1429     #define ASCQ_ERR_ISR_ON_CRITICAL      0x1C
1430     #define ASCQ_ERR_SG_LIST_ODD_ADDRESS  0x1D
1431     #define ASCQ_ERR_XFER_ADDRESS_TOO_BIG 0x1E
1432     #define ASCQ_ERR_SCSIQ_NULL_PTR       0x1F
1433     #define ASCQ_ERR_SCSIQ_BAD_NEXT_PTR   0x20
1434     #define ASCQ_ERR_GET_NUM_OF_FREE_Q    0x21
1435     #define ASCQ_ERR_SEND_SCSI_Q          0x22
1436     #define ASCQ_ERR_HOST_REQ_RISC_HALT   0x23
1437     #define ASCQ_ERR_RESET_SDTR           0x24
1438     
1439     /*
1440      * Warning code values are set in ASC_DVC_VAR  'warn_code'.
1441      */
1442     #define ASC_WARN_NO_ERROR             0x0000
1443     #define ASC_WARN_IO_PORT_ROTATE       0x0001
1444     #define ASC_WARN_EEPROM_CHKSUM        0x0002
1445     #define ASC_WARN_IRQ_MODIFIED         0x0004
1446     #define ASC_WARN_AUTO_CONFIG          0x0008
1447     #define ASC_WARN_CMD_QNG_CONFLICT     0x0010
1448     #define ASC_WARN_EEPROM_RECOVER       0x0020
1449     #define ASC_WARN_CFG_MSW_RECOVER      0x0040
1450     #define ASC_WARN_SET_PCI_CONFIG_SPACE 0x0080
1451     
1452     /*
1453      * Error code values are set in ASC_DVC_VAR  'err_code'.
1454      */
1455     #define ASC_IERR_WRITE_EEPROM         0x0001
1456     #define ASC_IERR_MCODE_CHKSUM         0x0002
1457     #define ASC_IERR_SET_PC_ADDR          0x0004
1458     #define ASC_IERR_START_STOP_CHIP      0x0008
1459     #define ASC_IERR_IRQ_NO               0x0010
1460     #define ASC_IERR_SET_IRQ_NO           0x0020
1461     #define ASC_IERR_CHIP_VERSION         0x0040
1462     #define ASC_IERR_SET_SCSI_ID          0x0080
1463     #define ASC_IERR_GET_PHY_ADDR         0x0100
1464     #define ASC_IERR_BAD_SIGNATURE        0x0200
1465     #define ASC_IERR_NO_BUS_TYPE          0x0400
1466     #define ASC_IERR_SCAM                 0x0800
1467     #define ASC_IERR_SET_SDTR             0x1000
1468     #define ASC_IERR_RW_LRAM              0x8000
1469     
1470     #define ASC_DEF_IRQ_NO  10
1471     #define ASC_MAX_IRQ_NO  15
1472     #define ASC_MIN_IRQ_NO  10
1473     #define ASC_MIN_REMAIN_Q        (0x02)
1474     #define ASC_DEF_MAX_TOTAL_QNG   (0xF0)
1475     #define ASC_MIN_TAG_Q_PER_DVC   (0x04)
1476     #define ASC_DEF_TAG_Q_PER_DVC   (0x04)
1477     #define ASC_MIN_FREE_Q        ASC_MIN_REMAIN_Q
1478     #define ASC_MIN_TOTAL_QNG     ((ASC_MAX_SG_QUEUE)+(ASC_MIN_FREE_Q))
1479     #define ASC_MAX_TOTAL_QNG 240
1480     #define ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG 16
1481     #define ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG   8
1482     #define ASC_MAX_PCI_INRAM_TOTAL_QNG  20
1483     #define ASC_MAX_INRAM_TAG_QNG   16
1484     #define ASC_IOADR_TABLE_MAX_IX  11
1485     #define ASC_IOADR_GAP   0x10
1486     #define ASC_SEARCH_IOP_GAP 0x10
1487     #define ASC_MIN_IOP_ADDR   (PortAddr)0x0100
1488     #define ASC_MAX_IOP_ADDR   (PortAddr)0x3F0
1489     #define ASC_IOADR_1     (PortAddr)0x0110
1490     #define ASC_IOADR_2     (PortAddr)0x0130
1491     #define ASC_IOADR_3     (PortAddr)0x0150
1492     #define ASC_IOADR_4     (PortAddr)0x0190
1493     #define ASC_IOADR_5     (PortAddr)0x0210
1494     #define ASC_IOADR_6     (PortAddr)0x0230
1495     #define ASC_IOADR_7     (PortAddr)0x0250
1496     #define ASC_IOADR_8     (PortAddr)0x0330
1497     #define ASC_IOADR_DEF   ASC_IOADR_8
1498     #define ASC_LIB_SCSIQ_WK_SP        256
1499     #define ASC_MAX_SYN_XFER_NO        16
1500     #define ASC_SYN_MAX_OFFSET         0x0F
1501     #define ASC_DEF_SDTR_OFFSET        0x0F
1502     #define ASC_DEF_SDTR_INDEX         0x00
1503     #define ASC_SDTR_ULTRA_PCI_10MB_INDEX  0x02
1504     #define SYN_XFER_NS_0  25
1505     #define SYN_XFER_NS_1  30
1506     #define SYN_XFER_NS_2  35
1507     #define SYN_XFER_NS_3  40
1508     #define SYN_XFER_NS_4  50
1509     #define SYN_XFER_NS_5  60
1510     #define SYN_XFER_NS_6  70
1511     #define SYN_XFER_NS_7  85
1512     #define SYN_ULTRA_XFER_NS_0    12
1513     #define SYN_ULTRA_XFER_NS_1    19
1514     #define SYN_ULTRA_XFER_NS_2    25
1515     #define SYN_ULTRA_XFER_NS_3    32
1516     #define SYN_ULTRA_XFER_NS_4    38
1517     #define SYN_ULTRA_XFER_NS_5    44
1518     #define SYN_ULTRA_XFER_NS_6    50
1519     #define SYN_ULTRA_XFER_NS_7    57
1520     #define SYN_ULTRA_XFER_NS_8    63
1521     #define SYN_ULTRA_XFER_NS_9    69
1522     #define SYN_ULTRA_XFER_NS_10   75
1523     #define SYN_ULTRA_XFER_NS_11   82
1524     #define SYN_ULTRA_XFER_NS_12   88
1525     #define SYN_ULTRA_XFER_NS_13   94
1526     #define SYN_ULTRA_XFER_NS_14  100
1527     #define SYN_ULTRA_XFER_NS_15  107
1528     
1529     typedef struct ext_msg {
1530         uchar               msg_type;
1531         uchar               msg_len;
1532         uchar               msg_req;
1533         union {
1534             struct {
1535                 uchar               sdtr_xfer_period;
1536                 uchar               sdtr_req_ack_offset;
1537             } sdtr;
1538             struct {
1539                 uchar               wdtr_width;
1540             } wdtr;
1541             struct {
1542                 uchar               mdp_b3;
1543                 uchar               mdp_b2;
1544                 uchar               mdp_b1;
1545                 uchar               mdp_b0;
1546             } mdp;
1547         } u_ext_msg;
1548         uchar               res;
1549     } EXT_MSG;
1550     
1551     #define xfer_period     u_ext_msg.sdtr.sdtr_xfer_period
1552     #define req_ack_offset  u_ext_msg.sdtr.sdtr_req_ack_offset
1553     #define wdtr_width      u_ext_msg.wdtr.wdtr_width
1554     #define mdp_b3          u_ext_msg.mdp_b3
1555     #define mdp_b2          u_ext_msg.mdp_b2
1556     #define mdp_b1          u_ext_msg.mdp_b1
1557     #define mdp_b0          u_ext_msg.mdp_b0
1558     
1559     typedef struct asc_dvc_cfg {
1560         ASC_SCSI_BIT_ID_TYPE can_tagged_qng;
1561         ASC_SCSI_BIT_ID_TYPE cmd_qng_enabled;
1562         ASC_SCSI_BIT_ID_TYPE disc_enable;
1563         ASC_SCSI_BIT_ID_TYPE sdtr_enable;
1564         uchar               chip_scsi_id;
1565         uchar               isa_dma_speed;
1566         uchar               isa_dma_channel;
1567         uchar               chip_version;
1568         ushort              pci_device_id;
1569         ushort              lib_serial_no;
1570         ushort              lib_version;
1571         ushort              mcode_date;
1572         ushort              mcode_version;
1573         uchar               max_tag_qng[ASC_MAX_TID + 1];
1574         uchar               *overrun_buf;
1575         uchar               sdtr_period_offset[ASC_MAX_TID + 1];
1576         ushort              pci_slot_info;
1577         uchar               adapter_info[6];
1578     } ASC_DVC_CFG;
1579     
1580     #define ASC_DEF_DVC_CNTL       0xFFFF
1581     #define ASC_DEF_CHIP_SCSI_ID   7
1582     #define ASC_DEF_ISA_DMA_SPEED  4
1583     #define ASC_INIT_STATE_NULL          0x0000
1584     #define ASC_INIT_STATE_BEG_GET_CFG   0x0001
1585     #define ASC_INIT_STATE_END_GET_CFG   0x0002
1586     #define ASC_INIT_STATE_BEG_SET_CFG   0x0004
1587     #define ASC_INIT_STATE_END_SET_CFG   0x0008
1588     #define ASC_INIT_STATE_BEG_LOAD_MC   0x0010
1589     #define ASC_INIT_STATE_END_LOAD_MC   0x0020
1590     #define ASC_INIT_STATE_BEG_INQUIRY   0x0040
1591     #define ASC_INIT_STATE_END_INQUIRY   0x0080
1592     #define ASC_INIT_RESET_SCSI_DONE     0x0100
1593     #define ASC_INIT_STATE_WITHOUT_EEP   0x8000
1594     #define ASC_PCI_DEVICE_ID_REV_A      0x1100
1595     #define ASC_PCI_DEVICE_ID_REV_B      0x1200
1596     #define ASC_BUG_FIX_IF_NOT_DWB       0x0001
1597     #define ASC_BUG_FIX_ASYN_USE_SYN     0x0002
1598     #define ASYN_SDTR_DATA_FIX_PCI_REV_AB 0x41
1599     #define ASC_MIN_TAGGED_CMD  7
1600     #define ASC_MAX_SCSI_RESET_WAIT      30
1601     
1602     struct asc_dvc_var;     /* Forward Declaration. */
1603     
1604     typedef void (* ASC_ISR_CALLBACK)(struct asc_dvc_var *, ASC_QDONE_INFO *);
1605     typedef int (* ASC_EXE_CALLBACK)(struct asc_dvc_var *, ASC_SCSI_Q *);
1606     
1607     typedef struct asc_dvc_var {
1608         PortAddr            iop_base;
1609         ushort              err_code;
1610         ushort              dvc_cntl;
1611         ushort              bug_fix_cntl;
1612         ushort              bus_type;
1613         ASC_ISR_CALLBACK    isr_callback;
1614         ASC_EXE_CALLBACK    exe_callback;
1615         ASC_SCSI_BIT_ID_TYPE init_sdtr;
1616         ASC_SCSI_BIT_ID_TYPE sdtr_done;
1617         ASC_SCSI_BIT_ID_TYPE use_tagged_qng;
1618         ASC_SCSI_BIT_ID_TYPE unit_not_ready;
1619         ASC_SCSI_BIT_ID_TYPE queue_full_or_busy;
1620         ASC_SCSI_BIT_ID_TYPE start_motor;
1621         uchar               scsi_reset_wait;
1622         uchar               chip_no;
1623         char                is_in_int;
1624         uchar               max_total_qng;
1625         uchar               cur_total_qng;
1626         uchar               in_critical_cnt;
1627         uchar               irq_no;
1628         uchar               last_q_shortage;
1629         ushort              init_state;
1630         uchar               cur_dvc_qng[ASC_MAX_TID + 1];
1631         uchar               max_dvc_qng[ASC_MAX_TID + 1];
1632         ASC_SCSI_Q  *scsiq_busy_head[ASC_MAX_TID + 1];
1633         ASC_SCSI_Q  *scsiq_busy_tail[ASC_MAX_TID + 1];
1634         uchar               sdtr_period_tbl[ASC_MAX_SYN_XFER_NO];
1635         ASC_DVC_CFG *cfg;
1636         ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer_always;
1637         char                redo_scam;
1638         ushort              res2;
1639         uchar               dos_int13_table[ASC_MAX_TID + 1];
1640         ASC_DCNT            max_dma_count;
1641         ASC_SCSI_BIT_ID_TYPE no_scam;
1642         ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer;
1643         uchar               max_sdtr_index;
1644         uchar               host_init_sdtr_index;
1645         struct asc_board    *drv_ptr;
1646         ASC_DCNT            uc_break;
1647     } ASC_DVC_VAR;
1648     
1649     typedef struct asc_dvc_inq_info {
1650         uchar               type[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
1651     } ASC_DVC_INQ_INFO;
1652     
1653     typedef struct asc_cap_info {
1654         ASC_DCNT            lba;
1655         ASC_DCNT            blk_size;
1656     } ASC_CAP_INFO;
1657     
1658     typedef struct asc_cap_info_array {
1659         ASC_CAP_INFO        cap_info[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
1660     } ASC_CAP_INFO_ARRAY;
1661     
1662     #define ASC_MCNTL_NO_SEL_TIMEOUT  (ushort)0x0001
1663     #define ASC_MCNTL_NULL_TARGET     (ushort)0x0002
1664     #define ASC_CNTL_INITIATOR         (ushort)0x0001
1665     #define ASC_CNTL_BIOS_GT_1GB       (ushort)0x0002
1666     #define ASC_CNTL_BIOS_GT_2_DISK    (ushort)0x0004
1667     #define ASC_CNTL_BIOS_REMOVABLE    (ushort)0x0008
1668     #define ASC_CNTL_NO_SCAM           (ushort)0x0010
1669     #define ASC_CNTL_INT_MULTI_Q       (ushort)0x0080
1670     #define ASC_CNTL_NO_LUN_SUPPORT    (ushort)0x0040
1671     #define ASC_CNTL_NO_VERIFY_COPY    (ushort)0x0100
1672     #define ASC_CNTL_RESET_SCSI        (ushort)0x0200
1673     #define ASC_CNTL_INIT_INQUIRY      (ushort)0x0400
1674     #define ASC_CNTL_INIT_VERBOSE      (ushort)0x0800
1675     #define ASC_CNTL_SCSI_PARITY       (ushort)0x1000
1676     #define ASC_CNTL_BURST_MODE        (ushort)0x2000
1677     #define ASC_CNTL_SDTR_ENABLE_ULTRA (ushort)0x4000
1678     #define ASC_EEP_DVC_CFG_BEG_VL    2
1679     #define ASC_EEP_MAX_DVC_ADDR_VL   15
1680     #define ASC_EEP_DVC_CFG_BEG      32
1681     #define ASC_EEP_MAX_DVC_ADDR     45
1682     #define ASC_EEP_DEFINED_WORDS    10
1683     #define ASC_EEP_MAX_ADDR         63
1684     #define ASC_EEP_RES_WORDS         0
1685     #define ASC_EEP_MAX_RETRY        20
1686     #define ASC_MAX_INIT_BUSY_RETRY   8
1687     #define ASC_EEP_ISA_PNP_WSIZE    16
1688     
1689     /*
1690      * These macros keep the chip SCSI id and ISA DMA speed
1691      * bitfields in board order. C bitfields aren't portable
1692      * between big and little-endian platforms so they are
1693      * not used.
1694      */
1695     
1696     #define ASC_EEP_GET_CHIP_ID(cfg)    ((cfg)->id_speed & 0x0f)
1697     #define ASC_EEP_GET_DMA_SPD(cfg)    (((cfg)->id_speed & 0xf0) >> 4)
1698     #define ASC_EEP_SET_CHIP_ID(cfg, sid) \
1699        ((cfg)->id_speed = ((cfg)->id_speed & 0xf0) | ((sid) & ASC_MAX_TID))
1700     #define ASC_EEP_SET_DMA_SPD(cfg, spd) \
1701        ((cfg)->id_speed = ((cfg)->id_speed & 0x0f) | ((spd) & 0x0f) << 4)
1702     
1703     typedef struct asceep_config {
1704         ushort              cfg_lsw;
1705         ushort              cfg_msw;
1706         uchar               init_sdtr;
1707         uchar               disc_enable;
1708         uchar               use_cmd_qng;
1709         uchar               start_motor;
1710         uchar               max_total_qng;
1711         uchar               max_tag_qng;
1712         uchar               bios_scan;
1713         uchar               power_up_wait;
1714         uchar               no_scam;
1715         uchar               id_speed; /* low order 4 bits is chip scsi id */
1716                                       /* high order 4 bits is isa dma speed */
1717         uchar               dos_int13_table[ASC_MAX_TID + 1];
1718         uchar               adapter_info[6];
1719         ushort              cntl;
1720         ushort              chksum;
1721     } ASCEEP_CONFIG;
1722     
1723     #define ASC_PCI_CFG_LSW_SCSI_PARITY  0x0800
1724     #define ASC_PCI_CFG_LSW_BURST_MODE   0x0080
1725     #define ASC_PCI_CFG_LSW_INTR_ABLE    0x0020
1726     
1727     #define ASC_EEP_CMD_READ          0x80
1728     #define ASC_EEP_CMD_WRITE         0x40
1729     #define ASC_EEP_CMD_WRITE_ABLE    0x30
1730     #define ASC_EEP_CMD_WRITE_DISABLE 0x00
1731     #define ASC_OVERRUN_BSIZE  0x00000048UL
1732     #define ASC_CTRL_BREAK_ONCE        0x0001
1733     #define ASC_CTRL_BREAK_STAY_IDLE   0x0002
1734     #define ASCV_MSGOUT_BEG         0x0000
1735     #define ASCV_MSGOUT_SDTR_PERIOD (ASCV_MSGOUT_BEG+3)
1736     #define ASCV_MSGOUT_SDTR_OFFSET (ASCV_MSGOUT_BEG+4)
1737     #define ASCV_BREAK_SAVED_CODE   (ushort)0x0006
1738     #define ASCV_MSGIN_BEG          (ASCV_MSGOUT_BEG+8)
1739     #define ASCV_MSGIN_SDTR_PERIOD  (ASCV_MSGIN_BEG+3)
1740     #define ASCV_MSGIN_SDTR_OFFSET  (ASCV_MSGIN_BEG+4)
1741     #define ASCV_SDTR_DATA_BEG      (ASCV_MSGIN_BEG+8)
1742     #define ASCV_SDTR_DONE_BEG      (ASCV_SDTR_DATA_BEG+8)
1743     #define ASCV_MAX_DVC_QNG_BEG    (ushort)0x0020
1744     #define ASCV_BREAK_ADDR           (ushort)0x0028
1745     #define ASCV_BREAK_NOTIFY_COUNT   (ushort)0x002A
1746     #define ASCV_BREAK_CONTROL        (ushort)0x002C
1747     #define ASCV_BREAK_HIT_COUNT      (ushort)0x002E
1748     
1749     #define ASCV_ASCDVC_ERR_CODE_W  (ushort)0x0030
1750     #define ASCV_MCODE_CHKSUM_W   (ushort)0x0032
1751     #define ASCV_MCODE_SIZE_W     (ushort)0x0034
1752     #define ASCV_STOP_CODE_B      (ushort)0x0036
1753     #define ASCV_DVC_ERR_CODE_B   (ushort)0x0037
1754     #define ASCV_OVERRUN_PADDR_D  (ushort)0x0038
1755     #define ASCV_OVERRUN_BSIZE_D  (ushort)0x003C
1756     #define ASCV_HALTCODE_W       (ushort)0x0040
1757     #define ASCV_CHKSUM_W         (ushort)0x0042
1758     #define ASCV_MC_DATE_W        (ushort)0x0044
1759     #define ASCV_MC_VER_W         (ushort)0x0046
1760     #define ASCV_NEXTRDY_B        (ushort)0x0048
1761     #define ASCV_DONENEXT_B       (ushort)0x0049
1762     #define ASCV_USE_TAGGED_QNG_B (ushort)0x004A
1763     #define ASCV_SCSIBUSY_B       (ushort)0x004B
1764     #define ASCV_Q_DONE_IN_PROGRESS_B  (ushort)0x004C
1765     #define ASCV_CURCDB_B         (ushort)0x004D
1766     #define ASCV_RCLUN_B          (ushort)0x004E
1767     #define ASCV_BUSY_QHEAD_B     (ushort)0x004F
1768     #define ASCV_DISC1_QHEAD_B    (ushort)0x0050
1769     #define ASCV_DISC_ENABLE_B    (ushort)0x0052
1770     #define ASCV_CAN_TAGGED_QNG_B (ushort)0x0053
1771     #define ASCV_HOSTSCSI_ID_B    (ushort)0x0055
1772     #define ASCV_MCODE_CNTL_B     (ushort)0x0056
1773     #define ASCV_NULL_TARGET_B    (ushort)0x0057
1774     #define ASCV_FREE_Q_HEAD_W    (ushort)0x0058
1775     #define ASCV_DONE_Q_TAIL_W    (ushort)0x005A
1776     #define ASCV_FREE_Q_HEAD_B    (ushort)(ASCV_FREE_Q_HEAD_W+1)
1777     #define ASCV_DONE_Q_TAIL_B    (ushort)(ASCV_DONE_Q_TAIL_W+1)
1778     #define ASCV_HOST_FLAG_B      (ushort)0x005D
1779     #define ASCV_TOTAL_READY_Q_B  (ushort)0x0064
1780     #define ASCV_VER_SERIAL_B     (ushort)0x0065
1781     #define ASCV_HALTCODE_SAVED_W (ushort)0x0066
1782     #define ASCV_WTM_FLAG_B       (ushort)0x0068
1783     #define ASCV_RISC_FLAG_B      (ushort)0x006A
1784     #define ASCV_REQ_SG_LIST_QP   (ushort)0x006B
1785     #define ASC_HOST_FLAG_IN_ISR        0x01
1786     #define ASC_HOST_FLAG_ACK_INT       0x02
1787     #define ASC_RISC_FLAG_GEN_INT      0x01
1788     #define ASC_RISC_FLAG_REQ_SG_LIST  0x02
1789     #define IOP_CTRL         (0x0F)
1790     #define IOP_STATUS       (0x0E)
1791     #define IOP_INT_ACK      IOP_STATUS
1792     #define IOP_REG_IFC      (0x0D)
1793     #define IOP_SYN_OFFSET    (0x0B)
1794     #define IOP_EXTRA_CONTROL (0x0D)
1795     #define IOP_REG_PC        (0x0C)
1796     #define IOP_RAM_ADDR      (0x0A)
1797     #define IOP_RAM_DATA      (0x08)
1798     #define IOP_EEP_DATA      (0x06)
1799     #define IOP_EEP_CMD       (0x07)
1800     #define IOP_VERSION       (0x03)
1801     #define IOP_CONFIG_HIGH   (0x04)
1802     #define IOP_CONFIG_LOW    (0x02)
1803     #define IOP_SIG_BYTE      (0x01)
1804     #define IOP_SIG_WORD      (0x00)
1805     #define IOP_REG_DC1      (0x0E)
1806     #define IOP_REG_DC0      (0x0C)
1807     #define IOP_REG_SB       (0x0B)
1808     #define IOP_REG_DA1      (0x0A)
1809     #define IOP_REG_DA0      (0x08)
1810     #define IOP_REG_SC       (0x09)
1811     #define IOP_DMA_SPEED    (0x07)
1812     #define IOP_REG_FLAG     (0x07)
1813     #define IOP_FIFO_H       (0x06)
1814     #define IOP_FIFO_L       (0x04)
1815     #define IOP_REG_ID       (0x05)
1816     #define IOP_REG_QP       (0x03)
1817     #define IOP_REG_IH       (0x02)
1818     #define IOP_REG_IX       (0x01)
1819     #define IOP_REG_AX       (0x00)
1820     #define IFC_REG_LOCK      (0x00)
1821     #define IFC_REG_UNLOCK    (0x09)
1822     #define IFC_WR_EN_FILTER  (0x10)
1823     #define IFC_RD_NO_EEPROM  (0x10)
1824     #define IFC_SLEW_RATE     (0x20)
1825     #define IFC_ACT_NEG       (0x40)
1826     #define IFC_INP_FILTER    (0x80)
1827     #define IFC_INIT_DEFAULT  (IFC_ACT_NEG | IFC_REG_UNLOCK)
1828     #define SC_SEL   (uchar)(0x80)
1829     #define SC_BSY   (uchar)(0x40)
1830     #define SC_ACK   (uchar)(0x20)
1831     #define SC_REQ   (uchar)(0x10)
1832     #define SC_ATN   (uchar)(0x08)
1833     #define SC_IO    (uchar)(0x04)
1834     #define SC_CD    (uchar)(0x02)
1835     #define SC_MSG   (uchar)(0x01)
1836     #define SEC_SCSI_CTL         (uchar)(0x80)
1837     #define SEC_ACTIVE_NEGATE    (uchar)(0x40)
1838     #define SEC_SLEW_RATE        (uchar)(0x20)
1839     #define SEC_ENABLE_FILTER    (uchar)(0x10)
1840     #define ASC_HALT_EXTMSG_IN     (ushort)0x8000
1841     #define ASC_HALT_CHK_CONDITION (ushort)0x8100
1842     #define ASC_HALT_SS_QUEUE_FULL (ushort)0x8200
1843     #define ASC_HALT_DISABLE_ASYN_USE_SYN_FIX  (ushort)0x8300
1844     #define ASC_HALT_ENABLE_ASYN_USE_SYN_FIX   (ushort)0x8400
1845     #define ASC_HALT_SDTR_REJECTED (ushort)0x4000
1846     #define ASC_HALT_HOST_COPY_SG_LIST_TO_RISC ( ushort )0x2000
1847     #define ASC_MAX_QNO        0xF8
1848     #define ASC_DATA_SEC_BEG   (ushort)0x0080
1849     #define ASC_DATA_SEC_END   (ushort)0x0080
1850     #define ASC_CODE_SEC_BEG   (ushort)0x0080
1851     #define ASC_CODE_SEC_END   (ushort)0x0080
1852     #define ASC_QADR_BEG       (0x4000)
1853     #define ASC_QADR_USED      (ushort)(ASC_MAX_QNO * 64)
1854     #define ASC_QADR_END       (ushort)0x7FFF
1855     #define ASC_QLAST_ADR      (ushort)0x7FC0
1856     #define ASC_QBLK_SIZE      0x40
1857     #define ASC_BIOS_DATA_QBEG 0xF8
1858     #define ASC_MIN_ACTIVE_QNO 0x01
1859     #define ASC_QLINK_END      0xFF
1860     #define ASC_EEPROM_WORDS   0x10
1861     #define ASC_MAX_MGS_LEN    0x10
1862     #define ASC_BIOS_ADDR_DEF  0xDC00
1863     #define ASC_BIOS_SIZE      0x3800
1864     #define ASC_BIOS_RAM_OFF   0x3800
1865     #define ASC_BIOS_RAM_SIZE  0x800
1866     #define ASC_BIOS_MIN_ADDR  0xC000
1867     #define ASC_BIOS_MAX_ADDR  0xEC00
1868     #define ASC_BIOS_BANK_SIZE 0x0400
1869     #define ASC_MCODE_START_ADDR  0x0080
1870     #define ASC_CFG0_HOST_INT_ON    0x0020
1871     #define ASC_CFG0_BIOS_ON        0x0040
1872     #define ASC_CFG0_VERA_BURST_ON  0x0080
1873     #define ASC_CFG0_SCSI_PARITY_ON 0x0800
1874     #define ASC_CFG1_SCSI_TARGET_ON 0x0080
1875     #define ASC_CFG1_LRAM_8BITS_ON  0x0800
1876     #define ASC_CFG_MSW_CLR_MASK    0x3080
1877     #define CSW_TEST1             (ASC_CS_TYPE)0x8000
1878     #define CSW_AUTO_CONFIG       (ASC_CS_TYPE)0x4000
1879     #define CSW_RESERVED1         (ASC_CS_TYPE)0x2000
1880     #define CSW_IRQ_WRITTEN       (ASC_CS_TYPE)0x1000
1881     #define CSW_33MHZ_SELECTED    (ASC_CS_TYPE)0x0800
1882     #define CSW_TEST2             (ASC_CS_TYPE)0x0400
1883     #define CSW_TEST3             (ASC_CS_TYPE)0x0200
1884     #define CSW_RESERVED2         (ASC_CS_TYPE)0x0100
1885     #define CSW_DMA_DONE          (ASC_CS_TYPE)0x0080
1886     #define CSW_FIFO_RDY          (ASC_CS_TYPE)0x0040
1887     #define CSW_EEP_READ_DONE     (ASC_CS_TYPE)0x0020
1888     #define CSW_HALTED            (ASC_CS_TYPE)0x0010
1889     #define CSW_SCSI_RESET_ACTIVE (ASC_CS_TYPE)0x0008
1890     #define CSW_PARITY_ERR        (ASC_CS_TYPE)0x0004
1891     #define CSW_SCSI_RESET_LATCH  (ASC_CS_TYPE)0x0002
1892     #define CSW_INT_PENDING       (ASC_CS_TYPE)0x0001
1893     #define CIW_CLR_SCSI_RESET_INT (ASC_CS_TYPE)0x1000
1894     #define CIW_INT_ACK      (ASC_CS_TYPE)0x0100
1895     #define CIW_TEST1        (ASC_CS_TYPE)0x0200
1896     #define CIW_TEST2        (ASC_CS_TYPE)0x0400
1897     #define CIW_SEL_33MHZ    (ASC_CS_TYPE)0x0800
1898     #define CIW_IRQ_ACT      (ASC_CS_TYPE)0x1000
1899     #define CC_CHIP_RESET   (uchar)0x80
1900     #define CC_SCSI_RESET   (uchar)0x40
1901     #define CC_HALT         (uchar)0x20
1902     #define CC_SINGLE_STEP  (uchar)0x10
1903     #define CC_DMA_ABLE     (uchar)0x08
1904     #define CC_TEST         (uchar)0x04
1905     #define CC_BANK_ONE     (uchar)0x02
1906     #define CC_DIAG         (uchar)0x01
1907     #define ASC_1000_ID0W      0x04C1
1908     #define ASC_1000_ID0W_FIX  0x00C1
1909     #define ASC_1000_ID1B      0x25
1910     #define ASC_EISA_BIG_IOP_GAP   (0x1C30-0x0C50)
1911     #define ASC_EISA_SMALL_IOP_GAP (0x0020)
1912     #define ASC_EISA_MIN_IOP_ADDR  (0x0C30)
1913     #define ASC_EISA_MAX_IOP_ADDR  (0xFC50)
1914     #define ASC_EISA_REV_IOP_MASK  (0x0C83)
1915     #define ASC_EISA_PID_IOP_MASK  (0x0C80)
1916     #define ASC_EISA_CFG_IOP_MASK  (0x0C86)
1917     #define ASC_GET_EISA_SLOT(iop)  (PortAddr)((iop) & 0xF000)
1918     #define ASC_EISA_ID_740    0x01745004UL
1919     #define ASC_EISA_ID_750    0x01755004UL
1920     #define INS_HALTINT        (ushort)0x6281
1921     #define INS_HALT           (ushort)0x6280
1922     #define INS_SINT           (ushort)0x6200
1923     #define INS_RFLAG_WTM      (ushort)0x7380
1924     #define ASC_MC_SAVE_CODE_WSIZE  0x500
1925     #define ASC_MC_SAVE_DATA_WSIZE  0x40
1926     
1927     typedef struct asc_mc_saved {
1928         ushort              data[ASC_MC_SAVE_DATA_WSIZE];
1929         ushort              code[ASC_MC_SAVE_CODE_WSIZE];
1930     } ASC_MC_SAVED;
1931     
1932     #define AscGetQDoneInProgress(port)         AscReadLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B)
1933     #define AscPutQDoneInProgress(port, val)    AscWriteLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B, val)
1934     #define AscGetVarFreeQHead(port)            AscReadLramWord((port), ASCV_FREE_Q_HEAD_W)
1935     #define AscGetVarDoneQTail(port)            AscReadLramWord((port), ASCV_DONE_Q_TAIL_W)
1936     #define AscPutVarFreeQHead(port, val)       AscWriteLramWord((port), ASCV_FREE_Q_HEAD_W, val)
1937     #define AscPutVarDoneQTail(port, val)       AscWriteLramWord((port), ASCV_DONE_Q_TAIL_W, val)
1938     #define AscGetRiscVarFreeQHead(port)        AscReadLramByte((port), ASCV_NEXTRDY_B)
1939     #define AscGetRiscVarDoneQTail(port)        AscReadLramByte((port), ASCV_DONENEXT_B)
1940     #define AscPutRiscVarFreeQHead(port, val)   AscWriteLramByte((port), ASCV_NEXTRDY_B, val)
1941     #define AscPutRiscVarDoneQTail(port, val)   AscWriteLramByte((port), ASCV_DONENEXT_B, val)
1942     #define AscPutMCodeSDTRDoneAtID(port, id, data)  AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id), (data));
1943     #define AscGetMCodeSDTRDoneAtID(port, id)        AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id));
1944     #define AscPutMCodeInitSDTRAtID(port, id, data)  AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id), data);
1945     #define AscGetMCodeInitSDTRAtID(port, id)        AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id));
1946     #define AscSynIndexToPeriod(index)        (uchar)(asc_dvc->sdtr_period_tbl[ (index) ])
1947     #define AscGetChipSignatureByte(port)     (uchar)inp((port)+IOP_SIG_BYTE)
1948     #define AscGetChipSignatureWord(port)     (ushort)inpw((port)+IOP_SIG_WORD)
1949     #define AscGetChipVerNo(port)             (uchar)inp((port)+IOP_VERSION)
1950     #define AscGetChipCfgLsw(port)            (ushort)inpw((port)+IOP_CONFIG_LOW)
1951     #define AscGetChipCfgMsw(port)            (ushort)inpw((port)+IOP_CONFIG_HIGH)
1952     #define AscSetChipCfgLsw(port, data)      outpw((port)+IOP_CONFIG_LOW, data)
1953     #define AscSetChipCfgMsw(port, data)      outpw((port)+IOP_CONFIG_HIGH, data)
1954     #define AscGetChipEEPCmd(port)            (uchar)inp((port)+IOP_EEP_CMD)
1955     #define AscSetChipEEPCmd(port, data)      outp((port)+IOP_EEP_CMD, data)
1956     #define AscGetChipEEPData(port)           (ushort)inpw((port)+IOP_EEP_DATA)
1957     #define AscSetChipEEPData(port, data)     outpw((port)+IOP_EEP_DATA, data)
1958     #define AscGetChipLramAddr(port)          (ushort)inpw((PortAddr)((port)+IOP_RAM_ADDR))
1959     #define AscSetChipLramAddr(port, addr)    outpw((PortAddr)((port)+IOP_RAM_ADDR), addr)
1960     #define AscGetChipLramData(port)          (ushort)inpw((port)+IOP_RAM_DATA)
1961     #define AscSetChipLramData(port, data)    outpw((port)+IOP_RAM_DATA, data)
1962     #define AscGetChipIFC(port)               (uchar)inp((port)+IOP_REG_IFC)
1963     #define AscSetChipIFC(port, data)          outp((port)+IOP_REG_IFC, data)
1964     #define AscGetChipStatus(port)            (ASC_CS_TYPE)inpw((port)+IOP_STATUS)
1965     #define AscSetChipStatus(port, cs_val)    outpw((port)+IOP_STATUS, cs_val)
1966     #define AscGetChipControl(port)           (uchar)inp((port)+IOP_CTRL)
1967     #define AscSetChipControl(port, cc_val)   outp((port)+IOP_CTRL, cc_val)
1968     #define AscGetChipSyn(port)               (uchar)inp((port)+IOP_SYN_OFFSET)
1969     #define AscSetChipSyn(port, data)         outp((port)+IOP_SYN_OFFSET, data)
1970     #define AscSetPCAddr(port, data)          outpw((port)+IOP_REG_PC, data)
1971     #define AscGetPCAddr(port)                (ushort)inpw((port)+IOP_REG_PC)
1972     #define AscIsIntPending(port)             (AscGetChipStatus(port) & (CSW_INT_PENDING | CSW_SCSI_RESET_LATCH))
1973     #define AscGetChipScsiID(port)            ((AscGetChipCfgLsw(port) >> 8) & ASC_MAX_TID)
1974     #define AscGetExtraControl(port)          (uchar)inp((port)+IOP_EXTRA_CONTROL)
1975     #define AscSetExtraControl(port, data)    outp((port)+IOP_EXTRA_CONTROL, data)
1976     #define AscReadChipAX(port)               (ushort)inpw((port)+IOP_REG_AX)
1977     #define AscWriteChipAX(port, data)        outpw((port)+IOP_REG_AX, data)
1978     #define AscReadChipIX(port)               (uchar)inp((port)+IOP_REG_IX)
1979     #define AscWriteChipIX(port, data)        outp((port)+IOP_REG_IX, data)
1980     #define AscReadChipIH(port)               (ushort)inpw((port)+IOP_REG_IH)
1981     #define AscWriteChipIH(port, data)        outpw((port)+IOP_REG_IH, data)
1982     #define AscReadChipQP(port)               (uchar)inp((port)+IOP_REG_QP)
1983     #define AscWriteChipQP(port, data)        outp((port)+IOP_REG_QP, data)
1984     #define AscReadChipFIFO_L(port)           (ushort)inpw((port)+IOP_REG_FIFO_L)
1985     #define AscWriteChipFIFO_L(port, data)    outpw((port)+IOP_REG_FIFO_L, data)
1986     #define AscReadChipFIFO_H(port)           (ushort)inpw((port)+IOP_REG_FIFO_H)
1987     #define AscWriteChipFIFO_H(port, data)    outpw((port)+IOP_REG_FIFO_H, data)
1988     #define AscReadChipDmaSpeed(port)         (uchar)inp((port)+IOP_DMA_SPEED)
1989     #define AscWriteChipDmaSpeed(port, data)  outp((port)+IOP_DMA_SPEED, data)
1990     #define AscReadChipDA0(port)              (ushort)inpw((port)+IOP_REG_DA0)
1991     #define AscWriteChipDA0(port)             outpw((port)+IOP_REG_DA0, data)
1992     #define AscReadChipDA1(port)              (ushort)inpw((port)+IOP_REG_DA1)
1993     #define AscWriteChipDA1(port)             outpw((port)+IOP_REG_DA1, data)
1994     #define AscReadChipDC0(port)              (ushort)inpw((port)+IOP_REG_DC0)
1995     #define AscWriteChipDC0(port)             outpw((port)+IOP_REG_DC0, data)
1996     #define AscReadChipDC1(port)              (ushort)inpw((port)+IOP_REG_DC1)
1997     #define AscWriteChipDC1(port)             outpw((port)+IOP_REG_DC1, data)
1998     #define AscReadChipDvcID(port)            (uchar)inp((port)+IOP_REG_ID)
1999     #define AscWriteChipDvcID(port, data)     outp((port)+IOP_REG_ID, data)
2000     
2001     STATIC int       AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg);
2002     STATIC int       AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg);
2003     STATIC void      AscWaitEEPRead(void);
2004     STATIC void      AscWaitEEPWrite(void);
2005     STATIC ushort    AscReadEEPWord(PortAddr, uchar);
2006     STATIC ushort    AscWriteEEPWord(PortAddr, uchar, ushort);
2007     STATIC ushort    AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
2008     STATIC int       AscSetEEPConfigOnce(PortAddr, ASCEEP_CONFIG *, ushort);
2009     STATIC int       AscSetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
2010     STATIC int       AscStartChip(PortAddr);
2011     STATIC int       AscStopChip(PortAddr);
2012     STATIC void      AscSetChipIH(PortAddr, ushort);
2013     STATIC int       AscIsChipHalted(PortAddr);
2014     STATIC void      AscAckInterrupt(PortAddr);
2015     STATIC void      AscDisableInterrupt(PortAddr);
2016     STATIC void      AscEnableInterrupt(PortAddr);
2017     STATIC void      AscSetBank(PortAddr, uchar);
2018     STATIC int       AscResetChipAndScsiBus(ASC_DVC_VAR *);
2019     #ifdef CONFIG_ISA
2020     STATIC ushort    AscGetIsaDmaChannel(PortAddr);
2021     STATIC ushort    AscSetIsaDmaChannel(PortAddr, ushort);
2022     STATIC uchar     AscSetIsaDmaSpeed(PortAddr, uchar);
2023     STATIC uchar     AscGetIsaDmaSpeed(PortAddr);
2024     #endif /* CONFIG_ISA */
2025     STATIC uchar     AscReadLramByte(PortAddr, ushort);
2026     STATIC ushort    AscReadLramWord(PortAddr, ushort);
2027     #if CC_VERY_LONG_SG_LIST
2028     STATIC ASC_DCNT  AscReadLramDWord(PortAddr, ushort);
2029     #endif /* CC_VERY_LONG_SG_LIST */
2030     STATIC void      AscWriteLramWord(PortAddr, ushort, ushort);
2031     STATIC void      AscWriteLramByte(PortAddr, ushort, uchar);
2032     STATIC ASC_DCNT  AscMemSumLramWord(PortAddr, ushort, int);
2033     STATIC void      AscMemWordSetLram(PortAddr, ushort, ushort, int);
2034     STATIC void      AscMemWordCopyPtrToLram(PortAddr, ushort, uchar *, int);
2035     STATIC void      AscMemDWordCopyPtrToLram(PortAddr, ushort, uchar *, int);
2036     STATIC void      AscMemWordCopyPtrFromLram(PortAddr, ushort, uchar *, int);
2037     STATIC ushort    AscInitAscDvcVar(ASC_DVC_VAR *);
2038     STATIC ushort    AscInitFromEEP(ASC_DVC_VAR *);
2039     STATIC ushort    AscInitFromAscDvcVar(ASC_DVC_VAR *);
2040     STATIC ushort    AscInitMicroCodeVar(ASC_DVC_VAR *);
2041     STATIC int       AscTestExternalLram(ASC_DVC_VAR *);
2042     STATIC uchar     AscMsgOutSDTR(ASC_DVC_VAR *, uchar, uchar);
2043     STATIC uchar     AscCalSDTRData(ASC_DVC_VAR *, uchar, uchar);
2044     STATIC void      AscSetChipSDTR(PortAddr, uchar, uchar);
2045     STATIC uchar     AscGetSynPeriodIndex(ASC_DVC_VAR *, uchar);
2046     STATIC uchar     AscAllocFreeQueue(PortAddr, uchar);
2047     STATIC uchar     AscAllocMultipleFreeQueue(PortAddr, uchar, uchar);
2048     STATIC int       AscHostReqRiscHalt(PortAddr);
2049     STATIC int       AscStopQueueExe(PortAddr);
2050     STATIC int       AscSendScsiQueue(ASC_DVC_VAR *,
2051                         ASC_SCSI_Q * scsiq,
2052                         uchar n_q_required);
2053     STATIC int       AscPutReadyQueue(ASC_DVC_VAR *,
2054                         ASC_SCSI_Q *, uchar);
2055     STATIC int       AscPutReadySgListQueue(ASC_DVC_VAR *,
2056                         ASC_SCSI_Q *, uchar);
2057     STATIC int       AscSetChipSynRegAtID(PortAddr, uchar, uchar);
2058     STATIC int       AscSetRunChipSynRegAtID(PortAddr, uchar, uchar);
2059     STATIC ushort    AscInitLram(ASC_DVC_VAR *);
2060     STATIC ushort    AscInitQLinkVar(ASC_DVC_VAR *);
2061     STATIC int       AscSetLibErrorCode(ASC_DVC_VAR *, ushort);
2062     STATIC int       AscIsrChipHalted(ASC_DVC_VAR *);
2063     STATIC uchar     _AscCopyLramScsiDoneQ(PortAddr, ushort,
2064                         ASC_QDONE_INFO *, ASC_DCNT);
2065     STATIC int       AscIsrQDone(ASC_DVC_VAR *);
2066     STATIC int       AscCompareString(uchar *, uchar *, int);
2067     #ifdef CONFIG_ISA
2068     STATIC ushort    AscGetEisaChipCfg(PortAddr);
2069     STATIC ASC_DCNT  AscGetEisaProductID(PortAddr);
2070     STATIC PortAddr  AscSearchIOPortAddrEISA(PortAddr);
2071     STATIC PortAddr  AscSearchIOPortAddr11(PortAddr);
2072     STATIC PortAddr  AscSearchIOPortAddr(PortAddr, ushort);
2073     STATIC void      AscSetISAPNPWaitForKey(void);
2074     #endif /* CONFIG_ISA */
2075     STATIC uchar     AscGetChipScsiCtrl(PortAddr);
2076     STATIC uchar     AscSetChipScsiID(PortAddr, uchar);
2077     STATIC uchar     AscGetChipVersion(PortAddr, ushort);
2078     STATIC ushort    AscGetChipBusType(PortAddr);
2079     STATIC ASC_DCNT  AscLoadMicroCode(PortAddr, ushort, uchar *, ushort);
2080     STATIC int       AscFindSignature(PortAddr);
2081     STATIC void      AscToggleIRQAct(PortAddr);
2082     STATIC uchar     AscGetChipIRQ(PortAddr, ushort);
2083     STATIC uchar     AscSetChipIRQ(PortAddr, uchar, ushort);
2084     STATIC ushort    AscGetChipBiosAddress(PortAddr, ushort);
2085     STATIC inline ulong DvcEnterCritical(void);
2086     STATIC inline void DvcLeaveCritical(ulong);
2087     #ifdef CONFIG_PCI
2088     STATIC uchar     DvcReadPCIConfigByte(ASC_DVC_VAR *, ushort);
2089     STATIC void      DvcWritePCIConfigByte(ASC_DVC_VAR *,
2090                         ushort, uchar);
2091     #endif /* CONFIG_PCI */
2092     STATIC ushort      AscGetChipBiosAddress(PortAddr, ushort);
2093     STATIC void      DvcSleepMilliSecond(ASC_DCNT);
2094     STATIC void      DvcDelayNanoSecond(ASC_DVC_VAR *, ASC_DCNT);
2095     STATIC void      DvcPutScsiQ(PortAddr, ushort, uchar *, int);
2096     STATIC void      DvcGetQinfo(PortAddr, ushort, uchar *, int);
2097     STATIC ushort    AscInitGetConfig(ASC_DVC_VAR *);
2098     STATIC ushort    AscInitSetConfig(ASC_DVC_VAR *);
2099     STATIC ushort    AscInitAsc1000Driver(ASC_DVC_VAR *);
2100     STATIC void      AscAsyncFix(ASC_DVC_VAR *, uchar,
2101                         ASC_SCSI_INQUIRY *);
2102     STATIC int       AscTagQueuingSafe(ASC_SCSI_INQUIRY *);
2103     STATIC void      AscInquiryHandling(ASC_DVC_VAR *,
2104                         uchar, ASC_SCSI_INQUIRY *);
2105     STATIC int       AscExeScsiQueue(ASC_DVC_VAR *, ASC_SCSI_Q *);
2106     STATIC int       AscISR(ASC_DVC_VAR *);
2107     STATIC uint      AscGetNumOfFreeQueue(ASC_DVC_VAR *, uchar,
2108                         uchar);
2109     STATIC int       AscSgListToQueue(int);
2110     #ifdef CONFIG_ISA
2111     STATIC void      AscEnableIsaDma(uchar);
2112     #endif /* CONFIG_ISA */
2113     STATIC ASC_DCNT  AscGetMaxDmaCount(ushort);
2114     
2115     
2116     /*
2117      * --- Adv Library Constants and Macros
2118      */
2119     
2120     #define ADV_LIB_VERSION_MAJOR  5
2121     #define ADV_LIB_VERSION_MINOR  14
2122     
2123     /* d_os_dep.h */
2124     #define ADV_OS_LINUX
2125     
2126     /*
2127      * Define Adv Library required special types.
2128      */
2129     
2130     /*
2131      * Portable Data Types
2132      *
2133      * Any instance where a 32-bit long or pointer type is assumed
2134      * for precision or HW defined structures, the following define
2135      * types must be used. In Linux the char, short, and int types
2136      * are all consistent at 8, 16, and 32 bits respectively. Pointers
2137      * and long types are 64 bits on Alpha and UltraSPARC.
2138      */
2139     #define ADV_PADDR __u32         /* Physical address data type. */
2140     #define ADV_VADDR __u32         /* Virtual address data type. */
2141     #define ADV_DCNT  __u32         /* Unsigned Data count type. */
2142     #define ADV_SDCNT __s32         /* Signed Data count type. */
2143     
2144     /*
2145      * These macros are used to convert a virtual address to a
2146      * 32-bit value. This currently can be used on Linux Alpha
2147      * which uses 64-bit virtual address but a 32-bit bus address.
2148      * This is likely to break in the future, but doing this now
2149      * will give us time to change the HW and FW to handle 64-bit
2150      * addresses.
2151      */
2152     #define ADV_VADDR_TO_U32   virt_to_bus
2153     #define ADV_U32_TO_VADDR   bus_to_virt
2154     
2155     #define AdvPortAddr  ulong              /* Virtual memory address size */
2156     
2157     /*
2158      * Define Adv Library required memory access macros.
2159      */
2160     #define ADV_MEM_READB(addr) readb(addr)
2161     #define ADV_MEM_READW(addr) readw(addr)
2162     #define ADV_MEM_WRITEB(addr, byte) writeb(byte, addr)
2163     #define ADV_MEM_WRITEW(addr, word) writew(word, addr)
2164     #define ADV_MEM_WRITEDW(addr, dword) writel(dword, addr)
2165     
2166     #define ADV_CARRIER_COUNT (ASC_DEF_MAX_HOST_QNG + 15)
2167     
2168     /*
2169      * For wide  boards a CDB length maximum of 16 bytes
2170      * is supported.
2171      */
2172     #define ADV_MAX_CDB_LEN     16
2173     
2174     /*
2175      * Define total number of simultaneous maximum element scatter-gather
2176      * request blocks per wide adapter. ASC_DEF_MAX_HOST_QNG (253) is the
2177      * maximum number of outstanding commands per wide host adapter. Each
2178      * command uses one or more ADV_SG_BLOCK each with 15 scatter-gather
2179      * elements. Allow each command to have at least one ADV_SG_BLOCK structure.
2180      * This allows about 15 commands to have the maximum 17 ADV_SG_BLOCK
2181      * structures or 255 scatter-gather elements.
2182      *
2183      */
2184     #define ADV_TOT_SG_BLOCK        ASC_DEF_MAX_HOST_QNG
2185     
2186     /*
2187      * Define Adv Library required maximum number of scatter-gather
2188      * elements per request.
2189      */
2190     #define ADV_MAX_SG_LIST         255
2191     
2192     /* Number of SG blocks needed. */
2193     #define ADV_NUM_SG_BLOCK \
2194         ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK)
2195     
2196     /* Total contiguous memory needed for SG blocks. */
2197     #define ADV_SG_TOTAL_MEM_SIZE \
2198         (sizeof(ADV_SG_BLOCK) *  ADV_NUM_SG_BLOCK)
2199     
2200     #define ADV_PAGE_SIZE PAGE_SIZE
2201     
2202     #define ADV_NUM_PAGE_CROSSING \
2203         ((ADV_SG_TOTAL_MEM_SIZE + (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
2204     
2205     /* a_condor.h */
2206     #define ADV_PCI_VENDOR_ID               0x10CD
2207     #define ADV_PCI_DEVICE_ID_REV_A         0x2300
2208     #define ADV_PCI_DEVID_38C0800_REV1      0x2500
2209     #define ADV_PCI_DEVID_38C1600_REV1      0x2700
2210     
2211     #define ADV_EEP_DVC_CFG_BEGIN           (0x00)
2212     #define ADV_EEP_DVC_CFG_END             (0x15)
2213     #define ADV_EEP_DVC_CTL_BEGIN           (0x16)  /* location of OEM name */
2214     #define ADV_EEP_MAX_WORD_ADDR           (0x1E)
2215     
2216     #define ADV_EEP_DELAY_MS                100
2217     
2218     #define ADV_EEPROM_BIG_ENDIAN          0x8000   /* EEPROM Bit 15 */
2219     #define ADV_EEPROM_BIOS_ENABLE         0x4000   /* EEPROM Bit 14 */
2220     /*
2221      * For the ASC3550 Bit 13 is Termination Polarity control bit.
2222      * For later ICs Bit 13 controls whether the CIS (Card Information
2223      * Service Section) is loaded from EEPROM.
2224      */
2225     #define ADV_EEPROM_TERM_POL            0x2000   /* EEPROM Bit 13 */
2226     #define ADV_EEPROM_CIS_LD              0x2000   /* EEPROM Bit 13 */
2227     /*
2228      * ASC38C1600 Bit 11
2229      *
2230      * If EEPROM Bit 11 is 0 for Function 0, then Function 0 will specify
2231      * INT A in the PCI Configuration Space Int Pin field. If it is 1, then
2232      * Function 0 will specify INT B.
2233      *
2234      * If EEPROM Bit 11 is 0 for Function 1, then Function 1 will specify
2235      * INT B in the PCI Configuration Space Int Pin field. If it is 1, then
2236      * Function 1 will specify INT A.
2237      */
2238     #define ADV_EEPROM_INTAB               0x0800   /* EEPROM Bit 11 */
2239     
2240     typedef struct adveep_3550_config
2241     {
2242                                     /* Word Offset, Description */
2243     
2244       ushort cfg_lsw;               /* 00 power up initialization */
2245                                     /*  bit 13 set - Term Polarity Control */
2246                                     /*  bit 14 set - BIOS Enable */
2247                                     /*  bit 15 set - Big Endian Mode */
2248       ushort cfg_msw;               /* 01 unused      */
2249       ushort disc_enable;           /* 02 disconnect enable */
2250       ushort wdtr_able;             /* 03 Wide DTR able */
2251       ushort sdtr_able;             /* 04 Synchronous DTR able */
2252       ushort start_motor;           /* 05 send start up motor */
2253       ushort tagqng_able;           /* 06 tag queuing able */
2254       ushort bios_scan;             /* 07 BIOS device control */
2255       ushort scam_tolerant;         /* 08 no scam */
2256     
2257       uchar  adapter_scsi_id;       /* 09 Host Adapter ID */
2258       uchar  bios_boot_delay;       /*    power up wait */
2259     
2260       uchar  scsi_reset_delay;      /* 10 reset delay */
2261       uchar  bios_id_lun;           /*    first boot device scsi id & lun */
2262                                     /*    high nibble is lun */
2263                                     /*    low nibble is scsi id */
2264     
2265       uchar  termination;           /* 11 0 - automatic */
2266                                     /*    1 - low off / high off */
2267                                     /*    2 - low off / high on */
2268                                     /*    3 - low on  / high on */
2269                                     /*    There is no low on  / high off */
2270     
2271       uchar  reserved1;             /*    reserved byte (not used) */
2272     
2273       ushort bios_ctrl;             /* 12 BIOS control bits */
2274                                     /*  bit 0  BIOS don't act as initiator. */
2275                                     /*  bit 1  BIOS > 1 GB support */
2276                                     /*  bit 2  BIOS > 2 Disk Support */
2277                                     /*  bit 3  BIOS don't support removables */
2278                                     /*  bit 4  BIOS support bootable CD */
2279                                     /*  bit 5  BIOS scan enabled */
2280                                     /*  bit 6  BIOS support multiple LUNs */
2281                                     /*  bit 7  BIOS display of message */
2282                                     /*  bit 8  SCAM disabled */
2283                                     /*  bit 9  Reset SCSI bus during init. */
2284                                     /*  bit 10 */
2285                                     /*  bit 11 No verbose initialization. */
2286                                     /*  bit 12 SCSI parity enabled */
2287                                     /*  bit 13 */
2288                                     /*  bit 14 */
2289                                     /*  bit 15 */
2290       ushort  ultra_able;           /* 13 ULTRA speed able */
2291       ushort  reserved2;            /* 14 reserved */
2292       uchar   max_host_qng;         /* 15 maximum host queuing */
2293       uchar   max_dvc_qng;          /*    maximum per device queuing */
2294       ushort  dvc_cntl;             /* 16 control bit for driver */
2295       ushort  bug_fix;              /* 17 control bit for bug fix */
2296       ushort  serial_number_word1;  /* 18 Board serial number word 1 */
2297       ushort  serial_number_word2;  /* 19 Board serial number word 2 */
2298       ushort  serial_number_word3;  /* 20 Board serial number word 3 */
2299       ushort  check_sum;            /* 21 EEP check sum */
2300       uchar   oem_name[16];         /* 22 OEM name */
2301       ushort  dvc_err_code;         /* 30 last device driver error code */
2302       ushort  adv_err_code;         /* 31 last uc and Adv Lib error code */
2303       ushort  adv_err_addr;         /* 32 last uc error address */
2304       ushort  saved_dvc_err_code;   /* 33 saved last dev. driver error code   */
2305       ushort  saved_adv_err_code;   /* 34 saved last uc and Adv Lib error code */
2306       ushort  saved_adv_err_addr;   /* 35 saved last uc error address         */
2307       ushort  num_of_err;           /* 36 number of error */
2308     } ADVEEP_3550_CONFIG;
2309     
2310     typedef struct adveep_38C0800_config
2311     {
2312                                     /* Word Offset, Description */
2313     
2314       ushort cfg_lsw;               /* 00 power up initialization */
2315                                     /*  bit 13 set - Load CIS */
2316                                     /*  bit 14 set - BIOS Enable */
2317                                     /*  bit 15 set - Big Endian Mode */
2318       ushort cfg_msw;               /* 01 unused      */
2319       ushort disc_enable;           /* 02 disconnect enable */
2320       ushort wdtr_able;             /* 03 Wide DTR able */
2321       ushort sdtr_speed1;           /* 04 SDTR Speed TID 0-3 */
2322       ushort start_motor;           /* 05 send start up motor */
2323       ushort tagqng_able;           /* 06 tag queuing able */
2324       ushort bios_scan;             /* 07 BIOS device control */
2325       ushort scam_tolerant;         /* 08 no scam */
2326     
2327       uchar  adapter_scsi_id;       /* 09 Host Adapter ID */
2328       uchar  bios_boot_delay;       /*    power up wait */
2329     
2330       uchar  scsi_reset_delay;      /* 10 reset delay */
2331       uchar  bios_id_lun;           /*    first boot device scsi id & lun */
2332                                     /*    high nibble is lun */
2333                                     /*    low nibble is scsi id */
2334     
2335       uchar  termination_se;        /* 11 0 - automatic */
2336                                     /*    1 - low off / high off */
2337                                     /*    2 - low off / high on */
2338                                     /*    3 - low on  / high on */
2339                                     /*    There is no low on  / high off */
2340     
2341       uchar  termination_lvd;       /* 11 0 - automatic */
2342                                     /*    1 - low off / high off */
2343                                     /*    2 - low off / high on */
2344                                     /*    3 - low on  / high on */
2345                                     /*    There is no low on  / high off */
2346     
2347       ushort bios_ctrl;             /* 12 BIOS control bits */
2348                                     /*  bit 0  BIOS don't act as initiator. */
2349                                     /*  bit 1  BIOS > 1 GB support */
2350                                     /*  bit 2  BIOS > 2 Disk Support */
2351                                     /*  bit 3  BIOS don't support removables */
2352                                     /*  bit 4  BIOS support bootable CD */
2353                                     /*  bit 5  BIOS scan enabled */
2354                                     /*  bit 6  BIOS support multiple LUNs */
2355                                     /*  bit 7  BIOS display of message */
2356                                     /*  bit 8  SCAM disabled */
2357                                     /*  bit 9  Reset SCSI bus during init. */
2358                                     /*  bit 10 */
2359                                     /*  bit 11 No verbose initialization. */
2360                                     /*  bit 12 SCSI parity enabled */
2361                                     /*  bit 13 */
2362                                     /*  bit 14 */
2363                                     /*  bit 15 */
2364       ushort  sdtr_speed2;          /* 13 SDTR speed TID 4-7 */
2365       ushort  sdtr_speed3;          /* 14 SDTR speed TID 8-11 */
2366       uchar   max_host_qng;         /* 15 maximum host queueing */
2367       uchar   max_dvc_qng;          /*    maximum per device queuing */
2368       ushort  dvc_cntl;             /* 16 control bit for driver */
2369       ushort  sdtr_speed4;          /* 17 SDTR speed 4 TID 12-15 */
2370       ushort  serial_number_word1;  /* 18 Board serial number word 1 */
2371       ushort  serial_number_word2;  /* 19 Board serial number word 2 */
2372       ushort  serial_number_word3;  /* 20 Board serial number word 3 */
2373       ushort  check_sum;            /* 21 EEP check sum */
2374       uchar   oem_name[16];         /* 22 OEM name */
2375       ushort  dvc_err_code;         /* 30 last device driver error code */
2376       ushort  adv_err_code;         /* 31 last uc and Adv Lib error code */
2377       ushort  adv_err_addr;         /* 32 last uc error address */
2378       ushort  saved_dvc_err_code;   /* 33 saved last dev. driver error code   */
2379       ushort  saved_adv_err_code;   /* 34 saved last uc and Adv Lib error code */
2380       ushort  saved_adv_err_addr;   /* 35 saved last uc error address         */
2381       ushort  reserved36;           /* 36 reserved */
2382       ushort  reserved37;           /* 37 reserved */
2383       ushort  reserved38;           /* 38 reserved */
2384       ushort  reserved39;           /* 39 reserved */
2385       ushort  reserved40;           /* 40 reserved */
2386       ushort  reserved41;           /* 41 reserved */
2387       ushort  reserved42;           /* 42 reserved */
2388       ushort  reserved43;           /* 43 reserved */
2389       ushort  reserved44;           /* 44 reserved */
2390       ushort  reserved45;           /* 45 reserved */
2391       ushort  reserved46;           /* 46 reserved */
2392       ushort  reserved47;           /* 47 reserved */
2393       ushort  reserved48;           /* 48 reserved */
2394       ushort  reserved49;           /* 49 reserved */
2395       ushort  reserved50;           /* 50 reserved */
2396       ushort  reserved51;           /* 51 reserved */
2397       ushort  reserved52;           /* 52 reserved */
2398       ushort  reserved53;           /* 53 reserved */
2399       ushort  reserved54;           /* 54 reserved */
2400       ushort  reserved55;           /* 55 reserved */
2401       ushort  cisptr_lsw;           /* 56 CIS PTR LSW */
2402       ushort  cisprt_msw;           /* 57 CIS PTR MSW */
2403       ushort  subsysvid;            /* 58 SubSystem Vendor ID */
2404       ushort  subsysid;             /* 59 SubSystem ID */
2405       ushort  reserved60;           /* 60 reserved */
2406       ushort  reserved61;           /* 61 reserved */
2407       ushort  reserved62;           /* 62 reserved */
2408       ushort  reserved63;           /* 63 reserved */
2409     } ADVEEP_38C0800_CONFIG;
2410     
2411     typedef struct adveep_38C1600_config
2412     {
2413                                     /* Word Offset, Description */
2414     
2415       ushort cfg_lsw;               /* 00 power up initialization */
2416                                     /*  bit 11 set - Func. 0 INTB, Func. 1 INTA */
2417                                     /*       clear - Func. 0 INTA, Func. 1 INTB */
2418                                     /*  bit 13 set - Load CIS */
2419                                     /*  bit 14 set - BIOS Enable */
2420                                     /*  bit 15 set - Big Endian Mode */
2421       ushort cfg_msw;               /* 01 unused */
2422       ushort disc_enable;           /* 02 disconnect enable */
2423       ushort wdtr_able;             /* 03 Wide DTR able */
2424       ushort sdtr_speed1;           /* 04 SDTR Speed TID 0-3 */
2425       ushort start_motor;           /* 05 send start up motor */
2426       ushort tagqng_able;           /* 06 tag queuing able */
2427       ushort bios_scan;             /* 07 BIOS device control */
2428       ushort scam_tolerant;         /* 08 no scam */
2429     
2430       uchar  adapter_scsi_id;       /* 09 Host Adapter ID */
2431       uchar  bios_boot_delay;       /*    power up wait */
2432     
2433       uchar  scsi_reset_delay;      /* 10 reset delay */
2434       uchar  bios_id_lun;           /*    first boot device scsi id & lun */
2435                                     /*    high nibble is lun */
2436                                     /*    low nibble is scsi id */
2437     
2438       uchar  termination_se;        /* 11 0 - automatic */
2439                                     /*    1 - low off / high off */
2440                                     /*    2 - low off / high on */
2441                                     /*    3 - low on  / high on */
2442                                     /*    There is no low on  / high off */
2443     
2444       uchar  termination_lvd;       /* 11 0 - automatic */
2445                                     /*    1 - low off / high off */
2446                                     /*    2 - low off / high on */
2447                                     /*    3 - low on  / high on */
2448                                     /*    There is no low on  / high off */
2449     
2450       ushort bios_ctrl;             /* 12 BIOS control bits */
2451                                     /*  bit 0  BIOS don't act as initiator. */
2452                                     /*  bit 1  BIOS > 1 GB support */
2453                                     /*  bit 2  BIOS > 2 Disk Support */
2454                                     /*  bit 3  BIOS don't support removables */
2455                                     /*  bit 4  BIOS support bootable CD */
2456                                     /*  bit 5  BIOS scan enabled */
2457                                     /*  bit 6  BIOS support multiple LUNs */
2458                                     /*  bit 7  BIOS display of message */
2459                                     /*  bit 8  SCAM disabled */
2460                                     /*  bit 9  Reset SCSI bus during init. */
2461                                     /*  bit 10 Basic Integrity Checking disabled */
2462                                     /*  bit 11 No verbose initialization. */
2463                                     /*  bit 12 SCSI parity enabled */
2464                                     /*  bit 13 AIPP (Asyn. Info. Ph. Prot.) dis. */
2465                                     /*  bit 14 */
2466                                     /*  bit 15 */
2467       ushort  sdtr_speed2;          /* 13 SDTR speed TID 4-7 */
2468       ushort  sdtr_speed3;          /* 14 SDTR speed TID 8-11 */
2469       uchar   max_host_qng;         /* 15 maximum host queueing */
2470       uchar   max_dvc_qng;          /*    maximum per device queuing */
2471       ushort  dvc_cntl;             /* 16 control bit for driver */
2472       ushort  sdtr_speed4;          /* 17 SDTR speed 4 TID 12-15 */
2473       ushort  serial_number_word1;  /* 18 Board serial number word 1 */
2474       ushort  serial_number_word2;  /* 19 Board serial number word 2 */
2475       ushort  serial_number_word3;  /* 20 Board serial number word 3 */
2476       ushort  check_sum;            /* 21 EEP check sum */
2477       uchar   oem_name[16];         /* 22 OEM name */
2478       ushort  dvc_err_code;         /* 30 last device driver error code */
2479       ushort  adv_err_code;         /* 31 last uc and Adv Lib error code */
2480       ushort  adv_err_addr;         /* 32 last uc error address */
2481       ushort  saved_dvc_err_code;   /* 33 saved last dev. driver error code   */
2482       ushort  saved_adv_err_code;   /* 34 saved last uc and Adv Lib error code */
2483       ushort  saved_adv_err_addr;   /* 35 saved last uc error address         */
2484       ushort  reserved36;           /* 36 reserved */
2485       ushort  reserved37;           /* 37 reserved */
2486       ushort  reserved38;           /* 38 reserved */
2487       ushort  reserved39;           /* 39 reserved */
2488       ushort  reserved40;           /* 40 reserved */
2489       ushort  reserved41;           /* 41 reserved */
2490       ushort  reserved42;           /* 42 reserved */
2491       ushort  reserved43;           /* 43 reserved */
2492       ushort  reserved44;           /* 44 reserved */
2493       ushort  reserved45;           /* 45 reserved */
2494       ushort  reserved46;           /* 46 reserved */
2495       ushort  reserved47;           /* 47 reserved */
2496       ushort  reserved48;           /* 48 reserved */
2497       ushort  reserved49;           /* 49 reserved */
2498       ushort  reserved50;           /* 50 reserved */
2499       ushort  reserved51;           /* 51 reserved */
2500       ushort  reserved52;           /* 52 reserved */
2501       ushort  reserved53;           /* 53 reserved */
2502       ushort  reserved54;           /* 54 reserved */
2503       ushort  reserved55;           /* 55 reserved */
2504       ushort  cisptr_lsw;           /* 56 CIS PTR LSW */
2505       ushort  cisprt_msw;           /* 57 CIS PTR MSW */
2506       ushort  subsysvid;            /* 58 SubSystem Vendor ID */
2507       ushort  subsysid;             /* 59 SubSystem ID */
2508       ushort  reserved60;           /* 60 reserved */
2509       ushort  reserved61;           /* 61 reserved */
2510       ushort  reserved62;           /* 62 reserved */
2511       ushort  reserved63;           /* 63 reserved */
2512     } ADVEEP_38C1600_CONFIG;
2513     
2514     /*
2515      * EEPROM Commands
2516      */
2517     #define ASC_EEP_CMD_DONE             0x0200
2518     #define ASC_EEP_CMD_DONE_ERR         0x0001
2519     
2520     /* cfg_word */
2521     #define EEP_CFG_WORD_BIG_ENDIAN      0x8000
2522     
2523     /* bios_ctrl */
2524     #define BIOS_CTRL_BIOS               0x0001
2525     #define BIOS_CTRL_EXTENDED_XLAT      0x0002
2526     #define BIOS_CTRL_GT_2_DISK          0x0004
2527     #define BIOS_CTRL_BIOS_REMOVABLE     0x0008
2528     #define BIOS_CTRL_BOOTABLE_CD        0x0010
2529     #define BIOS_CTRL_MULTIPLE_LUN       0x0040
2530     #define BIOS_CTRL_DISPLAY_MSG        0x0080
2531     #define BIOS_CTRL_NO_SCAM            0x0100
2532     #define BIOS_CTRL_RESET_SCSI_BUS     0x0200
2533     #define BIOS_CTRL_INIT_VERBOSE       0x0800
2534     #define BIOS_CTRL_SCSI_PARITY        0x1000
2535     #define BIOS_CTRL_AIPP_DIS           0x2000
2536     
2537     #define ADV_3550_MEMSIZE   0x2000       /* 8 KB Internal Memory */
2538     #define ADV_3550_IOLEN     0x40         /* I/O Port Range in bytes */
2539     
2540     #define ADV_38C0800_MEMSIZE  0x4000     /* 16 KB Internal Memory */
2541     #define ADV_38C0800_IOLEN    0x100      /* I/O Port Range in bytes */
2542     
2543     /*
2544      * XXX - Since ASC38C1600 Rev.3 has a local RAM failure issue, there is
2545      * a special 16K Adv Library and Microcode version. After the issue is
2546      * resolved, should restore 32K support.
2547      *
2548      * #define ADV_38C1600_MEMSIZE  0x8000L   * 32 KB Internal Memory *
2549      */
2550     #define ADV_38C1600_MEMSIZE  0x4000   /* 16 KB Internal Memory */
2551     #define ADV_38C1600_IOLEN    0x100     /* I/O Port Range 256 bytes */
2552     #define ADV_38C1600_MEMLEN   0x1000    /* Memory Range 4KB bytes */
2553     
2554     /*
2555      * Byte I/O register address from base of 'iop_base'.
2556      */
2557     #define IOPB_INTR_STATUS_REG    0x00
2558     #define IOPB_CHIP_ID_1          0x01
2559     #define IOPB_INTR_ENABLES       0x02
2560     #define IOPB_CHIP_TYPE_REV      0x03
2561     #define IOPB_RES_ADDR_4         0x04
2562     #define IOPB_RES_ADDR_5         0x05
2563     #define IOPB_RAM_DATA           0x06
2564     #define IOPB_RES_ADDR_7         0x07
2565     #define IOPB_FLAG_REG           0x08
2566     #define IOPB_RES_ADDR_9         0x09
2567     #define IOPB_RISC_CSR           0x0A
2568     #define IOPB_RES_ADDR_B         0x0B
2569     #define IOPB_RES_ADDR_C         0x0C
2570     #define IOPB_RES_ADDR_D         0x0D
2571     #define IOPB_SOFT_OVER_WR       0x0E
2572     #define IOPB_RES_ADDR_F         0x0F
2573     #define IOPB_MEM_CFG            0x10
2574     #define IOPB_RES_ADDR_11        0x11
2575     #define IOPB_GPIO_DATA          0x12
2576     #define IOPB_RES_ADDR_13        0x13
2577     #define IOPB_FLASH_PAGE         0x14
2578     #define IOPB_RES_ADDR_15        0x15
2579     #define IOPB_GPIO_CNTL          0x16
2580     #define IOPB_RES_ADDR_17        0x17
2581     #define IOPB_FLASH_DATA         0x18
2582     #define IOPB_RES_ADDR_19        0x19
2583     #define IOPB_RES_ADDR_1A        0x1A
2584     #define IOPB_RES_ADDR_1B        0x1B
2585     #define IOPB_RES_ADDR_1C        0x1C
2586     #define IOPB_RES_ADDR_1D        0x1D
2587     #define IOPB_RES_ADDR_1E        0x1E
2588     #define IOPB_RES_ADDR_1F        0x1F
2589     #define IOPB_DMA_CFG0           0x20
2590     #define IOPB_DMA_CFG1           0x21
2591     #define IOPB_TICKLE             0x22
2592     #define IOPB_DMA_REG_WR         0x23
2593     #define IOPB_SDMA_STATUS        0x24
2594     #define IOPB_SCSI_BYTE_CNT      0x25
2595     #define IOPB_HOST_BYTE_CNT      0x26
2596     #define IOPB_BYTE_LEFT_TO_XFER  0x27
2597     #define IOPB_BYTE_TO_XFER_0     0x28
2598     #define IOPB_BYTE_TO_XFER_1     0x29
2599     #define IOPB_BYTE_TO_XFER_2     0x2A
2600     #define IOPB_BYTE_TO_XFER_3     0x2B
2601     #define IOPB_ACC_GRP            0x2C
2602     #define IOPB_RES_ADDR_2D        0x2D
2603     #define IOPB_DEV_ID             0x2E
2604     #define IOPB_RES_ADDR_2F        0x2F
2605     #define IOPB_SCSI_DATA          0x30
2606     #define IOPB_RES_ADDR_31        0x31
2607     #define IOPB_RES_ADDR_32        0x32
2608     #define IOPB_SCSI_DATA_HSHK     0x33
2609     #define IOPB_SCSI_CTRL          0x34
2610     #define IOPB_RES_ADDR_35        0x35
2611     #define IOPB_RES_ADDR_36        0x36
2612     #define IOPB_RES_ADDR_37        0x37
2613     #define IOPB_RAM_BIST           0x38
2614     #define IOPB_PLL_TEST           0x39
2615     #define IOPB_PCI_INT_CFG        0x3A
2616     #define IOPB_RES_ADDR_3B        0x3B
2617     #define IOPB_RFIFO_CNT          0x3C
2618     #define IOPB_RES_ADDR_3D        0x3D
2619     #define IOPB_RES_ADDR_3E        0x3E
2620     #define IOPB_RES_ADDR_3F        0x3F
2621     
2622     /*
2623      * Word I/O register address from base of 'iop_base'.
2624      */
2625     #define IOPW_CHIP_ID_0          0x00  /* CID0  */
2626     #define IOPW_CTRL_REG           0x02  /* CC    */
2627     #define IOPW_RAM_ADDR           0x04  /* LA    */
2628     #define IOPW_RAM_DATA           0x06  /* LD    */
2629     #define IOPW_RES_ADDR_08        0x08
2630     #define IOPW_RISC_CSR           0x0A  /* CSR   */
2631     #define IOPW_SCSI_CFG0          0x0C  /* CFG0  */
2632     #define IOPW_SCSI_CFG1          0x0E  /* CFG1  */
2633     #define IOPW_RES_ADDR_10        0x10
2634     #define IOPW_SEL_MASK           0x12  /* SM    */
2635     #define IOPW_RES_ADDR_14        0x14
2636     #define IOPW_FLASH_ADDR         0x16  /* FA    */
2637     #define IOPW_RES_ADDR_18        0x18
2638     #define IOPW_EE_CMD             0x1A  /* EC    */
2639     #define IOPW_EE_DATA            0x1C  /* ED    */
2640     #define IOPW_SFIFO_CNT          0x1E  /* SFC   */
2641     #define IOPW_RES_ADDR_20        0x20
2642     #define IOPW_Q_BASE             0x22  /* QB    */
2643     #define IOPW_QP                 0x24  /* QP    */
2644     #define IOPW_IX                 0x26  /* IX    */
2645     #define IOPW_SP                 0x28  /* SP    */
2646     #define IOPW_PC                 0x2A  /* PC    */
2647     #define IOPW_RES_ADDR_2C        0x2C
2648     #define IOPW_RES_ADDR_2E        0x2E
2649     #define IOPW_SCSI_DATA          0x30  /* SD    */
2650     #define IOPW_SCSI_DATA_HSHK     0x32  /* SDH   */
2651     #define IOPW_SCSI_CTRL          0x34  /* SC    */
2652     #define IOPW_HSHK_CFG           0x36  /* HCFG  */
2653     #define IOPW_SXFR_STATUS        0x36  /* SXS   */
2654     #define IOPW_SXFR_CNTL          0x38  /* SXL   */
2655     #define IOPW_SXFR_CNTH          0x3A  /* SXH   */
2656     #define IOPW_RES_ADDR_3C        0x3C
2657     #define IOPW_RFIFO_DATA         0x3E  /* RFD   */
2658     
2659     /*
2660      * Doubleword I/O register address from base of 'iop_base'.
2661      */
2662     #define IOPDW_RES_ADDR_0         0x00
2663     #define IOPDW_RAM_DATA           0x04
2664     #define IOPDW_RES_ADDR_8         0x08
2665     #define IOPDW_RES_ADDR_C         0x0C
2666     #define IOPDW_RES_ADDR_10        0x10
2667     #define IOPDW_COMMA              0x14
2668     #define IOPDW_COMMB              0x18
2669     #define IOPDW_RES_ADDR_1C        0x1C
2670     #define IOPDW_SDMA_ADDR0         0x20
2671     #define IOPDW_SDMA_ADDR1         0x24
2672     #define IOPDW_SDMA_COUNT         0x28
2673     #define IOPDW_SDMA_ERROR         0x2C
2674     #define IOPDW_RDMA_ADDR0         0x30
2675     #define IOPDW_RDMA_ADDR1         0x34
2676     #define IOPDW_RDMA_COUNT         0x38
2677     #define IOPDW_RDMA_ERROR         0x3C
2678     
2679     #define ADV_CHIP_ID_BYTE         0x25
2680     #define ADV_CHIP_ID_WORD         0x04C1
2681     
2682     #define ADV_SC_SCSI_BUS_RESET    0x2000
2683     
2684     #define ADV_INTR_ENABLE_HOST_INTR                   0x01
2685     #define ADV_INTR_ENABLE_SEL_INTR                    0x02
2686     #define ADV_INTR_ENABLE_DPR_INTR                    0x04
2687     #define ADV_INTR_ENABLE_RTA_INTR                    0x08
2688     #define ADV_INTR_ENABLE_RMA_INTR                    0x10
2689     #define ADV_INTR_ENABLE_RST_INTR                    0x20
2690     #define ADV_INTR_ENABLE_DPE_INTR                    0x40
2691     #define ADV_INTR_ENABLE_GLOBAL_INTR                 0x80
2692     
2693     #define ADV_INTR_STATUS_INTRA            0x01
2694     #define ADV_INTR_STATUS_INTRB            0x02
2695     #define ADV_INTR_STATUS_INTRC            0x04
2696     
2697     #define ADV_RISC_CSR_STOP           (0x0000)
2698     #define ADV_RISC_TEST_COND          (0x2000)
2699     #define ADV_RISC_CSR_RUN            (0x4000)
2700     #define ADV_RISC_CSR_SINGLE_STEP    (0x8000)
2701     
2702     #define ADV_CTRL_REG_HOST_INTR      0x0100
2703     #define ADV_CTRL_REG_SEL_INTR       0x0200
2704     #define ADV_CTRL_REG_DPR_INTR       0x0400
2705     #define ADV_CTRL_REG_RTA_INTR       0x0800
2706     #define ADV_CTRL_REG_RMA_INTR       0x1000
2707     #define ADV_CTRL_REG_RES_BIT14      0x2000
2708     #define ADV_CTRL_REG_DPE_INTR       0x4000
2709     #define ADV_CTRL_REG_POWER_DONE     0x8000
2710     #define ADV_CTRL_REG_ANY_INTR       0xFF00
2711     
2712     #define ADV_CTRL_REG_CMD_RESET             0x00C6
2713     #define ADV_CTRL_REG_CMD_WR_IO_REG         0x00C5
2714     #define ADV_CTRL_REG_CMD_RD_IO_REG         0x00C4
2715     #define ADV_CTRL_REG_CMD_WR_PCI_CFG_SPACE  0x00C3
2716     #define ADV_CTRL_REG_CMD_RD_PCI_CFG_SPACE  0x00C2
2717     
2718     #define ADV_TICKLE_NOP                      0x00
2719     #define ADV_TICKLE_A                        0x01
2720     #define ADV_TICKLE_B                        0x02
2721     #define ADV_TICKLE_C                        0x03
2722     
2723     #define ADV_SCSI_CTRL_RSTOUT        0x2000
2724     
2725     #define AdvIsIntPending(port) \
2726         (AdvReadWordRegister(port, IOPW_CTRL_REG) & ADV_CTRL_REG_HOST_INTR)
2727     
2728     /*
2729      * SCSI_CFG0 Register bit definitions
2730      */
2731     #define TIMER_MODEAB    0xC000  /* Watchdog, Second, and Select. Timer Ctrl. */
2732     #define PARITY_EN       0x2000  /* Enable SCSI Parity Error detection */
2733     #define EVEN_PARITY     0x1000  /* Select Even Parity */
2734     #define WD_LONG         0x0800  /* Watchdog Interval, 1: 57 min, 0: 13 sec */
2735     #define QUEUE_128       0x0400  /* Queue Size, 1: 128 byte, 0: 64 byte */
2736     #define PRIM_MODE       0x0100  /* Primitive SCSI mode */
2737     #define SCAM_EN         0x0080  /* Enable SCAM selection */
2738     #define SEL_TMO_LONG    0x0040  /* Sel/Resel Timeout, 1: 400 ms, 0: 1.6 ms */
2739     #define CFRM_ID         0x0020  /* SCAM id sel. confirm., 1: fast, 0: 6.4 ms */
2740     #define OUR_ID_EN       0x0010  /* Enable OUR_ID bits */
2741     #define OUR_ID          0x000F  /* SCSI ID */
2742     
2743     /*
2744      * SCSI_CFG1 Register bit definitions
2745      */
2746     #define BIG_ENDIAN      0x8000  /* Enable Big Endian Mode MIO:15, EEP:15 */
2747     #define TERM_POL        0x2000  /* Terminator Polarity Ctrl. MIO:13, EEP:13 */
2748     #define SLEW_RATE       0x1000  /* SCSI output buffer slew rate */
2749     #define FILTER_SEL      0x0C00  /* Filter Period Selection */
2750     #define  FLTR_DISABLE    0x0000  /* Input Filtering Disabled */
2751     #define  FLTR_11_TO_20NS 0x0800  /* Input Filtering 11ns to 20ns */
2752     #define  FLTR_21_TO_39NS 0x0C00  /* Input Filtering 21ns to 39ns */
2753     #define ACTIVE_DBL      0x0200  /* Disable Active Negation */
2754     #define DIFF_MODE       0x0100  /* SCSI differential Mode (Read-Only) */
2755     #define DIFF_SENSE      0x0080  /* 1: No SE cables, 0: SE cable (Read-Only) */
2756     #define TERM_CTL_SEL    0x0040  /* Enable TERM_CTL_H and TERM_CTL_L */
2757     #define TERM_CTL        0x0030  /* External SCSI Termination Bits */
2758     #define  TERM_CTL_H      0x0020  /* Enable External SCSI Upper Termination */
2759     #define  TERM_CTL_L      0x0010  /* Enable External SCSI Lower Termination */
2760     #define CABLE_DETECT    0x000F  /* External SCSI Cable Connection Status */
2761     
2762     /*
2763      * Addendum for ASC-38C0800 Chip
2764      *
2765      * The ASC-38C1600 Chip uses the same definitions except that the
2766      * bus mode override bits [12:10] have been moved to byte register
2767      * offset 0xE (IOPB_SOFT_OVER_WR) bits [12:10]. The [12:10] bits in
2768      * SCSI_CFG1 are read-only and always available. Bit 14 (DIS_TERM_DRV)
2769      * is not needed. The [12:10] bits in IOPB_SOFT_OVER_WR are write-only.
2770      * Also each ASC-38C1600 function or channel uses only cable bits [5:4]
2771      * and [1:0]. Bits [14], [7:6], [3:2] are unused.
2772      */
2773     #define DIS_TERM_DRV    0x4000  /* 1: Read c_det[3:0], 0: cannot read */
2774     #define HVD_LVD_SE      0x1C00  /* Device Detect Bits */
2775     #define  HVD             0x1000  /* HVD Device Detect */
2776     #define  LVD             0x0800  /* LVD Device Detect */
2777     #define  SE              0x0400  /* SE Device Detect */
2778     #define TERM_LVD        0x00C0  /* LVD Termination Bits */
2779     #define  TERM_LVD_HI     0x0080  /* Enable LVD Upper Termination */
2780     #define  TERM_LVD_LO     0x0040  /* Enable LVD Lower Termination */
2781     #define TERM_SE         0x0030  /* SE Termination Bits */
2782     #define  TERM_SE_HI      0x0020  /* Enable SE Upper Termination */
2783     #define  TERM_SE_LO      0x0010  /* Enable SE Lower Termination */
2784     #define C_DET_LVD       0x000C  /* LVD Cable Detect Bits */
2785     #define  C_DET3          0x0008  /* Cable Detect for LVD External Wide */
2786     #define  C_DET2          0x0004  /* Cable Detect for LVD Internal Wide */
2787     #define C_DET_SE        0x0003  /* SE Cable Detect Bits */
2788     #define  C_DET1          0x0002  /* Cable Detect for SE Internal Wide */
2789     #define  C_DET0          0x0001  /* Cable Detect for SE Internal Narrow */
2790     
2791     
2792     #define CABLE_ILLEGAL_A 0x7
2793         /* x 0 0 0  | on  on | Illegal (all 3 connectors are used) */
2794     
2795     #define CABLE_ILLEGAL_B 0xB
2796         /* 0 x 0 0  | on  on | Illegal (all 3 connectors are used) */
2797     
2798     /*
2799      * MEM_CFG Register bit definitions
2800      */
2801     #define BIOS_EN         0x40    /* BIOS Enable MIO:14,EEP:14 */
2802     #define FAST_EE_CLK     0x20    /* Diagnostic Bit */
2803     #define RAM_SZ          0x1C    /* Specify size of RAM to RISC */
2804     #define  RAM_SZ_2KB      0x00    /* 2 KB */
2805     #define  RAM_SZ_4KB      0x04    /* 4 KB */
2806     #define  RAM_SZ_8KB      0x08    /* 8 KB */
2807     #define  RAM_SZ_16KB     0x0C    /* 16 KB */
2808     #define  RAM_SZ_32KB     0x10    /* 32 KB */
2809     #define  RAM_SZ_64KB     0x14    /* 64 KB */
2810     
2811     /*
2812      * DMA_CFG0 Register bit definitions
2813      *
2814      * This register is only accessible to the host.
2815      */
2816     #define BC_THRESH_ENB   0x80    /* PCI DMA Start Conditions */
2817     #define FIFO_THRESH     0x70    /* PCI DMA FIFO Threshold */
2818     #define  FIFO_THRESH_16B  0x00   /* 16 bytes */
2819     #define  FIFO_THRESH_32B  0x20   /* 32 bytes */
2820     #define  FIFO_THRESH_48B  0x30   /* 48 bytes */
2821     #define  FIFO_THRESH_64B  0x40   /* 64 bytes */
2822     #define  FIFO_THRESH_80B  0x50   /* 80 bytes (default) */
2823     #define  FIFO_THRESH_96B  0x60   /* 96 bytes */
2824     #define  FIFO_THRESH_112B 0x70   /* 112 bytes */
2825     #define START_CTL       0x0C    /* DMA start conditions */
2826     #define  START_CTL_TH    0x00    /* Wait threshold level (default) */
2827     #define  START_CTL_ID    0x04    /* Wait SDMA/SBUS idle */
2828     #define  START_CTL_THID  0x08    /* Wait threshold and SDMA/SBUS idle */
2829     #define  START_CTL_EMFU  0x0C    /* Wait SDMA FIFO empty/full */
2830     #define READ_CMD        0x03    /* Memory Read Method */
2831     #define  READ_CMD_MR     0x00    /* Memory Read */
2832     #define  READ_CMD_MRL    0x02    /* Memory Read Long */
2833     #define  READ_CMD_MRM    0x03    /* Memory Read Multiple (default) */
2834     
2835     /*
2836      * ASC-38C0800 RAM BIST Register bit definitions
2837      */
2838     #define RAM_TEST_MODE         0x80
2839     #define PRE_TEST_MODE         0x40
2840     #define NORMAL_MODE           0x00
2841     #define RAM_TEST_DONE         0x10
2842     #define RAM_TEST_STATUS       0x0F
2843     #define  RAM_TEST_HOST_ERROR   0x08
2844     #define  RAM_TEST_INTRAM_ERROR 0x04
2845     #define  RAM_TEST_RISC_ERROR   0x02
2846     #define  RAM_TEST_SCSI_ERROR   0x01
2847     #define  RAM_TEST_SUCCESS      0x00
2848     #define PRE_TEST_VALUE        0x05
2849     #define NORMAL_VALUE          0x00
2850     
2851     /*
2852      * ASC38C1600 Definitions
2853      *
2854      * IOPB_PCI_INT_CFG Bit Field Definitions
2855      */
2856     
2857     #define INTAB_LD        0x80    /* Value loaded from EEPROM Bit 11. */
2858     
2859     /*
2860      * Bit 1 can be set to change the interrupt for the Function to operate in
2861      * Totem Pole mode. By default Bit 1 is 0 and the interrupt operates in
2862      * Open Drain mode. Both functions of the ASC38C1600 must be set to the same
2863      * mode, otherwise the operating mode is undefined.
2864      */
2865     #define TOTEMPOLE       0x02
2866     
2867     /*
2868      * Bit 0 can be used to change the Int Pin for the Function. The value is
2869      * 0 by default for both Functions with Function 0 using INT A and Function
2870      * B using INT B. For Function 0 if set, INT B is used. For Function 1 if set,
2871      * INT A is used.
2872      *
2873      * EEPROM Word 0 Bit 11 for each Function may change the initial Int Pin
2874      * value specified in the PCI Configuration Space.
2875      */
2876     #define INTAB           0x01
2877     
2878     /* a_advlib.h */
2879     
2880     /*
2881      * Adv Library Status Definitions
2882      */
2883     #define ADV_TRUE        1
2884     #define ADV_FALSE       0
2885     #define ADV_NOERROR     1
2886     #define ADV_SUCCESS     1
2887     #define ADV_BUSY        0
2888     #define ADV_ERROR       (-1)
2889     
2890     
2891     /*
2892      * ADV_DVC_VAR 'warn_code' values
2893      */
2894     #define ASC_WARN_BUSRESET_ERROR         0x0001 /* SCSI Bus Reset error */
2895     #define ASC_WARN_EEPROM_CHKSUM          0x0002 /* EEP check sum error */
2896     #define ASC_WARN_EEPROM_TERMINATION     0x0004 /* EEP termination bad field */
2897     #define ASC_WARN_SET_PCI_CONFIG_SPACE   0x0080 /* PCI config space set error */
2898     #define ASC_WARN_ERROR                  0xFFFF /* ADV_ERROR return */
2899     
2900     #define ADV_MAX_TID                     15 /* max. target identifier */
2901     #define ADV_MAX_LUN                     7  /* max. logical unit number */
2902     
2903     /*
2904      * Error code values are set in ADV_DVC_VAR 'err_code'.
2905      */
2906     #define ASC_IERR_WRITE_EEPROM       0x0001 /* write EEPROM error */
2907     #define ASC_IERR_MCODE_CHKSUM       0x0002 /* micro code check sum error */
2908     #define ASC_IERR_NO_CARRIER         0x0004 /* No more carrier memory. */
2909     #define ASC_IERR_START_STOP_CHIP    0x0008 /* start/stop chip failed */
2910     #define ASC_IERR_CHIP_VERSION       0x0040 /* wrong chip version */
2911     #define ASC_IERR_SET_SCSI_ID        0x0080 /* set SCSI ID failed */
2912     #define ASC_IERR_HVD_DEVICE         0x0100 /* HVD attached to LVD connector. */
2913     #define ASC_IERR_BAD_SIGNATURE      0x0200 /* signature not found */
2914     #define ASC_IERR_ILLEGAL_CONNECTION 0x0400 /* Illegal cable connection */
2915     #define ASC_IERR_SINGLE_END_DEVICE  0x0800 /* Single-end used w/differential */
2916     #define ASC_IERR_REVERSED_CABLE     0x1000 /* Narrow flat cable reversed */
2917     #define ASC_IERR_BIST_PRE_TEST      0x2000 /* BIST pre-test error */
2918     #define ASC_IERR_BIST_RAM_TEST      0x4000 /* BIST RAM test error */
2919     #define ASC_IERR_BAD_CHIPTYPE       0x8000 /* Invalid 'chip_type' setting. */
2920     
2921     /*
2922      * Fixed locations of microcode operating variables.
2923      */
2924     #define ASC_MC_CODE_BEGIN_ADDR          0x0028 /* microcode start address */
2925     #define ASC_MC_CODE_END_ADDR            0x002A /* microcode end address */
2926     #define ASC_MC_CODE_CHK_SUM             0x002C /* microcode code checksum */
2927     #define ASC_MC_VERSION_DATE             0x0038 /* microcode version */
2928     #define ASC_MC_VERSION_NUM              0x003A /* microcode number */
2929     #define ASC_MC_BIOSMEM                  0x0040 /* BIOS RISC Memory Start */
2930     #define ASC_MC_BIOSLEN                  0x0050 /* BIOS RISC Memory Length */
2931     #define ASC_MC_BIOS_SIGNATURE           0x0058 /* BIOS Signature 0x55AA */
2932     #define ASC_MC_BIOS_VERSION             0x005A /* BIOS Version (2 bytes) */
2933     #define ASC_MC_SDTR_SPEED1              0x0090 /* SDTR Speed for TID 0-3 */
2934     #define ASC_MC_SDTR_SPEED2              0x0092 /* SDTR Speed for TID 4-7 */
2935     #define ASC_MC_SDTR_SPEED3              0x0094 /* SDTR Speed for TID 8-11 */
2936     #define ASC_MC_SDTR_SPEED4              0x0096 /* SDTR Speed for TID 12-15 */
2937     #define ASC_MC_CHIP_TYPE                0x009A
2938     #define ASC_MC_INTRB_CODE               0x009B
2939     #define ASC_MC_WDTR_ABLE                0x009C
2940     #define ASC_MC_SDTR_ABLE                0x009E
2941     #define ASC_MC_TAGQNG_ABLE              0x00A0
2942     #define ASC_MC_DISC_ENABLE              0x00A2
2943     #define ASC_MC_IDLE_CMD_STATUS          0x00A4
2944     #define ASC_MC_IDLE_CMD                 0x00A6
2945     #define ASC_MC_IDLE_CMD_PARAMETER       0x00A8
2946     #define ASC_MC_DEFAULT_SCSI_CFG0        0x00AC
2947     #define ASC_MC_DEFAULT_SCSI_CFG1        0x00AE
2948     #define ASC_MC_DEFAULT_MEM_CFG          0x00B0
2949     #define ASC_MC_DEFAULT_SEL_MASK         0x00B2
2950     #define ASC_MC_SDTR_DONE                0x00B6
2951     #define ASC_MC_NUMBER_OF_QUEUED_CMD     0x00C0
2952     #define ASC_MC_NUMBER_OF_MAX_CMD        0x00D0
2953     #define ASC_MC_DEVICE_HSHK_CFG_TABLE    0x0100
2954     #define ASC_MC_CONTROL_FLAG             0x0122 /* Microcode control flag. */
2955     #define ASC_MC_WDTR_DONE                0x0124
2956     #define ASC_MC_CAM_MODE_MASK            0x015E /* CAM mode TID bitmask. */
2957     #define ASC_MC_ICQ                      0x0160
2958     #define ASC_MC_IRQ                      0x0164
2959     #define ASC_MC_PPR_ABLE                 0x017A
2960     
2961     /*
2962      * BIOS LRAM variable absolute offsets.
2963      */
2964     #define BIOS_CODESEG    0x54
2965     #define BIOS_CODELEN    0x56
2966     #define BIOS_SIGNATURE  0x58
2967     #define BIOS_VERSION    0x5A
2968     
2969     /*
2970      * Microcode Control Flags
2971      *
2972      * Flags set by the Adv Library in RISC variable 'control_flag' (0x122)
2973      * and handled by the microcode.
2974      */
2975     #define CONTROL_FLAG_IGNORE_PERR        0x0001 /* Ignore DMA Parity Errors */
2976     #define CONTROL_FLAG_ENABLE_AIPP        0x0002 /* Enabled AIPP checking. */
2977     
2978     /*
2979      * ASC_MC_DEVICE_HSHK_CFG_TABLE microcode table or HSHK_CFG register format
2980      */
2981     #define HSHK_CFG_WIDE_XFR       0x8000
2982     #define HSHK_CFG_RATE           0x0F00
2983     #define HSHK_CFG_OFFSET         0x001F
2984     
2985     #define ASC_DEF_MAX_HOST_QNG    0xFD /* Max. number of host commands (253) */
2986     #define ASC_DEF_MIN_HOST_QNG    0x10 /* Min. number of host commands (16) */
2987     #define ASC_DEF_MAX_DVC_QNG     0x3F /* Max. number commands per device (63) */
2988     #define ASC_DEF_MIN_DVC_QNG     0x04 /* Min. number commands per device (4) */
2989     
2990     #define ASC_QC_DATA_CHECK  0x01 /* Require ASC_QC_DATA_OUT set or clear. */
2991     #define ASC_QC_DATA_OUT    0x02 /* Data out DMA transfer. */
2992     #define ASC_QC_START_MOTOR 0x04 /* Send auto-start motor before request. */
2993     #define ASC_QC_NO_OVERRUN  0x08 /* Don't report overrun. */
2994     #define ASC_QC_FREEZE_TIDQ 0x10 /* Freeze TID queue after request. XXX TBD */
2995     
2996     #define ASC_QSC_NO_DISC     0x01 /* Don't allow disconnect for request. */
2997     #define ASC_QSC_NO_TAGMSG   0x02 /* Don't allow tag queuing for request. */
2998     #define ASC_QSC_NO_SYNC     0x04 /* Don't use Synch. transfer on request. */
2999     #define ASC_QSC_NO_WIDE     0x08 /* Don't use Wide transfer on request. */
3000     #define ASC_QSC_REDO_DTR    0x10 /* Renegotiate WDTR/SDTR before request. */
3001     /*
3002      * Note: If a Tag Message is to be sent and neither ASC_QSC_HEAD_TAG or
3003      * ASC_QSC_ORDERED_TAG is set, then a Simple Tag Message (0x20) is used.
3004      */
3005     #define ASC_QSC_HEAD_TAG    0x40 /* Use Head Tag Message (0x21). */
3006     #define ASC_QSC_ORDERED_TAG 0x80 /* Use Ordered Tag Message (0x22). */
3007     
3008     /*
3009      * All fields here are accessed by the board microcode and need to be
3010      * little-endian.
3011      */
3012     typedef struct adv_carr_t
3013     {
3014         ADV_VADDR   carr_va;       /* Carrier Virtual Address */
3015         ADV_PADDR   carr_pa;       /* Carrier Physical Address */
3016         ADV_VADDR   areq_vpa;      /* ASC_SCSI_REQ_Q Virtual or Physical Address */
3017         /*
3018          * next_vpa [31:4]            Carrier Virtual or Physical Next Pointer
3019          *
3020          * next_vpa [3:1]             Reserved Bits
3021          * next_vpa [0]               Done Flag set in Response Queue.
3022          */
3023         ADV_VADDR   next_vpa;
3024     } ADV_CARR_T;
3025     
3026     /*
3027      * Mask used to eliminate low 4 bits of carrier 'next_vpa' field.
3028      */
3029     #define ASC_NEXT_VPA_MASK       0xFFFFFFF0
3030     
3031     #define ASC_RQ_DONE             0x00000001
3032     #define ASC_RQ_GOOD             0x00000002
3033     #define ASC_CQ_STOPPER          0x00000000
3034     
3035     #define ASC_GET_CARRP(carrp) ((carrp) & ASC_NEXT_VPA_MASK)
3036     
3037     #define ADV_CARRIER_NUM_PAGE_CROSSING \
3038         (((ADV_CARRIER_COUNT * sizeof(ADV_CARR_T)) + \
3039             (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
3040     
3041     #define ADV_CARRIER_BUFSIZE \
3042         ((ADV_CARRIER_COUNT + ADV_CARRIER_NUM_PAGE_CROSSING) * sizeof(ADV_CARR_T))
3043     
3044     /*
3045      * ASC_SCSI_REQ_Q 'a_flag' definitions
3046      *
3047      * The Adv Library should limit use to the lower nibble (4 bits) of
3048      * a_flag. Drivers are free to use the upper nibble (4 bits) of a_flag.
3049      */
3050     #define ADV_POLL_REQUEST                0x01   /* poll for request completion */
3051     #define ADV_SCSIQ_DONE                  0x02   /* request done */
3052     #define ADV_DONT_RETRY                  0x08   /* don't do retry */
3053     
3054     #define ADV_CHIP_ASC3550          0x01   /* Ultra-Wide IC */
3055     #define ADV_CHIP_ASC38C0800       0x02   /* Ultra2-Wide/LVD IC */
3056     #define ADV_CHIP_ASC38C1600       0x03   /* Ultra3-Wide/LVD2 IC */
3057     
3058     /*
3059      * Adapter temporary configuration structure
3060      *
3061      * This structure can be discarded after initialization. Don't add
3062      * fields here needed after initialization.
3063      *
3064      * Field naming convention:
3065      *
3066      *  *_enable indicates the field enables or disables a feature. The
3067      *  value of the field is never reset.
3068      */
3069     typedef struct adv_dvc_cfg {
3070       ushort disc_enable;       /* enable disconnection */
3071       uchar  chip_version;      /* chip version */
3072       uchar  termination;       /* Term. Ctrl. bits 6-5 of SCSI_CFG1 register */
3073       ushort pci_device_id;     /* PCI device code number */
3074       ushort lib_version;       /* Adv Library version number */
3075       ushort control_flag;      /* Microcode Control Flag */
3076       ushort mcode_date;        /* Microcode date */
3077       ushort mcode_version;     /* Microcode version */
3078       ushort pci_slot_info;     /* high byte device/function number */
3079                                 /* bits 7-3 device num., bits 2-0 function num. */
3080                                 /* low byte bus num. */
3081       ushort serial1;           /* EEPROM serial number word 1 */
3082       ushort serial2;           /* EEPROM serial number word 2 */
3083       ushort serial3;           /* EEPROM serial number word 3 */
3084     } ADV_DVC_CFG;
3085     
3086     struct adv_dvc_var;
3087     struct adv_scsi_req_q;
3088     
3089     typedef void (* ADV_ISR_CALLBACK)
3090         (struct adv_dvc_var *, struct adv_scsi_req_q *);
3091     
3092     typedef void (* ADV_ASYNC_CALLBACK)
3093         (struct adv_dvc_var *, uchar);
3094     
3095     /*
3096      * Adapter operation variable structure.
3097      *
3098      * One structure is required per host adapter.
3099      *
3100      * Field naming convention:
3101      *
3102      *  *_able indicates both whether a feature should be enabled or disabled
3103      *  and whether a device isi capable of the feature. At initialization
3104      *  this field may be set, but later if a device is found to be incapable
3105      *  of the feature, the field is cleared.
3106      */
3107     typedef struct adv_dvc_var {
3108       AdvPortAddr iop_base;   /* I/O port address */
3109       ushort err_code;        /* fatal error code */
3110       ushort bios_ctrl;       /* BIOS control word, EEPROM word 12 */
3111       ADV_ISR_CALLBACK isr_callback;
3112       ADV_ASYNC_CALLBACK async_callback;
3113       ushort wdtr_able;       /* try WDTR for a device */
3114       ushort sdtr_able;       /* try SDTR for a device */
3115       ushort ultra_able;      /* try SDTR Ultra speed for a device */
3116       ushort sdtr_speed1;     /* EEPROM SDTR Speed for TID 0-3   */
3117       ushort sdtr_speed2;     /* EEPROM SDTR Speed for TID 4-7   */
3118       ushort sdtr_speed3;     /* EEPROM SDTR Speed for TID 8-11  */
3119       ushort sdtr_speed4;     /* EEPROM SDTR Speed for TID 12-15 */
3120       ushort tagqng_able;     /* try tagged queuing with a device */
3121       ushort ppr_able;        /* PPR message capable per TID bitmask. */
3122       uchar  max_dvc_qng;     /* maximum number of tagged commands per device */
3123       ushort start_motor;     /* start motor command allowed */
3124       uchar  scsi_reset_wait; /* delay in seconds after scsi bus reset */
3125       uchar  chip_no;         /* should be assigned by caller */
3126       uchar  max_host_qng;    /* maximum number of Q'ed command allowed */
3127       uchar  irq_no;          /* IRQ number */
3128       ushort no_scam;         /* scam_tolerant of EEPROM */
3129       struct asc_board *drv_ptr; /* driver pointer to private structure */
3130       uchar  chip_scsi_id;    /* chip SCSI target ID */
3131       uchar  chip_type;
3132       uchar  bist_err_code;
3133       ADV_CARR_T *carrier_buf;
3134       ADV_CARR_T *carr_freelist; /* Carrier free list. */
3135       ADV_CARR_T *icq_sp;  /* Initiator command queue stopper pointer. */
3136       ADV_CARR_T *irq_sp;  /* Initiator response queue stopper pointer. */
3137       ushort carr_pending_cnt;    /* Count of pending carriers. */
3138      /*
3139       * Note: The following fields will not be used after initialization. The
3140       * driver may discard the buffer after initialization is done.
3141       */
3142       ADV_DVC_CFG *cfg; /* temporary configuration structure  */
3143     } ADV_DVC_VAR;
3144     
3145     #define NO_OF_SG_PER_BLOCK              15
3146     
3147     typedef struct asc_sg_block {
3148         uchar reserved1;
3149         uchar reserved2;
3150         uchar reserved3;
3151         uchar sg_cnt;                     /* Valid entries in block. */
3152         ADV_PADDR sg_ptr;                 /* Pointer to next sg block. */
3153         struct  {
3154             ADV_PADDR sg_addr;                  /* SG element address. */
3155             ADV_DCNT  sg_count;                 /* SG element count. */
3156         } sg_list[NO_OF_SG_PER_BLOCK];
3157     } ADV_SG_BLOCK;
3158     
3159     /*
3160      * ADV_SCSI_REQ_Q - microcode request structure
3161      *
3162      * All fields in this structure up to byte 60 are used by the microcode.
3163      * The microcode makes assumptions about the size and ordering of fields
3164      * in this structure. Do not change the structure definition here without
3165      * coordinating the change with the microcode.
3166      *
3167      * All fields accessed by microcode must be maintained in little_endian
3168      * order.
3169      */
3170     typedef struct adv_scsi_req_q {
3171         uchar       cntl;           /* Ucode flags and state (ASC_MC_QC_*). */
3172         uchar       target_cmd;
3173         uchar       target_id;      /* Device target identifier. */
3174         uchar       target_lun;     /* Device target logical unit number. */
3175         ADV_PADDR   data_addr;      /* Data buffer physical address. */
3176         ADV_DCNT    data_cnt;       /* Data count. Ucode sets to residual. */
3177         ADV_PADDR   sense_addr;
3178         ADV_PADDR   carr_pa;
3179         uchar       mflag;
3180         uchar       sense_len;
3181         uchar       cdb_len;        /* SCSI CDB length. Must <= 16 bytes. */
3182         uchar       scsi_cntl;
3183         uchar       done_status;    /* Completion status. */
3184         uchar       scsi_status;    /* SCSI status byte. */
3185         uchar       host_status;    /* Ucode host status. */
3186         uchar       sg_working_ix;
3187         uchar       cdb[12];        /* SCSI CDB bytes 0-11. */
3188         ADV_PADDR   sg_real_addr;   /* SG list physical address. */
3189         ADV_PADDR   scsiq_rptr;
3190         uchar       cdb16[4];       /* SCSI CDB bytes 12-15. */
3191         ADV_VADDR   scsiq_ptr;
3192         ADV_VADDR   carr_va;
3193         /*
3194          * End of microcode structure - 60 bytes. The rest of the structure
3195          * is used by the Adv Library and ignored by the microcode.
3196          */
3197         ADV_VADDR   srb_ptr;
3198         ADV_SG_BLOCK *sg_list_ptr; /* SG list virtual address. */
3199         char        *vdata_addr;   /* Data buffer virtual address. */
3200         uchar       a_flag;
3201         uchar       pad[2];        /* Pad out to a word boundary. */
3202     } ADV_SCSI_REQ_Q;
3203     
3204     /*
3205      * Microcode idle loop commands
3206      */
3207     #define IDLE_CMD_COMPLETED           0
3208     #define IDLE_CMD_STOP_CHIP           0x0001
3209     #define IDLE_CMD_STOP_CHIP_SEND_INT  0x0002
3210     #define IDLE_CMD_SEND_INT            0x0004
3211     #define IDLE_CMD_ABORT               0x0008
3212     #define IDLE_CMD_DEVICE_RESET        0x0010
3213     #define IDLE_CMD_SCSI_RESET_START    0x0020 /* Assert SCSI Bus Reset */
3214     #define IDLE_CMD_SCSI_RESET_END      0x0040 /* Deassert SCSI Bus Reset */
3215     #define IDLE_CMD_SCSIREQ             0x0080
3216     
3217     #define IDLE_CMD_STATUS_SUCCESS      0x0001
3218     #define IDLE_CMD_STATUS_FAILURE      0x0002
3219     
3220     /*
3221      * AdvSendIdleCmd() flag definitions.
3222      */
3223     #define ADV_NOWAIT     0x01
3224     
3225     /*
3226      * Wait loop time out values.
3227      */
3228     #define SCSI_WAIT_10_SEC             10UL    /* 10 seconds */
3229     #define SCSI_WAIT_100_MSEC           100UL   /* 100 milliseconds */
3230     #define SCSI_US_PER_MSEC             1000    /* microseconds per millisecond */
3231     #define SCSI_MS_PER_SEC              1000UL  /* milliseconds per second */
3232     #define SCSI_MAX_RETRY               10      /* retry count */
3233     
3234     #define ADV_ASYNC_RDMA_FAILURE          0x01 /* Fatal RDMA failure. */
3235     #define ADV_ASYNC_SCSI_BUS_RESET_DET    0x02 /* Detected SCSI Bus Reset. */
3236     #define ADV_ASYNC_CARRIER_READY_FAILURE 0x03 /* Carrier Ready failure. */
3237     #define ADV_RDMA_IN_CARR_AND_Q_INVALID  0x04 /* RDMAed-in data invalid. */
3238     
3239     
3240     #define ADV_HOST_SCSI_BUS_RESET      0x80 /* Host Initiated SCSI Bus Reset. */
3241     
3242     /*
3243      * Device drivers must define the following functions.
3244      */
3245     STATIC inline ulong DvcEnterCritical(void);
3246     STATIC inline void  DvcLeaveCritical(ulong);
3247     STATIC void  DvcSleepMilliSecond(ADV_DCNT);
3248     STATIC uchar DvcAdvReadPCIConfigByte(ADV_DVC_VAR *, ushort);
3249     STATIC void  DvcAdvWritePCIConfigByte(ADV_DVC_VAR *, ushort, uchar);
3250     STATIC ADV_PADDR DvcGetPhyAddr(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *,
3251                     uchar *, ASC_SDCNT *, int);
3252     STATIC void  DvcDelayMicroSecond(ADV_DVC_VAR *, ushort);
3253     
3254     /*
3255      * Adv Library functions available to drivers.
3256      */
3257     STATIC int     AdvExeScsiQueue(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
3258     STATIC int     AdvISR(ADV_DVC_VAR *);
3259     STATIC int     AdvInitGetConfig(ADV_DVC_VAR *);
3260     STATIC int     AdvInitAsc3550Driver(ADV_DVC_VAR *);
3261     STATIC int     AdvInitAsc38C0800Driver(ADV_DVC_VAR *);
3262     STATIC int     AdvInitAsc38C1600Driver(ADV_DVC_VAR *);
3263     STATIC int     AdvResetChipAndSB(ADV_DVC_VAR *);
3264     STATIC int     AdvResetSB(ADV_DVC_VAR *asc_dvc);
3265     
3266     /*
3267      * Internal Adv Library functions.
3268      */
3269     STATIC int    AdvSendIdleCmd(ADV_DVC_VAR *, ushort, ADV_DCNT);
3270     STATIC void   AdvInquiryHandling(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
3271     STATIC int    AdvInitFrom3550EEP(ADV_DVC_VAR *);
3272     STATIC int    AdvInitFrom38C0800EEP(ADV_DVC_VAR *);
3273     STATIC int    AdvInitFrom38C1600EEP(ADV_DVC_VAR *);
3274     STATIC ushort AdvGet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *);
3275     STATIC void   AdvSet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *);
3276     STATIC ushort AdvGet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *);
3277     STATIC void   AdvSet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *);
3278     STATIC ushort AdvGet38C1600EEPConfig(AdvPortAddr, ADVEEP_38C1600_CONFIG *);
3279     STATIC void   AdvSet38C1600EEPConfig(AdvPortAddr, ADVEEP_38C1600_CONFIG *);
3280     STATIC void   AdvWaitEEPCmd(AdvPortAddr);
3281     STATIC ushort AdvReadEEPWord(AdvPortAddr, int);
3282     
3283     /*
3284      * PCI Bus Definitions
3285      */
3286     #define AscPCICmdRegBits_BusMastering     0x0007
3287     #define AscPCICmdRegBits_ParErrRespCtrl   0x0040
3288     
3289     /* Read byte from a register. */
3290     #define AdvReadByteRegister(iop_base, reg_off) \
3291          (ADV_MEM_READB((iop_base) + (reg_off)))
3292     
3293     /* Write byte to a register. */
3294     #define AdvWriteByteRegister(iop_base, reg_off, byte) \
3295          (ADV_MEM_WRITEB((iop_base) + (reg_off), (byte)))
3296     
3297     /* Read word (2 bytes) from a register. */
3298     #define AdvReadWordRegister(iop_base, reg_off) \
3299          (ADV_MEM_READW((iop_base) + (reg_off)))
3300     
3301     /* Write word (2 bytes) to a register. */
3302     #define AdvWriteWordRegister(iop_base, reg_off, word) \
3303          (ADV_MEM_WRITEW((iop_base) + (reg_off), (word)))
3304     
3305     /* Write dword (4 bytes) to a register. */
3306     #define AdvWriteDWordRegister(iop_base, reg_off, dword) \
3307          (ADV_MEM_WRITEDW((iop_base) + (reg_off), (dword)))
3308     
3309     /* Read byte from LRAM. */
3310     #define AdvReadByteLram(iop_base, addr, byte) \
3311     do { \
3312         ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
3313         (byte) = ADV_MEM_READB((iop_base) + IOPB_RAM_DATA); \
3314     } while (0)
3315     
3316     /* Write byte to LRAM. */
3317     #define AdvWriteByteLram(iop_base, addr, byte) \
3318         (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3319          ADV_MEM_WRITEB((iop_base) + IOPB_RAM_DATA, (byte)))
3320     
3321     /* Read word (2 bytes) from LRAM. */
3322     #define AdvReadWordLram(iop_base, addr, word) \
3323     do { \
3324         ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
3325         (word) = (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA)); \
3326     } while (0)
3327     
3328     /* Write word (2 bytes) to LRAM. */
3329     #define AdvWriteWordLram(iop_base, addr, word) \
3330         (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3331          ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
3332     
3333     /* Write little-endian double word (4 bytes) to LRAM */
3334     /* Because of unspecified C language ordering don't use auto-increment. */
3335     #define AdvWriteDWordLramNoSwap(iop_base, addr, dword) \
3336         ((ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3337           ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
3338                          cpu_to_le16((ushort) ((dword) & 0xFFFF)))), \
3339          (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr) + 2), \
3340           ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
3341                          cpu_to_le16((ushort) ((dword >> 16) & 0xFFFF)))))
3342     
3343     /* Read word (2 bytes) from LRAM assuming that the address is already set. */
3344     #define AdvReadWordAutoIncLram(iop_base) \
3345          (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA))
3346     
3347     /* Write word (2 bytes) to LRAM assuming that the address is already set. */
3348     #define AdvWriteWordAutoIncLram(iop_base, word) \
3349          (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
3350     
3351     
3352     /*
3353      * Define macro to check for Condor signature.
3354      *
3355      * Evaluate to ADV_TRUE if a Condor chip is found the specified port
3356      * address 'iop_base'. Otherwise evalue to ADV_FALSE.
3357      */
3358     #define AdvFindSignature(iop_base) \
3359         (((AdvReadByteRegister((iop_base), IOPB_CHIP_ID_1) == \
3360         ADV_CHIP_ID_BYTE) && \
3361          (AdvReadWordRegister((iop_base), IOPW_CHIP_ID_0) == \
3362         ADV_CHIP_ID_WORD)) ?  ADV_TRUE : ADV_FALSE)
3363     
3364     /*
3365      * Define macro to Return the version number of the chip at 'iop_base'.
3366      *
3367      * The second parameter 'bus_type' is currently unused.
3368      */
3369     #define AdvGetChipVersion(iop_base, bus_type) \
3370         AdvReadByteRegister((iop_base), IOPB_CHIP_TYPE_REV)
3371     
3372     /*
3373      * Abort an SRB in the chip's RISC Memory. The 'srb_ptr' argument must
3374      * match the ASC_SCSI_REQ_Q 'srb_ptr' field.
3375      *
3376      * If the request has not yet been sent to the device it will simply be
3377      * aborted from RISC memory. If the request is disconnected it will be
3378      * aborted on reselection by sending an Abort Message to the target ID.
3379      *
3380      * Return value:
3381      *      ADV_TRUE(1) - Queue was successfully aborted.
3382      *      ADV_FALSE(0) - Queue was not found on the active queue list.
3383      */
3384     #define AdvAbortQueue(asc_dvc, scsiq) \
3385             AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_ABORT, \
3386                            (ADV_DCNT) (scsiq))
3387     
3388     /*
3389      * Send a Bus Device Reset Message to the specified target ID.
3390      *
3391      * All outstanding commands will be purged if sending the
3392      * Bus Device Reset Message is successful.
3393      *
3394      * Return Value:
3395      *      ADV_TRUE(1) - All requests on the target are purged.
3396      *      ADV_FALSE(0) - Couldn't issue Bus Device Reset Message; Requests
3397      *                     are not purged.
3398      */
3399     #define AdvResetDevice(asc_dvc, target_id) \
3400             AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_DEVICE_RESET, \
3401                         (ADV_DCNT) (target_id))
3402     
3403     /*
3404      * SCSI Wide Type definition.
3405      */
3406     #define ADV_SCSI_BIT_ID_TYPE   ushort
3407     
3408     /*
3409      * AdvInitScsiTarget() 'cntl_flag' options.
3410      */
3411     #define ADV_SCAN_LUN           0x01
3412     #define ADV_CAPINFO_NOLUN      0x02
3413     
3414     /*
3415      * Convert target id to target id bit mask.
3416      */
3417     #define ADV_TID_TO_TIDMASK(tid)   (0x01 << ((tid) & ADV_MAX_TID))
3418     
3419     /*
3420      * ASC_SCSI_REQ_Q 'done_status' and 'host_status' return values.
3421      */
3422     
3423     #define QD_NO_STATUS         0x00       /* Request not completed yet. */
3424     #define QD_NO_ERROR          0x01
3425     #define QD_ABORTED_BY_HOST   0x02
3426     #define QD_WITH_ERROR        0x04
3427     
3428     #define QHSTA_NO_ERROR              0x00
3429     #define QHSTA_M_SEL_TIMEOUT         0x11
3430     #define QHSTA_M_DATA_OVER_RUN       0x12
3431     #define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
3432     #define QHSTA_M_QUEUE_ABORTED       0x15
3433     #define QHSTA_M_SXFR_SDMA_ERR       0x16 /* SXFR_STATUS SCSI DMA Error */
3434     #define QHSTA_M_SXFR_SXFR_PERR      0x17 /* SXFR_STATUS SCSI Bus Parity Error */
3435     #define QHSTA_M_RDMA_PERR           0x18 /* RISC PCI DMA parity error */
3436     #define QHSTA_M_SXFR_OFF_UFLW       0x19 /* SXFR_STATUS Offset Underflow */
3437     #define QHSTA_M_SXFR_OFF_OFLW       0x20 /* SXFR_STATUS Offset Overflow */
3438     #define QHSTA_M_SXFR_WD_TMO         0x21 /* SXFR_STATUS Watchdog Timeout */
3439     #define QHSTA_M_SXFR_DESELECTED     0x22 /* SXFR_STATUS Deselected */
3440     /* Note: QHSTA_M_SXFR_XFR_OFLW is identical to QHSTA_M_DATA_OVER_RUN. */
3441     #define QHSTA_M_SXFR_XFR_OFLW       0x12 /* SXFR_STATUS Transfer Overflow */
3442     #define QHSTA_M_SXFR_XFR_PH_ERR     0x24 /* SXFR_STATUS Transfer Phase Error */
3443     #define QHSTA_M_SXFR_UNKNOWN_ERROR  0x25 /* SXFR_STATUS Unknown Error */
3444     #define QHSTA_M_SCSI_BUS_RESET      0x30 /* Request aborted from SBR */
3445     #define QHSTA_M_SCSI_BUS_RESET_UNSOL 0x31 /* Request aborted from unsol. SBR */
3446     #define QHSTA_M_BUS_DEVICE_RESET    0x32 /* Request aborted from BDR */
3447     #define QHSTA_M_DIRECTION_ERR       0x35 /* Data Phase mismatch */
3448     #define QHSTA_M_DIRECTION_ERR_HUNG  0x36 /* Data Phase mismatch and bus hang */
3449     #define QHSTA_M_WTM_TIMEOUT         0x41
3450     #define QHSTA_M_BAD_CMPL_STATUS_IN  0x42
3451     #define QHSTA_M_NO_AUTO_REQ_SENSE   0x43
3452     #define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
3453     #define QHSTA_M_INVALID_DEVICE      0x45 /* Bad target ID */
3454     #define QHSTA_M_FROZEN_TIDQ         0x46 /* TID Queue frozen. */
3455     #define QHSTA_M_SGBACKUP_ERROR      0x47 /* Scatter-Gather backup error */
3456     
3457     
3458     /*
3459      * Default EEPROM Configuration structure defined in a_init.c.
3460      */
3461     extern ADVEEP_3550_CONFIG Default_3550_EEPROM_Config;
3462     extern ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config;
3463     extern ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config;
3464     
3465     /*
3466      * DvcGetPhyAddr() flag arguments
3467      */
3468     #define ADV_IS_SCSIQ_FLAG       0x01 /* 'addr' is ASC_SCSI_REQ_Q pointer */
3469     #define ADV_ASCGETSGLIST_VADDR  0x02 /* 'addr' is AscGetSGList() virtual addr */
3470     #define ADV_IS_SENSE_FLAG       0x04 /* 'addr' is sense virtual pointer */
3471     #define ADV_IS_DATA_FLAG        0x08 /* 'addr' is data virtual pointer */
3472     #define ADV_IS_SGLIST_FLAG      0x10 /* 'addr' is sglist virtual pointer */
3473     #define ADV_IS_CARRIER_FLAG     0x20 /* 'addr' is ADV_CARR_T pointer */
3474     
3475     /* Return the address that is aligned at the next doubleword >= to 'addr'. */
3476     #define ADV_8BALIGN(addr)      (((ulong) (addr) + 0x7) & ~0x7)
3477     #define ADV_16BALIGN(addr)     (((ulong) (addr) + 0xF) & ~0xF)
3478     #define ADV_32BALIGN(addr)     (((ulong) (addr) + 0x1F) & ~0x1F)
3479     
3480     /*
3481      * Total contiguous memory needed for driver SG blocks.
3482      *
3483      * ADV_MAX_SG_LIST must be defined by a driver. It is the maximum
3484      * number of scatter-gather elements the driver supports in a
3485      * single request.
3486      */
3487     
3488     #define ADV_SG_LIST_MAX_BYTE_SIZE \
3489              (sizeof(ADV_SG_BLOCK) * \
3490               ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK))
3491     
3492     /*
3493      * Inquiry data structure and bitfield macros
3494      *
3495      * Using bitfields to access the subchar data isn't portable across
3496      * endianness, so instead mask and shift. Only quantities of more
3497      * than 1 bit are shifted, since the others are just tested for true
3498      * or false.
3499      */
3500     
3501     #define ADV_INQ_DVC_TYPE(inq)       ((inq)->periph & 0x1f)
3502     #define ADV_INQ_QUALIFIER(inq)      (((inq)->periph & 0xe0) >> 5)
3503     #define ADV_INQ_DVC_TYPE_MOD(inq)   ((inq)->devtype & 0x7f)
3504     #define ADV_INQ_REMOVABLE(inq)      ((inq)->devtype & 0x80)
3505     #define ADV_INQ_ANSI_VER(inq)       ((inq)->ver & 0x07)
3506     #define ADV_INQ_ECMA_VER(inq)       (((inq)->ver & 0x38) >> 3)
3507     #define ADV_INQ_ISO_VER(inq)        (((inq)->ver & 0xc0) >> 6)
3508     #define ADV_INQ_RESPONSE_FMT(inq)   ((inq)->byte3 & 0x0f)
3509     #define ADV_INQ_TERM_IO(inq)        ((inq)->byte3 & 0x40)
3510     #define ADV_INQ_ASYNC_NOTIF(inq)    ((inq)->byte3 & 0x80)
3511     #define ADV_INQ_SOFT_RESET(inq)     ((inq)->flags & 0x01)
3512     #define ADV_INQ_CMD_QUEUE(inq)      ((inq)->flags & 0x02)
3513     #define ADV_INQ_LINK_CMD(inq)       ((inq)->flags & 0x08)
3514     #define ADV_INQ_SYNC(inq)           ((inq)->flags & 0x10)
3515     #define ADV_INQ_WIDE16(inq)         ((inq)->flags & 0x20)
3516     #define ADV_INQ_WIDE32(inq)         ((inq)->flags & 0x40)
3517     #define ADV_INQ_REL_ADDR(inq)       ((inq)->flags & 0x80)
3518     #define ADV_INQ_INFO_UNIT(inq)      ((inq)->info & 0x01)
3519     #define ADV_INQ_QUICK_ARB(inq)      ((inq)->info & 0x02)
3520     #define ADV_INQ_CLOCKING(inq)       (((inq)->info & 0x0c) >> 2)
3521     
3522     typedef struct {
3523       uchar periph;                 /* peripheral device type [0:4] */
3524                                     /* peripheral qualifier [5:7] */
3525       uchar devtype;                /* device type modifier (for SCSI I) [0:6] */
3526                                     /* RMB - removable medium bit [7] */
3527       uchar ver;                    /* ANSI approved version [0:2] */
3528                                     /* ECMA version [3:5] */
3529                                     /* ISO version [6:7] */
3530       uchar byte3;                  /* response data format [0:3] */
3531                                     /* 0 SCSI 1 */
3532                                     /* 1 CCS */
3533                                     /* 2 SCSI-2 */
3534                                     /* 3-F reserved */
3535                                     /* reserved [4:5] */
3536                                     /* terminate I/O process bit (see 5.6.22) [6] */
3537                                     /* asynch. event notification (processor) [7] */
3538       uchar add_len;                /* additional length */
3539       uchar res1;                   /* reserved */
3540       uchar res2;                   /* reserved */
3541       uchar flags;                  /* soft reset implemented [0] */
3542                                     /* command queuing [1] */
3543                                     /* reserved [2] */
3544                                     /* linked command for this logical unit [3] */
3545                                     /* synchronous data transfer [4] */
3546                                     /* wide bus 16 bit data transfer [5] */
3547                                     /* wide bus 32 bit data transfer [6] */
3548                                     /* relative addressing mode [7] */
3549       uchar vendor_id[8];           /* vendor identification */
3550       uchar product_id[16];         /* product identification */
3551       uchar product_rev_level[4];   /* product revision level */
3552       uchar vendor_specific[20];    /* vendor specific */
3553       uchar info;                   /* information unit supported [0] */
3554                                     /* quick arbitrate supported [1] */
3555                                     /* clocking field [2:3] */
3556                                     /* reserved [4:7] */
3557       uchar res3;                   /* reserved */
3558     } ADV_SCSI_INQUIRY; /* 58 bytes */
3559     
3560     
3561     /*
3562      * --- Driver Constants and Macros
3563      */
3564     
3565     #define ASC_NUM_BOARD_SUPPORTED 16
3566     #define ASC_NUM_IOPORT_PROBE    4
3567     #define ASC_NUM_BUS             4
3568     
3569     /* Reference Scsi_Host hostdata */
3570     #define ASC_BOARDP(host) ((asc_board_t *) &((host)->hostdata))
3571     
3572     /* asc_board_t flags */
3573     #define ASC_HOST_IN_RESET       0x01
3574     #define ASC_IS_WIDE_BOARD       0x04    /* AdvanSys Wide Board */
3575     #define ASC_SELECT_QUEUE_DEPTHS 0x08
3576     
3577     #define ASC_NARROW_BOARD(boardp) (((boardp)->flags & ASC_IS_WIDE_BOARD) == 0)
3578     #define ASC_WIDE_BOARD(boardp)   ((boardp)->flags & ASC_IS_WIDE_BOARD)
3579     
3580     #define NO_ISA_DMA              0xff        /* No ISA DMA Channel Used */
3581     
3582     /*
3583      * If the Linux kernel version supports freeing initialization code
3584      * and data after loading, define macros for this purpose. These macros
3585      * are not used when the driver is built as a module, cf. linux/init.h.
3586      */
3587     #if ASC_LINUX_KERNEL24
3588     #define ASC_INITFUNC(type, func)        type __init func
3589     #elif ASC_LINUX_KERNEL22
3590     #define ASC_INITFUNC(type, func)        __initfunc(type func)
3591     #endif
3592     #define ASC_INITDATA                    __initdata
3593     #define ASC_INIT                        __init
3594     
3595     #define ASC_INFO_SIZE           128            /* advansys_info() line size */
3596     
3597     #ifdef CONFIG_PROC_FS
3598     /* /proc/scsi/advansys/[0...] related definitions */
3599     #define ASC_PRTBUF_SIZE         2048
3600     #define ASC_PRTLINE_SIZE        160
3601     
3602     #define ASC_PRT_NEXT() \
3603         if (cp) { \
3604             totlen += len; \
3605             leftlen -= len; \
3606             if (leftlen == 0) { \
3607                 return totlen; \
3608             } \
3609             cp += len; \
3610         }
3611     
3612     #define ASC_MIN(a, b) (((a) < (b)) ? (a) : (b))
3613     #endif /* CONFIG_PROC_FS */
3614     
3615     /*
3616      * XXX - Release and acquire the io_request_lock. These macros are needed
3617      * because the 2.4 kernel SCSI mid-level driver holds the 'io_request_lock'
3618      * on entry to SCSI low-level drivers.
3619      *
3620      * These definitions and all code that uses code should be removed when the
3621      * SCSI mid-level driver no longer holds the 'io_request_lock' on entry to
3622      * SCSI low-level driver detect, queuecommand, and reset entrypoints.
3623      *
3624      * The interrupt flags values doesn't matter in the macros because the
3625      * SCSI mid-level will save and restore the flags values before and after
3626      * calling advansys_detect, advansys_queuecommand, and advansys_reset where
3627      * these macros are used. We do want interrupts enabled after the lock is
3628      * released so an explicit sti() is done. The driver only needs interrupts
3629      * disabled when it acquires the per board lock.
3630      */
3631     #define ASC_UNLOCK_IO_REQUEST_LOCK \
3632         { \
3633             ulong flags; /* flags value not needed, cf. comment above. */ \
3634             save_flags(flags); \
3635             spin_unlock_irqrestore(&io_request_lock, flags); \
3636             sti(); /* enable interrupts */ \
3637         }
3638     
3639     #define ASC_LOCK_IO_REQUEST_LOCK \
3640         { \
3641             ulong flags; /* flags value not needed, cf. comment above. */ \
3642             spin_lock_irqsave(&io_request_lock, flags); \
3643         }
3644     
3645     /* Asc Library return codes */
3646     #define ASC_TRUE        1
3647     #define ASC_FALSE       0
3648     #define ASC_NOERROR     1
3649     #define ASC_BUSY        0
3650     #define ASC_ERROR       (-1)
3651     
3652     /* Scsi_Cmnd function return codes */
3653     #define STATUS_BYTE(byte)   (byte)
3654     #define MSG_BYTE(byte)      ((byte) << 8)
3655     #define HOST_BYTE(byte)     ((byte) << 16)
3656     #define DRIVER_BYTE(byte)   ((byte) << 24)
3657     
3658     /*
3659      * The following definitions and macros are OS independent interfaces to
3660      * the queue functions:
3661      *  REQ - SCSI request structure
3662      *  REQP - pointer to SCSI request structure
3663      *  REQPTID(reqp) - reqp's target id
3664      *  REQPNEXT(reqp) - reqp's next pointer
3665      *  REQPNEXTP(reqp) - pointer to reqp's next pointer
3666      *  REQPTIME(reqp) - reqp's time stamp value
3667      *  REQTIMESTAMP() - system time stamp value
3668      */
3669     typedef Scsi_Cmnd            REQ, *REQP;
3670     #define REQPNEXT(reqp)       ((REQP) ((reqp)->host_scribble))
3671     #define REQPNEXTP(reqp)      ((REQP *) &((reqp)->host_scribble))
3672     #define REQPTID(reqp)        ((reqp)->target)
3673     #define REQPTIME(reqp)       ((reqp)->SCp.this_residual)
3674     #define REQTIMESTAMP()       (jiffies)
3675     
3676     #define REQTIMESTAT(function, ascq, reqp, tid) \
3677     { \
3678         /*
3679          * If the request time stamp is less than the system time stamp, then \
3680          * maybe the system time stamp wrapped. Set the request time to zero.\
3681          */ \
3682         if (REQPTIME(reqp) <= REQTIMESTAMP()) { \
3683             REQPTIME(reqp) = REQTIMESTAMP() - REQPTIME(reqp); \
3684         } else { \
3685             /* Indicate an error occurred with the assertion. */ \
3686             ASC_ASSERT(REQPTIME(reqp) <= REQTIMESTAMP()); \
3687             REQPTIME(reqp) = 0; \
3688         } \
3689         /* Handle first minimum time case without external initialization. */ \
3690         if (((ascq)->q_tot_cnt[tid] == 1) ||  \
3691             (REQPTIME(reqp) < (ascq)->q_min_tim[tid])) { \
3692                 (ascq)->q_min_tim[tid] = REQPTIME(reqp); \
3693                 ASC_DBG3(1, "%s: new q_min_tim[%d] %u\n", \
3694                     (function), (tid), (ascq)->q_min_tim[tid]); \
3695             } \
3696         if (REQPTIME(reqp) > (ascq)->q_max_tim[tid]) { \
3697             (ascq)->q_max_tim[tid] = REQPTIME(reqp); \
3698             ASC_DBG3(1, "%s: new q_max_tim[%d] %u\n", \
3699                 (function), tid, (ascq)->q_max_tim[tid]); \
3700         } \
3701         (ascq)->q_tot_tim[tid] += REQPTIME(reqp); \
3702         /* Reset the time stamp field. */ \
3703         REQPTIME(reqp) = 0; \
3704     }
3705     
3706     /* asc_enqueue() flags */
3707     #define ASC_FRONT       1
3708     #define ASC_BACK        2
3709     
3710     /* asc_dequeue_list() argument */
3711     #define ASC_TID_ALL        (-1)
3712     
3713     /* Return non-zero, if the queue is empty. */
3714     #define ASC_QUEUE_EMPTY(ascq)    ((ascq)->q_tidmask == 0)
3715     
3716     /* PCI configuration declarations */
3717     
3718     #define PCI_BASE_CLASS_PREDEFINED               0x00
3719     #define PCI_BASE_CLASS_MASS_STORAGE             0x01
3720     #define PCI_BASE_CLASS_NETWORK                  0x02
3721     #define PCI_BASE_CLASS_DISPLAY                  0x03
3722     #define PCI_BASE_CLASS_MULTIMEDIA               0x04
3723     #define PCI_BASE_CLASS_MEMORY_CONTROLLER        0x05
3724     #define PCI_BASE_CLASS_BRIDGE_DEVICE            0x06
3725     
3726     /* MASS STORAGE */
3727     #define PCI_SUB_CLASS_SCSI_CONTROLLER           0x00
3728     #define PCI_SUB_CLASS_IDE_CONTROLLER            0x01
3729     #define PCI_SUB_CLASS_FLOPPY_DISK_CONTROLLER    0x02
3730     #define PCI_SUB_CLASS_IPI_BUS_CONTROLLER        0x03
3731     #define PCI_SUB_CLASS_OTHER_MASS_CONTROLLER     0x80
3732     
3733     /* NETWORK CONTROLLER */
3734     #define PCI_SUB_CLASS_ETHERNET_CONTROLLER       0x00
3735     #define PCI_SUB_CLASS_TOKEN_RING_CONTROLLER     0x01
3736     #define PCI_SUB_CLASS_FDDI_CONTROLLER           0x02
3737     #define PCI_SUB_CLASS_OTHER_NETWORK_CONTROLLER  0x80
3738     
3739     /* DISPLAY CONTROLLER */
3740     #define PCI_SUB_CLASS_VGA_CONTROLLER            0x00
3741     #define PCI_SUB_CLASS_XGA_CONTROLLER            0x01
3742     #define PCI_SUB_CLASS_OTHER_DISPLAY_CONTROLLER  0x80
3743     
3744     /* MULTIMEDIA CONTROLLER */
3745     #define PCI_SUB_CLASS_VIDEO_DEVICE              0x00
3746     #define PCI_SUB_CLASS_AUDIO_DEVICE              0x01
3747     #define PCI_SUB_CLASS_OTHER_MULTIMEDIA_DEVICE   0x80
3748     
3749     /* MEMORY CONTROLLER */
3750     #define PCI_SUB_CLASS_RAM_CONTROLLER            0x00
3751     #define PCI_SUB_CLASS_FLASH_CONTROLLER          0x01
3752     #define PCI_SUB_CLASS_OTHER_MEMORY_CONTROLLER   0x80
3753     
3754     /* BRIDGE CONTROLLER */
3755     #define PCI_SUB_CLASS_HOST_BRIDGE_CONTROLLER    0x00
3756     #define PCI_SUB_CLASS_ISA_BRIDGE_CONTROLLER     0x01
3757     #define PCI_SUB_CLASS_EISA_BRIDGE_CONTROLLER    0x02
3758     #define PCI_SUB_CLASS_MC_BRIDGE_CONTROLLER      0x03
3759     #define PCI_SUB_CLASS_PCI_TO_PCI_BRIDGE_CONTROLLER    0x04
3760     #define PCI_SUB_CLASS_PCMCIA_BRIDGE_CONTROLLER  0x05
3761     #define PCI_SUB_CLASS_OTHER_BRIDGE_CONTROLLER   0x80
3762     
3763     #define PCI_MAX_SLOT            0x1F
3764     #define PCI_MAX_BUS             0xFF
3765     #define PCI_IOADDRESS_MASK      0xFFFE
3766     #define ASC_PCI_VENDORID        0x10CD
3767     #define ASC_PCI_DEVICE_ID_CNT   6       /* PCI Device ID count. */
3768     #define ASC_PCI_DEVICE_ID_1100  0x1100
3769     #define ASC_PCI_DEVICE_ID_1200  0x1200
3770     #define ASC_PCI_DEVICE_ID_1300  0x1300
3771     #define ASC_PCI_DEVICE_ID_2300  0x2300  /* ASC-3550 */
3772     #define ASC_PCI_DEVICE_ID_2500  0x2500  /* ASC-38C0800 */
3773     #define ASC_PCI_DEVICE_ID_2700  0x2700  /* ASC-38C1600 */
3774     
3775     /* PCI IO Port Addresses to generate special cycle */
3776     
3777     #define PCI_CONFIG_ADDRESS_MECH1          0x0CF8
3778     #define PCI_CONFIG_DATA_MECH1             0x0CFC
3779     
3780     #define PCI_CONFIG_FORWARD_REGISTER       0x0CFA    /* 0=type 0; 1=type 1; */
3781     
3782     #define PCI_CONFIG_BUS_NUMBER_MASK        0x00FF0000
3783     #define PCI_CONFIG_DEVICE_FUNCTION_MASK   0x0000FF00
3784     #define PCI_CONFIG_REGISTER_NUMBER_MASK   0x000000F8
3785     
3786     #define PCI_DEVICE_FOUND                0x0000
3787     #define PCI_DEVICE_NOT_FOUND            0xffff
3788     
3789     #define SUBCLASS_OFFSET         0x0A
3790     #define CLASSCODE_OFFSET        0x0B
3791     #define VENDORID_OFFSET         0x00
3792     #define DEVICEID_OFFSET         0x02
3793     
3794     #ifndef ADVANSYS_STATS
3795     #define ASC_STATS(shp, counter)
3796     #define ASC_STATS_ADD(shp, counter, count)
3797     #else /* ADVANSYS_STATS */
3798     #define ASC_STATS(shp, counter) \
3799         (ASC_BOARDP(shp)->asc_stats.counter++)
3800     
3801     #define ASC_STATS_ADD(shp, counter, count) \
3802         (ASC_BOARDP(shp)->asc_stats.counter += (count))
3803     #endif /* ADVANSYS_STATS */
3804     
3805     #define ASC_CEILING(val, unit) (((val) + ((unit) - 1))/(unit))
3806     
3807     /* If the result wraps when calculating tenths, return 0. */
3808     #define ASC_TENTHS(num, den) \
3809         (((10 * ((num)/(den))) > (((num) * 10)/(den))) ? \
3810         0 : ((((num) * 10)/(den)) - (10 * ((num)/(den)))))
3811     
3812     /*
3813      * Display a message to the console.
3814      */
3815     #define ASC_PRINT(s) \
3816         { \
3817             printk("advansys: "); \
3818             printk(s); \
3819         }
3820     
3821     #define ASC_PRINT1(s, a1) \
3822         { \
3823             printk("advansys: "); \
3824             printk((s), (a1)); \
3825         }
3826     
3827     #define ASC_PRINT2(s, a1, a2) \
3828         { \
3829             printk("advansys: "); \
3830             printk((s), (a1), (a2)); \
3831         }
3832     
3833     #define ASC_PRINT3(s, a1, a2, a3) \
3834         { \
3835             printk("advansys: "); \
3836             printk((s), (a1), (a2), (a3)); \
3837         }
3838     
3839     #define ASC_PRINT4(s, a1, a2, a3, a4) \
3840         { \
3841             printk("advansys: "); \
3842             printk((s), (a1), (a2), (a3), (a4)); \
3843         }
3844     
3845     
3846     #ifndef ADVANSYS_DEBUG
3847     
3848     #define ASC_DBG(lvl, s)
3849     #define ASC_DBG1(lvl, s, a1)
3850     #define ASC_DBG2(lvl, s, a1, a2)
3851     #define ASC_DBG3(lvl, s, a1, a2, a3)
3852     #define ASC_DBG4(lvl, s, a1, a2, a3, a4)
3853     #define ASC_DBG_PRT_SCSI_HOST(lvl, s)
3854     #define ASC_DBG_PRT_SCSI_CMND(lvl, s)
3855     #define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp)
3856     #define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
3857     #define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone)
3858     #define ADV_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
3859     #define ASC_DBG_PRT_HEX(lvl, name, start, length)
3860     #define ASC_DBG_PRT_CDB(lvl, cdb, len)
3861     #define ASC_DBG_PRT_SENSE(lvl, sense, len)
3862     #define ASC_DBG_PRT_INQUIRY(lvl, inq, len)
3863     
3864     #else /* ADVANSYS_DEBUG */
3865     
3866     /*
3867      * Debugging Message Levels:
3868      * 0: Errors Only
3869      * 1: High-Level Tracing
3870      * 2-N: Verbose Tracing
3871      */
3872     
3873     #define ASC_DBG(lvl, s) \
3874         { \
3875             if (asc_dbglvl >= (lvl)) { \
3876                 printk(s); \
3877             } \
3878         }
3879     
3880     #define ASC_DBG1(lvl, s, a1) \
3881         { \
3882             if (asc_dbglvl >= (lvl)) { \
3883                 printk((s), (a1)); \
3884             } \
3885         }
3886     
3887     #define ASC_DBG2(lvl, s, a1, a2) \
3888         { \
3889             if (asc_dbglvl >= (lvl)) { \
3890                 printk((s), (a1), (a2)); \
3891             } \
3892         }
3893     
3894     #define ASC_DBG3(lvl, s, a1, a2, a3) \
3895         { \
3896             if (asc_dbglvl >= (lvl)) { \
3897                 printk((s), (a1), (a2), (a3)); \
3898             } \
3899         }
3900     
3901     #define ASC_DBG4(lvl, s, a1, a2, a3, a4) \
3902         { \
3903             if (asc_dbglvl >= (lvl)) { \
3904                 printk((s), (a1), (a2), (a3), (a4)); \
3905             } \
3906         }
3907     
3908     #define ASC_DBG_PRT_SCSI_HOST(lvl, s) \
3909         { \
3910             if (asc_dbglvl >= (lvl)) { \
3911                 asc_prt_scsi_host(s); \
3912             } \
3913         }
3914     
3915     #define ASC_DBG_PRT_SCSI_CMND(lvl, s) \
3916         { \
3917             if (asc_dbglvl >= (lvl)) { \
3918                 asc_prt_scsi_cmnd(s); \
3919             } \
3920         }
3921     
3922     #define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp) \
3923         { \
3924             if (asc_dbglvl >= (lvl)) { \
3925                 asc_prt_asc_scsi_q(scsiqp); \
3926             } \
3927         }
3928     
3929     #define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone) \
3930         { \
3931             if (asc_dbglvl >= (lvl)) { \
3932                 asc_prt_asc_qdone_info(qdone); \
3933             } \
3934         }
3935     
3936     #define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp) \
3937         { \
3938             if (asc_dbglvl >= (lvl)) { \
3939                 asc_prt_adv_scsi_req_q(scsiqp); \
3940             } \
3941         }
3942     
3943     #define ASC_DBG_PRT_HEX(lvl, name, start, length) \
3944         { \
3945             if (asc_dbglvl >= (lvl)) { \
3946                 asc_prt_hex((name), (start), (length)); \
3947             } \
3948         }
3949     
3950     #define ASC_DBG_PRT_CDB(lvl, cdb, len) \
3951             ASC_DBG_PRT_HEX((lvl), "CDB", (uchar *) (cdb), (len));
3952     
3953     #define ASC_DBG_PRT_SENSE(lvl, sense, len) \
3954             ASC_DBG_PRT_HEX((lvl), "SENSE", (uchar *) (sense), (len));
3955     
3956     #define ASC_DBG_PRT_INQUIRY(lvl, inq, len) \
3957             ASC_DBG_PRT_HEX((lvl), "INQUIRY", (uchar *) (inq), (len));
3958     #endif /* ADVANSYS_DEBUG */
3959     
3960     #ifndef ADVANSYS_ASSERT
3961     #define ASC_ASSERT(a)
3962     #else /* ADVANSYS_ASSERT */
3963     
3964     #define ASC_ASSERT(a) \
3965         { \
3966             if (!(a)) { \
3967                 printk("ASC_ASSERT() Failure: file %s, line %d\n", \
3968                     __FILE__, __LINE__); \
3969             } \
3970         }
3971     
3972     #endif /* ADVANSYS_ASSERT */
3973     
3974     
3975     /*
3976      * --- Driver Structures
3977      */
3978     
3979     #ifdef ADVANSYS_STATS
3980     
3981     /* Per board statistics structure */
3982     struct asc_stats {
3983         /* Driver Entrypoint Statistics */
3984         ADV_DCNT queuecommand;    /* # calls to advansys_queuecommand() */
3985         ADV_DCNT reset;           /* # calls to advansys_eh_bus_reset() */
3986         ADV_DCNT biosparam;       /* # calls to advansys_biosparam() */
3987         ADV_DCNT interrupt;       /* # advansys_interrupt() calls */
3988         ADV_DCNT callback;        /* # calls to asc/adv_isr_callback() */
3989         ADV_DCNT done;            /* # calls to request's scsi_done function */
3990         ADV_DCNT build_error;     /* # asc/adv_build_req() ASC_ERROR returns. */
3991         ADV_DCNT adv_build_noreq; /* # adv_build_req() adv_req_t alloc. fail. */
3992         ADV_DCNT adv_build_nosg;  /* # adv_build_req() adv_sgblk_t alloc. fail. */
3993         /* AscExeScsiQueue()/AdvExeScsiQueue() Statistics */
3994         ADV_DCNT exe_noerror;     /* # ASC_NOERROR returns. */
3995         ADV_DCNT exe_busy;        /* # ASC_BUSY returns. */
3996         ADV_DCNT exe_error;       /* # ASC_ERROR returns. */
3997         ADV_DCNT exe_unknown;     /* # unknown returns. */
3998         /* Data Transfer Statistics */
3999         ADV_DCNT cont_cnt;        /* # non-scatter-gather I/O requests received */
4000         ADV_DCNT cont_xfer;       /* # contiguous transfer 512-bytes */
4001         ADV_DCNT sg_cnt;          /* # scatter-gather I/O requests received */
4002         ADV_DCNT sg_elem;         /* # scatter-gather elements */
4003         ADV_DCNT sg_xfer;         /* # scatter-gather transfer 512-bytes */
4004     };
4005     #endif /* ADVANSYS_STATS */
4006     
4007     /*
4008      * Request queuing structure
4009      */
4010     typedef struct asc_queue {
4011         ADV_SCSI_BIT_ID_TYPE  q_tidmask;                /* queue mask */
4012         REQP                  q_first[ADV_MAX_TID+1];   /* first queued request */
4013         REQP                  q_last[ADV_MAX_TID+1];    /* last queued request */
4014     #ifdef ADVANSYS_STATS
4015         short                 q_cur_cnt[ADV_MAX_TID+1]; /* current queue count */
4016         short                 q_max_cnt[ADV_MAX_TID+1]; /* maximum queue count */
4017         ADV_DCNT              q_tot_cnt[ADV_MAX_TID+1]; /* total enqueue count */
4018         ADV_DCNT              q_tot_tim[ADV_MAX_TID+1]; /* total time queued */
4019         ushort                q_max_tim[ADV_MAX_TID+1]; /* maximum time queued */
4020         ushort                q_min_tim[ADV_MAX_TID+1]; /* minimum time queued */
4021     #endif /* ADVANSYS_STATS */
4022     } asc_queue_t;
4023     
4024     /*
4025      * Adv Library Request Structures
4026      *
4027      * The following two structures are used to process Wide Board requests.
4028      *
4029      * The ADV_SCSI_REQ_Q structure in adv_req_t is passed to the Adv Library
4030      * and microcode with the ADV_SCSI_REQ_Q field 'srb_ptr' pointing to the
4031      * adv_req_t. The adv_req_t structure 'cmndp' field in turn points to the
4032      * Mid-Level SCSI request structure.
4033      *
4034      * Zero or more ADV_SG_BLOCK are used with each ADV_SCSI_REQ_Q. Each
4035      * ADV_SG_BLOCK structure holds 15 scatter-gather elements. Under Linux
4036      * up to 255 scatter-gather elements may be used per request or
4037      * ADV_SCSI_REQ_Q.
4038      *
4039      * Both structures must be 32 byte aligned.
4040      */
4041     typedef struct adv_sgblk {
4042         ADV_SG_BLOCK        sg_block;     /* Sgblock structure. */
4043         uchar               align[32];    /* Sgblock structure padding. */
4044         struct adv_sgblk    *next_sgblkp; /* Next scatter-gather structure. */
4045     } adv_sgblk_t;
4046     
4047     typedef struct adv_req {
4048         ADV_SCSI_REQ_Q      scsi_req_q;   /* Adv Library request structure. */
4049         uchar               align[32];    /* Request structure padding. */
4050         Scsi_Cmnd           *cmndp;       /* Mid-Level SCSI command pointer. */
4051         adv_sgblk_t         *sgblkp;      /* Adv Library scatter-gather pointer. */
4052         struct adv_req      *next_reqp;   /* Next Request Structure. */
4053     } adv_req_t;
4054     
4055     /*
4056      * Structure allocated for each board.
4057      *
4058      * This structure is allocated by scsi_register() at the end
4059      * of the 'Scsi_Host' structure starting at the 'hostdata'
4060      * field. It is guaranteed to be allocated from DMA-able memory.
4061      */
4062     typedef struct asc_board {
4063         int                  id;                    /* Board Id */
4064         uint                 flags;                 /* Board flags */
4065         union {
4066             ASC_DVC_VAR      asc_dvc_var;           /* Narrow board */
4067             ADV_DVC_VAR      adv_dvc_var;           /* Wide board */
4068         } dvc_var;
4069         union {
4070             ASC_DVC_CFG      asc_dvc_cfg;           /* Narrow board */
4071             ADV_DVC_CFG      adv_dvc_cfg;           /* Wide board */
4072         } dvc_cfg;
4073         ushort               asc_n_io_port;         /* Number I/O ports. */
4074         asc_queue_t          active;                /* Active command queue */
4075         asc_queue_t          waiting;               /* Waiting command queue */
4076         asc_queue_t          done;                  /* Done command queue */
4077         ADV_SCSI_BIT_ID_TYPE init_tidmask;          /* Target init./valid mask */
4078         Scsi_Device          *device[ADV_MAX_TID+1]; /* Mid-Level Scsi Device */
4079         ushort               reqcnt[ADV_MAX_TID+1]; /* Starvation request count */
4080         ADV_SCSI_BIT_ID_TYPE queue_full;            /* Queue full mask */
4081         ushort               queue_full_cnt[ADV_MAX_TID+1]; /* Queue full count */
4082         union {
4083             ASCEEP_CONFIG         asc_eep;          /* Narrow EEPROM config. */
4084             ADVEEP_3550_CONFIG    adv_3550_eep;     /* 3550 EEPROM config. */
4085             ADVEEP_38C0800_CONFIG adv_38C0800_eep;  /* 38C0800 EEPROM config. */
4086             ADVEEP_38C1600_CONFIG adv_38C1600_eep;  /* 38C1600 EEPROM config. */
4087         } eep_config;
4088         ulong                last_reset;            /* Saved last reset time */
4089         spinlock_t lock;                            /* Board spinlock */
4090     #ifdef CONFIG_PROC_FS
4091         /* /proc/scsi/advansys/[0...] */
4092         char                 *prtbuf;               /* /proc print buffer */
4093     #endif /* CONFIG_PROC_FS */
4094     #ifdef ADVANSYS_STATS
4095         struct asc_stats     asc_stats;             /* Board statistics */
4096     #endif /* ADVANSYS_STATS */
4097         /*
4098          * The following fields are used only for Narrow Boards.
4099          */
4100         /* The following three structures must be in DMA-able memory. */
4101         ASC_SCSI_REQ_Q       scsireqq;
4102         ASC_CAP_INFO         cap_info;
4103         ASC_SCSI_INQUIRY     inquiry;
4104         uchar                sdtr_data[ASC_MAX_TID+1]; /* SDTR information */
4105         /*
4106          * The following fields are used only for Wide Boards.
4107          */
4108         void                 *ioremap_addr;         /* I/O Memory remap address. */
4109         ushort               ioport;                /* I/O Port address. */
4110         ADV_CARR_T           *orig_carrp;           /* ADV_CARR_T memory block. */
4111         adv_req_t            *orig_reqp;            /* adv_req_t memory block. */
4112         adv_req_t            *adv_reqp;             /* Request structures. */
4113         adv_sgblk_t          *adv_sgblkp;           /* Scatter-gather structures. */
4114         ushort               bios_signature;        /* BIOS Signature. */
4115         ushort               bios_version;          /* BIOS Version. */
4116         ushort               bios_codeseg;          /* BIOS Code Segment. */
4117         ushort               bios_codelen;          /* BIOS Code Segment Length. */
4118     } asc_board_t;
4119     
4120     /*
4121      * PCI configuration structures
4122      */
4123     typedef struct _PCI_DATA_
4124     {
4125         uchar    type;
4126         uchar    bus;
4127         uchar    slot;
4128         uchar    func;
4129         uchar    offset;
4130     } PCI_DATA;
4131     
4132     typedef struct _PCI_DEVICE_
4133     {
4134         ushort   vendorID;
4135         ushort   deviceID;
4136         ushort   slotNumber;
4137         ushort   slotFound;
4138         uchar    busNumber;
4139         uchar    maxBusNumber;
4140         uchar    devFunc;
4141         ushort   startSlot;
4142         ushort   endSlot;
4143         uchar    bridge;
4144         uchar    type;
4145     } PCI_DEVICE;
4146     
4147     typedef struct _PCI_CONFIG_SPACE_
4148     {
4149         ushort   vendorID;
4150         ushort   deviceID;
4151         ushort   command;
4152         ushort   status;
4153         uchar    revision;
4154         uchar    classCode[3];
4155         uchar    cacheSize;
4156         uchar    latencyTimer;
4157         uchar    headerType;
4158         uchar    bist;
4159         ADV_PADDR baseAddress[6];
4160         ushort   reserved[4];
4161         ADV_PADDR optionRomAddr;
4162         ushort   reserved2[4];
4163         uchar    irqLine;
4164         uchar    irqPin;
4165         uchar    minGnt;
4166         uchar    maxLatency;
4167     } PCI_CONFIG_SPACE;
4168     
4169     
4170     /*
4171      * --- Driver Data
4172      */
4173     
4174     /* Note: All driver global data should be initialized. */
4175     
4176     #if ASC_LINUX_KERNEL22
4177     #ifdef CONFIG_PROC_FS
4178     struct proc_dir_entry proc_scsi_advansys =
4179     {
4180         PROC_SCSI_ADVANSYS,              /* unsigned short low_ino */
4181         8,                               /* unsigned short namelen */
4182         "advansys",                      /* const char *name */
4183         S_IFDIR | S_IRUGO | S_IXUGO,     /* mode_t mode */
4184         2                                /* nlink_t nlink */
4185     };
4186     #endif /* CONFIG_PROC_FS */
4187     #endif /* ASC_LINUX_KERNEL22 */
4188     
4189     /* Number of boards detected in system. */
4190     STATIC int asc_board_count = 0;
4191     STATIC struct Scsi_Host    *asc_host[ASC_NUM_BOARD_SUPPORTED] = { 0 };
4192     
4193     /* Overrun buffer used by all narrow boards. */
4194     STATIC uchar overrun_buf[ASC_OVERRUN_BSIZE] = { 0 };
4195     
4196     /*
4197      * Global structures required to issue a command.
4198      */
4199     STATIC ASC_SCSI_Q asc_scsi_q = { { 0 } };
4200     STATIC ASC_SG_HEAD asc_sg_head = { 0 };
4201     
4202     /* List of supported bus types. */
4203     STATIC ushort asc_bus[ASC_NUM_BUS] ASC_INITDATA = {
4204         ASC_IS_ISA,
4205         ASC_IS_VL,
4206         ASC_IS_EISA,
4207         ASC_IS_PCI,
4208     };
4209     
4210     /*
4211      * Used with the LILO 'advansys' option to eliminate or
4212      * limit I/O port probing at boot time, cf. advansys_setup().
4213      */
4214     STATIC int asc_iopflag = ASC_FALSE;
4215     STATIC int asc_ioport[ASC_NUM_IOPORT_PROBE] = { 0, 0, 0, 0 };
4216     
4217     #ifdef ADVANSYS_DEBUG
4218     STATIC char *
4219     asc_bus_name[ASC_NUM_BUS] = {
4220         "ASC_IS_ISA",
4221         "ASC_IS_VL",
4222         "ASC_IS_EISA",
4223         "ASC_IS_PCI",
4224     };
4225     
4226     STATIC int          asc_dbglvl = 3;
4227     #endif /* ADVANSYS_DEBUG */
4228     
4229     /* Declaration for Asc Library internal data referenced by driver. */
4230     STATIC PortAddr     _asc_def_iop_base[];
4231     
4232     
4233     /*
4234      * --- Driver Function Prototypes
4235      *
4236      * advansys.h contains function prototypes for functions global to Linux.
4237      */
4238     
4239     STATIC void       advansys_interrupt(int, void *, struct pt_regs *);
4240     STATIC void       advansys_select_queue_depths(struct Scsi_Host *,
4241                                                    Scsi_Device *);
4242     STATIC void       asc_scsi_done_list(Scsi_Cmnd *);
4243     STATIC int        asc_execute_scsi_cmnd(Scsi_Cmnd *);
4244     STATIC int        asc_build_req(asc_board_t *, Scsi_Cmnd *);
4245     STATIC int        adv_build_req(asc_board_t *, Scsi_Cmnd *, ADV_SCSI_REQ_Q **);
4246     STATIC int        adv_get_sglist(asc_board_t *, adv_req_t *, Scsi_Cmnd *);
4247     STATIC void       asc_isr_callback(ASC_DVC_VAR *, ASC_QDONE_INFO *);
4248     STATIC void       adv_isr_callback(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
4249     STATIC void       adv_async_callback(ADV_DVC_VAR *, uchar);
4250     STATIC void       asc_enqueue(asc_queue_t *, REQP, int);
4251     STATIC REQP       asc_dequeue(asc_queue_t *, int);
4252     STATIC REQP       asc_dequeue_list(asc_queue_t *, REQP *, int);
4253     STATIC int        asc_rmqueue(asc_queue_t *, REQP);
4254     STATIC void       asc_execute_queue(asc_queue_t *);
4255     #ifdef CONFIG_PROC_FS
4256     STATIC int        asc_proc_copy(off_t, off_t, char *, int , char *, int);
4257     STATIC int        asc_prt_board_devices(struct Scsi_Host *, char *, int);
4258     STATIC int        asc_prt_adv_bios(struct Scsi_Host *, char *, int);
4259     STATIC int        asc_get_eeprom_string(ushort *serialnum, uchar *cp);
4260     STATIC int        asc_prt_asc_board_eeprom(struct Scsi_Host *, char *, int);
4261     STATIC int        asc_prt_adv_board_eeprom(struct Scsi_Host *, char *, int);
4262     STATIC int        asc_prt_driver_conf(struct Scsi_Host *, char *, int);
4263     STATIC int        asc_prt_asc_board_info(struct Scsi_Host *, char *, int);
4264     STATIC int        asc_prt_adv_board_info(struct Scsi_Host *, char *, int);
4265     STATIC int        asc_prt_line(char *, int, char *fmt, ...);
4266     #endif /* CONFIG_PROC_FS */
4267     
4268     /* Declaration for Asc Library internal functions referenced by driver. */
4269     STATIC int          AscFindSignature(PortAddr);
4270     STATIC ushort       AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
4271     
4272     /* Statistics function prototypes. */
4273     #ifdef ADVANSYS_STATS
4274     #ifdef CONFIG_PROC_FS
4275     STATIC int          asc_prt_board_stats(struct Scsi_Host *, char *, int);
4276     STATIC int          asc_prt_target_stats(struct Scsi_Host *, int, char *, int);
4277     #endif /* CONFIG_PROC_FS */
4278     #endif /* ADVANSYS_STATS */
4279     
4280     /* Debug function prototypes. */
4281     #ifdef ADVANSYS_DEBUG
4282     STATIC void         asc_prt_scsi_host(struct Scsi_Host *);
4283     STATIC void         asc_prt_scsi_cmnd(Scsi_Cmnd *);
4284     STATIC void         asc_prt_asc_dvc_cfg(ASC_DVC_CFG *);
4285     STATIC void         asc_prt_asc_dvc_var(ASC_DVC_VAR *);
4286     STATIC void         asc_prt_asc_scsi_q(ASC_SCSI_Q *);
4287     STATIC void         asc_prt_asc_qdone_info(ASC_QDONE_INFO *);
4288     STATIC void         asc_prt_adv_dvc_cfg(ADV_DVC_CFG *);
4289     STATIC void         asc_prt_adv_dvc_var(ADV_DVC_VAR *);
4290     STATIC void         asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *);
4291     STATIC void         asc_prt_adv_sgblock(int, ADV_SG_BLOCK *);
4292     STATIC void         asc_prt_hex(char *f, uchar *, int);
4293     #endif /* ADVANSYS_DEBUG */
4294     
4295     
4296     /*
4297      * --- Linux 'Scsi_Host_Template' and advansys_setup() Functions
4298      */
4299     
4300     #ifdef CONFIG_PROC_FS
4301     /*
4302      * advansys_proc_info() - /proc/scsi/advansys/[0-(ASC_NUM_BOARD_SUPPORTED-1)]
4303      *
4304      * *buffer: I/O buffer
4305      * **start: if inout == FALSE pointer into buffer where user read should start
4306      * offset: current offset into a /proc/scsi/advansys/[0...] file
4307      * length: length of buffer
4308      * hostno: Scsi_Host host_no
4309      * inout: TRUE - user is writing; FALSE - user is reading
4310      *
4311      * Return the number of bytes read from or written to a
4312      * /proc/scsi/advansys/[0...] file.
4313      *
4314      * Note: This function uses the per board buffer 'prtbuf' which is
4315      * allocated when the board is initialized in advansys_detect(). The
4316      * buffer is ASC_PRTBUF_SIZE bytes. The function asc_proc_copy() is
4317      * used to write to the buffer. The way asc_proc_copy() is written
4318      * if 'prtbuf' is too small it will not be overwritten. Instead the
4319      * user just won't get all the available statistics.
4320      */
4321     int
4322     advansys_proc_info(char *buffer, char **start, off_t offset, int length,
4323                        int hostno, int inout)
4324     {
4325         struct Scsi_Host    *shp;
4326         asc_board_t         *boardp;
4327         int                 i;
4328         char                *cp;
4329         int                 cplen;
4330         int                 cnt;
4331         int                 totcnt;
4332         int                 leftlen;
4333         char                *curbuf;
4334         off_t               advoffset;
4335         Scsi_Device         *scd;
4336     #ifdef ADVANSYS_STATS
4337         int                 tgt_id;
4338     #endif /* ADVANSYS_STATS */
4339     
4340         ASC_DBG(1, "advansys_proc_info: begin\n");
4341     
4342         /*
4343          * User write not supported.
4344          */
4345         if (inout == TRUE) {
4346             return(-ENOSYS);
4347         }
4348     
4349         /*
4350          * User read of /proc/scsi/advansys/[0...] file.
4351          */
4352     
4353         /* Find the specified board. */
4354         for (i = 0; i < asc_board_count; i++) {
4355             if (asc_host[i]->host_no == hostno) {
4356                 break;
4357             }
4358         }
4359         if (i == asc_board_count) {
4360             return(-ENOENT);
4361         }
4362     
4363         shp = asc_host[i];
4364         boardp = ASC_BOARDP(shp);
4365     
4366         /* Copy read data starting at the beginning of the buffer. */
4367         *start = buffer;
4368         curbuf = buffer;
4369         advoffset = 0;
4370         totcnt = 0;
4371         leftlen = length;
4372     
4373         /*
4374          * Get board configuration information.
4375          *
4376          * advansys_info() returns the board string from its own static buffer.
4377          */
4378         cp = (char *) advansys_info(shp);
4379         strcat(cp, "\n");
4380         cplen = strlen(cp);
4381         /* Copy board information. */
4382         cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4383         totcnt += cnt;
4384         leftlen -= cnt;
4385         if (leftlen == 0) {
4386             ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4387             return totcnt;
4388         }
4389         advoffset += cplen;
4390         curbuf += cnt;
4391     
4392         /*
4393          * Display Wide Board BIOS Information.
4394          */
4395         if (ASC_WIDE_BOARD(boardp)) {
4396             cp = boardp->prtbuf;
4397             cplen = asc_prt_adv_bios(shp, cp, ASC_PRTBUF_SIZE);
4398             ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4399             cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4400             totcnt += cnt;
4401             leftlen -= cnt;
4402             if (leftlen == 0) {
4403                 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4404                 return totcnt;
4405             }
4406             advoffset += cplen;
4407             curbuf += cnt;
4408         }
4409     
4410         /*
4411          * Display driver information for each device attached to the board.
4412          */
4413         cp = boardp->prtbuf;
4414         cplen = asc_prt_board_devices(shp, cp, ASC_PRTBUF_SIZE);
4415         ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4416         cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4417         totcnt += cnt;
4418         leftlen -= cnt;
4419         if (leftlen == 0) {
4420             ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4421             return totcnt;
4422         }
4423         advoffset += cplen;
4424         curbuf += cnt;
4425     
4426         /*
4427          * Display target driver information for each device attached
4428          * to the board.
4429          */
4430         for (scd = shp->host_queue; scd; scd = scd->next)
4431         {
4432             if (scd->host == shp) {
4433                 cp = boardp->prtbuf;
4434                 /*
4435                  * Note: If proc_print_scsidevice() writes more than
4436                  * ASC_PRTBUF_SIZE bytes, it will overrun 'prtbuf'.
4437                  */
4438                 proc_print_scsidevice(scd, cp, &cplen, 0);
4439                 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4440                 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4441                 totcnt += cnt;
4442                 leftlen -= cnt;
4443                 if (leftlen == 0) {
4444                     ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4445                     return totcnt;
4446                 }
4447                 advoffset += cplen;
4448                 curbuf += cnt;
4449             }
4450         }
4451     
4452         /*
4453          * Display EEPROM configuration for the board.
4454          */
4455         cp = boardp->prtbuf;
4456         if (ASC_NARROW_BOARD(boardp)) {
4457             cplen = asc_prt_asc_board_eeprom(shp, cp, ASC_PRTBUF_SIZE);
4458         } else {
4459             cplen = asc_prt_adv_board_eeprom(shp, cp, ASC_PRTBUF_SIZE);
4460         }
4461         ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4462         cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4463         totcnt += cnt;
4464         leftlen -= cnt;
4465         if (leftlen == 0) {
4466             ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4467             return totcnt;
4468         }
4469         advoffset += cplen;
4470         curbuf += cnt;
4471     
4472         /*
4473          * Display driver configuration and information for the board.
4474          */
4475         cp = boardp->prtbuf;
4476         cplen = asc_prt_driver_conf(shp, cp, ASC_PRTBUF_SIZE);
4477         ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4478         cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4479         totcnt += cnt;
4480         leftlen -= cnt;
4481         if (leftlen == 0) {
4482             ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4483             return totcnt;
4484         }
4485         advoffset += cplen;
4486         curbuf += cnt;
4487     
4488     #ifdef ADVANSYS_STATS
4489         /*
4490          * Display driver statistics for the board.
4491          */
4492         cp = boardp->prtbuf;
4493         cplen = asc_prt_board_stats(shp, cp, ASC_PRTBUF_SIZE);
4494         ASC_ASSERT(cplen <= ASC_PRTBUF_SIZE);
4495         cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4496         totcnt += cnt;
4497         leftlen -= cnt;
4498         if (leftlen == 0) {
4499             ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4500             return totcnt;
4501         }
4502         advoffset += cplen;
4503         curbuf += cnt;
4504     
4505         /*
4506          * Display driver statistics for each target.
4507          */
4508         for (tgt_id = 0; tgt_id <= ADV_MAX_TID; tgt_id++) {
4509           cp = boardp->prtbuf;
4510           cplen = asc_prt_target_stats(shp, tgt_id, cp, ASC_PRTBUF_SIZE);
4511           ASC_ASSERT(cplen <= ASC_PRTBUF_SIZE);
4512           cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4513           totcnt += cnt;
4514           leftlen -= cnt;
4515           if (leftlen == 0) {
4516             ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4517             return totcnt;
4518           }
4519           advoffset += cplen;
4520           curbuf += cnt;
4521         }
4522     #endif /* ADVANSYS_STATS */
4523     
4524         /*
4525          * Display Asc Library dynamic configuration information
4526          * for the board.
4527          */
4528         cp = boardp->prtbuf;
4529         if (ASC_NARROW_BOARD(boardp)) {
4530             cplen = asc_prt_asc_board_info(shp, cp, ASC_PRTBUF_SIZE);
4531         } else {
4532             cplen = asc_prt_adv_board_info(shp, cp, ASC_PRTBUF_SIZE);
4533         }
4534         ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4535         cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4536         totcnt += cnt;
4537         leftlen -= cnt;
4538         if (leftlen == 0) {
4539             ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4540             return totcnt;
4541         }
4542         advoffset += cplen;
4543         curbuf += cnt;
4544     
4545         ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4546     
4547         return totcnt;
4548     }
4549     #endif /* CONFIG_PROC_FS */
4550     
4551     /*
4552      * advansys_detect()
4553      *
4554      * Detect function for AdvanSys adapters.
4555      *
4556      * Argument is a pointer to the host driver's scsi_hosts entry.
4557      *
4558      * Return number of adapters found.
4559      *
4560      * Note: Because this function is called during system initialization
4561      * it must not call SCSI mid-level functions including scsi_malloc()
4562      * and scsi_free().
4563      */
4564     ASC_INITFUNC(
4565     int,
4566     advansys_detect(Scsi_Host_Template *tpnt)
4567     )
4568     {
4569         static int          detect_called = ASC_FALSE;
4570         int                 iop;
4571         int                 bus;
4572         struct Scsi_Host    *shp = NULL;
4573         asc_board_t         *boardp = NULL;
4574         ASC_DVC_VAR         *asc_dvc_varp = NULL;
4575         ADV_DVC_VAR         *adv_dvc_varp = NULL;
4576         adv_sgblk_t         *sgp = NULL;
4577         int                 ioport = 0;
4578         int                 share_irq = FALSE;
4579         int                 iolen = 0;
4580     #ifdef CONFIG_PCI
4581         int                 pci_init_search = 0;
4582         struct pci_dev      *pci_devicep[ASC_NUM_BOARD_SUPPORTED];
4583         int                 pci_card_cnt_max = 0;
4584         int                 pci_card_cnt = 0;
4585         struct pci_dev      *pci_devp = NULL;
4586         int                 pci_device_id_cnt = 0;
4587         unsigned int        pci_device_id[ASC_PCI_DEVICE_ID_CNT] = {
4588                                         ASC_PCI_DEVICE_ID_1100,
4589                                         ASC_PCI_DEVICE_ID_1200,
4590                                         ASC_PCI_DEVICE_ID_1300,
4591                                         ASC_PCI_DEVICE_ID_2300,
4592                                         ASC_PCI_DEVICE_ID_2500,
4593                                         ASC_PCI_DEVICE_ID_2700
4594                             };
4595         ADV_PADDR           pci_memory_address;
4596     #endif /* CONFIG_PCI */
4597         int                 warn_code, err_code;
4598         int                 ret;
4599     
4600         if (detect_called == ASC_FALSE) {
4601             detect_called = ASC_TRUE;
4602         } else {
4603             printk("AdvanSys SCSI: advansys_detect() multiple calls ignored\n");
4604             return 0;
4605         }
4606     
4607         ASC_DBG(1, "advansys_detect: begin\n");
4608     
4609         /*
4610          * XXX - Remove this comment and the next line when SCSI mid-level
4611          * no longer acquires 'io_request_lock' before calling the SCSI
4612          * low-level detect entrypoint.
4613          */
4614         ASC_UNLOCK_IO_REQUEST_LOCK
4615     
4616     #if ASC_LINUX_KERNEL24
4617         tpnt->proc_name = "advansys";
4618     #elif ASC_LINUX_KERNEL22
4619         tpnt->proc_dir = &proc_scsi_advansys;
4620     #endif
4621     
4622         asc_board_count = 0;
4623     
4624         /*
4625          * If I/O port probing has been modified, then verify and
4626          * clean-up the 'asc_ioport' list.
4627          */
4628         if (asc_iopflag == ASC_TRUE) {
4629             for (ioport = 0; ioport < ASC_NUM_IOPORT_PROBE; ioport++) {
4630                 ASC_DBG2(1, "advansys_detect: asc_ioport[%d] 0x%x\n",
4631                     ioport, asc_ioport[ioport]);
4632                 if (asc_ioport[ioport] != 0) {
4633                     for (iop = 0; iop < ASC_IOADR_TABLE_MAX_IX; iop++) {
4634                         if (_asc_def_iop_base[iop] == asc_ioport[ioport]) {
4635                             break;
4636                         }
4637                     }
4638                     if (iop == ASC_IOADR_TABLE_MAX_IX) {
4639                         printk(
4640     "AdvanSys SCSI: specified I/O Port 0x%X is invalid\n",
4641                             asc_ioport[ioport]);
4642                         asc_ioport[ioport] = 0;
4643                     }
4644                 }
4645             }
4646             ioport = 0;
4647         }
4648     
4649         for (bus = 0; bus < ASC_NUM_BUS; bus++) {
4650     
4651             ASC_DBG2(1, "advansys_detect: bus search type %d (%s)\n",
4652                 bus, asc_bus_name[bus]);
4653             iop = 0;
4654     
4655             while (asc_board_count < ASC_NUM_BOARD_SUPPORTED) {
4656     
4657                 ASC_DBG1(2, "advansys_detect: asc_board_count %d\n",
4658                     asc_board_count);
4659     
4660                 switch (asc_bus[bus]) {
4661                 case ASC_IS_ISA:
4662                 case ASC_IS_VL:
4663     #ifdef CONFIG_ISA
4664                     if (asc_iopflag == ASC_FALSE) {
4665                         iop = AscSearchIOPortAddr(iop, asc_bus[bus]);
4666                     } else {
4667                         /*
4668                          * ISA and VL I/O port scanning has either been
4669                          * eliminated or limited to selected ports on
4670                          * the LILO command line, /etc/lilo.conf, or
4671                          * by setting variables when the module was loaded.
4672                          */
4673                         ASC_DBG(1, "advansys_detect: I/O port scanning modified\n");
4674                     ioport_try_again:
4675                         iop = 0;
4676                         for (; ioport < ASC_NUM_IOPORT_PROBE; ioport++) {
4677                             if ((iop = asc_ioport[ioport]) != 0) {
4678                                 break;
4679                             }
4680                         }
4681                         if (iop) {
4682                             ASC_DBG1(1,
4683                                     "advansys_detect: probing I/O port 0x%x...\n",
4684                                 iop);
4685                             if (check_region(iop, ASC_IOADR_GAP) != 0) {
4686                                 printk(
4687     "AdvanSys SCSI: specified I/O Port 0x%X is busy\n", iop);
4688                                 /* Don't try this I/O port twice. */
4689                                 asc_ioport[ioport] = 0;
4690                                 goto ioport_try_again;
4691                             } else if (AscFindSignature(iop) == ASC_FALSE) {
4692                                 printk(
4693     "AdvanSys SCSI: specified I/O Port 0x%X has no adapter\n", iop);
4694                                 /* Don't try this I/O port twice. */
4695                                 asc_ioport[ioport] = 0;
4696                                 goto ioport_try_again;
4697                             } else {
4698                                 /*
4699                                  * If this isn't an ISA board, then it must be
4700                                  * a VL board. If currently looking an ISA
4701                                  * board is being looked for then try for
4702                                  * another ISA board in 'asc_ioport'.
4703                                  */
4704                                 if (asc_bus[bus] == ASC_IS_ISA &&
4705                                     (AscGetChipVersion(iop, ASC_IS_ISA) &
4706                                      ASC_CHIP_VER_ISA_BIT) == 0) {
4707                                      /*
4708                                       * Don't clear 'asc_ioport[ioport]'. Try
4709                                       * this board again for VL. Increment
4710                                       * 'ioport' past this board.
4711                                       */
4712                                      ioport++;
4713                                      goto ioport_try_again;
4714                                 }
4715                             }
4716                             /*
4717                              * This board appears good, don't try the I/O port
4718                              * again by clearing its value. Increment 'ioport'
4719                              * for the next iteration.
4720                              */
4721                             asc_ioport[ioport++] = 0;
4722                         }
4723                     }
4724     #endif /* CONFIG_ISA */
4725                     break;
4726     
4727                 case ASC_IS_EISA:
4728     #ifdef CONFIG_ISA
4729                     iop = AscSearchIOPortAddr(iop, asc_bus[bus]);
4730     #endif /* CONFIG_ISA */
4731                     break;
4732     
4733                 case ASC_IS_PCI:
4734     #ifdef CONFIG_PCI
4735                     if (pci_init_search == 0) {
4736                         int i, j;
4737     
4738                         pci_init_search = 1;
4739     
4740                         /* Find all PCI cards. */
4741                         while (pci_device_id_cnt < ASC_PCI_DEVICE_ID_CNT) {
4742                             if ((pci_devp = pci_find_device(ASC_PCI_VENDORID,
4743                                 pci_device_id[pci_device_id_cnt], pci_devp)) ==
4744                                 NULL) {
4745                                 pci_device_id_cnt++;
4746                             } else {
4747     #if ASC_LINUX_KERNEL24
4748                                 if (pci_enable_device(pci_devp) == 0) {
4749                                     pci_devicep[pci_card_cnt_max++] = pci_devp;
4750                                 }
4751     #elif ASC_LINUX_KERNEL22
4752                                 pci_devicep[pci_card_cnt_max++] = pci_devp;
4753     #endif
4754                             }
4755                         }
4756     
4757                         /*
4758                          * Sort PCI cards in ascending order by PCI Bus, Slot,
4759                          * and Device Number.
4760                          */
4761                         for (i = 0; i < pci_card_cnt_max - 1; i++)
4762                         {
4763                             for (j = i + 1; j < pci_card_cnt_max; j++) {
4764                                 if ((pci_devicep[j]->bus->number <
4765                                      pci_devicep[i]->bus->number) ||
4766                                     ((pci_devicep[j]->bus->number ==
4767                                       pci_devicep[i]->bus->number) &&
4768                                       (pci_devicep[j]->devfn <
4769                                        pci_devicep[i]->devfn))) {
4770                                     pci_devp = pci_devicep[i];
4771                                     pci_devicep[i] = pci_devicep[j];
4772                                     pci_devicep[j] = pci_devp;
4773                                 }
4774                             }
4775                         }
4776     
4777                         pci_card_cnt = 0;
4778                     } else {
4779                         pci_card_cnt++;
4780                     }
4781     
4782                     if (pci_card_cnt == pci_card_cnt_max) {
4783                         iop = 0;
4784                     } else {
4785                         pci_devp = pci_devicep[pci_card_cnt];
4786     
4787                         ASC_DBG2(2,
4788                             "advansys_detect: devfn %d, bus number %d\n",
4789                             pci_devp->devfn, pci_devp->bus->number);
4790     #if ASC_LINUX_KERNEL24
4791                         iop = pci_resource_start(pci_devp, 0);
4792     #elif ASC_LINUX_KERNEL22
4793                         iop = pci_devp->base_address[0] & PCI_IOADDRESS_MASK;
4794     #endif
4795                         ASC_DBG2(1,
4796                             "advansys_detect: vendorID %X, deviceID %X\n",
4797                             pci_devp->vendor, pci_devp->device);
4798                         ASC_DBG2(2, "advansys_detect: iop %X, irqLine %d\n",
4799                             iop, pci_devp->irq);
4800                     }
4801     #endif /* CONFIG_PCI */
4802                     break;
4803     
4804                 default:
4805                     ASC_PRINT1("advansys_detect: unknown bus type: %d\n",
4806                         asc_bus[bus]);
4807                     break;
4808                 }
4809                 ASC_DBG1(1, "advansys_detect: iop 0x%x\n", iop);
4810     
4811                 /*
4812                  * Adapter not found, try next bus type.
4813                  */
4814                 if (iop == 0) {
4815                     break;
4816                 }
4817     
4818                 /*
4819                  * Adapter found.
4820                  *
4821                  * Register the adapter, get its configuration, and
4822                  * initialize it.
4823                  */
4824                 ASC_DBG(2, "advansys_detect: scsi_register()\n");
4825                 shp = scsi_register(tpnt, sizeof(asc_board_t));
4826     
4827                 if (shp == NULL) {
4828                     continue;
4829                 }
4830     #ifdef CONFIG_PCI
4831     	    scsi_set_pci_device(shp, pci_devp);
4832     #endif
4833     
4834                 /* Save a pointer to the Scsi_host of each board found. */
4835                 asc_host[asc_board_count++] = shp;
4836     
4837                 /* Initialize private per board data */
4838                 boardp = ASC_BOARDP(shp);
4839                 memset(boardp, 0, sizeof(asc_board_t));
4840                 boardp->id = asc_board_count - 1;
4841     
4842                 /* Initialize spinlock. */
4843                 boardp->lock = SPIN_LOCK_UNLOCKED;
4844     
4845                 /*
4846                  * Handle both narrow and wide boards.
4847                  *
4848                  * If a Wide board was detected, set the board structure
4849                  * wide board flag. Set-up the board structure based on
4850                  * the board type.
4851                  */
4852     #ifdef CONFIG_PCI
4853                 if (asc_bus[bus] == ASC_IS_PCI &&
4854                     (pci_devp->device == ASC_PCI_DEVICE_ID_2300 ||
4855                      pci_devp->device == ASC_PCI_DEVICE_ID_2500 ||
4856                      pci_devp->device == ASC_PCI_DEVICE_ID_2700))
4857                 {
4858                     boardp->flags |= ASC_IS_WIDE_BOARD;
4859                 }
4860     #endif /* CONFIG_PCI */
4861     
4862                 if (ASC_NARROW_BOARD(boardp)) {
4863                     ASC_DBG(1, "advansys_detect: narrow board\n");
4864                     asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
4865                     asc_dvc_varp->bus_type = asc_bus[bus];
4866                     asc_dvc_varp->drv_ptr = boardp;
4867                     asc_dvc_varp->cfg = &boardp->dvc_cfg.asc_dvc_cfg;
4868                     asc_dvc_varp->cfg->overrun_buf = &overrun_buf[0];
4869                     asc_dvc_varp->iop_base = iop;
4870                     asc_dvc_varp->isr_callback = asc_isr_callback;
4871                 } else {
4872                     ASC_DBG(1, "advansys_detect: wide board\n");
4873                     adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
4874                     adv_dvc_varp->drv_ptr = boardp;
4875                     adv_dvc_varp->cfg = &boardp->dvc_cfg.adv_dvc_cfg;
4876                     adv_dvc_varp->isr_callback = adv_isr_callback;
4877                     adv_dvc_varp->async_callback = adv_async_callback;
4878     #ifdef CONFIG_PCI
4879                     if (pci_devp->device == ASC_PCI_DEVICE_ID_2300)
4880                     {
4881                         ASC_DBG(1, "advansys_detect: ASC-3550\n");
4882                         adv_dvc_varp->chip_type = ADV_CHIP_ASC3550;
4883                     } else if (pci_devp->device == ASC_PCI_DEVICE_ID_2500)
4884                     {
4885                         ASC_DBG(1, "advansys_detect: ASC-38C0800\n");
4886                         adv_dvc_varp->chip_type = ADV_CHIP_ASC38C0800;
4887                     } else
4888                     {
4889                         ASC_DBG(1, "advansys_detect: ASC-38C1600\n");
4890                         adv_dvc_varp->chip_type = ADV_CHIP_ASC38C1600;
4891                     }
4892     #endif /* CONFIG_PCI */
4893     
4894                     /*
4895                      * Map the board's registers into virtual memory for
4896                      * PCI slave access. Only memory accesses are used to
4897                      * access the board's registers.
4898                      *
4899                      * Note: The PCI register base address is not always
4900                      * page aligned, but the address passed to ioremap()
4901                      * must be page aligned. It is guaranteed that the
4902                      * PCI register base address will not cross a page
4903                      * boundary.
4904                      */
4905                     if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
4906                     {
4907                         iolen = ADV_3550_IOLEN;
4908                     } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
4909                     {
4910                         iolen = ADV_38C0800_IOLEN;
4911                     } else
4912                     {
4913                         iolen = ADV_38C1600_IOLEN;
4914                     }
4915     #ifdef CONFIG_PCI
4916     #if ASC_LINUX_KERNEL24
4917                     pci_memory_address = pci_resource_start(pci_devp, 1);
4918     #elif ASC_LINUX_KERNEL22
4919                     pci_memory_address = pci_devp->base_address[1];
4920     #endif
4921                     ASC_DBG1(1, "advansys_detect: pci_memory_address: 0x%lx\n",
4922                         (ulong) pci_memory_address);
4923                     if ((boardp->ioremap_addr =
4924                         ioremap(pci_memory_address & PAGE_MASK,
4925                              PAGE_SIZE)) == 0) {
4926                        ASC_PRINT3(
4927     "advansys_detect: board %d: ioremap(%x, %d) returned NULL\n",
4928                            boardp->id, pci_memory_address, iolen);
4929                        scsi_unregister(shp);
4930                        asc_board_count--;
4931                        continue;
4932                     }
4933                     ASC_DBG1(1, "advansys_detect: ioremap_addr: 0x%lx\n",
4934                         (ulong) boardp->ioremap_addr);
4935                     adv_dvc_varp->iop_base = (AdvPortAddr)
4936                         (boardp->ioremap_addr +
4937                          (pci_memory_address - (pci_memory_address & PAGE_MASK)));
4938                     ASC_DBG1(1, "advansys_detect: iop_base: 0x%lx\n",
4939                         adv_dvc_varp->iop_base);
4940     #endif /* CONFIG_PCI */
4941     
4942                     /*
4943                      * Even though it isn't used to access wide boards, other
4944                      * than for the debug line below, save I/O Port address so
4945                      * that it can be reported.
4946                      */
4947                     boardp->ioport = iop;
4948     
4949                     ASC_DBG2(1,
4950     "advansys_detect: iopb_chip_id_1 0x%x, iopw_chip_id_0 0x%x\n",
4951                         (ushort) inp(iop + 1), (ushort) inpw(iop));
4952                 }
4953     
4954     #ifdef CONFIG_PROC_FS
4955                 /*
4956                  * Allocate buffer for printing information from
4957                  * /proc/scsi/advansys/[0...].
4958                  */
4959                 if ((boardp->prtbuf =
4960                     kmalloc(ASC_PRTBUF_SIZE, GFP_ATOMIC)) == NULL) {
4961                     ASC_PRINT3(
4962     "advansys_detect: board %d: kmalloc(%d, %d) returned NULL\n",
4963                         boardp->id, ASC_PRTBUF_SIZE, GFP_ATOMIC);
4964                     scsi_unregister(shp);
4965                     asc_board_count--;
4966                     continue;
4967                 }
4968     #endif /* CONFIG_PROC_FS */
4969     
4970                 if (ASC_NARROW_BOARD(boardp)) {
4971                     /*
4972                      * Set the board bus type and PCI IRQ before
4973                      * calling AscInitGetConfig().
4974                      */
4975                     switch (asc_dvc_varp->bus_type) {
4976     #ifdef CONFIG_ISA
4977                     case ASC_IS_ISA:
4978                         shp->unchecked_isa_dma = TRUE;
4979                         share_irq = FALSE;
4980                         break;
4981                     case ASC_IS_VL:
4982                         shp->unchecked_isa_dma = FALSE;
4983                         share_irq = FALSE;
4984                         break;
4985                     case ASC_IS_EISA:
4986                         shp->unchecked_isa_dma = FALSE;
4987                         share_irq = TRUE;
4988                         break;
4989     #endif /* CONFIG_ISA */
4990     #ifdef CONFIG_PCI
4991                     case ASC_IS_PCI:
4992                         shp->irq = asc_dvc_varp->irq_no = pci_devp->irq;
4993                         asc_dvc_varp->cfg->pci_device_id = pci_devp->device;
4994                         asc_dvc_varp->cfg->pci_slot_info =
4995                             ASC_PCI_MKID(pci_devp->bus->number,
4996                                 PCI_SLOT(pci_devp->devfn),
4997                                 PCI_FUNC(pci_devp->devfn));
4998                         shp->unchecked_isa_dma = FALSE;
4999                         share_irq = TRUE;
5000                         break;
5001     #endif /* CONFIG_PCI */
5002                     default:
5003                         ASC_PRINT2(
5004     "advansys_detect: board %d: unknown adapter type: %d\n",
5005                             boardp->id, asc_dvc_varp->bus_type);
5006                         shp->unchecked_isa_dma = TRUE;
5007                         share_irq = FALSE;
5008                         break;
5009                     }
5010                 } else {
5011                     /*
5012                      * For Wide boards set PCI information before calling
5013                      * AdvInitGetConfig().
5014                      */
5015     #ifdef CONFIG_PCI
5016                     shp->irq = adv_dvc_varp->irq_no = pci_devp->irq;
5017                     adv_dvc_varp->cfg->pci_device_id = pci_devp->device;
5018                     adv_dvc_varp->cfg->pci_slot_info =
5019                         ASC_PCI_MKID(pci_devp->bus->number,
5020                             PCI_SLOT(pci_devp->devfn),
5021                             PCI_FUNC(pci_devp->devfn));
5022                     shp->unchecked_isa_dma = FALSE;
5023                     share_irq = TRUE;
5024     #endif /* CONFIG_PCI */
5025                 }
5026     
5027                 /*
5028                  * Read the board configuration.
5029                  */
5030                 if (ASC_NARROW_BOARD(boardp)) {
5031                      /*
5032                       * NOTE: AscInitGetConfig() may change the board's
5033                       * bus_type value. The asc_bus[bus] value should no
5034                       * longer be used. If the bus_type field must be
5035                       * referenced only use the bit-wise AND operator "&".
5036                       */
5037                     ASC_DBG(2, "advansys_detect: AscInitGetConfig()\n");
5038                     switch(ret = AscInitGetConfig(asc_dvc_varp)) {
5039                     case 0:    /* No error */
5040                         break;
5041                     case ASC_WARN_IO_PORT_ROTATE:
5042                         ASC_PRINT1(
5043     "AscInitGetConfig: board %d: I/O port address modified\n",
5044                             boardp->id);
5045                         break;
5046                     case ASC_WARN_AUTO_CONFIG:
5047                         ASC_PRINT1(
5048     "AscInitGetConfig: board %d: I/O port increment switch enabled\n",
5049                             boardp->id);
5050                         break;
5051                     case ASC_WARN_EEPROM_CHKSUM:
5052                         ASC_PRINT1(
5053     "AscInitGetConfig: board %d: EEPROM checksum error\n",
5054                             boardp->id);
5055                         break;
5056                     case ASC_WARN_IRQ_MODIFIED:
5057                         ASC_PRINT1(
5058     "AscInitGetConfig: board %d: IRQ modified\n",
5059                             boardp->id);
5060                         break;
5061                     case ASC_WARN_CMD_QNG_CONFLICT:
5062                         ASC_PRINT1(
5063     "AscInitGetConfig: board %d: tag queuing enabled w/o disconnects\n",
5064                             boardp->id);
5065                         break;
5066                     default:
5067                         ASC_PRINT2(
5068     "AscInitGetConfig: board %d: unknown warning: 0x%x\n",
5069                             boardp->id, ret);
5070                         break;
5071                     }
5072                     if ((err_code = asc_dvc_varp->err_code) != 0) {
5073                         ASC_PRINT3(
5074     "AscInitGetConfig: board %d error: init_state 0x%x, err_code 0x%x\n",
5075                             boardp->id, asc_dvc_varp->init_state,
5076                             asc_dvc_varp->err_code);
5077                     }
5078                 } else {
5079                     ASC_DBG(2, "advansys_detect: AdvInitGetConfig()\n");
5080                     if ((ret = AdvInitGetConfig(adv_dvc_varp)) != 0) {
5081                         ASC_PRINT2("AdvInitGetConfig: board %d: warning: 0x%x\n",
5082                             boardp->id, ret);
5083                     }
5084                     if ((err_code = adv_dvc_varp->err_code) != 0) {
5085                         ASC_PRINT2(
5086     "AdvInitGetConfig: board %d error: err_code 0x%x\n",
5087                             boardp->id, adv_dvc_varp->err_code);
5088                     }
5089                 }
5090     
5091                 if (err_code != 0) {
5092     #ifdef CONFIG_PROC_FS
5093                     kfree(boardp->prtbuf);
5094     #endif /* CONFIG_PROC_FS */
5095                     scsi_unregister(shp);
5096                     asc_board_count--;
5097                     continue;
5098                 }
5099     
5100                 /*
5101                  * Save the EEPROM configuration so that it can be displayed
5102                  * from /proc/scsi/advansys/[0...].
5103                  */
5104                 if (ASC_NARROW_BOARD(boardp)) {
5105     
5106                     ASCEEP_CONFIG *ep;
5107     
5108                     /*
5109                      * Set the adapter's target id bit in the 'init_tidmask' field.
5110                      */
5111                     boardp->init_tidmask |=
5112                         ADV_TID_TO_TIDMASK(asc_dvc_varp->cfg->chip_scsi_id);
5113     
5114                     /*
5115                      * Save EEPROM settings for the board.
5116                      */
5117                     ep = &boardp->eep_config.asc_eep;
5118     
5119                     ep->init_sdtr = asc_dvc_varp->cfg->sdtr_enable;
5120                     ep->disc_enable = asc_dvc_varp->cfg->disc_enable;
5121                     ep->use_cmd_qng = asc_dvc_varp->cfg->cmd_qng_enabled;
5122                     ASC_EEP_SET_DMA_SPD(ep, asc_dvc_varp->cfg->isa_dma_speed);
5123                     ep->start_motor = asc_dvc_varp->start_motor;
5124                     ep->cntl = asc_dvc_varp->dvc_cntl;
5125                     ep->no_scam = asc_dvc_varp->no_scam;
5126                     ep->max_total_qng = asc_dvc_varp->max_total_qng;
5127                     ASC_EEP_SET_CHIP_ID(ep, asc_dvc_varp->cfg->chip_scsi_id);
5128                     /* 'max_tag_qng' is set to the same value for every device. */
5129                     ep->max_tag_qng = asc_dvc_varp->cfg->max_tag_qng[0];
5130                     ep->adapter_info[0] = asc_dvc_varp->cfg->adapter_info[0];
5131                     ep->adapter_info[1] = asc_dvc_varp->cfg->adapter_info[1];
5132                     ep->adapter_info[2] = asc_dvc_varp->cfg->adapter_info[2];
5133                     ep->adapter_info[3] = asc_dvc_varp->cfg->adapter_info[3];
5134                     ep->adapter_info[4] = asc_dvc_varp->cfg->adapter_info[4];
5135                     ep->adapter_info[5] = asc_dvc_varp->cfg->adapter_info[5];
5136                     ep->adapter_info[6] = asc_dvc_varp->cfg->adapter_info[6];
5137     
5138                    /*
5139                     * Modify board configuration.
5140                     */
5141                     ASC_DBG(2, "advansys_detect: AscInitSetConfig()\n");
5142                     switch (ret = AscInitSetConfig(asc_dvc_varp)) {
5143                     case 0:    /* No error. */
5144                         break;
5145                     case ASC_WARN_IO_PORT_ROTATE:
5146                         ASC_PRINT1(
5147     "AscInitSetConfig: board %d: I/O port address modified\n",
5148                             boardp->id);
5149                         break;
5150                     case ASC_WARN_AUTO_CONFIG:
5151                         ASC_PRINT1(
5152     "AscInitSetConfig: board %d: I/O port increment switch enabled\n",
5153                             boardp->id);
5154                         break;
5155                     case ASC_WARN_EEPROM_CHKSUM:
5156                         ASC_PRINT1(
5157     "AscInitSetConfig: board %d: EEPROM checksum error\n",
5158                             boardp->id);
5159                         break;
5160                     case ASC_WARN_IRQ_MODIFIED:
5161                         ASC_PRINT1(
5162     "AscInitSetConfig: board %d: IRQ modified\n",
5163                             boardp->id);
5164                         break;
5165                     case ASC_WARN_CMD_QNG_CONFLICT:
5166                         ASC_PRINT1(
5167     "AscInitSetConfig: board %d: tag queuing w/o disconnects\n",
5168                             boardp->id);
5169                         break;
5170                     default:
5171                         ASC_PRINT2(
5172     "AscInitSetConfig: board %d: unknown warning: 0x%x\n",
5173                             boardp->id, ret);
5174                         break;
5175                     }
5176                     if (asc_dvc_varp->err_code != 0) {
5177                         ASC_PRINT3(
5178     "AscInitSetConfig: board %d error: init_state 0x%x, err_code 0x%x\n",
5179                             boardp->id, asc_dvc_varp->init_state,
5180                             asc_dvc_varp->err_code);
5181     #ifdef CONFIG_PROC_FS
5182                         kfree(boardp->prtbuf);
5183     #endif /* CONFIG_PROC_FS */
5184                         scsi_unregister(shp);
5185                         asc_board_count--;
5186                         continue;
5187                     }
5188     
5189                     /*
5190                      * Finish initializing the 'Scsi_Host' structure.
5191                      */
5192                     /* AscInitSetConfig() will set the IRQ for non-PCI boards. */
5193                     if ((asc_dvc_varp->bus_type & ASC_IS_PCI) == 0) {
5194                         shp->irq = asc_dvc_varp->irq_no;
5195                     }
5196                 } else {
5197                     ADVEEP_3550_CONFIG      *ep_3550;
5198                     ADVEEP_38C0800_CONFIG   *ep_38C0800;
5199                     ADVEEP_38C1600_CONFIG   *ep_38C1600;
5200     
5201                     /*
5202                      * Save Wide EEP Configuration Information.
5203                      */
5204                     if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
5205                     {
5206                         ep_3550 = &boardp->eep_config.adv_3550_eep;
5207     
5208                         ep_3550->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
5209                         ep_3550->max_host_qng = adv_dvc_varp->max_host_qng;
5210                         ep_3550->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
5211                         ep_3550->termination = adv_dvc_varp->cfg->termination;
5212                         ep_3550->disc_enable = adv_dvc_varp->cfg->disc_enable;
5213                         ep_3550->bios_ctrl = adv_dvc_varp->bios_ctrl;
5214                         ep_3550->wdtr_able = adv_dvc_varp->wdtr_able;
5215                         ep_3550->sdtr_able = adv_dvc_varp->sdtr_able;
5216                         ep_3550->ultra_able = adv_dvc_varp->ultra_able;
5217                         ep_3550->tagqng_able = adv_dvc_varp->tagqng_able;
5218                         ep_3550->start_motor = adv_dvc_varp->start_motor;
5219                         ep_3550->scsi_reset_delay = adv_dvc_varp->scsi_reset_wait;
5220                         ep_3550->serial_number_word1 =
5221                             adv_dvc_varp->cfg->serial1;
5222                         ep_3550->serial_number_word2 =
5223                             adv_dvc_varp->cfg->serial2;
5224                         ep_3550->serial_number_word3 =
5225                             adv_dvc_varp->cfg->serial3;
5226                     } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
5227                     {
5228                         ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
5229     
5230                         ep_38C0800->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
5231                         ep_38C0800->max_host_qng = adv_dvc_varp->max_host_qng;
5232                         ep_38C0800->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
5233                         ep_38C0800->termination_lvd =
5234                             adv_dvc_varp->cfg->termination;
5235                         ep_38C0800->disc_enable = adv_dvc_varp->cfg->disc_enable;
5236                         ep_38C0800->bios_ctrl = adv_dvc_varp->bios_ctrl;
5237                         ep_38C0800->wdtr_able = adv_dvc_varp->wdtr_able;
5238                         ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
5239                         ep_38C0800->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
5240                         ep_38C0800->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
5241                         ep_38C0800->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
5242                         ep_38C0800->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
5243                         ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
5244                         ep_38C0800->start_motor = adv_dvc_varp->start_motor;
5245                         ep_38C0800->scsi_reset_delay =
5246                             adv_dvc_varp->scsi_reset_wait;
5247                         ep_38C0800->serial_number_word1 =
5248                             adv_dvc_varp->cfg->serial1;
5249                         ep_38C0800->serial_number_word2 =
5250                             adv_dvc_varp->cfg->serial2;
5251                         ep_38C0800->serial_number_word3 =
5252                             adv_dvc_varp->cfg->serial3;
5253                     } else
5254                     {
5255                         ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
5256     
5257                         ep_38C1600->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
5258                         ep_38C1600->max_host_qng = adv_dvc_varp->max_host_qng;
5259                         ep_38C1600->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
5260                         ep_38C1600->termination_lvd =
5261                             adv_dvc_varp->cfg->termination;
5262                         ep_38C1600->disc_enable = adv_dvc_varp->cfg->disc_enable;
5263                         ep_38C1600->bios_ctrl = adv_dvc_varp->bios_ctrl;
5264                         ep_38C1600->wdtr_able = adv_dvc_varp->wdtr_able;
5265                         ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
5266                         ep_38C1600->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
5267                         ep_38C1600->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
5268                         ep_38C1600->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
5269                         ep_38C1600->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
5270                         ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
5271                         ep_38C1600->start_motor = adv_dvc_varp->start_motor;
5272                         ep_38C1600->scsi_reset_delay =
5273                             adv_dvc_varp->scsi_reset_wait;
5274                         ep_38C1600->serial_number_word1 =
5275                             adv_dvc_varp->cfg->serial1;
5276                         ep_38C1600->serial_number_word2 =
5277                             adv_dvc_varp->cfg->serial2;
5278                         ep_38C1600->serial_number_word3 =
5279                             adv_dvc_varp->cfg->serial3;
5280                     }
5281     
5282                     /*
5283                      * Set the adapter's target id bit in the 'init_tidmask' field.
5284                      */
5285                     boardp->init_tidmask |=
5286                         ADV_TID_TO_TIDMASK(adv_dvc_varp->chip_scsi_id);
5287     
5288                     /*
5289                      * Finish initializing the 'Scsi_Host' structure.
5290                      */
5291                     shp->irq = adv_dvc_varp->irq_no;
5292                 }
5293     
5294                 /*
5295                  * Channels are numbered beginning with 0. For AdvanSys one host
5296                  * structure supports one channel. Multi-channel boards have a
5297                  * separate host structure for each channel.
5298                  */
5299                 shp->max_channel = 0;
5300                 if (ASC_NARROW_BOARD(boardp)) {
5301                     shp->max_id = ASC_MAX_TID + 1;
5302                     shp->max_lun = ASC_MAX_LUN + 1;
5303     
5304                     shp->io_port = asc_dvc_varp->iop_base;
5305                     boardp->asc_n_io_port = ASC_IOADR_GAP;
5306                     shp->this_id = asc_dvc_varp->cfg->chip_scsi_id;
5307     
5308                     /* Set maximum number of queues the adapter can handle. */
5309                     shp->can_queue = asc_dvc_varp->max_total_qng;
5310                 } else {
5311                     shp->max_id = ADV_MAX_TID + 1;
5312                     shp->max_lun = ADV_MAX_LUN + 1;
5313     
5314                     /*
5315                      * Save the I/O Port address and length even though
5316                      * I/O ports are not used to access Wide boards.
5317                      * Instead the Wide boards are accessed with
5318                      * PCI Memory Mapped I/O.
5319                      */
5320                     shp->io_port = iop;
5321                     boardp->asc_n_io_port = iolen;
5322     
5323                     shp->this_id = adv_dvc_varp->chip_scsi_id;
5324     
5325                     /* Set maximum number of queues the adapter can handle. */
5326                     shp->can_queue = adv_dvc_varp->max_host_qng;
5327                 }
5328     
5329                 /*
5330                  * 'n_io_port' currently is one byte.
5331                  *
5332                  * Set a value to 'n_io_port', but never referenced it because
5333                  * it may be truncated.
5334                  */
5335                 shp->n_io_port = boardp->asc_n_io_port <= 255 ?
5336                     boardp->asc_n_io_port : 255;
5337     
5338                 /*
5339                  * Following v1.3.89, 'cmd_per_lun' is no longer needed
5340                  * and should be set to zero.
5341                  *
5342                  * But because of a bug introduced in v1.3.89 if the driver is
5343                  * compiled as a module and 'cmd_per_lun' is zero, the Mid-Level
5344                  * SCSI function 'allocate_device' will panic. To allow the driver
5345                  * to work as a module in these kernels set 'cmd_per_lun' to 1.
5346                  */
5347     #ifdef MODULE
5348                 shp->cmd_per_lun = 1;
5349     #else /* MODULE */
5350                 shp->cmd_per_lun = 0;
5351     #endif /* MODULE */
5352                 /*
5353                  * Use the host 'select_queue_depths' function to determine
5354                  * the number of commands to queue per device.
5355                  */
5356                 shp->select_queue_depths = advansys_select_queue_depths;
5357     
5358                 /*
5359                  * Set the maximum number of scatter-gather elements the
5360                  * adapter can handle.
5361                  */
5362                 if (ASC_NARROW_BOARD(boardp)) {
5363                     /*
5364                      * Allow two commands with 'sg_tablesize' scatter-gather
5365                      * elements to be executed simultaneously. This value is
5366                      * the theoretical hardware limit. It may be decreased
5367                      * below.
5368                      */
5369                     shp->sg_tablesize =
5370                         (((asc_dvc_varp->max_total_qng - 2) / 2) *
5371                         ASC_SG_LIST_PER_Q) + 1;
5372                 } else {
5373                     shp->sg_tablesize = ADV_MAX_SG_LIST;
5374                 }
5375     
5376                 /*
5377                  * The value of 'sg_tablesize' can not exceed the SCSI
5378                  * mid-level driver definition of SG_ALL. SG_ALL also
5379                  * must not be exceeded, because it is used to define the
5380                  * size of the scatter-gather table in 'struct asc_sg_head'.
5381                  */
5382                 if (shp->sg_tablesize > SG_ALL) {
5383                     shp->sg_tablesize = SG_ALL;
5384                 }
5385     
5386                 ASC_DBG1(1, "advansys_detect: sg_tablesize: %d\n",
5387                     shp->sg_tablesize);
5388     
5389                 /* BIOS start address. */
5390                 if (ASC_NARROW_BOARD(boardp)) {
5391     #if ASC_LINUX_KERNEL24
5392                     shp->base =
5393     #elif ASC_LINUX_KERNEL22
5394                     shp->base = (char *)
5395     #endif
5396                             ((ulong) AscGetChipBiosAddress(
5397                                 asc_dvc_varp->iop_base,
5398                                 asc_dvc_varp->bus_type));
5399                 } else {
5400                     /*
5401                      * Fill-in BIOS board variables. The Wide BIOS saves
5402                      * information in LRAM that is used by the driver.
5403                      */
5404                     AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_SIGNATURE,
5405                         boardp->bios_signature);
5406                     AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_VERSION,
5407                         boardp->bios_version);
5408                     AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_CODESEG,
5409                         boardp->bios_codeseg);
5410                     AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_CODELEN,
5411                         boardp->bios_codelen);
5412     
5413                     ASC_DBG2(1,
5414                         "advansys_detect: bios_signature 0x%x, bios_version 0x%x\n",
5415                         boardp->bios_signature, boardp->bios_version);
5416     
5417                     ASC_DBG2(1,
5418                         "advansys_detect: bios_codeseg 0x%x, bios_codelen 0x%x\n",
5419                         boardp->bios_codeseg, boardp->bios_codelen);
5420     
5421                     /*
5422                      * If the BIOS saved a valid signature, then fill in
5423                      * the BIOS code segment base address.
5424                      */
5425                     if (boardp->bios_signature == 0x55AA) {
5426                         /*
5427                          * Convert x86 realmode code segment to a linear
5428                          * address by shifting left 4.
5429                          */
5430                         shp->base =
5431     #if ASC_LINUX_KERNEL22
5432                             (char *)
5433     #endif
5434                             ((ulong) boardp->bios_codeseg << 4);
5435                     } else {
5436                         shp->base = 0;
5437                     }
5438                 }
5439     
5440                 /*
5441                  * Register Board Resources - I/O Port, DMA, IRQ
5442                  */
5443     
5444                 /*
5445                  * Register I/O port range.
5446                  *
5447                  * For Wide boards the I/O ports are not used to access
5448                  * the board, but request the region anyway.
5449                  *
5450                  * 'shp->n_io_port' is not referenced, because it may be truncated.
5451                  */
5452                 ASC_DBG2(2,
5453                     "advansys_detect: request_region port 0x%lx, len 0x%x\n",
5454                     (ulong) shp->io_port, boardp->asc_n_io_port);
5455     #if ASC_LINUX_KERNEL24
5456                 if (request_region(shp->io_port, boardp->asc_n_io_port,
5457                                    "advansys") == NULL) {
5458                     ASC_PRINT3(
5459     "advansys_detect: board %d: request_region() failed, port 0x%lx, len 0x%x\n",
5460                         boardp->id, (ulong) shp->io_port, boardp->asc_n_io_port);
5461     #ifdef CONFIG_PROC_FS
5462                     kfree(boardp->prtbuf);
5463     #endif /* CONFIG_PROC_FS */
5464                     scsi_unregister(shp);
5465                     asc_board_count--;
5466                     continue;
5467                 }
5468     #elif ASC_LINUX_KERNEL22
5469                 request_region(shp->io_port, boardp->asc_n_io_port, "advansys");
5470     #endif
5471     
5472                 /* Register DMA Channel for Narrow boards. */
5473                 shp->dma_channel = NO_ISA_DMA; /* Default to no ISA DMA. */
5474     #ifdef CONFIG_ISA
5475                 if (ASC_NARROW_BOARD(boardp)) {
5476                     /* Register DMA channel for ISA bus. */
5477                     if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
5478                         shp->dma_channel = asc_dvc_varp->cfg->isa_dma_channel;
5479                         if ((ret =
5480                              request_dma(shp->dma_channel, "advansys")) != 0) {
5481                             ASC_PRINT3(
5482     "advansys_detect: board %d: request_dma() %d failed %d\n",
5483                                 boardp->id, shp->dma_channel, ret);
5484                             release_region(shp->io_port, boardp->asc_n_io_port);
5485     #ifdef CONFIG_PROC_FS
5486                             kfree(boardp->prtbuf);
5487     #endif /* CONFIG_PROC_FS */
5488                             scsi_unregister(shp);
5489                             asc_board_count--;
5490                             continue;
5491                         }
5492                         AscEnableIsaDma(shp->dma_channel);
5493                     }
5494                 }
5495     #endif /* CONFIG_ISA */
5496     
5497                 /* Register IRQ Number. */
5498                 ASC_DBG1(2, "advansys_detect: request_irq() %d\n", shp->irq);
5499                /*
5500                 * If request_irq() fails with the SA_INTERRUPT flag set,
5501                 * then try again without the SA_INTERRUPT flag set. This
5502                 * allows IRQ sharing to work even with other drivers that
5503                 * do not set the SA_INTERRUPT flag.
5504                 *
5505                 * If SA_INTERRUPT is not set, then interrupts are enabled
5506                 * before the driver interrupt function is called.
5507                 */
5508                 if (((ret = request_irq(shp->irq, advansys_interrupt,
5509                                 SA_INTERRUPT | (share_irq == TRUE ? SA_SHIRQ : 0),
5510                                 "advansys", boardp)) != 0) &&
5511                     ((ret = request_irq(shp->irq, advansys_interrupt,
5512                                 (share_irq == TRUE ? SA_SHIRQ : 0),
5513                                 "advansys", boardp)) != 0))
5514                 {
5515                     if (ret == -EBUSY) {
5516                         ASC_PRINT2(
5517     "advansys_detect: board %d: request_irq(): IRQ 0x%x already in use.\n",
5518                             boardp->id, shp->irq);
5519                     } else if (ret == -EINVAL) {
5520                         ASC_PRINT2(
5521     "advansys_detect: board %d: request_irq(): IRQ 0x%x not valid.\n",
5522                             boardp->id, shp->irq);
5523                     } else {
5524                         ASC_PRINT3(
5525     "advansys_detect: board %d: request_irq(): IRQ 0x%x failed with %d\n",
5526                             boardp->id, shp->irq, ret);
5527                     }
5528                     release_region(shp->io_port, boardp->asc_n_io_port);
5529                     iounmap(boardp->ioremap_addr);
5530                     if (shp->dma_channel != NO_ISA_DMA) {
5531                         free_dma(shp->dma_channel);
5532                     }
5533     #ifdef CONFIG_PROC_FS
5534                     kfree(boardp->prtbuf);
5535     #endif /* CONFIG_PROC_FS */
5536                     scsi_unregister(shp);
5537                     asc_board_count--;
5538                     continue;
5539                 }
5540     
5541                 /*
5542                  * Initialize board RISC chip and enable interrupts.
5543                  */
5544                 if (ASC_NARROW_BOARD(boardp)) {
5545                     ASC_DBG(2, "advansys_detect: AscInitAsc1000Driver()\n");
5546                     warn_code = AscInitAsc1000Driver(asc_dvc_varp);
5547                     err_code = asc_dvc_varp->err_code;
5548     
5549                     if (warn_code || err_code) {
5550                         ASC_PRINT4(
5551     "advansys_detect: board %d error: init_state 0x%x, warn 0x%x, error 0x%x\n",
5552                             boardp->id, asc_dvc_varp->init_state,
5553                             warn_code, err_code);
5554                     }
5555                 } else {
5556                     ADV_CARR_T      *carrp;
5557                     int             req_cnt;
5558                     adv_req_t       *reqp = NULL;
5559                     int             sg_cnt = 0;
5560     
5561                     /*
5562                      * Allocate buffer carrier structures. The total size
5563                      * is about 4 KB, so allocate all at once.
5564                      */
5565                     carrp =
5566                         (ADV_CARR_T *) kmalloc(ADV_CARRIER_BUFSIZE, GFP_ATOMIC);
5567                     ASC_DBG1(1, "advansys_detect: carrp 0x%lx\n", (ulong) carrp);
5568     
5569                     if (carrp == NULL) {
5570                         goto kmalloc_error;
5571                     }
5572     
5573                     /*
5574                      * Allocate up to 'max_host_qng' request structures for
5575                      * the Wide board. The total size is about 16 KB, so
5576                      * allocate all at once. If the allocation fails decrement
5577                      * and try again.
5578                      */
5579                     for (req_cnt = adv_dvc_varp->max_host_qng;
5580                         req_cnt > 0; req_cnt--) {
5581     
5582                         reqp = (adv_req_t *)
5583                             kmalloc(sizeof(adv_req_t) * req_cnt, GFP_ATOMIC);
5584     
5585                         ASC_DBG3(1,
5586                             "advansys_detect: reqp 0x%lx, req_cnt %d, bytes %lu\n",
5587                             (ulong) reqp, req_cnt,
5588                             (ulong) sizeof(adv_req_t) * req_cnt);
5589     
5590                         if (reqp != NULL) {
5591                             break;
5592                         }
5593                     }
5594                     if (reqp == NULL)
5595                     {
5596                         goto kmalloc_error;
5597                     }
5598     
5599                     /*
5600                      * Allocate up to ADV_TOT_SG_BLOCK request structures for
5601                      * the Wide board. Each structure is about 136 bytes.
5602                      */
5603                     boardp->adv_sgblkp = NULL;
5604                     for (sg_cnt = 0; sg_cnt < ADV_TOT_SG_BLOCK; sg_cnt++) {
5605     
5606                         sgp = (adv_sgblk_t *)
5607                             kmalloc(sizeof(adv_sgblk_t), GFP_ATOMIC);
5608     
5609                         if (sgp == NULL) {
5610                             break;
5611                         }
5612     
5613                         sgp->next_sgblkp = boardp->adv_sgblkp;
5614                         boardp->adv_sgblkp = sgp;
5615     
5616                     }
5617                     ASC_DBG3(1,
5618                         "advansys_detect: sg_cnt %d * %u = %u bytes\n",
5619                         sg_cnt, sizeof(adv_sgblk_t),
5620                         (unsigned) (sizeof(adv_sgblk_t) * sg_cnt));
5621     
5622                     /*
5623                      * If no request structures or scatter-gather structures could
5624                      * be allocated, then return an error. Otherwise continue with
5625                      * initialization.
5626                      */
5627         kmalloc_error:
5628                     if (carrp == NULL)
5629                     {
5630                         ASC_PRINT1(
5631     "advansys_detect: board %d error: failed to kmalloc() carrier buffer.\n",
5632                             boardp->id);
5633                         err_code = ADV_ERROR;
5634                     } else if (reqp == NULL) {
5635                         kfree(carrp);
5636                         ASC_PRINT1(
5637     "advansys_detect: board %d error: failed to kmalloc() adv_req_t buffer.\n",
5638                             boardp->id);
5639                         err_code = ADV_ERROR;
5640                     } else if (boardp->adv_sgblkp == NULL) {
5641                         kfree(carrp);
5642                         kfree(reqp);
5643                         ASC_PRINT1(
5644     "advansys_detect: board %d error: failed to kmalloc() adv_sgblk_t buffers.\n",
5645                             boardp->id);
5646                         err_code = ADV_ERROR;
5647                     } else {
5648     
5649                         /* Save carrier buffer pointer. */
5650                         boardp->orig_carrp = carrp;
5651     
5652                         /*
5653                          * Save original pointer for kfree() in case the
5654                          * driver is built as a module and can be unloaded.
5655                          */
5656                         boardp->orig_reqp = reqp;
5657     
5658                         adv_dvc_varp->carrier_buf = carrp;
5659     
5660                         /*
5661                          * Point 'adv_reqp' to the request structures and
5662                          * link them together.
5663                          */
5664                         req_cnt--;
5665                         reqp[req_cnt].next_reqp = NULL;
5666                         for (; req_cnt > 0; req_cnt--) {
5667                             reqp[req_cnt - 1].next_reqp = &reqp[req_cnt];
5668                         }
5669                         boardp->adv_reqp = &reqp[0];
5670     
5671                         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
5672                         {
5673                             ASC_DBG(2,
5674                                 "advansys_detect: AdvInitAsc3550Driver()\n");
5675                             warn_code = AdvInitAsc3550Driver(adv_dvc_varp);
5676                         } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
5677                             ASC_DBG(2,
5678                                 "advansys_detect: AdvInitAsc38C0800Driver()\n");
5679                             warn_code = AdvInitAsc38C0800Driver(adv_dvc_varp);
5680                         } else {
5681                             ASC_DBG(2,
5682                                 "advansys_detect: AdvInitAsc38C1600Driver()\n");
5683                             warn_code = AdvInitAsc38C1600Driver(adv_dvc_varp);
5684                         }
5685                         err_code = adv_dvc_varp->err_code;
5686     
5687                         if (warn_code || err_code) {
5688                             ASC_PRINT3(
5689     "advansys_detect: board %d error: warn 0x%x, error 0x%x\n",
5690                                 boardp->id, warn_code, err_code);
5691                         }
5692                     }
5693                 }
5694     
5695                 if (err_code != 0) {
5696                     release_region(shp->io_port, boardp->asc_n_io_port);
5697                     if (ASC_WIDE_BOARD(boardp)) {
5698                         iounmap(boardp->ioremap_addr);
5699                         if (boardp->orig_carrp) {
5700                             kfree(boardp->orig_carrp);
5701                             boardp->orig_carrp = NULL;
5702                         }
5703                         if (boardp->orig_reqp) {
5704                             kfree(boardp->orig_reqp);
5705                             boardp->orig_reqp = boardp->adv_reqp = NULL;
5706                         }
5707                         while ((sgp = boardp->adv_sgblkp) != NULL)
5708                         {
5709                             boardp->adv_sgblkp = sgp->next_sgblkp;
5710                             kfree(sgp);
5711                         }
5712                     }
5713                     if (shp->dma_channel != NO_ISA_DMA) {
5714                         free_dma(shp->dma_channel);
5715                     }
5716     #ifdef CONFIG_PROC_FS
5717                     kfree(boardp->prtbuf);
5718     #endif /* CONFIG_PROC_FS */
5719                     free_irq(shp->irq, boardp);
5720                     scsi_unregister(shp);
5721                     asc_board_count--;
5722                     continue;
5723                 }
5724                 ASC_DBG_PRT_SCSI_HOST(2, shp);
5725             }
5726         }
5727     
5728         /*
5729          * XXX - Remove this comment and the next line when SCSI mid-level
5730          * no longer acquires 'io_request_lock' before calling the SCSI
5731          * low-level detect entrypoint.
5732          */
5733         ASC_LOCK_IO_REQUEST_LOCK
5734     
5735         ASC_DBG1(1, "advansys_detect: done: asc_board_count %d\n", asc_board_count);
5736         return asc_board_count;
5737     }
5738     
5739     /*
5740      * advansys_release()
5741      *
5742      * Release resources allocated for a single AdvanSys adapter.
5743      */
5744     int
5745     advansys_release(struct Scsi_Host *shp)
5746     {
5747         asc_board_t    *boardp;
5748     
5749         ASC_DBG(1, "advansys_release: begin\n");
5750         boardp = ASC_BOARDP(shp);
5751         free_irq(shp->irq, boardp);
5752         if (shp->dma_channel != NO_ISA_DMA) {
5753             ASC_DBG(1, "advansys_release: free_dma()\n");
5754             free_dma(shp->dma_channel);
5755         }
5756         release_region(shp->io_port, boardp->asc_n_io_port);
5757         if (ASC_WIDE_BOARD(boardp)) {
5758             adv_sgblk_t    *sgp = NULL;
5759     
5760             iounmap(boardp->ioremap_addr);
5761             if (boardp->orig_carrp) {
5762                 kfree(boardp->orig_carrp);
5763                 boardp->orig_carrp = NULL;
5764             }
5765             if (boardp->orig_reqp) {
5766                 kfree(boardp->orig_reqp);
5767                 boardp->orig_reqp = boardp->adv_reqp = NULL;
5768             }
5769             while ((sgp = boardp->adv_sgblkp) != NULL)
5770             {
5771                 boardp->adv_sgblkp = sgp->next_sgblkp;
5772                 kfree(sgp);
5773             }
5774         }
5775     #ifdef CONFIG_PROC_FS
5776         ASC_ASSERT(boardp->prtbuf != NULL);
5777         kfree(boardp->prtbuf);
5778     #endif /* CONFIG_PROC_FS */
5779         scsi_unregister(shp);
5780         ASC_DBG(1, "advansys_release: end\n");
5781         return 0;
5782     }
5783     
5784     /*
5785      * advansys_info()
5786      *
5787      * Return suitable for printing on the console with the argument
5788      * adapter's configuration information.
5789      *
5790      * Note: The information line should not exceed ASC_INFO_SIZE bytes,
5791      * otherwise the static 'info' array will be overrun.
5792      */
5793     const char *
5794     advansys_info(struct Scsi_Host *shp)
5795     {
5796         static char     info[ASC_INFO_SIZE];
5797         asc_board_t     *boardp;
5798         ASC_DVC_VAR     *asc_dvc_varp;
5799         ADV_DVC_VAR     *adv_dvc_varp;
5800         char            *busname;
5801         int             iolen;
5802         char            *widename = NULL;
5803     
5804         boardp = ASC_BOARDP(shp);
5805         if (ASC_NARROW_BOARD(boardp)) {
5806             asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
5807             ASC_DBG(1, "advansys_info: begin\n");
5808             if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
5809                 if ((asc_dvc_varp->bus_type & ASC_IS_ISAPNP) == ASC_IS_ISAPNP) {
5810                     busname = "ISA PnP";
5811                 } else {
5812                     busname = "ISA";
5813                 }
5814                 /* Don't reference 'shp->n_io_port'; It may be truncated. */
5815                 sprintf(info,
5816     "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X, DMA 0x%X",
5817                     ASC_VERSION, busname,
5818                     (ulong) shp->io_port,
5819                     (ulong) shp->io_port + boardp->asc_n_io_port - 1,
5820                     shp->irq, shp->dma_channel);
5821             } else {
5822                 if (asc_dvc_varp->bus_type & ASC_IS_VL) {
5823                     busname = "VL";
5824                 } else if (asc_dvc_varp->bus_type & ASC_IS_EISA) {
5825                     busname = "EISA";
5826                 } else if (asc_dvc_varp->bus_type & ASC_IS_PCI) {
5827                     if ((asc_dvc_varp->bus_type & ASC_IS_PCI_ULTRA)
5828                         == ASC_IS_PCI_ULTRA) {
5829                         busname = "PCI Ultra";
5830                     } else {
5831                         busname = "PCI";
5832                     }
5833                 } else {
5834                     busname = "?";
5835                     ASC_PRINT2( "advansys_info: board %d: unknown bus type %d\n",
5836                         boardp->id, asc_dvc_varp->bus_type);
5837                 }
5838                 /* Don't reference 'shp->n_io_port'; It may be truncated. */
5839                 sprintf(info,
5840                     "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X",
5841                     ASC_VERSION, busname,
5842                     (ulong) shp->io_port,
5843                     (ulong) shp->io_port + boardp->asc_n_io_port - 1,
5844                     shp->irq);
5845             }
5846         } else {
5847             /*
5848              * Wide Adapter Information
5849              *
5850              * Memory-mapped I/O is used instead of I/O space to access
5851              * the adapter, but display the I/O Port range. The Memory
5852              * I/O address is displayed through the driver /proc file.
5853              */
5854             adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
5855             if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
5856             {
5857                 iolen = ADV_3550_IOLEN;
5858                 widename = "Ultra-Wide";
5859             } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
5860             {
5861                 iolen = ADV_38C0800_IOLEN;
5862                 widename = "Ultra2-Wide";
5863             } else
5864             {
5865                 iolen = ADV_38C1600_IOLEN;
5866                 widename = "Ultra3-Wide";
5867             }
5868             sprintf(info, "AdvanSys SCSI %s: PCI %s: PCIMEM 0x%lX-0x%lX, IRQ 0x%X",
5869                 ASC_VERSION,
5870                 widename,
5871                 (ulong) adv_dvc_varp->iop_base,
5872                 (ulong) adv_dvc_varp->iop_base + iolen - 1,
5873                 shp->irq);
5874         }
5875         ASC_ASSERT(strlen(info) < ASC_INFO_SIZE);
5876         ASC_DBG(1, "advansys_info: end\n");
5877         return info;
5878     }
5879     
5880     /*
5881      * advansys_queuecommand() - interrupt-driven I/O entrypoint.
5882      *
5883      * This function always returns 0. Command return status is saved
5884      * in the 'scp' result field.
5885      */
5886     int
5887     advansys_queuecommand(Scsi_Cmnd *scp, void (*done)(Scsi_Cmnd *))
5888     {
5889         struct Scsi_Host    *shp;
5890         asc_board_t         *boardp;
5891         ulong               flags;
5892         Scsi_Cmnd           *done_scp;
5893     
5894         shp = scp->host;
5895         boardp = ASC_BOARDP(shp);
5896         ASC_STATS(shp, queuecommand);
5897     
5898         /*
5899          * XXX - Remove this comment and the next line when SCSI mid-level
5900          * no longer acquires 'io_request_lock' before calling the SCSI
5901          * low-level queuecommand entrypoint.
5902          */
5903         ASC_UNLOCK_IO_REQUEST_LOCK
5904     
5905         spin_lock_irqsave(&boardp->lock, flags);
5906     
5907         /*
5908          * Block new commands while handling a reset or abort request.
5909          */
5910         if (boardp->flags & ASC_HOST_IN_RESET) {
5911             ASC_DBG1(1,
5912                 "advansys_queuecommand: scp 0x%lx blocked for reset request\n",
5913                 (ulong) scp);
5914             scp->result = HOST_BYTE(DID_RESET);
5915     
5916             /*
5917              * Add blocked requests to the board's 'done' queue. The queued
5918              * requests will be completed at the end of the abort or reset
5919              * handling.
5920              */
5921             asc_enqueue(&boardp->done, scp, ASC_BACK);
5922             spin_unlock_irqrestore(&boardp->lock, flags);
5923             return 0;
5924         }
5925     
5926         /*
5927          * Attempt to execute any waiting commands for the board.
5928          */
5929         if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
5930             ASC_DBG(1,
5931                 "advansys_queuecommand: before asc_execute_queue() waiting\n");
5932             asc_execute_queue(&boardp->waiting);
5933         }
5934     
5935         /*
5936          * Save the function pointer to Linux mid-level 'done' function
5937          * and attempt to execute the command.
5938          *
5939          * If ASC_NOERROR is returned the request has been added to the
5940          * board's 'active' queue and will be completed by the interrupt
5941          * handler.
5942          *
5943          * If ASC_BUSY is returned add the request to the board's per
5944          * target waiting list. This is the first time the request has
5945          * been tried. Add it to the back of the waiting list. It will be
5946          * retried later.
5947          *
5948          * If an error occurred, the request will have been placed on the
5949          * board's 'done' queue and must be completed before returning.
5950          */
5951         scp->scsi_done = done;
5952         switch (asc_execute_scsi_cmnd(scp)) {
5953         case ASC_NOERROR:
5954             break;
5955         case ASC_BUSY:
5956             asc_enqueue(&boardp->waiting, scp, ASC_BACK);
5957             break;
5958         case ASC_ERROR:
5959         default:
5960             done_scp = asc_dequeue_list(&boardp->done, NULL, ASC_TID_ALL);
5961             /* Interrupts could be enabled here. */
5962             asc_scsi_done_list(done_scp);
5963             break;
5964         }
5965     
5966         spin_unlock_irqrestore(&boardp->lock, flags);
5967     
5968         /*
5969          * XXX - Remove this comment and the next line when SCSI mid-level
5970          * no longer acquires 'io_request_lock' before calling the SCSI
5971          * low-level queuecommand entrypoint.
5972          */
5973         ASC_LOCK_IO_REQUEST_LOCK
5974     
5975         return 0;
5976     }
5977     
5978     /*
5979      * advansys_reset()
5980      *
5981      * Reset the bus associated with the command 'scp'.
5982      *
5983      * This function runs its own thread. Interrupts must be blocked but
5984      * sleeping is allowed and no locking other than for host structures is
5985      * required. Returns SUCCESS or FAILED.
5986      */
5987     int
5988     advansys_reset(Scsi_Cmnd *scp)
5989     {
5990         struct Scsi_Host     *shp;
5991         asc_board_t          *boardp;
5992         ASC_DVC_VAR          *asc_dvc_varp;
5993         ADV_DVC_VAR          *adv_dvc_varp;
5994         ulong                flags;
5995         Scsi_Cmnd            *done_scp = NULL, *last_scp = NULL;
5996         Scsi_Cmnd            *tscp, *new_last_scp;
5997         int                  status;
5998         int                  ret = SUCCESS;
5999     
6000         ASC_DBG1(1, "advansys_reset: 0x%lx\n", (ulong) scp);
6001     
6002     #ifdef ADVANSYS_STATS
6003         if (scp->host != NULL) {
6004             ASC_STATS(scp->host, reset);
6005         }
6006     #endif /* ADVANSYS_STATS */
6007     
6008         if ((shp = scp->host) == NULL) {
6009             scp->result = HOST_BYTE(DID_ERROR);
6010             return FAILED;
6011         }
6012     
6013         boardp = ASC_BOARDP(shp);
6014     
6015         ASC_PRINT1("advansys_reset: board %d: SCSI bus reset started...\n",
6016             boardp->id);
6017         /*
6018          * Check for re-entrancy.
6019          */
6020         spin_lock_irqsave(&boardp->lock, flags);
6021         if (boardp->flags & ASC_HOST_IN_RESET) {
6022             spin_unlock_irqrestore(&boardp->lock, flags);
6023             return FAILED;
6024         }
6025         boardp->flags |= ASC_HOST_IN_RESET;
6026         spin_unlock_irqrestore(&boardp->lock, flags);
6027     
6028         /*
6029          * XXX - Remove this comment and the next line when SCSI mid-level
6030          * no longer acquires 'io_request_lock' before calling the SCSI
6031          * low-level reset entrypoint.
6032          */
6033         ASC_UNLOCK_IO_REQUEST_LOCK
6034     
6035         if (ASC_NARROW_BOARD(boardp)) {
6036             /*
6037              * Narrow Board
6038              */
6039             asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
6040     
6041             /*
6042              * Reset the chip and SCSI bus.
6043              */
6044             ASC_DBG(1, "advansys_reset: before AscInitAsc1000Driver()\n");
6045             status = AscInitAsc1000Driver(asc_dvc_varp);
6046     
6047             /* Refer to ASC_IERR_* defintions for meaning of 'err_code'. */
6048             if (asc_dvc_varp->err_code) {
6049                 ASC_PRINT2(
6050                     "advansys_reset: board %d: SCSI bus reset error: 0x%x\n",
6051                     boardp->id, asc_dvc_varp->err_code);
6052                 ret = FAILED;
6053             } else if (status) {
6054                 ASC_PRINT2(
6055                     "advansys_reset: board %d: SCSI bus reset warning: 0x%x\n",
6056                     boardp->id, status);
6057             } else {
6058                 ASC_PRINT1(
6059                     "advansys_reset: board %d: SCSI bus reset successful.\n",
6060                     boardp->id);
6061             }
6062     
6063             ASC_DBG(1, "advansys_reset: after AscInitAsc1000Driver()\n");
6064     
6065             /*
6066              * Acquire the board lock.
6067              */
6068             spin_lock_irqsave(&boardp->lock, flags);
6069     
6070         } else {
6071             /*
6072              * Wide Board
6073              *
6074              * If the suggest reset bus flags are set, then reset the bus.
6075              * Otherwise only reset the device.
6076              */
6077             adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
6078     
6079             /*
6080              * Reset the target's SCSI bus.
6081              */
6082             ASC_DBG(1, "advansys_reset: before AdvResetChipAndSB()\n");
6083             switch (AdvResetChipAndSB(adv_dvc_varp)) {
6084             case ASC_TRUE:
6085                 ASC_PRINT1("advansys_reset: board %d: SCSI bus reset successful.\n",
6086                     boardp->id);
6087                 break;
6088             case ASC_FALSE:
6089             default:
6090                 ASC_PRINT1("advansys_reset: board %d: SCSI bus reset error.\n",
6091                     boardp->id);
6092                 ret = FAILED;
6093                 break;
6094             }
6095             /*
6096              * Acquire the board lock and ensure all requests completed by the
6097              * microcode have been processed by calling AdvISR().
6098              */
6099             spin_lock_irqsave(&boardp->lock, flags);
6100             (void) AdvISR(adv_dvc_varp);
6101         }
6102     
6103         /* Board lock is held. */
6104     
6105         /*
6106          * Dequeue all board 'done' requests. A pointer to the last request
6107          * is returned in 'last_scp'.
6108          */
6109         done_scp = asc_dequeue_list(&boardp->done, &last_scp, ASC_TID_ALL);
6110     
6111         /*
6112          * Dequeue all board 'active' requests for all devices and set
6113          * the request status to DID_RESET. A pointer to the last request
6114          * is returned in 'last_scp'.
6115          */
6116         if (done_scp == NULL) {
6117             done_scp = asc_dequeue_list(&boardp->active, &last_scp, ASC_TID_ALL);
6118             for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) {
6119                 tscp->result = HOST_BYTE(DID_RESET);
6120             }
6121         } else {
6122             /* Append to 'done_scp' at the end with 'last_scp'. */
6123             ASC_ASSERT(last_scp != NULL);
6124             REQPNEXT(last_scp) = asc_dequeue_list(&boardp->active,
6125                 &new_last_scp, ASC_TID_ALL);
6126             if (new_last_scp != NULL) {
6127                 ASC_ASSERT(REQPNEXT(last_scp) != NULL);
6128                 for (tscp = REQPNEXT(last_scp); tscp; tscp = REQPNEXT(tscp)) {
6129                     tscp->result = HOST_BYTE(DID_RESET);
6130                 }
6131                 last_scp = new_last_scp;
6132             }
6133         }
6134     
6135         /*
6136          * Dequeue all 'waiting' requests and set the request status
6137          * to DID_RESET.
6138          */
6139         if (done_scp == NULL) {
6140             done_scp = asc_dequeue_list(&boardp->waiting, &last_scp, ASC_TID_ALL);
6141             for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) {
6142                 tscp->result = HOST_BYTE(DID_RESET);
6143             }
6144         } else {
6145             /* Append to 'done_scp' at the end with 'last_scp'. */
6146             ASC_ASSERT(last_scp != NULL);
6147             REQPNEXT(last_scp) = asc_dequeue_list(&boardp->waiting,
6148                 &new_last_scp, ASC_TID_ALL);
6149             if (new_last_scp != NULL) {
6150                 ASC_ASSERT(REQPNEXT(last_scp) != NULL);
6151                 for (tscp = REQPNEXT(last_scp); tscp; tscp = REQPNEXT(tscp)) {
6152                     tscp->result = HOST_BYTE(DID_RESET);
6153                 }
6154                 last_scp = new_last_scp;
6155             }
6156         }
6157     
6158         /* Save the time of the most recently completed reset. */
6159         boardp->last_reset = jiffies;
6160     
6161         /* Clear reset flag. */
6162         boardp->flags &= ~ASC_HOST_IN_RESET;
6163     
6164         /* Release the board. */
6165         spin_unlock_irqrestore(&boardp->lock, flags);
6166     
6167         /*
6168          * Complete all the 'done_scp' requests.
6169          */
6170         if (done_scp != NULL) {
6171             asc_scsi_done_list(done_scp);
6172         }
6173     
6174         /*
6175          * XXX - Remove this comment and the next line when SCSI mid-level
6176          * no longer acquires 'io_request_lock' before calling the SCSI
6177          * low-level reset entrypoint.
6178          */
6179         ASC_LOCK_IO_REQUEST_LOCK
6180     
6181         ASC_DBG1(1, "advansys_reset: ret %d\n", ret);
6182     
6183         return ret;
6184     }
6185     
6186     /*
6187      * advansys_biosparam()
6188      *
6189      * Translate disk drive geometry if the "BIOS greater than 1 GB"
6190      * support is enabled for a drive.
6191      *
6192      * ip (information pointer) is an int array with the following definition:
6193      * ip[0]: heads
6194      * ip[1]: sectors
6195      * ip[2]: cylinders
6196      */
6197     int
6198     advansys_biosparam(Disk *dp, kdev_t dep, int ip[])
6199     {
6200         asc_board_t     *boardp;
6201     
6202         ASC_DBG(1, "advansys_biosparam: begin\n");
6203         ASC_STATS(dp->device->host, biosparam);
6204         boardp = ASC_BOARDP(dp->device->host);
6205         if (ASC_NARROW_BOARD(boardp)) {
6206             if ((boardp->dvc_var.asc_dvc_var.dvc_cntl &
6207                  ASC_CNTL_BIOS_GT_1GB) && dp->capacity > 0x200000) {
6208                     ip[0] = 255;
6209                     ip[1] = 63;
6210             } else {
6211                     ip[0] = 64;
6212                     ip[1] = 32;
6213             }
6214         } else {
6215             if ((boardp->dvc_var.adv_dvc_var.bios_ctrl &
6216                  BIOS_CTRL_EXTENDED_XLAT) && dp->capacity > 0x200000) {
6217                     ip[0] = 255;
6218                     ip[1] = 63;
6219             } else {
6220                     ip[0] = 64;
6221                     ip[1] = 32;
6222             }
6223         }
6224         ip[2] = dp->capacity / (ip[0] * ip[1]);
6225         ASC_DBG(1, "advansys_biosparam: end\n");
6226         return 0;
6227     }
6228     
6229     /*
6230      * advansys_setup()
6231      *
6232      * This function is called from init/main.c at boot time.
6233      * It it passed LILO parameters that can be set from the
6234      * LILO command line or in /etc/lilo.conf.
6235      *
6236      * It is used by the AdvanSys driver to either disable I/O
6237      * port scanning or to limit scanning to 1 - 4 I/O ports.
6238      * Regardless of the option setting EISA and PCI boards
6239      * will still be searched for and detected. This option
6240      * only affects searching for ISA and VL boards.
6241      *
6242      * If ADVANSYS_DEBUG is defined the driver debug level may
6243      * be set using the 5th (ASC_NUM_IOPORT_PROBE + 1) I/O Port.
6244      *
6245      * Examples:
6246      * 1. Eliminate I/O port scanning:
6247      *         boot: linux advansys=
6248      *       or
6249      *         boot: linux advansys=0x0
6250      * 2. Limit I/O port scanning to one I/O port:
6251      *        boot: linux advansys=0x110
6252      * 3. Limit I/O port scanning to four I/O ports:
6253      *        boot: linux advansys=0x110,0x210,0x230,0x330
6254      * 4. If ADVANSYS_DEBUG, limit I/O port scanning to four I/O ports and
6255      *    set the driver debug level to 2.
6256      *        boot: linux advansys=0x110,0x210,0x230,0x330,0xdeb2
6257      *
6258      * ints[0] - number of arguments
6259      * ints[1] - first argument
6260      * ints[2] - second argument
6261      * ...
6262      */
6263     ASC_INITFUNC(
6264     void,
6265     advansys_setup(char *str, int *ints)
6266     )
6267     {
6268         int    i;
6269     
6270         if (asc_iopflag == ASC_TRUE) {
6271             printk("AdvanSys SCSI: 'advansys' LILO option may appear only once\n");
6272             return;
6273         }
6274     
6275         asc_iopflag = ASC_TRUE;
6276     
6277         if (ints[0] > ASC_NUM_IOPORT_PROBE) {
6278     #ifdef ADVANSYS_DEBUG
6279             if ((ints[0] == ASC_NUM_IOPORT_PROBE + 1) &&
6280                 (ints[ASC_NUM_IOPORT_PROBE + 1] >> 4 == 0xdeb)) {
6281                 asc_dbglvl = ints[ASC_NUM_IOPORT_PROBE + 1] & 0xf;
6282             } else {
6283     #endif /* ADVANSYS_DEBUG */
6284                 printk("AdvanSys SCSI: only %d I/O ports accepted\n",
6285                     ASC_NUM_IOPORT_PROBE);
6286     #ifdef ADVANSYS_DEBUG
6287             }
6288     #endif /* ADVANSYS_DEBUG */
6289         }
6290     
6291     #ifdef ADVANSYS_DEBUG
6292         ASC_DBG1(1, "advansys_setup: ints[0] %d\n", ints[0]);
6293         for (i = 1; i < ints[0]; i++) {
6294             ASC_DBG2(1, " ints[%d] 0x%x", i, ints[i]);
6295         }
6296         ASC_DBG(1, "\n");
6297     #endif /* ADVANSYS_DEBUG */
6298     
6299         for (i = 1; i <= ints[0] && i <= ASC_NUM_IOPORT_PROBE; i++) {
6300             asc_ioport[i-1] = ints[i];
6301             ASC_DBG2(1, "advansys_setup: asc_ioport[%d] 0x%x\n",
6302                 i - 1, asc_ioport[i-1]);
6303         }
6304     }
6305     
6306     
6307     /*
6308      * --- Loadable Driver Support
6309      */
6310     
6311     #if ASC_LINUX_KERNEL24
6312     static
6313     #endif
6314     #if ASC_LINUX_KERNEL24 || (ASC_LINUX_KERNEL22 && defined(MODULE))
6315     Scsi_Host_Template driver_template = ADVANSYS;
6316     # include "scsi_module.c"
6317     #endif
6318     
6319     
6320     /*
6321      * --- Miscellaneous Driver Functions
6322      */
6323     
6324     /*
6325      * First-level interrupt handler.
6326      *
6327      * 'dev_id' is a pointer to the interrupting adapter's asc_board_t. Because
6328      * all boards are currently checked for interrupts on each interrupt, 'dev_id'
6329      * is not referenced. 'dev_id' could be used to identify an interrupt passed
6330      * to the AdvanSys driver which is for a device sharing an interrupt with
6331      * an AdvanSys adapter.
6332      */
6333     STATIC void
6334     advansys_interrupt(int irq, void *dev_id, struct pt_regs *regs)
6335     {
6336         ulong           flags;
6337         int             i;
6338         asc_board_t     *boardp;
6339         Scsi_Cmnd       *done_scp = NULL, *last_scp = NULL;
6340         Scsi_Cmnd       *new_last_scp;
6341     
6342         ASC_DBG(1, "advansys_interrupt: begin\n");
6343     
6344         /*
6345          * Check for interrupts on all boards.
6346          * AscISR() will call asc_isr_callback().
6347          */
6348         for (i = 0; i < asc_board_count; i++) {
6349             boardp = ASC_BOARDP(asc_host[i]);
6350             ASC_DBG2(2, "advansys_interrupt: i %d, boardp 0x%lx\n",
6351                 i, (ulong) boardp);
6352             spin_lock_irqsave(&boardp->lock, flags);
6353             if (ASC_NARROW_BOARD(boardp)) {
6354                 /*
6355                  * Narrow Board
6356                  */
6357                 if (AscIsIntPending(asc_host[i]->io_port)) {
6358                     ASC_STATS(asc_host[i], interrupt);
6359                     ASC_DBG(1, "advansys_interrupt: before AscISR()\n");
6360                     AscISR(&boardp->dvc_var.asc_dvc_var);
6361                 }
6362             } else {
6363                 /*
6364                  * Wide Board
6365                  */
6366                 ASC_DBG(1, "advansys_interrupt: before AdvISR()\n");
6367                 if (AdvISR(&boardp->dvc_var.adv_dvc_var)) {
6368                     ASC_STATS(asc_host[i], interrupt);
6369                 }
6370             }
6371     
6372             /*
6373              * Start waiting requests and create a list of completed requests.
6374              *
6375              * If a reset request is being performed for the board, the reset
6376              * handler will complete pending requests after it has completed.
6377              */
6378             if ((boardp->flags & ASC_HOST_IN_RESET) == 0) {
6379                 ASC_DBG2(1, "advansys_interrupt: done_scp 0x%lx, last_scp 0x%lx\n",
6380                     (ulong) done_scp, (ulong) last_scp);
6381     
6382                 /* Start any waiting commands for the board. */
6383                 if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
6384                     ASC_DBG(1, "advansys_interrupt: before asc_execute_queue()\n");
6385                     asc_execute_queue(&boardp->waiting);
6386                 }
6387     
6388                  /*
6389                   * Add to the list of requests that must be completed.
6390                   *
6391                   * 'done_scp' will always be NULL on the first iteration
6392                   * of this loop. 'last_scp' is set at the same time as
6393                   * 'done_scp'.
6394                   */
6395                 if (done_scp == NULL) {
6396                     done_scp = asc_dequeue_list(&boardp->done, &last_scp,
6397                         ASC_TID_ALL);
6398                 } else {
6399                     ASC_ASSERT(last_scp != NULL);
6400                     REQPNEXT(last_scp) = asc_dequeue_list(&boardp->done,
6401                         &new_last_scp, ASC_TID_ALL);
6402                     if (new_last_scp != NULL) {
6403                         ASC_ASSERT(REQPNEXT(last_scp) != NULL);
6404                         last_scp = new_last_scp;
6405                     }
6406                 }
6407             }
6408             spin_unlock_irqrestore(&boardp->lock, flags);
6409         }
6410     
6411         /*
6412          * If interrupts were enabled on entry, then they
6413          * are now enabled here.
6414          *
6415          * Complete all requests on the done list.
6416          */
6417         asc_scsi_done_list(done_scp);
6418     
6419         ASC_DBG(1, "advansys_interrupt: end\n");
6420         return;
6421     }
6422     
6423     /*
6424      * Set the number of commands to queue per device for the
6425      * specified host adapter.
6426      */
6427     STATIC void
6428     advansys_select_queue_depths(struct Scsi_Host *shp, Scsi_Device *devicelist)
6429     {
6430         Scsi_Device        *device;
6431         asc_board_t        *boardp;
6432     
6433         boardp = ASC_BOARDP(shp);
6434         boardp->flags |= ASC_SELECT_QUEUE_DEPTHS;
6435         for (device = devicelist; device != NULL; device = device->next) {
6436             if (device->host != shp) {
6437                 continue;
6438             }
6439             /*
6440              * Save a pointer to the device and set its initial/maximum
6441              * queue depth.
6442              */
6443             boardp->device[device->id] = device;
6444             if (ASC_NARROW_BOARD(boardp)) {
6445                 device->queue_depth =
6446                     boardp->dvc_var.asc_dvc_var.max_dvc_qng[device->id];
6447             } else {
6448                 device->queue_depth =
6449                     boardp->dvc_var.adv_dvc_var.max_dvc_qng;
6450             }
6451             ASC_DBG3(1,
6452                 "advansys_select_queue_depths: shp 0x%lx, id %d, depth %d\n",
6453                 (ulong) shp, device->id, device->queue_depth);
6454         }
6455     }
6456     
6457     /*
6458      * Complete all requests on the singly linked list pointed
6459      * to by 'scp'.
6460      *
6461      * Interrupts can be enabled on entry.
6462      */
6463     STATIC void
6464     asc_scsi_done_list(Scsi_Cmnd *scp)
6465     {
6466         Scsi_Cmnd    *tscp;
6467     
6468         ASC_DBG(2, "asc_scsi_done_list: begin\n");
6469         while (scp != NULL) {
6470             ASC_DBG1(3, "asc_scsi_done_list: scp 0x%lx\n", (ulong) scp);
6471             tscp = REQPNEXT(scp);
6472             REQPNEXT(scp) = NULL;
6473             ASC_STATS(scp->host, done);
6474             ASC_ASSERT(scp->scsi_done != NULL);
6475             scp->scsi_done(scp);
6476             scp = tscp;
6477         }
6478         ASC_DBG(2, "asc_scsi_done_list: done\n");
6479         return;
6480     }
6481     
6482     /*
6483      * Execute a single 'Scsi_Cmnd'.
6484      *
6485      * The function 'done' is called when the request has been completed.
6486      *
6487      * Scsi_Cmnd:
6488      *
6489      *  host - board controlling device
6490      *  device - device to send command
6491      *  target - target of device
6492      *  lun - lun of device
6493      *  cmd_len - length of SCSI CDB
6494      *  cmnd - buffer for SCSI 8, 10, or 12 byte CDB
6495      *  use_sg - if non-zero indicates scatter-gather request with use_sg elements
6496      *
6497      *  if (use_sg == 0) {
6498      *    request_buffer - buffer address for request
6499      *    request_bufflen - length of request buffer
6500      *  } else {
6501      *    request_buffer - pointer to scatterlist structure
6502      *  }
6503      *
6504      *  sense_buffer - sense command buffer
6505      *
6506      *  result (4 bytes of an int):
6507      *    Byte Meaning
6508      *    0 SCSI Status Byte Code
6509      *    1 SCSI One Byte Message Code
6510      *    2 Host Error Code
6511      *    3 Mid-Level Error Code
6512      *
6513      *  host driver fields:
6514      *    SCp - Scsi_Pointer used for command processing status
6515      *    scsi_done - used to save caller's done function
6516      *    host_scribble - used for pointer to another Scsi_Cmnd
6517      *
6518      * If this function returns ASC_NOERROR the request has been enqueued
6519      * on the board's 'active' queue and will be completed from the
6520      * interrupt handler.
6521      *
6522      * If this function returns ASC_NOERROR the request has been enqueued
6523      * on the board's 'done' queue and must be completed by the caller.
6524      *
6525      * If ASC_BUSY is returned the request will be enqueued by the
6526      * caller on the target's waiting queue and re-tried later.
6527      */
6528     STATIC int
6529     asc_execute_scsi_cmnd(Scsi_Cmnd *scp)
6530     {
6531         asc_board_t        *boardp;
6532         ASC_DVC_VAR        *asc_dvc_varp;
6533         ADV_DVC_VAR        *adv_dvc_varp;
6534         ADV_SCSI_REQ_Q     *adv_scsiqp;
6535         Scsi_Device        *device;
6536         int                ret;
6537     
6538         ASC_DBG2(1, "asc_execute_scsi_cmnd: scp 0x%lx, done 0x%lx\n",
6539             (ulong) scp, (ulong) scp->scsi_done);
6540     
6541         boardp = ASC_BOARDP(scp->host);
6542         device = boardp->device[scp->target];
6543     
6544         if (ASC_NARROW_BOARD(boardp)) {
6545             /*
6546              * Build and execute Narrow Board request.
6547              */
6548     
6549             asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
6550     
6551             /*
6552              * Build Asc Library request structure using the
6553              * global structures 'asc_scsi_req' and 'asc_sg_head'.
6554              *
6555              * If an error is returned, then the request has been
6556              * queued on the board done queue. It will be completed
6557              * by the caller.
6558              *
6559              * asc_build_req() can not return ASC_BUSY.
6560              */
6561             if (asc_build_req(boardp, scp) == ASC_ERROR) {
6562                 ASC_STATS(scp->host, build_error);
6563                 return ASC_ERROR;
6564             }
6565     
6566             /*
6567              * Execute the command. If there is no error, add the command
6568              * to the active queue.
6569              */
6570             switch (ret = AscExeScsiQueue(asc_dvc_varp, &asc_scsi_q)) {
6571             case ASC_NOERROR:
6572                 ASC_STATS(scp->host, exe_noerror);
6573                 /*
6574                  * Increment monotonically increasing per device successful
6575                  * request counter. Wrapping doesn't matter.
6576                  */
6577                 boardp->reqcnt[scp->target]++;
6578                 asc_enqueue(&boardp->active, scp, ASC_BACK);
6579                 ASC_DBG(1,
6580                     "asc_execute_scsi_cmnd: AscExeScsiQueue(), ASC_NOERROR\n");
6581                 break;
6582             case ASC_BUSY:
6583                 /*
6584                  * Caller will enqueue request on the target's waiting queue
6585                  * and retry later.
6586                  */
6587                 ASC_STATS(scp->host, exe_busy);
6588                 break;
6589             case ASC_ERROR:
6590                 ASC_PRINT2(
6591     "asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
6592                     boardp->id, asc_dvc_varp->err_code);
6593                 ASC_STATS(scp->host, exe_error);
6594                 scp->result = HOST_BYTE(DID_ERROR);
6595                 asc_enqueue(&boardp->done, scp, ASC_BACK);
6596                 break;
6597             default:
6598                 ASC_PRINT2(
6599     "asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() unknown, err_code 0x%x\n",
6600                     boardp->id, asc_dvc_varp->err_code);
6601                 ASC_STATS(scp->host, exe_unknown);
6602                 scp->result = HOST_BYTE(DID_ERROR);
6603                 asc_enqueue(&boardp->done, scp, ASC_BACK);
6604                 break;
6605             }
6606         } else {
6607             /*
6608              * Build and execute Wide Board request.
6609              */
6610             adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
6611     
6612             /*
6613              * Build and get a pointer to an Adv Library request structure.
6614              *
6615              * If the request is successfully built then send it below,
6616              * otherwise return with an error.
6617              */
6618             switch (adv_build_req(boardp, scp, &adv_scsiqp)) {
6619             case ASC_NOERROR:
6620                 ASC_DBG(3, "asc_execute_scsi_cmnd: adv_build_req ASC_NOERROR\n");
6621                 break;
6622             case ASC_BUSY:
6623                 ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req ASC_BUSY\n");
6624                 /*
6625                  * If busy is returned the request has not been enqueued.
6626                  * It will be enqueued by the caller on the target's waiting
6627                  * queue and retried later.
6628                  *
6629                  * The asc_stats fields 'adv_build_noreq' and 'adv_build_nosg'
6630                  * count wide board busy conditions. They are updated in
6631                  * adv_build_req and adv_get_sglist, respectively.
6632                  */
6633                 return ASC_BUSY;
6634             case ASC_ERROR:
6635                  /* 
6636                   * If an error is returned, then the request has been
6637                   * queued on the board done queue. It will be completed
6638                   * by the caller.
6639                   */
6640             default:
6641                 ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req ASC_ERROR\n");
6642                 ASC_STATS(scp->host, build_error);
6643                 return ASC_ERROR;
6644             }
6645     
6646             /*
6647              * Execute the command. If there is no error, add the command
6648              * to the active queue.
6649              */
6650             switch (ret = AdvExeScsiQueue(adv_dvc_varp, adv_scsiqp)) {
6651             case ASC_NOERROR:
6652                 ASC_STATS(scp->host, exe_noerror);
6653                 /*
6654                  * Increment monotonically increasing per device successful
6655                  * request counter. Wrapping doesn't matter.
6656                  */
6657                 boardp->reqcnt[scp->target]++;
6658                 asc_enqueue(&boardp->active, scp, ASC_BACK);
6659                 ASC_DBG(1,
6660                     "asc_execute_scsi_cmnd: AdvExeScsiQueue(), ASC_NOERROR\n");
6661                 break;
6662             case ASC_BUSY:
6663                 /*
6664                  * Caller will enqueue request on the target's waiting queue
6665                  * and retry later.
6666                  */
6667                 ASC_STATS(scp->host, exe_busy);
6668                 break;
6669             case ASC_ERROR:
6670                 ASC_PRINT2(
6671     "asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
6672                     boardp->id, adv_dvc_varp->err_code);
6673                 ASC_STATS(scp->host, exe_error);
6674                 scp->result = HOST_BYTE(DID_ERROR);
6675                 asc_enqueue(&boardp->done, scp, ASC_BACK);
6676                 break;
6677             default:
6678                 ASC_PRINT2(
6679     "asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() unknown, err_code 0x%x\n",
6680                     boardp->id, adv_dvc_varp->err_code);
6681                 ASC_STATS(scp->host, exe_unknown);
6682                 scp->result = HOST_BYTE(DID_ERROR);
6683                 asc_enqueue(&boardp->done, scp, ASC_BACK);
6684                 break;
6685             }
6686         }
6687     
6688         ASC_DBG(1, "asc_execute_scsi_cmnd: end\n");
6689         return ret;
6690     }
6691     
6692     /*
6693      * Build a request structure for the Asc Library (Narrow Board).
6694      *
6695      * The global structures 'asc_scsi_q' and 'asc_sg_head' are
6696      * used to build the request.
6697      *
6698      * If an error occurs, then queue the request on the board done
6699      * queue and return ASC_ERROR.
6700      */
6701     STATIC int
6702     asc_build_req(asc_board_t *boardp, Scsi_Cmnd *scp)
6703     {
6704         /*
6705          * Mutually exclusive access is required to 'asc_scsi_q' and
6706          * 'asc_sg_head' until after the request is started.
6707          */
6708         memset(&asc_scsi_q, 0, sizeof(ASC_SCSI_Q));
6709     
6710         /*
6711          * Point the ASC_SCSI_Q to the 'Scsi_Cmnd'.
6712          */
6713         asc_scsi_q.q2.srb_ptr = ASC_VADDR_TO_U32(scp);
6714     
6715         /*
6716          * Build the ASC_SCSI_Q request.
6717          *
6718          * For narrow boards a CDB length maximum of 12 bytes
6719          * is supported.
6720          */
6721         if (scp->cmd_len > ASC_MAX_CDB_LEN) {
6722             ASC_PRINT3(
6723     "asc_build_req: board %d: cmd_len %d > ASC_MAX_CDB_LEN  %d\n",
6724                 boardp->id, scp->cmd_len, ASC_MAX_CDB_LEN);
6725             scp->result = HOST_BYTE(DID_ERROR);
6726             asc_enqueue(&boardp->done, scp, ASC_BACK);
6727             return ASC_ERROR;
6728         }
6729         asc_scsi_q.cdbptr = &scp->cmnd[0];
6730         asc_scsi_q.q2.cdb_len = scp->cmd_len;
6731         asc_scsi_q.q1.target_id = ASC_TID_TO_TARGET_ID(scp->target);
6732         asc_scsi_q.q1.target_lun = scp->lun;
6733         asc_scsi_q.q2.target_ix = ASC_TIDLUN_TO_IX(scp->target, scp->lun);
6734         asc_scsi_q.q1.sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
6735         asc_scsi_q.q1.sense_len = sizeof(scp->sense_buffer);
6736     
6737         /*
6738          * If there are any outstanding requests for the current target,
6739          * then every 255th request send an ORDERED request. This heuristic
6740          * tries to retain the benefit of request sorting while preventing
6741          * request starvation. 255 is the max number of tags or pending commands
6742          * a device may have outstanding.
6743          *
6744          * The request count is incremented below for every successfully
6745          * started request.
6746          *
6747          */
6748         if ((boardp->dvc_var.asc_dvc_var.cur_dvc_qng[scp->target] > 0) &&
6749             (boardp->reqcnt[scp->target] % 255) == 0) {
6750             asc_scsi_q.q2.tag_code = M2_QTAG_MSG_ORDERED;
6751         } else {
6752             asc_scsi_q.q2.tag_code = M2_QTAG_MSG_SIMPLE;
6753         }
6754     
6755         /*
6756          * Build ASC_SCSI_Q for a contiguous buffer or a scatter-gather
6757          * buffer command.
6758          */
6759         if (scp->use_sg == 0) {
6760             /*
6761              * CDB request of single contiguous buffer.
6762              */
6763             ASC_STATS(scp->host, cont_cnt);
6764             asc_scsi_q.q1.data_addr =
6765                 cpu_to_le32(virt_to_bus(scp->request_buffer));
6766             asc_scsi_q.q1.data_cnt = cpu_to_le32(scp->request_bufflen);
6767             ASC_STATS_ADD(scp->host, cont_xfer,
6768                           ASC_CEILING(scp->request_bufflen, 512));
6769             asc_scsi_q.q1.sg_queue_cnt = 0;
6770             asc_scsi_q.sg_head = NULL;
6771         } else {
6772             /*
6773              * CDB scatter-gather request list.
6774              */
6775             int                     sgcnt;
6776             struct scatterlist      *slp;
6777     
6778             if (scp->use_sg > scp->host->sg_tablesize) {
6779                 ASC_PRINT3(
6780     "asc_build_req: board %d: use_sg %d > sg_tablesize %d\n",
6781                     boardp->id, scp->use_sg, scp->host->sg_tablesize);
6782                 scp->result = HOST_BYTE(DID_ERROR);
6783                 asc_enqueue(&boardp->done, scp, ASC_BACK);
6784                 return ASC_ERROR;
6785             }
6786     
6787             ASC_STATS(scp->host, sg_cnt);
6788     
6789             /*
6790              * Use global ASC_SG_HEAD structure and set the ASC_SCSI_Q
6791              * structure to point to it.
6792              */
6793             memset(&asc_sg_head, 0, sizeof(ASC_SG_HEAD));
6794     
6795             asc_scsi_q.q1.cntl |= QC_SG_HEAD;
6796             asc_scsi_q.sg_head = &asc_sg_head;
6797             asc_scsi_q.q1.data_cnt = 0;
6798             asc_scsi_q.q1.data_addr = 0;
6799             /* This is a byte value, otherwise it would need to be swapped. */
6800             asc_sg_head.entry_cnt = asc_scsi_q.q1.sg_queue_cnt = scp->use_sg;
6801             ASC_STATS_ADD(scp->host, sg_elem, asc_sg_head.entry_cnt);
6802     
6803             /*
6804              * Convert scatter-gather list into ASC_SG_HEAD list.
6805              */
6806             slp = (struct scatterlist *) scp->request_buffer;
6807             for (sgcnt = 0; sgcnt < scp->use_sg; sgcnt++, slp++) {
6808                 asc_sg_head.sg_list[sgcnt].addr =
6809                     cpu_to_le32(virt_to_bus(slp->address));
6810                 asc_sg_head.sg_list[sgcnt].bytes = cpu_to_le32(slp->length);
6811                 ASC_STATS_ADD(scp->host, sg_xfer, ASC_CEILING(slp->length, 512));
6812             }
6813         }
6814     
6815         ASC_DBG_PRT_ASC_SCSI_Q(2, &asc_scsi_q);
6816         ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
6817     
6818         return ASC_NOERROR;
6819     }
6820     
6821     /*
6822      * Build a request structure for the Adv Library (Wide Board).
6823      *
6824      * If an adv_req_t can not be allocated to issue the request,
6825      * then return ASC_BUSY. If an error occurs, then return ASC_ERROR.
6826      *
6827      * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the
6828      * microcode for DMA addresses or math operations are byte swapped
6829      * to little-endian order.
6830      */
6831     STATIC int
6832     adv_build_req(asc_board_t *boardp, Scsi_Cmnd *scp,
6833         ADV_SCSI_REQ_Q **adv_scsiqpp)
6834     {
6835         adv_req_t           *reqp;
6836         ADV_SCSI_REQ_Q      *scsiqp;
6837         int                 i;
6838         int                 ret;
6839     
6840         /*
6841          * Allocate an adv_req_t structure from the board to execute
6842          * the command.
6843          */
6844         if (boardp->adv_reqp == NULL) {
6845             ASC_DBG(1, "adv_build_req: no free adv_req_t\n");
6846             ASC_STATS(scp->host, adv_build_noreq);
6847             return ASC_BUSY;
6848         } else {
6849             reqp = boardp->adv_reqp;
6850             boardp->adv_reqp = reqp->next_reqp;
6851             reqp->next_reqp = NULL;
6852         }
6853     
6854         /*
6855          * Get 32-byte aligned ADV_SCSI_REQ_Q and ADV_SG_BLOCK pointers.
6856          */
6857         scsiqp = (ADV_SCSI_REQ_Q *) ADV_32BALIGN(&reqp->scsi_req_q);
6858     
6859         /*
6860          * Initialize the structure.
6861          */
6862         scsiqp->cntl = scsiqp->scsi_cntl = scsiqp->done_status = 0;
6863     
6864         /*
6865          * Set the ADV_SCSI_REQ_Q 'srb_ptr' to point to the adv_req_t structure.
6866          */
6867         scsiqp->srb_ptr = ASC_VADDR_TO_U32(reqp);
6868     
6869         /*
6870          * Set the adv_req_t 'cmndp' to point to the Scsi_Cmnd structure.
6871          */
6872         reqp->cmndp = scp;
6873     
6874         /*
6875          * Build the ADV_SCSI_REQ_Q request.
6876          */
6877     
6878         /*
6879          * Set CDB length and copy it to the request structure.
6880          * For wide  boards a CDB length maximum of 16 bytes
6881          * is supported.
6882          */
6883         if (scp->cmd_len > ADV_MAX_CDB_LEN) {
6884             ASC_PRINT3(
6885     "adv_build_req: board %d: cmd_len %d > ADV_MAX_CDB_LEN  %d\n",
6886                 boardp->id, scp->cmd_len, ADV_MAX_CDB_LEN);
6887             scp->result = HOST_BYTE(DID_ERROR);
6888             asc_enqueue(&boardp->done, scp, ASC_BACK);
6889             return ASC_ERROR;
6890         }
6891         scsiqp->cdb_len = scp->cmd_len;
6892         /* Copy first 12 CDB bytes to cdb[]. */
6893         for (i = 0; i < scp->cmd_len && i < 12; i++) {
6894             scsiqp->cdb[i] = scp->cmnd[i];
6895         }
6896         /* Copy last 4 CDB bytes, if present, to cdb16[]. */
6897         for (; i < scp->cmd_len; i++) {
6898             scsiqp->cdb16[i - 12] = scp->cmnd[i];
6899         }
6900     
6901         scsiqp->target_id = scp->target;
6902         scsiqp->target_lun = scp->lun;
6903     
6904         scsiqp->sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
6905         scsiqp->sense_len = sizeof(scp->sense_buffer);
6906     
6907         /*
6908          * Build ADV_SCSI_REQ_Q for a contiguous buffer or a scatter-gather
6909          * buffer command.
6910          */
6911         scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
6912         scsiqp->vdata_addr = scp->request_buffer;
6913         scsiqp->data_addr = cpu_to_le32(virt_to_bus(scp->request_buffer));
6914     
6915         if (scp->use_sg == 0) {
6916             /*
6917              * CDB request of single contiguous buffer.
6918              */
6919             reqp->sgblkp = NULL;
6920             scsiqp->sg_list_ptr = NULL;
6921             scsiqp->sg_real_addr = 0;
6922             ASC_STATS(scp->host, cont_cnt);
6923             ASC_STATS_ADD(scp->host, cont_xfer,
6924                           ASC_CEILING(scp->request_bufflen, 512));
6925         } else {
6926             /*
6927              * CDB scatter-gather request list.
6928              */
6929             if (scp->use_sg > ADV_MAX_SG_LIST) {
6930                 ASC_PRINT3(
6931     "adv_build_req: board %d: use_sg %d > ADV_MAX_SG_LIST %d\n",
6932                     boardp->id, scp->use_sg, scp->host->sg_tablesize);
6933                 scp->result = HOST_BYTE(DID_ERROR);
6934                 asc_enqueue(&boardp->done, scp, ASC_BACK);
6935     
6936                 /*
6937                  * Free the 'adv_req_t' structure by adding it back to the
6938                  * board free list.
6939                  */
6940                 reqp->next_reqp = boardp->adv_reqp;
6941                 boardp->adv_reqp = reqp;
6942     
6943                 return ASC_ERROR;
6944             }
6945     
6946             if ((ret = adv_get_sglist(boardp, reqp, scp)) != ADV_SUCCESS) {
6947                 /*
6948                  * Free the adv_req_t structure by adding it back to the
6949                  * board free list.
6950                  */
6951                 reqp->next_reqp = boardp->adv_reqp;
6952                 boardp->adv_reqp = reqp;
6953     
6954                 return ret;
6955             }
6956     
6957             ASC_STATS(scp->host, sg_cnt);
6958             ASC_STATS_ADD(scp->host, sg_elem, scp->use_sg);
6959         }
6960     
6961         ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
6962         ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
6963     
6964         *adv_scsiqpp = scsiqp;
6965     
6966         return ASC_NOERROR;
6967     }
6968     
6969     /*
6970      * Build scatter-gather list for Adv Library (Wide Board).
6971      *
6972      * Additional ADV_SG_BLOCK structures will need to be allocated
6973      * if the total number of scatter-gather elements exceeds
6974      * NO_OF_SG_PER_BLOCK (15). The ADV_SG_BLOCK structures are
6975      * assumed to be physically contiguous.
6976      *
6977      * Return:
6978      *      ADV_SUCCESS(1) - SG List successfully created
6979      *      ADV_ERROR(-1) - SG List creation failed
6980      */
6981     STATIC int
6982     adv_get_sglist(asc_board_t *boardp, adv_req_t *reqp, Scsi_Cmnd *scp)
6983     {
6984         adv_sgblk_t         *sgblkp;
6985         ADV_SCSI_REQ_Q      *scsiqp;
6986         struct scatterlist  *slp;
6987         int                 sg_elem_cnt;
6988         ADV_SG_BLOCK        *sg_block, *prev_sg_block;
6989         ADV_PADDR           sg_block_paddr;
6990         int                 i;
6991     
6992         scsiqp = (ADV_SCSI_REQ_Q *) ADV_32BALIGN(&reqp->scsi_req_q);
6993         slp = (struct scatterlist *) scp->request_buffer;
6994         sg_elem_cnt = scp->use_sg;
6995         prev_sg_block = NULL;
6996         reqp->sgblkp = NULL;
6997     
6998         do
6999         {
7000             /*
7001              * Allocate a 'adv_sgblk_t' structure from the board free
7002              * list. One 'adv_sgblk_t' structure holds NO_OF_SG_PER_BLOCK
7003              * (15) scatter-gather elements.
7004              */
7005             if ((sgblkp = boardp->adv_sgblkp) == NULL) {
7006                 ASC_DBG(1, "adv_get_sglist: no free adv_sgblk_t\n");
7007                 ASC_STATS(scp->host, adv_build_nosg);
7008     
7009                 /*
7010                  * Allocation failed. Free 'adv_sgblk_t' structures already
7011                  * allocated for the request.
7012                  */
7013                 while ((sgblkp = reqp->sgblkp) != NULL)
7014                 {
7015                     /* Remove 'sgblkp' from the request list. */
7016                     reqp->sgblkp = sgblkp->next_sgblkp;
7017     
7018                     /* Add 'sgblkp' to the board free list. */
7019                     sgblkp->next_sgblkp = boardp->adv_sgblkp;
7020                     boardp->adv_sgblkp = sgblkp;
7021                 }
7022                 return ASC_BUSY;
7023             } else {
7024                 /* Complete 'adv_sgblk_t' board allocation. */
7025                 boardp->adv_sgblkp = sgblkp->next_sgblkp;
7026                 sgblkp->next_sgblkp = NULL;
7027     
7028                 /*
7029                  * Get 8 byte aligned virtual and physical addresses for
7030                  * the allocated ADV_SG_BLOCK structure.
7031                  */
7032                 sg_block = (ADV_SG_BLOCK *) ADV_8BALIGN(&sgblkp->sg_block);
7033                 sg_block_paddr = virt_to_bus(sg_block);
7034     
7035                 /*
7036                  * Check if this is the first 'adv_sgblk_t' for the request.
7037                  */
7038                 if (reqp->sgblkp == NULL)
7039                 {
7040                     /* Request's first scatter-gather block. */
7041                     reqp->sgblkp = sgblkp;
7042     
7043                     /*
7044                      * Set ADV_SCSI_REQ_T ADV_SG_BLOCK virtual and physical
7045                      * address pointers.
7046                      */
7047                     scsiqp->sg_list_ptr = sg_block;
7048                     scsiqp->sg_real_addr = cpu_to_le32(sg_block_paddr);
7049                 } else
7050                 {
7051                     /* Request's second or later scatter-gather block. */
7052                     sgblkp->next_sgblkp = reqp->sgblkp;
7053                     reqp->sgblkp = sgblkp;
7054     
7055                     /*
7056                      * Point the previous ADV_SG_BLOCK structure to
7057                      * the newly allocated ADV_SG_BLOCK structure.
7058                      */
7059                     ASC_ASSERT(prev_sg_block != NULL);
7060                     prev_sg_block->sg_ptr = cpu_to_le32(sg_block_paddr);
7061                 }
7062             }
7063     
7064             for (i = 0; i < NO_OF_SG_PER_BLOCK; i++)
7065             {
7066                 sg_block->sg_list[i].sg_addr =
7067                     cpu_to_le32(virt_to_bus(slp->address));
7068                 sg_block->sg_list[i].sg_count = cpu_to_le32(slp->length);
7069                 ASC_STATS_ADD(scp->host, sg_xfer, ASC_CEILING(slp->length, 512));
7070     
7071                 if (--sg_elem_cnt == 0)
7072                 {   /* Last ADV_SG_BLOCK and scatter-gather entry. */
7073                     sg_block->sg_cnt = i + 1;
7074                     sg_block->sg_ptr = 0L;    /* Last ADV_SG_BLOCK in list. */
7075                     return ADV_SUCCESS;
7076                 }
7077                 slp++;
7078             }
7079             sg_block->sg_cnt = NO_OF_SG_PER_BLOCK;
7080             prev_sg_block = sg_block;
7081         }
7082         while (1);
7083         /* NOTREACHED */
7084     }
7085     
7086     /*
7087      * asc_isr_callback() - Second Level Interrupt Handler called by AscISR().
7088      *
7089      * Interrupt callback function for the Narrow SCSI Asc Library.
7090      */
7091     STATIC void
7092     asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
7093     {
7094         asc_board_t         *boardp;
7095         Scsi_Cmnd           *scp;
7096         struct Scsi_Host    *shp;
7097         int                 i;
7098     
7099         ASC_DBG2(1, "asc_isr_callback: asc_dvc_varp 0x%lx, qdonep 0x%lx\n",
7100             (ulong) asc_dvc_varp, (ulong) qdonep);
7101         ASC_DBG_PRT_ASC_QDONE_INFO(2, qdonep);
7102     
7103         /*
7104          * Get the Scsi_Cmnd structure and Scsi_Host structure for the
7105          * command that has been completed.
7106          */
7107         scp = (Scsi_Cmnd *) ASC_U32_TO_VADDR(qdonep->d2.srb_ptr);
7108         ASC_DBG1(1, "asc_isr_callback: scp 0x%lx\n", (ulong) scp);
7109     
7110         if (scp == NULL) {
7111             ASC_PRINT("asc_isr_callback: scp is NULL\n");
7112             return;
7113         }
7114         ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
7115     
7116         /*
7117          * If the request's host pointer is not valid, display a
7118          * message and return.
7119          */
7120         shp = scp->host;
7121         for (i = 0; i < asc_board_count; i++) {
7122             if (asc_host[i] == shp) {
7123                 break;
7124             }
7125         }
7126         if (i == asc_board_count) {
7127             ASC_PRINT2(
7128                 "asc_isr_callback: scp 0x%lx has bad host pointer, host 0x%lx\n",
7129                 (ulong) scp, (ulong) shp);
7130             return;
7131         }
7132     
7133         ASC_STATS(shp, callback);
7134         ASC_DBG1(1, "asc_isr_callback: shp 0x%lx\n", (ulong) shp);
7135     
7136         /*
7137          * If the request isn't found on the active queue, it may
7138          * have been removed to handle a reset request.
7139          * Display a message and return.
7140          */
7141         boardp = ASC_BOARDP(shp);
7142         ASC_ASSERT(asc_dvc_varp == &boardp->dvc_var.asc_dvc_var);
7143         if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) {
7144             ASC_PRINT2(
7145                 "asc_isr_callback: board %d: scp 0x%lx not on active queue\n",
7146                 boardp->id, (ulong) scp);
7147             return;
7148         }
7149     
7150         /*
7151          * 'qdonep' contains the command's ending status.
7152          */
7153         switch (qdonep->d3.done_stat) {
7154         case QD_NO_ERROR:
7155             ASC_DBG(2, "asc_isr_callback: QD_NO_ERROR\n");
7156             scp->result = 0;
7157     
7158             /*
7159              * If an INQUIRY command completed successfully, then call
7160              * the AscInquiryHandling() function to set-up the device.
7161              */
7162             if (scp->cmnd[0] == SCSICMD_Inquiry && scp->lun == 0 &&
7163                 (scp->request_bufflen - qdonep->remain_bytes) >= 8)
7164             {
7165                 AscInquiryHandling(asc_dvc_varp, scp->target & 0x7,
7166                     (ASC_SCSI_INQUIRY *) scp->request_buffer);
7167             }
7168     
7169     #if ASC_LINUX_KERNEL24
7170             /*
7171              * Check for an underrun condition.
7172              *
7173              * If there was no error and an underrun condition, then
7174              * then return the number of underrun bytes.
7175              */
7176             if (scp->request_bufflen != 0 && qdonep->remain_bytes != 0 &&
7177                 qdonep->remain_bytes <= scp->request_bufflen != 0) {
7178                 ASC_DBG1(1, "asc_isr_callback: underrun condition %u bytes\n",
7179                 (unsigned) qdonep->remain_bytes);
7180                 scp->resid = qdonep->remain_bytes;
7181             }
7182     #endif
7183             break;
7184     
7185         case QD_WITH_ERROR:
7186             ASC_DBG(2, "asc_isr_callback: QD_WITH_ERROR\n");
7187             switch (qdonep->d3.host_stat) {
7188             case QHSTA_NO_ERROR:
7189                 if (qdonep->d3.scsi_stat == SS_CHK_CONDITION) {
7190                     ASC_DBG(2, "asc_isr_callback: SS_CHK_CONDITION\n");
7191                     ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
7192                         sizeof(scp->sense_buffer));
7193                     /*
7194                      * Note: The 'status_byte()' macro used by target drivers
7195                      * defined in scsi.h shifts the status byte returned by
7196                      * host drivers right by 1 bit. This is why target drivers
7197                      * also use right shifted status byte definitions. For
7198                      * instance target drivers use CHECK_CONDITION, defined to
7199                      * 0x1, instead of the SCSI defined check condition value
7200                      * of 0x2. Host drivers are supposed to return the status
7201                      * byte as it is defined by SCSI.
7202                      */
7203                     scp->result = DRIVER_BYTE(DRIVER_SENSE) |
7204                         STATUS_BYTE(qdonep->d3.scsi_stat);
7205                 } else {
7206                     scp->result = STATUS_BYTE(qdonep->d3.scsi_stat);
7207                 }
7208                 break;
7209     
7210             default:
7211                 /* QHSTA error occurred */
7212                 ASC_DBG1(1, "asc_isr_callback: host_stat 0x%x\n",
7213                     qdonep->d3.host_stat);
7214                 scp->result = HOST_BYTE(DID_BAD_TARGET);
7215                 break;
7216             }
7217             break;
7218     
7219         case QD_ABORTED_BY_HOST:
7220             ASC_DBG(1, "asc_isr_callback: QD_ABORTED_BY_HOST\n");
7221             scp->result = HOST_BYTE(DID_ABORT) | MSG_BYTE(qdonep->d3.scsi_msg) |
7222                     STATUS_BYTE(qdonep->d3.scsi_stat);
7223             break;
7224     
7225         default:
7226             ASC_DBG1(1, "asc_isr_callback: done_stat 0x%x\n", qdonep->d3.done_stat);
7227             scp->result = HOST_BYTE(DID_ERROR) | MSG_BYTE(qdonep->d3.scsi_msg) |
7228                     STATUS_BYTE(qdonep->d3.scsi_stat);
7229             break;
7230         }
7231     
7232         /*
7233          * If the 'init_tidmask' bit isn't already set for the target and the
7234          * current request finished normally, then set the bit for the target
7235          * to indicate that a device is present.
7236          */
7237         if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->target)) == 0 &&
7238             qdonep->d3.done_stat == QD_NO_ERROR &&
7239             qdonep->d3.host_stat == QHSTA_NO_ERROR) {
7240             boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->target);
7241         }
7242     
7243         /*
7244          * Because interrupts may be enabled by the 'Scsi_Cmnd' done
7245          * function, add the command to the end of the board's done queue.
7246          * The done function for the command will be called from
7247          * advansys_interrupt().
7248          */
7249         asc_enqueue(&boardp->done, scp, ASC_BACK);
7250     
7251         return;
7252     }
7253     
7254     /*
7255      * adv_isr_callback() - Second Level Interrupt Handler called by AdvISR().
7256      *
7257      * Callback function for the Wide SCSI Adv Library.
7258      */
7259     STATIC void
7260     adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp)
7261     {
7262         asc_board_t         *boardp;
7263         adv_req_t           *reqp;
7264         adv_sgblk_t         *sgblkp;
7265         Scsi_Cmnd           *scp;
7266         struct Scsi_Host    *shp;
7267         int                 i;
7268     #if ASC_LINUX_KERNEL24
7269         ADV_DCNT            resid_cnt;
7270     #endif
7271     
7272     
7273         ASC_DBG2(1, "adv_isr_callback: adv_dvc_varp 0x%lx, scsiqp 0x%lx\n",
7274             (ulong) adv_dvc_varp, (ulong) scsiqp);
7275         ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
7276     
7277         /*
7278          * Get the adv_req_t structure for the command that has been
7279          * completed. The adv_req_t structure actually contains the
7280          * completed ADV_SCSI_REQ_Q structure.
7281          */
7282         reqp = (adv_req_t *) ADV_U32_TO_VADDR(scsiqp->srb_ptr);
7283         ASC_DBG1(1, "adv_isr_callback: reqp 0x%lx\n", (ulong) reqp);
7284         if (reqp == NULL) {
7285             ASC_PRINT("adv_isr_callback: reqp is NULL\n");
7286             return;
7287         }
7288     
7289         /*
7290          * Get the Scsi_Cmnd structure and Scsi_Host structure for the
7291          * command that has been completed.
7292          *
7293          * Note: The adv_req_t request structure and adv_sgblk_t structure,
7294          * if any, are dropped, because a board structure pointer can not be
7295          * determined.
7296          */
7297         scp = reqp->cmndp;
7298         ASC_DBG1(1, "adv_isr_callback: scp 0x%lx\n", (ulong) scp);
7299         if (scp == NULL) {
7300             ASC_PRINT("adv_isr_callback: scp is NULL; adv_req_t dropped.\n");
7301             return;
7302         }
7303         ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
7304     
7305         /*
7306          * If the request's host pointer is not valid, display a message
7307          * and return.
7308          */
7309         shp = scp->host;
7310         for (i = 0; i < asc_board_count; i++) {
7311             if (asc_host[i] == shp) {
7312                 break;
7313             }
7314         }
7315         /*
7316          * Note: If the host structure is not found, the adv_req_t request
7317          * structure and adv_sgblk_t structure, if any, is dropped.
7318          */
7319         if (i == asc_board_count) {
7320             ASC_PRINT2(
7321                 "adv_isr_callback: scp 0x%lx has bad host pointer, host 0x%lx\n",
7322                 (ulong) scp, (ulong) shp);
7323             return;
7324         }
7325     
7326         ASC_STATS(shp, callback);
7327         ASC_DBG1(1, "adv_isr_callback: shp 0x%lx\n", (ulong) shp);
7328     
7329         /*
7330          * If the request isn't found on the active queue, it may have been
7331          * removed to handle a reset request. Display a message and return.
7332          *
7333          * Note: Because the structure may still be in use don't attempt
7334          * to free the adv_req_t and adv_sgblk_t, if any, structures.
7335          */
7336         boardp = ASC_BOARDP(shp);
7337         ASC_ASSERT(adv_dvc_varp == &boardp->dvc_var.adv_dvc_var);
7338         if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) {
7339             ASC_PRINT2(
7340                 "adv_isr_callback: board %d: scp 0x%lx not on active queue\n",
7341                 boardp->id, (ulong) scp);
7342             return;
7343         }
7344     
7345         /*
7346          * 'done_status' contains the command's ending status.
7347          */
7348         switch (scsiqp->done_status) {
7349         case QD_NO_ERROR:
7350             ASC_DBG(2, "adv_isr_callback: QD_NO_ERROR\n");
7351             scp->result = 0;
7352     
7353     #if ASC_LINUX_KERNEL24
7354             /*
7355              * Check for an underrun condition.
7356              *
7357              * If there was no error and an underrun condition, then
7358              * then return the number of underrun bytes.
7359              */
7360             resid_cnt = le32_to_cpu(scsiqp->data_cnt);
7361             if (scp->request_bufflen != 0 && resid_cnt != 0 &&
7362                 resid_cnt <= scp->request_bufflen) {
7363                 ASC_DBG1(1, "adv_isr_callback: underrun condition %lu bytes\n",
7364                     (ulong) resid_cnt);
7365                 scp->resid = resid_cnt;
7366             }
7367     #endif
7368             break;
7369     
7370         case QD_WITH_ERROR:
7371             ASC_DBG(2, "adv_isr_callback: QD_WITH_ERROR\n");
7372             switch (scsiqp->host_status) {
7373             case QHSTA_NO_ERROR:
7374                 if (scsiqp->scsi_status == SS_CHK_CONDITION) {
7375                     ASC_DBG(2, "adv_isr_callback: SS_CHK_CONDITION\n");
7376                     ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
7377                         sizeof(scp->sense_buffer));
7378                     /*
7379                      * Note: The 'status_byte()' macro used by target drivers
7380                      * defined in scsi.h shifts the status byte returned by
7381                      * host drivers right by 1 bit. This is why target drivers
7382                      * also use right shifted status byte definitions. For
7383                      * instance target drivers use CHECK_CONDITION, defined to
7384                      * 0x1, instead of the SCSI defined check condition value
7385                      * of 0x2. Host drivers are supposed to return the status
7386                      * byte as it is defined by SCSI.
7387                      */
7388                     scp->result = DRIVER_BYTE(DRIVER_SENSE) |
7389                         STATUS_BYTE(scsiqp->scsi_status);
7390                 } else {
7391                     scp->result = STATUS_BYTE(scsiqp->scsi_status);
7392                 }
7393                 break;
7394     
7395             default:
7396                 /* Some other QHSTA error occurred. */
7397                 ASC_DBG1(1, "adv_isr_callback: host_status 0x%x\n",
7398                     scsiqp->host_status);
7399                 scp->result = HOST_BYTE(DID_BAD_TARGET);
7400                 break;
7401             }
7402             break;
7403     
7404         case QD_ABORTED_BY_HOST:
7405             ASC_DBG(1, "adv_isr_callback: QD_ABORTED_BY_HOST\n");
7406             scp->result = HOST_BYTE(DID_ABORT) | STATUS_BYTE(scsiqp->scsi_status);
7407             break;
7408     
7409         default:
7410             ASC_DBG1(1, "adv_isr_callback: done_status 0x%x\n", scsiqp->done_status);
7411             scp->result = HOST_BYTE(DID_ERROR) | STATUS_BYTE(scsiqp->scsi_status);
7412             break;
7413         }
7414     
7415         /*
7416          * If the 'init_tidmask' bit isn't already set for the target and the
7417          * current request finished normally, then set the bit for the target
7418          * to indicate that a device is present.
7419          */
7420         if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->target)) == 0 &&
7421             scsiqp->done_status == QD_NO_ERROR &&
7422             scsiqp->host_status == QHSTA_NO_ERROR) {
7423             boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->target);
7424         }
7425     
7426         /*
7427          * Because interrupts may be enabled by the 'Scsi_Cmnd' done
7428          * function, add the command to the end of the board's done queue.
7429          * The done function for the command will be called from
7430          * advansys_interrupt().
7431          */
7432         asc_enqueue(&boardp->done, scp, ASC_BACK);
7433     
7434         /*
7435          * Free all 'adv_sgblk_t' structures allocated for the request.
7436          */
7437         while ((sgblkp = reqp->sgblkp) != NULL)
7438         {
7439             /* Remove 'sgblkp' from the request list. */
7440             reqp->sgblkp = sgblkp->next_sgblkp;
7441     
7442             /* Add 'sgblkp' to the board free list. */
7443             sgblkp->next_sgblkp = boardp->adv_sgblkp;
7444             boardp->adv_sgblkp = sgblkp;
7445         }
7446     
7447         /*
7448          * Free the adv_req_t structure used with the command by adding
7449          * it back to the board free list.
7450          */
7451         reqp->next_reqp = boardp->adv_reqp;
7452         boardp->adv_reqp = reqp;
7453     
7454         ASC_DBG(1, "adv_isr_callback: done\n");
7455     
7456         return;
7457     }
7458     
7459     /*
7460      * adv_async_callback() - Adv Library asynchronous event callback function.
7461      */
7462     STATIC void
7463     adv_async_callback(ADV_DVC_VAR *adv_dvc_varp, uchar code)
7464     {
7465         switch (code)
7466         {
7467         case ADV_ASYNC_SCSI_BUS_RESET_DET:
7468             /*
7469              * The firmware detected a SCSI Bus reset.
7470              */
7471             ASC_DBG(0, "adv_async_callback: ADV_ASYNC_SCSI_BUS_RESET_DET\n");
7472             break;
7473     
7474         case ADV_ASYNC_RDMA_FAILURE:
7475             /*
7476              * Handle RDMA failure by resetting the SCSI Bus and
7477              * possibly the chip if it is unresponsive. Log the error
7478              * with a unique code.
7479              */
7480             ASC_DBG(0, "adv_async_callback: ADV_ASYNC_RDMA_FAILURE\n");
7481             AdvResetChipAndSB(adv_dvc_varp);
7482             break;
7483     
7484         case ADV_HOST_SCSI_BUS_RESET:
7485             /*
7486              * Host generated SCSI bus reset occurred.
7487              */
7488             ASC_DBG(0, "adv_async_callback: ADV_HOST_SCSI_BUS_RESET\n");
7489             break;
7490     
7491         default:
7492             ASC_DBG1(0, "DvcAsyncCallBack: unknown code 0x%x\n", code);
7493             break;
7494         }
7495     }
7496     
7497     /*
7498      * Add a 'REQP' to the end of specified queue. Set 'tidmask'
7499      * to indicate a command is queued for the device.
7500      *
7501      * 'flag' may be either ASC_FRONT or ASC_BACK.
7502      *
7503      * 'REQPNEXT(reqp)' returns reqp's next pointer.
7504      */
7505     STATIC void
7506     asc_enqueue(asc_queue_t *ascq, REQP reqp, int flag)
7507     {
7508         int        tid;
7509     
7510         ASC_DBG3(3, "asc_enqueue: ascq 0x%lx, reqp 0x%lx, flag %d\n",
7511             (ulong) ascq, (ulong) reqp, flag);
7512         ASC_ASSERT(reqp != NULL);
7513         ASC_ASSERT(flag == ASC_FRONT || flag == ASC_BACK);
7514         tid = REQPTID(reqp);
7515         ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
7516         if (flag == ASC_FRONT) {
7517             REQPNEXT(reqp) = ascq->q_first[tid];
7518             ascq->q_first[tid] = reqp;
7519             /* If the queue was empty, set the last pointer. */
7520             if (ascq->q_last[tid] == NULL) {
7521                 ascq->q_last[tid] = reqp;
7522             }
7523         } else { /* ASC_BACK */
7524             if (ascq->q_last[tid] != NULL) {
7525                 REQPNEXT(ascq->q_last[tid]) = reqp;
7526             }
7527             ascq->q_last[tid] = reqp;
7528             REQPNEXT(reqp) = NULL;
7529             /* If the queue was empty, set the first pointer. */
7530             if (ascq->q_first[tid] == NULL) {
7531                 ascq->q_first[tid] = reqp;
7532             }
7533         }
7534         /* The queue has at least one entry, set its bit. */
7535         ascq->q_tidmask |= ADV_TID_TO_TIDMASK(tid);
7536     #ifdef ADVANSYS_STATS
7537         /* Maintain request queue statistics. */
7538         ascq->q_tot_cnt[tid]++;
7539         ascq->q_cur_cnt[tid]++;
7540         if (ascq->q_cur_cnt[tid] > ascq->q_max_cnt[tid]) {
7541             ascq->q_max_cnt[tid] = ascq->q_cur_cnt[tid];
7542             ASC_DBG2(2, "asc_enqueue: new q_max_cnt[%d] %d\n",
7543                 tid, ascq->q_max_cnt[tid]);
7544         }
7545         REQPTIME(reqp) = REQTIMESTAMP();
7546     #endif /* ADVANSYS_STATS */
7547         ASC_DBG1(3, "asc_enqueue: reqp 0x%lx\n", (ulong) reqp);
7548         return;
7549     }
7550     
7551     /*
7552      * Return first queued 'REQP' on the specified queue for
7553      * the specified target device. Clear the 'tidmask' bit for
7554      * the device if no more commands are left queued for it.
7555      *
7556      * 'REQPNEXT(reqp)' returns reqp's next pointer.
7557      */
7558     STATIC REQP
7559     asc_dequeue(asc_queue_t *ascq, int tid)
7560     {
7561         REQP    reqp;
7562     
7563         ASC_DBG2(3, "asc_dequeue: ascq 0x%lx, tid %d\n", (ulong) ascq, tid);
7564         ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
7565         if ((reqp = ascq->q_first[tid]) != NULL) {
7566             ASC_ASSERT(ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid));
7567             ascq->q_first[tid] = REQPNEXT(reqp);
7568             /* If the queue is empty, clear its bit and the last pointer. */
7569             if (ascq->q_first[tid] == NULL) {
7570                 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
7571                 ASC_ASSERT(ascq->q_last[tid] == reqp);
7572                 ascq->q_last[tid] = NULL;
7573             }
7574     #ifdef ADVANSYS_STATS
7575             /* Maintain request queue statistics. */
7576             ascq->q_cur_cnt[tid]--;
7577             ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0);
7578             REQTIMESTAT("asc_dequeue", ascq, reqp, tid);
7579     #endif /* ADVANSYS_STATS */
7580         }
7581         ASC_DBG1(3, "asc_dequeue: reqp 0x%lx\n", (ulong) reqp);
7582         return reqp;
7583     }
7584     
7585     /*
7586      * Return a pointer to a singly linked list of all the requests queued
7587      * for 'tid' on the 'asc_queue_t' pointed to by 'ascq'.
7588      *
7589      * If 'lastpp' is not NULL, '*lastpp' will be set to point to the
7590      * the last request returned in the singly linked list.
7591      *
7592      * 'tid' should either be a valid target id or if it is ASC_TID_ALL,
7593      * then all queued requests are concatenated into one list and
7594      * returned.
7595      *
7596      * Note: If 'lastpp' is used to append a new list to the end of
7597      * an old list, only change the old list last pointer if '*lastpp'
7598      * (or the function return value) is not NULL, i.e. use a temporary
7599      * variable for 'lastpp' and check its value after the function return
7600      * before assigning it to the list last pointer.
7601      *
7602      * Unfortunately collecting queuing time statistics adds overhead to
7603      * the function that isn't inherent to the function's algorithm.
7604      */
7605     STATIC REQP
7606     asc_dequeue_list(asc_queue_t *ascq, REQP *lastpp, int tid)
7607     {
7608         REQP    firstp, lastp;
7609         int     i;
7610     
7611         ASC_DBG2(3, "asc_dequeue_list: ascq 0x%lx, tid %d\n", (ulong) ascq, tid);
7612         ASC_ASSERT((tid == ASC_TID_ALL) || (tid >= 0 && tid <= ADV_MAX_TID));
7613     
7614         /*
7615          * If 'tid' is not ASC_TID_ALL, return requests only for
7616          * the specified 'tid'. If 'tid' is ASC_TID_ALL, return all
7617          * requests for all tids.
7618          */
7619         if (tid != ASC_TID_ALL) {
7620             /* Return all requests for the specified 'tid'. */
7621             if ((ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid)) == 0) {
7622                 /* List is empty; Set first and last return pointers to NULL. */
7623                 firstp = lastp = NULL;
7624             } else {
7625                 firstp = ascq->q_first[tid];
7626                 lastp = ascq->q_last[tid];
7627                 ascq->q_first[tid] = ascq->q_last[tid] = NULL;
7628                 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
7629     #ifdef ADVANSYS_STATS
7630                 {
7631                     REQP reqp;
7632                     ascq->q_cur_cnt[tid] = 0;
7633                     for (reqp = firstp; reqp; reqp = REQPNEXT(reqp)) {
7634                         REQTIMESTAT("asc_dequeue_list", ascq, reqp, tid);
7635                     }
7636                 }
7637     #endif /* ADVANSYS_STATS */
7638             }
7639         } else {
7640             /* Return all requests for all tids. */
7641             firstp = lastp = NULL;
7642             for (i = 0; i <= ADV_MAX_TID; i++) {
7643                 if (ascq->q_tidmask & ADV_TID_TO_TIDMASK(i)) {
7644                     if (firstp == NULL) {
7645                         firstp = ascq->q_first[i];
7646                         lastp = ascq->q_last[i];
7647                     } else {
7648                         ASC_ASSERT(lastp != NULL);
7649                         REQPNEXT(lastp) = ascq->q_first[i];
7650                         lastp = ascq->q_last[i];
7651                     }
7652                     ascq->q_first[i] = ascq->q_last[i] = NULL;
7653                     ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(i);
7654     #ifdef ADVANSYS_STATS
7655                     ascq->q_cur_cnt[i] = 0;
7656     #endif /* ADVANSYS_STATS */
7657                 }
7658             }
7659     #ifdef ADVANSYS_STATS
7660             {
7661                 REQP reqp;
7662                 for (reqp = firstp; reqp; reqp = REQPNEXT(reqp)) {
7663                     REQTIMESTAT("asc_dequeue_list", ascq, reqp, reqp->target);
7664                 }
7665             }
7666     #endif /* ADVANSYS_STATS */
7667         }
7668         if (lastpp) {
7669             *lastpp = lastp;
7670         }
7671         ASC_DBG1(3, "asc_dequeue_list: firstp 0x%lx\n", (ulong) firstp);
7672         return firstp;
7673     }
7674     
7675     /*
7676      * Remove the specified 'REQP' from the specified queue for
7677      * the specified target device. Clear the 'tidmask' bit for the
7678      * device if no more commands are left queued for it.
7679      *
7680      * 'REQPNEXT(reqp)' returns reqp's the next pointer.
7681      *
7682      * Return ASC_TRUE if the command was found and removed,
7683      * otherwise return ASC_FALSE.
7684      */
7685     STATIC int
7686     asc_rmqueue(asc_queue_t *ascq, REQP reqp)
7687     {
7688         REQP        currp, prevp;
7689         int         tid;
7690         int         ret = ASC_FALSE;
7691     
7692         ASC_DBG2(3, "asc_rmqueue: ascq 0x%lx, reqp 0x%lx\n",
7693             (ulong) ascq, (ulong) reqp);
7694         ASC_ASSERT(reqp != NULL);
7695     
7696         tid = REQPTID(reqp);
7697         ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
7698     
7699         /*
7700          * Handle the common case of 'reqp' being the first
7701          * entry on the queue.
7702          */
7703         if (reqp == ascq->q_first[tid]) {
7704             ret = ASC_TRUE;
7705             ascq->q_first[tid] = REQPNEXT(reqp);
7706             /* If the queue is now empty, clear its bit and the last pointer. */
7707             if (ascq->q_first[tid] == NULL) {
7708                 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
7709                 ASC_ASSERT(ascq->q_last[tid] == reqp);
7710                 ascq->q_last[tid] = NULL;
7711             }
7712         } else if (ascq->q_first[tid] != NULL) {
7713             ASC_ASSERT(ascq->q_last[tid] != NULL);
7714             /*
7715              * Because the case of 'reqp' being the first entry has been
7716              * handled above and it is known the queue is not empty, if
7717              * 'reqp' is found on the queue it is guaranteed the queue will
7718              * not become empty and that 'q_first[tid]' will not be changed.
7719              *
7720              * Set 'prevp' to the first entry, 'currp' to the second entry,
7721              * and search for 'reqp'.
7722              */
7723             for (prevp = ascq->q_first[tid], currp = REQPNEXT(prevp);
7724                  currp; prevp = currp, currp = REQPNEXT(currp)) {
7725                 if (currp == reqp) {
7726                     ret = ASC_TRUE;
7727                     REQPNEXT(prevp) = REQPNEXT(currp);
7728                     REQPNEXT(reqp) = NULL;
7729                     if (ascq->q_last[tid] == reqp) {
7730                         ascq->q_last[tid] = prevp;
7731                     }
7732                     break;
7733                 }
7734             }
7735         }
7736     #ifdef ADVANSYS_STATS
7737         /* Maintain request queue statistics. */
7738         if (ret == ASC_TRUE) {
7739             ascq->q_cur_cnt[tid]--;
7740             REQTIMESTAT("asc_rmqueue", ascq, reqp, tid);
7741         }
7742         ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0);
7743     #endif /* ADVANSYS_STATS */
7744         ASC_DBG2(3, "asc_rmqueue: reqp 0x%lx, ret %d\n", (ulong) reqp, ret);
7745         return ret;
7746     }
7747     
7748     /*
7749      * Execute as many queued requests as possible for the specified queue.
7750      *
7751      * Calls asc_execute_scsi_cmnd() to execute a REQP/Scsi_Cmnd.
7752      */
7753     STATIC void
7754     asc_execute_queue(asc_queue_t *ascq)
7755     {
7756         ADV_SCSI_BIT_ID_TYPE    scan_tidmask;
7757         REQP                    reqp;
7758         int                     i;
7759     
7760         ASC_DBG1(1, "asc_execute_queue: ascq 0x%lx\n", (ulong) ascq);
7761         /*
7762          * Execute queued commands for devices attached to
7763          * the current board in round-robin fashion.
7764          */
7765         scan_tidmask = ascq->q_tidmask;
7766         do {
7767             for (i = 0; i <= ADV_MAX_TID; i++) {
7768                 if (scan_tidmask & ADV_TID_TO_TIDMASK(i)) {
7769                     if ((reqp = asc_dequeue(ascq, i)) == NULL) {
7770                         scan_tidmask &= ~ADV_TID_TO_TIDMASK(i);
7771                     } else if (asc_execute_scsi_cmnd((Scsi_Cmnd *) reqp)
7772                                 == ASC_BUSY) {
7773                         scan_tidmask &= ~ADV_TID_TO_TIDMASK(i);
7774                         /*
7775                          * The request returned ASC_BUSY. Enqueue at the front of
7776                          * target's waiting list to maintain correct ordering.
7777                          */
7778                         asc_enqueue(ascq, reqp, ASC_FRONT);
7779                     }
7780                 }
7781             }
7782         } while (scan_tidmask);
7783         return;
7784     }
7785     
7786     #ifdef CONFIG_PROC_FS
7787     /*
7788      * asc_prt_board_devices()
7789      *
7790      * Print driver information for devices attached to the board.
7791      *
7792      * Note: no single line should be greater than ASC_PRTLINE_SIZE,
7793      * cf. asc_prt_line().
7794      *
7795      * Return the number of characters copied into 'cp'. No more than
7796      * 'cplen' characters will be copied to 'cp'.
7797      */
7798     STATIC int
7799     asc_prt_board_devices(struct Scsi_Host *shp, char *cp, int cplen)
7800     {
7801         asc_board_t        *boardp;
7802         int                leftlen;
7803         int                totlen;
7804         int                len;
7805         int                chip_scsi_id;
7806         int                i;
7807     
7808         boardp = ASC_BOARDP(shp);
7809         leftlen = cplen;
7810         totlen = len = 0;
7811     
7812         len = asc_prt_line(cp, leftlen,
7813     "\nDevice Information for AdvanSys SCSI Host %d:\n", shp->host_no);
7814         ASC_PRT_NEXT();
7815     
7816         if (ASC_NARROW_BOARD(boardp)) {
7817             chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
7818         } else {
7819             chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
7820         }
7821     
7822         len = asc_prt_line(cp, leftlen, "Target IDs Detected:");
7823         ASC_PRT_NEXT();
7824         for (i = 0; i <= ADV_MAX_TID; i++) {
7825             if (boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) {
7826                 len = asc_prt_line(cp, leftlen, " %X,", i);
7827                 ASC_PRT_NEXT();
7828             }
7829         }
7830         len = asc_prt_line(cp, leftlen, " (%X=Host Adapter)\n", chip_scsi_id);
7831         ASC_PRT_NEXT();
7832     
7833         return totlen;
7834     }
7835     
7836     /*
7837      * Display Wide Board BIOS Information.
7838      */
7839     STATIC int
7840     asc_prt_adv_bios(struct Scsi_Host *shp, char *cp, int cplen)
7841     {
7842         asc_board_t        *boardp;
7843         int                leftlen;
7844         int                totlen;
7845         int                len;
7846         ushort             major, minor, letter;
7847     
7848         boardp = ASC_BOARDP(shp);
7849         leftlen = cplen;
7850         totlen = len = 0;
7851     
7852         len = asc_prt_line(cp, leftlen, "\nROM BIOS Version: ");
7853         ASC_PRT_NEXT();
7854     
7855         /*
7856          * If the BIOS saved a valid signature, then fill in
7857          * the BIOS code segment base address.
7858          */
7859         if (boardp->bios_signature != 0x55AA) {
7860             len = asc_prt_line(cp, leftlen, "Disabled or Pre-3.1\n");
7861             ASC_PRT_NEXT();
7862             len = asc_prt_line(cp, leftlen,
7863     "BIOS either disabled or Pre-3.1. If it is pre-3.1, then a newer version\n");
7864             ASC_PRT_NEXT();
7865             len = asc_prt_line(cp, leftlen,
7866     "can be found at the ConnectCom FTP site: ftp://ftp.connectcom.net/pub\n");
7867             ASC_PRT_NEXT();
7868         } else {
7869             major = (boardp->bios_version >> 12) & 0xF;
7870             minor = (boardp->bios_version >> 8) & 0xF;
7871             letter = (boardp->bios_version & 0xFF);
7872     
7873             len = asc_prt_line(cp, leftlen, "%d.%d%c\n",
7874                 major, minor, letter >= 26 ? '?' : letter + 'A');
7875             ASC_PRT_NEXT();
7876     
7877             /*
7878              * Current available ROM BIOS release is 3.1I for UW
7879              * and 3.2I for U2W. This code doesn't differentiate
7880              * UW and U2W boards.
7881              */
7882             if (major < 3 || (major <= 3 && minor < 1) ||
7883                 (major <= 3 && minor <= 1 && letter < ('I'- 'A'))) {
7884                 len = asc_prt_line(cp, leftlen,
7885     "Newer version of ROM BIOS is available at the ConnectCom FTP site:\n");
7886                 ASC_PRT_NEXT();
7887                 len = asc_prt_line(cp, leftlen,
7888     "ftp://ftp.connectcom.net/pub\n");
7889                 ASC_PRT_NEXT();
7890             }
7891         }
7892     
7893         return totlen;
7894     }
7895     
7896     /*
7897      * Add serial number to information bar if signature AAh
7898      * is found in at bit 15-9 (7 bits) of word 1.
7899      *
7900      * Serial Number consists fo 12 alpha-numeric digits.
7901      *
7902      *       1 - Product type (A,B,C,D..)  Word0: 15-13 (3 bits)
7903      *       2 - MFG Location (A,B,C,D..)  Word0: 12-10 (3 bits)
7904      *     3-4 - Product ID (0-99)         Word0: 9-0 (10 bits)
7905      *       5 - Product revision (A-J)    Word0:  "         "
7906      *
7907      *           Signature                 Word1: 15-9 (7 bits)
7908      *       6 - Year (0-9)                Word1: 8-6 (3 bits) & Word2: 15 (1 bit)
7909      *     7-8 - Week of the year (1-52)   Word1: 5-0 (6 bits)
7910      *
7911      *    9-12 - Serial Number (A001-Z999) Word2: 14-0 (15 bits)
7912      *
7913      * Note 1: Only production cards will have a serial number.
7914      *
7915      * Note 2: Signature is most significant 7 bits (0xFE).
7916      *
7917      * Returns ASC_TRUE if serial number found, otherwise returns ASC_FALSE.
7918      */
7919     STATIC int
7920     asc_get_eeprom_string(ushort *serialnum, uchar *cp)
7921     {
7922         ushort      w, num;
7923     
7924         if ((serialnum[1] & 0xFE00) != ((ushort) 0xAA << 8)) {
7925             return ASC_FALSE;
7926         } else {
7927             /*
7928              * First word - 6 digits.
7929              */
7930             w = serialnum[0];
7931     
7932             /* Product type - 1st digit. */
7933             if ((*cp = 'A' + ((w & 0xE000) >> 13)) == 'H') {
7934                 /* Product type is P=Prototype */
7935                 *cp += 0x8;
7936             }
7937             cp++;
7938     
7939             /* Manufacturing location - 2nd digit. */
7940             *cp++ = 'A' + ((w & 0x1C00) >> 10);
7941     
7942             /* Product ID - 3rd, 4th digits. */
7943             num = w & 0x3FF;
7944             *cp++ = '0' + (num / 100);
7945             num %= 100;
7946             *cp++ = '0' + (num / 10);
7947     
7948             /* Product revision - 5th digit. */
7949             *cp++ = 'A' + (num % 10);
7950     
7951             /*
7952              * Second word
7953              */
7954             w = serialnum[1];
7955     
7956             /*
7957              * Year - 6th digit.
7958              *
7959              * If bit 15 of third word is set, then the
7960              * last digit of the year is greater than 7.
7961              */
7962             if (serialnum[2] & 0x8000) {
7963                 *cp++ = '8' + ((w & 0x1C0) >> 6);
7964             } else {
7965                 *cp++ = '0' + ((w & 0x1C0) >> 6);
7966             }
7967     
7968             /* Week of year - 7th, 8th digits. */
7969             num = w & 0x003F;
7970             *cp++ = '0' + num / 10;
7971             num %= 10;
7972             *cp++ = '0' + num;
7973     
7974             /*
7975              * Third word
7976              */
7977             w = serialnum[2] & 0x7FFF;
7978     
7979             /* Serial number - 9th digit. */
7980             *cp++ = 'A' + (w / 1000);
7981     
7982             /* 10th, 11th, 12th digits. */
7983             num = w % 1000;
7984             *cp++ = '0' + num / 100;
7985             num %= 100;
7986             *cp++ = '0' + num / 10;
7987             num %= 10;
7988             *cp++ = '0' + num;
7989     
7990             *cp = '\0';     /* Null Terminate the string. */
7991             return ASC_TRUE;
7992         }
7993     }
7994     
7995     /*
7996      * asc_prt_asc_board_eeprom()
7997      *
7998      * Print board EEPROM configuration.
7999      *
8000      * Note: no single line should be greater than ASC_PRTLINE_SIZE,
8001      * cf. asc_prt_line().
8002      *
8003      * Return the number of characters copied into 'cp'. No more than
8004      * 'cplen' characters will be copied to 'cp'.
8005      */
8006     STATIC int
8007     asc_prt_asc_board_eeprom(struct Scsi_Host *shp, char *cp, int cplen)
8008     {
8009         asc_board_t        *boardp;
8010         ASC_DVC_VAR        *asc_dvc_varp;
8011         int                leftlen;
8012         int                totlen;
8013         int                len;
8014         ASCEEP_CONFIG      *ep;
8015         int                i;
8016     #ifdef CONFIG_ISA
8017         int                isa_dma_speed[] = { 10, 8, 7, 6, 5, 4, 3, 2 };
8018     #endif /* CONFIG_ISA */
8019         uchar              serialstr[13];
8020     
8021         boardp = ASC_BOARDP(shp);
8022         asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
8023         ep = &boardp->eep_config.asc_eep;
8024     
8025         leftlen = cplen;
8026         totlen = len = 0;
8027     
8028         len = asc_prt_line(cp, leftlen,
8029     "\nEEPROM Settings for AdvanSys SCSI Host %d:\n", shp->host_no);
8030         ASC_PRT_NEXT();
8031     
8032         if (asc_get_eeprom_string((ushort *) &ep->adapter_info[0], serialstr) ==
8033             ASC_TRUE) {
8034             len = asc_prt_line(cp, leftlen, " Serial Number: %s\n", serialstr);
8035             ASC_PRT_NEXT();
8036         } else {
8037             if (ep->adapter_info[5] == 0xBB) {
8038                 len = asc_prt_line(cp, leftlen,
8039                     " Default Settings Used for EEPROM-less Adapter.\n");
8040                 ASC_PRT_NEXT();
8041             } else {
8042                 len = asc_prt_line(cp, leftlen,
8043                     " Serial Number Signature Not Present.\n");
8044                 ASC_PRT_NEXT();
8045             }
8046         }
8047     
8048         len = asc_prt_line(cp, leftlen,
8049     " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
8050             ASC_EEP_GET_CHIP_ID(ep), ep->max_total_qng, ep->max_tag_qng);
8051         ASC_PRT_NEXT();
8052     
8053         len = asc_prt_line(cp, leftlen,
8054     " cntl 0x%x, no_scam 0x%x\n",
8055             ep->cntl, ep->no_scam);
8056         ASC_PRT_NEXT();
8057     
8058         len = asc_prt_line(cp, leftlen,
8059     " Target ID:           ");
8060         ASC_PRT_NEXT();
8061         for (i = 0; i <= ASC_MAX_TID; i++) {
8062             len = asc_prt_line(cp, leftlen, " %d", i);
8063             ASC_PRT_NEXT();
8064         }
8065         len = asc_prt_line(cp, leftlen, "\n");
8066         ASC_PRT_NEXT();
8067     
8068         len = asc_prt_line(cp, leftlen,
8069     " Disconnects:         ");
8070         ASC_PRT_NEXT();
8071         for (i = 0; i <= ASC_MAX_TID; i++) {
8072             len = asc_prt_line(cp, leftlen, " %c",
8073                 (ep->disc_enable & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8074             ASC_PRT_NEXT();
8075         }
8076         len = asc_prt_line(cp, leftlen, "\n");
8077         ASC_PRT_NEXT();
8078     
8079         len = asc_prt_line(cp, leftlen,
8080     " Command Queuing:     ");
8081         ASC_PRT_NEXT();
8082         for (i = 0; i <= ASC_MAX_TID; i++) {
8083             len = asc_prt_line(cp, leftlen, " %c",
8084                 (ep->use_cmd_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8085             ASC_PRT_NEXT();
8086         }
8087         len = asc_prt_line(cp, leftlen, "\n");
8088         ASC_PRT_NEXT();
8089     
8090         len = asc_prt_line(cp, leftlen,
8091     " Start Motor:         ");
8092         ASC_PRT_NEXT();
8093         for (i = 0; i <= ASC_MAX_TID; i++) {
8094             len = asc_prt_line(cp, leftlen, " %c",
8095                 (ep->start_motor & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8096             ASC_PRT_NEXT();
8097         }
8098         len = asc_prt_line(cp, leftlen, "\n");
8099         ASC_PRT_NEXT();
8100     
8101         len = asc_prt_line(cp, leftlen,
8102     " Synchronous Transfer:");
8103         ASC_PRT_NEXT();
8104         for (i = 0; i <= ASC_MAX_TID; i++) {
8105             len = asc_prt_line(cp, leftlen, " %c",
8106                 (ep->init_sdtr & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8107             ASC_PRT_NEXT();
8108         }
8109         len = asc_prt_line(cp, leftlen, "\n");
8110         ASC_PRT_NEXT();
8111     
8112     #ifdef CONFIG_ISA
8113         if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
8114             len = asc_prt_line(cp, leftlen,
8115     " Host ISA DMA speed:   %d MB/S\n",
8116                 isa_dma_speed[ASC_EEP_GET_DMA_SPD(ep)]);
8117             ASC_PRT_NEXT();
8118         }
8119     #endif /* CONFIG_ISA */
8120     
8121          return totlen;
8122     }
8123     
8124     /*
8125      * asc_prt_adv_board_eeprom()
8126      *
8127      * Print board EEPROM configuration.
8128      *
8129      * Note: no single line should be greater than ASC_PRTLINE_SIZE,
8130      * cf. asc_prt_line().
8131      *
8132      * Return the number of characters copied into 'cp'. No more than
8133      * 'cplen' characters will be copied to 'cp'.
8134      */
8135     STATIC int
8136     asc_prt_adv_board_eeprom(struct Scsi_Host *shp, char *cp, int cplen)
8137     {
8138         asc_board_t                 *boardp;
8139         ADV_DVC_VAR                 *adv_dvc_varp;
8140         int                         leftlen;
8141         int                         totlen;
8142         int                         len;
8143         int                         i;
8144         char                        *termstr;
8145         uchar                       serialstr[13];
8146         ADVEEP_3550_CONFIG          *ep_3550 = NULL;
8147         ADVEEP_38C0800_CONFIG       *ep_38C0800 = NULL;
8148         ADVEEP_38C1600_CONFIG       *ep_38C1600 = NULL;
8149         ushort                      word;
8150         ushort                      *wordp;
8151         ushort                      sdtr_speed = 0;
8152     
8153         boardp = ASC_BOARDP(shp);
8154         adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
8155         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8156         {
8157             ep_3550 = &boardp->eep_config.adv_3550_eep;
8158         } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
8159         {
8160             ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
8161         } else
8162         {
8163             ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
8164         }
8165     
8166         leftlen = cplen;
8167         totlen = len = 0;
8168     
8169         len = asc_prt_line(cp, leftlen,
8170     "\nEEPROM Settings for AdvanSys SCSI Host %d:\n", shp->host_no);
8171         ASC_PRT_NEXT();
8172     
8173         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8174         {
8175             wordp = &ep_3550->serial_number_word1;
8176         } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
8177         {
8178             wordp = &ep_38C0800->serial_number_word1;
8179         } else
8180         {
8181             wordp = &ep_38C1600->serial_number_word1;
8182         }
8183     
8184         if (asc_get_eeprom_string(wordp, serialstr) == ASC_TRUE) {
8185             len = asc_prt_line(cp, leftlen, " Serial Number: %s\n", serialstr);
8186             ASC_PRT_NEXT();
8187         } else {
8188             len = asc_prt_line(cp, leftlen,
8189                 " Serial Number Signature Not Present.\n");
8190             ASC_PRT_NEXT();
8191         }
8192     
8193         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8194         {
8195             len = asc_prt_line(cp, leftlen,
8196     " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
8197                 ep_3550->adapter_scsi_id, ep_3550->max_host_qng,
8198                 ep_3550->max_dvc_qng);
8199             ASC_PRT_NEXT();
8200         } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
8201         {
8202             len = asc_prt_line(cp, leftlen,
8203     " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
8204                 ep_38C0800->adapter_scsi_id, ep_38C0800->max_host_qng,
8205                 ep_38C0800->max_dvc_qng);
8206             ASC_PRT_NEXT();
8207         } else
8208         {
8209             len = asc_prt_line(cp, leftlen,
8210     " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
8211                 ep_38C1600->adapter_scsi_id, ep_38C1600->max_host_qng,
8212                 ep_38C1600->max_dvc_qng);
8213             ASC_PRT_NEXT();
8214         }
8215         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8216         {
8217             word = ep_3550->termination;
8218         } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
8219         {
8220             word = ep_38C0800->termination_lvd;
8221         } else
8222         {
8223             word = ep_38C1600->termination_lvd;
8224         }
8225         switch (word) {
8226             case 1:
8227                 termstr = "Low Off/High Off";
8228                 break;
8229             case 2:
8230                 termstr = "Low Off/High On";
8231                 break;
8232             case 3:
8233                 termstr = "Low On/High On";
8234                 break;
8235             default:
8236             case 0:
8237                 termstr = "Automatic";
8238                 break;
8239         }
8240     
8241         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8242         {
8243             len = asc_prt_line(cp, leftlen,
8244     " termination: %u (%s), bios_ctrl: 0x%x\n",
8245                 ep_3550->termination, termstr, ep_3550->bios_ctrl);
8246             ASC_PRT_NEXT();
8247         } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
8248         {
8249             len = asc_prt_line(cp, leftlen,
8250     " termination: %u (%s), bios_ctrl: 0x%x\n",
8251                 ep_38C0800->termination_lvd, termstr, ep_38C0800->bios_ctrl);
8252             ASC_PRT_NEXT();
8253         } else
8254         {
8255             len = asc_prt_line(cp, leftlen,
8256     " termination: %u (%s), bios_ctrl: 0x%x\n",
8257                 ep_38C1600->termination_lvd, termstr, ep_38C1600->bios_ctrl);
8258             ASC_PRT_NEXT();
8259         }
8260     
8261         len = asc_prt_line(cp, leftlen,
8262     " Target ID:           ");
8263         ASC_PRT_NEXT();
8264         for (i = 0; i <= ADV_MAX_TID; i++) {
8265             len = asc_prt_line(cp, leftlen, " %X", i);
8266             ASC_PRT_NEXT();
8267         }
8268         len = asc_prt_line(cp, leftlen, "\n");
8269         ASC_PRT_NEXT();
8270     
8271         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8272         {
8273             word = ep_3550->disc_enable;
8274         } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
8275         {
8276             word = ep_38C0800->disc_enable;
8277         } else
8278         {
8279             word = ep_38C1600->disc_enable;
8280         }
8281         len = asc_prt_line(cp, leftlen,
8282     " Disconnects:         ");
8283         ASC_PRT_NEXT();
8284         for (i = 0; i <= ADV_MAX_TID; i++) {
8285             len = asc_prt_line(cp, leftlen, " %c",
8286                 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8287             ASC_PRT_NEXT();
8288         }
8289         len = asc_prt_line(cp, leftlen, "\n");
8290         ASC_PRT_NEXT();
8291     
8292         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8293         {
8294             word = ep_3550->tagqng_able;
8295         } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
8296         {
8297             word = ep_38C0800->tagqng_able;
8298         } else
8299         {
8300             word = ep_38C1600->tagqng_able;
8301         }
8302         len = asc_prt_line(cp, leftlen,
8303     " Command Queuing:     ");
8304         ASC_PRT_NEXT();
8305         for (i = 0; i <= ADV_MAX_TID; i++) {
8306             len = asc_prt_line(cp, leftlen, " %c",
8307                 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8308             ASC_PRT_NEXT();
8309         }
8310         len = asc_prt_line(cp, leftlen, "\n");
8311         ASC_PRT_NEXT();
8312     
8313         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8314         {
8315             word = ep_3550->start_motor;
8316         } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
8317         {
8318             word = ep_38C0800->start_motor;
8319         } else
8320         {
8321             word = ep_38C1600->start_motor;
8322         }
8323         len = asc_prt_line(cp, leftlen,
8324     " Start Motor:         ");
8325         ASC_PRT_NEXT();
8326         for (i = 0; i <= ADV_MAX_TID; i++) {
8327             len = asc_prt_line(cp, leftlen, " %c",
8328                 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8329             ASC_PRT_NEXT();
8330         }
8331         len = asc_prt_line(cp, leftlen, "\n");
8332         ASC_PRT_NEXT();
8333     
8334         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8335         {
8336             len = asc_prt_line(cp, leftlen,
8337     " Synchronous Transfer:");
8338             ASC_PRT_NEXT();
8339             for (i = 0; i <= ADV_MAX_TID; i++) {
8340                 len = asc_prt_line(cp, leftlen, " %c",
8341                     (ep_3550->sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8342                 ASC_PRT_NEXT();
8343             }
8344             len = asc_prt_line(cp, leftlen, "\n");
8345             ASC_PRT_NEXT();
8346         }
8347     
8348         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8349         {
8350             len = asc_prt_line(cp, leftlen,
8351     " Ultra Transfer:      ");
8352         ASC_PRT_NEXT();
8353             for (i = 0; i <= ADV_MAX_TID; i++) {
8354                 len = asc_prt_line(cp, leftlen, " %c",
8355                     (ep_3550->ultra_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8356                 ASC_PRT_NEXT();
8357             }
8358             len = asc_prt_line(cp, leftlen, "\n");
8359             ASC_PRT_NEXT();
8360         }
8361     
8362         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8363         {
8364             word = ep_3550->wdtr_able;
8365         } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
8366         {
8367             word = ep_38C0800->wdtr_able;
8368         } else
8369         {
8370             word = ep_38C1600->wdtr_able;
8371         }
8372         len = asc_prt_line(cp, leftlen,
8373     " Wide Transfer:       ");
8374         ASC_PRT_NEXT();
8375         for (i = 0; i <= ADV_MAX_TID; i++) {
8376             len = asc_prt_line(cp, leftlen, " %c",
8377                 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8378             ASC_PRT_NEXT();
8379         }
8380         len = asc_prt_line(cp, leftlen, "\n");
8381         ASC_PRT_NEXT();
8382     
8383         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800 ||
8384             adv_dvc_varp->chip_type == ADV_CHIP_ASC38C1600)
8385         {
8386             len = asc_prt_line(cp, leftlen,
8387     " Synchronous Transfer Speed (Mhz):\n  ");
8388             ASC_PRT_NEXT();
8389             for (i = 0; i <= ADV_MAX_TID; i++) {
8390                 char *speed_str;
8391     
8392                 if (i == 0)
8393                 {
8394                     sdtr_speed = adv_dvc_varp->sdtr_speed1;
8395                 } else if (i == 4)
8396                 {
8397                     sdtr_speed = adv_dvc_varp->sdtr_speed2;
8398                 } else if (i == 8)
8399                 {
8400                     sdtr_speed = adv_dvc_varp->sdtr_speed3;
8401                 } else if (i == 12)
8402                 {
8403                     sdtr_speed = adv_dvc_varp->sdtr_speed4;
8404                 }
8405                 switch (sdtr_speed & ADV_MAX_TID)
8406                 {
8407                     case 0:  speed_str = "Off"; break;
8408                     case 1:  speed_str = "  5"; break;
8409                     case 2:  speed_str = " 10"; break;
8410                     case 3:  speed_str = " 20"; break;
8411                     case 4:  speed_str = " 40"; break;
8412                     case 5:  speed_str = " 80"; break;
8413                     default: speed_str = "Unk"; break;
8414                 }
8415                 len = asc_prt_line(cp, leftlen, "%X:%s ", i, speed_str);
8416                 ASC_PRT_NEXT();
8417                 if (i == 7)
8418                 {
8419                     len = asc_prt_line(cp, leftlen, "\n  ");
8420                     ASC_PRT_NEXT();
8421                 }
8422                 sdtr_speed >>= 4;
8423             }
8424             len = asc_prt_line(cp, leftlen, "\n");
8425             ASC_PRT_NEXT();
8426         }
8427     
8428         return totlen;
8429     }
8430     
8431     /*
8432      * asc_prt_driver_conf()
8433      *
8434      * Note: no single line should be greater than ASC_PRTLINE_SIZE,
8435      * cf. asc_prt_line().
8436      *
8437      * Return the number of characters copied into 'cp'. No more than
8438      * 'cplen' characters will be copied to 'cp'.
8439      */
8440     STATIC int
8441     asc_prt_driver_conf(struct Scsi_Host *shp, char *cp, int cplen)
8442     {
8443         asc_board_t            *boardp;
8444         int                    leftlen;
8445         int                    totlen;
8446         int                    len;
8447         int                    chip_scsi_id;
8448         int                    i;
8449     
8450         boardp = ASC_BOARDP(shp);
8451     
8452         leftlen = cplen;
8453         totlen = len = 0;
8454     
8455         len = asc_prt_line(cp, leftlen,
8456     "\nLinux Driver Configuration and Information for AdvanSys SCSI Host %d:\n",
8457             shp->host_no);
8458         ASC_PRT_NEXT();
8459     
8460         len = asc_prt_line(cp, leftlen,
8461     " host_busy %u, last_reset %u, max_id %u, max_lun %u, max_channel %u\n",
8462             shp->host_busy, shp->last_reset, shp->max_id, shp->max_lun,
8463             shp->max_channel);
8464         ASC_PRT_NEXT();
8465     
8466         len = asc_prt_line(cp, leftlen,
8467     " unique_id %d, can_queue %d, this_id %d, sg_tablesize %u, cmd_per_lun %u\n",
8468             shp->unique_id, shp->can_queue, shp->this_id, shp->sg_tablesize,
8469             shp->cmd_per_lun);
8470         ASC_PRT_NEXT();
8471     
8472         len = asc_prt_line(cp, leftlen,
8473     " unchecked_isa_dma %d, use_clustering %d, loaded_as_module %d\n",
8474             shp->unchecked_isa_dma, shp->use_clustering, shp->loaded_as_module);
8475         ASC_PRT_NEXT();
8476     
8477         len = asc_prt_line(cp, leftlen,
8478     " flags 0x%x, last_reset 0x%x, jiffies 0x%x, asc_n_io_port 0x%x\n",
8479             boardp->flags, boardp->last_reset, jiffies, boardp->asc_n_io_port);
8480         ASC_PRT_NEXT();
8481     
8482          /* 'shp->n_io_port' may be truncated because it is only one byte. */
8483         len = asc_prt_line(cp, leftlen,
8484     " io_port 0x%x, n_io_port 0x%x\n",
8485             shp->io_port, shp->n_io_port);
8486         ASC_PRT_NEXT();
8487     
8488         if (ASC_NARROW_BOARD(boardp)) {
8489             chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
8490         } else {
8491             chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
8492         }
8493     
8494         if (boardp->flags & ASC_SELECT_QUEUE_DEPTHS) {
8495             len = asc_prt_line(cp, leftlen, " queue_depth:");
8496             ASC_PRT_NEXT();
8497             for (i = 0; i <= ADV_MAX_TID; i++) {
8498                 if ((chip_scsi_id == i) ||
8499                     ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8500                     continue;
8501                 }
8502                 if (boardp->device[i] == NULL) {
8503                     continue;
8504                 }
8505                 len = asc_prt_line(cp, leftlen, " %X:%d",
8506                     i, boardp->device[i]->queue_depth);
8507                 ASC_PRT_NEXT();
8508             }
8509             len = asc_prt_line(cp, leftlen, "\n");
8510             ASC_PRT_NEXT();
8511         }
8512     
8513         return totlen;
8514     }
8515     
8516     /*
8517      * asc_prt_asc_board_info()
8518      *
8519      * Print dynamic board configuration information.
8520      *
8521      * Note: no single line should be greater than ASC_PRTLINE_SIZE,
8522      * cf. asc_prt_line().
8523      *
8524      * Return the number of characters copied into 'cp'. No more than
8525      * 'cplen' characters will be copied to 'cp'.
8526      */
8527     STATIC int
8528     asc_prt_asc_board_info(struct Scsi_Host *shp, char *cp, int cplen)
8529     {
8530         asc_board_t            *boardp;
8531         int                    chip_scsi_id;
8532         int                    leftlen;
8533         int                    totlen;
8534         int                    len;
8535         ASC_DVC_VAR            *v;
8536         ASC_DVC_CFG            *c;
8537         int                    i;
8538         int                    renegotiate = 0;
8539     
8540         boardp = ASC_BOARDP(shp);
8541         v = &boardp->dvc_var.asc_dvc_var;
8542         c = &boardp->dvc_cfg.asc_dvc_cfg;
8543         chip_scsi_id = c->chip_scsi_id;
8544     
8545         leftlen = cplen;
8546         totlen = len = 0;
8547     
8548         len = asc_prt_line(cp, leftlen,
8549     "\nAsc Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
8550         shp->host_no);
8551         ASC_PRT_NEXT();
8552     
8553         len = asc_prt_line(cp, leftlen,
8554     " chip_version %u, lib_version 0x%x, lib_serial_no %u, mcode_date 0x%x\n",
8555             c->chip_version, c->lib_version, c->lib_serial_no, c->mcode_date);
8556         ASC_PRT_NEXT();
8557     
8558         len = asc_prt_line(cp, leftlen,
8559     " mcode_version 0x%x, err_code %u\n",
8560              c->mcode_version, v->err_code);
8561         ASC_PRT_NEXT();
8562     
8563         /* Current number of commands waiting for the host. */
8564         len = asc_prt_line(cp, leftlen,
8565     " Total Command Pending: %d\n", v->cur_total_qng);
8566         ASC_PRT_NEXT();
8567     
8568         len = asc_prt_line(cp, leftlen,
8569     " Command Queuing:");
8570         ASC_PRT_NEXT();
8571         for (i = 0; i <= ASC_MAX_TID; i++) {
8572             if ((chip_scsi_id == i) ||
8573                 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8574                 continue;
8575             }
8576             len = asc_prt_line(cp, leftlen, " %X:%c",
8577                 i, (v->use_tagged_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8578             ASC_PRT_NEXT();
8579         }
8580         len = asc_prt_line(cp, leftlen, "\n");
8581         ASC_PRT_NEXT();
8582     
8583         /* Current number of commands waiting for a device. */
8584         len = asc_prt_line(cp, leftlen,
8585     " Command Queue Pending:");
8586         ASC_PRT_NEXT();
8587         for (i = 0; i <= ASC_MAX_TID; i++) {
8588             if ((chip_scsi_id == i) ||
8589                 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8590                 continue;
8591             }
8592             len = asc_prt_line(cp, leftlen, " %X:%u", i, v->cur_dvc_qng[i]);
8593             ASC_PRT_NEXT();
8594         }
8595         len = asc_prt_line(cp, leftlen, "\n");
8596         ASC_PRT_NEXT();
8597     
8598         /* Current limit on number of commands that can be sent to a device. */
8599         len = asc_prt_line(cp, leftlen,
8600     " Command Queue Limit:");
8601         ASC_PRT_NEXT();
8602         for (i = 0; i <= ASC_MAX_TID; i++) {
8603             if ((chip_scsi_id == i) ||
8604                 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8605                 continue;
8606             }
8607             len = asc_prt_line(cp, leftlen, " %X:%u", i, v->max_dvc_qng[i]);
8608             ASC_PRT_NEXT();
8609         }
8610         len = asc_prt_line(cp, leftlen, "\n");
8611         ASC_PRT_NEXT();
8612     
8613         /* Indicate whether the device has returned queue full status. */
8614         len = asc_prt_line(cp, leftlen,
8615     " Command Queue Full:");
8616         ASC_PRT_NEXT();
8617         for (i = 0; i <= ASC_MAX_TID; i++) {
8618             if ((chip_scsi_id == i) ||
8619                 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8620                 continue;
8621             }
8622             if (boardp->queue_full & ADV_TID_TO_TIDMASK(i)) {
8623                 len = asc_prt_line(cp, leftlen, " %X:Y-%d",
8624                     i, boardp->queue_full_cnt[i]);
8625             } else {
8626                 len = asc_prt_line(cp, leftlen, " %X:N", i);
8627             }
8628             ASC_PRT_NEXT();
8629         }
8630         len = asc_prt_line(cp, leftlen, "\n");
8631         ASC_PRT_NEXT();
8632     
8633         len = asc_prt_line(cp, leftlen,
8634     " Synchronous Transfer:");
8635         ASC_PRT_NEXT();
8636         for (i = 0; i <= ASC_MAX_TID; i++) {
8637             if ((chip_scsi_id == i) ||
8638                 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8639                 continue;
8640             }
8641             len = asc_prt_line(cp, leftlen, " %X:%c",
8642                 i, (v->sdtr_done & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8643             ASC_PRT_NEXT();
8644         }
8645         len = asc_prt_line(cp, leftlen, "\n");
8646         ASC_PRT_NEXT();
8647     
8648         for (i = 0; i <= ASC_MAX_TID; i++) {
8649             uchar syn_period_ix;
8650     
8651             if ((chip_scsi_id == i) ||
8652                 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
8653                 ((v->init_sdtr & ADV_TID_TO_TIDMASK(i)) == 0)) {
8654                 continue;
8655             }
8656     
8657             len = asc_prt_line(cp, leftlen, "  %X:", i);
8658             ASC_PRT_NEXT();
8659     
8660             if ((boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET) == 0)
8661             {
8662                 len = asc_prt_line(cp, leftlen, " Asynchronous");
8663                 ASC_PRT_NEXT();
8664             } else
8665             {
8666                 syn_period_ix =
8667                     (boardp->sdtr_data[i] >> 4) & (v->max_sdtr_index - 1);
8668     
8669                 len = asc_prt_line(cp, leftlen,
8670                     " Transfer Period Factor: %d (%d.%d Mhz),",
8671                     v->sdtr_period_tbl[syn_period_ix],
8672                     250 / v->sdtr_period_tbl[syn_period_ix],
8673                     ASC_TENTHS(250, v->sdtr_period_tbl[syn_period_ix]));
8674                 ASC_PRT_NEXT();
8675     
8676                 len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
8677                     boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET);
8678                 ASC_PRT_NEXT();
8679             }
8680     
8681             if ((v->sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
8682                 len = asc_prt_line(cp, leftlen, "*\n");
8683                 renegotiate = 1;
8684             } else
8685             {
8686                 len = asc_prt_line(cp, leftlen, "\n");
8687             }
8688             ASC_PRT_NEXT();
8689         }
8690     
8691         if (renegotiate)
8692         {
8693             len = asc_prt_line(cp, leftlen,
8694                 " * = Re-negotiation pending before next command.\n");
8695             ASC_PRT_NEXT();
8696         }
8697     
8698         return totlen;
8699     }
8700     
8701     /*
8702      * asc_prt_adv_board_info()
8703      *
8704      * Print dynamic board configuration information.
8705      *
8706      * Note: no single line should be greater than ASC_PRTLINE_SIZE,
8707      * cf. asc_prt_line().
8708      *
8709      * Return the number of characters copied into 'cp'. No more than
8710      * 'cplen' characters will be copied to 'cp'.
8711      */
8712     STATIC int
8713     asc_prt_adv_board_info(struct Scsi_Host *shp, char *cp, int cplen)
8714     {
8715         asc_board_t            *boardp;
8716         int                    leftlen;
8717         int                    totlen;
8718         int                    len;
8719         int                    i;
8720         ADV_DVC_VAR            *v;
8721         ADV_DVC_CFG            *c;
8722         AdvPortAddr            iop_base;
8723         ushort                 chip_scsi_id;
8724         ushort                 lramword;
8725         uchar                  lrambyte;
8726         ushort                 tagqng_able;
8727         ushort                 sdtr_able, wdtr_able;
8728         ushort                 wdtr_done, sdtr_done;
8729         ushort                 period = 0;
8730         int                    renegotiate = 0;
8731     
8732         boardp = ASC_BOARDP(shp);
8733         v = &boardp->dvc_var.adv_dvc_var;
8734         c = &boardp->dvc_cfg.adv_dvc_cfg;
8735         iop_base = v->iop_base;
8736         chip_scsi_id = v->chip_scsi_id;
8737     
8738         leftlen = cplen;
8739         totlen = len = 0;
8740     
8741         len = asc_prt_line(cp, leftlen,
8742     "\nAdv Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
8743         shp->host_no);
8744         ASC_PRT_NEXT();
8745     
8746         len = asc_prt_line(cp, leftlen,
8747     " iop_base 0x%lx, cable_detect: %X, err_code %u\n",
8748              v->iop_base,
8749              AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1) & CABLE_DETECT,
8750              v->err_code);
8751         ASC_PRT_NEXT();
8752     
8753         len = asc_prt_line(cp, leftlen,
8754     " chip_version %u, lib_version 0x%x, mcode_date 0x%x, mcode_version 0x%x\n",
8755             c->chip_version, c->lib_version, c->mcode_date, c->mcode_version);
8756         ASC_PRT_NEXT();
8757     
8758         AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
8759         len = asc_prt_line(cp, leftlen,
8760     " Queuing Enabled:");
8761         ASC_PRT_NEXT();
8762         for (i = 0; i <= ADV_MAX_TID; i++) {
8763             if ((chip_scsi_id == i) ||
8764                 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8765                 continue;
8766             }
8767     
8768             len = asc_prt_line(cp, leftlen, " %X:%c",
8769                 i, (tagqng_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8770             ASC_PRT_NEXT();
8771         }
8772         len = asc_prt_line(cp, leftlen, "\n");
8773         ASC_PRT_NEXT();
8774     
8775         len = asc_prt_line(cp, leftlen,
8776     " Queue Limit:");
8777         ASC_PRT_NEXT();
8778         for (i = 0; i <= ADV_MAX_TID; i++) {
8779             if ((chip_scsi_id == i) ||
8780                 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8781                 continue;
8782             }
8783     
8784             AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + i, lrambyte);
8785     
8786             len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
8787             ASC_PRT_NEXT();
8788         }
8789         len = asc_prt_line(cp, leftlen, "\n");
8790         ASC_PRT_NEXT();
8791     
8792         len = asc_prt_line(cp, leftlen,
8793     " Command Pending:");
8794         ASC_PRT_NEXT();
8795         for (i = 0; i <= ADV_MAX_TID; i++) {
8796             if ((chip_scsi_id == i) ||
8797                 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8798                 continue;
8799             }
8800     
8801             AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_QUEUED_CMD + i, lrambyte);
8802     
8803             len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
8804             ASC_PRT_NEXT();
8805         }
8806         len = asc_prt_line(cp, leftlen, "\n");
8807         ASC_PRT_NEXT();
8808     
8809         AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
8810         len = asc_prt_line(cp, leftlen,
8811     " Wide Enabled:");
8812         ASC_PRT_NEXT();
8813         for (i = 0; i <= ADV_MAX_TID; i++) {
8814             if ((chip_scsi_id == i) ||
8815                 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8816                 continue;
8817             }
8818     
8819             len = asc_prt_line(cp, leftlen, " %X:%c",
8820                 i, (wdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8821             ASC_PRT_NEXT();
8822         }
8823         len = asc_prt_line(cp, leftlen, "\n");
8824         ASC_PRT_NEXT();
8825     
8826         AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, wdtr_done);
8827         len = asc_prt_line(cp, leftlen,
8828     " Transfer Bit Width:");
8829         ASC_PRT_NEXT();
8830         for (i = 0; i <= ADV_MAX_TID; i++) {
8831             if ((chip_scsi_id == i) ||
8832                 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8833                 continue;
8834             }
8835     
8836             AdvReadWordLram(iop_base, ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
8837                 lramword);
8838     
8839             len = asc_prt_line(cp, leftlen, " %X:%d",
8840                 i, (lramword & 0x8000) ? 16 : 8);
8841             ASC_PRT_NEXT();
8842     
8843             if ((wdtr_able & ADV_TID_TO_TIDMASK(i)) &&
8844                 (wdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
8845                 len = asc_prt_line(cp, leftlen, "*");
8846                 ASC_PRT_NEXT();
8847                 renegotiate = 1;
8848             }
8849         }
8850         len = asc_prt_line(cp, leftlen, "\n");
8851         ASC_PRT_NEXT();
8852     
8853         AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
8854         len = asc_prt_line(cp, leftlen,
8855     " Synchronous Enabled:");
8856         ASC_PRT_NEXT();
8857         for (i = 0; i <= ADV_MAX_TID; i++) {
8858             if ((chip_scsi_id == i) ||
8859                 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8860                 continue;
8861             }
8862     
8863             len = asc_prt_line(cp, leftlen, " %X:%c",
8864                 i, (sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8865             ASC_PRT_NEXT();
8866         }
8867         len = asc_prt_line(cp, leftlen, "\n");
8868         ASC_PRT_NEXT();
8869     
8870         AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, sdtr_done);
8871         for (i = 0; i <= ADV_MAX_TID; i++) {
8872     
8873             AdvReadWordLram(iop_base, ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
8874                 lramword);
8875             lramword &= ~0x8000;
8876     
8877             if ((chip_scsi_id == i) ||
8878                 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
8879                 ((sdtr_able & ADV_TID_TO_TIDMASK(i)) == 0)) {
8880                 continue;
8881             }
8882     
8883             len = asc_prt_line(cp, leftlen, "  %X:", i);
8884             ASC_PRT_NEXT();
8885     
8886             if ((lramword & 0x1F) == 0) /* Check for REQ/ACK Offset 0. */
8887             {
8888                 len = asc_prt_line(cp, leftlen, " Asynchronous");
8889                 ASC_PRT_NEXT();
8890             } else
8891             {
8892                 len = asc_prt_line(cp, leftlen, " Transfer Period Factor: ");
8893                 ASC_PRT_NEXT();
8894     
8895                 if ((lramword & 0x1F00) == 0x1100) /* 80 Mhz */
8896                 {
8897                     len = asc_prt_line(cp, leftlen, "9 (80.0 Mhz),");
8898                     ASC_PRT_NEXT();
8899                 } else if ((lramword & 0x1F00) == 0x1000) /* 40 Mhz */
8900                 {
8901                     len = asc_prt_line(cp, leftlen, "10 (40.0 Mhz),");
8902                     ASC_PRT_NEXT();
8903                 } else /* 20 Mhz or below. */
8904                 {
8905                     period = (((lramword >> 8) * 25) + 50)/4;
8906     
8907                     if (period == 0) /* Should never happen. */
8908                     {
8909                         len = asc_prt_line(cp, leftlen, "%d (? Mhz), ");
8910                         ASC_PRT_NEXT();
8911                     } else
8912                     {
8913                         len = asc_prt_line(cp, leftlen,
8914                             "%d (%d.%d Mhz),",
8915                             period, 250/period, ASC_TENTHS(250, period));
8916                         ASC_PRT_NEXT();
8917                     }
8918                 }
8919     
8920                 len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
8921                     lramword & 0x1F);
8922                 ASC_PRT_NEXT();
8923             }
8924     
8925             if ((sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
8926                 len = asc_prt_line(cp, leftlen, "*\n");
8927                 renegotiate = 1;
8928             } else
8929             {
8930                 len = asc_prt_line(cp, leftlen, "\n");
8931             }
8932             ASC_PRT_NEXT();
8933         }
8934     
8935         if (renegotiate)
8936         {
8937             len = asc_prt_line(cp, leftlen,
8938                 " * = Re-negotiation pending before next command.\n");
8939             ASC_PRT_NEXT();
8940         }
8941     
8942         return totlen;
8943     }
8944     
8945     /*
8946      * asc_proc_copy()
8947      *
8948      * Copy proc information to a read buffer taking into account the current
8949      * read offset in the file and the remaining space in the read buffer.
8950      */
8951     STATIC int
8952     asc_proc_copy(off_t advoffset, off_t offset, char *curbuf, int leftlen,
8953                   char *cp, int cplen)
8954     {
8955         int cnt = 0;
8956     
8957         ASC_DBG3(2, "asc_proc_copy: offset %d, advoffset %d, cplen %d\n",
8958                 (unsigned) offset, (unsigned) advoffset, cplen);
8959         if (offset <= advoffset) {
8960             /* Read offset below current offset, copy everything. */
8961             cnt = ASC_MIN(cplen, leftlen);
8962             ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
8963                     (ulong) curbuf, (ulong) cp, cnt);
8964             memcpy(curbuf, cp, cnt);
8965         } else if (offset < advoffset + cplen) {
8966             /* Read offset within current range, partial copy. */
8967             cnt = (advoffset + cplen) - offset;
8968             cp = (cp + cplen) - cnt;
8969             cnt = ASC_MIN(cnt, leftlen);
8970             ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
8971                     (ulong) curbuf, (ulong) cp, cnt);
8972             memcpy(curbuf, cp, cnt);
8973         }
8974         return cnt;
8975     }
8976     
8977     /*
8978      * asc_prt_line()
8979      *
8980      * If 'cp' is NULL print to the console, otherwise print to a buffer.
8981      *
8982      * Return 0 if printing to the console, otherwise return the number of
8983      * bytes written to the buffer.
8984      *
8985      * Note: If any single line is greater than ASC_PRTLINE_SIZE bytes the stack
8986      * will be corrupted. 's[]' is defined to be ASC_PRTLINE_SIZE bytes.
8987      */
8988     STATIC int
8989     asc_prt_line(char *buf, int buflen, char *fmt, ...)
8990     {
8991         va_list        args;
8992         int            ret;
8993         char           s[ASC_PRTLINE_SIZE];
8994     
8995         va_start(args, fmt);
8996         ret = vsprintf(s, fmt, args);
8997         ASC_ASSERT(ret < ASC_PRTLINE_SIZE);
8998         if (buf == NULL) {
8999             (void) printk(s);
9000             ret = 0;
9001         } else {
9002             ret = ASC_MIN(buflen, ret);
9003             memcpy(buf, s, ret);
9004         }
9005         va_end(args);
9006         return ret;
9007     }
9008     #endif /* CONFIG_PROC_FS */
9009     
9010     
9011     /*
9012      * --- Functions Required by the Asc Library
9013      */
9014     
9015     /*
9016      * Delay for 'n' milliseconds. Don't use the 'jiffies'
9017      * global variable which is incremented once every 5 ms
9018      * from a timer interrupt, because this function may be
9019      * called when interrupts are disabled.
9020      */
9021     STATIC void
9022     DvcSleepMilliSecond(ADV_DCNT n)
9023     {
9024         ASC_DBG1(4, "DvcSleepMilliSecond: %lu\n", (ulong) n);
9025         mdelay(n);
9026     }
9027     
9028     /*
9029      * Currently and inline noop but leave as a placeholder.
9030      * Leave DvcEnterCritical() as a noop placeholder.
9031      */
9032     STATIC inline ulong
9033     DvcEnterCritical(void)
9034     {
9035         return 0;
9036     }
9037     
9038     /*
9039      * Critical sections are all protected by the board spinlock.
9040      * Leave DvcLeaveCritical() as a noop placeholder.
9041      */
9042     STATIC inline void
9043     DvcLeaveCritical(ulong flags)
9044     {
9045         return;
9046     }
9047     
9048     /*
9049      * void
9050      * DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
9051      *
9052      * Calling/Exit State:
9053      *    none
9054      *
9055      * Description:
9056      *     Output an ASC_SCSI_Q structure to the chip
9057      */
9058     STATIC void
9059     DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
9060     {
9061         int    i;
9062     
9063         ASC_DBG_PRT_HEX(2, "DvcPutScsiQ", outbuf, 2 * words);
9064         AscSetChipLramAddr(iop_base, s_addr);
9065         for (i = 0; i < 2 * words; i += 2) {
9066             if (i == 4 || i == 20) {
9067                 continue;
9068             }
9069             outpw(iop_base + IOP_RAM_DATA,
9070                 ((ushort) outbuf[i + 1] << 8) | outbuf[i]);
9071         }
9072     }
9073     
9074     /*
9075      * void
9076      * DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
9077      *
9078      * Calling/Exit State:
9079      *    none
9080      *
9081      * Description:
9082      *     Input an ASC_QDONE_INFO structure from the chip
9083      */
9084     STATIC void
9085     DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
9086     {
9087         int    i;
9088         ushort word;
9089     
9090         AscSetChipLramAddr(iop_base, s_addr);
9091         for (i = 0; i < 2 * words; i += 2) {
9092             if (i == 10) {
9093                 continue;
9094             }
9095             word = inpw(iop_base + IOP_RAM_DATA);
9096             inbuf[i] = word & 0xff;
9097             inbuf[i + 1] = (word >> 8) & 0xff;
9098         }
9099         ASC_DBG_PRT_HEX(2, "DvcGetQinfo", inbuf, 2 * words);
9100     }
9101     
9102     /*
9103      * Read a PCI configuration byte.
9104      */
9105     ASC_INITFUNC(
9106     STATIC uchar,
9107     DvcReadPCIConfigByte(
9108             ASC_DVC_VAR *asc_dvc,
9109             ushort offset)
9110     )
9111     {
9112     #ifdef CONFIG_PCI
9113         uchar byte_data;
9114         pcibios_read_config_byte(ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info),
9115             PCI_DEVFN(ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info),
9116                 ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info)),
9117             offset, &byte_data);
9118         return byte_data;
9119     #else /* !defined(CONFIG_PCI) */
9120         return 0;
9121     #endif /* !defined(CONFIG_PCI) */
9122     }
9123     
9124     /*
9125      * Write a PCI configuration byte.
9126      */
9127     ASC_INITFUNC(
9128     STATIC void,
9129     DvcWritePCIConfigByte(
9130             ASC_DVC_VAR *asc_dvc,
9131             ushort offset,
9132             uchar  byte_data)
9133     )
9134     {
9135     #ifdef CONFIG_PCI
9136         pcibios_write_config_byte(ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info),
9137             PCI_DEVFN(ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info),
9138                 ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info)),
9139             offset, byte_data);
9140     #endif /* CONFIG_PCI */
9141     }
9142     
9143     /*
9144      * Return the BIOS address of the adapter at the specified
9145      * I/O port and with the specified bus type.
9146      */
9147     ASC_INITFUNC(
9148     STATIC ushort,
9149     AscGetChipBiosAddress(
9150             PortAddr iop_base,
9151             ushort bus_type
9152     )
9153     )
9154     {
9155         ushort  cfg_lsw;
9156         ushort  bios_addr;
9157     
9158         /*
9159          * The PCI BIOS is re-located by the motherboard BIOS. Because
9160          * of this the driver can not determine where a PCI BIOS is
9161          * loaded and executes.
9162          */
9163         if (bus_type & ASC_IS_PCI)
9164         {
9165             return(0);
9166         }
9167     
9168     #ifdef CONFIG_ISA
9169         if((bus_type & ASC_IS_EISA) != 0)
9170         {
9171             cfg_lsw = AscGetEisaChipCfg(iop_base);
9172             cfg_lsw &= 0x000F;
9173             bios_addr = (ushort)(ASC_BIOS_MIN_ADDR  +
9174                                     (cfg_lsw * ASC_BIOS_BANK_SIZE));
9175             return(bios_addr);
9176         }/* if */
9177     #endif /* CONFIG_ISA */
9178     
9179         cfg_lsw = AscGetChipCfgLsw(iop_base);
9180     
9181         /*
9182         *  ISA PnP uses the top bit as the 32K BIOS flag
9183         */
9184         if (bus_type == ASC_IS_ISAPNP)
9185         {
9186             cfg_lsw &= 0x7FFF;
9187         }/* if */
9188     
9189         bios_addr = (ushort)(((cfg_lsw >> 12) * ASC_BIOS_BANK_SIZE) +
9190                 ASC_BIOS_MIN_ADDR);
9191         return(bios_addr);
9192     }
9193     
9194     
9195     /*
9196      * --- Functions Required by the Adv Library
9197      */
9198     
9199     /*
9200      * DvcGetPhyAddr()
9201      *
9202      * Return the physical address of 'vaddr' and set '*lenp' to the
9203      * number of physically contiguous bytes that follow 'vaddr'.
9204      * 'flag' indicates the type of structure whose physical address
9205      * is being translated.
9206      *
9207      * Note: Because Linux currently doesn't page the kernel and all
9208      * kernel buffers are physically contiguous, leave '*lenp' unchanged.
9209      */
9210     ADV_PADDR
9211     DvcGetPhyAddr(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq,
9212             uchar *vaddr, ADV_SDCNT *lenp, int flag)
9213     {
9214         ADV_PADDR           paddr;
9215     
9216         paddr = virt_to_bus(vaddr);
9217     
9218         ASC_DBG4(4,
9219             "DvcGetPhyAddr: vaddr 0x%lx, lenp 0x%lx *lenp %lu, paddr 0x%lx\n",
9220             (ulong) vaddr, (ulong) lenp, (ulong) *((ulong *) lenp), (ulong) paddr);
9221     
9222         return paddr;
9223     }
9224     
9225     /*
9226      * Read a PCI configuration byte.
9227      */
9228     ASC_INITFUNC(
9229     STATIC uchar,
9230     DvcAdvReadPCIConfigByte(
9231             ADV_DVC_VAR *asc_dvc,
9232             ushort offset)
9233     )
9234     {
9235     #ifdef CONFIG_PCI
9236         uchar byte_data;
9237         pcibios_read_config_byte(ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info),
9238             PCI_DEVFN(ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info),
9239                 ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info)),
9240             offset, &byte_data);
9241         return byte_data;
9242     #else /* CONFIG_PCI */
9243         return 0;
9244     #endif /* CONFIG_PCI */
9245     }
9246     
9247     /*
9248      * Write a PCI configuration byte.
9249      */
9250     ASC_INITFUNC(
9251     STATIC void,
9252     DvcAdvWritePCIConfigByte(
9253             ADV_DVC_VAR *asc_dvc,
9254             ushort offset,
9255             uchar  byte_data)
9256     )
9257     {
9258     #ifdef CONFIG_PCI
9259         pcibios_write_config_byte(ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info),
9260             PCI_DEVFN(ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info),
9261                 ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info)),
9262             offset, byte_data);
9263     #else /* CONFIG_PCI */
9264         return 0;
9265     #endif /* CONFIG_PCI */
9266     }
9267     
9268     /*
9269      * --- Tracing and Debugging Functions
9270      */
9271     
9272     #ifdef ADVANSYS_STATS
9273     #ifdef CONFIG_PROC_FS
9274     /*
9275      * asc_prt_board_stats()
9276      *
9277      * Note: no single line should be greater than ASC_PRTLINE_SIZE,
9278      * cf. asc_prt_line().
9279      *
9280      * Return the number of characters copied into 'cp'. No more than
9281      * 'cplen' characters will be copied to 'cp'.
9282      */
9283     STATIC int
9284     asc_prt_board_stats(struct Scsi_Host *shp, char *cp, int cplen)
9285     {
9286         int                    leftlen;
9287         int                    totlen;
9288         int                    len;
9289         struct asc_stats       *s;
9290         asc_board_t            *boardp;
9291     
9292         leftlen = cplen;
9293         totlen = len = 0;
9294     
9295         boardp = ASC_BOARDP(shp);
9296         s = &boardp->asc_stats;
9297     
9298         len = asc_prt_line(cp, leftlen,
9299     "\nLinux Driver Statistics for AdvanSys SCSI Host %d:\n", shp->host_no);
9300         ASC_PRT_NEXT();
9301     
9302         len = asc_prt_line(cp, leftlen,
9303     " queuecommand %lu, reset %lu, biosparam %lu, interrupt %lu\n",
9304             s->queuecommand, s->reset, s->biosparam, s->interrupt);
9305         ASC_PRT_NEXT();
9306     
9307         len = asc_prt_line(cp, leftlen,
9308     " callback %lu, done %lu, build_error %lu, build_noreq %lu, build_nosg %lu\n",
9309             s->callback, s->done, s->build_error, s->adv_build_noreq,
9310             s->adv_build_nosg);
9311         ASC_PRT_NEXT();
9312     
9313         len = asc_prt_line(cp, leftlen,
9314     " exe_noerror %lu, exe_busy %lu, exe_error %lu, exe_unknown %lu\n",
9315             s->exe_noerror, s->exe_busy, s->exe_error, s->exe_unknown);
9316         ASC_PRT_NEXT();
9317     
9318         /*
9319          * Display data transfer statistics.
9320          */
9321         if (s->cont_cnt > 0) {
9322             len = asc_prt_line(cp, leftlen, " cont_cnt %lu, ", s->cont_cnt);
9323             ASC_PRT_NEXT();
9324     
9325             len = asc_prt_line(cp, leftlen, "cont_xfer %lu.%01lu kb ",
9326                         s->cont_xfer/2,
9327                         ASC_TENTHS(s->cont_xfer, 2));
9328             ASC_PRT_NEXT();
9329     
9330             /* Contiguous transfer average size */
9331             len = asc_prt_line(cp, leftlen, "avg_xfer %lu.%01lu kb\n",
9332                         (s->cont_xfer/2)/s->cont_cnt,
9333                         ASC_TENTHS((s->cont_xfer/2), s->cont_cnt));
9334             ASC_PRT_NEXT();
9335         }
9336     
9337         if (s->sg_cnt > 0) {
9338     
9339             len = asc_prt_line(cp, leftlen, " sg_cnt %lu, sg_elem %lu, ",
9340                         s->sg_cnt, s->sg_elem);
9341             ASC_PRT_NEXT();
9342     
9343             len = asc_prt_line(cp, leftlen, "sg_xfer %lu.%01lu kb\n",
9344                         s->sg_xfer/2,
9345                         ASC_TENTHS(s->sg_xfer, 2));
9346             ASC_PRT_NEXT();
9347     
9348             /* Scatter gather transfer statistics */
9349             len = asc_prt_line(cp, leftlen, " avg_num_elem %lu.%01lu, ",
9350                         s->sg_elem/s->sg_cnt,
9351                         ASC_TENTHS(s->sg_elem, s->sg_cnt));
9352             ASC_PRT_NEXT();
9353     
9354             len = asc_prt_line(cp, leftlen, "avg_elem_size %lu.%01lu kb, ",
9355                         (s->sg_xfer/2)/s->sg_elem,
9356                         ASC_TENTHS((s->sg_xfer/2), s->sg_elem));
9357             ASC_PRT_NEXT();
9358     
9359             len = asc_prt_line(cp, leftlen, "avg_xfer_size %lu.%01lu kb\n",
9360                         (s->sg_xfer/2)/s->sg_cnt,
9361                         ASC_TENTHS((s->sg_xfer/2), s->sg_cnt));
9362             ASC_PRT_NEXT();
9363         }
9364     
9365         /*
9366          * Display request queuing statistics.
9367          */
9368         len = asc_prt_line(cp, leftlen,
9369     " Active and Waiting Request Queues (Time Unit: %d HZ):\n", HZ);
9370         ASC_PRT_NEXT();
9371     
9372     
9373          return totlen;
9374     }
9375     
9376     /*
9377      * asc_prt_target_stats()
9378      *
9379      * Note: no single line should be greater than ASC_PRTLINE_SIZE,
9380      * cf. asc_prt_line().
9381      *
9382      * This is separated from asc_prt_board_stats because a full set
9383      * of targets will overflow ASC_PRTBUF_SIZE.
9384      *
9385      * Return the number of characters copied into 'cp'. No more than
9386      * 'cplen' characters will be copied to 'cp'.
9387      */
9388     STATIC int
9389     asc_prt_target_stats(struct Scsi_Host *shp, int tgt_id, char *cp, int cplen)
9390     {
9391         int                    leftlen;
9392         int                    totlen;
9393         int                    len;
9394         struct asc_stats       *s;
9395         ushort                 chip_scsi_id;
9396         asc_board_t            *boardp;
9397         asc_queue_t            *active;
9398         asc_queue_t            *waiting;
9399     
9400         leftlen = cplen;
9401         totlen = len = 0;
9402     
9403         boardp = ASC_BOARDP(shp);
9404         s = &boardp->asc_stats;
9405     
9406         active = &ASC_BOARDP(shp)->active;
9407         waiting = &ASC_BOARDP(shp)->waiting;
9408     
9409         if (ASC_NARROW_BOARD(boardp)) {
9410             chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
9411         } else {
9412             chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
9413         }
9414     
9415         if ((chip_scsi_id == tgt_id) ||
9416             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(tgt_id)) == 0)) {
9417             return 0;
9418         }
9419     
9420         do {
9421             if (active->q_tot_cnt[tgt_id] > 0 || waiting->q_tot_cnt[tgt_id] > 0) {
9422                 len = asc_prt_line(cp, leftlen, " target %d\n", tgt_id);
9423                 ASC_PRT_NEXT();
9424     
9425                 len = asc_prt_line(cp, leftlen,
9426     "   active: cnt [cur %d, max %d, tot %u], time [min %d, max %d, avg %lu.%01lu]\n",
9427                     active->q_cur_cnt[tgt_id], active->q_max_cnt[tgt_id],
9428                     active->q_tot_cnt[tgt_id],
9429                     active->q_min_tim[tgt_id], active->q_max_tim[tgt_id],
9430                     (active->q_tot_cnt[tgt_id] == 0) ? 0 :
9431                     (active->q_tot_tim[tgt_id]/active->q_tot_cnt[tgt_id]),
9432                     (active->q_tot_cnt[tgt_id] == 0) ? 0 :
9433                     ASC_TENTHS(active->q_tot_tim[tgt_id],
9434                     active->q_tot_cnt[tgt_id]));
9435                  ASC_PRT_NEXT();
9436     
9437                  len = asc_prt_line(cp, leftlen,
9438     "   waiting: cnt [cur %d, max %d, tot %u], time [min %u, max %u, avg %lu.%01lu]\n",
9439                     waiting->q_cur_cnt[tgt_id], waiting->q_max_cnt[tgt_id],
9440                     waiting->q_tot_cnt[tgt_id],
9441                     waiting->q_min_tim[tgt_id], waiting->q_max_tim[tgt_id],
9442                     (waiting->q_tot_cnt[tgt_id] == 0) ? 0 :
9443                     (waiting->q_tot_tim[tgt_id]/waiting->q_tot_cnt[tgt_id]),
9444                     (waiting->q_tot_cnt[tgt_id] == 0) ? 0 :
9445                     ASC_TENTHS(waiting->q_tot_tim[tgt_id],
9446                     waiting->q_tot_cnt[tgt_id]));
9447                  ASC_PRT_NEXT();
9448             }
9449         } while (0);
9450     
9451          return totlen;
9452     }
9453     #endif /* CONFIG_PROC_FS */
9454     #endif /* ADVANSYS_STATS */
9455     
9456     #ifdef ADVANSYS_DEBUG
9457     /*
9458      * asc_prt_scsi_host()
9459      */
9460     STATIC void
9461     asc_prt_scsi_host(struct Scsi_Host *s)
9462     {
9463         asc_board_t         *boardp;
9464     
9465         boardp = ASC_BOARDP(s);
9466     
9467         printk("Scsi_Host at addr 0x%lx\n", (ulong) s);
9468         printk(
9469     " next 0x%lx, extra_bytes %u, host_busy %u, host_no %d, last_reset %d,\n",
9470             (ulong) s->next, s->extra_bytes, s->host_busy, s->host_no,
9471             (unsigned) s->last_reset);
9472     
9473     #if ASC_LINUX_KERNEL24
9474         printk(
9475     " host_queue 0x%lx, hostt 0x%lx\n",
9476             (ulong) s->host_queue, (ulong) s->hostt);
9477     #elif ASC_LINUX_KERNEL22
9478         printk(
9479     " host_queue 0x%lx, hostt 0x%lx, block 0x%lx,\n",
9480             (ulong) s->host_queue, (ulong) s->hostt, (ulong) s->block);
9481     #endif
9482     
9483         printk(
9484     " base 0x%lx, io_port 0x%lx, n_io_port %u, irq 0x%x,\n",
9485             (ulong) s->base, (ulong) s->io_port, s->n_io_port, s->irq);
9486     
9487         printk(
9488     " dma_channel %d, this_id %d, can_queue %d,\n",
9489             s->dma_channel, s->this_id, s->can_queue);
9490     
9491         printk(
9492     " cmd_per_lun %d, sg_tablesize %d, unchecked_isa_dma %d, loaded_as_module %d\n",
9493             s->cmd_per_lun, s->sg_tablesize, s->unchecked_isa_dma,
9494             s->loaded_as_module);
9495     
9496         if (ASC_NARROW_BOARD(boardp)) {
9497             asc_prt_asc_dvc_var(&ASC_BOARDP(s)->dvc_var.asc_dvc_var);
9498             asc_prt_asc_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.asc_dvc_cfg);
9499         } else {
9500             asc_prt_adv_dvc_var(&ASC_BOARDP(s)->dvc_var.adv_dvc_var);
9501             asc_prt_adv_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.adv_dvc_cfg);
9502         }
9503     }
9504     
9505     /*
9506      * asc_prt_scsi_cmnd()
9507      */
9508     STATIC void
9509     asc_prt_scsi_cmnd(Scsi_Cmnd *s)
9510     {
9511         printk("Scsi_Cmnd at addr 0x%lx\n", (ulong) s);
9512     
9513         printk(
9514     " host 0x%lx, device 0x%lx, target %u, lun %u, channel %u,\n",
9515             (ulong) s->host, (ulong) s->device, s->target, s->lun,
9516             s->channel);
9517     
9518         asc_prt_hex(" CDB", s->cmnd, s->cmd_len);
9519     
9520     #if ASC_LINUX_KERNEL24
9521         printk (
9522     "sc_data_direction %u, resid %d\n",
9523             s->sc_data_direction, s->resid);
9524     #endif
9525     
9526         printk(
9527     " use_sg %u, sglist_len %u, abort_reason 0x%x\n",
9528             s->use_sg, s->sglist_len, s->abort_reason);
9529     
9530         printk(
9531     " serial_number 0x%x, serial_number_at_timeout 0x%x, retries %d, allowed %d\n",
9532             (unsigned) s->serial_number, (unsigned) s->serial_number_at_timeout,
9533              s->retries, s->allowed);
9534     
9535         printk(
9536     " timeout_per_command %d, timeout_total %d, timeout %d\n",
9537             s->timeout_per_command, s->timeout_total, s->timeout);
9538     
9539     #if ASC_LINUX_KERNEL24
9540         printk(
9541     " internal_timeout %u, flags %u\n",
9542             s->internal_timeout, s->flags);
9543     #elif ASC_LINUX_KERNEL22
9544         printk(
9545     " internal_timeout %u, flags %u, this_count %d\n",
9546             s->internal_timeout, s->flags,s->this_count);
9547     #endif
9548     
9549         printk(
9550     " scsi_done 0x%lx, done 0x%lx, host_scribble 0x%lx, result 0x%x\n",
9551             (ulong) s->scsi_done, (ulong) s->done,
9552             (ulong) s->host_scribble, s->result);
9553     
9554         printk(
9555     " tag %u, pid %u\n",
9556             (unsigned) s->tag, (unsigned) s->pid);
9557     }
9558     
9559     /*
9560      * asc_prt_asc_dvc_var()
9561      */
9562     STATIC void
9563     asc_prt_asc_dvc_var(ASC_DVC_VAR *h)
9564     {
9565         printk("ASC_DVC_VAR at addr 0x%lx\n", (ulong) h);
9566     
9567         printk(
9568     " iop_base 0x%x, err_code 0x%x, dvc_cntl 0x%x, bug_fix_cntl %d,\n",
9569             h->iop_base, h->err_code, h->dvc_cntl, h->bug_fix_cntl);
9570     
9571         printk(
9572     " bus_type %d, isr_callback 0x%lx, exe_callback 0x%lx, init_sdtr 0x%x,\n",
9573             h->bus_type, (ulong) h->isr_callback, (ulong) h->exe_callback,
9574             (unsigned) h->init_sdtr);
9575     
9576         printk(
9577     " sdtr_done 0x%x, use_tagged_qng 0x%x, unit_not_ready 0x%x, chip_no 0x%x,\n",
9578             (unsigned) h->sdtr_done, (unsigned) h->use_tagged_qng,
9579             (unsigned) h->unit_not_ready, (unsigned) h->chip_no);
9580     
9581         printk(
9582     " queue_full_or_busy 0x%x, start_motor 0x%x, scsi_reset_wait %u,\n",
9583             (unsigned) h->queue_full_or_busy, (unsigned) h->start_motor,
9584             (unsigned) h->scsi_reset_wait);
9585     
9586         printk(
9587     " is_in_int %u, max_total_qng %u, cur_total_qng %u, in_critical_cnt %u,\n",
9588             (unsigned) h->is_in_int, (unsigned) h->max_total_qng,
9589             (unsigned) h->cur_total_qng, (unsigned) h->in_critical_cnt);
9590     
9591         printk(
9592     " last_q_shortage %u, init_state 0x%x, no_scam 0x%x, pci_fix_asyn_xfer 0x%x,\n",
9593             (unsigned) h->last_q_shortage, (unsigned) h->init_state,
9594             (unsigned) h->no_scam, (unsigned) h->pci_fix_asyn_xfer);
9595     
9596         printk(
9597     " cfg 0x%lx, irq_no 0x%x\n",
9598             (ulong) h->cfg, (unsigned) h->irq_no);
9599     }
9600     
9601     /*
9602      * asc_prt_asc_dvc_cfg()
9603      */
9604     STATIC void
9605     asc_prt_asc_dvc_cfg(ASC_DVC_CFG *h)
9606     {
9607         printk("ASC_DVC_CFG at addr 0x%lx\n", (ulong) h);
9608     
9609         printk(
9610     " can_tagged_qng 0x%x, cmd_qng_enabled 0x%x,\n",
9611                 h->can_tagged_qng, h->cmd_qng_enabled);
9612         printk(
9613     " disc_enable 0x%x, sdtr_enable 0x%x,\n",
9614                 h->disc_enable, h->sdtr_enable);
9615     
9616         printk(
9617     " chip_scsi_id %d, isa_dma_speed %d, isa_dma_channel %d, chip_version %d,\n",
9618                  h->chip_scsi_id, h->isa_dma_speed, h->isa_dma_channel,
9619                  h->chip_version);
9620     
9621         printk(
9622     " pci_device_id %d, lib_serial_no %u, lib_version %u, mcode_date 0x%x,\n",
9623               h->pci_device_id, h->lib_serial_no, h->lib_version, h->mcode_date);
9624     
9625         printk(
9626     " mcode_version %d, overrun_buf 0x%lx\n",
9627                 h->mcode_version, (ulong) h->overrun_buf);
9628     }
9629     
9630     /*
9631      * asc_prt_asc_scsi_q()
9632      */
9633     STATIC void
9634     asc_prt_asc_scsi_q(ASC_SCSI_Q *q)
9635     {
9636         ASC_SG_HEAD    *sgp;
9637         int i;
9638     
9639         printk("ASC_SCSI_Q at addr 0x%lx\n", (ulong) q);
9640     
9641         printk(
9642     " target_ix 0x%x, target_lun %u, srb_ptr 0x%lx, tag_code 0x%x,\n",
9643                 q->q2.target_ix, q->q1.target_lun,
9644                 (ulong) q->q2.srb_ptr, q->q2.tag_code);
9645     
9646         printk(
9647     " data_addr 0x%lx, data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
9648                 (ulong) le32_to_cpu(q->q1.data_addr),
9649                 (ulong) le32_to_cpu(q->q1.data_cnt),
9650                 (ulong) le32_to_cpu(q->q1.sense_addr), q->q1.sense_len);
9651     
9652         printk(
9653     " cdbptr 0x%lx, cdb_len %u, sg_head 0x%lx, sg_queue_cnt %u\n",
9654                 (ulong) q->cdbptr, q->q2.cdb_len,
9655                 (ulong) q->sg_head, q->q1.sg_queue_cnt);
9656     
9657         if (q->sg_head) {
9658             sgp = q->sg_head;
9659             printk("ASC_SG_HEAD at addr 0x%lx\n", (ulong) sgp);
9660             printk(" entry_cnt %u, queue_cnt %u\n", sgp->entry_cnt, sgp->queue_cnt);
9661             for (i = 0; i < sgp->entry_cnt; i++) {
9662                 printk(" [%u]: addr 0x%lx, bytes %lu\n",
9663                     i, (ulong) le32_to_cpu(sgp->sg_list[i].addr),
9664                     (ulong) le32_to_cpu(sgp->sg_list[i].bytes));
9665             }
9666     
9667         }
9668     }
9669     
9670     /*
9671      * asc_prt_asc_qdone_info()
9672      */
9673     STATIC void
9674     asc_prt_asc_qdone_info(ASC_QDONE_INFO *q)
9675     {
9676         printk("ASC_QDONE_INFO at addr 0x%lx\n", (ulong) q);
9677         printk(
9678     " srb_ptr 0x%lx, target_ix %u, cdb_len %u, tag_code %u,\n",
9679                 (ulong) q->d2.srb_ptr, q->d2.target_ix, q->d2.cdb_len,
9680                 q->d2.tag_code);
9681         printk(
9682     " done_stat 0x%x, host_stat 0x%x, scsi_stat 0x%x, scsi_msg 0x%x\n",
9683                 q->d3.done_stat, q->d3.host_stat, q->d3.scsi_stat, q->d3.scsi_msg);
9684     }
9685     
9686     /*
9687      * asc_prt_adv_dvc_var()
9688      *
9689      * Display an ADV_DVC_VAR structure.
9690      */
9691     STATIC void
9692     asc_prt_adv_dvc_var(ADV_DVC_VAR *h)
9693     {
9694         printk(" ADV_DVC_VAR at addr 0x%lx\n", (ulong) h);
9695     
9696         printk(
9697     "  iop_base 0x%lx, err_code 0x%x, ultra_able 0x%x\n",
9698             (ulong) h->iop_base, h->err_code, (unsigned) h->ultra_able);
9699     
9700         printk(
9701     "  isr_callback 0x%lx, sdtr_able 0x%x, wdtr_able 0x%x\n",
9702             (ulong) h->isr_callback, (unsigned) h->sdtr_able,
9703             (unsigned) h->wdtr_able);
9704     
9705         printk(
9706     "  start_motor 0x%x, scsi_reset_wait 0x%x, irq_no 0x%x,\n",
9707             (unsigned) h->start_motor,
9708             (unsigned) h->scsi_reset_wait, (unsigned) h->irq_no);
9709     
9710         printk(
9711     "  max_host_qng %u, max_dvc_qng %u, carr_freelist 0x%lxn\n",
9712             (unsigned) h->max_host_qng, (unsigned) h->max_dvc_qng,
9713             (ulong) h->carr_freelist);
9714     
9715         printk(
9716     "  icq_sp 0x%lx, irq_sp 0x%lx\n",
9717             (ulong) h->icq_sp, (ulong) h->irq_sp);
9718     
9719         printk(
9720     "  no_scam 0x%x, tagqng_able 0x%x\n",
9721             (unsigned) h->no_scam, (unsigned) h->tagqng_able);
9722     
9723         printk(
9724     "  chip_scsi_id 0x%x, cfg 0x%lx\n",
9725             (unsigned) h->chip_scsi_id, (ulong) h->cfg);
9726     }
9727     
9728     /*
9729      * asc_prt_adv_dvc_cfg()
9730      *
9731      * Display an ADV_DVC_CFG structure.
9732      */
9733     STATIC void
9734     asc_prt_adv_dvc_cfg(ADV_DVC_CFG *h)
9735     {
9736         printk(" ADV_DVC_CFG at addr 0x%lx\n", (ulong) h);
9737     
9738         printk(
9739     "  disc_enable 0x%x, termination 0x%x\n",
9740             h->disc_enable, h->termination);
9741     
9742         printk(
9743     "  chip_version 0x%x, mcode_date 0x%x\n",
9744             h->chip_version, h->mcode_date);
9745     
9746         printk(
9747     "  mcode_version 0x%x, pci_device_id 0x%x, lib_version %u\n",
9748            h->mcode_version, h->pci_device_id, h->lib_version);
9749     
9750         printk(
9751     "  control_flag 0x%x, pci_slot_info 0x%x\n",
9752            h->control_flag, h->pci_slot_info);
9753     }
9754     
9755     /*
9756      * asc_prt_adv_scsi_req_q()
9757      *
9758      * Display an ADV_SCSI_REQ_Q structure.
9759      */
9760     STATIC void
9761     asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *q)
9762     {
9763         int                 sg_blk_cnt;
9764         struct asc_sg_block *sg_ptr;
9765     
9766         printk("ADV_SCSI_REQ_Q at addr 0x%lx\n", (ulong) q);
9767     
9768         printk(
9769     "  target_id %u, target_lun %u, srb_ptr 0x%lx, a_flag 0x%x\n",
9770                 q->target_id, q->target_lun, (ulong) q->srb_ptr, q->a_flag);
9771     
9772         printk("  cntl 0x%x, data_addr 0x%lx, vdata_addr 0x%lx\n",
9773                 q->cntl, (ulong) le32_to_cpu(q->data_addr), (ulong) q->vdata_addr);
9774     
9775         printk(
9776     "  data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
9777                 (ulong) le32_to_cpu(q->data_cnt),
9778                 (ulong) le32_to_cpu(q->sense_addr), q->sense_len);
9779     
9780         printk(
9781     "  cdb_len %u, done_status 0x%x, host_status 0x%x, scsi_status 0x%x\n",
9782                 q->cdb_len, q->done_status, q->host_status, q->scsi_status);
9783     
9784         printk(
9785     "  sg_working_ix 0x%x, target_cmd %u\n",
9786                 q->sg_working_ix, q->target_cmd);
9787     
9788         printk(
9789     "  scsiq_rptr 0x%lx, sg_real_addr 0x%lx, sg_list_ptr 0x%lx\n",
9790                 (ulong) le32_to_cpu(q->scsiq_rptr),
9791                 (ulong) le32_to_cpu(q->sg_real_addr), (ulong) q->sg_list_ptr);
9792     
9793         /* Display the request's ADV_SG_BLOCK structures. */
9794         if (q->sg_list_ptr != NULL)
9795         {
9796             sg_blk_cnt = 0;
9797             while (1) {
9798                 /*
9799                  * 'sg_ptr' is a physical address. Convert it to a virtual
9800                  * address by indexing 'sg_blk_cnt' into the virtual address
9801                  * array 'sg_list_ptr'.
9802                  *
9803                  * XXX - Assumes all SG physical blocks are virtually contiguous.
9804                  */
9805                 sg_ptr = &(((ADV_SG_BLOCK *) (q->sg_list_ptr))[sg_blk_cnt]);
9806                 asc_prt_adv_sgblock(sg_blk_cnt, sg_ptr);
9807                 if (sg_ptr->sg_ptr == 0)
9808                 {
9809                     break;
9810                 }
9811                 sg_blk_cnt++;
9812             }
9813         }
9814     }
9815     
9816     /*
9817      * asc_prt_adv_sgblock()
9818      *
9819      * Display an ADV_SG_BLOCK structure.
9820      */
9821     STATIC void
9822     asc_prt_adv_sgblock(int sgblockno, ADV_SG_BLOCK *b)
9823     {
9824         int i;
9825     
9826         printk(" ASC_SG_BLOCK at addr 0x%lx (sgblockno %d)\n",
9827             (ulong) b, sgblockno);
9828         printk("  sg_cnt %u, sg_ptr 0x%lx\n",
9829             b->sg_cnt, (ulong) le32_to_cpu(b->sg_ptr));
9830         ASC_ASSERT(b->sg_cnt <= NO_OF_SG_PER_BLOCK);
9831         if (b->sg_ptr != 0)
9832         {
9833             ASC_ASSERT(b->sg_cnt == NO_OF_SG_PER_BLOCK);
9834         }
9835         for (i = 0; i < b->sg_cnt; i++) {
9836             printk("  [%u]: sg_addr 0x%lx, sg_count 0x%lx\n",
9837                 i, (ulong) b->sg_list[i].sg_addr, (ulong) b->sg_list[i].sg_count);
9838         }
9839     }
9840     
9841     /*
9842      * asc_prt_hex()
9843      *
9844      * Print hexadecimal output in 4 byte groupings 32 bytes
9845      * or 8 double-words per line.
9846      */
9847     STATIC void
9848     asc_prt_hex(char *f, uchar *s, int l)
9849     {
9850         int            i;
9851         int            j;
9852         int            k;
9853         int            m;
9854     
9855         printk("%s: (%d bytes)\n", f, l);
9856     
9857         for (i = 0; i < l; i += 32) {
9858     
9859             /* Display a maximum of 8 double-words per line. */
9860             if ((k = (l - i) / 4) >= 8) {
9861                 k = 8;
9862                 m = 0;
9863             } else {
9864                 m = (l - i) % 4;
9865             }
9866     
9867             for (j = 0; j < k; j++) {
9868                 printk(" %2.2X%2.2X%2.2X%2.2X",
9869                     (unsigned) s[i+(j*4)], (unsigned) s[i+(j*4)+1],
9870                     (unsigned) s[i+(j*4)+2], (unsigned) s[i+(j*4)+3]);
9871             }
9872     
9873             switch (m) {
9874             case 0:
9875             default:
9876                 break;
9877             case 1:
9878                 printk(" %2.2X",
9879                     (unsigned) s[i+(j*4)]);
9880                 break;
9881             case 2:
9882                 printk(" %2.2X%2.2X",
9883                     (unsigned) s[i+(j*4)],
9884                     (unsigned) s[i+(j*4)+1]);
9885                 break;
9886             case 3:
9887                 printk(" %2.2X%2.2X%2.2X",
9888                     (unsigned) s[i+(j*4)+1],
9889                     (unsigned) s[i+(j*4)+2],
9890                     (unsigned) s[i+(j*4)+3]);
9891                 break;
9892             }
9893     
9894             printk("\n");
9895         }
9896     }
9897     #endif /* ADVANSYS_DEBUG */
9898     
9899     /*
9900      * --- Asc Library Functions
9901      */
9902     
9903     ASC_INITFUNC(
9904     STATIC ushort,
9905     AscGetEisaChipCfg(
9906                          PortAddr iop_base
9907     )
9908     )
9909     {
9910         PortAddr            eisa_cfg_iop;
9911     
9912         eisa_cfg_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
9913           (PortAddr) (ASC_EISA_CFG_IOP_MASK);
9914         return (inpw(eisa_cfg_iop));
9915     }
9916     
9917     ASC_INITFUNC(
9918     STATIC uchar,
9919     AscSetChipScsiID(
9920                         PortAddr iop_base,
9921                         uchar new_host_id
9922     )
9923     )
9924     {
9925         ushort              cfg_lsw;
9926     
9927         if (AscGetChipScsiID(iop_base) == new_host_id) {
9928             return (new_host_id);
9929         }
9930         cfg_lsw = AscGetChipCfgLsw(iop_base);
9931         cfg_lsw &= 0xF8FF;
9932         cfg_lsw |= (ushort) ((new_host_id & ASC_MAX_TID) << 8);
9933         AscSetChipCfgLsw(iop_base, cfg_lsw);
9934         return (AscGetChipScsiID(iop_base));
9935     }
9936     
9937     ASC_INITFUNC(
9938     STATIC uchar,
9939     AscGetChipScsiCtrl(
9940                           PortAddr iop_base
9941     )
9942     )
9943     {
9944         uchar               sc;
9945     
9946         AscSetBank(iop_base, 1);
9947         sc = inp(iop_base + IOP_REG_SC);
9948         AscSetBank(iop_base, 0);
9949         return (sc);
9950     }
9951     
9952     ASC_INITFUNC(
9953     STATIC uchar,
9954     AscGetChipVersion(
9955                          PortAddr iop_base,
9956                          ushort bus_type
9957     )
9958     )
9959     {
9960         if ((bus_type & ASC_IS_EISA) != 0) {
9961             PortAddr            eisa_iop;
9962             uchar               revision;
9963             eisa_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
9964               (PortAddr) ASC_EISA_REV_IOP_MASK;
9965             revision = inp(eisa_iop);
9966             return ((uchar) ((ASC_CHIP_MIN_VER_EISA - 1) + revision));
9967         }
9968         return (AscGetChipVerNo(iop_base));
9969     }
9970     
9971     ASC_INITFUNC(
9972     STATIC ushort,
9973     AscGetChipBusType(
9974                          PortAddr iop_base
9975     )
9976     )
9977     {
9978         ushort              chip_ver;
9979     
9980         chip_ver = AscGetChipVerNo(iop_base);
9981         if (
9982                (chip_ver >= ASC_CHIP_MIN_VER_VL)
9983                && (chip_ver <= ASC_CHIP_MAX_VER_VL)
9984     ) {
9985             if (
9986                    ((iop_base & 0x0C30) == 0x0C30)
9987                    || ((iop_base & 0x0C50) == 0x0C50)
9988     ) {
9989                 return (ASC_IS_EISA);
9990             }
9991             return (ASC_IS_VL);
9992         }
9993         if ((chip_ver >= ASC_CHIP_MIN_VER_ISA) &&
9994             (chip_ver <= ASC_CHIP_MAX_VER_ISA)) {
9995             if (chip_ver >= ASC_CHIP_MIN_VER_ISA_PNP) {
9996                 return (ASC_IS_ISAPNP);
9997             }
9998             return (ASC_IS_ISA);
9999         } else if ((chip_ver >= ASC_CHIP_MIN_VER_PCI) &&
10000                    (chip_ver <= ASC_CHIP_MAX_VER_PCI)) {
10001             return (ASC_IS_PCI);
10002         }
10003         return (0);
10004     }
10005     
10006     STATIC ASC_DCNT
10007     AscLoadMicroCode(
10008                         PortAddr iop_base,
10009                         ushort s_addr,
10010                         uchar *mcode_buf,
10011                         ushort mcode_size
10012     )
10013     {
10014         ASC_DCNT            chksum;
10015         ushort              mcode_word_size;
10016         ushort              mcode_chksum;
10017     
10018         /* Write the microcode buffer starting at LRAM address 0. */
10019         mcode_word_size = (ushort) (mcode_size >> 1);
10020         AscMemWordSetLram(iop_base, s_addr, 0, mcode_word_size);
10021         AscMemWordCopyPtrToLram(iop_base, s_addr, mcode_buf, mcode_word_size);
10022     
10023         chksum = AscMemSumLramWord(iop_base, s_addr, mcode_word_size);
10024         ASC_DBG1(1, "AscLoadMicroCode: chksum 0x%lx\n", (ulong) chksum);
10025         mcode_chksum = (ushort) AscMemSumLramWord(iop_base,
10026               (ushort) ASC_CODE_SEC_BEG,
10027               (ushort) ((mcode_size - s_addr - (ushort) ASC_CODE_SEC_BEG) / 2));
10028         ASC_DBG1(1, "AscLoadMicroCode: mcode_chksum 0x%lx\n",
10029             (ulong) mcode_chksum);
10030         AscWriteLramWord(iop_base, ASCV_MCODE_CHKSUM_W, mcode_chksum);
10031         AscWriteLramWord(iop_base, ASCV_MCODE_SIZE_W, mcode_size);
10032         return (chksum);
10033     }
10034     
10035     STATIC int
10036     AscFindSignature(
10037                         PortAddr iop_base
10038     )
10039     {
10040         ushort              sig_word;
10041     
10042         ASC_DBG2(1, "AscFindSignature: AscGetChipSignatureByte(0x%x) 0x%x\n",
10043             iop_base, AscGetChipSignatureByte(iop_base));
10044         if (AscGetChipSignatureByte(iop_base) == (uchar) ASC_1000_ID1B) {
10045             ASC_DBG2(1, "AscFindSignature: AscGetChipSignatureWord(0x%x) 0x%x\n",
10046                 iop_base, AscGetChipSignatureWord(iop_base));
10047             sig_word = AscGetChipSignatureWord(iop_base);
10048             if ((sig_word == (ushort) ASC_1000_ID0W) ||
10049                 (sig_word == (ushort) ASC_1000_ID0W_FIX)) {
10050                 return (1);
10051             }
10052         }
10053         return (0);
10054     }
10055     
10056     STATIC PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] ASC_INITDATA =
10057     {
10058         0x100, ASC_IOADR_1, 0x120, ASC_IOADR_2, 0x140, ASC_IOADR_3, ASC_IOADR_4,
10059         ASC_IOADR_5, ASC_IOADR_6, ASC_IOADR_7, ASC_IOADR_8
10060     };
10061     
10062     #ifdef CONFIG_ISA
10063     STATIC uchar _isa_pnp_inited ASC_INITDATA = 0;
10064     
10065     ASC_INITFUNC(
10066     STATIC PortAddr,
10067     AscSearchIOPortAddr(
10068                            PortAddr iop_beg,
10069                            ushort bus_type
10070     )
10071     )
10072     {
10073         if (bus_type & ASC_IS_VL) {
10074             while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) {
10075                 if (AscGetChipVersion(iop_beg, bus_type) <= ASC_CHIP_MAX_VER_VL) {
10076                     return (iop_beg);
10077                 }
10078             }
10079             return (0);
10080         }
10081         if (bus_type & ASC_IS_ISA) {
10082             if (_isa_pnp_inited == 0) {
10083                 AscSetISAPNPWaitForKey();
10084                 _isa_pnp_inited++;
10085             }
10086             while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) {
10087                 if ((AscGetChipVersion(iop_beg, bus_type) & ASC_CHIP_VER_ISA_BIT) != 0) {
10088                     return (iop_beg);
10089                 }
10090             }
10091             return (0);
10092         }
10093         if (bus_type & ASC_IS_EISA) {
10094             if ((iop_beg = AscSearchIOPortAddrEISA(iop_beg)) != 0) {
10095                 return (iop_beg);
10096             }
10097             return (0);
10098         }
10099         return (0);
10100     }
10101     
10102     ASC_INITFUNC(
10103     STATIC PortAddr,
10104     AscSearchIOPortAddr11(
10105                              PortAddr s_addr
10106     )
10107     )
10108     {
10109         int                 i;
10110         PortAddr            iop_base;
10111     
10112         for (i = 0; i < ASC_IOADR_TABLE_MAX_IX; i++) {
10113             if (_asc_def_iop_base[i] > s_addr) {
10114                 break;
10115             }
10116         }
10117         for (; i < ASC_IOADR_TABLE_MAX_IX; i++) {
10118             iop_base = _asc_def_iop_base[i];
10119             if (check_region(iop_base, ASC_IOADR_GAP) != 0) {
10120                 ASC_DBG1(1,
10121                    "AscSearchIOPortAddr11: check_region() failed I/O port 0x%x\n",
10122                          iop_base);
10123                 continue;
10124             }
10125             ASC_DBG1(1, "AscSearchIOPortAddr11: probing I/O port 0x%x\n", iop_base);
10126             if (AscFindSignature(iop_base)) {
10127                 return (iop_base);
10128             }
10129         }
10130         return (0);
10131     }
10132     
10133     ASC_INITFUNC(
10134     STATIC void,
10135     AscSetISAPNPWaitForKey(
10136         void)
10137     )
10138     {
10139         outp(ASC_ISA_PNP_PORT_ADDR, 0x02);
10140         outp(ASC_ISA_PNP_PORT_WRITE, 0x02);
10141         return;
10142     }
10143     #endif /* CONFIG_ISA */
10144     
10145     ASC_INITFUNC(
10146     STATIC void,
10147     AscToggleIRQAct(
10148                        PortAddr iop_base
10149     )
10150     )
10151     {
10152         AscSetChipStatus(iop_base, CIW_IRQ_ACT);
10153         AscSetChipStatus(iop_base, 0);
10154         return;
10155     }
10156     
10157     ASC_INITFUNC(
10158     STATIC uchar,
10159     AscGetChipIRQ(
10160                      PortAddr iop_base,
10161                      ushort bus_type
10162     )
10163     )
10164     {
10165         ushort              cfg_lsw;
10166         uchar               chip_irq;
10167     
10168         if ((bus_type & ASC_IS_EISA) != 0) {
10169             cfg_lsw = AscGetEisaChipCfg(iop_base);
10170             chip_irq = (uchar) (((cfg_lsw >> 8) & 0x07) + 10);
10171             if ((chip_irq == 13) || (chip_irq > 15)) {
10172                 return (0);
10173             }
10174             return (chip_irq);
10175         }
10176         if ((bus_type & ASC_IS_VL) != 0) {
10177             cfg_lsw = AscGetChipCfgLsw(iop_base);
10178             chip_irq = (uchar) (((cfg_lsw >> 2) & 0x07));
10179             if ((chip_irq == 0) ||
10180                 (chip_irq == 4) ||
10181                 (chip_irq == 7)) {
10182                 return (0);
10183             }
10184             return ((uchar) (chip_irq + (ASC_MIN_IRQ_NO - 1)));
10185         }
10186         cfg_lsw = AscGetChipCfgLsw(iop_base);
10187         chip_irq = (uchar) (((cfg_lsw >> 2) & 0x03));
10188         if (chip_irq == 3)
10189             chip_irq += (uchar) 2;
10190         return ((uchar) (chip_irq + ASC_MIN_IRQ_NO));
10191     }
10192     
10193     ASC_INITFUNC(
10194     STATIC uchar,
10195     AscSetChipIRQ(
10196                      PortAddr iop_base,
10197                      uchar irq_no,
10198                      ushort bus_type
10199     )
10200     )
10201     {
10202         ushort              cfg_lsw;
10203     
10204         if ((bus_type & ASC_IS_VL) != 0) {
10205             if (irq_no != 0) {
10206                 if ((irq_no < ASC_MIN_IRQ_NO) || (irq_no > ASC_MAX_IRQ_NO)) {
10207                     irq_no = 0;
10208                 } else {
10209                     irq_no -= (uchar) ((ASC_MIN_IRQ_NO - 1));
10210                 }
10211             }
10212             cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base) & 0xFFE3);
10213             cfg_lsw |= (ushort) 0x0010;
10214             AscSetChipCfgLsw(iop_base, cfg_lsw);
10215             AscToggleIRQAct(iop_base);
10216             cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base) & 0xFFE0);
10217             cfg_lsw |= (ushort) ((irq_no & 0x07) << 2);
10218             AscSetChipCfgLsw(iop_base, cfg_lsw);
10219             AscToggleIRQAct(iop_base);
10220             return (AscGetChipIRQ(iop_base, bus_type));
10221         }
10222         if ((bus_type & (ASC_IS_ISA)) != 0) {
10223             if (irq_no == 15)
10224                 irq_no -= (uchar) 2;
10225             irq_no -= (uchar) ASC_MIN_IRQ_NO;
10226             cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base) & 0xFFF3);
10227             cfg_lsw |= (ushort) ((irq_no & 0x03) << 2);
10228             AscSetChipCfgLsw(iop_base, cfg_lsw);
10229             return (AscGetChipIRQ(iop_base, bus_type));
10230         }
10231         return (0);
10232     }
10233     
10234     #ifdef CONFIG_ISA
10235     ASC_INITFUNC(
10236     STATIC void,
10237     AscEnableIsaDma(
10238                        uchar dma_channel
10239     )
10240     )
10241     {
10242         if (dma_channel < 4) {
10243             outp(0x000B, (ushort) (0xC0 | dma_channel));
10244             outp(0x000A, dma_channel);
10245         } else if (dma_channel < 8) {
10246             outp(0x00D6, (ushort) (0xC0 | (dma_channel - 4)));
10247             outp(0x00D4, (ushort) (dma_channel - 4));
10248         }
10249         return;
10250     }
10251     #endif /* CONFIG_ISA */
10252     
10253     STATIC int
10254     AscIsrChipHalted(
10255                         ASC_DVC_VAR *asc_dvc
10256     )
10257     {
10258         EXT_MSG             ext_msg;
10259         EXT_MSG             out_msg;
10260         ushort              halt_q_addr;
10261         int                 sdtr_accept;
10262         ushort              int_halt_code;
10263         ASC_SCSI_BIT_ID_TYPE scsi_busy;
10264         ASC_SCSI_BIT_ID_TYPE target_id;
10265         PortAddr            iop_base;
10266         uchar               tag_code;
10267         uchar               q_status;
10268         uchar               halt_qp;
10269         uchar               sdtr_data;
10270         uchar               target_ix;
10271         uchar               q_cntl, tid_no;
10272         uchar               cur_dvc_qng;
10273         uchar               asyn_sdtr;
10274         uchar               scsi_status;
10275         asc_board_t         *boardp;
10276     
10277         ASC_ASSERT(asc_dvc->drv_ptr != NULL);
10278         boardp = asc_dvc->drv_ptr;
10279     
10280         iop_base = asc_dvc->iop_base;
10281         int_halt_code = AscReadLramWord(iop_base, ASCV_HALTCODE_W);
10282     
10283         halt_qp = AscReadLramByte(iop_base, ASCV_CURCDB_B);
10284         halt_q_addr = ASC_QNO_TO_QADDR(halt_qp);
10285         target_ix = AscReadLramByte(iop_base,
10286                        (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TARGET_IX));
10287         q_cntl = AscReadLramByte(iop_base,
10288                             (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL));
10289         tid_no = ASC_TIX_TO_TID(target_ix);
10290         target_id = (uchar) ASC_TID_TO_TARGET_ID(tid_no);
10291         if (asc_dvc->pci_fix_asyn_xfer & target_id) {
10292             asyn_sdtr = ASYN_SDTR_DATA_FIX_PCI_REV_AB;
10293         } else {
10294             asyn_sdtr = 0;
10295         }
10296         if (int_halt_code == ASC_HALT_DISABLE_ASYN_USE_SYN_FIX) {
10297             if (asc_dvc->pci_fix_asyn_xfer & target_id) {
10298                 AscSetChipSDTR(iop_base, 0, tid_no);
10299                 boardp->sdtr_data[tid_no] = 0;
10300             }
10301             AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10302             return (0);
10303         } else if (int_halt_code == ASC_HALT_ENABLE_ASYN_USE_SYN_FIX) {
10304             if (asc_dvc->pci_fix_asyn_xfer & target_id) {
10305                 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
10306                 boardp->sdtr_data[tid_no] = asyn_sdtr;
10307             }
10308             AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10309             return (0);
10310         } else if (int_halt_code == ASC_HALT_EXTMSG_IN) {
10311     
10312             AscMemWordCopyPtrFromLram(iop_base,
10313                                    ASCV_MSGIN_BEG,
10314                                    (uchar *) &ext_msg,
10315                                    sizeof(EXT_MSG) >> 1);
10316     
10317             if (ext_msg.msg_type == MS_EXTEND &&
10318                 ext_msg.msg_req == MS_SDTR_CODE &&
10319                 ext_msg.msg_len == MS_SDTR_LEN) {
10320                 sdtr_accept = TRUE;
10321                 if ((ext_msg.req_ack_offset > ASC_SYN_MAX_OFFSET)) {
10322     
10323                     sdtr_accept = FALSE;
10324                     ext_msg.req_ack_offset = ASC_SYN_MAX_OFFSET;
10325                 }
10326                 if ((ext_msg.xfer_period <
10327                      asc_dvc->sdtr_period_tbl[asc_dvc->host_init_sdtr_index]) ||
10328                     (ext_msg.xfer_period >
10329                      asc_dvc->sdtr_period_tbl[asc_dvc->max_sdtr_index])) {
10330                     sdtr_accept = FALSE;
10331                     ext_msg.xfer_period =
10332                         asc_dvc->sdtr_period_tbl[asc_dvc->host_init_sdtr_index];
10333                 }
10334                 if (sdtr_accept) {
10335                     sdtr_data = AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
10336                                                ext_msg.req_ack_offset);
10337                     if ((sdtr_data == 0xFF)) {
10338     
10339                         q_cntl |= QC_MSG_OUT;
10340                         asc_dvc->init_sdtr &= ~target_id;
10341                         asc_dvc->sdtr_done &= ~target_id;
10342                         AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
10343                         boardp->sdtr_data[tid_no] = asyn_sdtr;
10344                     }
10345                 }
10346                 if (ext_msg.req_ack_offset == 0) {
10347     
10348                     q_cntl &= ~QC_MSG_OUT;
10349                     asc_dvc->init_sdtr &= ~target_id;
10350                     asc_dvc->sdtr_done &= ~target_id;
10351                     AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
10352                 } else {
10353                     if (sdtr_accept && (q_cntl & QC_MSG_OUT)) {
10354     
10355                         q_cntl &= ~QC_MSG_OUT;
10356                         asc_dvc->sdtr_done |= target_id;
10357                         asc_dvc->init_sdtr |= target_id;
10358                         asc_dvc->pci_fix_asyn_xfer &= ~target_id;
10359                         sdtr_data = AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
10360                                                    ext_msg.req_ack_offset);
10361                         AscSetChipSDTR(iop_base, sdtr_data, tid_no);
10362                         boardp->sdtr_data[tid_no] = sdtr_data;
10363                     } else {
10364     
10365                         q_cntl |= QC_MSG_OUT;
10366                         AscMsgOutSDTR(asc_dvc,
10367                                       ext_msg.xfer_period,
10368                                       ext_msg.req_ack_offset);
10369                         asc_dvc->pci_fix_asyn_xfer &= ~target_id;
10370                         sdtr_data = AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
10371                                                    ext_msg.req_ack_offset);
10372                         AscSetChipSDTR(iop_base, sdtr_data, tid_no);
10373                         boardp->sdtr_data[tid_no] = sdtr_data;
10374                         asc_dvc->sdtr_done |= target_id;
10375                         asc_dvc->init_sdtr |= target_id;
10376                     }
10377                 }
10378     
10379                 AscWriteLramByte(iop_base,
10380                              (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
10381                                  q_cntl);
10382                 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10383                 return (0);
10384             } else if (ext_msg.msg_type == MS_EXTEND &&
10385                        ext_msg.msg_req == MS_WDTR_CODE &&
10386                        ext_msg.msg_len == MS_WDTR_LEN) {
10387     
10388                 ext_msg.wdtr_width = 0;
10389                 AscMemWordCopyPtrToLram(iop_base,
10390                                      ASCV_MSGOUT_BEG,
10391                                      (uchar *) &ext_msg,
10392                                      sizeof(EXT_MSG) >> 1);
10393                 q_cntl |= QC_MSG_OUT;
10394                 AscWriteLramByte(iop_base,
10395                              (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
10396                                  q_cntl);
10397                 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10398                 return (0);
10399             } else {
10400     
10401                 ext_msg.msg_type = M1_MSG_REJECT;
10402                 AscMemWordCopyPtrToLram(iop_base,
10403                                      ASCV_MSGOUT_BEG,
10404                                      (uchar *) &ext_msg,
10405                                      sizeof(EXT_MSG) >> 1);
10406                 q_cntl |= QC_MSG_OUT;
10407                 AscWriteLramByte(iop_base,
10408                              (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
10409                                  q_cntl);
10410                 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10411                 return (0);
10412             }
10413         } else if (int_halt_code == ASC_HALT_CHK_CONDITION) {
10414     
10415             q_cntl |= QC_REQ_SENSE;
10416     
10417             if ((asc_dvc->init_sdtr & target_id) != 0) {
10418     
10419                 asc_dvc->sdtr_done &= ~target_id;
10420     
10421                 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
10422                 q_cntl |= QC_MSG_OUT;
10423                 AscMsgOutSDTR(asc_dvc,
10424                               asc_dvc->sdtr_period_tbl[(sdtr_data >> 4) &
10425                                (uchar) (asc_dvc->max_sdtr_index - 1)],
10426                               (uchar) (sdtr_data & (uchar) ASC_SYN_MAX_OFFSET));
10427             }
10428     
10429             AscWriteLramByte(iop_base,
10430                              (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
10431                              q_cntl);
10432     
10433             tag_code = AscReadLramByte(iop_base,
10434                         (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TAG_CODE));
10435             tag_code &= 0xDC;
10436             if (
10437                    (asc_dvc->pci_fix_asyn_xfer & target_id)
10438                    && !(asc_dvc->pci_fix_asyn_xfer_always & target_id)
10439     ) {
10440     
10441                 tag_code |= (ASC_TAG_FLAG_DISABLE_DISCONNECT
10442                              | ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX);
10443     
10444             }
10445             AscWriteLramByte(iop_base,
10446                          (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TAG_CODE),
10447                              tag_code);
10448     
10449             q_status = AscReadLramByte(iop_base,
10450                           (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_STATUS));
10451             q_status |= (QS_READY | QS_BUSY);
10452             AscWriteLramByte(iop_base,
10453                            (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_STATUS),
10454                              q_status);
10455     
10456             scsi_busy = AscReadLramByte(iop_base,
10457                                         (ushort) ASCV_SCSIBUSY_B);
10458             scsi_busy &= ~target_id;
10459             AscWriteLramByte(iop_base, (ushort) ASCV_SCSIBUSY_B, scsi_busy);
10460     
10461             AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10462             return (0);
10463         } else if (int_halt_code == ASC_HALT_SDTR_REJECTED) {
10464     
10465             AscMemWordCopyPtrFromLram(iop_base,
10466                                    ASCV_MSGOUT_BEG,
10467                                    (uchar *) &out_msg,
10468                                    sizeof(EXT_MSG) >> 1);
10469     
10470             if ((out_msg.msg_type == MS_EXTEND) &&
10471                 (out_msg.msg_len == MS_SDTR_LEN) &&
10472                 (out_msg.msg_req == MS_SDTR_CODE)) {
10473     
10474                 asc_dvc->init_sdtr &= ~target_id;
10475                 asc_dvc->sdtr_done &= ~target_id;
10476                 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
10477                 boardp->sdtr_data[tid_no] = asyn_sdtr;
10478             }
10479             q_cntl &= ~QC_MSG_OUT;
10480             AscWriteLramByte(iop_base,
10481                              (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
10482                              q_cntl);
10483             AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10484             return (0);
10485         } else if (int_halt_code == ASC_HALT_SS_QUEUE_FULL) {
10486     
10487             scsi_status = AscReadLramByte(iop_base,
10488               (ushort) ((ushort) halt_q_addr + (ushort) ASC_SCSIQ_SCSI_STATUS));
10489             cur_dvc_qng = AscReadLramByte(iop_base,
10490                          (ushort) ((ushort) ASC_QADR_BEG + (ushort) target_ix));
10491             if ((cur_dvc_qng > 0) &&
10492                 (asc_dvc->cur_dvc_qng[tid_no] > 0)) {
10493     
10494                 scsi_busy = AscReadLramByte(iop_base,
10495                                             (ushort) ASCV_SCSIBUSY_B);
10496                 scsi_busy |= target_id;
10497                 AscWriteLramByte(iop_base,
10498                                  (ushort) ASCV_SCSIBUSY_B, scsi_busy);
10499                 asc_dvc->queue_full_or_busy |= target_id;
10500     
10501                 if (scsi_status == SS_QUEUE_FULL) {
10502                     if (cur_dvc_qng > ASC_MIN_TAGGED_CMD) {
10503                         cur_dvc_qng -= 1;
10504                         asc_dvc->max_dvc_qng[tid_no] = cur_dvc_qng;
10505     
10506                         AscWriteLramByte(iop_base,
10507                               (ushort) ((ushort) ASCV_MAX_DVC_QNG_BEG +
10508                                (ushort) tid_no),
10509                               cur_dvc_qng);
10510     
10511                         /*
10512                          * Set the device queue depth to the number of
10513                          * active requests when the QUEUE FULL condition
10514                          * was encountered.
10515                          */
10516                         boardp->queue_full |= target_id;
10517                         boardp->queue_full_cnt[tid_no] = cur_dvc_qng;
10518                     }
10519                 }
10520             }
10521             AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10522             return (0);
10523         }
10524     #if CC_VERY_LONG_SG_LIST
10525         else if (int_halt_code == ASC_HALT_HOST_COPY_SG_LIST_TO_RISC)
10526         {
10527             uchar              q_no;
10528             ushort             q_addr;
10529             uchar              sg_wk_q_no;
10530             uchar              first_sg_wk_q_no;
10531             ASC_SCSI_Q         *scsiq; /* Ptr to driver request. */
10532             ASC_SG_HEAD        *sg_head; /* Ptr to driver SG request. */
10533             ASC_SG_LIST_Q      scsi_sg_q; /* Structure written to queue. */
10534             ushort             sg_list_dwords;
10535             ushort             sg_entry_cnt;
10536             uchar              next_qp;
10537             int                i;
10538     
10539             q_no = AscReadLramByte(iop_base, (ushort) ASCV_REQ_SG_LIST_QP);
10540             if (q_no == ASC_QLINK_END)
10541             {
10542                 return(0);
10543             }
10544     
10545             q_addr = ASC_QNO_TO_QADDR(q_no);
10546     
10547             /*
10548              * Convert the request's SRB pointer to a host ASC_SCSI_REQ
10549              * structure pointer using a macro provided by the driver.
10550              * The ASC_SCSI_REQ pointer provides a pointer to the
10551              * host ASC_SG_HEAD structure.
10552              */
10553             /* Read request's SRB pointer. */
10554             scsiq = (ASC_SCSI_Q *)
10555                ASC_SRB2SCSIQ(
10556                    ASC_U32_TO_VADDR(AscReadLramDWord(iop_base,
10557                    (ushort) (q_addr + ASC_SCSIQ_D_SRBPTR))));
10558     
10559             /*
10560              * Get request's first and working SG queue.
10561              */
10562             sg_wk_q_no = AscReadLramByte(iop_base,
10563                 (ushort) (q_addr + ASC_SCSIQ_B_SG_WK_QP));
10564     
10565             first_sg_wk_q_no = AscReadLramByte(iop_base,
10566                 (ushort) (q_addr + ASC_SCSIQ_B_FIRST_SG_WK_QP));
10567     
10568             /*
10569              * Reset request's working SG queue back to the
10570              * first SG queue.
10571              */
10572             AscWriteLramByte(iop_base,
10573                 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_SG_WK_QP),
10574                 first_sg_wk_q_no);
10575     
10576             sg_head = scsiq->sg_head;
10577     
10578             /*
10579              * Set sg_entry_cnt to the number of SG elements
10580              * that will be completed on this interrupt.
10581              *
10582              * Note: The allocated SG queues contain ASC_MAX_SG_LIST - 1
10583              * SG elements. The data_cnt and data_addr fields which
10584              * add 1 to the SG element capacity are not used when
10585              * restarting SG handling after a halt.
10586              */
10587             if (scsiq->remain_sg_entry_cnt > (ASC_MAX_SG_LIST - 1))
10588             {
10589                  sg_entry_cnt = ASC_MAX_SG_LIST - 1;
10590     
10591                  /*
10592                   * Keep track of remaining number of SG elements that will
10593                   * need to be handled on the next interrupt.
10594                   */
10595                  scsiq->remain_sg_entry_cnt -= (ASC_MAX_SG_LIST - 1);
10596             } else
10597             {
10598                  sg_entry_cnt = scsiq->remain_sg_entry_cnt;
10599                  scsiq->remain_sg_entry_cnt = 0;
10600             }
10601     
10602             /*
10603              * Copy SG elements into the list of allocated SG queues.
10604              *
10605              * Last index completed is saved in scsiq->next_sg_index.
10606              */
10607             next_qp = first_sg_wk_q_no;
10608             q_addr = ASC_QNO_TO_QADDR(next_qp);
10609             scsi_sg_q.sg_head_qp = q_no;
10610             scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
10611             for( i = 0; i < sg_head->queue_cnt; i++)
10612             {
10613                  scsi_sg_q.seq_no = i + 1;
10614                  if (sg_entry_cnt > ASC_SG_LIST_PER_Q)
10615                  {
10616                      sg_list_dwords = (uchar) (ASC_SG_LIST_PER_Q * 2);
10617                      sg_entry_cnt -= ASC_SG_LIST_PER_Q;
10618                      /*
10619                       * After very first SG queue RISC FW uses next
10620                       * SG queue first element then checks sg_list_cnt
10621                       * against zero and then decrements, so set
10622                       * sg_list_cnt 1 less than number of SG elements
10623                       * in each SG queue.
10624                       */
10625                      scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q - 1;
10626                      scsi_sg_q.sg_cur_list_cnt = ASC_SG_LIST_PER_Q - 1;
10627                  } else {
10628                      /*
10629                       * This is the last SG queue in the list of
10630                       * allocated SG queues. If there are more
10631                       * SG elements than will fit in the allocated
10632                       * queues, then set the QCSG_SG_XFER_MORE flag.
10633                       */
10634                      if (scsiq->remain_sg_entry_cnt != 0)
10635                      {
10636                          scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
10637                      } else
10638                      {
10639                          scsi_sg_q.cntl |= QCSG_SG_XFER_END;
10640                      }
10641                      /* equals sg_entry_cnt * 2 */
10642                      sg_list_dwords = sg_entry_cnt << 1;
10643                      scsi_sg_q.sg_list_cnt = sg_entry_cnt - 1;
10644                      scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt - 1;
10645                      sg_entry_cnt = 0;
10646                  }
10647     
10648                  scsi_sg_q.q_no = next_qp;
10649                  AscMemWordCopyPtrToLram(iop_base,
10650                               q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
10651                               (uchar *) &scsi_sg_q,
10652                               sizeof(ASC_SG_LIST_Q) >> 1);
10653     
10654                  AscMemDWordCopyPtrToLram(iop_base,
10655                               q_addr + ASC_SGQ_LIST_BEG,
10656                               (uchar *) &sg_head->sg_list[scsiq->next_sg_index],
10657                               sg_list_dwords);
10658     
10659                  scsiq->next_sg_index += ASC_SG_LIST_PER_Q;
10660     
10661                  /*
10662                   * If the just completed SG queue contained the
10663                   * last SG element, then no more SG queues need
10664                   * to be written.
10665                   */
10666                  if (scsi_sg_q.cntl & QCSG_SG_XFER_END)
10667                  {
10668                      break;
10669                  }
10670     
10671                  next_qp = AscReadLramByte( iop_base,
10672                               ( ushort )( q_addr+ASC_SCSIQ_B_FWD ) );
10673                  q_addr = ASC_QNO_TO_QADDR( next_qp );
10674             }
10675     
10676             /*
10677              * Clear the halt condition so the RISC will be restarted
10678              * after the return.
10679              */
10680             AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10681             return(0);
10682         }
10683     #endif /* CC_VERY_LONG_SG_LIST */
10684         return (0);
10685     }
10686     
10687     STATIC uchar
10688     _AscCopyLramScsiDoneQ(
10689                              PortAddr iop_base,
10690                              ushort q_addr,
10691                              ASC_QDONE_INFO * scsiq,
10692                              ASC_DCNT max_dma_count
10693     )
10694     {
10695         ushort              _val;
10696         uchar               sg_queue_cnt;
10697     
10698         DvcGetQinfo(iop_base,
10699                     q_addr + ASC_SCSIQ_DONE_INFO_BEG,
10700                     (uchar *) scsiq,
10701                     (sizeof (ASC_SCSIQ_2) + sizeof (ASC_SCSIQ_3)) / 2);
10702     
10703         _val = AscReadLramWord(iop_base,
10704                                (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS));
10705         scsiq->q_status = (uchar) _val;
10706         scsiq->q_no = (uchar) (_val >> 8);
10707         _val = AscReadLramWord(iop_base,
10708                                (ushort) (q_addr + (ushort) ASC_SCSIQ_B_CNTL));
10709         scsiq->cntl = (uchar) _val;
10710         sg_queue_cnt = (uchar) (_val >> 8);
10711         _val = AscReadLramWord(iop_base,
10712                             (ushort) (q_addr + (ushort) ASC_SCSIQ_B_SENSE_LEN));
10713         scsiq->sense_len = (uchar) _val;
10714         scsiq->extra_bytes = (uchar) (_val >> 8);
10715     
10716         /*
10717          * Read high word of remain bytes from alternate location.
10718          */
10719         scsiq->remain_bytes = (((ADV_DCNT) AscReadLramWord( iop_base,
10720                           (ushort) (q_addr+ (ushort) ASC_SCSIQ_W_ALT_DC1))) << 16);
10721         /*
10722          * Read low word of remain bytes from original location.
10723          */
10724         scsiq->remain_bytes += AscReadLramWord(iop_base,
10725             (ushort) (q_addr+ (ushort) ASC_SCSIQ_DW_REMAIN_XFER_CNT));
10726     
10727         scsiq->remain_bytes &= max_dma_count;
10728         return (sg_queue_cnt);
10729     }
10730     
10731     STATIC int
10732     AscIsrQDone(
10733                    ASC_DVC_VAR *asc_dvc
10734     )
10735     {
10736         uchar               next_qp;
10737         uchar               n_q_used;
10738         uchar               sg_list_qp;
10739         uchar               sg_queue_cnt;
10740         uchar               q_cnt;
10741         uchar               done_q_tail;
10742         uchar               tid_no;
10743         ASC_SCSI_BIT_ID_TYPE scsi_busy;
10744         ASC_SCSI_BIT_ID_TYPE target_id;
10745         PortAddr            iop_base;
10746         ushort              q_addr;
10747         ushort              sg_q_addr;
10748         uchar               cur_target_qng;
10749         ASC_QDONE_INFO      scsiq_buf;
10750         ASC_QDONE_INFO *scsiq;
10751         int                 false_overrun;
10752         ASC_ISR_CALLBACK    asc_isr_callback;
10753     
10754         iop_base = asc_dvc->iop_base;
10755         asc_isr_callback = asc_dvc->isr_callback;
10756         n_q_used = 1;
10757         scsiq = (ASC_QDONE_INFO *) & scsiq_buf;
10758         done_q_tail = (uchar) AscGetVarDoneQTail(iop_base);
10759         q_addr = ASC_QNO_TO_QADDR(done_q_tail);
10760         next_qp = AscReadLramByte(iop_base,
10761                                   (ushort) (q_addr + (ushort) ASC_SCSIQ_B_FWD));
10762         if (next_qp != ASC_QLINK_END) {
10763             AscPutVarDoneQTail(iop_base, next_qp);
10764             q_addr = ASC_QNO_TO_QADDR(next_qp);
10765             sg_queue_cnt = _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq,
10766                 asc_dvc->max_dma_count);
10767             AscWriteLramByte(iop_base,
10768                              (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS),
10769                  (uchar) (scsiq->q_status & (uchar) ~ (QS_READY | QS_ABORTED)));
10770             tid_no = ASC_TIX_TO_TID(scsiq->d2.target_ix);
10771             target_id = ASC_TIX_TO_TARGET_ID(scsiq->d2.target_ix);
10772             if ((scsiq->cntl & QC_SG_HEAD) != 0) {
10773                 sg_q_addr = q_addr;
10774                 sg_list_qp = next_qp;
10775                 for (q_cnt = 0; q_cnt < sg_queue_cnt; q_cnt++) {
10776                     sg_list_qp = AscReadLramByte(iop_base,
10777                                (ushort) (sg_q_addr + (ushort) ASC_SCSIQ_B_FWD));
10778                     sg_q_addr = ASC_QNO_TO_QADDR(sg_list_qp);
10779                     if (sg_list_qp == ASC_QLINK_END) {
10780                         AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SG_Q_LINKS);
10781                         scsiq->d3.done_stat = QD_WITH_ERROR;
10782                         scsiq->d3.host_stat = QHSTA_D_QDONE_SG_LIST_CORRUPTED;
10783                         goto FATAL_ERR_QDONE;
10784                     }
10785                     AscWriteLramByte(iop_base,
10786                              (ushort) (sg_q_addr + (ushort) ASC_SCSIQ_B_STATUS),
10787                                      QS_FREE);
10788                 }
10789                 n_q_used = sg_queue_cnt + 1;
10790                 AscPutVarDoneQTail(iop_base, sg_list_qp);
10791             }
10792             if (asc_dvc->queue_full_or_busy & target_id) {
10793                 cur_target_qng = AscReadLramByte(iop_base,
10794                 (ushort) ((ushort) ASC_QADR_BEG + (ushort) scsiq->d2.target_ix));
10795                 if (cur_target_qng < asc_dvc->max_dvc_qng[tid_no]) {
10796                     scsi_busy = AscReadLramByte(iop_base,
10797                                                 (ushort) ASCV_SCSIBUSY_B);
10798                     scsi_busy &= ~target_id;
10799                     AscWriteLramByte(iop_base,
10800                                      (ushort) ASCV_SCSIBUSY_B, scsi_busy);
10801                     asc_dvc->queue_full_or_busy &= ~target_id;
10802                 }
10803             }
10804             if (asc_dvc->cur_total_qng >= n_q_used) {
10805                 asc_dvc->cur_total_qng -= n_q_used;
10806                 if (asc_dvc->cur_dvc_qng[tid_no] != 0) {
10807                     asc_dvc->cur_dvc_qng[tid_no]--;
10808                 }
10809             } else {
10810                 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CUR_QNG);
10811                 scsiq->d3.done_stat = QD_WITH_ERROR;
10812                 goto FATAL_ERR_QDONE;
10813             }
10814             if ((scsiq->d2.srb_ptr == 0UL) ||
10815                 ((scsiq->q_status & QS_ABORTED) != 0)) {
10816                 return (0x11);
10817             } else if (scsiq->q_status == QS_DONE) {
10818                 false_overrun = FALSE;
10819                 if (scsiq->extra_bytes != 0) {
10820                     scsiq->remain_bytes += (ADV_DCNT) scsiq->extra_bytes;
10821                 }
10822                 if (scsiq->d3.done_stat == QD_WITH_ERROR) {
10823                     if (scsiq->d3.host_stat == QHSTA_M_DATA_OVER_RUN) {
10824                         if ((scsiq->cntl & (QC_DATA_IN | QC_DATA_OUT)) == 0) {
10825                             scsiq->d3.done_stat = QD_NO_ERROR;
10826                             scsiq->d3.host_stat = QHSTA_NO_ERROR;
10827                         } else if (false_overrun) {
10828                             scsiq->d3.done_stat = QD_NO_ERROR;
10829                             scsiq->d3.host_stat = QHSTA_NO_ERROR;
10830                         }
10831                     } else if (scsiq->d3.host_stat ==
10832                                QHSTA_M_HUNG_REQ_SCSI_BUS_RESET) {
10833                         AscStopChip(iop_base);
10834                         AscSetChipControl(iop_base,
10835                             (uchar) (CC_SCSI_RESET | CC_HALT));
10836                         DvcDelayNanoSecond(asc_dvc, 60000);
10837                         AscSetChipControl(iop_base, CC_HALT);
10838                         AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
10839                         AscSetChipStatus(iop_base, 0);
10840                         AscSetChipControl(iop_base, 0);
10841                     }
10842                 }
10843                 if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
10844                     (*asc_isr_callback) (asc_dvc, scsiq);
10845                 } else {
10846                     if ((AscReadLramByte(iop_base,
10847                               (ushort) (q_addr + (ushort) ASC_SCSIQ_CDB_BEG)) ==
10848                          SCSICMD_StartStopUnit)) {
10849                         asc_dvc->unit_not_ready &= ~target_id;
10850                         if (scsiq->d3.done_stat != QD_NO_ERROR) {
10851                             asc_dvc->start_motor &= ~target_id;
10852                         }
10853                     }
10854                 }
10855                 return (1);
10856             } else {
10857                 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_Q_STATUS);
10858               FATAL_ERR_QDONE:
10859                 if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
10860                     (*asc_isr_callback) (asc_dvc, scsiq);
10861                 }
10862                 return (0x80);
10863             }
10864         }
10865         return (0);
10866     }
10867     
10868     STATIC int
10869     AscISR(
10870               ASC_DVC_VAR *asc_dvc
10871     )
10872     {
10873         ASC_CS_TYPE         chipstat;
10874         PortAddr            iop_base;
10875         ushort              saved_ram_addr;
10876         uchar               ctrl_reg;
10877         uchar               saved_ctrl_reg;
10878         int                 int_pending;
10879         int                 status;
10880         uchar               host_flag;
10881     
10882         iop_base = asc_dvc->iop_base;
10883         int_pending = FALSE;
10884     
10885         if (AscIsIntPending(iop_base) == 0)
10886         {
10887             return int_pending;
10888         }
10889     
10890         if (((asc_dvc->init_state & ASC_INIT_STATE_END_LOAD_MC) == 0)
10891             || (asc_dvc->isr_callback == 0)
10892     ) {
10893             return (ERR);
10894         }
10895         if (asc_dvc->in_critical_cnt != 0) {
10896             AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_ON_CRITICAL);
10897             return (ERR);
10898         }
10899         if (asc_dvc->is_in_int) {
10900             AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_RE_ENTRY);
10901             return (ERR);
10902         }
10903         asc_dvc->is_in_int = TRUE;
10904         ctrl_reg = AscGetChipControl(iop_base);
10905         saved_ctrl_reg = ctrl_reg & (~(CC_SCSI_RESET | CC_CHIP_RESET |
10906                                        CC_SINGLE_STEP | CC_DIAG | CC_TEST));
10907         chipstat = AscGetChipStatus(iop_base);
10908         if (chipstat & CSW_SCSI_RESET_LATCH) {
10909             if (!(asc_dvc->bus_type & (ASC_IS_VL | ASC_IS_EISA))) {
10910                 int i = 10;
10911                 int_pending = TRUE;
10912                 asc_dvc->sdtr_done = 0;
10913                 saved_ctrl_reg &= (uchar) (~CC_HALT);
10914                 while ((AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE) &&
10915                        (i-- > 0))
10916                 {
10917                       DvcSleepMilliSecond(100);
10918                 }
10919                 AscSetChipControl(iop_base, (CC_CHIP_RESET | CC_HALT));
10920                 AscSetChipControl(iop_base, CC_HALT);
10921                 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
10922                 AscSetChipStatus(iop_base, 0);
10923                 chipstat = AscGetChipStatus(iop_base);
10924             }
10925         }
10926         saved_ram_addr = AscGetChipLramAddr(iop_base);
10927         host_flag = AscReadLramByte(iop_base,
10928             ASCV_HOST_FLAG_B) & (uchar) (~ASC_HOST_FLAG_IN_ISR);
10929         AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
10930                          (uchar) (host_flag | (uchar) ASC_HOST_FLAG_IN_ISR));
10931         if ((chipstat & CSW_INT_PENDING)
10932             || (int_pending)
10933     ) {
10934             AscAckInterrupt(iop_base);
10935             int_pending = TRUE;
10936             if ((chipstat & CSW_HALTED) &&
10937                 (ctrl_reg & CC_SINGLE_STEP)) {
10938                 if (AscIsrChipHalted(asc_dvc) == ERR) {
10939                     goto ISR_REPORT_QDONE_FATAL_ERROR;
10940                 } else {
10941                     saved_ctrl_reg &= (uchar) (~CC_HALT);
10942                 }
10943             } else {
10944               ISR_REPORT_QDONE_FATAL_ERROR:
10945                 if ((asc_dvc->dvc_cntl & ASC_CNTL_INT_MULTI_Q) != 0) {
10946                     while (((status = AscIsrQDone(asc_dvc)) & 0x01) != 0) {
10947                     }
10948                 } else {
10949                     do {
10950                         if ((status = AscIsrQDone(asc_dvc)) == 1) {
10951                             break;
10952                         }
10953                     } while (status == 0x11);
10954                 }
10955                 if ((status & 0x80) != 0)
10956                     int_pending = ERR;
10957             }
10958         }
10959         AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
10960         AscSetChipLramAddr(iop_base, saved_ram_addr);
10961         AscSetChipControl(iop_base, saved_ctrl_reg);
10962         asc_dvc->is_in_int = FALSE;
10963         return (int_pending);
10964     }
10965     
10966     /* Microcode buffer is kept after initialization for error recovery. */
10967     STATIC uchar _asc_mcode_buf[] =
10968     {
10969       0x01,  0x03,  0x01,  0x19,  0x0F,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
10970       0x0F,  0x0F,  0x0F,  0x0F,  0x0F,  0x0F,  0x0F,  0x0F,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
10971       0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
10972       0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
10973       0x00,  0x00,  0x00,  0x00,  0xC3,  0x12,  0x0D,  0x05,  0x01,  0x00,  0x00,  0x00,  0x00,  0xFF,  0x00,  0x00,
10974       0x00,  0x00,  0x00,  0x00,  0xFF,  0x80,  0xFF,  0xFF,  0x01,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
10975       0x00,  0x00,  0x00,  0x23,  0x00,  0x00,  0x00,  0x00,  0x00,  0x07,  0x00,  0xFF,  0x00,  0x00,  0x00,  0x00,
10976       0xFF,  0xFF,  0xFF,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xE4,  0x88,  0x00,  0x00,  0x00,  0x00,
10977       0x80,  0x73,  0x48,  0x04,  0x36,  0x00,  0x00,  0xA2,  0xC2,  0x00,  0x80,  0x73,  0x03,  0x23,  0x36,  0x40,
10978       0xB6,  0x00,  0x36,  0x00,  0x05,  0xD6,  0x0C,  0xD2,  0x12,  0xDA,  0x00,  0xA2,  0xC2,  0x00,  0x92,  0x80,
10979       0x1E,  0x98,  0x50,  0x00,  0xF5,  0x00,  0x48,  0x98,  0xDF,  0x23,  0x36,  0x60,  0xB6,  0x00,  0x92,  0x80,
10980       0x4F,  0x00,  0xF5,  0x00,  0x48,  0x98,  0xEF,  0x23,  0x36,  0x60,  0xB6,  0x00,  0x92,  0x80,  0x80,  0x62,
10981       0x92,  0x80,  0x00,  0x46,  0x15,  0xEE,  0x13,  0xEA,  0x02,  0x01,  0x09,  0xD8,  0xCD,  0x04,  0x4D,  0x00,
10982       0x00,  0xA3,  0xD6,  0x00,  0xA6,  0x97,  0x7F,  0x23,  0x04,  0x61,  0x84,  0x01,  0xE6,  0x84,  0xD2,  0xC1,
10983       0x80,  0x73,  0xCD,  0x04,  0x4D,  0x00,  0x00,  0xA3,  0xDA,  0x01,  0xA6,  0x97,  0xC6,  0x81,  0xC2,  0x88,
10984       0x80,  0x73,  0x80,  0x77,  0x00,  0x01,  0x01,  0xA1,  0xFE,  0x00,  0x4F,  0x00,  0x84,  0x97,  0x07,  0xA6,
10985       0x08,  0x01,  0x00,  0x33,  0x03,  0x00,  0xC2,  0x88,  0x03,  0x03,  0x01,  0xDE,  0xC2,  0x88,  0xCE,  0x00,
10986       0x69,  0x60,  0xCE,  0x00,  0x02,  0x03,  0x4A,  0x60,  0x00,  0xA2,  0x78,  0x01,  0x80,  0x63,  0x07,  0xA6,
10987       0x24,  0x01,  0x78,  0x81,  0x03,  0x03,  0x80,  0x63,  0xE2,  0x00,  0x07,  0xA6,  0x34,  0x01,  0x00,  0x33,
10988       0x04,  0x00,  0xC2,  0x88,  0x03,  0x07,  0x02,  0x01,  0x04,  0xCA,  0x0D,  0x23,  0x68,  0x98,  0x4D,  0x04,
10989       0x04,  0x85,  0x05,  0xD8,  0x0D,  0x23,  0x68,  0x98,  0xCD,  0x04,  0x15,  0x23,  0xF8,  0x88,  0xFB,  0x23,
10990       0x02,  0x61,  0x82,  0x01,  0x80,  0x63,  0x02,  0x03,  0x06,  0xA3,  0x62,  0x01,  0x00,  0x33,  0x0A,  0x00,
10991       0xC2,  0x88,  0x4E,  0x00,  0x07,  0xA3,  0x6E,  0x01,  0x00,  0x33,  0x0B,  0x00,  0xC2,  0x88,  0xCD,  0x04,
10992       0x36,  0x2D,  0x00,  0x33,  0x1A,  0x00,  0xC2,  0x88,  0x50,  0x04,  0x88,  0x81,  0x06,  0xAB,  0x82,  0x01,
10993       0x88,  0x81,  0x4E,  0x00,  0x07,  0xA3,  0x92,  0x01,  0x50,  0x00,  0x00,  0xA3,  0x3C,  0x01,  0x00,  0x05,
10994       0x7C,  0x81,  0x46,  0x97,  0x02,  0x01,  0x05,  0xC6,  0x04,  0x23,  0xA0,  0x01,  0x15,  0x23,  0xA1,  0x01,
10995       0xBE,  0x81,  0xFD,  0x23,  0x02,  0x61,  0x82,  0x01,  0x0A,  0xDA,  0x4A,  0x00,  0x06,  0x61,  0x00,  0xA0,
10996       0xB4,  0x01,  0x80,  0x63,  0xCD,  0x04,  0x36,  0x2D,  0x00,  0x33,  0x1B,  0x00,  0xC2,  0x88,  0x06,  0x23,
10997       0x68,  0x98,  0xCD,  0x04,  0xE6,  0x84,  0x06,  0x01,  0x00,  0xA2,  0xD4,  0x01,  0x57,  0x60,  0x00,  0xA0,
10998       0xDA,  0x01,  0xE6,  0x84,  0x80,  0x23,  0xA0,  0x01,  0xE6,  0x84,  0x80,  0x73,  0x4B,  0x00,  0x06,  0x61,
10999       0x00,  0xA2,  0x00,  0x02,  0x04,  0x01,  0x0C,  0xDE,  0x02,  0x01,  0x03,  0xCC,  0x4F,  0x00,  0x84,  0x97,
11000       0xFC,  0x81,  0x08,  0x23,  0x02,  0x41,  0x82,  0x01,  0x4F,  0x00,  0x62,  0x97,  0x48,  0x04,  0x84,  0x80,
11001       0xF0,  0x97,  0x00,  0x46,  0x56,  0x00,  0x03,  0xC0,  0x01,  0x23,  0xE8,  0x00,  0x81,  0x73,  0x06,  0x29,
11002       0x03,  0x42,  0x06,  0xE2,  0x03,  0xEE,  0x6B,  0xEB,  0x11,  0x23,  0xF8,  0x88,  0x04,  0x98,  0xF0,  0x80,
11003       0x80,  0x73,  0x80,  0x77,  0x07,  0xA4,  0x2A,  0x02,  0x7C,  0x95,  0x06,  0xA6,  0x34,  0x02,  0x03,  0xA6,
11004       0x4C,  0x04,  0x46,  0x82,  0x04,  0x01,  0x03,  0xD8,  0xB4,  0x98,  0x6A,  0x96,  0x46,  0x82,  0xFE,  0x95,
11005       0x80,  0x67,  0x83,  0x03,  0x80,  0x63,  0xB6,  0x2D,  0x02,  0xA6,  0x6C,  0x02,  0x07,  0xA6,  0x5A,  0x02,
11006       0x06,  0xA6,  0x5E,  0x02,  0x03,  0xA6,  0x62,  0x02,  0xC2,  0x88,  0x7C,  0x95,  0x48,  0x82,  0x60,  0x96,
11007       0x48,  0x82,  0x04,  0x23,  0xA0,  0x01,  0x14,  0x23,  0xA1,  0x01,  0x3C,  0x84,  0x04,  0x01,  0x0C,  0xDC,
11008       0xE0,  0x23,  0x25,  0x61,  0xEF,  0x00,  0x14,  0x01,  0x4F,  0x04,  0xA8,  0x01,  0x6F,  0x00,  0xA5,  0x01,
11009       0x03,  0x23,  0xA4,  0x01,  0x06,  0x23,  0x9C,  0x01,  0x24,  0x2B,  0x1C,  0x01,  0x02,  0xA6,  0xAA,  0x02,
11010       0x07,  0xA6,  0x5A,  0x02,  0x06,  0xA6,  0x5E,  0x02,  0x03,  0xA6,  0x20,  0x04,  0x01,  0xA6,  0xB4,  0x02,
11011       0x00,  0xA6,  0xB4,  0x02,  0x00,  0x33,  0x12,  0x00,  0xC2,  0x88,  0x00,  0x0E,  0x80,  0x63,  0x00,  0x43,
11012       0x00,  0xA0,  0x8C,  0x02,  0x4D,  0x04,  0x04,  0x01,  0x0B,  0xDC,  0xE7,  0x23,  0x04,  0x61,  0x84,  0x01,
11013       0x10,  0x31,  0x12,  0x35,  0x14,  0x01,  0xEC,  0x00,  0x6C,  0x38,  0x00,  0x3F,  0x00,  0x00,  0xEA,  0x82,
11014       0x18,  0x23,  0x04,  0x61,  0x18,  0xA0,  0xE2,  0x02,  0x04,  0x01,  0xA2,  0xC8,  0x00,  0x33,  0x1F,  0x00,
11015       0xC2,  0x88,  0x08,  0x31,  0x0A,  0x35,  0x0C,  0x39,  0x0E,  0x3D,  0x7E,  0x98,  0xB6,  0x2D,  0x01,  0xA6,
11016       0x14,  0x03,  0x00,  0xA6,  0x14,  0x03,  0x07,  0xA6,  0x0C,  0x03,  0x06,  0xA6,  0x10,  0x03,  0x03,  0xA6,
11017       0x20,  0x04,  0x02,  0xA6,  0x6C,  0x02,  0x00,  0x33,  0x33,  0x00,  0xC2,  0x88,  0x7C,  0x95,  0xEE,  0x82,
11018       0x60,  0x96,  0xEE,  0x82,  0x82,  0x98,  0x80,  0x42,  0x7E,  0x98,  0x64,  0xE4,  0x04,  0x01,  0x2D,  0xC8,
11019       0x31,  0x05,  0x07,  0x01,  0x00,  0xA2,  0x54,  0x03,  0x00,  0x43,  0x87,  0x01,  0x05,  0x05,  0x86,  0x98,
11020       0x7E,  0x98,  0x00,  0xA6,  0x16,  0x03,  0x07,  0xA6,  0x4C,  0x03,  0x03,  0xA6,  0x3C,  0x04,  0x06,  0xA6,
11021       0x50,  0x03,  0x01,  0xA6,  0x16,  0x03,  0x00,  0x33,  0x25,  0x00,  0xC2,  0x88,  0x7C,  0x95,  0x32,  0x83,
11022       0x60,  0x96,  0x32,  0x83,  0x04,  0x01,  0x10,  0xCE,  0x07,  0xC8,  0x05,  0x05,  0xEB,  0x04,  0x00,  0x33,
11023       0x00,  0x20,  0xC0,  0x20,  0x81,  0x62,  0x72,  0x83,  0x00,  0x01,  0x05,  0x05,  0xFF,  0xA2,  0x7A,  0x03,
11024       0xB1,  0x01,  0x08,  0x23,  0xB2,  0x01,  0x2E,  0x83,  0x05,  0x05,  0x15,  0x01,  0x00,  0xA2,  0x9A,  0x03,
11025       0xEC,  0x00,  0x6E,  0x00,  0x95,  0x01,  0x6C,  0x38,  0x00,  0x3F,  0x00,  0x00,  0x01,  0xA6,  0x96,  0x03,
11026       0x00,  0xA6,  0x96,  0x03,  0x10,  0x84,  0x80,  0x42,  0x7E,  0x98,  0x01,  0xA6,  0xA4,  0x03,  0x00,  0xA6,
11027       0xBC,  0x03,  0x10,  0x84,  0xA8,  0x98,  0x80,  0x42,  0x01,  0xA6,  0xA4,  0x03,  0x07,  0xA6,  0xB2,  0x03,
11028       0xD4,  0x83,  0x7C,  0x95,  0xA8,  0x83,  0x00,  0x33,  0x2F,  0x00,  0xC2,  0x88,  0xA8,  0x98,  0x80,  0x42,
11029       0x00,  0xA6,  0xBC,  0x03,  0x07,  0xA6,  0xCA,  0x03,  0xD4,  0x83,  0x7C,  0x95,  0xC0,  0x83,  0x00,  0x33,
11030       0x26,  0x00,  0xC2,  0x88,  0x38,  0x2B,  0x80,  0x32,  0x80,  0x36,  0x04,  0x23,  0xA0,  0x01,  0x12,  0x23,
11031       0xA1,  0x01,  0x10,  0x84,  0x07,  0xF0,  0x06,  0xA4,  0xF4,  0x03,  0x80,  0x6B,  0x80,  0x67,  0x05,  0x23,
11032       0x83,  0x03,  0x80,  0x63,  0x03,  0xA6,  0x0E,  0x04,  0x07,  0xA6,  0x06,  0x04,  0x06,  0xA6,  0x0A,  0x04,
11033       0x00,  0x33,  0x17,  0x00,  0xC2,  0x88,  0x7C,  0x95,  0xF4,  0x83,  0x60,  0x96,  0xF4,  0x83,  0x20,  0x84,
11034       0x07,  0xF0,  0x06,  0xA4,  0x20,  0x04,  0x80,  0x6B,  0x80,  0x67,  0x05,  0x23,  0x83,  0x03,  0x80,  0x63,
11035       0xB6,  0x2D,  0x03,  0xA6,  0x3C,  0x04,  0x07,  0xA6,  0x34,  0x04,  0x06,  0xA6,  0x38,  0x04,  0x00,  0x33,
11036       0x30,  0x00,  0xC2,  0x88,  0x7C,  0x95,  0x20,  0x84,  0x60,  0x96,  0x20,  0x84,  0x1D,  0x01,  0x06,  0xCC,
11037       0x00,  0x33,  0x00,  0x84,  0xC0,  0x20,  0x00,  0x23,  0xEA,  0x00,  0x81,  0x62,  0xA2,  0x0D,  0x80,  0x63,
11038       0x07,  0xA6,  0x5A,  0x04,  0x00,  0x33,  0x18,  0x00,  0xC2,  0x88,  0x03,  0x03,  0x80,  0x63,  0xA3,  0x01,
11039       0x07,  0xA4,  0x64,  0x04,  0x23,  0x01,  0x00,  0xA2,  0x86,  0x04,  0x0A,  0xA0,  0x76,  0x04,  0xE0,  0x00,
11040       0x00,  0x33,  0x1D,  0x00,  0xC2,  0x88,  0x0B,  0xA0,  0x82,  0x04,  0xE0,  0x00,  0x00,  0x33,  0x1E,  0x00,
11041       0xC2,  0x88,  0x42,  0x23,  0xF8,  0x88,  0x00,  0x23,  0x22,  0xA3,  0xE6,  0x04,  0x08,  0x23,  0x22,  0xA3,
11042       0xA2,  0x04,  0x28,  0x23,  0x22,  0xA3,  0xAE,  0x04,  0x02,  0x23,  0x22,  0xA3,  0xC4,  0x04,  0x42,  0x23,
11043       0xF8,  0x88,  0x4A,  0x00,  0x06,  0x61,  0x00,  0xA0,  0xAE,  0x04,  0x45,  0x23,  0xF8,  0x88,  0x04,  0x98,
11044       0x00,  0xA2,  0xC0,  0x04,  0xB4,  0x98,  0x00,  0x33,  0x00,  0x82,  0xC0,  0x20,  0x81,  0x62,  0xE8,  0x81,
11045       0x47,  0x23,  0xF8,  0x88,  0x04,  0x01,  0x0B,  0xDE,  0x04,  0x98,  0xB4,  0x98,  0x00,  0x33,  0x00,  0x81,
11046       0xC0,  0x20,  0x81,  0x62,  0x14,  0x01,  0x00,  0xA0,  0x00,  0x02,  0x43,  0x23,  0xF8,  0x88,  0x04,  0x23,
11047       0xA0,  0x01,  0x44,  0x23,  0xA1,  0x01,  0x80,  0x73,  0x4D,  0x00,  0x03,  0xA3,  0xF4,  0x04,  0x00,  0x33,
11048       0x27,  0x00,  0xC2,  0x88,  0x04,  0x01,  0x04,  0xDC,  0x02,  0x23,  0xA2,  0x01,  0x04,  0x23,  0xA0,  0x01,
11049       0x04,  0x98,  0x26,  0x95,  0x4B,  0x00,  0xF6,  0x00,  0x4F,  0x04,  0x4F,  0x00,  0x00,  0xA3,  0x22,  0x05,
11050       0x00,  0x05,  0x76,  0x00,  0x06,  0x61,  0x00,  0xA2,  0x1C,  0x05,  0x0A,  0x85,  0x46,  0x97,  0xCD,  0x04,
11051       0x24,  0x85,  0x48,  0x04,  0x84,  0x80,  0x02,  0x01,  0x03,  0xDA,  0x80,  0x23,  0x82,  0x01,  0x34,  0x85,
11052       0x02,  0x23,  0xA0,  0x01,  0x4A,  0x00,  0x06,  0x61,  0x00,  0xA2,  0x40,  0x05,  0x1D,  0x01,  0x04,  0xD6,
11053       0xFF,  0x23,  0x86,  0x41,  0x4B,  0x60,  0xCB,  0x00,  0xFF,  0x23,  0x80,  0x01,  0x49,  0x00,  0x81,  0x01,
11054       0x04,  0x01,  0x02,  0xC8,  0x30,  0x01,  0x80,  0x01,  0xF7,  0x04,  0x03,  0x01,  0x49,  0x04,  0x80,  0x01,
11055       0xC9,  0x00,  0x00,  0x05,  0x00,  0x01,  0xFF,  0xA0,  0x60,  0x05,  0x77,  0x04,  0x01,  0x23,  0xEA,  0x00,
11056       0x5D,  0x00,  0xFE,  0xC7,  0x00,  0x62,  0x00,  0x23,  0xEA,  0x00,  0x00,  0x63,  0x07,  0xA4,  0xF8,  0x05,
11057       0x03,  0x03,  0x02,  0xA0,  0x8E,  0x05,  0xF4,  0x85,  0x00,  0x33,  0x2D,  0x00,  0xC2,  0x88,  0x04,  0xA0,
11058       0xB8,  0x05,  0x80,  0x63,  0x00,  0x23,  0xDF,  0x00,  0x4A,  0x00,  0x06,  0x61,  0x00,  0xA2,  0xA4,  0x05,
11059       0x1D,  0x01,  0x06,  0xD6,  0x02,  0x23,  0x02,  0x41,  0x82,  0x01,  0x50,  0x00,  0x62,  0x97,  0x04,  0x85,
11060       0x04,  0x23,  0x02,  0x41,  0x82,  0x01,  0x04,  0x85,  0x08,  0xA0,  0xBE,  0x05,  0xF4,  0x85,  0x03,  0xA0,
11061       0xC4,  0x05,  0xF4,  0x85,  0x01,  0xA0,  0xCE,  0x05,  0x88,  0x00,  0x80,  0x63,  0xCC,  0x86,  0x07,  0xA0,
11062       0xEE,  0x05,  0x5F,  0x00,  0x00,  0x2B,  0xDF,  0x08,  0x00,  0xA2,  0xE6,  0x05,  0x80,  0x67,  0x80,  0x63,
11063       0x01,  0xA2,  0x7A,  0x06,  0x7C,  0x85,  0x06,  0x23,  0x68,  0x98,  0x48,  0x23,  0xF8,  0x88,  0x07,  0x23,
11064       0x80,  0x00,  0x06,  0x87,  0x80,  0x63,  0x7C,  0x85,  0x00,  0x23,  0xDF,  0x00,  0x00,  0x63,  0x4A,  0x00,
11065       0x06,  0x61,  0x00,  0xA2,  0x36,  0x06,  0x1D,  0x01,  0x16,  0xD4,  0xC0,  0x23,  0x07,  0x41,  0x83,  0x03,
11066       0x80,  0x63,  0x06,  0xA6,  0x1C,  0x06,  0x00,  0x33,  0x37,  0x00,  0xC2,  0x88,  0x1D,  0x01,  0x01,  0xD6,
11067       0x20,  0x23,  0x63,  0x60,  0x83,  0x03,  0x80,  0x63,  0x02,  0x23,  0xDF,  0x00,  0x07,  0xA6,  0x7C,  0x05,
11068       0xEF,  0x04,  0x6F,  0x00,  0x00,  0x63,  0x4B,  0x00,  0x06,  0x41,  0xCB,  0x00,  0x52,  0x00,  0x06,  0x61,
11069       0x00,  0xA2,  0x4E,  0x06,  0x1D,  0x01,  0x03,  0xCA,  0xC0,  0x23,  0x07,  0x41,  0x00,  0x63,  0x1D,  0x01,
11070       0x04,  0xCC,  0x00,  0x33,  0x00,  0x83,  0xC0,  0x20,  0x81,  0x62,  0x80,  0x23,  0x07,  0x41,  0x00,  0x63,
11071       0x80,  0x67,  0x08,  0x23,  0x83,  0x03,  0x80,  0x63,  0x00,  0x63,  0x01,  0x23,  0xDF,  0x00,  0x06,  0xA6,
11072       0x84,  0x06,  0x07,  0xA6,  0x7C,  0x05,  0x80,  0x67,  0x80,  0x63,  0x00,  0x33,  0x00,  0x40,  0xC0,  0x20,
11073       0x81,  0x62,  0x00,  0x63,  0x00,  0x00,  0xFE,  0x95,  0x83,  0x03,  0x80,  0x63,  0x06,  0xA6,  0x94,  0x06,
11074       0x07,  0xA6,  0x7C,  0x05,  0x00,  0x00,  0x01,  0xA0,  0x14,  0x07,  0x00,  0x2B,  0x40,  0x0E,  0x80,  0x63,
11075       0x01,  0x00,  0x06,  0xA6,  0xAA,  0x06,  0x07,  0xA6,  0x7C,  0x05,  0x40,  0x0E,  0x80,  0x63,  0x00,  0x43,
11076       0x00,  0xA0,  0xA2,  0x06,  0x06,  0xA6,  0xBC,  0x06,  0x07,  0xA6,  0x7C,  0x05,  0x80,  0x67,  0x40,  0x0E,
11077       0x80,  0x63,  0x07,  0xA6,  0x7C,  0x05,  0x00,  0x23,  0xDF,  0x00,  0x00,  0x63,  0x07,  0xA6,  0xD6,  0x06,
11078       0x00,  0x33,  0x2A,  0x00,  0xC2,  0x88,  0x03,  0x03,  0x80,  0x63,  0x89,  0x00,  0x0A,  0x2B,  0x07,  0xA6,
11079       0xE8,  0x06,  0x00,  0x33,  0x29,  0x00,  0xC2,  0x88,  0x00,  0x43,  0x00,  0xA2,  0xF4,  0x06,  0xC0,  0x0E,
11080       0x80,  0x63,  0xDE,  0x86,  0xC0,  0x0E,  0x00,  0x33,  0x00,  0x80,  0xC0,  0x20,  0x81,  0x62,  0x04,  0x01,
11081       0x02,  0xDA,  0x80,  0x63,  0x7C,  0x85,  0x80,  0x7B,  0x80,  0x63,  0x06,  0xA6,  0x8C,  0x06,  0x00,  0x33,
11082       0x2C,  0x00,  0xC2,  0x88,  0x0C,  0xA2,  0x2E,  0x07,  0xFE,  0x95,  0x83,  0x03,  0x80,  0x63,  0x06,  0xA6,
11083       0x2C,  0x07,  0x07,  0xA6,  0x7C,  0x05,  0x00,  0x33,  0x3D,  0x00,  0xC2,  0x88,  0x00,  0x00,  0x80,  0x67,
11084       0x83,  0x03,  0x80,  0x63,  0x0C,  0xA0,  0x44,  0x07,  0x07,  0xA6,  0x7C,  0x05,  0xBF,  0x23,  0x04,  0x61,
11085       0x84,  0x01,  0xE6,  0x84,  0x00,  0x63,  0xF0,  0x04,  0x01,  0x01,  0xF1,  0x00,  0x00,  0x01,  0xF2,  0x00,
11086       0x01,  0x05,  0x80,  0x01,  0x72,  0x04,  0x71,  0x00,  0x81,  0x01,  0x70,  0x04,  0x80,  0x05,  0x81,  0x05,
11087       0x00,  0x63,  0xF0,  0x04,  0xF2,  0x00,  0x72,  0x04,  0x01,  0x01,  0xF1,  0x00,  0x70,  0x00,  0x81,  0x01,
11088       0x70,  0x04,  0x71,  0x00,  0x81,  0x01,  0x72,  0x00,  0x80,  0x01,  0x71,  0x04,  0x70,  0x00,  0x80,  0x01,
11089       0x70,  0x04,  0x00,  0x63,  0xF0,  0x04,  0xF2,  0x00,  0x72,  0x04,  0x00,  0x01,  0xF1,  0x00,  0x70,  0x00,
11090       0x80,  0x01,  0x70,  0x04,  0x71,  0x00,  0x80,  0x01,  0x72,  0x00,  0x81,  0x01,  0x71,  0x04,  0x70,  0x00,
11091       0x81,  0x01,  0x70,  0x04,  0x00,  0x63,  0x00,  0x23,  0xB3,  0x01,  0x83,  0x05,  0xA3,  0x01,  0xA2,  0x01,
11092       0xA1,  0x01,  0x01,  0x23,  0xA0,  0x01,  0x00,  0x01,  0xC8,  0x00,  0x03,  0xA1,  0xC4,  0x07,  0x00,  0x33,
11093       0x07,  0x00,  0xC2,  0x88,  0x80,  0x05,  0x81,  0x05,  0x04,  0x01,  0x11,  0xC8,  0x48,  0x00,  0xB0,  0x01,
11094       0xB1,  0x01,  0x08,  0x23,  0xB2,  0x01,  0x05,  0x01,  0x48,  0x04,  0x00,  0x43,  0x00,  0xA2,  0xE4,  0x07,
11095       0x00,  0x05,  0xDA,  0x87,  0x00,  0x01,  0xC8,  0x00,  0xFF,  0x23,  0x80,  0x01,  0x05,  0x05,  0x00,  0x63,
11096       0xF7,  0x04,  0x1A,  0x09,  0xF6,  0x08,  0x6E,  0x04,  0x00,  0x02,  0x80,  0x43,  0x76,  0x08,  0x80,  0x02,
11097       0x77,  0x04,  0x00,  0x63,  0xF7,  0x04,  0x1A,  0x09,  0xF6,  0x08,  0x6E,  0x04,  0x00,  0x02,  0x00,  0xA0,
11098       0x14,  0x08,  0x16,  0x88,  0x00,  0x43,  0x76,  0x08,  0x80,  0x02,  0x77,  0x04,  0x00,  0x63,  0xF3,  0x04,
11099       0x00,  0x23,  0xF4,  0x00,  0x74,  0x00,  0x80,  0x43,  0xF4,  0x00,  0xCF,  0x40,  0x00,  0xA2,  0x44,  0x08,
11100       0x74,  0x04,  0x02,  0x01,  0xF7,  0xC9,  0xF6,  0xD9,  0x00,  0x01,  0x01,  0xA1,  0x24,  0x08,  0x04,  0x98,
11101       0x26,  0x95,  0x24,  0x88,  0x73,  0x04,  0x00,  0x63,  0xF3,  0x04,  0x75,  0x04,  0x5A,  0x88,  0x02,  0x01,
11102       0x04,  0xD8,  0x46,  0x97,  0x04,  0x98,  0x26,  0x95,  0x4A,  0x88,  0x75,  0x00,  0x00,  0xA3,  0x64,  0x08,
11103       0x00,  0x05,  0x4E,  0x88,  0x73,  0x04,  0x00,  0x63,  0x80,  0x7B,  0x80,  0x63,  0x06,  0xA6,  0x76,  0x08,
11104       0x00,  0x33,  0x3E,  0x00,  0xC2,  0x88,  0x80,  0x67,  0x83,  0x03,  0x80,  0x63,  0x00,  0x63,  0x38,  0x2B,
11105       0x9C,  0x88,  0x38,  0x2B,  0x92,  0x88,  0x32,  0x09,  0x31,  0x05,  0x92,  0x98,  0x05,  0x05,  0xB2,  0x09,
11106       0x00,  0x63,  0x00,  0x32,  0x00,  0x36,  0x00,  0x3A,  0x00,  0x3E,  0x00,  0x63,  0x80,  0x32,  0x80,  0x36,
11107       0x80,  0x3A,  0x80,  0x3E,  0xB4,  0x3D,  0x00,  0x63,  0x38,  0x2B,  0x40,  0x32,  0x40,  0x36,  0x40,  0x3A,
11108       0x40,  0x3E,  0x00,  0x63,  0x5A,  0x20,  0xC9,  0x40,  0x00,  0xA0,  0xB4,  0x08,  0x5D,  0x00,  0xFE,  0xC3,
11109       0x00,  0x63,  0x80,  0x73,  0xE6,  0x20,  0x02,  0x23,  0xE8,  0x00,  0x82,  0x73,  0xFF,  0xFD,  0x80,  0x73,
11110       0x13,  0x23,  0xF8,  0x88,  0x66,  0x20,  0xC0,  0x20,  0x04,  0x23,  0xA0,  0x01,  0xA1,  0x23,  0xA1,  0x01,
11111       0x81,  0x62,  0xE2,  0x88,  0x80,  0x73,  0x80,  0x77,  0x68,  0x00,  0x00,  0xA2,  0x80,  0x00,  0x03,  0xC2,
11112       0xF1,  0xC7,  0x41,  0x23,  0xF8,  0x88,  0x11,  0x23,  0xA1,  0x01,  0x04,  0x23,  0xA0,  0x01,  0xE6,  0x84,
11113     };
11114     
11115     STATIC ushort _asc_mcode_size = sizeof(_asc_mcode_buf);
11116     STATIC ADV_DCNT _asc_mcode_chksum = 0x012C453FUL;
11117     
11118     #define ASC_SYN_OFFSET_ONE_DISABLE_LIST  16
11119     STATIC uchar _syn_offset_one_disable_cmd[ASC_SYN_OFFSET_ONE_DISABLE_LIST] =
11120     {
11121         SCSICMD_Inquiry,
11122         SCSICMD_RequestSense,
11123         SCSICMD_ReadCapacity,
11124         SCSICMD_ReadTOC,
11125         SCSICMD_ModeSelect6,
11126         SCSICMD_ModeSense6,
11127         SCSICMD_ModeSelect10,
11128         SCSICMD_ModeSense10,
11129         0xFF,
11130         0xFF,
11131         0xFF,
11132         0xFF,
11133         0xFF,
11134         0xFF,
11135         0xFF,
11136         0xFF
11137     };
11138     
11139     STATIC int
11140     AscExeScsiQueue(
11141                        ASC_DVC_VAR *asc_dvc,
11142                        ASC_SCSI_Q *scsiq
11143     )
11144     {
11145         PortAddr            iop_base;
11146         ulong               last_int_level;
11147         int                 sta;
11148         int                 n_q_required;
11149         int                 disable_syn_offset_one_fix;
11150         int                 i;
11151         ASC_PADDR           addr;
11152         ASC_EXE_CALLBACK    asc_exe_callback;
11153         ushort              sg_entry_cnt = 0;
11154         ushort              sg_entry_cnt_minus_one = 0;
11155         uchar               target_ix;
11156         uchar               tid_no;
11157         uchar               sdtr_data;
11158         uchar               extra_bytes;
11159         uchar               scsi_cmd;
11160         uchar               disable_cmd;
11161         ASC_SG_HEAD         *sg_head;
11162         ASC_DCNT            data_cnt;
11163     
11164         iop_base = asc_dvc->iop_base;
11165         sg_head = scsiq->sg_head;
11166         asc_exe_callback = asc_dvc->exe_callback;
11167         if (asc_dvc->err_code != 0)
11168             return (ERR);
11169         if (scsiq == (ASC_SCSI_Q *) 0L) {
11170             AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SCSIQ_NULL_PTR);
11171             return (ERR);
11172         }
11173         scsiq->q1.q_no = 0;
11174         if ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES) == 0) {
11175             scsiq->q1.extra_bytes = 0;
11176         }
11177         sta = 0;
11178         target_ix = scsiq->q2.target_ix;
11179         tid_no = ASC_TIX_TO_TID(target_ix);
11180         n_q_required = 1;
11181         if (scsiq->cdbptr[0] == SCSICMD_RequestSense) {
11182             if ((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) {
11183                 asc_dvc->sdtr_done &= ~scsiq->q1.target_id;
11184                 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
11185                 AscMsgOutSDTR(asc_dvc,
11186                               asc_dvc->sdtr_period_tbl[(sdtr_data >> 4) &
11187                               (uchar) (asc_dvc->max_sdtr_index - 1)],
11188                               (uchar) (sdtr_data & (uchar) ASC_SYN_MAX_OFFSET));
11189                 scsiq->q1.cntl |= (QC_MSG_OUT | QC_URGENT);
11190             }
11191         }
11192         last_int_level = DvcEnterCritical();
11193         if (asc_dvc->in_critical_cnt != 0) {
11194             DvcLeaveCritical(last_int_level);
11195             AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CRITICAL_RE_ENTRY);
11196             return (ERR);
11197         }
11198         asc_dvc->in_critical_cnt++;
11199         if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
11200             if ((sg_entry_cnt = sg_head->entry_cnt) == 0) {
11201                 asc_dvc->in_critical_cnt--;
11202                 DvcLeaveCritical(last_int_level);
11203                 return (ERR);
11204             }
11205     #if !CC_VERY_LONG_SG_LIST
11206             if (sg_entry_cnt > ASC_MAX_SG_LIST)
11207             {
11208                 asc_dvc->in_critical_cnt--;
11209                 DvcLeaveCritical(last_int_level);
11210                 return(ERR);
11211             }
11212     #endif /* !CC_VERY_LONG_SG_LIST */
11213             if (sg_entry_cnt == 1) {
11214                 scsiq->q1.data_addr = (ADV_PADDR) sg_head->sg_list[0].addr;
11215                 scsiq->q1.data_cnt = (ADV_DCNT) sg_head->sg_list[0].bytes;
11216                 scsiq->q1.cntl &= ~(QC_SG_HEAD | QC_SG_SWAP_QUEUE);
11217             }
11218             sg_entry_cnt_minus_one = sg_entry_cnt - 1;
11219         }
11220         scsi_cmd = scsiq->cdbptr[0];
11221         disable_syn_offset_one_fix = FALSE;
11222         if ((asc_dvc->pci_fix_asyn_xfer & scsiq->q1.target_id) &&
11223             !(asc_dvc->pci_fix_asyn_xfer_always & scsiq->q1.target_id)) {
11224             if (scsiq->q1.cntl & QC_SG_HEAD) {
11225                 data_cnt = 0;
11226                 for (i = 0; i < sg_entry_cnt; i++) {
11227                     data_cnt += (ADV_DCNT) le32_to_cpu(sg_head->sg_list[i].bytes);
11228                 }
11229             } else {
11230                 data_cnt = le32_to_cpu(scsiq->q1.data_cnt);
11231             }
11232             if (data_cnt != 0UL) {
11233                 if (data_cnt < 512UL) {
11234                     disable_syn_offset_one_fix = TRUE;
11235                 } else {
11236                     for (i = 0; i < ASC_SYN_OFFSET_ONE_DISABLE_LIST; i++) {
11237                         disable_cmd = _syn_offset_one_disable_cmd[i];
11238                         if (disable_cmd == 0xFF) {
11239                             break;
11240                         }
11241                         if (scsi_cmd == disable_cmd) {
11242                             disable_syn_offset_one_fix = TRUE;
11243                             break;
11244                         }
11245                     }
11246                 }
11247             }
11248         }
11249         if (disable_syn_offset_one_fix) {
11250             scsiq->q2.tag_code &= ~M2_QTAG_MSG_SIMPLE;
11251             scsiq->q2.tag_code |= (ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX |
11252                                    ASC_TAG_FLAG_DISABLE_DISCONNECT);
11253         } else {
11254             scsiq->q2.tag_code &= 0x27;
11255         }
11256         if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
11257             if (asc_dvc->bug_fix_cntl) {
11258                 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
11259                     if ((scsi_cmd == SCSICMD_Read6) ||
11260                         (scsi_cmd == SCSICMD_Read10)) {
11261                         addr =
11262                             (ADV_PADDR) le32_to_cpu(
11263                                 sg_head->sg_list[sg_entry_cnt_minus_one].addr) +
11264                             (ADV_DCNT) le32_to_cpu(
11265                                 sg_head->sg_list[sg_entry_cnt_minus_one].bytes);
11266                         extra_bytes = (uchar) ((ushort) addr & 0x0003);
11267                         if ((extra_bytes != 0) &&
11268                             ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES)
11269                              == 0)) {
11270                             scsiq->q2.tag_code |= ASC_TAG_FLAG_EXTRA_BYTES;
11271                             scsiq->q1.extra_bytes = extra_bytes;
11272                             data_cnt = le32_to_cpu(
11273                                 sg_head->sg_list[sg_entry_cnt_minus_one].bytes);
11274                             data_cnt -= (ASC_DCNT) extra_bytes;
11275                             sg_head->sg_list[sg_entry_cnt_minus_one].bytes =
11276                                 cpu_to_le32(data_cnt);
11277                         }
11278                     }
11279                 }
11280             }
11281             sg_head->entry_to_copy = sg_head->entry_cnt;
11282     #if CC_VERY_LONG_SG_LIST
11283             /*
11284              * Set the sg_entry_cnt to the maximum possible. The rest of
11285              * the SG elements will be copied when the RISC completes the
11286              * SG elements that fit and halts.
11287              */
11288             if (sg_entry_cnt > ASC_MAX_SG_LIST)
11289             {
11290                  sg_entry_cnt = ASC_MAX_SG_LIST;
11291             }
11292     #endif /* CC_VERY_LONG_SG_LIST */
11293             n_q_required = AscSgListToQueue(sg_entry_cnt);
11294             if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, n_q_required) >=
11295                 (uint) n_q_required) || ((scsiq->q1.cntl & QC_URGENT) != 0)) {
11296                 if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
11297                                             n_q_required)) == 1) {
11298                     asc_dvc->in_critical_cnt--;
11299                     if (asc_exe_callback != 0) {
11300                         (*asc_exe_callback) (asc_dvc, scsiq);
11301                     }
11302                     DvcLeaveCritical(last_int_level);
11303                     return (sta);
11304                 }
11305             }
11306         } else {
11307             if (asc_dvc->bug_fix_cntl) {
11308                 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
11309                     if ((scsi_cmd == SCSICMD_Read6) ||
11310                         (scsi_cmd == SCSICMD_Read10)) {
11311                         addr = le32_to_cpu(scsiq->q1.data_addr) +
11312                             le32_to_cpu(scsiq->q1.data_cnt);
11313                         extra_bytes = (uchar) ((ushort) addr & 0x0003);
11314                         if ((extra_bytes != 0) &&
11315                             ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES)
11316                               == 0)) {
11317                             data_cnt = le32_to_cpu(scsiq->q1.data_cnt);
11318                             if (((ushort) data_cnt & 0x01FF) == 0) {
11319                                 scsiq->q2.tag_code |= ASC_TAG_FLAG_EXTRA_BYTES;
11320                                 data_cnt -= (ASC_DCNT) extra_bytes;
11321                                 scsiq->q1.data_cnt = cpu_to_le32(data_cnt);
11322                                 scsiq->q1.extra_bytes = extra_bytes;
11323                             }
11324                         }
11325                     }
11326                 }
11327             }
11328             n_q_required = 1;
11329             if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, 1) >= 1) ||
11330                 ((scsiq->q1.cntl & QC_URGENT) != 0)) {
11331                 if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
11332                                             n_q_required)) == 1) {
11333                     asc_dvc->in_critical_cnt--;
11334                     if (asc_exe_callback != 0) {
11335                         (*asc_exe_callback) (asc_dvc, scsiq);
11336                     }
11337                     DvcLeaveCritical(last_int_level);
11338                     return (sta);
11339                 }
11340             }
11341         }
11342         asc_dvc->in_critical_cnt--;
11343         DvcLeaveCritical(last_int_level);
11344         return (sta);
11345     }
11346     
11347     STATIC int
11348     AscSendScsiQueue(
11349                         ASC_DVC_VAR *asc_dvc,
11350                         ASC_SCSI_Q *scsiq,
11351                         uchar n_q_required
11352     )
11353     {
11354         PortAddr            iop_base;
11355         uchar               free_q_head;
11356         uchar               next_qp;
11357         uchar               tid_no;
11358         uchar               target_ix;
11359         int                 sta;
11360     
11361         iop_base = asc_dvc->iop_base;
11362         target_ix = scsiq->q2.target_ix;
11363         tid_no = ASC_TIX_TO_TID(target_ix);
11364         sta = 0;
11365         free_q_head = (uchar) AscGetVarFreeQHead(iop_base);
11366         if (n_q_required > 1) {
11367             if ((next_qp = AscAllocMultipleFreeQueue(iop_base,
11368                                            free_q_head, (uchar) (n_q_required)))
11369                 != (uchar) ASC_QLINK_END) {
11370                 asc_dvc->last_q_shortage = 0;
11371                 scsiq->sg_head->queue_cnt = n_q_required - 1;
11372                 scsiq->q1.q_no = free_q_head;
11373                 if ((sta = AscPutReadySgListQueue(asc_dvc, scsiq,
11374                                                   free_q_head)) == 1) {
11375                     AscPutVarFreeQHead(iop_base, next_qp);
11376                     asc_dvc->cur_total_qng += (uchar) (n_q_required);
11377                     asc_dvc->cur_dvc_qng[tid_no]++;
11378                 }
11379                 return (sta);
11380             }
11381         } else if (n_q_required == 1) {
11382             if ((next_qp = AscAllocFreeQueue(iop_base,
11383                                              free_q_head)) != ASC_QLINK_END) {
11384                 scsiq->q1.q_no = free_q_head;
11385                 if ((sta = AscPutReadyQueue(asc_dvc, scsiq,
11386                                             free_q_head)) == 1) {
11387                     AscPutVarFreeQHead(iop_base, next_qp);
11388                     asc_dvc->cur_total_qng++;
11389                     asc_dvc->cur_dvc_qng[tid_no]++;
11390                 }
11391                 return (sta);
11392             }
11393         }
11394         return (sta);
11395     }
11396     
11397     STATIC int
11398     AscSgListToQueue(
11399                         int sg_list
11400     )
11401     {
11402         int                 n_sg_list_qs;
11403     
11404         n_sg_list_qs = ((sg_list - 1) / ASC_SG_LIST_PER_Q);
11405         if (((sg_list - 1) % ASC_SG_LIST_PER_Q) != 0)
11406             n_sg_list_qs++;
11407         return (n_sg_list_qs + 1);
11408     }
11409     
11410     
11411     STATIC uint
11412     AscGetNumOfFreeQueue(
11413                             ASC_DVC_VAR *asc_dvc,
11414                             uchar target_ix,
11415                             uchar n_qs
11416     )
11417     {
11418         uint                cur_used_qs;
11419         uint                cur_free_qs;
11420         ASC_SCSI_BIT_ID_TYPE target_id;
11421         uchar               tid_no;
11422     
11423         target_id = ASC_TIX_TO_TARGET_ID(target_ix);
11424         tid_no = ASC_TIX_TO_TID(target_ix);
11425         if ((asc_dvc->unit_not_ready & target_id) ||
11426             (asc_dvc->queue_full_or_busy & target_id)) {
11427             return (0);
11428         }
11429         if (n_qs == 1) {
11430             cur_used_qs = (uint) asc_dvc->cur_total_qng +
11431               (uint) asc_dvc->last_q_shortage +
11432               (uint) ASC_MIN_FREE_Q;
11433         } else {
11434             cur_used_qs = (uint) asc_dvc->cur_total_qng +
11435               (uint) ASC_MIN_FREE_Q;
11436         }
11437         if ((uint) (cur_used_qs + n_qs) <= (uint) asc_dvc->max_total_qng) {
11438             cur_free_qs = (uint) asc_dvc->max_total_qng - cur_used_qs;
11439             if (asc_dvc->cur_dvc_qng[tid_no] >=
11440                 asc_dvc->max_dvc_qng[tid_no]) {
11441                 return (0);
11442             }
11443             return (cur_free_qs);
11444         }
11445         if (n_qs > 1) {
11446             if ((n_qs > asc_dvc->last_q_shortage) && (n_qs <= (asc_dvc->max_total_qng - ASC_MIN_FREE_Q))) {
11447                 asc_dvc->last_q_shortage = n_qs;
11448             }
11449         }
11450         return (0);
11451     }
11452     
11453     STATIC int
11454     AscPutReadyQueue(
11455                         ASC_DVC_VAR *asc_dvc,
11456                         ASC_SCSI_Q *scsiq,
11457                         uchar q_no
11458     )
11459     {
11460         ushort              q_addr;
11461         uchar               tid_no;
11462         uchar               sdtr_data;
11463         uchar               syn_period_ix;
11464         uchar               syn_offset;
11465         PortAddr            iop_base;
11466     
11467         iop_base = asc_dvc->iop_base;
11468         if (((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) &&
11469             ((asc_dvc->sdtr_done & scsiq->q1.target_id) == 0)) {
11470             tid_no = ASC_TIX_TO_TID(scsiq->q2.target_ix);
11471             sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
11472             syn_period_ix = (sdtr_data >> 4) & (asc_dvc->max_sdtr_index - 1);
11473             syn_offset = sdtr_data & ASC_SYN_MAX_OFFSET;
11474             AscMsgOutSDTR(asc_dvc,
11475                           asc_dvc->sdtr_period_tbl[syn_period_ix],
11476                           syn_offset);
11477             scsiq->q1.cntl |= QC_MSG_OUT;
11478         }
11479         q_addr = ASC_QNO_TO_QADDR(q_no);
11480         if ((scsiq->q1.target_id & asc_dvc->use_tagged_qng) == 0) {
11481             scsiq->q2.tag_code &= ~M2_QTAG_MSG_SIMPLE;
11482         }
11483         scsiq->q1.status = QS_FREE;
11484         AscMemWordCopyPtrToLram(iop_base,
11485                              q_addr + ASC_SCSIQ_CDB_BEG,
11486                              (uchar *) scsiq->cdbptr,
11487                              scsiq->q2.cdb_len >> 1);
11488     
11489         DvcPutScsiQ(iop_base,
11490                     q_addr + ASC_SCSIQ_CPY_BEG,
11491                     (uchar *) &scsiq->q1.cntl,
11492                     ((sizeof(ASC_SCSIQ_1) + sizeof(ASC_SCSIQ_2)) / 2) - 1);
11493         AscWriteLramWord(iop_base,
11494                          (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS),
11495                  (ushort) (((ushort) scsiq->q1.q_no << 8) | (ushort) QS_READY));
11496         return (1);
11497     }
11498     
11499     STATIC int
11500     AscPutReadySgListQueue(
11501                               ASC_DVC_VAR *asc_dvc,
11502                               ASC_SCSI_Q *scsiq,
11503                               uchar q_no
11504     )
11505     {
11506         int                 sta;
11507         int                 i;
11508         ASC_SG_HEAD *sg_head;
11509         ASC_SG_LIST_Q       scsi_sg_q;
11510         ASC_DCNT            saved_data_addr;
11511         ASC_DCNT            saved_data_cnt;
11512         PortAddr            iop_base;
11513         ushort              sg_list_dwords;
11514         ushort              sg_index;
11515         ushort              sg_entry_cnt;
11516         ushort              q_addr;
11517         uchar               next_qp;
11518     
11519         iop_base = asc_dvc->iop_base;
11520         sg_head = scsiq->sg_head;
11521         saved_data_addr = scsiq->q1.data_addr;
11522         saved_data_cnt = scsiq->q1.data_cnt;
11523         scsiq->q1.data_addr = (ASC_PADDR) sg_head->sg_list[0].addr;
11524         scsiq->q1.data_cnt = (ASC_DCNT) sg_head->sg_list[0].bytes;
11525     #if CC_VERY_LONG_SG_LIST
11526         /*
11527          * If sg_head->entry_cnt is greater than ASC_MAX_SG_LIST
11528          * then not all SG elements will fit in the allocated queues.
11529          * The rest of the SG elements will be copied when the RISC
11530          * completes the SG elements that fit and halts.
11531          */
11532         if (sg_head->entry_cnt > ASC_MAX_SG_LIST)
11533         {
11534              /*
11535               * Set sg_entry_cnt to be the number of SG elements that
11536               * will fit in the allocated SG queues. It is minus 1, because
11537               * the first SG element is handled above. ASC_MAX_SG_LIST is
11538               * already inflated by 1 to account for this. For example it
11539               * may be 50 which is 1 + 7 queues * 7 SG elements.
11540               */
11541              sg_entry_cnt = ASC_MAX_SG_LIST - 1;
11542     
11543              /*
11544               * Keep track of remaining number of SG elements that will
11545               * need to be handled from a_isr.c.
11546               */
11547              scsiq->remain_sg_entry_cnt = sg_head->entry_cnt - ASC_MAX_SG_LIST;
11548         } else
11549         {
11550     #endif /* CC_VERY_LONG_SG_LIST */
11551              /*
11552               * Set sg_entry_cnt to be the number of SG elements that
11553               * will fit in the allocated SG queues. It is minus 1, because
11554               * the first SG element is handled above.
11555               */
11556              sg_entry_cnt = sg_head->entry_cnt - 1;
11557     #if CC_VERY_LONG_SG_LIST
11558         }
11559     #endif /* CC_VERY_LONG_SG_LIST */
11560         if (sg_entry_cnt != 0) {
11561             scsiq->q1.cntl |= QC_SG_HEAD;
11562             q_addr = ASC_QNO_TO_QADDR(q_no);
11563             sg_index = 1;
11564             scsiq->q1.sg_queue_cnt = sg_head->queue_cnt;
11565             scsi_sg_q.sg_head_qp = q_no;
11566             scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
11567             for (i = 0; i < sg_head->queue_cnt; i++) {
11568                 scsi_sg_q.seq_no = i + 1;
11569                 if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
11570                     sg_list_dwords = (uchar) (ASC_SG_LIST_PER_Q * 2);
11571                     sg_entry_cnt -= ASC_SG_LIST_PER_Q;
11572                     if (i == 0) {
11573                         scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q;
11574                         scsi_sg_q.sg_cur_list_cnt = ASC_SG_LIST_PER_Q;
11575                     } else {
11576                         scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q - 1;
11577                         scsi_sg_q.sg_cur_list_cnt = ASC_SG_LIST_PER_Q - 1;
11578                     }
11579                 } else {
11580     #if CC_VERY_LONG_SG_LIST
11581                     /*
11582                      * This is the last SG queue in the list of
11583                      * allocated SG queues. If there are more
11584                      * SG elements than will fit in the allocated
11585                      * queues, then set the QCSG_SG_XFER_MORE flag.
11586                      */
11587                     if (sg_head->entry_cnt > ASC_MAX_SG_LIST)
11588                     {
11589                         scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
11590                     } else
11591                     {
11592     #endif /* CC_VERY_LONG_SG_LIST */
11593                         scsi_sg_q.cntl |= QCSG_SG_XFER_END;
11594     #if CC_VERY_LONG_SG_LIST
11595                     }
11596     #endif /* CC_VERY_LONG_SG_LIST */
11597                     sg_list_dwords = sg_entry_cnt << 1;
11598                     if (i == 0) {
11599                         scsi_sg_q.sg_list_cnt = sg_entry_cnt;
11600                         scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt;
11601                     } else {
11602                         scsi_sg_q.sg_list_cnt = sg_entry_cnt - 1;
11603                         scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt - 1;
11604                     }
11605                     sg_entry_cnt = 0;
11606                 }
11607                 next_qp = AscReadLramByte(iop_base,
11608                                           (ushort) (q_addr + ASC_SCSIQ_B_FWD));
11609                 scsi_sg_q.q_no = next_qp;
11610                 q_addr = ASC_QNO_TO_QADDR(next_qp);
11611                 AscMemWordCopyPtrToLram(iop_base,
11612                                     q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
11613                                     (uchar *) &scsi_sg_q,
11614                                     sizeof(ASC_SG_LIST_Q) >> 1);
11615                 AscMemDWordCopyPtrToLram(iop_base,
11616                                     q_addr + ASC_SGQ_LIST_BEG,
11617                                     (uchar *) &sg_head->sg_list[sg_index],
11618                                     sg_list_dwords);
11619                 sg_index += ASC_SG_LIST_PER_Q;
11620                 scsiq->next_sg_index = sg_index;
11621             }
11622         } else {
11623             scsiq->q1.cntl &= ~QC_SG_HEAD;
11624         }
11625         sta = AscPutReadyQueue(asc_dvc, scsiq, q_no);
11626         scsiq->q1.data_addr = saved_data_addr;
11627         scsiq->q1.data_cnt = saved_data_cnt;
11628         return (sta);
11629     }
11630     
11631     STATIC int
11632     AscSetRunChipSynRegAtID(
11633                                PortAddr iop_base,
11634                                uchar tid_no,
11635                                uchar sdtr_data
11636     )
11637     {
11638         int                 sta = FALSE;
11639     
11640         if (AscHostReqRiscHalt(iop_base)) {
11641             sta = AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
11642             AscStartChip(iop_base);
11643             return (sta);
11644         }
11645         return (sta);
11646     }
11647     
11648     STATIC int
11649     AscSetChipSynRegAtID(
11650                             PortAddr iop_base,
11651                             uchar id,
11652                             uchar sdtr_data
11653     )
11654     {
11655         ASC_SCSI_BIT_ID_TYPE org_id;
11656         int                 i;
11657         int                 sta = TRUE;
11658     
11659         AscSetBank(iop_base, 1);
11660         org_id = AscReadChipDvcID(iop_base);
11661         for (i = 0; i <= ASC_MAX_TID; i++) {
11662             if (org_id == (0x01 << i))
11663                 break;
11664         }
11665         org_id = (ASC_SCSI_BIT_ID_TYPE) i;
11666         AscWriteChipDvcID(iop_base, id);
11667         if (AscReadChipDvcID(iop_base) == (0x01 << id)) {
11668             AscSetBank(iop_base, 0);
11669             AscSetChipSyn(iop_base, sdtr_data);
11670             if (AscGetChipSyn(iop_base) != sdtr_data) {
11671                 sta = FALSE;
11672             }
11673         } else {
11674             sta = FALSE;
11675         }
11676         AscSetBank(iop_base, 1);
11677         AscWriteChipDvcID(iop_base, org_id);
11678         AscSetBank(iop_base, 0);
11679         return (sta);
11680     }
11681     
11682     STATIC ushort
11683     AscInitLram(
11684                    ASC_DVC_VAR *asc_dvc
11685     )
11686     {
11687         uchar               i;
11688         ushort              s_addr;
11689         PortAddr            iop_base;
11690         ushort              warn_code;
11691     
11692         iop_base = asc_dvc->iop_base;
11693         warn_code = 0;
11694         AscMemWordSetLram(iop_base, ASC_QADR_BEG, 0,
11695                    (ushort) (((int) (asc_dvc->max_total_qng + 2 + 1) * 64) >> 1)
11696     );
11697         i = ASC_MIN_ACTIVE_QNO;
11698         s_addr = ASC_QADR_BEG + ASC_QBLK_SIZE;
11699         AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_FWD),
11700                          (uchar) (i + 1));
11701         AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_BWD),
11702                          (uchar) (asc_dvc->max_total_qng));
11703         AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_QNO),
11704                          (uchar) i);
11705         i++;
11706         s_addr += ASC_QBLK_SIZE;
11707         for (; i < asc_dvc->max_total_qng; i++, s_addr += ASC_QBLK_SIZE) {
11708             AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_FWD),
11709                              (uchar) (i + 1));
11710             AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_BWD),
11711                              (uchar) (i - 1));
11712             AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_QNO),
11713                              (uchar) i);
11714         }
11715         AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_FWD),
11716                          (uchar) ASC_QLINK_END);
11717         AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_BWD),
11718                          (uchar) (asc_dvc->max_total_qng - 1));
11719         AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_QNO),
11720                          (uchar) asc_dvc->max_total_qng);
11721         i++;
11722         s_addr += ASC_QBLK_SIZE;
11723         for (; i <= (uchar) (asc_dvc->max_total_qng + 3);
11724              i++, s_addr += ASC_QBLK_SIZE) {
11725             AscWriteLramByte(iop_base,
11726                              (ushort) (s_addr + (ushort) ASC_SCSIQ_B_FWD), i);
11727             AscWriteLramByte(iop_base,
11728                              (ushort) (s_addr + (ushort) ASC_SCSIQ_B_BWD), i);
11729             AscWriteLramByte(iop_base,
11730                              (ushort) (s_addr + (ushort) ASC_SCSIQ_B_QNO), i);
11731         }
11732         return (warn_code);
11733     }
11734     
11735     STATIC ushort
11736     AscInitQLinkVar(
11737                        ASC_DVC_VAR *asc_dvc
11738     )
11739     {
11740         PortAddr            iop_base;
11741         int                 i;
11742         ushort              lram_addr;
11743     
11744         iop_base = asc_dvc->iop_base;
11745         AscPutRiscVarFreeQHead(iop_base, 1);
11746         AscPutRiscVarDoneQTail(iop_base, asc_dvc->max_total_qng);
11747         AscPutVarFreeQHead(iop_base, 1);
11748         AscPutVarDoneQTail(iop_base, asc_dvc->max_total_qng);
11749         AscWriteLramByte(iop_base, ASCV_BUSY_QHEAD_B,
11750                          (uchar) ((int) asc_dvc->max_total_qng + 1));
11751         AscWriteLramByte(iop_base, ASCV_DISC1_QHEAD_B,
11752                          (uchar) ((int) asc_dvc->max_total_qng + 2));
11753         AscWriteLramByte(iop_base, (ushort) ASCV_TOTAL_READY_Q_B,
11754                          asc_dvc->max_total_qng);
11755         AscWriteLramWord(iop_base, ASCV_ASCDVC_ERR_CODE_W, 0);
11756         AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
11757         AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 0);
11758         AscWriteLramByte(iop_base, ASCV_SCSIBUSY_B, 0);
11759         AscWriteLramByte(iop_base, ASCV_WTM_FLAG_B, 0);
11760         AscPutQDoneInProgress(iop_base, 0);
11761         lram_addr = ASC_QADR_BEG;
11762         for (i = 0; i < 32; i++, lram_addr += 2) {
11763             AscWriteLramWord(iop_base, lram_addr, 0);
11764         }
11765         return (0);
11766     }
11767     
11768     STATIC int
11769     AscSetLibErrorCode(
11770                           ASC_DVC_VAR *asc_dvc,
11771                           ushort err_code
11772     )
11773     {
11774         if (asc_dvc->err_code == 0) {
11775             asc_dvc->err_code = err_code;
11776             AscWriteLramWord(asc_dvc->iop_base, ASCV_ASCDVC_ERR_CODE_W,
11777                              err_code);
11778         }
11779         return (err_code);
11780     }
11781     
11782     
11783     STATIC uchar
11784     AscMsgOutSDTR(
11785                      ASC_DVC_VAR *asc_dvc,
11786                      uchar sdtr_period,
11787                      uchar sdtr_offset
11788     )
11789     {
11790         EXT_MSG             sdtr_buf;
11791         uchar               sdtr_period_index;
11792         PortAddr            iop_base;
11793     
11794         iop_base = asc_dvc->iop_base;
11795         sdtr_buf.msg_type = MS_EXTEND;
11796         sdtr_buf.msg_len = MS_SDTR_LEN;
11797         sdtr_buf.msg_req = MS_SDTR_CODE;
11798         sdtr_buf.xfer_period = sdtr_period;
11799         sdtr_offset &= ASC_SYN_MAX_OFFSET;
11800         sdtr_buf.req_ack_offset = sdtr_offset;
11801         if ((sdtr_period_index =
11802              AscGetSynPeriodIndex(asc_dvc, sdtr_period)) <=
11803             asc_dvc->max_sdtr_index) {
11804             AscMemWordCopyPtrToLram(iop_base,
11805                                  ASCV_MSGOUT_BEG,
11806                                  (uchar *) &sdtr_buf,
11807                                  sizeof (EXT_MSG) >> 1);
11808             return ((sdtr_period_index << 4) | sdtr_offset);
11809         } else {
11810     
11811             sdtr_buf.req_ack_offset = 0;
11812             AscMemWordCopyPtrToLram(iop_base,
11813                                  ASCV_MSGOUT_BEG,
11814                                  (uchar *) &sdtr_buf,
11815                                  sizeof (EXT_MSG) >> 1);
11816             return (0);
11817         }
11818     }
11819     
11820     STATIC uchar
11821     AscCalSDTRData(
11822                       ASC_DVC_VAR *asc_dvc,
11823                       uchar sdtr_period,
11824                       uchar syn_offset
11825     )
11826     {
11827         uchar               byte;
11828         uchar               sdtr_period_ix;
11829     
11830         sdtr_period_ix = AscGetSynPeriodIndex(asc_dvc, sdtr_period);
11831         if (
11832                (sdtr_period_ix > asc_dvc->max_sdtr_index)
11833     ) {
11834             return (0xFF);
11835         }
11836         byte = (sdtr_period_ix << 4) | (syn_offset & ASC_SYN_MAX_OFFSET);
11837         return (byte);
11838     }
11839     
11840     STATIC void
11841     AscSetChipSDTR(
11842                       PortAddr iop_base,
11843                       uchar sdtr_data,
11844                       uchar tid_no
11845     )
11846     {
11847         AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
11848         AscPutMCodeSDTRDoneAtID(iop_base, tid_no, sdtr_data);
11849         return;
11850     }
11851     
11852     STATIC uchar
11853     AscGetSynPeriodIndex(
11854                             ASC_DVC_VAR *asc_dvc,
11855                             uchar syn_time
11856     )
11857     {
11858         uchar             *period_table;
11859         int                 max_index;
11860         int                 min_index;
11861         int                 i;
11862     
11863         period_table = asc_dvc->sdtr_period_tbl;
11864         max_index = (int) asc_dvc->max_sdtr_index;
11865         min_index = (int)asc_dvc->host_init_sdtr_index;
11866         if ((syn_time <= period_table[max_index])) {
11867             for (i = min_index; i < (max_index - 1); i++) {
11868                 if (syn_time <= period_table[i]) {
11869                     return ((uchar) i);
11870                 }
11871             }
11872             return ((uchar) max_index);
11873         } else {
11874             return ((uchar) (max_index + 1));
11875         }
11876     }
11877     
11878     STATIC uchar
11879     AscAllocFreeQueue(
11880                          PortAddr iop_base,
11881                          uchar free_q_head
11882     )
11883     {
11884         ushort              q_addr;
11885         uchar               next_qp;
11886         uchar               q_status;
11887     
11888         q_addr = ASC_QNO_TO_QADDR(free_q_head);
11889         q_status = (uchar) AscReadLramByte(iop_base,
11890                                         (ushort) (q_addr + ASC_SCSIQ_B_STATUS));
11891         next_qp = AscReadLramByte(iop_base,
11892                                   (ushort) (q_addr + ASC_SCSIQ_B_FWD));
11893         if (((q_status & QS_READY) == 0) && (next_qp != ASC_QLINK_END)) {
11894             return (next_qp);
11895         }
11896         return (ASC_QLINK_END);
11897     }
11898     
11899     STATIC uchar
11900     AscAllocMultipleFreeQueue(
11901                                  PortAddr iop_base,
11902                                  uchar free_q_head,
11903                                  uchar n_free_q
11904     )
11905     {
11906         uchar               i;
11907     
11908         for (i = 0; i < n_free_q; i++) {
11909             if ((free_q_head = AscAllocFreeQueue(iop_base, free_q_head))
11910                 == ASC_QLINK_END) {
11911                 return (ASC_QLINK_END);
11912             }
11913         }
11914         return (free_q_head);
11915     }
11916     
11917     STATIC int
11918     AscHostReqRiscHalt(
11919                           PortAddr iop_base
11920     )
11921     {
11922         int                 count = 0;
11923         int                 sta = 0;
11924         uchar               saved_stop_code;
11925     
11926         if (AscIsChipHalted(iop_base))
11927             return (1);
11928         saved_stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
11929         AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
11930                          ASC_STOP_HOST_REQ_RISC_HALT | ASC_STOP_REQ_RISC_STOP
11931     );
11932         do {
11933             if (AscIsChipHalted(iop_base)) {
11934                 sta = 1;
11935                 break;
11936             }
11937             DvcSleepMilliSecond(100);
11938         } while (count++ < 20);
11939         AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, saved_stop_code);
11940         return (sta);
11941     }
11942     
11943     STATIC int
11944     AscStopQueueExe(
11945                        PortAddr iop_base
11946     )
11947     {
11948         int                 count = 0;
11949     
11950         if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) == 0) {
11951             AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
11952                              ASC_STOP_REQ_RISC_STOP);
11953             do {
11954                 if (
11955                        AscReadLramByte(iop_base, ASCV_STOP_CODE_B) &
11956                        ASC_STOP_ACK_RISC_STOP) {
11957                     return (1);
11958                 }
11959                 DvcSleepMilliSecond(100);
11960             } while (count++ < 20);
11961         }
11962         return (0);
11963     }
11964     
11965     STATIC void
11966     DvcDelayMicroSecond(ADV_DVC_VAR *asc_dvc, ushort micro_sec)
11967     {
11968         udelay(micro_sec);
11969     }
11970     
11971     STATIC void
11972     DvcDelayNanoSecond(ASC_DVC_VAR *asc_dvc, ASC_DCNT nano_sec)
11973     {
11974         udelay((nano_sec + 999)/1000);
11975     }
11976     
11977     #ifdef CONFIG_ISA
11978     ASC_INITFUNC(
11979     STATIC ASC_DCNT,
11980     AscGetEisaProductID(
11981                            PortAddr iop_base
11982     )
11983     )
11984     {
11985         PortAddr            eisa_iop;
11986         ushort              product_id_high, product_id_low;
11987         ASC_DCNT            product_id;
11988     
11989         eisa_iop = ASC_GET_EISA_SLOT(iop_base) | ASC_EISA_PID_IOP_MASK;
11990         product_id_low = inpw(eisa_iop);
11991         product_id_high = inpw(eisa_iop + 2);
11992         product_id = ((ASC_DCNT) product_id_high << 16) |
11993             (ASC_DCNT) product_id_low;
11994         return (product_id);
11995     }
11996     
11997     ASC_INITFUNC(
11998     STATIC PortAddr,
11999     AscSearchIOPortAddrEISA(
12000                                PortAddr iop_base
12001     )
12002     )
12003     {
12004         ASC_DCNT            eisa_product_id;
12005     
12006         if (iop_base == 0) {
12007             iop_base = ASC_EISA_MIN_IOP_ADDR;
12008         } else {
12009             if (iop_base == ASC_EISA_MAX_IOP_ADDR)
12010                 return (0);
12011             if ((iop_base & 0x0050) == 0x0050) {
12012                 iop_base += ASC_EISA_BIG_IOP_GAP;
12013             } else {
12014                 iop_base += ASC_EISA_SMALL_IOP_GAP;
12015             }
12016         }
12017         while (iop_base <= ASC_EISA_MAX_IOP_ADDR) {
12018             eisa_product_id = AscGetEisaProductID(iop_base);
12019             if ((eisa_product_id == ASC_EISA_ID_740) ||
12020                 (eisa_product_id == ASC_EISA_ID_750)) {
12021                 if (AscFindSignature(iop_base)) {
12022                     inpw(iop_base + 4);
12023                     return (iop_base);
12024                 }
12025             }
12026             if (iop_base == ASC_EISA_MAX_IOP_ADDR)
12027                 return (0);
12028             if ((iop_base & 0x0050) == 0x0050) {
12029                 iop_base += ASC_EISA_BIG_IOP_GAP;
12030             } else {
12031                 iop_base += ASC_EISA_SMALL_IOP_GAP;
12032             }
12033         }
12034         return (0);
12035     }
12036     #endif /* CONFIG_ISA */
12037     
12038     STATIC int
12039     AscStartChip(
12040                     PortAddr iop_base
12041     )
12042     {
12043         AscSetChipControl(iop_base, 0);
12044         if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
12045             return (0);
12046         }
12047         return (1);
12048     }
12049     
12050     STATIC int
12051     AscStopChip(
12052                    PortAddr iop_base
12053     )
12054     {
12055         uchar               cc_val;
12056     
12057         cc_val = AscGetChipControl(iop_base) & (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG));
12058         AscSetChipControl(iop_base, (uchar) (cc_val | CC_HALT));
12059         AscSetChipIH(iop_base, INS_HALT);
12060         AscSetChipIH(iop_base, INS_RFLAG_WTM);
12061         if ((AscGetChipStatus(iop_base) & CSW_HALTED) == 0) {
12062             return (0);
12063         }
12064         return (1);
12065     }
12066     
12067     STATIC int
12068     AscIsChipHalted(
12069                        PortAddr iop_base
12070     )
12071     {
12072         if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
12073             if ((AscGetChipControl(iop_base) & CC_HALT) != 0) {
12074                 return (1);
12075             }
12076         }
12077         return (0);
12078     }
12079     
12080     STATIC void
12081     AscSetChipIH(
12082                     PortAddr iop_base,
12083                     ushort ins_code
12084     )
12085     {
12086         AscSetBank(iop_base, 1);
12087         AscWriteChipIH(iop_base, ins_code);
12088         AscSetBank(iop_base, 0);
12089         return;
12090     }
12091     
12092     STATIC void
12093     AscAckInterrupt(
12094                        PortAddr iop_base
12095     )
12096     {
12097         uchar               host_flag;
12098         uchar               risc_flag;
12099         ushort              loop;
12100     
12101         loop = 0;
12102         do {
12103             risc_flag = AscReadLramByte(iop_base, ASCV_RISC_FLAG_B);
12104             if (loop++ > 0x7FFF) {
12105                 break;
12106             }
12107         } while ((risc_flag & ASC_RISC_FLAG_GEN_INT) != 0);
12108         host_flag = AscReadLramByte(iop_base, ASCV_HOST_FLAG_B) & (~ASC_HOST_FLAG_ACK_INT);
12109         AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
12110                          (uchar) (host_flag | ASC_HOST_FLAG_ACK_INT));
12111         AscSetChipStatus(iop_base, CIW_INT_ACK);
12112         loop = 0;
12113         while (AscGetChipStatus(iop_base) & CSW_INT_PENDING) {
12114             AscSetChipStatus(iop_base, CIW_INT_ACK);
12115             if (loop++ > 3) {
12116                 break;
12117             }
12118         }
12119         AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
12120         return;
12121     }
12122     
12123     STATIC void
12124     AscDisableInterrupt(
12125                            PortAddr iop_base
12126     )
12127     {
12128         ushort              cfg;
12129     
12130         cfg = AscGetChipCfgLsw(iop_base);
12131         AscSetChipCfgLsw(iop_base, cfg & (~ASC_CFG0_HOST_INT_ON));
12132         return;
12133     }
12134     
12135     STATIC void
12136     AscEnableInterrupt(
12137                           PortAddr iop_base
12138     )
12139     {
12140         ushort              cfg;
12141     
12142         cfg = AscGetChipCfgLsw(iop_base);
12143         AscSetChipCfgLsw(iop_base, cfg | ASC_CFG0_HOST_INT_ON);
12144         return;
12145     }
12146     
12147     
12148     
12149     STATIC void
12150     AscSetBank(
12151                   PortAddr iop_base,
12152                   uchar bank
12153     )
12154     {
12155         uchar               val;
12156     
12157         val = AscGetChipControl(iop_base) &
12158           (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG | CC_SCSI_RESET | CC_CHIP_RESET));
12159         if (bank == 1) {
12160             val |= CC_BANK_ONE;
12161         } else if (bank == 2) {
12162             val |= CC_DIAG | CC_BANK_ONE;
12163         } else {
12164             val &= ~CC_BANK_ONE;
12165         }
12166         AscSetChipControl(iop_base, val);
12167         return;
12168     }
12169     
12170     STATIC int
12171     AscResetChipAndScsiBus(
12172                               ASC_DVC_VAR *asc_dvc
12173     )
12174     {
12175         PortAddr    iop_base;
12176         int         i = 10;
12177     
12178         iop_base = asc_dvc->iop_base;
12179         while ((AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE) && (i-- > 0))
12180         {
12181               DvcSleepMilliSecond(100);
12182         }
12183         AscStopChip(iop_base);
12184         AscSetChipControl(iop_base, CC_CHIP_RESET | CC_SCSI_RESET | CC_HALT);
12185         DvcDelayNanoSecond(asc_dvc, 60000);
12186         AscSetChipIH(iop_base, INS_RFLAG_WTM);
12187         AscSetChipIH(iop_base, INS_HALT);
12188         AscSetChipControl(iop_base, CC_CHIP_RESET | CC_HALT);
12189         AscSetChipControl(iop_base, CC_HALT);
12190         DvcSleepMilliSecond(200);
12191         AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
12192         AscSetChipStatus(iop_base, 0);
12193         return (AscIsChipHalted(iop_base));
12194     }
12195     
12196     ASC_INITFUNC(
12197     STATIC ASC_DCNT,
12198     AscGetMaxDmaCount(
12199                          ushort bus_type
12200     )
12201     )
12202     {
12203         if (bus_type & ASC_IS_ISA)
12204             return (ASC_MAX_ISA_DMA_COUNT);
12205         else if (bus_type & (ASC_IS_EISA | ASC_IS_VL))
12206             return (ASC_MAX_VL_DMA_COUNT);
12207         return (ASC_MAX_PCI_DMA_COUNT);
12208     }
12209     
12210     #ifdef CONFIG_ISA
12211     ASC_INITFUNC(
12212     STATIC ushort,
12213     AscGetIsaDmaChannel(
12214                            PortAddr iop_base
12215     )
12216     )
12217     {
12218         ushort              channel;
12219     
12220         channel = AscGetChipCfgLsw(iop_base) & 0x0003;
12221         if (channel == 0x03)
12222             return (0);
12223         else if (channel == 0x00)
12224             return (7);
12225         return (channel + 4);
12226     }
12227     
12228     ASC_INITFUNC(
12229     STATIC ushort,
12230     AscSetIsaDmaChannel(
12231                            PortAddr iop_base,
12232                            ushort dma_channel
12233     )
12234     )
12235     {
12236         ushort              cfg_lsw;
12237         uchar               value;