OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [drivers/] [scsi/] [advansys.c] - Blame information for rev 1772

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1626 jcastillo
/* $Id: advansys.c,v 1.1 2005-12-20 10:17:45 jcastillo Exp $ */
2
#define ASC_VERSION "3.1E"    /* AdvanSys Driver Version */
3
 
4
/*
5
 * advansys.c - Linux Host Driver for AdvanSys SCSI Adapters
6
 *
7
 * Copyright (c) 1995-1998 Advanced System Products, Inc.
8
 * All Rights Reserved.
9
 *
10
 * Redistribution and use in source and binary forms, with or without
11
 * modification, are permitted provided that redistributions of source
12
 * code retain the above copyright notice and this comment without
13
 * modification.
14
 *
15
 * There is an AdvanSys Linux WWW page at:
16
 *  http://www.advansys.com/linux.html
17
 *
18
 * The latest version of the AdvanSys driver is available at:
19
 *  ftp://ftp.advansys.com/pub/linux/linux.tgz
20
 *
21
 * Please send questions, comments, bug reports to:
22
 *  bobf@advansys.com (Bob Frey)
23
 */
24
 
25
/*
26
 
27
  Documentation for the AdvanSys Driver
28
 
29
  A. Linux Kernel Testing
30
  B. Adapters Supported by this Driver
31
  C. Linux v1.2.X - Directions for Adding the AdvanSys Driver
32
  D. Linux v1.3.1 - v1.3.57 - Directions for Adding the AdvanSys Driver
33
  E. Linux v1.3.58 and Newer - Upgrading the AdvanSys Driver
34
  F. Source Comments
35
  G. Driver Compile Time Options and Debugging
36
  H. Driver LILO Option
37
  I. Release History
38
  J. Known Problems or Issues
39
  K. Credits
40
  L. AdvanSys Contact Information
41
 
42
  A. Linux Kernel Testing
43
 
44
     This driver has been tested in the following Linux kernels: v1.2.13,
45
     v1.3.57, v2.0.33, v2.1.77. These kernel versions are major releases
46
     of Linux or the latest Linux kernel versions available when this version
47
     of the driver was released. The driver should also work in earlier
48
     versions of the Linux kernel. Beginning with v1.3.58 the AdvanSys driver
49
     is included with all Linux kernels. Please refer to sections C, D, and
50
     E for instructions on adding or upgrading the AdvanSys driver.
51
 
52
  B. Adapters Supported by this Driver
53
 
54
     AdvanSys (Advanced System Products, Inc.) manufactures the following
55
     RISC-based, Bus-Mastering, Fast (10 Mhz) and Ultra (20 Mhz) Narrow
56
     (8-bit transfer) SCSI Host Adapters for the ISA, EISA, VL, and PCI
57
     buses and RISC-based, Bus-Mastering, Ultra (20 Mhz) Wide (16-bit
58
     transfer) SCSI Host Adapters for the PCI bus.
59
 
60
     The CDB counts below indicate the number of SCSI CDB (Command
61
     Descriptor Block) requests that can be stored in the RISC chip
62
     cache and board LRAM. A CDB is a single SCSI command. The driver
63
     detect routine will display the number of CDBs available for each
64
     adapter detected. The number of CDBs used by the driver can be
65
     lowered in the BIOS by changing the 'Host Queue Size' adapter setting.
66
 
67
     Connectivity Products:
68
        ABP510/5150 - Bus-Master ISA (240 CDB) (Footnote 1)
69
        ABP5140 - Bus-Master ISA PnP (16 CDB) (Footnote 1, 3)
70
        ABP5142 - Bus-Master ISA PnP with floppy (16 CDB) (Footnote 4)
71
        ABP920 - Bus-Master PCI (16 CDB)
72
        ABP930 - Bus-Master PCI (16 CDB) (Footnote 5)
73
        ABP930U - Bus-Master PCI Ultra (16 CDB)
74
        ABP930UA - Bus-Master PCI Ultra (16 CDB)
75
        ABP960 - Bus-Master PCI MAC/PC (16 CDB) (Footnote 2)
76
        ABP960U - Bus-Master PCI MAC/PC Ultra (16 CDB) (Footnote 2)
77
 
78
     Single Channel Products:
79
        ABP542 - Bus-Master ISA with floppy (240 CDB)
80
        ABP742 - Bus-Master EISA (240 CDB)
81
        ABP842 - Bus-Master VL (240 CDB)
82
        ABP940 - Bus-Master PCI (240 CDB)
83
        ABP940U - Bus-Master PCI Ultra (240 CDB)
84
        ABP970 - Bus-Master PCI MAC/PC (240 CDB)
85
        ABP970U - Bus-Master PCI MAC/PC Ultra (240 CDB)
86
        ABP940UW - Bus-Master PCI Ultra-Wide (240 CDB)
87
 
88
     Multi Channel Products:
89
        ABP752 - Dual Channel Bus-Master EISA (240 CDB Per Channel)
90
        ABP852 - Dual Channel Bus-Master VL (240 CDB Per Channel)
91
        ABP950 - Dual Channel Bus-Master PCI (240 CDB Per Channel)
92
        ABP980 - Four Channel Bus-Master PCI (240 CDB Per Channel)
93
        ABP980U - Four Channel Bus-Master PCI Ultra (240 CDB Per Channel)
94
 
95
     Footnotes:
96
       1. This board has been shipped by HP with the 4020i CD-R drive.
97
          The board has no BIOS so it cannot control a boot device, but
98
          it can control any secondary SCSI device.
99
       2. This board has been sold by Iomega as a Jaz Jet PCI adapter.
100
       3. This board has been sold by SIIG as the i540 SpeedMaster.
101
       4. This board has been sold by SIIG as the i542 SpeedMaster.
102
       5. This board has been sold by SIIG as the Fast SCSI Pro PCI.
103
 
104
  C. Linux v1.2.X - Directions for Adding the AdvanSys Driver
105
 
106
     These directions apply to v1.2.13. For versions that follow v1.2.13.
107
     but precede v1.3.57 some of the changes for Linux v1.3.X listed
108
     below may need to be modified or included. A patch is available
109
     for v1.2.13 from the AdvanSys WWW and FTP sites.
110
 
111
     There are two source files: advansys.h and advansys.c. Copy
112
     both of these files to the directory /usr/src/linux/drivers/scsi.
113
 
114
     1. Add the following line to /usr/src/linux/arch/i386/config.in
115
        after "comment 'SCSI low-level drivers'":
116
 
117
          bool 'AdvanSys SCSI support' CONFIG_SCSI_ADVANSYS y
118
 
119
     2. Add the following lines to /usr/src/linux/drivers/scsi/hosts.c
120
        after "#include "hosts.h"":
121
 
122
          #ifdef CONFIG_SCSI_ADVANSYS
123
          #include "advansys.h"
124
          #endif
125
 
126
        and after "static Scsi_Host_Template builtin_scsi_hosts[] =":
127
 
128
          #ifdef CONFIG_SCSI_ADVANSYS
129
          ADVANSYS,
130
          #endif
131
 
132
     3. Add the following lines to /usr/src/linux/drivers/scsi/Makefile:
133
 
134
          ifdef CONFIG_SCSI_ADVANSYS
135
          SCSI_SRCS := $(SCSI_SRCS) advansys.c
136
          SCSI_OBJS := $(SCSI_OBJS) advansys.o
137
          else
138
          SCSI_MODULE_OBJS := $(SCSI_MODULE_OBJS) advansys.o
139
          endif
140
 
141
     4. (Optional) If you would like to enable the LILO command line
142
        and /etc/lilo.conf 'advansys' option, make the following changes.
143
        This option can be used to disable I/O port scanning or to limit
144
        I/O port scanning to specific addresses. Refer to the 'Driver
145
        LILO Option' section below. Add the following lines to
146
        /usr/src/linux/init/main.c in the prototype section:
147
 
148
          extern void advansys_setup(char *str, int *ints);
149
 
150
        and add the following lines to the bootsetups[] array.
151
 
152
          #ifdef CONFIG_SCSI_ADVANSYS
153
             { "advansys=", advansys_setup },
154
          #endif
155
 
156
     5. If you have the HP 4020i CD-R driver and Linux v1.2.X you should
157
        add a fix to the CD-ROM target driver. This fix will allow
158
        you to mount CDs with the iso9660 file system. Linux v1.3.X
159
        already has this fix. In the file /usr/src/linux/drivers/scsi/sr.c
160
        and function get_sectorsize() after the line:
161
 
162
        if(scsi_CDs[i].sector_size == 0) scsi_CDs[i].sector_size = 2048;
163
 
164
        add the following line:
165
 
166
        if(scsi_CDs[i].sector_size == 2340) scsi_CDs[i].sector_size = 2048;
167
 
168
     6. In the directory /usr/src/linux run 'make config' to configure
169
        the AdvanSys driver, then run 'make vmlinux' or 'make zlilo' to
170
        make the kernel. If the AdvanSys driver is not configured, then
171
        a loadable module can be built by running 'make modules' and
172
        'make modules_install'. Use 'insmod' and 'rmmod' to install
173
        and remove advansys.o.
174
 
175
  D. Linux v1.3.1 - v1.3.57 - Directions for Adding the AdvanSys Driver
176
 
177
     These directions apply to v1.3.57. For versions that precede v1.3.57
178
     some of these changes may need to be modified or eliminated. A patch
179
     is available for v1.3.57 from the AdvanSys WWW and FTP sites.
180
     Beginning with v1.3.58 this driver is included with the Linux
181
     distribution eliminating the need for making any changes.
182
 
183
     There are two source files: advansys.h and advansys.c. Copy
184
     both of these files to the directory /usr/src/linux/drivers/scsi.
185
 
186
     1. Add the following line to /usr/src/linux/drivers/scsi/Config.in
187
        after "comment 'SCSI low-level drivers'":
188
 
189
          dep_tristate 'AdvanSys SCSI support' CONFIG_SCSI_ADVANSYS $CONFIG_SCSI
190
 
191
     2. Add the following lines to /usr/src/linux/drivers/scsi/hosts.c
192
        after "#include "hosts.h"":
193
 
194
          #ifdef CONFIG_SCSI_ADVANSYS
195
          #include "advansys.h"
196
          #endif
197
 
198
        and after "static Scsi_Host_Template builtin_scsi_hosts[] =":
199
 
200
          #ifdef CONFIG_SCSI_ADVANSYS
201
          ADVANSYS,
202
          #endif
203
 
204
     3. Add the following lines to /usr/src/linux/drivers/scsi/Makefile:
205
 
206
          ifeq ($(CONFIG_SCSI_ADVANSYS),y)
207
          L_OBJS += advansys.o
208
          else
209
            ifeq ($(CONFIG_SCSI_ADVANSYS),m)
210
            M_OBJS += advansys.o
211
            endif
212
          endif
213
 
214
     4. Add the following line to /usr/src/linux/include/linux/proc_fs.h
215
        in the enum scsi_directory_inos array:
216
 
217
          PROC_SCSI_ADVANSYS,
218
 
219
     5. (Optional) If you would like to enable the LILO command line
220
        and /etc/lilo.conf 'advansys' option, make the following changes.
221
        This option can be used to disable I/O port scanning or to limit
222
        I/O port scanning to specific addresses. Refer to the 'Driver
223
        LILO Option' section below. Add the following lines to
224
        /usr/src/linux/init/main.c in the prototype section:
225
 
226
          extern void advansys_setup(char *str, int *ints);
227
 
228
        and add the following lines to the bootsetups[] array.
229
 
230
          #ifdef CONFIG_SCSI_ADVANSYS
231
             { "advansys=", advansys_setup },
232
          #endif
233
 
234
     6. In the directory /usr/src/linux run 'make config' to configure
235
        the AdvanSys driver, then run 'make vmlinux' or 'make zlilo' to
236
        make the kernel. If the AdvanSys driver is not configured, then
237
        a loadable module can be built by running 'make modules' and
238
        'make modules_install'. Use 'insmod' and 'rmmod' to install
239
        and remove advansys.o.
240
 
241
  E. Linux v1.3.58 and Newer - Upgrading the AdvanSys Driver
242
 
243
     To upgrade the AdvanSys driver in a Linux v1.3.58 and newer
244
     kernel, first check the version of the current driver. The
245
     version is defined by the manifest constant ASC_VERSION at
246
     the beginning of advansys.c. The new driver should have a
247
     ASC_VERSION value greater than the current version. To install
248
     the new driver rename advansys.c and advansys.h in the Linux
249
     kernel source tree drivers/scsi directory to different names
250
     or save them to a different directory in case you want to revert
251
     to the old version of the driver. After the old driver is saved
252
     copy the new advansys.c and advansys.h to drivers/scsi, rebuild
253
     the kernel, and install the new kernel. No other changes are needed.
254
 
255
  F. Source Comments
256
 
257
     1. Use tab stops set to 4 for the source files. For vi use 'se tabstops=4'.
258
 
259
     2. This driver should be maintained in multiple files. But to make
260
        it easier to include with Linux and to follow Linux conventions,
261
        the whole driver is maintained in the source files advansys.h and
262
        advansys.c. In this file logical sections of the driver begin with
263
        a comment that contains '---'. The following are the logical sections
264
        of the driver below.
265
 
266
           --- Linux Version
267
           --- Linux Include Files
268
           --- Driver Options
269
           --- Debugging Header
270
           --- Asc Library Constants and Macros
271
           --- Adv Library Constants and Macros
272
           --- Driver Constants and Macros
273
           --- Driver Structures
274
           --- Driver Data
275
           --- Driver Function Prototypes
276
           --- Linux 'Scsi_Host_Template' and advansys_setup() Functions
277
           --- Loadable Driver Support
278
           --- Miscellaneous Driver Functions
279
           --- Functions Required by the Asc Library
280
           --- Functions Required by the Adv Library
281
           --- Tracing and Debugging Functions
282
           --- Asc Library Functions
283
           --- Adv Library Functions
284
 
285
     3. The string 'XXX' is used to flag code that needs to be re-written
286
        or that contains a problem that needs to be addressed.
287
 
288
     4. I have stripped comments from and reformatted the source for the
289
        Asc Library and Adv Library to reduce the size of this file. This
290
        source can be found under the following headings. The Asc Library
291
        is used to support Narrow Boards. The Adv Library is used to
292
        support Wide Boards.
293
 
294
           --- Asc Library Constants and Macros
295
           --- Adv Library Constants and Macros
296
           --- Asc Library Functions
297
           --- Adv Library Functions
298
 
299
  G. Driver Compile Time Options and Debugging
300
 
301
     In this source file the following constants can be defined. They are
302
     defined in the source below. Both of these options are enabled by
303
     default.
304
 
305
     1. ADVANSYS_ASSERT - Enable driver assertions (Def: Enabled)
306
 
307
        Enabling this option adds assertion logic statements to the
308
        driver. If an assertion fails a message will be displayed to
309
        the console, but the system will continue to operate. Any
310
        assertions encountered should be reported to the person
311
        responsible for the driver. Assertion statements may proactively
312
        detect problems with the driver and facilitate fixing these
313
        problems. Enabling assertions will add a small overhead to the
314
        execution of the driver.
315
 
316
     2. ADVANSYS_DEBUG - Enable driver debugging (Def: Disabled)
317
 
318
        Enabling this option adds tracing functions to the driver and
319
        the ability to set a driver tracing level at boot time. This
320
        option will also export symbols not required outside the driver to
321
        the kernel name space. This option is very useful for debugging
322
        the driver, but it will add to the size of the driver execution
323
        image and add overhead to the execution of the driver.
324
 
325
        The amount of debugging output can be controlled with the global
326
        variable 'asc_dbglvl'. The higher the number the more output. By
327
        default the debug level is 0.
328
 
329
        If the driver is loaded at boot time and the LILO Driver Option
330
        is included in the system, the debug level can be changed by
331
        specifying a 5th (ASC_NUM_IOPORT_PROBE + 1) I/O Port. The
332
        first three hex digits of the pseudo I/O Port must be set to
333
        'deb' and the fourth hex digit specifies the debug level: 0 - F.
334
        The following command line will look for an adapter at 0x330
335
        and set the debug level to 2.
336
 
337
           linux advansys=0x330,0,0,0,0xdeb2
338
 
339
        If the driver is built as a loadable module this variable can be
340
        defined when the driver is loaded. The following insmod command
341
        will set the debug level to one.
342
 
343
           insmod advansys.o asc_dbglvl=1
344
 
345
        Debugging Message Levels:
346
           0: Errors Only
347
           1: High-Level Tracing
348
           2-N: Verbose Tracing
349
 
350
        I don't know the approved way for turning on printk()s to the
351
        console. Here's a program I use to do this. Debug output is
352
        logged in /var/adm/messages.
353
 
354
          main()
355
          {
356
                  syscall(103, 7, 0, 0);
357
          }
358
 
359
        I found that increasing LOG_BUF_LEN to 40960 in kernel/printk.c
360
        prevents most level 1 debug messages from being lost.
361
 
362
     3. ADVANSYS_STATS - Enable statistics (Def: Enabled >= v1.3.0)
363
 
364
        Enabling this option adds statistics collection and display
365
        through /proc to the driver. The information is useful for
366
        monitoring driver and device performance. It will add to the
367
        size of the driver execution image and add minor overhead to
368
        the execution of the driver.
369
 
370
        Statistics are maintained on a per adapter basis. Driver entry
371
        point call counts and transfer size counts are maintained.
372
        Statistics are only available for kernels greater than or equal
373
        to v1.3.0 with the CONFIG_PROC_FS (/proc) file system configured.
374
 
375
        AdvanSys SCSI adapter files have the following path name format:
376
 
377
           /proc/scsi/advansys/[0-(ASC_NUM_BOARD_SUPPORTED-1)]
378
 
379
        This information can be displayed with cat. For example:
380
 
381
           cat /proc/scsi/advansys/0
382
 
383
        When ADVANSYS_STATS is not defined the AdvanSys /proc files only
384
        contain adapter and device configuration information.
385
 
386
  H. Driver LILO Option
387
 
388
     If init/main.c is modified as described in the 'Directions for Adding
389
     the AdvanSys Driver to Linux' section (B.4.) above, the driver will
390
     recognize the 'advansys' LILO command line and /etc/lilo.conf option.
391
     This option can be used to either disable I/O port scanning or to limit
392
     scanning to 1 - 4 I/O ports. Regardless of the option setting EISA and
393
     PCI boards will still be searched for and detected. This option only
394
     affects searching for ISA and VL boards.
395
 
396
     Examples:
397
       1. Eliminate I/O port scanning:
398
            boot: linux advansys=
399
              or
400
            boot: linux advansys=0x0
401
       2. Limit I/O port scanning to one I/O port:
402
            boot: linux advansys=0x110
403
       3. Limit I/O port scanning to four I/O ports:
404
            boot: linux advansys=0x110,0x210,0x230,0x330
405
 
406
     For a loadable module the same effect can be achieved by setting
407
     the 'asc_iopflag' variable and 'asc_ioport' array when loading
408
     the driver, e.g.
409
 
410
           insmod advansys.o asc_iopflag=1 asc_ioport=0x110,0x330
411
 
412
     If ADVANSYS_DEBUG is defined a 5th (ASC_NUM_IOPORT_PROBE + 1)
413
     I/O Port may be added to specify the driver debug level. Refer to
414
     the 'Driver Compile Time Options and Debugging' section above for
415
     more information.
416
 
417
  I. Release History
418
 
419
     BETA-1.0 (12/23/95):
420
         First Release
421
 
422
     BETA-1.1 (12/28/95):
423
         1. Prevent advansys_detect() from being called twice.
424
         2. Add LILO 0xdeb[0-f] option to set 'asc_dbglvl'.
425
 
426
     1.2 (1/12/96):
427
         1. Prevent re-entrancy in the interrupt handler which
428
            resulted in the driver hanging Linux.
429
         2. Fix problem that prevented ABP-940 cards from being
430
            recognized on some PCI motherboards.
431
         3. Add support for the ABP-5140 PnP ISA card.
432
         4. Fix check condition return status.
433
         5. Add conditionally compiled code for Linux v1.3.X.
434
 
435
     1.3 (2/23/96):
436
         1. Fix problem in advansys_biosparam() that resulted in the
437
            wrong drive geometry being returned for drives > 1GB with
438
            extended translation enabled.
439
         2. Add additional tracing during device initialization.
440
         3. Change code that only applies to ISA PnP adapter.
441
         4. Eliminate 'make dep' warning.
442
         5. Try to fix problem with handling resets by increasing their
443
            timeout value.
444
 
445
     1.4 (5/8/96):
446
         1. Change definitions to eliminate conflicts with other subsystems.
447
         2. Add versioning code for the shared interrupt changes.
448
         3. Eliminate problem in asc_rmqueue() with iterating after removing
449
            a request.
450
         4. Remove reset request loop problem from the "Known Problems or
451
            Issues" section. This problem was isolated and fixed in the
452
            mid-level SCSI driver.
453
 
454
     1.5 (8/8/96):
455
         1. Add support for ABP-940U (PCI Ultra) adapter.
456
         2. Add support for IRQ sharing by setting the SA_SHIRQ flag for
457
            request_irq and supplying a dev_id pointer to both request_irq()
458
            and free_irq().
459
         3. In AscSearchIOPortAddr11() restore a call to check_region() which
460
            should be used before I/O port probing.
461
         4. Fix bug in asc_prt_hex() which resulted in the displaying
462
            the wrong data.
463
         5. Incorporate miscellaneous Asc Library bug fixes and new microcode.
464
         6. Change driver versioning to be specific to each Linux sub-level.
465
         7. Change statistics gathering to be per adapter instead of global
466
            to the driver.
467
         8. Add more information and statistics to the adapter /proc file:
468
            /proc/scsi/advansys[0...].
469
         9. Remove 'cmd_per_lun' from the "Known Problems or Issues" list.
470
            This problem has been addressed with the SCSI mid-level changes
471
            made in v1.3.89. The advansys_select_queue_depths() function
472
            was added for the v1.3.89 changes.
473
 
474
     1.6 (9/10/96):
475
         1. Incorporate miscellaneous Asc Library bug fixes and new microcode.
476
 
477
     1.7 (9/25/96):
478
         1. Enable clustering and optimize the setting of the maximum number
479
            of scatter gather elements for any particular board. Clustering
480
            increases CPU utilization, but results in a relatively larger
481
            increase in I/O throughput.
482
         2. Improve the performance of the request queuing functions by
483
            adding a last pointer to the queue structure.
484
         3. Correct problems with reset and abort request handling that
485
            could have hung or crashed Linux.
486
         4. Add more information to the adapter /proc file:
487
            /proc/scsi/advansys[0...].
488
         5. Remove the request timeout issue form the driver issues list.
489
         6. Miscellaneous documentation additions and changes.
490
 
491
     1.8 (10/4/96):
492
         1. Make changes to handle the new v2.1.0 kernel memory mapping
493
            in which a kernel virtual address may not be equivalent to its
494
            bus or DMA memory address.
495
         2. Change abort and reset request handling to make it yet even
496
            more robust.
497
         3. Try to mitigate request starvation by sending ordered requests
498
            to heavily loaded, tag queuing enabled devices.
499
         4. Maintain statistics on request response time.
500
         5. Add request response time statistics and other information to
501
            the adapter /proc file: /proc/scsi/advansys[0...].
502
 
503
     1.9 (10/21/96):
504
         1. Add conditionally compiled code (ASC_QUEUE_FLOW_CONTROL) to
505
            make use of mid-level SCSI driver device queue depth flow
506
            control mechanism. This will eliminate aborts caused by a
507
            device being unable to keep up with requests and eliminate
508
            repeat busy or QUEUE FULL status returned by a device.
509
         2. Incorporate miscellaneous Asc Library bug fixes.
510
         3. To allow the driver to work in kernels with broken module
511
            support set 'cmd_per_lun' if the driver is compiled as a
512
            module. This change affects kernels v1.3.89 to present.
513
         4. Remove PCI BIOS address from the driver banner. The PCI BIOS
514
            is relocated by the motherboard BIOS and its new address can
515
            not be determined by the driver.
516
         5. Add mid-level SCSI queue depth information to the adapter
517
            /proc file: /proc/scsi/advansys[0...].
518
 
519
     2.0 (11/14/96):
520
         1. Change allocation of global structures used for device
521
            initialization to guarantee they are in DMA-able memory.
522
            Previously when the driver was loaded as a module these
523
            structures might not have been in DMA-able memory, causing
524
            device initialization to fail.
525
 
526
     2.1 (12/30/96):
527
         1. In advansys_reset(), if the request is a synchronous reset
528
            request, even if the request serial number has changed, then
529
            complete the request.
530
         2. Add Asc Library bug fixes including new microcode.
531
         3. Clear inquiry buffer before using it.
532
         4. Correct ifdef typo.
533
 
534
     2.2 (1/15/97):
535
         1. Add Asc Library bug fixes including new microcode.
536
         2. Add synchronous data transfer rate information to the
537
            adapter /proc file: /proc/scsi/advansys[0...].
538
         3. Change ADVANSYS_DEBUG to be disabled by default. This
539
            will reduce the size of the driver image, eliminate execution
540
            overhead, and remove unneeded symbols from the kernel symbol
541
            space that were previously added by the driver.
542
         4. Add new compile-time option ADVANSYS_ASSERT for assertion
543
            code that used to be defined within ADVANSYS_DEBUG. This
544
            option is enabled by default.
545
 
546
     2.8 (5/26/97):
547
         1. Change version number to 2.8 to synchronize the Linux driver
548
            version numbering with other AdvanSys drivers.
549
         2. Reformat source files without tabs to present the same view
550
            of the file to everyone regardless of the editor tab setting
551
            being used.
552
         3. Add Asc Library bug fixes.
553
 
554
     3.1A (1/8/98):
555
         1. Change version number to 3.1 to indicate that support for
556
            Ultra-Wide adapters (ABP-940UW) is included in this release.
557
         2. Add Asc Library (Narrow Board) bug fixes.
558
         3. Report an underrun condition with the host status byte set
559
            to DID_UNDERRUN. Currently DID_UNDERRUN is defined to 0 which
560
            causes the underrun condition to be ignored. When Linux defines
561
            its own DID_UNDERRUN the constant defined in this file can be
562
            removed.
563
         4. Add patch to AscWaitTixISRDone().
564
         5. Add support for up to 16 different AdvanSys host adapter SCSI
565
            channels in one system. This allows four cards with four channels
566
            to be used in one system.
567
 
568
     3.1B (1/9/98):
569
         1. Handle that PCI register base addresses are not always page
570
            aligned even though ioremap() requires that the address argument
571
            be page aligned.
572
 
573
     3.1C (1/10/98):
574
         1. Update latest BIOS version checked for from the /proc file.
575
         2. Don't set microcode SDTR variable at initialization. Instead
576
            wait until device capabilities have been detected from an Inquiry
577
            command.
578
 
579
     3.1D (1/21/98):
580
         1. Improve performance when the driver is compiled as module by
581
            allowing up to 64 scatter-gather elements instead of 8.
582
 
583
     3.1E (5/1/98):
584
         1. Set time delay in AscWaitTixISRDone() to 1000 ms.
585
         2. Include SMP locking changes.
586
         3. For v2.1.93 and newer kernels use CONFIG_PCI and new PCI BIOS
587
            access functions.
588
         4. Update board serial number printing.
589
         5. Try allocating an IRQ both with and without the SA_INTERRUPT
590
            flag set to allow IRQ sharing with drivers that do not set
591
            the SA_INTERRUPT flag. Also display a more descriptive error
592
            message if request_irq() fails.
593
         5. Update to latest Asc and Adv Libraries.
594
 
595
  J. Known Problems or Issues
596
 
597
         1. Remove conditional constants (ASC_QUEUE_FLOW_CONTROL) around
598
            the queue depth flow control code when mid-level SCSI changes
599
            are included in Linux.
600
 
601
  K. Credits
602
 
603
     Nathan Hartwell <mage@cdc3.cdc.net> provided the directions and
604
     basis for the Linux v1.3.X changes which were included in the
605
     1.2 release.
606
 
607
     Thomas E Zerucha <zerucha@shell.portal.com> pointed out a bug
608
     in advansys_biosparam() which was fixed in the 1.3 release.
609
 
610
     Erik Ratcliffe <erik@caldera.com> has done testing of the
611
     AdvanSys driver in the Caldera releases.
612
 
613
     Rik van Riel <H.H.vanRiel@fys.ruu.nl> provided a patch to
614
     AscWaitTixISRDone() which he found necessary to make the
615
     driver work with a SCSI-1 disk.
616
 
617
     Mark Moran <mmoran@mmoran.com> has helped test Ultra-Wide
618
     support in the 3.1A driver.
619
 
620
  L. AdvanSys Contact Information
621
 
622
     Mail:                   Advanced System Products, Inc.
623
                             1150 Ringwood Court
624
                             San Jose, CA 95131
625
     Operator:               1-408-383-9400
626
     FAX:                    1-408-383-9612
627
     Tech Support:           1-800-525-7440/1-408-467-2930
628
     BBS:                    1-408-383-9540 (14400,N,8,1)
629
     Interactive FAX:        1-408-383-9753
630
     Customer Direct Sales:  1-800-525-7443/1-408-383-5777
631
     Tech Support E-Mail:    support@advansys.com
632
     FTP Site:               ftp.advansys.com (login: anonymous)
633
     Web Site:               http://www.advansys.com
634
 
635
*/
636
 
637
 
638
/*
639
 * --- Linux Version
640
 */
641
 
642
/* Convert Linux Version, Patch-level, Sub-level to LINUX_VERSION_CODE. */
643
#define ASC_LINUX_VERSION(V, P, S)    (((V) * 65536) + ((P) * 256) + (S))
644
 
645
#ifndef LINUX_VERSION_CODE
646
#include <linux/version.h>
647
#endif /* LINUX_VERSION_CODE */
648
 
649
 
650
/*
651
 * --- Linux Include Files
652
 */
653
 
654
#include <linux/config.h>
655
#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
656
#ifdef MODULE
657
#include <linux/module.h>
658
#endif /* MODULE */
659
#endif /* version >= v1.3.0 */
660
#include <linux/string.h>
661
#include <linux/sched.h>
662
#include <linux/kernel.h>
663
#include <linux/head.h>
664
#include <linux/types.h>
665
#include <linux/ioport.h>
666
#include <linux/delay.h>
667
#include <linux/malloc.h>
668
#include <linux/mm.h>
669
#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
670
#include <linux/proc_fs.h>
671
#endif /* version >= v1.3.0 */
672
#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(2,1,23)
673
#include <linux/init.h>
674
#endif /* version >= v2.1.23 */
675
#include <asm/io.h>
676
#include <asm/system.h>
677
#include <asm/dma.h>
678
#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0)
679
#include "../block/blk.h"
680
#else /* version >= v1.3.0 */
681
#include <linux/blk.h>
682
#include <linux/stat.h>
683
#endif /* version >= v1.3.0 */
684
#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(2,1,95)
685
#include <asm/spinlock.h>
686
#endif /* version >= 2.1.95 */
687
#include "scsi.h"
688
#include "hosts.h"
689
#include "sd.h"
690
#include "advansys.h"
691
#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(2,1,93)
692
#ifdef CONFIG_PCI
693
#include <linux/pci.h>
694
#endif /* CONFIG_PCI */
695
#else /* version < v2.1.93 */
696
/*
697
 * For earlier than v2.1.93 the driver has its own PCI configuration.
698
 * If PCI is not needed in a kernel before v2.1.93 this define can be
699
 * turned-off to make the driver object smaller.
700
 */
701
#define ASC_CONFIG_PCI
702
#endif /* version < v2.1.93 */
703
 
704
/*
705
 * If Linux eventually defines a DID_UNDERRUN, the constant here can be
706
 * removed. The current value of zero for DID_UNDERRUN results in underrun
707
 * conditions being ignored.
708
 */
709
#define DID_UNDERRUN 0
710
 
711
 
712
/*
713
 * --- Driver Options
714
 */
715
 
716
/* Enable driver assertions. */
717
#define ADVANSYS_ASSERT
718
 
719
/* Enable driver tracing. */
720
/* #define ADVANSYS_DEBUG */
721
 
722
/*
723
 * Because of no /proc to display them, statistics are disabled
724
 * for versions prior to v1.3.0.
725
 */
726
#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0)
727
#undef ADVANSYS_STATS /* Disable statistics */
728
#else /* version >= v1.3.0 */
729
#define ADVANSYS_STATS /* Enable statistics. */
730
#endif /* version >= v1.3.0 */
731
 
732
 
733
/*
734
 * --- Debugging Header
735
 */
736
 
737
#ifdef ADVANSYS_DEBUG
738
#define STATIC
739
#else /* ADVANSYS_DEBUG */
740
#define STATIC static
741
#endif /* ADVANSYS_DEBUG */
742
 
743
 
744
/*
745
 * --- Asc Library Constants and Macros
746
 */
747
 
748
#define ASC_LIB_VERSION_MAJOR  1
749
#define ASC_LIB_VERSION_MINOR  22
750
#define ASC_LIB_SERIAL_NUMBER  113
751
 
752
typedef unsigned char uchar;
753
 
754
#ifndef NULL
755
#define NULL     (0)
756
#endif
757
#ifndef TRUE
758
#define TRUE     (1)
759
#endif
760
#ifndef FALSE
761
#define FALSE    (0)
762
#endif
763
#define  REG     register
764
#define rchar    REG __s8
765
#define rshort   REG __s16
766
#define rint     REG __s32
767
#define rlong    REG __s32
768
#define ruchar   REG __u8
769
#define rushort  REG __u16
770
#define ruint    REG __u32
771
#define rulong   REG __u32
772
#define NULLPTR  (void *)0
773
#define FNULLPTR (void *)0UL
774
#define EOF      (-1)
775
#define EOS      '\0'
776
#define ERR      (-1)
777
#define UB_ERR   (uchar)(0xFF)
778
#define UW_ERR   (uint)(0xFFFF)
779
#define UL_ERR   (ulong)(0xFFFFFFFFUL)
780
#define iseven_word(val)  ((((uint)val) & (uint)0x0001) == 0)
781
#define isodd_word(val)   ((((uint)val) & (uint)0x0001) != 0)
782
#define toeven_word(val)  (((uint)val) & (uint)0xFFFE)
783
#define biton(val, bits)   (((uint)(val >> bits) & (uint)0x0001) != 0)
784
#define bitoff(val, bits)  (((uint)(val >> bits) & (uint)0x0001) == 0)
785
#define lbiton(val, bits)  (((ulong)(val >> bits) & (ulong)0x00000001UL) != 0)
786
#define lbitoff(val, bits) (((ulong)(val >> bits) & (ulong)0x00000001UL) == 0)
787
#define  absh(val)    ((val) < 0 ? -(val) : (val))
788
#define  swapbyte(ch)  ((((ch) << 4) | ((ch) >> 4)))
789
#ifndef GBYTE
790
#define GBYTE       (0x40000000UL)
791
#endif
792
#ifndef MBYTE
793
#define MBYTE       (0x100000UL)
794
#endif
795
#ifndef KBYTE
796
#define KBYTE       (0x400)
797
#endif
798
#define HI_BYTE(x) (*((__u8 *)(&x)+1))
799
#define LO_BYTE(x) (*((__u8 *)&x))
800
#define HI_WORD(x) (*((__u16 *)(&x)+1))
801
#define LO_WORD(x) (*((__u16 *)&x))
802
#ifndef MAKEWORD
803
#define MAKEWORD(lo, hi)    ((__u16) (((__u16) lo) | ((__u16) hi << 8)))
804
#endif
805
#ifndef MAKELONG
806
#define MAKELONG(lo, hi)    ((__u32) (((__u32) lo) | ((__u32) hi << 16)))
807
#endif
808
#define SwapWords(dWord)        ((__u32) ((dWord >> 16) | (dWord << 16)))
809
#define SwapBytes(word)         ((__u16) ((word >> 8) | (word << 8)))
810
#define BigToLittle(dWord) ((__u32) (SwapWords(MAKELONG(SwapBytes(LO_WORD(dWord)), SwapBytes(HI_WORD(dWord))))))
811
#define LittleToBig(dWord)      BigToLittle(dWord)
812
#define AscPCIConfigVendorIDRegister      0x0000
813
#define AscPCIConfigDeviceIDRegister      0x0002
814
#define AscPCIConfigCommandRegister       0x0004
815
#define AscPCIConfigStatusRegister        0x0006
816
#define AscPCIConfigRevisionIDRegister    0x0008
817
#define AscPCIConfigCacheSize             0x000C
818
#define AscPCIConfigLatencyTimer          0x000D
819
#define AscPCIIOBaseRegister              0x0010
820
#define AscPCICmdRegBits_IOMemBusMaster   0x0007
821
#define ASC_PCI_ID2BUS(id)    ((id) & 0xFF)
822
#define ASC_PCI_ID2DEV(id)    (((id) >> 11) & 0x1F)
823
#define ASC_PCI_ID2FUNC(id)   (((id) >> 8) & 0x7)
824
#define ASC_PCI_MKID(bus, dev, func) ((((dev) & 0x1F) << 11) | (((func) & 0x7) << 8) | ((bus) & 0xFF))
825
#define ASC_PCI_VENDORID                  0x10CD
826
#define ASC_PCI_DEVICEID_1200A            0x1100
827
#define ASC_PCI_DEVICEID_1200B            0x1200
828
#define ASC_PCI_DEVICEID_ULTRA            0x1300 
829
#define ASC_PCI_REVISION_3150             0x02
830
#define ASC_PCI_REVISION_3050             0x03
831
 
832
#define  ASC_DVCLIB_CALL_DONE     (1)
833
#define  ASC_DVCLIB_CALL_FAILED   (0)
834
#define  ASC_DVCLIB_CALL_ERROR    (-1)
835
 
836
#define PortAddr            unsigned short    /* port address size  */
837
#define Ptr2Func            ulong
838
#define inp(port)           inb(port)
839
#define inpw(port)          inw(port)
840
#define inpl(port)          inl(port)
841
#define outp(port, byte)    outb((byte), (port))
842
#define outpw(port, word)   outw((word), (port))
843
#define outpl(port, long)   outl((long), (port))
844
#define ASC_MAX_SG_QUEUE    7
845
#define ASC_MAX_SG_LIST     SG_ALL
846
 
847
#define ASC_CS_TYPE  unsigned short
848
#ifndef asc_ptr_type
849
#define asc_ptr_type
850
#endif
851
 
852
#ifndef ASC_GET_PTR2FUNC
853
#define ASC_GET_PTR2FUNC(fun)  (Ptr2Func)(fun)
854
#endif
855
#define FLIP_BYTE_NIBBLE(x)    (((x<<4)& 0xFF) | (x>>4))
856
#define ASC_IS_ISA          (0x0001)
857
#define ASC_IS_ISAPNP       (0x0081)
858
#define ASC_IS_EISA         (0x0002)
859
#define ASC_IS_PCI          (0x0004)
860
#define ASC_IS_PCI_ULTRA    (0x0104)
861
#define ASC_IS_PCMCIA       (0x0008)
862
#define ASC_IS_MCA          (0x0020)
863
#define ASC_IS_VL           (0x0040)
864
#define ASC_ISA_PNP_PORT_ADDR  (0x279)
865
#define ASC_ISA_PNP_PORT_WRITE (ASC_ISA_PNP_PORT_ADDR+0x800)
866
#define ASC_IS_WIDESCSI_16  (0x0100)
867
#define ASC_IS_WIDESCSI_32  (0x0200)
868
#define ASC_IS_BIG_ENDIAN   (0x8000)
869
#define ASC_CHIP_MIN_VER_VL      (0x01)
870
#define ASC_CHIP_MAX_VER_VL      (0x07)
871
#define ASC_CHIP_MIN_VER_PCI     (0x09)
872
#define ASC_CHIP_MAX_VER_PCI     (0x0F)
873
#define ASC_CHIP_VER_PCI_BIT     (0x08)
874
#define ASC_CHIP_MIN_VER_ISA     (0x11)
875
#define ASC_CHIP_MIN_VER_ISA_PNP (0x21)
876
#define ASC_CHIP_MAX_VER_ISA     (0x27)
877
#define ASC_CHIP_VER_ISA_BIT     (0x30)
878
#define ASC_CHIP_VER_ISAPNP_BIT  (0x20)
879
#define ASC_CHIP_VER_ASYN_BUG    (0x21)
880
#define ASC_CHIP_VER_PCI             0x08
881
#define ASC_CHIP_VER_PCI_ULTRA_3150  (ASC_CHIP_VER_PCI | 0x02)
882
#define ASC_CHIP_VER_PCI_ULTRA_3050  (ASC_CHIP_VER_PCI | 0x03)
883
#define ASC_CHIP_MIN_VER_EISA (0x41)
884
#define ASC_CHIP_MAX_VER_EISA (0x47)
885
#define ASC_CHIP_VER_EISA_BIT (0x40)
886
#define ASC_CHIP_LATEST_VER_EISA   ((ASC_CHIP_MIN_VER_EISA - 1) + 3)
887
#define ASC_MAX_LIB_SUPPORTED_ISA_CHIP_VER   0x21
888
#define ASC_MAX_LIB_SUPPORTED_PCI_CHIP_VER   0x0A
889
#define ASC_MAX_VL_DMA_ADDR     (0x07FFFFFFL)
890
#define ASC_MAX_VL_DMA_COUNT    (0x07FFFFFFL)
891
#define ASC_MAX_PCI_DMA_ADDR    (0xFFFFFFFFL)
892
#define ASC_MAX_PCI_DMA_COUNT   (0xFFFFFFFFL)
893
#define ASC_MAX_ISA_DMA_ADDR    (0x00FFFFFFL)
894
#define ASC_MAX_ISA_DMA_COUNT   (0x00FFFFFFL)
895
#define ASC_MAX_EISA_DMA_ADDR   (0x07FFFFFFL)
896
#define ASC_MAX_EISA_DMA_COUNT  (0x07FFFFFFL)
897
#ifndef inpw_noswap
898
#define inpw_noswap(port)         inpw(port)
899
#endif
900
#ifndef outpw_noswap
901
#define outpw_noswap(port, data)  outpw(port, data)
902
#endif
903
#define ASC_SCSI_ID_BITS  3
904
#define ASC_SCSI_TIX_TYPE     uchar
905
#define ASC_ALL_DEVICE_BIT_SET  0xFF
906
#ifdef ASC_WIDESCSI_16
907
#undef  ASC_SCSI_ID_BITS
908
#define ASC_SCSI_ID_BITS  4
909
#define ASC_ALL_DEVICE_BIT_SET  0xFFFF
910
#endif
911
#ifdef ASC_WIDESCSI_32
912
#undef  ASC_SCSI_ID_BITS
913
#define ASC_SCSI_ID_BITS  5
914
#define ASC_ALL_DEVICE_BIT_SET  0xFFFFFFFFL
915
#endif
916
#if ASC_SCSI_ID_BITS == 3
917
#define ASC_SCSI_BIT_ID_TYPE  uchar
918
#define ASC_MAX_TID       7
919
#define ASC_MAX_LUN       7
920
#define ASC_SCSI_WIDTH_BIT_SET  0xFF
921
#elif ASC_SCSI_ID_BITS == 4
922
#define ASC_SCSI_BIT_ID_TYPE   ushort
923
#define ASC_MAX_TID         15
924
#define ASC_MAX_LUN         7
925
#define ASC_SCSI_WIDTH_BIT_SET  0xFFFF
926
#elif ASC_SCSI_ID_BITS == 5
927
#define ASC_SCSI_BIT_ID_TYPE    ulong
928
#define ASC_MAX_TID         31
929
#define ASC_MAX_LUN         7
930
#define ASC_SCSI_WIDTH_BIT_SET  0xFFFFFFFF
931
#else
932
#error  ASC_SCSI_ID_BITS definition is wrong
933
#endif
934
#define ASC_MAX_SENSE_LEN   32
935
#define ASC_MIN_SENSE_LEN   14
936
#define ASC_MAX_CDB_LEN     12
937
#define ASC_SCSI_RESET_HOLD_TIME_US  60
938
#define SCSICMD_TestUnitReady     0x00
939
#define SCSICMD_Rewind            0x01
940
#define SCSICMD_Rezero            0x01
941
#define SCSICMD_RequestSense      0x03
942
#define SCSICMD_Format            0x04
943
#define SCSICMD_FormatUnit        0x04
944
#define SCSICMD_Read6             0x08
945
#define SCSICMD_Write6            0x0A
946
#define SCSICMD_Seek6             0x0B
947
#define SCSICMD_Inquiry           0x12
948
#define SCSICMD_Verify6           0x13
949
#define SCSICMD_ModeSelect6       0x15
950
#define SCSICMD_ModeSense6        0x1A
951
#define SCSICMD_StartStopUnit     0x1B
952
#define SCSICMD_LoadUnloadTape    0x1B
953
#define SCSICMD_ReadCapacity      0x25
954
#define SCSICMD_Read10            0x28
955
#define SCSICMD_Write10           0x2A
956
#define SCSICMD_Seek10            0x2B
957
#define SCSICMD_Erase10           0x2C
958
#define SCSICMD_WriteAndVerify10  0x2E
959
#define SCSICMD_Verify10          0x2F
960
#define SCSICMD_WriteBuffer       0x3B
961
#define SCSICMD_ReadBuffer        0x3C
962
#define SCSICMD_ReadLong          0x3E
963
#define SCSICMD_WriteLong         0x3F
964
#define SCSICMD_ReadTOC           0x43
965
#define SCSICMD_ReadHeader        0x44
966
#define SCSICMD_ModeSelect10      0x55
967
#define SCSICMD_ModeSense10       0x5A
968
#define SCSI_TYPE_DASD     0x00
969
#define SCSI_TYPE_SASD     0x01
970
#define SCSI_TYPE_PRN      0x02
971
#define SCSI_TYPE_PROC     0x03
972
#define SCSI_TYPE_WORM     0x04
973
#define SCSI_TYPE_CDROM    0x05
974
#define SCSI_TYPE_SCANNER  0x06
975
#define SCSI_TYPE_OPTMEM   0x07
976
#define SCSI_TYPE_MED_CHG  0x08
977
#define SCSI_TYPE_COMM     0x09
978
#define SCSI_TYPE_UNKNOWN  0x1F
979
#define SCSI_TYPE_NO_DVC   0xFF
980
#define ASC_SCSIDIR_NOCHK    0x00
981
#define ASC_SCSIDIR_T2H      0x08
982
#define ASC_SCSIDIR_H2T      0x10
983
#define ASC_SCSIDIR_NODATA   0x18
984
#define SCSI_SENKEY_NO_SENSE      0x00
985
#define SCSI_SENKEY_UNDEFINED     0x01
986
#define SCSI_SENKEY_NOT_READY     0x02
987
#define SCSI_SENKEY_MEDIUM_ERR    0x03
988
#define SCSI_SENKEY_HW_ERR        0x04
989
#define SCSI_SENKEY_ILLEGAL       0x05
990
#define SCSI_SENKEY_ATTENTION     0x06
991
#define SCSI_SENKEY_PROTECTED     0x07
992
#define SCSI_SENKEY_BLANK         0x08
993
#define SCSI_SENKEY_V_UNIQUE      0x09
994
#define SCSI_SENKEY_CPY_ABORT     0x0A
995
#define SCSI_SENKEY_ABORT         0x0B
996
#define SCSI_SENKEY_EQUAL         0x0C
997
#define SCSI_SENKEY_VOL_OVERFLOW  0x0D
998
#define SCSI_SENKEY_MISCOMP       0x0E
999
#define SCSI_SENKEY_RESERVED      0x0F
1000
#define SCSI_ASC_NOMEDIA          0x3A
1001
#define ASC_SRB_HOST(x)  ((uchar)((uchar)(x) >> 4))
1002
#define ASC_SRB_TID(x)   ((uchar)((uchar)(x) & (uchar)0x0F))
1003
#define ASC_SRB_LUN(x)   ((uchar)((uint)(x) >> 13))
1004
#define PUT_CDB1(x)   ((uchar)((uint)(x) >> 8))
1005
#define SS_GOOD              0x00
1006
#define SS_CHK_CONDITION     0x02
1007
#define SS_CONDITION_MET     0x04
1008
#define SS_TARGET_BUSY       0x08
1009
#define SS_INTERMID          0x10
1010
#define SS_INTERMID_COND_MET 0x14
1011
#define SS_RSERV_CONFLICT    0x18
1012
#define SS_CMD_TERMINATED    0x22
1013
#define SS_QUEUE_FULL        0x28
1014
#define MS_CMD_DONE    0x00
1015
#define MS_EXTEND      0x01
1016
#define MS_SDTR_LEN    0x03
1017
#define MS_SDTR_CODE   0x01
1018
#define MS_WDTR_LEN    0x02
1019
#define MS_WDTR_CODE   0x03
1020
#define MS_MDP_LEN    0x05
1021
#define MS_MDP_CODE   0x00
1022
#define M1_SAVE_DATA_PTR        0x02
1023
#define M1_RESTORE_PTRS         0x03
1024
#define M1_DISCONNECT           0x04
1025
#define M1_INIT_DETECTED_ERR    0x05
1026
#define M1_ABORT                0x06
1027
#define M1_MSG_REJECT           0x07
1028
#define M1_NO_OP                0x08
1029
#define M1_MSG_PARITY_ERR       0x09
1030
#define M1_LINK_CMD_DONE        0x0A
1031
#define M1_LINK_CMD_DONE_WFLAG  0x0B
1032
#define M1_BUS_DVC_RESET        0x0C
1033
#define M1_ABORT_TAG            0x0D
1034
#define M1_CLR_QUEUE            0x0E
1035
#define M1_INIT_RECOVERY        0x0F
1036
#define M1_RELEASE_RECOVERY     0x10
1037
#define M1_KILL_IO_PROC         0x11
1038
#define M2_QTAG_MSG_SIMPLE      0x20
1039
#define M2_QTAG_MSG_HEAD        0x21
1040
#define M2_QTAG_MSG_ORDERED     0x22
1041
#define M2_IGNORE_WIDE_RESIDUE  0x23
1042
 
1043
typedef struct {
1044
    uchar               peri_dvc_type:5;
1045
    uchar               peri_qualifier:3;
1046
} ASC_SCSI_INQ0;
1047
 
1048
typedef struct {
1049
    uchar               dvc_type_modifier:7;
1050
    uchar               rmb:1;
1051
} ASC_SCSI_INQ1;
1052
 
1053
typedef struct {
1054
    uchar               ansi_apr_ver:3;
1055
    uchar               ecma_ver:3;
1056
    uchar               iso_ver:2;
1057
} ASC_SCSI_INQ2;
1058
 
1059
typedef struct {
1060
    uchar               rsp_data_fmt:4;
1061
    uchar               res:2;
1062
    uchar               TemIOP:1;
1063
    uchar               aenc:1;
1064
} ASC_SCSI_INQ3;
1065
 
1066
typedef struct {
1067
    uchar               StfRe:1;
1068
    uchar               CmdQue:1;
1069
    uchar               Reserved:1;
1070
    uchar               Linked:1;
1071
    uchar               Sync:1;
1072
    uchar               WBus16:1;
1073
    uchar               WBus32:1;
1074
    uchar               RelAdr:1;
1075
} ASC_SCSI_INQ7;
1076
 
1077
typedef struct {
1078
    ASC_SCSI_INQ0       byte0;
1079
    ASC_SCSI_INQ1       byte1;
1080
    ASC_SCSI_INQ2       byte2;
1081
    ASC_SCSI_INQ3       byte3;
1082
    uchar               add_len;
1083
    uchar               res1;
1084
    uchar               res2;
1085
    ASC_SCSI_INQ7       byte7;
1086
    uchar               vendor_id[8];
1087
    uchar               product_id[16];
1088
    uchar               product_rev_level[4];
1089
} ASC_SCSI_INQUIRY;
1090
 
1091
typedef struct asc_req_sense {
1092
    uchar               err_code:7;
1093
    uchar               info_valid:1;
1094
    uchar               segment_no;
1095
    uchar               sense_key:4;
1096
    uchar               reserved_bit:1;
1097
    uchar               sense_ILI:1;
1098
    uchar               sense_EOM:1;
1099
    uchar               file_mark:1;
1100
    uchar               info1[4];
1101
    uchar               add_sense_len;
1102
    uchar               cmd_sp_info[4];
1103
    uchar               asc;
1104
    uchar               ascq;
1105
    uchar               fruc;
1106
    uchar               sks_byte0:7;
1107
    uchar               sks_valid:1;
1108
    uchar               sks_bytes[2];
1109
    uchar               notused[2];
1110
    uchar               ex_sense_code;
1111
    uchar               info2[4];
1112
} ASC_REQ_SENSE;
1113
 
1114
#define ASC_SG_LIST_PER_Q   7
1115
#define QS_FREE        0x00
1116
#define QS_READY       0x01
1117
#define QS_DISC1       0x02
1118
#define QS_DISC2       0x04
1119
#define QS_BUSY        0x08
1120
#define QS_ABORTED     0x40
1121
#define QS_DONE        0x80
1122
#define QC_NO_CALLBACK   0x01
1123
#define QC_SG_SWAP_QUEUE 0x02
1124
#define QC_SG_HEAD       0x04
1125
#define QC_DATA_IN       0x08
1126
#define QC_DATA_OUT      0x10
1127
#define QC_URGENT        0x20
1128
#define QC_MSG_OUT       0x40
1129
#define QC_REQ_SENSE     0x80
1130
#define QCSG_SG_XFER_LIST  0x02
1131
#define QCSG_SG_XFER_MORE  0x04
1132
#define QCSG_SG_XFER_END   0x08
1133
#define QD_IN_PROGRESS       0x00
1134
#define QD_NO_ERROR          0x01
1135
#define QD_ABORTED_BY_HOST   0x02
1136
#define QD_WITH_ERROR        0x04
1137
#define QD_INVALID_REQUEST   0x80
1138
#define QD_INVALID_HOST_NUM  0x81
1139
#define QD_INVALID_DEVICE    0x82
1140
#define QD_ERR_INTERNAL      0xFF
1141
#define QHSTA_NO_ERROR               0x00
1142
#define QHSTA_M_SEL_TIMEOUT          0x11
1143
#define QHSTA_M_DATA_OVER_RUN        0x12
1144
#define QHSTA_M_DATA_UNDER_RUN       0x12
1145
#define QHSTA_M_UNEXPECTED_BUS_FREE  0x13
1146
#define QHSTA_M_BAD_BUS_PHASE_SEQ    0x14
1147
#define QHSTA_D_QDONE_SG_LIST_CORRUPTED 0x21
1148
#define QHSTA_D_ASC_DVC_ERROR_CODE_SET  0x22
1149
#define QHSTA_D_HOST_ABORT_FAILED       0x23
1150
#define QHSTA_D_EXE_SCSI_Q_FAILED       0x24
1151
#define QHSTA_D_EXE_SCSI_Q_BUSY_TIMEOUT 0x25
1152
#define QHSTA_D_ASPI_NO_BUF_POOL        0x26
1153
#define QHSTA_M_WTM_TIMEOUT         0x41
1154
#define QHSTA_M_BAD_CMPL_STATUS_IN  0x42
1155
#define QHSTA_M_NO_AUTO_REQ_SENSE   0x43
1156
#define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
1157
#define QHSTA_M_TARGET_STATUS_BUSY  0x45
1158
#define QHSTA_M_BAD_TAG_CODE        0x46
1159
#define QHSTA_M_BAD_QUEUE_FULL_OR_BUSY  0x47
1160
#define QHSTA_M_HUNG_REQ_SCSI_BUS_RESET 0x48
1161
#define QHSTA_D_LRAM_CMP_ERROR        0x81
1162
#define QHSTA_M_MICRO_CODE_ERROR_HALT 0xA1
1163
#define ASC_FLAG_SCSIQ_REQ        0x01
1164
#define ASC_FLAG_BIOS_SCSIQ_REQ   0x02
1165
#define ASC_FLAG_BIOS_ASYNC_IO    0x04
1166
#define ASC_FLAG_SRB_LINEAR_ADDR  0x08
1167
#define ASC_FLAG_WIN16            0x10
1168
#define ASC_FLAG_WIN32            0x20
1169
#define ASC_FLAG_ISA_OVER_16MB    0x40
1170
#define ASC_FLAG_DOS_VM_CALLBACK  0x80
1171
#define ASC_TAG_FLAG_EXTRA_BYTES               0x10
1172
#define ASC_TAG_FLAG_DISABLE_DISCONNECT        0x04
1173
#define ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX  0x08
1174
#define ASC_TAG_FLAG_DISABLE_CHK_COND_INT_HOST 0x40
1175
#define ASC_SCSIQ_CPY_BEG              4
1176
#define ASC_SCSIQ_SGHD_CPY_BEG         2
1177
#define ASC_SCSIQ_B_FWD                0
1178
#define ASC_SCSIQ_B_BWD                1
1179
#define ASC_SCSIQ_B_STATUS             2
1180
#define ASC_SCSIQ_B_QNO                3
1181
#define ASC_SCSIQ_B_CNTL               4
1182
#define ASC_SCSIQ_B_SG_QUEUE_CNT       5
1183
#define ASC_SCSIQ_D_DATA_ADDR          8
1184
#define ASC_SCSIQ_D_DATA_CNT          12
1185
#define ASC_SCSIQ_B_SENSE_LEN         20
1186
#define ASC_SCSIQ_DONE_INFO_BEG       22
1187
#define ASC_SCSIQ_D_SRBPTR            22
1188
#define ASC_SCSIQ_B_TARGET_IX         26
1189
#define ASC_SCSIQ_B_CDB_LEN           28
1190
#define ASC_SCSIQ_B_TAG_CODE          29
1191
#define ASC_SCSIQ_W_VM_ID             30
1192
#define ASC_SCSIQ_DONE_STATUS         32
1193
#define ASC_SCSIQ_HOST_STATUS         33
1194
#define ASC_SCSIQ_SCSI_STATUS         34
1195
#define ASC_SCSIQ_CDB_BEG             36
1196
#define ASC_SCSIQ_DW_REMAIN_XFER_ADDR 56
1197
#define ASC_SCSIQ_DW_REMAIN_XFER_CNT  60
1198
#define ASC_SCSIQ_B_SG_WK_QP          49
1199
#define ASC_SCSIQ_B_SG_WK_IX          50
1200
#define ASC_SCSIQ_W_REQ_COUNT         52
1201
#define ASC_SCSIQ_B_LIST_CNT          6
1202
#define ASC_SCSIQ_B_CUR_LIST_CNT      7
1203
#define ASC_SGQ_B_SG_CNTL             4
1204
#define ASC_SGQ_B_SG_HEAD_QP          5
1205
#define ASC_SGQ_B_SG_LIST_CNT         6
1206
#define ASC_SGQ_B_SG_CUR_LIST_CNT     7
1207
#define ASC_SGQ_LIST_BEG              8
1208
#define ASC_DEF_SCSI1_QNG    4
1209
#define ASC_MAX_SCSI1_QNG    4
1210
#define ASC_DEF_SCSI2_QNG    16
1211
#define ASC_MAX_SCSI2_QNG    32
1212
#define ASC_TAG_CODE_MASK    0x23
1213
#define ASC_STOP_REQ_RISC_STOP      0x01
1214
#define ASC_STOP_ACK_RISC_STOP      0x03
1215
#define ASC_STOP_CLEAN_UP_BUSY_Q    0x10
1216
#define ASC_STOP_CLEAN_UP_DISC_Q    0x20
1217
#define ASC_STOP_HOST_REQ_RISC_HALT 0x40
1218
#define ASC_TIDLUN_TO_IX(tid, lun)  (ASC_SCSI_TIX_TYPE)((tid) + ((lun)<<ASC_SCSI_ID_BITS))
1219
#define ASC_TID_TO_TARGET_ID(tid)   (ASC_SCSI_BIT_ID_TYPE)(0x01 << (tid))
1220
#define ASC_TIX_TO_TARGET_ID(tix)   (0x01 << ((tix) & ASC_MAX_TID))
1221
#define ASC_TIX_TO_TID(tix)         ((tix) & ASC_MAX_TID)
1222
#define ASC_TID_TO_TIX(tid)         ((tid) & ASC_MAX_TID)
1223
#define ASC_TIX_TO_LUN(tix)         (((tix) >> ASC_SCSI_ID_BITS) & ASC_MAX_LUN)
1224
#define ASC_QNO_TO_QADDR(q_no)      ((ASC_QADR_BEG)+((int)(q_no) << 6))
1225
 
1226
typedef struct asc_scisq_1 {
1227
    uchar               status;
1228
    uchar               q_no;
1229
    uchar               cntl;
1230
    uchar               sg_queue_cnt;
1231
    uchar               target_id;
1232
    uchar               target_lun;
1233
    ulong               data_addr;
1234
    ulong               data_cnt;
1235
    ulong               sense_addr;
1236
    uchar               sense_len;
1237
    uchar               extra_bytes;
1238
} ASC_SCSIQ_1;
1239
 
1240
typedef struct asc_scisq_2 {
1241
    ulong               srb_ptr;
1242
    uchar               target_ix;
1243
    uchar               flag;
1244
    uchar               cdb_len;
1245
    uchar               tag_code;
1246
    ushort              vm_id;
1247
} ASC_SCSIQ_2;
1248
 
1249
typedef struct asc_scsiq_3 {
1250
    uchar               done_stat;
1251
    uchar               host_stat;
1252
    uchar               scsi_stat;
1253
    uchar               scsi_msg;
1254
} ASC_SCSIQ_3;
1255
 
1256
typedef struct asc_scsiq_4 {
1257
    uchar               cdb[ASC_MAX_CDB_LEN];
1258
    uchar               y_first_sg_list_qp;
1259
    uchar               y_working_sg_qp;
1260
    uchar               y_working_sg_ix;
1261
    uchar               y_res;
1262
    ushort              x_req_count;
1263
    ushort              x_reconnect_rtn;
1264
    ulong               x_saved_data_addr;
1265
    ulong               x_saved_data_cnt;
1266
} ASC_SCSIQ_4;
1267
 
1268
typedef struct asc_q_done_info {
1269
    ASC_SCSIQ_2         d2;
1270
    ASC_SCSIQ_3         d3;
1271
    uchar               q_status;
1272
    uchar               q_no;
1273
    uchar               cntl;
1274
    uchar               sense_len;
1275
    uchar               extra_bytes;
1276
    uchar               res;
1277
    ulong               remain_bytes;
1278
} ASC_QDONE_INFO;
1279
 
1280
typedef struct asc_sg_list {
1281
    ulong               addr;
1282
    ulong               bytes;
1283
} ASC_SG_LIST;
1284
 
1285
typedef struct asc_sg_head {
1286
    ushort              entry_cnt;
1287
    ushort              queue_cnt;
1288
    ushort              entry_to_copy;
1289
    ushort              res;
1290
    ASC_SG_LIST         sg_list[ASC_MAX_SG_LIST];
1291
} ASC_SG_HEAD;
1292
 
1293
#define ASC_MIN_SG_LIST   2
1294
 
1295
typedef struct asc_min_sg_head {
1296
    ushort              entry_cnt;
1297
    ushort              queue_cnt;
1298
    ushort              entry_to_copy;
1299
    ushort              res;
1300
    ASC_SG_LIST         sg_list[ASC_MIN_SG_LIST];
1301
} ASC_MIN_SG_HEAD;
1302
 
1303
#define QCX_SORT        (0x0001)
1304
#define QCX_COALEASE    (0x0002)
1305
 
1306
typedef struct asc_scsi_q {
1307
    ASC_SCSIQ_1         q1;
1308
    ASC_SCSIQ_2         q2;
1309
    uchar               *cdbptr;
1310
    ASC_SG_HEAD         *sg_head;
1311
} ASC_SCSI_Q;
1312
 
1313
typedef struct asc_scsi_req_q {
1314
    ASC_SCSIQ_1         r1;
1315
    ASC_SCSIQ_2         r2;
1316
    uchar       *cdbptr;
1317
    ASC_SG_HEAD *sg_head;
1318
    uchar               *sense_ptr;
1319
    ASC_SCSIQ_3         r3;
1320
    uchar               cdb[ASC_MAX_CDB_LEN];
1321
    uchar               sense[ASC_MIN_SENSE_LEN];
1322
} ASC_SCSI_REQ_Q;
1323
 
1324
typedef struct asc_scsi_bios_req_q {
1325
    ASC_SCSIQ_1         r1;
1326
    ASC_SCSIQ_2         r2;
1327
    uchar               *cdbptr;
1328
    ASC_SG_HEAD         *sg_head;
1329
    uchar               *sense_ptr;
1330
    ASC_SCSIQ_3         r3;
1331
    uchar               cdb[ASC_MAX_CDB_LEN];
1332
    uchar               sense[ASC_MIN_SENSE_LEN];
1333
} ASC_SCSI_BIOS_REQ_Q;
1334
 
1335
typedef struct asc_risc_q {
1336
    uchar               fwd;
1337
    uchar               bwd;
1338
    ASC_SCSIQ_1         i1;
1339
    ASC_SCSIQ_2         i2;
1340
    ASC_SCSIQ_3         i3;
1341
    ASC_SCSIQ_4         i4;
1342
} ASC_RISC_Q;
1343
 
1344
typedef struct asc_sg_list_q {
1345
    uchar               seq_no;
1346
    uchar               q_no;
1347
    uchar               cntl;
1348
    uchar               sg_head_qp;
1349
    uchar               sg_list_cnt;
1350
    uchar               sg_cur_list_cnt;
1351
} ASC_SG_LIST_Q;
1352
 
1353
typedef struct asc_risc_sg_list_q {
1354
    uchar               fwd;
1355
    uchar               bwd;
1356
    ASC_SG_LIST_Q       sg;
1357
    ASC_SG_LIST         sg_list[7];
1358
} ASC_RISC_SG_LIST_Q;
1359
 
1360
#define ASC_EXE_SCSI_IO_MAX_IDLE_LOOP  0x1000000UL
1361
#define ASC_EXE_SCSI_IO_MAX_WAIT_LOOP  1024
1362
#define ASCQ_ERR_NO_ERROR             0
1363
#define ASCQ_ERR_IO_NOT_FOUND         1
1364
#define ASCQ_ERR_LOCAL_MEM            2
1365
#define ASCQ_ERR_CHKSUM               3
1366
#define ASCQ_ERR_START_CHIP           4
1367
#define ASCQ_ERR_INT_TARGET_ID        5
1368
#define ASCQ_ERR_INT_LOCAL_MEM        6
1369
#define ASCQ_ERR_HALT_RISC            7
1370
#define ASCQ_ERR_GET_ASPI_ENTRY       8
1371
#define ASCQ_ERR_CLOSE_ASPI           9
1372
#define ASCQ_ERR_HOST_INQUIRY         0x0A
1373
#define ASCQ_ERR_SAVED_SRB_BAD        0x0B
1374
#define ASCQ_ERR_QCNTL_SG_LIST        0x0C
1375
#define ASCQ_ERR_Q_STATUS             0x0D
1376
#define ASCQ_ERR_WR_SCSIQ             0x0E
1377
#define ASCQ_ERR_PC_ADDR              0x0F
1378
#define ASCQ_ERR_SYN_OFFSET           0x10
1379
#define ASCQ_ERR_SYN_XFER_TIME        0x11
1380
#define ASCQ_ERR_LOCK_DMA             0x12
1381
#define ASCQ_ERR_UNLOCK_DMA           0x13
1382
#define ASCQ_ERR_VDS_CHK_INSTALL      0x14
1383
#define ASCQ_ERR_MICRO_CODE_HALT      0x15
1384
#define ASCQ_ERR_SET_LRAM_ADDR        0x16
1385
#define ASCQ_ERR_CUR_QNG              0x17
1386
#define ASCQ_ERR_SG_Q_LINKS           0x18
1387
#define ASCQ_ERR_SCSIQ_PTR            0x19
1388
#define ASCQ_ERR_ISR_RE_ENTRY         0x1A
1389
#define ASCQ_ERR_CRITICAL_RE_ENTRY    0x1B
1390
#define ASCQ_ERR_ISR_ON_CRITICAL      0x1C
1391
#define ASCQ_ERR_SG_LIST_ODD_ADDRESS  0x1D
1392
#define ASCQ_ERR_XFER_ADDRESS_TOO_BIG 0x1E
1393
#define ASCQ_ERR_SCSIQ_NULL_PTR       0x1F
1394
#define ASCQ_ERR_SCSIQ_BAD_NEXT_PTR   0x20
1395
#define ASCQ_ERR_GET_NUM_OF_FREE_Q    0x21
1396
#define ASCQ_ERR_SEND_SCSI_Q          0x22
1397
#define ASCQ_ERR_HOST_REQ_RISC_HALT   0x23
1398
#define ASCQ_ERR_RESET_SDTR           0x24
1399
#define ASC_WARN_NO_ERROR             0x0000
1400
#define ASC_WARN_IO_PORT_ROTATE       0x0001
1401
#define ASC_WARN_EEPROM_CHKSUM        0x0002
1402
#define ASC_WARN_IRQ_MODIFIED         0x0004
1403
#define ASC_WARN_AUTO_CONFIG          0x0008
1404
#define ASC_WARN_CMD_QNG_CONFLICT     0x0010
1405
#define ASC_WARN_EEPROM_RECOVER       0x0020
1406
#define ASC_WARN_CFG_MSW_RECOVER      0x0040
1407
#define ASC_WARN_SET_PCI_CONFIG_SPACE 0x0080
1408
#define ASC_IERR_WRITE_EEPROM         0x0001
1409
#define ASC_IERR_MCODE_CHKSUM         0x0002
1410
#define ASC_IERR_SET_PC_ADDR          0x0004
1411
#define ASC_IERR_START_STOP_CHIP      0x0008
1412
#define ASC_IERR_IRQ_NO               0x0010
1413
#define ASC_IERR_SET_IRQ_NO           0x0020
1414
#define ASC_IERR_CHIP_VERSION         0x0040
1415
#define ASC_IERR_SET_SCSI_ID          0x0080
1416
#define ASC_IERR_GET_PHY_ADDR         0x0100
1417
#define ASC_IERR_BAD_SIGNATURE        0x0200
1418
#define ASC_IERR_NO_BUS_TYPE          0x0400
1419
#define ASC_IERR_SCAM                 0x0800
1420
#define ASC_IERR_SET_SDTR             0x1000
1421
#define ASC_IERR_RW_LRAM              0x8000
1422
#define ASC_DEF_IRQ_NO  10
1423
#define ASC_MAX_IRQ_NO  15
1424
#define ASC_MIN_IRQ_NO  10
1425
#define ASC_MIN_REMAIN_Q        (0x02)
1426
#define ASC_DEF_MAX_TOTAL_QNG   (0xF0)
1427
#define ASC_MIN_TAG_Q_PER_DVC   (0x04)
1428
#define ASC_DEF_TAG_Q_PER_DVC   (0x04)
1429
#define ASC_MIN_FREE_Q        ASC_MIN_REMAIN_Q
1430
#define ASC_MIN_TOTAL_QNG     ((ASC_MAX_SG_QUEUE)+(ASC_MIN_FREE_Q))
1431
#define ASC_MAX_TOTAL_QNG 240
1432
#define ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG 16
1433
#define ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG   8
1434
#define ASC_MAX_PCI_INRAM_TOTAL_QNG  20
1435
#define ASC_MAX_INRAM_TAG_QNG   16
1436
#define ASC_IOADR_TABLE_MAX_IX  11
1437
#define ASC_IOADR_GAP   0x10
1438
#define ASC_SEARCH_IOP_GAP 0x10
1439
#define ASC_MIN_IOP_ADDR   (PortAddr)0x0100
1440
#define ASC_MAX_IOP_ADDR   (PortAddr)0x3F0
1441
#define ASC_IOADR_1     (PortAddr)0x0110
1442
#define ASC_IOADR_2     (PortAddr)0x0130
1443
#define ASC_IOADR_3     (PortAddr)0x0150
1444
#define ASC_IOADR_4     (PortAddr)0x0190
1445
#define ASC_IOADR_5     (PortAddr)0x0210
1446
#define ASC_IOADR_6     (PortAddr)0x0230
1447
#define ASC_IOADR_7     (PortAddr)0x0250
1448
#define ASC_IOADR_8     (PortAddr)0x0330
1449
#define ASC_IOADR_DEF   ASC_IOADR_8
1450
#define ASC_LIB_SCSIQ_WK_SP        256
1451
#define ASC_MAX_SYN_XFER_NO        16
1452
#define ASC_SYN_MAX_OFFSET         0x0F
1453
#define ASC_DEF_SDTR_OFFSET        0x0F
1454
#define ASC_DEF_SDTR_INDEX         0x00
1455
#define ASC_SDTR_ULTRA_PCI_10MB_INDEX  0x02
1456
#define SYN_XFER_NS_0  25
1457
#define SYN_XFER_NS_1  30
1458
#define SYN_XFER_NS_2  35
1459
#define SYN_XFER_NS_3  40
1460
#define SYN_XFER_NS_4  50
1461
#define SYN_XFER_NS_5  60
1462
#define SYN_XFER_NS_6  70
1463
#define SYN_XFER_NS_7  85
1464
#define SYN_ULTRA_XFER_NS_0    12
1465
#define SYN_ULTRA_XFER_NS_1    19
1466
#define SYN_ULTRA_XFER_NS_2    25
1467
#define SYN_ULTRA_XFER_NS_3    32
1468
#define SYN_ULTRA_XFER_NS_4    38
1469
#define SYN_ULTRA_XFER_NS_5    44
1470
#define SYN_ULTRA_XFER_NS_6    50
1471
#define SYN_ULTRA_XFER_NS_7    57
1472
#define SYN_ULTRA_XFER_NS_8    63
1473
#define SYN_ULTRA_XFER_NS_9    69
1474
#define SYN_ULTRA_XFER_NS_10   75
1475
#define SYN_ULTRA_XFER_NS_11   82
1476
#define SYN_ULTRA_XFER_NS_12   88
1477
#define SYN_ULTRA_XFER_NS_13   94
1478
#define SYN_ULTRA_XFER_NS_14  100
1479
#define SYN_ULTRA_XFER_NS_15  107
1480
 
1481
typedef struct ext_msg {
1482
    uchar               msg_type;
1483
    uchar               msg_len;
1484
    uchar               msg_req;
1485
    union {
1486
        struct {
1487
            uchar               sdtr_xfer_period;
1488
            uchar               sdtr_req_ack_offset;
1489
        } sdtr;
1490
        struct {
1491
            uchar               wdtr_width;
1492
        } wdtr;
1493
        struct {
1494
            uchar               mdp_b3;
1495
            uchar               mdp_b2;
1496
            uchar               mdp_b1;
1497
            uchar               mdp_b0;
1498
        } mdp;
1499
    } u_ext_msg;
1500
    uchar               res;
1501
} EXT_MSG;
1502
 
1503
#define xfer_period     u_ext_msg.sdtr.sdtr_xfer_period
1504
#define req_ack_offset  u_ext_msg.sdtr.sdtr_req_ack_offset
1505
#define wdtr_width      u_ext_msg.wdtr.wdtr_width
1506
#define mdp_b3          u_ext_msg.mdp_b3
1507
#define mdp_b2          u_ext_msg.mdp_b2
1508
#define mdp_b1          u_ext_msg.mdp_b1
1509
#define mdp_b0          u_ext_msg.mdp_b0
1510
 
1511
typedef struct asc_dvc_cfg {
1512
    ASC_SCSI_BIT_ID_TYPE can_tagged_qng;
1513
    ASC_SCSI_BIT_ID_TYPE cmd_qng_enabled;
1514
    ASC_SCSI_BIT_ID_TYPE disc_enable;
1515
    ASC_SCSI_BIT_ID_TYPE sdtr_enable;
1516
    uchar               chip_scsi_id:4;
1517
    uchar               isa_dma_speed:4;
1518
    uchar               isa_dma_channel;
1519
    uchar               chip_version;
1520
    ushort              pci_device_id;
1521
    ushort              lib_serial_no;
1522
    ushort              lib_version;
1523
    ushort              mcode_date;
1524
    ushort              mcode_version;
1525
    uchar               max_tag_qng[ASC_MAX_TID + 1];
1526
    uchar               *overrun_buf;
1527
    uchar               sdtr_period_offset[ASC_MAX_TID + 1];
1528
    ushort              pci_slot_info;
1529
    uchar               adapter_info[6];
1530
} ASC_DVC_CFG;
1531
 
1532
#define ASC_DEF_DVC_CNTL       0xFFFF
1533
#define ASC_DEF_CHIP_SCSI_ID   7
1534
#define ASC_DEF_ISA_DMA_SPEED  4
1535
#define ASC_INIT_STATE_NULL          0x0000
1536
#define ASC_INIT_STATE_BEG_GET_CFG   0x0001
1537
#define ASC_INIT_STATE_END_GET_CFG   0x0002
1538
#define ASC_INIT_STATE_BEG_SET_CFG   0x0004
1539
#define ASC_INIT_STATE_END_SET_CFG   0x0008
1540
#define ASC_INIT_STATE_BEG_LOAD_MC   0x0010
1541
#define ASC_INIT_STATE_END_LOAD_MC   0x0020
1542
#define ASC_INIT_STATE_BEG_INQUIRY   0x0040
1543
#define ASC_INIT_STATE_END_INQUIRY   0x0080
1544
#define ASC_INIT_RESET_SCSI_DONE     0x0100
1545
#define ASC_INIT_STATE_WITHOUT_EEP   0x8000
1546
#define ASC_PCI_DEVICE_ID_REV_A      0x1100
1547
#define ASC_PCI_DEVICE_ID_REV_B      0x1200
1548
#define ASC_BUG_FIX_IF_NOT_DWB       0x0001
1549
#define ASC_BUG_FIX_ASYN_USE_SYN     0x0002
1550
#define ASYN_SDTR_DATA_FIX_PCI_REV_AB 0x41
1551
#define ASC_MIN_TAGGED_CMD  7
1552
#define ASC_MAX_SCSI_RESET_WAIT      30
1553
 
1554
typedef struct asc_dvc_var {
1555
    PortAddr            iop_base;
1556
    ushort              err_code;
1557
    ushort              dvc_cntl;
1558
    ushort              bug_fix_cntl;
1559
    ushort              bus_type;
1560
    Ptr2Func            isr_callback;
1561
    Ptr2Func            exe_callback;
1562
    ASC_SCSI_BIT_ID_TYPE init_sdtr;
1563
    ASC_SCSI_BIT_ID_TYPE sdtr_done;
1564
    ASC_SCSI_BIT_ID_TYPE use_tagged_qng;
1565
    ASC_SCSI_BIT_ID_TYPE unit_not_ready;
1566
    ASC_SCSI_BIT_ID_TYPE queue_full_or_busy;
1567
    ASC_SCSI_BIT_ID_TYPE start_motor;
1568
    uchar               scsi_reset_wait;
1569
    uchar               chip_no;
1570
    char                is_in_int;
1571
    uchar               max_total_qng;
1572
    uchar               cur_total_qng;
1573
    uchar               in_critical_cnt;
1574
    uchar               irq_no;
1575
    uchar               last_q_shortage;
1576
    ushort              init_state;
1577
    uchar               cur_dvc_qng[ASC_MAX_TID + 1];
1578
    uchar               max_dvc_qng[ASC_MAX_TID + 1];
1579
    ASC_SCSI_Q  *scsiq_busy_head[ASC_MAX_TID + 1];
1580
    ASC_SCSI_Q  *scsiq_busy_tail[ASC_MAX_TID + 1];
1581
    uchar               sdtr_period_tbl[ASC_MAX_SYN_XFER_NO];
1582
    ASC_DVC_CFG *cfg;
1583
    Ptr2Func            saved_ptr2func;
1584
    ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer_always;
1585
    char                redo_scam;
1586
    ushort              res2;
1587
    uchar               dos_int13_table[ASC_MAX_TID + 1];
1588
    ulong               max_dma_count;
1589
    ASC_SCSI_BIT_ID_TYPE no_scam;
1590
    ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer;
1591
    uchar               max_sdtr_index;
1592
    uchar               host_init_sdtr_index;
1593
    ulong               drv_ptr;
1594
    ulong               uc_break;
1595
    ulong               res7;
1596
    ulong               res8;
1597
} ASC_DVC_VAR;
1598
 
1599
typedef int (* ASC_ISR_CALLBACK) (ASC_DVC_VAR asc_ptr_type *, ASC_QDONE_INFO *);
1600
typedef int (* ASC_EXE_CALLBACK) (ASC_DVC_VAR asc_ptr_type *, ASC_SCSI_Q *);
1601
 
1602
typedef struct asc_dvc_inq_info {
1603
    uchar               type[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
1604
} ASC_DVC_INQ_INFO;
1605
 
1606
typedef struct asc_cap_info {
1607
    ulong               lba;
1608
    ulong               blk_size;
1609
} ASC_CAP_INFO;
1610
 
1611
typedef struct asc_cap_info_array {
1612
    ASC_CAP_INFO        cap_info[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
1613
} ASC_CAP_INFO_ARRAY;
1614
 
1615
#define ASC_MCNTL_NO_SEL_TIMEOUT  (ushort)0x0001
1616
#define ASC_MCNTL_NULL_TARGET     (ushort)0x0002
1617
#define ASC_CNTL_INITIATOR         (ushort)0x0001
1618
#define ASC_CNTL_BIOS_GT_1GB       (ushort)0x0002
1619
#define ASC_CNTL_BIOS_GT_2_DISK    (ushort)0x0004
1620
#define ASC_CNTL_BIOS_REMOVABLE    (ushort)0x0008
1621
#define ASC_CNTL_NO_SCAM           (ushort)0x0010
1622
#define ASC_CNTL_INT_MULTI_Q       (ushort)0x0080
1623
#define ASC_CNTL_NO_LUN_SUPPORT    (ushort)0x0040
1624
#define ASC_CNTL_NO_VERIFY_COPY    (ushort)0x0100
1625
#define ASC_CNTL_RESET_SCSI        (ushort)0x0200
1626
#define ASC_CNTL_INIT_INQUIRY      (ushort)0x0400
1627
#define ASC_CNTL_INIT_VERBOSE      (ushort)0x0800
1628
#define ASC_CNTL_SCSI_PARITY       (ushort)0x1000
1629
#define ASC_CNTL_BURST_MODE        (ushort)0x2000
1630
#define ASC_CNTL_SDTR_ENABLE_ULTRA (ushort)0x4000
1631
#define ASC_EEP_DVC_CFG_BEG_VL    2
1632
#define ASC_EEP_MAX_DVC_ADDR_VL   15
1633
#define ASC_EEP_DVC_CFG_BEG      32
1634
#define ASC_EEP_MAX_DVC_ADDR     45
1635
#define ASC_EEP_DEFINED_WORDS    10
1636
#define ASC_EEP_MAX_ADDR         63
1637
#define ASC_EEP_RES_WORDS         0
1638
#define ASC_EEP_MAX_RETRY        20
1639
#define ASC_MAX_INIT_BUSY_RETRY   8
1640
#define ASC_EEP_ISA_PNP_WSIZE    16
1641
 
1642
typedef struct asceep_config {
1643
    ushort              cfg_lsw;
1644
    ushort              cfg_msw;
1645
    uchar               init_sdtr;
1646
    uchar               disc_enable;
1647
    uchar               use_cmd_qng;
1648
    uchar               start_motor;
1649
    uchar               max_total_qng;
1650
    uchar               max_tag_qng;
1651
    uchar               bios_scan;
1652
    uchar               power_up_wait;
1653
    uchar               no_scam;
1654
    uchar               chip_scsi_id:4;
1655
    uchar               isa_dma_speed:4;
1656
    uchar               dos_int13_table[ASC_MAX_TID + 1];
1657
    uchar               adapter_info[6];
1658
    ushort              cntl;
1659
    ushort              chksum;
1660
} ASCEEP_CONFIG;
1661
 
1662
#define ASC_PCI_CFG_LSW_SCSI_PARITY  0x0800
1663
#define ASC_PCI_CFG_LSW_BURST_MODE   0x0080
1664
#define ASC_PCI_CFG_LSW_INTR_ABLE    0x0020
1665
 
1666
#define ASC_EEP_CMD_READ          0x80
1667
#define ASC_EEP_CMD_WRITE         0x40
1668
#define ASC_EEP_CMD_WRITE_ABLE    0x30
1669
#define ASC_EEP_CMD_WRITE_DISABLE 0x00
1670
#define ASC_OVERRUN_BSIZE  0x00000048UL
1671
#define ASC_CTRL_BREAK_ONCE        0x0001
1672
#define ASC_CTRL_BREAK_STAY_IDLE   0x0002
1673
#define ASCV_MSGOUT_BEG         0x0000
1674
#define ASCV_MSGOUT_SDTR_PERIOD (ASCV_MSGOUT_BEG+3)
1675
#define ASCV_MSGOUT_SDTR_OFFSET (ASCV_MSGOUT_BEG+4)
1676
#define ASCV_BREAK_SAVED_CODE   (ushort)0x0006
1677
#define ASCV_MSGIN_BEG          (ASCV_MSGOUT_BEG+8)
1678
#define ASCV_MSGIN_SDTR_PERIOD  (ASCV_MSGIN_BEG+3)
1679
#define ASCV_MSGIN_SDTR_OFFSET  (ASCV_MSGIN_BEG+4)
1680
#define ASCV_SDTR_DATA_BEG      (ASCV_MSGIN_BEG+8)
1681
#define ASCV_SDTR_DONE_BEG      (ASCV_SDTR_DATA_BEG+8)
1682
#define ASCV_MAX_DVC_QNG_BEG    (ushort)0x0020
1683
#define ASCV_BREAK_ADDR           (ushort)0x0028
1684
#define ASCV_BREAK_NOTIFY_COUNT   (ushort)0x002A
1685
#define ASCV_BREAK_CONTROL        (ushort)0x002C
1686
#define ASCV_BREAK_HIT_COUNT      (ushort)0x002E
1687
 
1688
#define ASCV_ASCDVC_ERR_CODE_W  (ushort)0x0030
1689
#define ASCV_MCODE_CHKSUM_W   (ushort)0x0032
1690
#define ASCV_MCODE_SIZE_W     (ushort)0x0034
1691
#define ASCV_STOP_CODE_B      (ushort)0x0036
1692
#define ASCV_DVC_ERR_CODE_B   (ushort)0x0037
1693
#define ASCV_OVERRUN_PADDR_D  (ushort)0x0038
1694
#define ASCV_OVERRUN_BSIZE_D  (ushort)0x003C
1695
#define ASCV_HALTCODE_W       (ushort)0x0040
1696
#define ASCV_CHKSUM_W         (ushort)0x0042
1697
#define ASCV_MC_DATE_W        (ushort)0x0044
1698
#define ASCV_MC_VER_W         (ushort)0x0046
1699
#define ASCV_NEXTRDY_B        (ushort)0x0048
1700
#define ASCV_DONENEXT_B       (ushort)0x0049
1701
#define ASCV_USE_TAGGED_QNG_B (ushort)0x004A
1702
#define ASCV_SCSIBUSY_B       (ushort)0x004B
1703
#define ASCV_Q_DONE_IN_PROGRESS_B  (ushort)0x004C
1704
#define ASCV_CURCDB_B         (ushort)0x004D
1705
#define ASCV_RCLUN_B          (ushort)0x004E
1706
#define ASCV_BUSY_QHEAD_B     (ushort)0x004F
1707
#define ASCV_DISC1_QHEAD_B    (ushort)0x0050
1708
#define ASCV_DISC_ENABLE_B    (ushort)0x0052
1709
#define ASCV_CAN_TAGGED_QNG_B (ushort)0x0053
1710
#define ASCV_HOSTSCSI_ID_B    (ushort)0x0055
1711
#define ASCV_MCODE_CNTL_B     (ushort)0x0056
1712
#define ASCV_NULL_TARGET_B    (ushort)0x0057
1713
#define ASCV_FREE_Q_HEAD_W    (ushort)0x0058
1714
#define ASCV_DONE_Q_TAIL_W    (ushort)0x005A
1715
#define ASCV_FREE_Q_HEAD_B    (ushort)(ASCV_FREE_Q_HEAD_W+1)
1716
#define ASCV_DONE_Q_TAIL_B    (ushort)(ASCV_DONE_Q_TAIL_W+1)
1717
#define ASCV_HOST_FLAG_B      (ushort)0x005D
1718
#define ASCV_TOTAL_READY_Q_B  (ushort)0x0064
1719
#define ASCV_VER_SERIAL_B     (ushort)0x0065
1720
#define ASCV_HALTCODE_SAVED_W (ushort)0x0066
1721
#define ASCV_WTM_FLAG_B       (ushort)0x0068
1722
#define ASCV_RISC_FLAG_B      (ushort)0x006A
1723
#define ASCV_REQ_SG_LIST_QP   (ushort)0x006B
1724
#define ASC_HOST_FLAG_IN_ISR        0x01
1725
#define ASC_HOST_FLAG_ACK_INT       0x02
1726
#define ASC_RISC_FLAG_GEN_INT      0x01
1727
#define ASC_RISC_FLAG_REQ_SG_LIST  0x02
1728
#define IOP_CTRL         (0x0F)
1729
#define IOP_STATUS       (0x0E)
1730
#define IOP_INT_ACK      IOP_STATUS
1731
#define IOP_REG_IFC      (0x0D)
1732
#define IOP_SYN_OFFSET    (0x0B)
1733
#define IOP_EXTRA_CONTROL (0x0D)
1734
#define IOP_REG_PC        (0x0C)
1735
#define IOP_RAM_ADDR      (0x0A)
1736
#define IOP_RAM_DATA      (0x08)
1737
#define IOP_EEP_DATA      (0x06)
1738
#define IOP_EEP_CMD       (0x07)
1739
#define IOP_VERSION       (0x03)
1740
#define IOP_CONFIG_HIGH   (0x04)
1741
#define IOP_CONFIG_LOW    (0x02)
1742
#define IOP_SIG_BYTE      (0x01)
1743
#define IOP_SIG_WORD      (0x00)
1744
#define IOP_REG_DC1      (0x0E)
1745
#define IOP_REG_DC0      (0x0C)
1746
#define IOP_REG_SB       (0x0B)
1747
#define IOP_REG_DA1      (0x0A)
1748
#define IOP_REG_DA0      (0x08)
1749
#define IOP_REG_SC       (0x09)
1750
#define IOP_DMA_SPEED    (0x07)
1751
#define IOP_REG_FLAG     (0x07)
1752
#define IOP_FIFO_H       (0x06)
1753
#define IOP_FIFO_L       (0x04)
1754
#define IOP_REG_ID       (0x05)
1755
#define IOP_REG_QP       (0x03)
1756
#define IOP_REG_IH       (0x02)
1757
#define IOP_REG_IX       (0x01)
1758
#define IOP_REG_AX       (0x00)
1759
#define IFC_REG_LOCK      (0x00)
1760
#define IFC_REG_UNLOCK    (0x09)
1761
#define IFC_WR_EN_FILTER  (0x10)
1762
#define IFC_RD_NO_EEPROM  (0x10)
1763
#define IFC_SLEW_RATE     (0x20)
1764
#define IFC_ACT_NEG       (0x40)
1765
#define IFC_INP_FILTER    (0x80)
1766
#define IFC_INIT_DEFAULT  (IFC_ACT_NEG | IFC_REG_UNLOCK)
1767
#define SC_SEL   (uchar)(0x80)
1768
#define SC_BSY   (uchar)(0x40)
1769
#define SC_ACK   (uchar)(0x20)
1770
#define SC_REQ   (uchar)(0x10)
1771
#define SC_ATN   (uchar)(0x08)
1772
#define SC_IO    (uchar)(0x04)
1773
#define SC_CD    (uchar)(0x02)
1774
#define SC_MSG   (uchar)(0x01)
1775
#define SEC_SCSI_CTL         (uchar)(0x80)
1776
#define SEC_ACTIVE_NEGATE    (uchar)(0x40)
1777
#define SEC_SLEW_RATE        (uchar)(0x20)
1778
#define SEC_ENABLE_FILTER    (uchar)(0x10)
1779
#define ASC_HALT_EXTMSG_IN     (ushort)0x8000
1780
#define ASC_HALT_CHK_CONDITION (ushort)0x8100
1781
#define ASC_HALT_SS_QUEUE_FULL (ushort)0x8200
1782
#define ASC_HALT_DISABLE_ASYN_USE_SYN_FIX  (ushort)0x8300
1783
#define ASC_HALT_ENABLE_ASYN_USE_SYN_FIX   (ushort)0x8400
1784
#define ASC_HALT_SDTR_REJECTED (ushort)0x4000
1785
#define ASC_MAX_QNO        0xF8
1786
#define ASC_DATA_SEC_BEG   (ushort)0x0080
1787
#define ASC_DATA_SEC_END   (ushort)0x0080
1788
#define ASC_CODE_SEC_BEG   (ushort)0x0080
1789
#define ASC_CODE_SEC_END   (ushort)0x0080
1790
#define ASC_QADR_BEG       (0x4000)
1791
#define ASC_QADR_USED      (ushort)(ASC_MAX_QNO * 64)
1792
#define ASC_QADR_END       (ushort)0x7FFF
1793
#define ASC_QLAST_ADR      (ushort)0x7FC0
1794
#define ASC_QBLK_SIZE      0x40
1795
#define ASC_BIOS_DATA_QBEG 0xF8
1796
#define ASC_MIN_ACTIVE_QNO 0x01
1797
#define ASC_QLINK_END      0xFF
1798
#define ASC_EEPROM_WORDS   0x10
1799
#define ASC_MAX_MGS_LEN    0x10
1800
#define ASC_BIOS_ADDR_DEF  0xDC00
1801
#define ASC_BIOS_SIZE      0x3800
1802
#define ASC_BIOS_RAM_OFF   0x3800
1803
#define ASC_BIOS_RAM_SIZE  0x800
1804
#define ASC_BIOS_MIN_ADDR  0xC000
1805
#define ASC_BIOS_MAX_ADDR  0xEC00
1806
#define ASC_BIOS_BANK_SIZE 0x0400
1807
#define ASC_MCODE_START_ADDR  0x0080
1808
#define ASC_CFG0_HOST_INT_ON    0x0020
1809
#define ASC_CFG0_BIOS_ON        0x0040
1810
#define ASC_CFG0_VERA_BURST_ON  0x0080
1811
#define ASC_CFG0_SCSI_PARITY_ON 0x0800
1812
#define ASC_CFG1_SCSI_TARGET_ON 0x0080
1813
#define ASC_CFG1_LRAM_8BITS_ON  0x0800
1814
#define ASC_CFG_MSW_CLR_MASK    0x3080
1815
#define CSW_TEST1             (ASC_CS_TYPE)0x8000
1816
#define CSW_AUTO_CONFIG       (ASC_CS_TYPE)0x4000
1817
#define CSW_RESERVED1         (ASC_CS_TYPE)0x2000
1818
#define CSW_IRQ_WRITTEN       (ASC_CS_TYPE)0x1000
1819
#define CSW_33MHZ_SELECTED    (ASC_CS_TYPE)0x0800
1820
#define CSW_TEST2             (ASC_CS_TYPE)0x0400
1821
#define CSW_TEST3             (ASC_CS_TYPE)0x0200
1822
#define CSW_RESERVED2         (ASC_CS_TYPE)0x0100
1823
#define CSW_DMA_DONE          (ASC_CS_TYPE)0x0080
1824
#define CSW_FIFO_RDY          (ASC_CS_TYPE)0x0040
1825
#define CSW_EEP_READ_DONE     (ASC_CS_TYPE)0x0020
1826
#define CSW_HALTED            (ASC_CS_TYPE)0x0010
1827
#define CSW_SCSI_RESET_ACTIVE (ASC_CS_TYPE)0x0008
1828
#define CSW_PARITY_ERR        (ASC_CS_TYPE)0x0004
1829
#define CSW_SCSI_RESET_LATCH  (ASC_CS_TYPE)0x0002
1830
#define CSW_INT_PENDING       (ASC_CS_TYPE)0x0001
1831
#define CIW_CLR_SCSI_RESET_INT (ASC_CS_TYPE)0x1000
1832
#define CIW_INT_ACK      (ASC_CS_TYPE)0x0100
1833
#define CIW_TEST1        (ASC_CS_TYPE)0x0200
1834
#define CIW_TEST2        (ASC_CS_TYPE)0x0400
1835
#define CIW_SEL_33MHZ    (ASC_CS_TYPE)0x0800
1836
#define CIW_IRQ_ACT      (ASC_CS_TYPE)0x1000
1837
#define CC_CHIP_RESET   (uchar)0x80
1838
#define CC_SCSI_RESET   (uchar)0x40
1839
#define CC_HALT         (uchar)0x20
1840
#define CC_SINGLE_STEP  (uchar)0x10
1841
#define CC_DMA_ABLE     (uchar)0x08
1842
#define CC_TEST         (uchar)0x04
1843
#define CC_BANK_ONE     (uchar)0x02
1844
#define CC_DIAG         (uchar)0x01
1845
#define ASC_1000_ID0W      0x04C1
1846
#define ASC_1000_ID0W_FIX  0x00C1
1847
#define ASC_1000_ID1B      0x25
1848
#define ASC_EISA_BIG_IOP_GAP   (0x1C30-0x0C50)
1849
#define ASC_EISA_SMALL_IOP_GAP (0x0020)
1850
#define ASC_EISA_MIN_IOP_ADDR  (0x0C30)
1851
#define ASC_EISA_MAX_IOP_ADDR  (0xFC50)
1852
#define ASC_EISA_REV_IOP_MASK  (0x0C83)
1853
#define ASC_EISA_PID_IOP_MASK  (0x0C80)
1854
#define ASC_EISA_CFG_IOP_MASK  (0x0C86)
1855
#define ASC_GET_EISA_SLOT(iop)  (PortAddr)((iop) & 0xF000)
1856
#define ASC_EISA_ID_740    0x01745004UL
1857
#define ASC_EISA_ID_750    0x01755004UL
1858
#define INS_HALTINT        (ushort)0x6281
1859
#define INS_HALT           (ushort)0x6280
1860
#define INS_SINT           (ushort)0x6200
1861
#define INS_RFLAG_WTM      (ushort)0x7380
1862
#define ASC_MC_SAVE_CODE_WSIZE  0x500
1863
#define ASC_MC_SAVE_DATA_WSIZE  0x40
1864
 
1865
typedef struct asc_mc_saved {
1866
    ushort              data[ASC_MC_SAVE_DATA_WSIZE];
1867
    ushort              code[ASC_MC_SAVE_CODE_WSIZE];
1868
} ASC_MC_SAVED;
1869
 
1870
#define AscGetQDoneInProgress(port)         AscReadLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B)
1871
#define AscPutQDoneInProgress(port, val)    AscWriteLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B, val)
1872
#define AscGetVarFreeQHead(port)            AscReadLramWord((port), ASCV_FREE_Q_HEAD_W)
1873
#define AscGetVarDoneQTail(port)            AscReadLramWord((port), ASCV_DONE_Q_TAIL_W)
1874
#define AscPutVarFreeQHead(port, val)       AscWriteLramWord((port), ASCV_FREE_Q_HEAD_W, val)
1875
#define AscPutVarDoneQTail(port, val)       AscWriteLramWord((port), ASCV_DONE_Q_TAIL_W, val)
1876
#define AscGetRiscVarFreeQHead(port)        AscReadLramByte((port), ASCV_NEXTRDY_B)
1877
#define AscGetRiscVarDoneQTail(port)        AscReadLramByte((port), ASCV_DONENEXT_B)
1878
#define AscPutRiscVarFreeQHead(port, val)   AscWriteLramByte((port), ASCV_NEXTRDY_B, val)
1879
#define AscPutRiscVarDoneQTail(port, val)   AscWriteLramByte((port), ASCV_DONENEXT_B, val)
1880
#define AscPutMCodeSDTRDoneAtID(port, id, data)  AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id), (data)) ;
1881
#define AscGetMCodeSDTRDoneAtID(port, id)        AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id)) ;
1882
#define AscPutMCodeInitSDTRAtID(port, id, data)  AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id), data) ;
1883
#define AscGetMCodeInitSDTRAtID(port, id)        AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id)) ;
1884
#define AscSynIndexToPeriod(index)        (uchar)(asc_dvc->sdtr_period_tbl[ (index) ])
1885
#define AscGetChipSignatureByte(port)     (uchar)inp((port)+IOP_SIG_BYTE)
1886
#define AscGetChipSignatureWord(port)     (ushort)inpw((port)+IOP_SIG_WORD)
1887
#define AscGetChipVerNo(port)             (uchar)inp((port)+IOP_VERSION)
1888
#define AscGetChipCfgLsw(port)            (ushort)inpw((port)+IOP_CONFIG_LOW)
1889
#define AscGetChipCfgMsw(port)            (ushort)inpw((port)+IOP_CONFIG_HIGH)
1890
#define AscSetChipCfgLsw(port, data)      outpw((port)+IOP_CONFIG_LOW, data)
1891
#define AscSetChipCfgMsw(port, data)      outpw((port)+IOP_CONFIG_HIGH, data)
1892
#define AscGetChipEEPCmd(port)            (uchar)inp((port)+IOP_EEP_CMD)
1893
#define AscSetChipEEPCmd(port, data)      outp((port)+IOP_EEP_CMD, data)
1894
#define AscGetChipEEPData(port)           (ushort)inpw((port)+IOP_EEP_DATA)
1895
#define AscSetChipEEPData(port, data)     outpw((port)+IOP_EEP_DATA, data)
1896
#define AscGetChipLramAddr(port)          (ushort)inpw((PortAddr)((port)+IOP_RAM_ADDR))
1897
#define AscSetChipLramAddr(port, addr)    outpw((PortAddr)((port)+IOP_RAM_ADDR), addr)
1898
#define AscGetChipLramData(port)          (ushort)inpw((port)+IOP_RAM_DATA)
1899
#define AscSetChipLramData(port, data)    outpw((port)+IOP_RAM_DATA, data)
1900
#define AscGetChipLramDataNoSwap(port)         (ushort)inpw_noswap((port)+IOP_RAM_DATA)
1901
#define AscSetChipLramDataNoSwap(port, data)   outpw_noswap((port)+IOP_RAM_DATA, data)
1902
#define AscGetChipIFC(port)               (uchar)inp((port)+IOP_REG_IFC)
1903
#define AscSetChipIFC(port, data)          outp((port)+IOP_REG_IFC, data)
1904
#define AscGetChipStatus(port)            (ASC_CS_TYPE)inpw((port)+IOP_STATUS)
1905
#define AscSetChipStatus(port, cs_val)    outpw((port)+IOP_STATUS, cs_val)
1906
#define AscGetChipControl(port)           (uchar)inp((port)+IOP_CTRL)
1907
#define AscSetChipControl(port, cc_val)   outp((port)+IOP_CTRL, cc_val)
1908
#define AscGetChipSyn(port)               (uchar)inp((port)+IOP_SYN_OFFSET)
1909
#define AscSetChipSyn(port, data)         outp((port)+IOP_SYN_OFFSET, data)
1910
#define AscSetPCAddr(port, data)          outpw((port)+IOP_REG_PC, data)
1911
#define AscGetPCAddr(port)                (ushort)inpw((port)+IOP_REG_PC)
1912
#define AscIsIntPending(port)             (AscGetChipStatus(port) & (CSW_INT_PENDING | CSW_SCSI_RESET_LATCH))
1913
#define AscGetChipScsiID(port)            ((AscGetChipCfgLsw(port) >> 8) & ASC_MAX_TID)
1914
#define AscGetExtraControl(port)          (uchar)inp((port)+IOP_EXTRA_CONTROL)
1915
#define AscSetExtraControl(port, data)    outp((port)+IOP_EXTRA_CONTROL, data)
1916
#define AscReadChipAX(port)               (ushort)inpw((port)+IOP_REG_AX)
1917
#define AscWriteChipAX(port, data)        outpw((port)+IOP_REG_AX, data)
1918
#define AscReadChipIX(port)               (uchar)inp((port)+IOP_REG_IX)
1919
#define AscWriteChipIX(port, data)        outp((port)+IOP_REG_IX, data)
1920
#define AscReadChipIH(port)               (ushort)inpw((port)+IOP_REG_IH)
1921
#define AscWriteChipIH(port, data)        outpw((port)+IOP_REG_IH, data)
1922
#define AscReadChipQP(port)               (uchar)inp((port)+IOP_REG_QP)
1923
#define AscWriteChipQP(port, data)        outp((port)+IOP_REG_QP, data)
1924
#define AscReadChipFIFO_L(port)           (ushort)inpw((port)+IOP_REG_FIFO_L)
1925
#define AscWriteChipFIFO_L(port, data)    outpw((port)+IOP_REG_FIFO_L, data)
1926
#define AscReadChipFIFO_H(port)           (ushort)inpw((port)+IOP_REG_FIFO_H)
1927
#define AscWriteChipFIFO_H(port, data)    outpw((port)+IOP_REG_FIFO_H, data)
1928
#define AscReadChipDmaSpeed(port)         (uchar)inp((port)+IOP_DMA_SPEED)
1929
#define AscWriteChipDmaSpeed(port, data)  outp((port)+IOP_DMA_SPEED, data)
1930
#define AscReadChipDA0(port)              (ushort)inpw((port)+IOP_REG_DA0)
1931
#define AscWriteChipDA0(port)             outpw((port)+IOP_REG_DA0, data)
1932
#define AscReadChipDA1(port)              (ushort)inpw((port)+IOP_REG_DA1)
1933
#define AscWriteChipDA1(port)             outpw((port)+IOP_REG_DA1, data)
1934
#define AscReadChipDC0(port)              (ushort)inpw((port)+IOP_REG_DC0)
1935
#define AscWriteChipDC0(port)             outpw((port)+IOP_REG_DC0, data)
1936
#define AscReadChipDC1(port)              (ushort)inpw((port)+IOP_REG_DC1)
1937
#define AscWriteChipDC1(port)             outpw((port)+IOP_REG_DC1, data)
1938
#define AscReadChipDvcID(port)            (uchar)inp((port)+IOP_REG_ID)
1939
#define AscWriteChipDvcID(port, data)     outp((port)+IOP_REG_ID, data)
1940
 
1941
STATIC int       AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg);
1942
STATIC int       AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg);
1943
STATIC void      AscWaitEEPRead(void);
1944
STATIC void      AscWaitEEPWrite(void);
1945
STATIC ushort    AscReadEEPWord(PortAddr, uchar);
1946
STATIC ushort    AscWriteEEPWord(PortAddr, uchar, ushort);
1947
STATIC ushort    AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
1948
STATIC int       AscSetEEPConfigOnce(PortAddr, ASCEEP_CONFIG *, ushort);
1949
STATIC int       AscSetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
1950
STATIC int       AscStartChip(PortAddr);
1951
STATIC int       AscStopChip(PortAddr);
1952
STATIC void      AscSetChipIH(PortAddr, ushort);
1953
STATIC int       AscIsChipHalted(PortAddr);
1954
STATIC void      AscAckInterrupt(PortAddr);
1955
STATIC void      AscDisableInterrupt(PortAddr);
1956
STATIC void      AscEnableInterrupt(PortAddr);
1957
STATIC void      AscSetBank(PortAddr, uchar);
1958
STATIC int       AscResetChipAndScsiBus(ASC_DVC_VAR *);
1959
STATIC ushort    AscGetIsaDmaChannel(PortAddr);
1960
STATIC ushort    AscSetIsaDmaChannel(PortAddr, ushort);
1961
STATIC uchar     AscSetIsaDmaSpeed(PortAddr, uchar);
1962
STATIC uchar     AscGetIsaDmaSpeed(PortAddr);
1963
STATIC uchar     AscReadLramByte(PortAddr, ushort);
1964
STATIC ushort    AscReadLramWord(PortAddr, ushort);
1965
STATIC ulong     AscReadLramDWord(PortAddr, ushort);
1966
STATIC void      AscWriteLramWord(PortAddr, ushort, ushort);
1967
STATIC void      AscWriteLramDWord(PortAddr, ushort, ulong);
1968
STATIC void      AscWriteLramByte(PortAddr, ushort, uchar);
1969
STATIC ulong     AscMemSumLramWord(PortAddr, ushort, rint);
1970
STATIC void      AscMemWordSetLram(PortAddr, ushort, ushort, rint);
1971
STATIC void      AscMemWordCopyToLram(PortAddr, ushort, ushort *, int);
1972
STATIC void      AscMemDWordCopyToLram(PortAddr, ushort, ulong *, int);
1973
STATIC void      AscMemWordCopyFromLram(PortAddr, ushort, ushort *, int);
1974
STATIC ushort    AscInitAscDvcVar(ASC_DVC_VAR asc_ptr_type *);
1975
STATIC ushort    AscInitFromEEP(ASC_DVC_VAR asc_ptr_type *);
1976
STATIC ushort    AscInitFromAscDvcVar(ASC_DVC_VAR asc_ptr_type *);
1977
STATIC ushort    AscInitMicroCodeVar(ASC_DVC_VAR asc_ptr_type * asc_dvc);
1978
STATIC int       AscTestExternalLram(ASC_DVC_VAR asc_ptr_type *);
1979
STATIC uchar     AscMsgOutSDTR(ASC_DVC_VAR asc_ptr_type *, uchar, uchar);
1980
STATIC uchar     AscCalSDTRData(ASC_DVC_VAR asc_ptr_type *, uchar, uchar);
1981
STATIC void      AscSetChipSDTR(PortAddr, uchar, uchar);
1982
STATIC uchar     AscGetSynPeriodIndex(ASC_DVC_VAR asc_ptr_type *, ruchar);
1983
STATIC uchar     AscAllocFreeQueue(PortAddr, uchar);
1984
STATIC uchar     AscAllocMultipleFreeQueue(PortAddr, uchar, uchar);
1985
STATIC int       AscRiscHaltedAbortSRB(ASC_DVC_VAR asc_ptr_type *, ulong);
1986
#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
1987
STATIC int       AscRiscHaltedAbortTIX(ASC_DVC_VAR asc_ptr_type *, uchar);
1988
#endif /* version >= v1.3.89 */
1989
STATIC int       AscHostReqRiscHalt(PortAddr);
1990
STATIC int       AscStopQueueExe(PortAddr);
1991
STATIC int       AscStartQueueExe(PortAddr);
1992
#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
1993
STATIC int       AscCleanUpDiscQueue(PortAddr);
1994
#endif /* version >= v1.3.89 */
1995
STATIC int       AscCleanUpBusyQueue(PortAddr);
1996
STATIC int       AscWaitTixISRDone(ASC_DVC_VAR asc_ptr_type *, uchar);
1997
STATIC int       AscWaitISRDone(ASC_DVC_VAR asc_ptr_type *);
1998
STATIC ulong     AscGetOnePhyAddr(ASC_DVC_VAR asc_ptr_type *, uchar *,
1999
                    ulong);
2000
STATIC int       AscSendScsiQueue(ASC_DVC_VAR asc_ptr_type * asc_dvc,
2001
                    ASC_SCSI_Q * scsiq,
2002
                    uchar n_q_required);
2003
STATIC int       AscPutReadyQueue(ASC_DVC_VAR asc_ptr_type *,
2004
                    ASC_SCSI_Q *, uchar);
2005
STATIC int       AscPutReadySgListQueue(ASC_DVC_VAR asc_ptr_type *,
2006
                    ASC_SCSI_Q *, uchar);
2007
STATIC int       AscSetChipSynRegAtID(PortAddr, uchar, uchar);
2008
STATIC int       AscSetRunChipSynRegAtID(PortAddr, uchar, uchar);
2009
STATIC ushort    AscInitLram(ASC_DVC_VAR asc_ptr_type *);
2010
STATIC int       AscReInitLram(ASC_DVC_VAR asc_ptr_type *);
2011
STATIC ushort    AscInitQLinkVar(ASC_DVC_VAR asc_ptr_type *);
2012
STATIC int       AscSetLibErrorCode(ASC_DVC_VAR asc_ptr_type *, ushort);
2013
#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
2014
STATIC int       _AscWaitQDone(PortAddr, ASC_SCSI_Q *);
2015
#endif /* version >= v1.3.89 */
2016
STATIC int       AscIsrChipHalted(ASC_DVC_VAR asc_ptr_type *);
2017
STATIC uchar     _AscCopyLramScsiDoneQ(PortAddr, ushort,
2018
                    ASC_QDONE_INFO *, ulong);
2019
STATIC int       AscIsrQDone(ASC_DVC_VAR asc_ptr_type *);
2020
STATIC int       AscCompareString(uchar *, uchar *, int);
2021
STATIC ushort    AscGetEisaChipCfg(PortAddr);
2022
STATIC ulong     AscGetEisaProductID(PortAddr);
2023
STATIC PortAddr  AscSearchIOPortAddrEISA(PortAddr);
2024
STATIC uchar     AscGetChipScsiCtrl(PortAddr);
2025
STATIC uchar     AscSetChipScsiID(PortAddr, uchar);
2026
STATIC uchar     AscGetChipVersion(PortAddr, ushort);
2027
STATIC ushort    AscGetChipBusType(PortAddr);
2028
STATIC ulong     AscLoadMicroCode(PortAddr, ushort, ushort *, ushort);
2029
STATIC int       AscFindSignature(PortAddr);
2030
STATIC PortAddr  AscSearchIOPortAddr11(PortAddr);
2031
STATIC void      AscToggleIRQAct(PortAddr);
2032
STATIC void      AscSetISAPNPWaitForKey(void);
2033
STATIC uchar     AscGetChipIRQ(PortAddr, ushort);
2034
STATIC uchar     AscSetChipIRQ(PortAddr, uchar, ushort);
2035
STATIC ushort    AscGetChipBiosAddress(PortAddr, ushort);
2036
STATIC int       DvcEnterCritical(void);
2037
STATIC void      DvcLeaveCritical(int);
2038
STATIC void      DvcInPortWords(PortAddr, ushort *, int);
2039
STATIC void      DvcOutPortWords(PortAddr, ushort *, int);
2040
STATIC void      DvcOutPortDWords(PortAddr, ulong *, int);
2041
STATIC uchar     DvcReadPCIConfigByte(ASC_DVC_VAR asc_ptr_type *, ushort);
2042
STATIC void      DvcWritePCIConfigByte(ASC_DVC_VAR asc_ptr_type *,
2043
                    ushort, uchar);
2044
STATIC ushort      AscGetChipBiosAddress(PortAddr, ushort);
2045
STATIC void      DvcSleepMilliSecond(ulong);
2046
STATIC void      DvcDelayNanoSecond(ASC_DVC_VAR asc_ptr_type *, ulong);
2047
STATIC ulong     DvcGetSGList(ASC_DVC_VAR asc_ptr_type *, uchar *,
2048
                    ulong, ASC_SG_HEAD *);
2049
STATIC void      DvcPutScsiQ(PortAddr, ushort, ushort *, int);
2050
STATIC void      DvcGetQinfo(PortAddr, ushort, ushort *, int);
2051
STATIC PortAddr  AscSearchIOPortAddr(PortAddr, ushort);
2052
STATIC ushort    AscInitGetConfig(ASC_DVC_VAR asc_ptr_type *);
2053
STATIC ushort    AscInitSetConfig(ASC_DVC_VAR asc_ptr_type *);
2054
STATIC ushort    AscInitAsc1000Driver(ASC_DVC_VAR asc_ptr_type *);
2055
STATIC void      AscAsyncFix(ASC_DVC_VAR asc_ptr_type *, uchar,
2056
                    ASC_SCSI_INQUIRY *);
2057
STATIC int       AscTagQueuingSafe(ASC_SCSI_INQUIRY *);
2058
STATIC void      AscInquiryHandling(ASC_DVC_VAR asc_ptr_type *,
2059
                    uchar, ASC_SCSI_INQUIRY *);
2060
STATIC int       AscExeScsiQueue(ASC_DVC_VAR asc_ptr_type *, ASC_SCSI_Q *);
2061
STATIC int       AscISR(ASC_DVC_VAR asc_ptr_type *);
2062
STATIC uint      AscGetNumOfFreeQueue(ASC_DVC_VAR asc_ptr_type *, uchar,
2063
                    uchar);
2064
STATIC int       AscSgListToQueue(int);
2065
STATIC int       AscAbortSRB(ASC_DVC_VAR asc_ptr_type *, ulong);
2066
#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
2067
STATIC int       AscResetDevice(ASC_DVC_VAR asc_ptr_type *, uchar);
2068
#endif /* version >= v1.3.89 */
2069
STATIC int       AscResetSB(ASC_DVC_VAR asc_ptr_type *);
2070
STATIC void      AscEnableIsaDma(uchar);
2071
STATIC ulong     AscGetMaxDmaCount(ushort);
2072
 
2073
 
2074
/*
2075
 * --- Adv Library Constants and Macros
2076
 */
2077
 
2078
#define ADV_LIB_VERSION_MAJOR  3
2079
#define ADV_LIB_VERSION_MINOR  45
2080
 
2081
/* d_os_dep.h */
2082
#define ADV_OS_LINUX
2083
 
2084
/*
2085
 * Define Adv Library required special types.
2086
 */
2087
#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0)
2088
#define AdvPortAddr  unsigned short     /* I/O Port address size */
2089
#else /* version >= v1,3,0 */
2090
#define AdvPortAddr  unsigned long      /* Virtual memory address size */
2091
#endif /* version >= v1,3,0 */
2092
 
2093
/*
2094
 * Define Adv Library required memory access macros.
2095
 */
2096
#define ADV_MEM_READB(addr) readb(addr)
2097
#define ADV_MEM_READW(addr) readw(addr)
2098
#define ADV_MEM_WRITEB(addr, byte) writeb(byte, addr)
2099
#define ADV_MEM_WRITEW(addr, word) writew(word, addr)
2100
 
2101
/*
2102
 * The I/O memory mapping function names changed in 2.1.X.
2103
 */
2104
#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,0)
2105
#define ioremap vremap
2106
#define iounmap vfree
2107
#endif /* version < v2.1.0 */
2108
 
2109
/*
2110
 * Define total number of simultaneous maximum element scatter-gather
2111
 * requests, i.e. ADV_TOT_SG_LIST * ADV_MAX_SG_LIST is the total number
2112
 * of simultaneous scatter-gather elements supported per wide adapter.
2113
 */
2114
#define ADV_TOT_SG_LIST         64
2115
 
2116
/*
2117
 * Define Adv Library required per request scatter-gather element limit.
2118
 */
2119
#define ADV_MAX_SG_LIST         64
2120
 
2121
/*
2122
 * Scatter-Gather Definitions per request.
2123
 *
2124
 * Because SG block memory is allocated in virtual memory but is
2125
 * referenced by the microcode as physical memory, we need to do
2126
 * calculations to insure there will be enough physically contiguous
2127
 * memory to support ADV_MAX_SG_LIST SG entries.
2128
 */
2129
 
2130
/* Number of SG blocks needed. */
2131
#define ADV_NUM_SG_BLOCK \
2132
     ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK)
2133
 
2134
/* Total contiguous memory needed for SG blocks. */
2135
#define ADV_SG_TOTAL_MEM_SIZE \
2136
    (sizeof(ADV_SG_BLOCK) *  ADV_NUM_SG_BLOCK)
2137
 
2138
#define ASC_PAGE_SIZE PAGE_SIZE
2139
 
2140
/*
2141
 * Number of page crossings possible for the total contiguous virtual memory
2142
 * needed for SG blocks.
2143
 *
2144
 * We need to allocate this many additional SG blocks in virtual memory to
2145
 * insure there will be space for ADV_NUM_SG_BLOCK physically contiguous
2146
 * scatter-gather blocks.
2147
 */
2148
#define ADV_NUM_PAGE_CROSSING \
2149
    ((ADV_SG_TOTAL_MEM_SIZE + (ASC_PAGE_SIZE - 1))/ASC_PAGE_SIZE)
2150
 
2151
/*
2152
 * Define Adv Library Assertion Macro.
2153
 */
2154
 
2155
#define ADV_ASSERT(a) ASC_ASSERT(a)
2156
 
2157
/* a_condor.h */
2158
#define ADV_PCI_VENDOR_ID               0x10CD
2159
#define ADV_PCI_DEVICE_ID_REV_A         0x2300
2160
 
2161
#define ASC_EEP_DVC_CFG_BEGIN           (0x00)
2162
#define ASC_EEP_DVC_CFG_END             (0x15)
2163
#define ASC_EEP_DVC_CTL_BEGIN           (0x16)  /* location of OEM name */
2164
#define ASC_EEP_MAX_WORD_ADDR           (0x1E)
2165
 
2166
#define ASC_EEP_DELAY_MS                100
2167
 
2168
/*
2169
 * EEPROM bits reference by the RISC after initialization.
2170
 */
2171
#define ADV_EEPROM_BIG_ENDIAN          0x8000   /* EEPROM Bit 15 */
2172
#define ADV_EEPROM_BIOS_ENABLE         0x4000   /* EEPROM Bit 14 */
2173
#define ADV_EEPROM_TERM_POL            0x2000   /* EEPROM Bit 13 */
2174
 
2175
/*
2176
 * EEPROM configuration format
2177
 *
2178
 * Field naming convention:
2179
 *
2180
 *  *_enable indicates the field enables or disables the feature. The
2181
 *  value is never reset.
2182
 *
2183
 *  *_able indicates both whether a feature should be enabled or disabled
2184
 *  and whether a device isi capable of the feature. At initialization
2185
 *  this field may be set, but later if a device is found to be incapable
2186
 *  of the feature, the field is cleared.
2187
 *
2188
 * Default values are maintained in a_init.c in the structure
2189
 * Default_EEPROM_Config.
2190
 */
2191
typedef struct adveep_config
2192
{
2193
                                /* Word Offset, Description */
2194
 
2195
  ushort cfg_lsw;               /* 00 power up initialization */
2196
                                /*  bit 13 set - Term Polarity Control */
2197
                                /*  bit 14 set - BIOS Enable */
2198
                                /*  bit 15 set - Big Endian Mode */
2199
  ushort cfg_msw;               /* 01 unused      */
2200
  ushort disc_enable;           /* 02 disconnect enable */
2201
  ushort wdtr_able;             /* 03 Wide DTR able */
2202
  ushort sdtr_able;             /* 04 Synchronous DTR able */
2203
  ushort start_motor;           /* 05 send start up motor */
2204
  ushort tagqng_able;           /* 06 tag queuing able */
2205
  ushort bios_scan;             /* 07 BIOS device control */
2206
  ushort scam_tolerant;         /* 08 no scam */
2207
 
2208
  uchar  adapter_scsi_id;       /* 09 Host Adapter ID */
2209
  uchar  bios_boot_delay;       /*    power up wait */
2210
 
2211
  uchar  scsi_reset_delay;      /* 10 reset delay */
2212
  uchar  bios_id_lun;           /*    first boot device scsi id & lun */
2213
                                /*    high nibble is lun */
2214
                                /*    low nibble is scsi id */
2215
 
2216
  uchar  termination;           /* 11 0 - automatic */
2217
                                /*    1 - low off / high off */
2218
                                /*    2 - low off / high on */
2219
                                /*    3 - low on  / high on */
2220
                                /*    There is no low on  / high off */
2221
 
2222
  uchar  reserved1;             /*    reserved byte (not used) */
2223
 
2224
  ushort bios_ctrl;             /* 12 BIOS control bits */
2225
                                /*  bit 0  set: BIOS don't act as initiator. */
2226
                                /*  bit 1  set: BIOS > 1 GB support */
2227
                                /*  bit 2  set: BIOS > 2 Disk Support */
2228
                                /*  bit 3  set: BIOS don't support removables */
2229
                                /*  bit 4  set: BIOS support bootable CD */
2230
                                /*  bit 5  set: */
2231
                                /*  bit 6  set: BIOS support multiple LUNs */
2232
                                /*  bit 7  set: BIOS display of message */
2233
                                /*  bit 8  set: */
2234
                                /*  bit 9  set: Reset SCSI bus during init. */
2235
                                /*  bit 10 set: */
2236
                                /*  bit 11 set: No verbose initialization. */
2237
                                /*  bit 12 set: SCSI parity enabled */
2238
                                /*  bit 13 set: */
2239
                                /*  bit 14 set: */
2240
                                /*  bit 15 set: */
2241
  ushort  ultra_able;           /* 13 ULTRA speed able */
2242
  ushort  reserved2;            /* 14 reserved */
2243
  uchar   max_host_qng;         /* 15 maximum host queuing */
2244
  uchar   max_dvc_qng;          /*    maximum per device queuing */
2245
  ushort  dvc_cntl;             /* 16 control bit for driver */
2246
  ushort  bug_fix;              /* 17 control bit for bug fix */
2247
  ushort  serial_number_word1;  /* 18 Board serial number word 1 */
2248
  ushort  serial_number_word2;  /* 19 Board serial number word 2 */
2249
  ushort  serial_number_word3;  /* 20 Board serial number word 3 */
2250
  ushort  check_sum;            /* 21 EEP check sum */
2251
  uchar   oem_name[16];         /* 22 OEM name */
2252
  ushort  dvc_err_code;         /* 30 last device driver error code */
2253
  ushort  adv_err_code;         /* 31 last uc and Adv Lib error code */
2254
  ushort  adv_err_addr;         /* 32 last uc error address */
2255
  ushort  saved_dvc_err_code;   /* 33 saved last dev. driver error code   */
2256
  ushort  saved_adv_err_code;   /* 34 saved last uc and Adv Lib error code */
2257
  ushort  saved_adv_err_addr;   /* 35 saved last uc error address         */
2258
  ushort  num_of_err;           /* 36 number of error */
2259
} ADVEEP_CONFIG;
2260
 
2261
/*
2262
 * EEPROM Commands
2263
 */
2264
#define ASC_EEP_CMD_DONE             0x0200
2265
#define ASC_EEP_CMD_DONE_ERR         0x0001
2266
 
2267
/* cfg_word */
2268
#define EEP_CFG_WORD_BIG_ENDIAN      0x8000
2269
 
2270
/* bios_ctrl */
2271
#define BIOS_CTRL_BIOS               0x0001
2272
#define BIOS_CTRL_EXTENDED_XLAT      0x0002
2273
#define BIOS_CTRL_GT_2_DISK          0x0004
2274
#define BIOS_CTRL_BIOS_REMOVABLE     0x0008
2275
#define BIOS_CTRL_BOOTABLE_CD        0x0010
2276
#define BIOS_CTRL_MULTIPLE_LUN       0x0040
2277
#define BIOS_CTRL_DISPLAY_MSG        0x0080
2278
#define BIOS_CTRL_NO_SCAM            0x0100
2279
#define BIOS_CTRL_RESET_SCSI_BUS     0x0200
2280
#define BIOS_CTRL_INIT_VERBOSE       0x0800
2281
#define BIOS_CTRL_SCSI_PARITY        0x1000
2282
 
2283
/*
2284
 * ASC 3550 Internal Memory Size - 8KB
2285
 */
2286
#define ADV_CONDOR_MEMSIZE   0x2000     /* 8 KB Internal Memory */
2287
 
2288
/*
2289
 * ASC 3550 I/O Length - 64 bytes
2290
 */
2291
#define ADV_CONDOR_IOLEN     0x40       /* I/O Port Range in bytes */
2292
 
2293
/*
2294
 * Byte I/O register address from base of 'iop_base'.
2295
 */
2296
#define IOPB_INTR_STATUS_REG    0x00
2297
#define IOPB_CHIP_ID_1          0x01
2298
#define IOPB_INTR_ENABLES       0x02
2299
#define IOPB_CHIP_TYPE_REV      0x03
2300
#define IOPB_RES_ADDR_4         0x04
2301
#define IOPB_RES_ADDR_5         0x05
2302
#define IOPB_RAM_DATA           0x06
2303
#define IOPB_RES_ADDR_7         0x07
2304
#define IOPB_FLAG_REG           0x08
2305
#define IOPB_RES_ADDR_9         0x09
2306
#define IOPB_RISC_CSR           0x0A
2307
#define IOPB_RES_ADDR_B         0x0B
2308
#define IOPB_RES_ADDR_C         0x0C
2309
#define IOPB_RES_ADDR_D         0x0D
2310
#define IOPB_RES_ADDR_E         0x0E
2311
#define IOPB_RES_ADDR_F         0x0F
2312
#define IOPB_MEM_CFG            0x10
2313
#define IOPB_RES_ADDR_11        0x11
2314
#define IOPB_RES_ADDR_12        0x12
2315
#define IOPB_RES_ADDR_13        0x13
2316
#define IOPB_FLASH_PAGE         0x14
2317
#define IOPB_RES_ADDR_15        0x15
2318
#define IOPB_RES_ADDR_16        0x16
2319
#define IOPB_RES_ADDR_17        0x17
2320
#define IOPB_FLASH_DATA         0x18
2321
#define IOPB_RES_ADDR_19        0x19
2322
#define IOPB_RES_ADDR_1A        0x1A
2323
#define IOPB_RES_ADDR_1B        0x1B
2324
#define IOPB_RES_ADDR_1C        0x1C
2325
#define IOPB_RES_ADDR_1D        0x1D
2326
#define IOPB_RES_ADDR_1E        0x1E
2327
#define IOPB_RES_ADDR_1F        0x1F
2328
#define IOPB_DMA_CFG0           0x20
2329
#define IOPB_DMA_CFG1           0x21
2330
#define IOPB_TICKLE             0x22
2331
#define IOPB_DMA_REG_WR         0x23
2332
#define IOPB_SDMA_STATUS        0x24
2333
#define IOPB_SCSI_BYTE_CNT      0x25
2334
#define IOPB_HOST_BYTE_CNT      0x26
2335
#define IOPB_BYTE_LEFT_TO_XFER  0x27
2336
#define IOPB_BYTE_TO_XFER_0     0x28
2337
#define IOPB_BYTE_TO_XFER_1     0x29
2338
#define IOPB_BYTE_TO_XFER_2     0x2A
2339
#define IOPB_BYTE_TO_XFER_3     0x2B
2340
#define IOPB_ACC_GRP            0x2C
2341
#define IOPB_RES_ADDR_2D        0x2D
2342
#define IOPB_DEV_ID             0x2E
2343
#define IOPB_RES_ADDR_2F        0x2F
2344
#define IOPB_SCSI_DATA          0x30
2345
#define IOPB_RES_ADDR_31        0x31
2346
#define IOPB_RES_ADDR_32        0x32
2347
#define IOPB_SCSI_DATA_HSHK     0x33
2348
#define IOPB_SCSI_CTRL          0x34
2349
#define IOPB_RES_ADDR_35        0x35
2350
#define IOPB_RES_ADDR_36        0x36
2351
#define IOPB_RES_ADDR_37        0x37
2352
#define IOPB_RES_ADDR_38        0x38
2353
#define IOPB_RES_ADDR_39        0x39
2354
#define IOPB_RES_ADDR_3A        0x3A
2355
#define IOPB_RES_ADDR_3B        0x3B
2356
#define IOPB_RFIFO_CNT          0x3C
2357
#define IOPB_RES_ADDR_3D        0x3D
2358
#define IOPB_RES_ADDR_3E        0x3E
2359
#define IOPB_RES_ADDR_3F        0x3F
2360
 
2361
/*
2362
 * Word I/O register address from base of 'iop_base'.
2363
 */
2364
#define IOPW_CHIP_ID_0          0x00  /* CID0  */
2365
#define IOPW_CTRL_REG           0x02  /* CC    */
2366
#define IOPW_RAM_ADDR           0x04  /* LA    */
2367
#define IOPW_RAM_DATA           0x06  /* LD    */
2368
#define IOPW_RES_ADDR_08        0x08
2369
#define IOPW_RISC_CSR           0x0A  /* CSR   */
2370
#define IOPW_SCSI_CFG0          0x0C  /* CFG0  */
2371
#define IOPW_SCSI_CFG1          0x0E  /* CFG1  */
2372
#define IOPW_RES_ADDR_10        0x10
2373
#define IOPW_SEL_MASK           0x12  /* SM    */
2374
#define IOPW_RES_ADDR_14        0x14
2375
#define IOPW_FLASH_ADDR         0x16  /* FA    */
2376
#define IOPW_RES_ADDR_18        0x18
2377
#define IOPW_EE_CMD             0x1A  /* EC    */
2378
#define IOPW_EE_DATA            0x1C  /* ED    */
2379
#define IOPW_SFIFO_CNT          0x1E  /* SFC   */
2380
#define IOPW_RES_ADDR_20        0x20
2381
#define IOPW_Q_BASE             0x22  /* QB    */
2382
#define IOPW_QP                 0x24  /* QP    */
2383
#define IOPW_IX                 0x26  /* IX    */
2384
#define IOPW_SP                 0x28  /* SP    */
2385
#define IOPW_PC                 0x2A  /* PC    */
2386
#define IOPW_RES_ADDR_2C        0x2C
2387
#define IOPW_RES_ADDR_2E        0x2E
2388
#define IOPW_SCSI_DATA          0x30  /* SD    */
2389
#define IOPW_SCSI_DATA_HSHK     0x32  /* SDH   */
2390
#define IOPW_SCSI_CTRL          0x34  /* SC    */
2391
#define IOPW_HSHK_CFG           0x36  /* HCFG  */
2392
#define IOPW_SXFR_STATUS        0x36  /* SXS   */
2393
#define IOPW_SXFR_CNTL          0x38  /* SXL   */
2394
#define IOPW_SXFR_CNTH          0x3A  /* SXH   */
2395
#define IOPW_RES_ADDR_3C        0x3C
2396
#define IOPW_RFIFO_DATA         0x3E  /* RFD   */
2397
 
2398
/*
2399
 * Doubleword I/O register address from base of 'iop_base'.
2400
 */
2401
#define IOPDW_RES_ADDR_0         0x00
2402
#define IOPDW_RAM_DATA           0x04
2403
#define IOPDW_RES_ADDR_8         0x08
2404
#define IOPDW_RES_ADDR_C         0x0C
2405
#define IOPDW_RES_ADDR_10        0x10
2406
#define IOPDW_RES_ADDR_14        0x14
2407
#define IOPDW_RES_ADDR_18        0x18
2408
#define IOPDW_RES_ADDR_1C        0x1C
2409
#define IOPDW_SDMA_ADDR0         0x20
2410
#define IOPDW_SDMA_ADDR1         0x24
2411
#define IOPDW_SDMA_COUNT         0x28
2412
#define IOPDW_SDMA_ERROR         0x2C
2413
#define IOPDW_RDMA_ADDR0         0x30
2414
#define IOPDW_RDMA_ADDR1         0x34
2415
#define IOPDW_RDMA_COUNT         0x38
2416
#define IOPDW_RDMA_ERROR         0x3C
2417
 
2418
#define ADV_CHIP_ID_BYTE         0x25
2419
#define ADV_CHIP_ID_WORD         0x04C1
2420
 
2421
#define ADV_SC_SCSI_BUS_RESET    0x2000
2422
 
2423
#define ADV_INTR_ENABLE_HOST_INTR                   0x01
2424
#define ADV_INTR_ENABLE_SEL_INTR                    0x02
2425
#define ADV_INTR_ENABLE_DPR_INTR                    0x04
2426
#define ADV_INTR_ENABLE_RTA_INTR                    0x08
2427
#define ADV_INTR_ENABLE_RMA_INTR                    0x10
2428
#define ADV_INTR_ENABLE_RST_INTR                    0x20
2429
#define ADV_INTR_ENABLE_DPE_INTR                    0x40
2430
#define ADV_INTR_ENABLE_GLOBAL_INTR                 0x80
2431
 
2432
#define ADV_INTR_STATUS_INTRA            0x01
2433
#define ADV_INTR_STATUS_INTRB            0x02
2434
#define ADV_INTR_STATUS_INTRC            0x04
2435
 
2436
#define ADV_RISC_CSR_STOP           (0x0000)
2437
#define ADV_RISC_TEST_COND          (0x2000)
2438
#define ADV_RISC_CSR_RUN            (0x4000)
2439
#define ADV_RISC_CSR_SINGLE_STEP    (0x8000)
2440
 
2441
#define ADV_CTRL_REG_HOST_INTR      0x0100
2442
#define ADV_CTRL_REG_SEL_INTR       0x0200
2443
#define ADV_CTRL_REG_DPR_INTR       0x0400
2444
#define ADV_CTRL_REG_RTA_INTR       0x0800
2445
#define ADV_CTRL_REG_RMA_INTR       0x1000
2446
#define ADV_CTRL_REG_RES_BIT14      0x2000
2447
#define ADV_CTRL_REG_DPE_INTR       0x4000
2448
#define ADV_CTRL_REG_POWER_DONE     0x8000
2449
#define ADV_CTRL_REG_ANY_INTR       0xFF00
2450
 
2451
#define ADV_CTRL_REG_CMD_RESET             0x00C6
2452
#define ADV_CTRL_REG_CMD_WR_IO_REG         0x00C5
2453
#define ADV_CTRL_REG_CMD_RD_IO_REG         0x00C4
2454
#define ADV_CTRL_REG_CMD_WR_PCI_CFG_SPACE  0x00C3
2455
#define ADV_CTRL_REG_CMD_RD_PCI_CFG_SPACE  0x00C2
2456
 
2457
#define ADV_SCSI_CTRL_RSTOUT        0x2000
2458
 
2459
#define AdvIsIntPending(port)  \
2460
    (AdvReadWordRegister(port, IOPW_CTRL_REG) & ADV_CTRL_REG_HOST_INTR)
2461
 
2462
/*
2463
 * SCSI_CFG0 Register bit definitions
2464
 */
2465
#define TIMER_MODEAB    0xC000  /* Watchdog, Second, and Select. Timer Ctrl. */
2466
#define PARITY_EN       0x2000  /* Enable SCSI Parity Error detection */
2467
#define EVEN_PARITY     0x1000  /* Select Even Parity */
2468
#define WD_LONG         0x0800  /* Watchdog Interval, 1: 57 min, 0: 13 sec */
2469
#define QUEUE_128       0x0400  /* Queue Size, 1: 128 byte, 0: 64 byte */
2470
#define PRIM_MODE       0x0100  /* Primitive SCSI mode */
2471
#define SCAM_EN         0x0080  /* Enable SCAM selection */
2472
#define SEL_TMO_LONG    0x0040  /* Sel/Resel Timeout, 1: 400 ms, 0: 1.6 ms */
2473
#define CFRM_ID         0x0020  /* SCAM id sel. confirm., 1: fast, 0: 6.4 ms */
2474
#define OUR_ID_EN       0x0010  /* Enable OUR_ID bits */
2475
#define OUR_ID          0x000F  /* SCSI ID */
2476
 
2477
/*
2478
 * SCSI_CFG1 Register bit definitions
2479
 */
2480
#define BIG_ENDIAN      0x8000  /* Enable Big Endian Mode MIO:15, EEP:15 */
2481
#define TERM_POL        0x2000  /* Terminator Polarity Ctrl. MIO:13, EEP:13 */
2482
#define SLEW_RATE       0x1000  /* SCSI output buffer slew rate */
2483
#define FILTER_SEL      0x0C00  /* Filter Period Selection */
2484
#define  FLTR_DISABLE    0x0000  /* Input Filtering Disabled */
2485
#define  FLTR_11_TO_20NS 0x0800  /* Input Filtering 11ns to 20ns */          
2486
#define  FLTR_21_TO_39NS 0x0C00  /* Input Filtering 21ns to 39ns */          
2487
#define ACTIVE_DBL      0x0200  /* Disable Active Negation */
2488
#define DIFF_MODE       0x0100  /* SCSI differential Mode (Read-Only) */
2489
#define DIFF_SENSE      0x0080  /* 1: No SE cables, 0: SE cable (Read-Only) */
2490
#define TERM_CTL_SEL    0x0040  /* Enable TERM_CTL_H and TERM_CTL_L */
2491
#define TERM_CTL        0x0030  /* External SCSI Termination Bits */
2492
#define  TERM_CTL_H      0x0020  /* Enable External SCSI Upper Termination */
2493
#define  TERM_CTL_L      0x0010  /* Enable External SCSI Lower Termination */
2494
#define CABLE_DETECT    0x000F  /* External SCSI Cable Connection Status */
2495
 
2496
#define CABLE_ILLEGAL_A 0x7
2497
    /* x 0 0 0  | on  on | Illegal (all 3 connectors are used) */
2498
 
2499
#define CABLE_ILLEGAL_B 0xB
2500
    /* 0 x 0 0  | on  on | Illegal (all 3 connectors are used) */
2501
 
2502
/*
2503
   The following table details the SCSI_CFG1 Termination Polarity,
2504
   Termination Control and Cable Detect bits.
2505
 
2506
   Cable Detect | Termination
2507
   Bit 3 2 1 0  | 5   4  | Notes
2508
   _____________|________|____________________
2509
       1 1 1 0  | on  on | Internal wide only
2510
       1 1 0 1  | on  on | Internal narrow only
2511
       1 0 1 1  | on  on | External narrow only
2512
 
2513
       1 1 0 0  | on  off| Internal wide and internal narrow
2514
       1 0 1 0  | on  off| Internal wide and external narrow
2515
 
2516
       1 0 0 1  | on  off| Internal narrow and external narrow
2517
 
2518
       1 1 1 1  | on  on | No devices are attached
2519
       x 0 0 0  | on  on | Illegal (all 3 connectors are used)
2520
 
2521
 
2522
       x means don't-care (either '0' or '1')
2523
 
2524
       If term_pol (bit 13) is '0' (active-low terminator enable), then:
2525
           'on' is '0' and 'off' is '1'.
2526
 
2527
       If term_pol bit is '1' (meaning active-hi terminator enable), then:
2528
           'on' is '1' and 'off' is '0'.
2529
 */
2530
 
2531
/*
2532
 * MEM_CFG Register bit definitions
2533
 */
2534
#define BIOS_EN         0x40    /* BIOS Enable MIO:14,EEP:14 */
2535
#define FAST_EE_CLK     0x20    /* Diagnostic Bit */
2536
#define RAM_SZ          0x1C    /* Specify size of RAM to RISC */
2537
#define  RAM_SZ_2KB      0x00    /* 2 KB */
2538
#define  RAM_SZ_4KB      0x04    /* 4 KB */
2539
#define  RAM_SZ_8KB      0x08    /* 8 KB */
2540
#define  RAM_SZ_16KB     0x0C    /* 16 KB */
2541
#define  RAM_SZ_32KB     0x10    /* 32 KB */
2542
#define  RAM_SZ_64KB     0x14    /* 64 KB */
2543
 
2544
/*
2545
 * DMA_CFG0 Register bit definitions
2546
 *
2547
 * This register is only accessible to the host.
2548
 */
2549
#define BC_THRESH_ENB   0x80    /* PCI DMA Start Conditions */
2550
#define FIFO_THRESH     0x70    /* PCI DMA FIFO Threshold */
2551
#define  FIFO_THRESH_16B  0x00   /* 16 bytes */
2552
#define  FIFO_THRESH_32B  0x20   /* 32 bytes */
2553
#define  FIFO_THRESH_48B  0x30   /* 48 bytes */
2554
#define  FIFO_THRESH_64B  0x40   /* 64 bytes */
2555
#define  FIFO_THRESH_80B  0x50   /* 80 bytes (default) */
2556
#define  FIFO_THRESH_96B  0x60   /* 96 bytes */
2557
#define  FIFO_THRESH_112B 0x70   /* 112 bytes */
2558
#define START_CTL       0x0C    /* DMA start conditions */
2559
#define  START_CTL_TH    0x00    /* Wait threshold level (default) */
2560
#define  START_CTL_ID    0x04    /* Wait SDMA/SBUS idle */
2561
#define  START_CTL_THID  0x08    /* Wait threshold and SDMA/SBUS idle */
2562
#define  START_CTL_EMFU  0x0C    /* Wait SDMA FIFO empty/full */
2563
#define READ_CMD        0x03    /* Memory Read Method */
2564
#define  READ_CMD_MR     0x00    /* Memory Read */
2565
#define  READ_CMD_MRL    0x02    /* Memory Read Long */
2566
#define  READ_CMD_MRM    0x03    /* Memory Read Multiple (default) */
2567
 
2568
/* a_advlib.h */
2569
 
2570
/*
2571
 * Adv Library Status Definitions
2572
 */
2573
#define ADV_TRUE        1
2574
#define ADV_FALSE       0
2575
#define ADV_NOERROR     1
2576
#define ADV_SUCCESS     1
2577
#define ADV_BUSY        0
2578
#define ADV_ERROR       (-1)
2579
 
2580
 
2581
/*
2582
 * ASC_DVC_VAR 'warn_code' values
2583
 */
2584
#define ASC_WARN_EEPROM_CHKSUM          0x0002 /* EEP check sum error */
2585
#define ASC_WARN_EEPROM_TERMINATION     0x0004 /* EEP termination bad field */
2586
#define ASC_WARN_SET_PCI_CONFIG_SPACE   0x0080 /* PCI config space set error */
2587
#define ASC_WARN_ERROR                  0xFFFF /* ADV_ERROR return */
2588
 
2589
#define ADV_MAX_TID                     15 /* max. target identifier */
2590
#define ADV_MAX_LUN                     7  /* max. logical unit number */
2591
 
2592
 
2593
/*
2594
 * AscInitGetConfig() and AscInitAsc1000Driver() Definitions
2595
 *
2596
 * Error code values are set in ASC_DVC_VAR 'err_code'.
2597
 */
2598
#define ASC_IERR_WRITE_EEPROM       0x0001 /* write EEPROM error */
2599
#define ASC_IERR_MCODE_CHKSUM       0x0002 /* micro code check sum error */
2600
#define ASC_IERR_START_STOP_CHIP    0x0008 /* start/stop chip failed */
2601
#define ASC_IERR_CHIP_VERSION       0x0040 /* wrong chip version */
2602
#define ASC_IERR_SET_SCSI_ID        0x0080 /* set SCSI ID failed */
2603
#define ASC_IERR_BAD_SIGNATURE      0x0200 /* signature not found */
2604
#define ASC_IERR_ILLEGAL_CONNECTION 0x0400 /* Illegal cable connection */
2605
#define ASC_IERR_SINGLE_END_DEVICE  0x0800 /* Single-end used w/differential */
2606
#define ASC_IERR_REVERSED_CABLE     0x1000 /* Narrow flat cable reversed */
2607
#define ASC_IERR_RW_LRAM            0x8000 /* read/write local RAM error */
2608
 
2609
/*
2610
 * Fixed locations of microcode operating variables.
2611
 */
2612
#define ASC_MC_CODE_BEGIN_ADDR          0x0028 /* microcode start address */
2613
#define ASC_MC_CODE_END_ADDR            0x002A /* microcode end address */
2614
#define ASC_MC_CODE_CHK_SUM             0x002C /* microcode code checksum */
2615
#define ASC_MC_STACK_BEGIN              0x002E /* microcode stack begin */
2616
#define ASC_MC_STACK_END                0x0030 /* microcode stack end */
2617
#define ASC_MC_VERSION_DATE             0x0038 /* microcode version */
2618
#define ASC_MC_VERSION_NUM              0x003A /* microcode number */
2619
#define ASCV_VER_SERIAL_W               0x003C /* used in dos_init */
2620
#define ASC_MC_BIOSMEM                  0x0040 /* BIOS RISC Memory Start */
2621
#define ASC_MC_BIOSLEN                  0x0050 /* BIOS RISC Memory Length */
2622
#define ASC_MC_HALTCODE                 0x0094 /* microcode halt code */
2623
#define ASC_MC_CALLERPC                 0x0096 /* microcode halt caller PC */
2624
#define ASC_MC_ADAPTER_SCSI_ID          0x0098 /* one ID byte + reserved */
2625
#define ASC_MC_ULTRA_ABLE               0x009C
2626
#define ASC_MC_SDTR_ABLE                0x009E
2627
#define ASC_MC_TAGQNG_ABLE              0x00A0
2628
#define ASC_MC_DISC_ENABLE              0x00A2
2629
#define ASC_MC_IDLE_CMD                 0x00A6
2630
#define ASC_MC_IDLE_PARA_STAT           0x00A8
2631
#define ASC_MC_DEFAULT_SCSI_CFG0        0x00AC
2632
#define ASC_MC_DEFAULT_SCSI_CFG1        0x00AE
2633
#define ASC_MC_DEFAULT_MEM_CFG          0x00B0
2634
#define ASC_MC_DEFAULT_SEL_MASK         0x00B2
2635
#define ASC_MC_RISC_NEXT_READY          0x00B4
2636
#define ASC_MC_RISC_NEXT_DONE           0x00B5
2637
#define ASC_MC_SDTR_DONE                0x00B6
2638
#define ASC_MC_NUMBER_OF_QUEUED_CMD     0x00C0
2639
#define ASC_MC_NUMBER_OF_MAX_CMD        0x00D0
2640
#define ASC_MC_DEVICE_HSHK_CFG_TABLE    0x0100
2641
#define ASC_MC_WDTR_ABLE                0x0120 /* Wide Transfer TID bitmask. */
2642
#define ASC_MC_CONTROL_FLAG             0x0122 /* Microcode control flag. */
2643
#define ASC_MC_WDTR_DONE                0x0124
2644
#define ASC_MC_HOST_NEXT_READY          0x0128 /* Host Next Ready RQL Entry. */
2645
#define ASC_MC_HOST_NEXT_DONE           0x0129 /* Host Next Done RQL Entry. */
2646
 
2647
/*
2648
 * BIOS LRAM variable absolute offsets.
2649
 */
2650
#define BIOS_CODESEG    0x54
2651
#define BIOS_CODELEN    0x56
2652
#define BIOS_SIGNATURE  0x58
2653
#define BIOS_VERSION    0x5A
2654
#define BIOS_SIGNATURE  0x58
2655
 
2656
/*
2657
 * Microcode Control Flags
2658
 *
2659
 * Flags set by the Adv Library in RISC variable 'control_flag' (0x122)
2660
 * and handled by the microcode.
2661
 */
2662
#define CONTROL_FLAG_IGNORE_PERR        0x0001 /* Ignore DMA Parity Errors */
2663
 
2664
/*
2665
 * ASC_MC_DEVICE_HSHK_CFG_TABLE microcode table or HSHK_CFG register format
2666
 */
2667
#define HSHK_CFG_WIDE_XFR       0x8000
2668
#define HSHK_CFG_RATE           0x0F00
2669
#define HSHK_CFG_OFFSET         0x001F
2670
 
2671
/*
2672
 * LRAM RISC Queue Lists (LRAM addresses 0x1200 - 0x19FF)
2673
 *
2674
 * Each of the 255 Adv Library/Microcode RISC queue lists or mailboxes
2675
 * starting at LRAM address 0x1200 is 8 bytes and has the following
2676
 * structure. Only 253 of these are actually used for command queues.
2677
 */
2678
 
2679
#define ASC_MC_RISC_Q_LIST_BASE         0x1200
2680
#define ASC_MC_RISC_Q_LIST_SIZE         0x0008
2681
#define ASC_MC_RISC_Q_TOTAL_CNT         0x00FF /* Num. queue slots in LRAM. */
2682
#define ASC_MC_RISC_Q_FIRST             0x0001
2683
#define ASC_MC_RISC_Q_LAST              0x00FF
2684
 
2685
#define ASC_DEF_MAX_HOST_QNG    0xFD /* Max. number of host commands (253) */
2686
#define ASC_DEF_MIN_HOST_QNG    0x10 /* Min. number of host commands (16) */
2687
#define ASC_DEF_MAX_DVC_QNG     0x3F /* Max. number commands per device (63) */
2688
#define ASC_DEF_MIN_DVC_QNG     0x04 /* Min. number commands per device (4) */
2689
 
2690
/* RISC Queue List structure - 8 bytes */
2691
#define RQL_FWD     0     /* forward pointer (1 byte) */
2692
#define RQL_BWD     1     /* backward pointer (1 byte) */
2693
#define RQL_STATE   2     /* state byte - free, ready, done, aborted (1 byte) */
2694
#define RQL_TID     3     /* request target id (1 byte) */
2695
#define RQL_PHYADDR 4     /* request physical pointer (4 bytes) */
2696
 
2697
/* RISC Queue List state values */
2698
#define ASC_MC_QS_FREE                  0x00
2699
#define ASC_MC_QS_READY                 0x01
2700
#define ASC_MC_QS_DONE                  0x40
2701
#define ASC_MC_QS_ABORTED               0x80
2702
 
2703
/* RISC Queue List pointer values */
2704
#define ASC_MC_NULL_Q                   0x00            /* NULL_Q == 0   */
2705
#define ASC_MC_BIOS_Q                   0xFF            /* BIOS_Q = 255  */
2706
 
2707
/* ASC_SCSI_REQ_Q 'cntl' field values */
2708
#define ASC_MC_QC_START_MOTOR           0x02     /* Issue start motor. */
2709
#define ASC_MC_QC_NO_OVERRUN            0x04     /* Don't report overrun. */
2710
#define ASC_MC_QC_FIRST_DMA             0x08     /* Internal microcode flag. */
2711
#define ASC_MC_QC_ABORTED               0x10     /* Request aborted by host. */
2712
#define ASC_MC_QC_REQ_SENSE             0x20     /* Auto-Request Sense. */
2713
#define ASC_MC_QC_DOS_REQ               0x80     /* Request issued by DOS. */
2714
 
2715
 
2716
/*
2717
 * ASC_SCSI_REQ_Q 'a_flag' definitions
2718
 *
2719
 * The Adv Library should limit use to the lower nibble (4 bits) of
2720
 * a_flag. Drivers are free to use the upper nibble (4 bits) of a_flag.
2721
 */
2722
#define ADV_POLL_REQUEST                0x01   /* poll for request completion */
2723
#define ADV_SCSIQ_DONE                  0x02   /* request done */
2724
 
2725
/*
2726
 * Adapter temporary configuration structure
2727
 *
2728
 * This structure can be discarded after initialization. Don't add
2729
 * fields here needed after initialization.
2730
 *
2731
 * Field naming convention:
2732
 *
2733
 *  *_enable indicates the field enables or disables a feature. The
2734
 *  value of the field is never reset.
2735
 */
2736
typedef struct adv_dvc_cfg {
2737
  ushort disc_enable;       /* enable disconnection */
2738
  uchar  chip_version;      /* chip version */
2739
  uchar  termination;       /* Term. Ctrl. bits 6-5 of SCSI_CFG1 register */
2740
  ushort pci_device_id;     /* PCI device code number */
2741
  ushort lib_version;       /* Adv Library version number */
2742
  ushort control_flag;      /* Microcode Control Flag */
2743
  ushort mcode_date;        /* Microcode date */
2744
  ushort mcode_version;     /* Microcode version */
2745
  ushort pci_slot_info;     /* high byte device/function number */
2746
                            /* bits 7-3 device num., bits 2-0 function num. */
2747
                            /* low byte bus num. */
2748
  ushort bios_boot_wait;    /* BIOS boot time delay */
2749
  ushort serial1;           /* EEPROM serial number word 1 */
2750
  ushort serial2;           /* EEPROM serial number word 2 */
2751
  ushort serial3;           /* EEPROM serial number word 3 */
2752
} ADV_DVC_CFG;
2753
 
2754
/*
2755
 * Adapter operation variable structure.
2756
 *
2757
 * One structure is required per host adapter.
2758
 *
2759
 * Field naming convention:
2760
 *
2761
 *  *_able indicates both whether a feature should be enabled or disabled
2762
 *  and whether a device isi capable of the feature. At initialization
2763
 *  this field may be set, but later if a device is found to be incapable
2764
 *  of the feature, the field is cleared.
2765
 */
2766
typedef struct adv_dvc_var {
2767
  AdvPortAddr iop_base;   /* I/O port address */
2768
  ushort err_code;        /* fatal error code */
2769
  ushort bios_ctrl;       /* BIOS control word, EEPROM word 12 */
2770
  Ptr2Func isr_callback;  /* pointer to function, called in AdvISR() */
2771
  Ptr2Func sbreset_callback;  /* pointer to function, called in AdvISR() */
2772
  ushort wdtr_able;       /* try WDTR for a device */
2773
  ushort sdtr_able;       /* try SDTR for a device */
2774
  ushort ultra_able;      /* try SDTR Ultra speed for a device */
2775
  ushort tagqng_able;     /* try tagged queuing with a device */
2776
  uchar  max_dvc_qng;     /* maximum number of tagged commands per device */
2777
  ushort start_motor;     /* start motor command allowed */
2778
  uchar  scsi_reset_wait; /* delay in seconds after scsi bus reset */
2779
  uchar  chip_no;         /* should be assigned by caller */
2780
  uchar  max_host_qng;    /* maximum number of Q'ed command allowed */
2781
  uchar  cur_host_qng;    /* total number of queue command */
2782
  uchar  irq_no;          /* IRQ number */
2783
  ushort no_scam;         /* scam_tolerant of EEPROM */
2784
  ushort idle_cmd_done;   /* microcode idle command done set by AdvISR() */
2785
  ulong  drv_ptr;         /* driver pointer to private structure */
2786
  uchar  chip_scsi_id;    /* chip SCSI target ID */
2787
 /*
2788
  * Note: The following fields will not be used after initialization. The
2789
  * driver may discard the buffer after initialization is done.
2790
  */
2791
  ADV_DVC_CFG *cfg; /* temporary configuration structure  */
2792
} ADV_DVC_VAR;
2793
 
2794
#define NO_OF_SG_PER_BLOCK              15
2795
 
2796
typedef struct asc_sg_block {
2797
    uchar reserved1;
2798
    uchar reserved2;
2799
    uchar first_entry_no;             /* starting entry number */
2800
    uchar last_entry_no;              /* last entry number */
2801
    struct asc_sg_block *sg_ptr; /* links to the next sg block */
2802
    struct  {
2803
        ulong sg_addr;                /* SG element address */
2804
        ulong sg_count;               /* SG element count */
2805
    } sg_list[NO_OF_SG_PER_BLOCK];
2806
} ADV_SG_BLOCK;
2807
 
2808
/*
2809
 * ASC_SCSI_REQ_Q - microcode request structure
2810
 *
2811
 * All fields in this structure up to byte 60 are used by the microcode.
2812
 * The microcode makes assumptions about the size and ordering of fields
2813
 * in this structure. Do not change the structure definition here without
2814
 * coordinating the change with the microcode.
2815
 */
2816
typedef struct adv_scsi_req_q {
2817
    uchar       cntl;           /* Ucode flags and state (ASC_MC_QC_*). */
2818
    uchar       sg_entry_cnt;   /* SG element count. Zero for no SG. */
2819
    uchar       target_id;      /* Device target identifier. */
2820
    uchar       target_lun;     /* Device target logical unit number. */
2821
    ulong       data_addr;      /* Data buffer physical address. */
2822
    ulong       data_cnt;       /* Data count. Ucode sets to residual. */
2823
    ulong       sense_addr;     /* Sense buffer physical address. */
2824
    ulong       srb_ptr;        /* Driver request pointer. */
2825
    uchar       a_flag;         /* Adv Library flag field. */
2826
    uchar       sense_len;      /* Auto-sense length. Ucode sets to residual. */
2827
    uchar       cdb_len;        /* SCSI CDB length. */
2828
    uchar       tag_code;       /* SCSI-2 Tag Queue Code: 00, 20-22. */
2829
    uchar       done_status;    /* Completion status. */
2830
    uchar       scsi_status;    /* SCSI status byte. */
2831
    uchar       host_status;    /* Ucode host status. */
2832
    uchar       ux_sg_ix;       /* Ucode working SG variable. */
2833
    uchar       cdb[12];        /* SCSI command block. */
2834
    ulong       sg_real_addr;   /* SG list physical address. */
2835
    struct adv_scsi_req_q *free_scsiq_link;
2836
    ulong       ux_wk_data_cnt; /* Saved data count at disconnection. */
2837
    struct adv_scsi_req_q *scsiq_ptr;
2838
    ADV_SG_BLOCK *sg_list_ptr; /* SG list virtual address. */
2839
    /*
2840
     * End of microcode structure - 60 bytes. The rest of the structure
2841
     * is used by the Adv Library and ignored by the microcode.
2842
     */
2843
    ulong       vsense_addr;    /* Sense buffer virtual address. */
2844
    ulong       vdata_addr;     /* Data buffer virtual address. */
2845
    uchar       orig_sense_len; /* Original length of sense buffer. */
2846
} ADV_SCSI_REQ_Q; /* BIOS - 70 bytes, DOS - 76 bytes, W95, WNT - 69 bytes */
2847
 
2848
/*
2849
 * Microcode idle loop commands
2850
 */
2851
#define IDLE_CMD_COMPLETED           0
2852
#define IDLE_CMD_STOP_CHIP           0x0001
2853
#define IDLE_CMD_STOP_CHIP_SEND_INT  0x0002
2854
#define IDLE_CMD_SEND_INT            0x0004
2855
#define IDLE_CMD_ABORT               0x0008
2856
#define IDLE_CMD_DEVICE_RESET        0x0010
2857
#define IDLE_CMD_SCSI_RESET          0x0020
2858
 
2859
/*
2860
 * AdvSendIdleCmd() flag definitions.
2861
 */
2862
#define ADV_NOWAIT     0x01
2863
 
2864
/*
2865
 * Wait loop time out values.
2866
 */
2867
#define SCSI_WAIT_10_SEC             10         /* 10 seconds */
2868
#define SCSI_MS_PER_SEC              1000       /* milliseconds per second */
2869
 
2870
/*
2871
 * Device drivers must define the following functions.
2872
 */
2873
STATIC int   DvcEnterCritical(void);
2874
STATIC void  DvcLeaveCritical(int);
2875
STATIC void  DvcSleepMilliSecond(ulong);
2876
STATIC uchar DvcAdvReadPCIConfigByte(ADV_DVC_VAR *, ushort);
2877
STATIC void  DvcAdvWritePCIConfigByte(ADV_DVC_VAR *, ushort, uchar);
2878
STATIC ulong DvcGetPhyAddr(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *,
2879
                uchar *, long *, int);
2880
STATIC void  DvcDelayMicroSecond(ADV_DVC_VAR *, ushort);
2881
 
2882
/*
2883
 * Adv Library functions available to drivers.
2884
 */
2885
STATIC int     AdvExeScsiQueue(ADV_DVC_VAR *,
2886
                         ADV_SCSI_REQ_Q *);
2887
STATIC int     AdvISR(ADV_DVC_VAR *);
2888
STATIC int     AdvInitGetConfig(ADV_DVC_VAR *);
2889
STATIC int     AdvInitAsc3550Driver(ADV_DVC_VAR *);
2890
STATIC int     AdvResetSB(ADV_DVC_VAR *);
2891
 
2892
/*
2893
 * Internal Adv Library functions.
2894
 */
2895
STATIC int    AdvSendIdleCmd(ADV_DVC_VAR *, ushort, ulong, int);
2896
STATIC void   AdvResetChip(ADV_DVC_VAR *);
2897
STATIC int    AdvSendScsiCmd(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
2898
STATIC void   AdvInquiryHandling(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
2899
STATIC int    AdvInitFromEEP(ADV_DVC_VAR *);
2900
STATIC ushort AdvGetEEPConfig(AdvPortAddr, ADVEEP_CONFIG *);
2901
STATIC void   AdvSetEEPConfig(AdvPortAddr, ADVEEP_CONFIG *);
2902
STATIC void   AdvWaitEEPCmd(AdvPortAddr);
2903
STATIC ushort AdvReadEEPWord(AdvPortAddr, int);
2904
STATIC void   AdvResetSCSIBus(ADV_DVC_VAR *);
2905
 
2906
/*
2907
 * PCI Bus Definitions
2908
 */
2909
#define AscPCICmdRegBits_BusMastering     0x0007
2910
#define AscPCICmdRegBits_ParErrRespCtrl   0x0040
2911
 
2912
#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0)
2913
 
2914
/* Read byte from a register. */
2915
#define AdvReadByteRegister(iop_base, reg_off) \
2916
     (inp((iop_base) + (reg_off)))
2917
 
2918
/* Write byte to a register. */
2919
#define AdvWriteByteRegister(iop_base, reg_off, byte) \
2920
     (outp((iop_base) + (reg_off), (byte)))
2921
 
2922
/* Read word (2 bytes) from a register. */
2923
#define AdvReadWordRegister(iop_base, reg_off) \
2924
     (inpw((iop_base) + (reg_off)))
2925
 
2926
/* Write word (2 bytes) to a register. */
2927
#define AdvWriteWordRegister(iop_base, reg_off, word) \
2928
     (outpw((iop_base) + (reg_off), (word)))
2929
 
2930
/* Read byte from LRAM. */
2931
#define AdvReadByteLram(iop_base, addr, byte) \
2932
do { \
2933
    outpw((iop_base) + IOPW_RAM_ADDR, (addr)); \
2934
    (byte) = inp((iop_base) + IOPB_RAM_DATA); \
2935
} while (0)
2936
 
2937
/* Write byte to LRAM. */
2938
#define AdvWriteByteLram(iop_base, addr, byte) \
2939
    (outpw((iop_base) + IOPW_RAM_ADDR, (addr)), \
2940
     outp((iop_base) + IOPB_RAM_DATA, (byte)))
2941
 
2942
/* Read word (2 bytes) from LRAM. */
2943
#define AdvReadWordLram(iop_base, addr, word) \
2944
do { \
2945
    outpw((iop_base) + IOPW_RAM_ADDR, (addr));  \
2946
    (word) = inpw((iop_base) + IOPW_RAM_DATA); \
2947
} while (0)
2948
 
2949
/* Write word (2 bytes) to LRAM. */
2950
#define AdvWriteWordLram(iop_base, addr, word) \
2951
    (outpw((iop_base) + IOPW_RAM_ADDR, (addr)), \
2952
     outpw((iop_base) + IOPW_RAM_DATA, (word)))
2953
 
2954
/* Write double word (4 bytes) to LRAM */
2955
/* Because of unspecified C language ordering don't use auto-increment. */
2956
#define AdvWriteDWordLram(iop_base, addr, dword) \
2957
    ((outpw((iop_base) + IOPW_RAM_ADDR, (addr)), \
2958
      outpw((iop_base) + IOPW_RAM_DATA, (ushort) ((dword) & 0xFFFF))), \
2959
     (outpw((iop_base) + IOPW_RAM_ADDR, (addr) + 2), \
2960
      outpw((iop_base) + IOPW_RAM_DATA, (ushort) ((dword >> 16) & 0xFFFF))))
2961
 
2962
/* Read word (2 bytes) from LRAM assuming that the address is already set. */
2963
#define AdvReadWordAutoIncLram(iop_base) \
2964
     (inpw((iop_base) + IOPW_RAM_DATA))
2965
 
2966
/* Write word (2 bytes) to LRAM assuming that the address is already set. */
2967
#define AdvWriteWordAutoIncLram(iop_base, word) \
2968
     (outpw((iop_base) + IOPW_RAM_DATA, (word)))
2969
 
2970
#else /* version >= v1,3,0 */
2971
 
2972
/* Read byte from a register. */
2973
#define AdvReadByteRegister(iop_base, reg_off) \
2974
     (ADV_MEM_READB((iop_base) + (reg_off)))
2975
 
2976
/* Write byte to a register. */
2977
#define AdvWriteByteRegister(iop_base, reg_off, byte) \
2978
     (ADV_MEM_WRITEB((iop_base) + (reg_off), (byte)))
2979
 
2980
/* Read word (2 bytes) from a register. */
2981
#define AdvReadWordRegister(iop_base, reg_off) \
2982
     (ADV_MEM_READW((iop_base) + (reg_off)))
2983
 
2984
/* Write word (2 bytes) to a register. */
2985
#define AdvWriteWordRegister(iop_base, reg_off, word) \
2986
     (ADV_MEM_WRITEW((iop_base) + (reg_off), (word)))
2987
 
2988
/* Read byte from LRAM. */
2989
#define AdvReadByteLram(iop_base, addr, byte) \
2990
do { \
2991
    ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
2992
    (byte) = ADV_MEM_READB((iop_base) + IOPB_RAM_DATA); \
2993
} while (0)
2994
 
2995
/* Write byte to LRAM. */
2996
#define AdvWriteByteLram(iop_base, addr, byte) \
2997
    (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
2998
     ADV_MEM_WRITEB((iop_base) + IOPB_RAM_DATA, (byte)))
2999
 
3000
/* Read word (2 bytes) from LRAM. */
3001
#define AdvReadWordLram(iop_base, addr, word) \
3002
do { \
3003
    ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
3004
    (word) = ADV_MEM_READW((iop_base) + IOPW_RAM_DATA); \
3005
} while (0)
3006
 
3007
/* Write word (2 bytes) to LRAM. */
3008
#define AdvWriteWordLram(iop_base, addr, word) \
3009
    (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3010
     ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
3011
 
3012
/* Write double word (4 bytes) to LRAM */
3013
/* Because of unspecified C language ordering don't use auto-increment. */
3014
#define AdvWriteDWordLram(iop_base, addr, dword) \
3015
    ((ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3016
      ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
3017
                     (ushort) ((dword) & 0xFFFF))), \
3018
     (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr) + 2), \
3019
      ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
3020
                     (ushort) ((dword >> 16) & 0xFFFF))))
3021
 
3022
/* Read word (2 bytes) from LRAM assuming that the address is already set. */
3023
#define AdvReadWordAutoIncLram(iop_base) \
3024
     (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA))
3025
 
3026
/* Write word (2 bytes) to LRAM assuming that the address is already set. */
3027
#define AdvWriteWordAutoIncLram(iop_base, word) \
3028
     (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
3029
 
3030
#endif /* version >= v1,3,0 */
3031
 
3032
/*
3033
 * Define macro to check for Condor signature.
3034
 *
3035
 * Evaluate to ADV_TRUE if a Condor chip is found the specified port
3036
 * address 'iop_base'. Otherwise evalue to ADV_FALSE.
3037
 */
3038
#define AdvFindSignature(iop_base) \
3039
    (((AdvReadByteRegister((iop_base), IOPB_CHIP_ID_1) == \
3040
    ADV_CHIP_ID_BYTE) && \
3041
     (AdvReadWordRegister((iop_base), IOPW_CHIP_ID_0) == \
3042
    ADV_CHIP_ID_WORD)) ?  ADV_TRUE : ADV_FALSE)
3043
 
3044
/*
3045
 * Define macro to Return the version number of the chip at 'iop_base'.
3046
 *
3047
 * The second parameter 'bus_type' is currently unused.
3048
 */
3049
#define AdvGetChipVersion(iop_base, bus_type) \
3050
    AdvReadByteRegister((iop_base), IOPB_CHIP_TYPE_REV)
3051
 
3052
/*
3053
 * Abort an SRB in the chip's RISC Memory. The 'srb_ptr' argument must
3054
 * match the ASC_SCSI_REQ_Q 'srb_ptr' field.
3055
 *
3056
 * If the request has not yet been sent to the device it will simply be
3057
 * aborted from RISC memory. If the request is disconnected it will be
3058
 * aborted on reselection by sending an Abort Message to the target ID.
3059
 *
3060
 * Return value:
3061
 *      ADV_TRUE(1) - Queue was successfully aborted.
3062
 *      ADV_FALSE(0) - Queue was not found on the active queue list.
3063
 */
3064
#define AdvAbortSRB(asc_dvc, srb_ptr) \
3065
    AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_ABORT, \
3066
                (ulong) (srb_ptr), 0)
3067
 
3068
/*
3069
 * Send a Bus Device Reset Message to the specified target ID.
3070
 *
3071
 * All outstanding commands will be purged if sending the
3072
 * Bus Device Reset Message is successful.
3073
 *
3074
 * Return Value:
3075
 *      ADV_TRUE(1) - All requests on the target are purged.
3076
 *      ADV_FALSE(0) - Couldn't issue Bus Device Reset Message; Requests
3077
 *                     are not purged.
3078
 */
3079
#define AdvResetDevice(asc_dvc, target_id) \
3080
        AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_DEVICE_RESET, \
3081
                    (ulong) (target_id), 0)
3082
 
3083
/*
3084
 * SCSI Wide Type definition.
3085
 */
3086
#define ADV_SCSI_BIT_ID_TYPE   ushort
3087
 
3088
/*
3089
 * AdvInitScsiTarget() 'cntl_flag' options.
3090
 */
3091
#define ADV_SCAN_LUN           0x01
3092
#define ADV_CAPINFO_NOLUN      0x02
3093
 
3094
/*
3095
 * Convert target id to target id bit mask.
3096
 */
3097
#define ADV_TID_TO_TIDMASK(tid)   (0x01 << ((tid) & ADV_MAX_TID))
3098
 
3099
/*
3100
 * ASC_SCSI_REQ_Q 'done_status' and 'host_status' return values.
3101
 */
3102
 
3103
#define QD_NO_STATUS         0x00       /* Request not completed yet. */
3104
#define QD_NO_ERROR          0x01
3105
#define QD_ABORTED_BY_HOST   0x02
3106
#define QD_WITH_ERROR        0x04
3107
 
3108
#define QHSTA_NO_ERROR              0x00
3109
#define QHSTA_M_SEL_TIMEOUT         0x11
3110
#define QHSTA_M_DATA_OVER_RUN       0x12
3111
#define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
3112
#define QHSTA_M_QUEUE_ABORTED       0x15
3113
#define QHSTA_M_SXFR_SDMA_ERR       0x16 /* SXFR_STATUS SCSI DMA Error */
3114
#define QHSTA_M_SXFR_SXFR_PERR      0x17 /* SXFR_STATUS SCSI Bus Parity Error */
3115
#define QHSTA_M_RDMA_PERR           0x18 /* RISC PCI DMA parity error */
3116
#define QHSTA_M_SXFR_OFF_UFLW       0x19 /* SXFR_STATUS Offset Underflow */
3117
#define QHSTA_M_SXFR_OFF_OFLW       0x20 /* SXFR_STATUS Offset Overflow */
3118
#define QHSTA_M_SXFR_WD_TMO         0x21 /* SXFR_STATUS Watchdog Timeout */
3119
#define QHSTA_M_SXFR_DESELECTED     0x22 /* SXFR_STATUS Deselected */
3120
/* Note: QHSTA_M_SXFR_XFR_OFLW is identical to QHSTA_M_DATA_OVER_RUN. */
3121
#define QHSTA_M_SXFR_XFR_OFLW       0x12 /* SXFR_STATUS Transfer Overflow */
3122
#define QHSTA_M_SXFR_XFR_PH_ERR     0x24 /* SXFR_STATUS Transfer Phase Error */
3123
#define QHSTA_M_SXFR_UNKNOWN_ERROR  0x25 /* SXFR_STATUS Unknown Error */
3124
#define QHSTA_M_WTM_TIMEOUT         0x41
3125
#define QHSTA_M_BAD_CMPL_STATUS_IN  0x42
3126
#define QHSTA_M_NO_AUTO_REQ_SENSE   0x43
3127
#define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
3128
#define QHSTA_M_INVALID_DEVICE      0x45 /* Bad target ID */
3129
 
3130
typedef int (* ADV_ISR_CALLBACK)
3131
    (ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
3132
 
3133
typedef int (* ADV_SBRESET_CALLBACK)
3134
    (ADV_DVC_VAR *);
3135
 
3136
/*
3137
 * Default EEPROM Configuration structure defined in a_init.c.
3138
 */
3139
extern ADVEEP_CONFIG Default_EEPROM_Config;
3140
 
3141
/*
3142
 * DvcGetPhyAddr() flag arguments
3143
 */
3144
#define ADV_IS_SCSIQ_FLAG       0x01 /* 'addr' is ASC_SCSI_REQ_Q pointer */
3145
#define ADV_ASCGETSGLIST_VADDR  0x02 /* 'addr' is AscGetSGList() virtual addr */
3146
#define ADV_IS_SENSE_FLAG       0x04 /* 'addr' is sense virtual pointer */
3147
#define ADV_IS_DATA_FLAG        0x08 /* 'addr' is data virtual pointer */
3148
#define ADV_IS_SGLIST_FLAG      0x10 /* 'addr' is sglist virtual pointer */
3149
 
3150
/* Return the address that is aligned at the next doubleword >= to 'addr'. */
3151
#define ADV_DWALIGN(addr)       (((ulong) (addr) + 0x3) & ~0x3)
3152
 
3153
/*
3154
 * Total contiguous memory needed for driver SG blocks.
3155
 *
3156
 * ADV_MAX_SG_LIST must be defined by a driver. It is the maximum
3157
 * number of scatter-gather elements the driver supports in a
3158
 * single request.
3159
 */
3160
 
3161
#ifndef ADV_MAX_SG_LIST
3162
Forced Error: Driver must define ADV_MAX_SG_LIST.
3163
#endif /* ADV_MAX_SG_LIST */
3164
 
3165
#define ADV_SG_LIST_MAX_BYTE_SIZE \
3166
         (sizeof(ADV_SG_BLOCK) * \
3167
          ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK))
3168
 
3169
/*
3170
 * A driver may optionally define the assertion macro ADV_ASSERT() in
3171
 * its d_os_dep.h file. If the macro has not already been defined,
3172
 * then define the macro to a no-op.
3173
 */
3174
#ifndef ADV_ASSERT
3175
#define ADV_ASSERT(a)
3176
#endif /* ADV_ASSERT */
3177
 
3178
 
3179
/*
3180
 * --- Driver Constants and Macros
3181
 */
3182
 
3183
#define ASC_NUM_BOARD_SUPPORTED 16
3184
#define ASC_NUM_IOPORT_PROBE    4
3185
#define ASC_NUM_BUS             4
3186
 
3187
/* Reference Scsi_Host hostdata */
3188
#define ASC_BOARDP(host) ((asc_board_t *) &((host)->hostdata))
3189
 
3190
/* asc_board_t flags */
3191
#define ASC_HOST_IN_RESET       0x01
3192
#define ASC_HOST_IN_ABORT       0x02
3193
#define ASC_IS_WIDE_BOARD       0x04    /* AdvanSys Wide Board */
3194
#define ASC_SELECT_QUEUE_DEPTHS 0x08
3195
 
3196
#define ASC_NARROW_BOARD(boardp) (((boardp)->flags & ASC_IS_WIDE_BOARD) == 0)
3197
#define ASC_WIDE_BOARD(boardp)   ((boardp)->flags & ASC_IS_WIDE_BOARD)
3198
 
3199
#define NO_ISA_DMA              0xff        /* No ISA DMA Channel Used */
3200
 
3201
/*
3202
 * If the Linux kernel version supports freeing initialization code
3203
 * and data after loading, define macros for this purpose. These macros
3204
 * are not used when the driver is built as a module, cf. linux/init.h.
3205
 */
3206
#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,23)
3207
#define ASC_INITFUNC(func)      func
3208
#define ASC_INITDATA
3209
#define ASC_INIT
3210
#else /* version >= v2.1.23 */
3211
#define ASC_INITFUNC(func)      __initfunc(func)
3212
#define ASC_INITDATA            __initdata
3213
#define ASC_INIT                __init
3214
#endif /* version >= v2.1.23 */
3215
 
3216
#define ASC_INFO_SIZE           128            /* advansys_info() line size */
3217
 
3218
/* /proc/scsi/advansys/[0...] related definitions */
3219
#define ASC_PRTBUF_SIZE         2048
3220
#define ASC_PRTLINE_SIZE        160
3221
 
3222
#define ASC_PRT_NEXT() \
3223
    if (cp) { \
3224
        totlen += len; \
3225
        leftlen -= len; \
3226
        if (leftlen == 0) { \
3227
            return totlen; \
3228
        } \
3229
        cp += len; \
3230
    }
3231
 
3232
#define ASC_MIN(a, b) (((a) < (b)) ? (a) : (b))
3233
 
3234
/* Asc Library return codes */
3235
#define ASC_TRUE        1
3236
#define ASC_FALSE       0
3237
#define ASC_NOERROR     1
3238
#define ASC_BUSY        0
3239
#define ASC_ERROR       (-1)
3240
 
3241
/* Scsi_Cmnd function return codes */
3242
#define STATUS_BYTE(byte)   (byte)
3243
#define MSG_BYTE(byte)      ((byte) << 8)
3244
#define HOST_BYTE(byte)     ((byte) << 16)
3245
#define DRIVER_BYTE(byte)   ((byte) << 24)
3246
 
3247
/*
3248
 * The following definitions and macros are OS independent interfaces to
3249
 * the queue functions:
3250
 *  REQ - SCSI request structure
3251
 *  REQP - pointer to SCSI request structure
3252
 *  REQPTID(reqp) - reqp's target id
3253
 *  REQPNEXT(reqp) - reqp's next pointer
3254
 *  REQPNEXTP(reqp) - pointer to reqp's next pointer
3255
 *  REQPTIME(reqp) - reqp's time stamp value
3256
 *  REQTIMESTAMP() - system time stamp value
3257
 */
3258
typedef Scsi_Cmnd            REQ, *REQP;
3259
#define REQPNEXT(reqp)       ((REQP) ((reqp)->host_scribble))
3260
#define REQPNEXTP(reqp)      ((REQP *) &((reqp)->host_scribble))
3261
#define REQPTID(reqp)        ((reqp)->target)
3262
#define REQPTIME(reqp)       ((reqp)->SCp.this_residual)
3263
#define REQTIMESTAMP()       (jiffies)
3264
 
3265
#define REQTIMESTAT(function, ascq, reqp, tid) \
3266
{ \
3267
    /*
3268
     * If the request time stamp is less than the system time stamp, then \
3269
     * maybe the system time stamp wrapped. Set the request time to zero.\
3270
     */ \
3271
    if (REQPTIME(reqp) <= REQTIMESTAMP()) { \
3272
        REQPTIME(reqp) = REQTIMESTAMP() - REQPTIME(reqp); \
3273
    } else { \
3274
        /* Indicate an error occurred with the assertion. */ \
3275
        ASC_ASSERT(REQPTIME(reqp) <= REQTIMESTAMP()); \
3276
        REQPTIME(reqp) = 0; \
3277
    } \
3278
    /* Handle first minimum time case without external initialization. */ \
3279
    if (((ascq)->q_tot_cnt[tid] == 1) ||  \
3280
        (REQPTIME(reqp) < (ascq)->q_min_tim[tid])) { \
3281
            (ascq)->q_min_tim[tid] = REQPTIME(reqp); \
3282
            ASC_DBG3(1, "%s: new q_min_tim[%d] %u\n", \
3283
                (function), (tid), (ascq)->q_min_tim[tid]); \
3284
        } \
3285
    if (REQPTIME(reqp) > (ascq)->q_max_tim[tid]) { \
3286
        (ascq)->q_max_tim[tid] = REQPTIME(reqp); \
3287
        ASC_DBG3(1, "%s: new q_max_tim[%d] %u\n", \
3288
            (function), tid, (ascq)->q_max_tim[tid]); \
3289
    } \
3290
    (ascq)->q_tot_tim[tid] += REQPTIME(reqp); \
3291
    /* Reset the time stamp field. */ \
3292
    REQPTIME(reqp) = 0; \
3293
}
3294
 
3295
/* asc_enqueue() flags */
3296
#define ASC_FRONT       1
3297
#define ASC_BACK        2
3298
 
3299
/* asc_dequeue_list() argument */
3300
#define ASC_TID_ALL        (-1)
3301
 
3302
/* Return non-zero, if the queue is empty. */
3303
#define ASC_QUEUE_EMPTY(ascq)    ((ascq)->q_tidmask == 0)
3304
 
3305
/* PCI configuration declarations */
3306
 
3307
#define PCI_BASE_CLASS_PREDEFINED               0x00
3308
#define PCI_BASE_CLASS_MASS_STORAGE             0x01
3309
#define PCI_BASE_CLASS_NETWORK                  0x02
3310
#define PCI_BASE_CLASS_DISPLAY                  0x03
3311
#define PCI_BASE_CLASS_MULTIMEDIA               0x04
3312
#define PCI_BASE_CLASS_MEMORY_CONTROLLER        0x05
3313
#define PCI_BASE_CLASS_BRIDGE_DEVICE            0x06
3314
 
3315
/* MASS STORAGE */
3316
#define PCI_SUB_CLASS_SCSI_CONTROLLER           0x00
3317
#define PCI_SUB_CLASS_IDE_CONTROLLER            0x01
3318
#define PCI_SUB_CLASS_FLOPPY_DISK_CONTROLLER    0x02
3319
#define PCI_SUB_CLASS_IPI_BUS_CONTROLLER        0x03
3320
#define PCI_SUB_CLASS_OTHER_MASS_CONTROLLER     0x80
3321
 
3322
/* NETWORK CONTROLLER */
3323
#define PCI_SUB_CLASS_ETHERNET_CONTROLLER       0x00
3324
#define PCI_SUB_CLASS_TOKEN_RING_CONTROLLER     0x01
3325
#define PCI_SUB_CLASS_FDDI_CONTROLLER           0x02
3326
#define PCI_SUB_CLASS_OTHER_NETWORK_CONTROLLER  0x80
3327
 
3328
/* DISPLAY CONTROLLER */
3329
#define PCI_SUB_CLASS_VGA_CONTROLLER            0x00
3330
#define PCI_SUB_CLASS_XGA_CONTROLLER            0x01
3331
#define PCI_SUB_CLASS_OTHER_DISPLAY_CONTROLLER  0x80
3332
 
3333
/* MULTIMEDIA CONTROLLER */
3334
#define PCI_SUB_CLASS_VIDEO_DEVICE              0x00
3335
#define PCI_SUB_CLASS_AUDIO_DEVICE              0x01
3336
#define PCI_SUB_CLASS_OTHER_MULTIMEDIA_DEVICE   0x80
3337
 
3338
/* MEMORY CONTROLLER */
3339
#define PCI_SUB_CLASS_RAM_CONTROLLER            0x00
3340
#define PCI_SUB_CLASS_FLASH_CONTROLLER          0x01
3341
#define PCI_SUB_CLASS_OTHER_MEMORY_CONTROLLER   0x80
3342
 
3343
/* BRIDGE CONTROLLER */
3344
#define PCI_SUB_CLASS_HOST_BRIDGE_CONTROLLER    0x00
3345
#define PCI_SUB_CLASS_ISA_BRIDGE_CONTROLLER     0x01
3346
#define PCI_SUB_CLASS_EISA_BRIDGE_CONTROLLER    0x02
3347
#define PCI_SUB_CLASS_MC_BRIDGE_CONTROLLER      0x03
3348
#define PCI_SUB_CLASS_PCI_TO_PCI_BRIDGE_CONTROLLER    0x04
3349
#define PCI_SUB_CLASS_PCMCIA_BRIDGE_CONTROLLER  0x05
3350
#define PCI_SUB_CLASS_OTHER_BRIDGE_CONTROLLER   0x80
3351
 
3352
#define PCI_MAX_SLOT            0x1F
3353
#define PCI_MAX_BUS             0xFF
3354
#define PCI_IOADDRESS_MASK      0xFFFE
3355
#define ASC_PCI_VENDORID        0x10CD
3356
#define ASC_PCI_DEVICE_ID_CNT   4       /* PCI Device ID count. */
3357
#define ASC_PCI_DEVICE_ID_1100  0x1100
3358
#define ASC_PCI_DEVICE_ID_1200  0x1200
3359
#define ASC_PCI_DEVICE_ID_1300  0x1300
3360
#define ASC_PCI_DEVICE_ID_2300  0x2300
3361
 
3362
/* PCI IO Port Addresses to generate special cycle */
3363
 
3364
#define PCI_CONFIG_ADDRESS_MECH1          0x0CF8
3365
#define PCI_CONFIG_DATA_MECH1             0x0CFC
3366
 
3367
#define PCI_CONFIG_FORWARD_REGISTER       0x0CFA    /* 0=type 0; 1=type 1; */
3368
 
3369
#define PCI_CONFIG_BUS_NUMBER_MASK        0x00FF0000
3370
#define PCI_CONFIG_DEVICE_FUNCTION_MASK   0x0000FF00
3371
#define PCI_CONFIG_REGISTER_NUMBER_MASK   0x000000F8
3372
 
3373
#define PCI_DEVICE_FOUND                0x0000
3374
#define PCI_DEVICE_NOT_FOUND            0xffff
3375
 
3376
#define SUBCLASS_OFFSET         0x0A
3377
#define CLASSCODE_OFFSET        0x0B
3378
#define VENDORID_OFFSET         0x00
3379
#define DEVICEID_OFFSET         0x02
3380
 
3381
#ifndef ADVANSYS_STATS
3382
#define ASC_STATS(shp, counter)
3383
#define ASC_STATS_ADD(shp, counter, count)
3384
#else /* ADVANSYS_STATS */
3385
#define ASC_STATS(shp, counter) \
3386
    (ASC_BOARDP(shp)->asc_stats.counter++)
3387
 
3388
#define ASC_STATS_ADD(shp, counter, count) \
3389
    (ASC_BOARDP(shp)->asc_stats.counter += (count))
3390
#endif /* ADVANSYS_STATS */
3391
 
3392
#define ASC_CEILING(val, unit) (((val) + ((unit) - 1))/(unit))
3393
 
3394
/* If the result wraps when calculating tenths, return 0. */
3395
#define ASC_TENTHS(num, den) \
3396
    (((10 * ((num)/(den))) > (((num) * 10)/(den))) ? \
3397
 
3398
 
3399
/*
3400
 * Display a message to the console.
3401
 */
3402
#define ASC_PRINT(s) \
3403
    { \
3404
        printk("advansys: "); \
3405
        printk(s); \
3406
    }
3407
 
3408
#define ASC_PRINT1(s, a1) \
3409
    { \
3410
        printk("advansys: "); \
3411
        printk((s), (a1)); \
3412
    }
3413
 
3414
#define ASC_PRINT2(s, a1, a2) \
3415
    { \
3416
        printk("advansys: "); \
3417
        printk((s), (a1), (a2)); \
3418
    }
3419
 
3420
#define ASC_PRINT3(s, a1, a2, a3) \
3421
    { \
3422
        printk("advansys: "); \
3423
        printk((s), (a1), (a2), (a3)); \
3424
    }
3425
 
3426
#define ASC_PRINT4(s, a1, a2, a3, a4) \
3427
    { \
3428
        printk("advansys: "); \
3429
        printk((s), (a1), (a2), (a3), (a4)); \
3430
    }
3431
 
3432
 
3433
#ifndef ADVANSYS_DEBUG
3434
 
3435
#define ASC_DBG(lvl, s)
3436
#define ASC_DBG1(lvl, s, a1)
3437
#define ASC_DBG2(lvl, s, a1, a2)
3438
#define ASC_DBG3(lvl, s, a1, a2, a3)
3439
#define ASC_DBG4(lvl, s, a1, a2, a3, a4)
3440
#define ASC_DBG_PRT_SCSI_HOST(lvl, s)
3441
#define ASC_DBG_PRT_SCSI_CMND(lvl, s)
3442
#define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp)
3443
#define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
3444
#define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone)
3445
#define ADV_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
3446
#define ASC_DBG_PRT_HEX(lvl, name, start, length)
3447
#define ASC_DBG_PRT_CDB(lvl, cdb, len)
3448
#define ASC_DBG_PRT_SENSE(lvl, sense, len)
3449
#define ASC_DBG_PRT_INQUIRY(lvl, inq, len)
3450
 
3451
#else /* ADVANSYS_DEBUG */
3452
 
3453
/*
3454
 * Debugging Message Levels:
3455
 * 0: Errors Only
3456
 * 1: High-Level Tracing
3457
 * 2-N: Verbose Tracing
3458
 */
3459
 
3460
#define ASC_DBG(lvl, s) \
3461
    { \
3462
        if (asc_dbglvl >= (lvl)) { \
3463
            printk(s); \
3464
        } \
3465
    }
3466
 
3467
#define ASC_DBG1(lvl, s, a1) \
3468
    { \
3469
        if (asc_dbglvl >= (lvl)) { \
3470
            printk((s), (a1)); \
3471
        } \
3472
    }
3473
 
3474
#define ASC_DBG2(lvl, s, a1, a2) \
3475
    { \
3476
        if (asc_dbglvl >= (lvl)) { \
3477
            printk((s), (a1), (a2)); \
3478
        } \
3479
    }
3480
 
3481
#define ASC_DBG3(lvl, s, a1, a2, a3) \
3482
    { \
3483
        if (asc_dbglvl >= (lvl)) { \
3484
            printk((s), (a1), (a2), (a3)); \
3485
        } \
3486
    }
3487
 
3488
#define ASC_DBG4(lvl, s, a1, a2, a3, a4) \
3489
    { \
3490
        if (asc_dbglvl >= (lvl)) { \
3491
            printk((s), (a1), (a2), (a3), (a4)); \
3492
        } \
3493
    }
3494
 
3495
#define ASC_DBG_PRT_SCSI_HOST(lvl, s) \
3496
    { \
3497
        if (asc_dbglvl >= (lvl)) { \
3498
            asc_prt_scsi_host(s); \
3499
        } \
3500
    }
3501
 
3502
#define ASC_DBG_PRT_SCSI_CMND(lvl, s) \
3503
    { \
3504
        if (asc_dbglvl >= (lvl)) { \
3505
            asc_prt_scsi_cmnd(s); \
3506
        } \
3507
    }
3508
 
3509
#define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp) \
3510
    { \
3511
        if (asc_dbglvl >= (lvl)) { \
3512
            asc_prt_asc_scsi_q(scsiqp); \
3513
        } \
3514
    }
3515
 
3516
#define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone) \
3517
    { \
3518
        if (asc_dbglvl >= (lvl)) { \
3519
            asc_prt_asc_qdone_info(qdone); \
3520
        } \
3521
    }
3522
 
3523
#define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp) \
3524
    { \
3525
        if (asc_dbglvl >= (lvl)) { \
3526
            asc_prt_adv_scsi_req_q(scsiqp); \
3527
        } \
3528
    }
3529
 
3530
#define ASC_DBG_PRT_HEX(lvl, name, start, length) \
3531
    { \
3532
        if (asc_dbglvl >= (lvl)) { \
3533
            asc_prt_hex((name), (start), (length)); \
3534
        } \
3535
    }
3536
 
3537
#define ASC_DBG_PRT_CDB(lvl, cdb, len) \
3538
        ASC_DBG_PRT_HEX((lvl), "CDB", (uchar *) (cdb), (len));
3539
 
3540
#define ASC_DBG_PRT_SENSE(lvl, sense, len) \
3541
        ASC_DBG_PRT_HEX((lvl), "SENSE", (uchar *) (sense), (len));
3542
 
3543
#define ASC_DBG_PRT_INQUIRY(lvl, inq, len) \
3544
        ASC_DBG_PRT_HEX((lvl), "INQUIRY", (uchar *) (inq), (len));
3545
#endif /* ADVANSYS_DEBUG */
3546
 
3547
#ifndef ADVANSYS_ASSERT
3548
#define ASC_ASSERT(a)
3549
#else /* ADVANSYS_ASSERT */
3550
 
3551
#define ASC_ASSERT(a) \
3552
    { \
3553
        if (!(a)) { \
3554
            printk("ASC_ASSERT() Failure: file %s, line %d\n", \
3555
                __FILE__, __LINE__); \
3556
        } \
3557
    }
3558
 
3559
#endif /* ADVANSYS_ASSERT */
3560
 
3561
 
3562
/*
3563
 * --- Driver Structures
3564
 */
3565
 
3566
#ifdef ADVANSYS_STATS
3567
 
3568
/* Per board statistics structure */
3569
struct asc_stats {
3570
    /* Driver Entrypoint Statistics */
3571
    ulong     command;         /* # calls to advansys_command() */
3572
    ulong     queuecommand;    /* # calls to advansys_queuecommand() */
3573
    ulong     abort;           /* # calls to advansys_abort() */
3574
    ulong     reset;           /* # calls to advansys_reset() */
3575
    ulong     biosparam;       /* # calls to advansys_biosparam() */
3576
    ulong     interrupt;       /* # advansys_interrupt() calls */
3577
    ulong     callback;        /* # calls to asc/adv_isr_callback() */
3578
    ulong     done;            /* # calls to request's scsi_done function */
3579
    ulong     build_error;     /* # asc/adv_build_req() ASC_ERROR returns. */
3580
    ulong     adv_build_noreq; /* # adv_build_req() adv_req_t alloc. fail. */
3581
    ulong     adv_build_nosg;  /* # adv_build_req() adv_sgblk_t alloc. fail. */
3582
    /* AscExeScsiQueue()/AdvExeScsiQueue() Statistics */
3583
    ulong     exe_noerror;     /* # ASC_NOERROR returns. */
3584
    ulong     exe_busy;        /* # ASC_BUSY returns. */
3585
    ulong     exe_error;       /* # ASC_ERROR returns. */
3586
    ulong     exe_unknown;     /* # unknown returns. */
3587
    /* Data Transfer Statistics */
3588
    ulong     cont_cnt;        /* # non-scatter-gather I/O requests received */
3589
    ulong     cont_xfer;       /* # contiguous transfer 512-bytes */
3590
    ulong     sg_cnt;          /* # scatter-gather I/O requests received */
3591
    ulong     sg_elem;         /* # scatter-gather elements */
3592
    ulong     sg_xfer;         /* # scatter-gather transfer 512-bytes */
3593
};
3594
#endif /* ADVANSYS_STATS */
3595
 
3596
/*
3597
 * Request queuing structure
3598
 */
3599
typedef struct asc_queue {
3600
    ADV_SCSI_BIT_ID_TYPE  q_tidmask;                /* queue mask */
3601
    REQP                  q_first[ADV_MAX_TID+1];   /* first queued request */
3602
    REQP                  q_last[ADV_MAX_TID+1];    /* last queued request */
3603
#ifdef ADVANSYS_STATS
3604
    short                 q_cur_cnt[ADV_MAX_TID+1]; /* current queue count */
3605
    short                 q_max_cnt[ADV_MAX_TID+1]; /* maximum queue count */
3606
    ulong                 q_tot_cnt[ADV_MAX_TID+1]; /* total enqueue count */
3607
    ulong                 q_tot_tim[ADV_MAX_TID+1]; /* total time queued */
3608
    ushort                q_max_tim[ADV_MAX_TID+1]; /* maximum time queued */
3609
    ushort                q_min_tim[ADV_MAX_TID+1]; /* minimum time queued */
3610
#endif /* ADVANSYS_STATS */
3611
} asc_queue_t;
3612
 
3613
/*
3614
 * Adv Library Request Structures
3615
 *
3616
 * The following two se structures are used to process Wide Board requests.
3617
 * One structure is needed for each command received from the Mid-Level SCSI
3618
 * driver.
3619
 *
3620
 * The ADV_SCSI_REQ_Q structure in adv_req_t is passed to the Adv Library
3621
 * and microcode with the ADV_SCSI_REQ_Q field 'srb_ptr' pointing to the
3622
 * adv_req_t. The adv_req_t structure 'cmndp' field in turn points to the
3623
 * Mid-Level SCSI request structure.
3624
 *
3625
 * The adv_sgblk_t structure is used to handle requests that include
3626
 * scatter-gather elements.
3627
 */
3628
typedef struct adv_sgblk {
3629
    ADV_SG_BLOCK        sg_block[ADV_NUM_SG_BLOCK + ADV_NUM_PAGE_CROSSING];
3630
    uchar               align2[4];       /* Sgblock structure padding. */
3631
    struct adv_sgblk    *next_sgblkp;    /* Next scatter-gather structure. */
3632
} adv_sgblk_t;
3633
 
3634
typedef struct adv_req {
3635
    ADV_SCSI_REQ_Q      scsi_req_q;   /* Adv Library request structure. */
3636
    uchar               align1[4];    /* Request structure padding. */
3637
    Scsi_Cmnd           *cmndp;       /* Mid-Level SCSI command pointer. */
3638
    adv_sgblk_t         *sgblkp;      /* Adv Library scatter-gather pointer. */
3639
    struct adv_req      *next_reqp;   /* Next Request Structure. */
3640
} adv_req_t;
3641
 
3642
/*
3643
 * Structure allocated for each board.
3644
 *
3645
 * This structure is allocated by scsi_register() at the end
3646
 * of the 'Scsi_Host' structure starting at the 'hostdata'
3647
 * field. It is guaranteed to be allocated from DMA-able memory.
3648
 */
3649
typedef struct asc_board {
3650
    int                  id;                    /* Board Id */
3651
    uint                 flags;                 /* Board flags */
3652
    union {
3653
        ASC_DVC_VAR      asc_dvc_var;           /* Narrow board */
3654
        ADV_DVC_VAR      adv_dvc_var;           /* Wide board */
3655
    } dvc_var;
3656
    union {
3657
        ASC_DVC_CFG      asc_dvc_cfg;           /* Narrow board */
3658
        ADV_DVC_CFG      adv_dvc_cfg;           /* Wide board */
3659
    } dvc_cfg;
3660
    asc_queue_t          active;                /* Active command queue */
3661
    asc_queue_t          waiting;               /* Waiting command queue */
3662
    asc_queue_t          done;                  /* Done command queue */
3663
    ADV_SCSI_BIT_ID_TYPE init_tidmask;          /* Target init./valid mask */
3664
    Scsi_Device          *device[ADV_MAX_TID+1]; /* Mid-Level Scsi Device */
3665
    ushort               reqcnt[ADV_MAX_TID+1]; /* Starvation request count */
3666
#if ASC_QUEUE_FLOW_CONTROL
3667
    ushort               nerrcnt[ADV_MAX_TID+1]; /* No error request count */
3668
#endif /* ASC_QUEUE_FLOW_CONTROL */
3669
    ADV_SCSI_BIT_ID_TYPE queue_full;            /* Queue full mask */
3670
    ushort               queue_full_cnt[ADV_MAX_TID+1]; /* Queue full count */
3671
    union {
3672
        ASCEEP_CONFIG    asc_eep;               /* Narrow EEPROM config. */
3673
        ADVEEP_CONFIG    adv_eep;               /* Wide EEPROM config. */
3674
    } eep_config;
3675
    ulong                last_reset;            /* Saved last reset time */
3676
#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
3677
    /* /proc/scsi/advansys/[0...] */
3678
    char                 *prtbuf;               /* Statistics Print Buffer */
3679
#endif /* version >= v1.3.0 */
3680
#ifdef ADVANSYS_STATS
3681
    struct asc_stats     asc_stats;             /* Board statistics */
3682
#endif /* ADVANSYS_STATS */
3683
    /*
3684
     * The following fields are used only for Narrow Boards.
3685
     */
3686
    /* The following three structures must be in DMA-able memory. */
3687
    ASC_SCSI_REQ_Q       scsireqq;
3688
    ASC_CAP_INFO         cap_info;
3689
    ASC_SCSI_INQUIRY     inquiry;
3690
    uchar                sdtr_data[ASC_MAX_TID+1]; /* SDTR information */
3691
    /*
3692
     * The following fields are used only for Wide Boards.
3693
     */
3694
    void                 *ioremap_addr;         /* I/O Memory remap address. */
3695
    ushort               ioport;                /* I/O Port address. */
3696
    adv_req_t            *orig_reqp;            /* adv_req_t memory block. */
3697
    adv_req_t            *adv_reqp;             /* Request structures. */
3698
    adv_sgblk_t          *orig_sgblkp;          /* adv_sgblk_t memory block. */
3699
    adv_sgblk_t          *adv_sgblkp;           /* Scatter-gather structures. */
3700
    ushort               bios_signature;        /* BIOS Signature. */
3701
    ushort               bios_version;          /* BIOS Version. */
3702
    ushort               bios_codeseg;          /* BIOS Code Segment. */
3703
    ushort               bios_codelen;          /* BIOS Code Segment Length. */
3704
} asc_board_t;
3705
 
3706
/*
3707
 * PCI configuration structures
3708
 */
3709
typedef struct _PCI_DATA_
3710
{
3711
    uchar    type;
3712
    uchar    bus;
3713
    uchar    slot;
3714
    uchar    func;
3715
    uchar    offset;
3716
} PCI_DATA;
3717
 
3718
typedef struct _PCI_DEVICE_
3719
{
3720
    ushort   vendorID;
3721
    ushort   deviceID;
3722
    ushort   slotNumber;
3723
    ushort   slotFound;
3724
    uchar    busNumber;
3725
    uchar    maxBusNumber;
3726
    uchar    devFunc;
3727
    ushort   startSlot;
3728
    ushort   endSlot;
3729
    uchar    bridge;
3730
    uchar    type;
3731
} PCI_DEVICE;
3732
 
3733
typedef struct _PCI_CONFIG_SPACE_
3734
{
3735
    ushort   vendorID;
3736
    ushort   deviceID;
3737
    ushort   command;
3738
    ushort   status;
3739
    uchar    revision;
3740
    uchar    classCode[3];
3741
    uchar    cacheSize;
3742
    uchar    latencyTimer;
3743
    uchar    headerType;
3744
    uchar    bist;
3745
    ulong    baseAddress[6];
3746
    ushort   reserved[4];
3747
    ulong    optionRomAddr;
3748
    ushort   reserved2[4];
3749
    uchar    irqLine;
3750
    uchar    irqPin;
3751
    uchar    minGnt;
3752
    uchar    maxLatency;
3753
} PCI_CONFIG_SPACE;
3754
 
3755
 
3756
/*
3757
 * --- Driver Data
3758
 */
3759
 
3760
/* Note: All driver global data should be initialized. */
3761
 
3762
#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
3763
struct proc_dir_entry proc_scsi_advansys =
3764
{
3765
    PROC_SCSI_ADVANSYS,              /* unsigned short low_ino */
3766
    8,                               /* unsigned short namelen */
3767
    "advansys",                      /* const char *name */
3768
    S_IFDIR | S_IRUGO | S_IXUGO,     /* mode_t mode */
3769
    2                                /* nlink_t nlink */
3770
};
3771
#endif /* version >= v1.3.0 */
3772
 
3773
/* Number of boards detected in system. */
3774
STATIC int asc_board_count = 0;
3775
STATIC struct Scsi_Host    *asc_host[ASC_NUM_BOARD_SUPPORTED] = { 0 };
3776
 
3777
/* Overrun buffer shared between all boards. */
3778
STATIC uchar overrun_buf[ASC_OVERRUN_BSIZE] = { 0 };
3779
 
3780
/*
3781
 * Global structures required to issue a command.
3782
 */
3783
STATIC ASC_SCSI_Q asc_scsi_q = { { 0 } };
3784
STATIC ASC_SG_HEAD asc_sg_head = { 0 };
3785
 
3786
/* List of supported bus types. */
3787
STATIC ushort asc_bus[ASC_NUM_BUS] ASC_INITDATA = {
3788
    ASC_IS_ISA,
3789
    ASC_IS_VL,
3790
    ASC_IS_EISA,
3791
    ASC_IS_PCI,
3792
};
3793
 
3794
#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
3795
#ifdef ASC_CONFIG_PCI
3796
STATIC int pci_scan_method ASC_INITDATA = -1;
3797
#endif /* ASC_CONFIG_PCI */
3798
#endif /* version < v2.1.93 */
3799
 
3800
/*
3801
 * Used with the LILO 'advansys' option to eliminate or
3802
 * limit I/O port probing at boot time, cf. advansys_setup().
3803
 */
3804
STATIC int asc_iopflag = ASC_FALSE;
3805
STATIC int asc_ioport[ASC_NUM_IOPORT_PROBE] = { 0, 0, 0, 0 };
3806
 
3807
#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0)
3808
/*
3809
 * In kernels earlier than v1.3.0, kmalloc() does not work
3810
 * during driver initialization. Therefore statically declare
3811
 * 16 elements of each structure. v1.3.0 kernels will probably
3812
 * not need any more than this number.
3813
 */
3814
uchar adv_req_buf[16 * sizeof(adv_req_t)] = { 0 };
3815
uchar adv_sgblk_buf[16 * sizeof(adv_sgblk_t)] = { 0 };
3816
#endif /* version >= v1,3,0 */
3817
 
3818
#ifdef ADVANSYS_DEBUG
3819
STATIC char *
3820
asc_bus_name[ASC_NUM_BUS] = {
3821
    "ASC_IS_ISA",
3822
    "ASC_IS_VL",
3823
    "ASC_IS_EISA",
3824
    "ASC_IS_PCI",
3825
};
3826
 
3827
STATIC int          asc_dbglvl = 0;
3828
#endif /* ADVANSYS_DEBUG */
3829
 
3830
/* Declaration for Asc Library internal data referenced by driver. */
3831
STATIC PortAddr     _asc_def_iop_base[];
3832
 
3833
 
3834
/*
3835
 * --- Driver Function Prototypes
3836
 *
3837
 * advansys.h contains function prototypes for functions global to Linux.
3838
 */
3839
 
3840
#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
3841
STATIC int          asc_proc_copy(off_t, off_t, char *, int , char *, int);
3842
#endif /* version >= v1.3.0 */
3843
#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,70)
3844
STATIC void         advansys_interrupt(int, struct pt_regs *);
3845
#else /* version >= v1.3.70 */
3846
STATIC void         advansys_interrupt(int, void *, struct pt_regs *);
3847
#endif /* version >= v1.3.70 */
3848
#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
3849
STATIC void         advansys_select_queue_depths(struct Scsi_Host *,
3850
                                                Scsi_Device *);
3851
#endif /* version >= v1.3.89 */
3852
STATIC void       advansys_command_done(Scsi_Cmnd *);
3853
STATIC void       asc_scsi_done_list(Scsi_Cmnd *);
3854
STATIC int        asc_execute_scsi_cmnd(Scsi_Cmnd *);
3855
STATIC int        asc_build_req(asc_board_t *, Scsi_Cmnd *);
3856
STATIC int        adv_build_req(asc_board_t *, Scsi_Cmnd *, ADV_SCSI_REQ_Q **);
3857
STATIC int        adv_get_sglist(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *, Scsi_Cmnd *);
3858
STATIC void       asc_isr_callback(ASC_DVC_VAR *, ASC_QDONE_INFO *);
3859
STATIC void       adv_isr_callback(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
3860
#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
3861
#ifdef ASC_CONFIG_PCI
3862
STATIC int        asc_srch_pci_dev(PCI_DEVICE *);
3863
STATIC uchar      asc_scan_method(void);
3864
STATIC int        asc_pci_find_dev(PCI_DEVICE *);
3865
STATIC void       asc_get_pci_cfg(PCI_DEVICE *, PCI_CONFIG_SPACE *);
3866
STATIC ushort     asc_get_cfg_word(PCI_DATA *);
3867
STATIC uchar      asc_get_cfg_byte(PCI_DATA *);
3868
STATIC void       asc_put_cfg_byte(PCI_DATA *, uchar);
3869
#endif /* ASC_CONFIG_PCI */
3870
#endif /* version < v2.1.93 */
3871
STATIC void       asc_enqueue(asc_queue_t *, REQP, int);
3872
STATIC REQP       asc_dequeue(asc_queue_t *, int);
3873
STATIC REQP       asc_dequeue_list(asc_queue_t *, REQP *, int);
3874
STATIC int        asc_rmqueue(asc_queue_t *, REQP);
3875
STATIC int        asc_isqueued(asc_queue_t *, REQP);
3876
STATIC void       asc_execute_queue(asc_queue_t *);
3877
#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
3878
STATIC int        asc_prt_board_devices(struct Scsi_Host *, char *, int);
3879
STATIC int        asc_prt_adv_bios(struct Scsi_Host *, char *, int);
3880
STATIC int        asc_get_eeprom_string(ushort *serialnum, uchar *cp);
3881
STATIC int        asc_prt_asc_board_eeprom(struct Scsi_Host *, char *, int);
3882
STATIC int        asc_prt_adv_board_eeprom(struct Scsi_Host *, char *, int);
3883
STATIC int        asc_prt_driver_conf(struct Scsi_Host *, char *, int);
3884
STATIC int        asc_prt_asc_board_info(struct Scsi_Host *, char *, int);
3885
STATIC int        asc_prt_adv_board_info(struct Scsi_Host *, char *, int);
3886
STATIC int        asc_prt_line(char *, int, char *fmt, ...);
3887
#endif /* version >= v1.3.0 */
3888
 
3889
/* Declaration for Asc Library internal functions reference by driver. */
3890
STATIC int          AscFindSignature(PortAddr);
3891
STATIC ushort       AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
3892
 
3893
#ifdef ADVANSYS_STATS
3894
STATIC int          asc_prt_board_stats(struct Scsi_Host *, char *, int);
3895
#endif /* ADVANSYS_STATS */
3896
 
3897
#ifdef ADVANSYS_DEBUG
3898
STATIC void         asc_prt_scsi_host(struct Scsi_Host *);
3899
STATIC void         asc_prt_scsi_cmnd(Scsi_Cmnd *);
3900
STATIC void         asc_prt_asc_dvc_cfg(ASC_DVC_CFG *);
3901
STATIC void         asc_prt_asc_dvc_var(ASC_DVC_VAR *);
3902
STATIC void         asc_prt_asc_scsi_q(ASC_SCSI_Q *);
3903
STATIC void         asc_prt_asc_qdone_info(ASC_QDONE_INFO *);
3904
STATIC void         asc_prt_adv_dvc_cfg(ADV_DVC_CFG *);
3905
STATIC void         asc_prt_adv_dvc_var(ADV_DVC_VAR *);
3906
STATIC void         asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *);
3907
STATIC void         asc_prt_adv_sgblock(int, ADV_SG_BLOCK *);
3908
STATIC void         asc_prt_hex(char *f, uchar *, int);
3909
#endif /* ADVANSYS_DEBUG */
3910
 
3911
#ifdef ADVANSYS_ASSERT
3912
STATIC int             interrupts_enabled(void);
3913
#endif /* ADVANSYS_ASSERT */
3914
 
3915
 
3916
/*
3917
 * --- Linux 'Scsi_Host_Template' and advansys_setup() Functions
3918
 */
3919
 
3920
#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
3921
/*
3922
 * advansys_proc_info() - /proc/scsi/advansys/[0-(ASC_NUM_BOARD_SUPPORTED-1)]
3923
 *
3924
 * *buffer: I/O buffer
3925
 * **start: if inout == FALSE pointer into buffer where user read should start
3926
 * offset: current offset into a /proc/scsi/advansys/[0...] file
3927
 * length: length of buffer
3928
 * hostno: Scsi_Host host_no
3929
 * inout: TRUE - user is writing; FALSE - user is reading
3930
 *
3931
 * Return the number of bytes read from or written to a
3932
 * /proc/scsi/advansys/[0...] file.
3933
 *
3934
 * Note: This function uses the per board buffer 'prtbuf' which is
3935
 * allocated when the board is initialized in advansys_detect(). The
3936
 * buffer is ASC_PRTBUF_SIZE bytes. The function asc_proc_copy() is
3937
 * used to write to the buffer. The way asc_proc_copy() is written
3938
 * if 'prtbuf' is too small it will not be overwritten. Instead the
3939
 * user just won't get all the available statistics.
3940
 */
3941
int
3942
advansys_proc_info(char *buffer, char **start, off_t offset, int length,
3943
                   int hostno, int inout)
3944
{
3945
    struct Scsi_Host    *shp;
3946
    asc_board_t         *boardp;
3947
    int                 i;
3948
    char                *cp;
3949
    int                 cplen;
3950
    int                 cnt;
3951
    int                 totcnt;
3952
    int                 leftlen;
3953
    char                *curbuf;
3954
    off_t               advoffset;
3955
    Scsi_Device         *scd;
3956
 
3957
    ASC_DBG(1, "advansys_proc_info: begin\n");
3958
 
3959
    /*
3960
     * User write not supported.
3961
     */
3962
    if (inout == TRUE) {
3963
        return(-ENOSYS);
3964
    }
3965
 
3966
    /*
3967
     * User read of /proc/scsi/advansys/[0...] file.
3968
     */
3969
 
3970
    /* Find the specified board. */
3971
    for (i = 0; i < asc_board_count; i++) {
3972
        if (asc_host[i]->host_no == hostno) {
3973
            break;
3974
        }
3975
    }
3976
    if (i == asc_board_count) {
3977
        return(-ENOENT);
3978
    }
3979
 
3980
    shp = asc_host[i];
3981
    boardp = ASC_BOARDP(shp);
3982
 
3983
    /* Copy read data starting at the beginning of the buffer. */
3984
    *start = buffer;
3985
    curbuf = buffer;
3986
    advoffset = 0;
3987
    totcnt = 0;
3988
    leftlen = length;
3989
 
3990
    /*
3991
     * Get board configuration information.
3992
     *
3993
     * advansys_info() returns the board string from its own static buffer.
3994
     */
3995
    cp = (char *) advansys_info(shp);
3996
    strcat(cp, "\n");
3997
    cplen = strlen(cp);
3998
    /* Copy board information. */
3999
    cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4000
    totcnt += cnt;
4001
    leftlen -= cnt;
4002
    if (leftlen == 0) {
4003
        ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4004
        return totcnt;
4005
    }
4006
    advoffset += cplen;
4007
    curbuf += cnt;
4008
 
4009
    /*
4010
     * Display Wide Board BIOS Information.
4011
     */
4012
    if (ASC_WIDE_BOARD(boardp)) {
4013
        cp = boardp->prtbuf;
4014
        cplen = asc_prt_adv_bios(shp, cp, ASC_PRTBUF_SIZE);
4015
        ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4016
        cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4017
        totcnt += cnt;
4018
        leftlen -= cnt;
4019
        if (leftlen == 0) {
4020
            ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4021
            return totcnt;
4022
        }
4023
        advoffset += cplen;
4024
        curbuf += cnt;
4025
    }
4026
 
4027
    /*
4028
     * Display driver information for each device attached to the board.
4029
     */
4030
    cp = boardp->prtbuf;
4031
    cplen = asc_prt_board_devices(shp, cp, ASC_PRTBUF_SIZE);
4032
    ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4033
    cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4034
    totcnt += cnt;
4035
    leftlen -= cnt;
4036
    if (leftlen == 0) {
4037
        ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4038
        return totcnt;
4039
    }
4040
    advoffset += cplen;
4041
    curbuf += cnt;
4042
 
4043
    /*
4044
     * Display target driver information for each device attached
4045
     * to the board.
4046
     */
4047
#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,75)
4048
    for (scd = scsi_devices; scd; scd = scd->next)
4049
#else /* version >= v2.1.75 */
4050
    for (scd = shp->host_queue; scd; scd = scd->next)
4051
#endif /* version >= v2.1.75 */
4052
    {
4053
        if (scd->host == shp) {
4054
            cp = boardp->prtbuf;
4055
            /*
4056
             * Note: If proc_print_scsidevice() writes more than
4057
             * ASC_PRTBUF_SIZE bytes, it will overrun 'prtbuf'.
4058
             */
4059
            proc_print_scsidevice(scd, cp, &cplen, 0);
4060
            ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4061
            cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4062
            totcnt += cnt;
4063
            leftlen -= cnt;
4064
            if (leftlen == 0) {
4065
                ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4066
                return totcnt;
4067
            }
4068
            advoffset += cplen;
4069
            curbuf += cnt;
4070
        }
4071
    }
4072
 
4073
    /*
4074
     * Display EEPROM configuration for the board.
4075
     */
4076
    cp = boardp->prtbuf;
4077
    if (ASC_NARROW_BOARD(boardp)) {
4078
        cplen = asc_prt_asc_board_eeprom(shp, cp, ASC_PRTBUF_SIZE);
4079
    } else {
4080
        cplen = asc_prt_adv_board_eeprom(shp, cp, ASC_PRTBUF_SIZE);
4081
    }
4082
    ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4083
    cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4084
    totcnt += cnt;
4085
    leftlen -= cnt;
4086
    if (leftlen == 0) {
4087
        ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4088
        return totcnt;
4089
    }
4090
    advoffset += cplen;
4091
    curbuf += cnt;
4092
 
4093
    /*
4094
     * Display driver configuration and information for the board.
4095
     */
4096
    cp = boardp->prtbuf;
4097
    cplen = asc_prt_driver_conf(shp, cp, ASC_PRTBUF_SIZE);
4098
    ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4099
    cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4100
    totcnt += cnt;
4101
    leftlen -= cnt;
4102
    if (leftlen == 0) {
4103
        ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4104
        return totcnt;
4105
    }
4106
    advoffset += cplen;
4107
    curbuf += cnt;
4108
 
4109
#ifdef ADVANSYS_STATS
4110
    /*
4111
     * Display driver statistics for the board.
4112
     */
4113
    cp = boardp->prtbuf;
4114
    cplen = asc_prt_board_stats(shp, cp, ASC_PRTBUF_SIZE);
4115
    ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4116
    cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4117
    totcnt += cnt;
4118
    leftlen -= cnt;
4119
    if (leftlen == 0) {
4120
        ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4121
        return totcnt;
4122
    }
4123
    advoffset += cplen;
4124
    curbuf += cnt;
4125
#endif /* ADVANSYS_STATS */
4126
 
4127
    /*
4128
     * Display Asc Library dynamic configuration information
4129
     * for the board.
4130
     */
4131
    cp = boardp->prtbuf;
4132
    if (ASC_NARROW_BOARD(boardp)) {
4133
        cplen = asc_prt_asc_board_info(shp, cp, ASC_PRTBUF_SIZE);
4134
    } else {
4135
        cplen = asc_prt_adv_board_info(shp, cp, ASC_PRTBUF_SIZE);
4136
    }
4137
    ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4138
    cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4139
    totcnt += cnt;
4140
    leftlen -= cnt;
4141
    if (leftlen == 0) {
4142
        ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4143
        return totcnt;
4144
    }
4145
    advoffset += cplen;
4146
    curbuf += cnt;
4147
 
4148
    ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4149
 
4150
    return totcnt;
4151
}
4152
#endif /* version >= v1.3.0 */
4153
 
4154
/*
4155
 * advansys_detect()
4156
 *
4157
 * Detect function for AdvanSys adapters.
4158
 *
4159
 * Argument is a pointer to the host driver's scsi_hosts entry.
4160
 *
4161
 * Return number of adapters found.
4162
 *
4163
 * Note: Because this function is called during system initialization
4164
 * it must not call SCSI mid-level functions including scsi_malloc()
4165
 * and scsi_free().
4166
 */
4167
ASC_INITFUNC(
4168
int
4169
advansys_detect(Scsi_Host_Template *tpnt)
4170
)
4171
{
4172
    static int          detect_called = ASC_FALSE;
4173
    int                 iop;
4174
    int                 bus;
4175
    struct Scsi_Host    *shp;
4176
    asc_board_t         *boardp;
4177
    ASC_DVC_VAR         *asc_dvc_varp = NULL;
4178
    ADV_DVC_VAR         *adv_dvc_varp = NULL;
4179
    int                 ioport = 0;
4180
    int                 share_irq = FALSE;
4181
#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
4182
#ifdef ASC_CONFIG_PCI
4183
    PCI_DEVICE          pciDevice;
4184
    PCI_CONFIG_SPACE    pciConfig;
4185
#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
4186
    unsigned long       pci_memory_address;
4187
#endif /* version >= v1,3,0 */
4188
#endif /* ASC_CONFIG_PCI */
4189
#else /* version >= v2.1.93 */ 
4190
#ifdef CONFIG_PCI
4191
    struct pci_dev      *pci_devp = NULL;
4192
    int                 pci_device_id_cnt = 0;
4193
    unsigned int        pci_device_id[ASC_PCI_DEVICE_ID_CNT] = {
4194
                                    ASC_PCI_DEVICE_ID_1100,
4195
                                    ASC_PCI_DEVICE_ID_1200,
4196
                                    ASC_PCI_DEVICE_ID_1300,
4197
                                    ASC_PCI_DEVICE_ID_2300
4198
                        };
4199
    unsigned long       pci_memory_address;
4200
#endif /* CONFIG_PCI */
4201
#endif /* version >= v2.1.93 */ 
4202
    int                 warn_code, err_code;
4203
    int                 ret;
4204
 
4205
    if (detect_called == ASC_FALSE) {
4206
        detect_called = ASC_TRUE;
4207
    } else {
4208
        printk("AdvanSys SCSI: advansys_detect() multiple calls ignored\n");
4209
        return 0;
4210
    }
4211
 
4212
    ASC_DBG(1, "advansys_detect: begin\n");
4213
 
4214
#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
4215
    tpnt->proc_dir = &proc_scsi_advansys;
4216
#endif /* version >= v1.3.0 */
4217
 
4218
    asc_board_count = 0;
4219
 
4220
    /*
4221
     * If I/O port probing has been modified, then verify and
4222
     * clean-up the 'asc_ioport' list.
4223
     */
4224
    if (asc_iopflag == ASC_TRUE) {
4225
        for (ioport = 0; ioport < ASC_NUM_IOPORT_PROBE; ioport++) {
4226
            ASC_DBG2(1, "advansys_detect: asc_ioport[%d] %x\n",
4227
                ioport, asc_ioport[ioport]);
4228
            if (asc_ioport[ioport] != 0) {
4229
                for (iop = 0; iop < ASC_IOADR_TABLE_MAX_IX; iop++) {
4230
                    if (_asc_def_iop_base[iop] == asc_ioport[ioport]) {
4231
                        break;
4232
                    }
4233
                }
4234
                if (iop == ASC_IOADR_TABLE_MAX_IX) {
4235
                    printk(
4236
"AdvanSys SCSI: specified I/O Port 0x%X is invalid\n",
4237
                        asc_ioport[ioport]);
4238
                    asc_ioport[ioport] = 0;
4239
                }
4240
            }
4241
        }
4242
        ioport = 0;
4243
    }
4244
 
4245
#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
4246
#ifdef ASC_CONFIG_PCI
4247
    memset(&pciDevice, 0, sizeof(PCI_DEVICE));
4248
    memset(&pciConfig, 0, sizeof(PCI_CONFIG_SPACE));
4249
    pciDevice.maxBusNumber = PCI_MAX_BUS;
4250
    pciDevice.endSlot = PCI_MAX_SLOT;
4251
#endif /* ASC_CONFIG_PCI */
4252
#endif /* version < v2.1.93 */ 
4253
 
4254
    for (bus = 0; bus < ASC_NUM_BUS; bus++) {
4255
 
4256
        ASC_DBG2(1, "advansys_detect: bus search type %d (%s)\n",
4257
            bus, asc_bus_name[bus]);
4258
        iop = 0;
4259
 
4260
        while (asc_board_count < ASC_NUM_BOARD_SUPPORTED) {
4261
 
4262
            ASC_DBG1(2, "advansys_detect: asc_board_count %d\n",
4263
                asc_board_count);
4264
 
4265
            switch (asc_bus[bus]) {
4266
            case ASC_IS_ISA:
4267
            case ASC_IS_VL:
4268
                if (asc_iopflag == ASC_FALSE) {
4269
                    iop = AscSearchIOPortAddr(iop, asc_bus[bus]);
4270
                } else {
4271
                    /*
4272
                     * ISA and VL I/O port scanning has either been
4273
                     * eliminated or limited to selected ports on
4274
                     * the LILO command line, /etc/lilo.conf, or
4275
                     * by setting variables when the module was loaded.
4276
                     */
4277
                    ASC_DBG(1, "advansys_detect: I/O port scanning modified\n");
4278
                ioport_try_again:
4279
                    iop = 0;
4280
                    for (; ioport < ASC_NUM_IOPORT_PROBE; ioport++) {
4281
                        if ((iop = asc_ioport[ioport]) != 0) {
4282
                            break;
4283
                        }
4284
                    }
4285
                    if (iop) {
4286
                        ASC_DBG1(1, "advansys_detect: probing I/O port %x...\n",
4287
                            iop);
4288
                        if (check_region(iop, ASC_IOADR_GAP) != 0) {
4289
                            printk(
4290
"AdvanSys SCSI: specified I/O Port 0x%X is busy\n", iop);
4291
                            /* Don't try this I/O port twice. */
4292
                            asc_ioport[ioport] = 0;
4293
                            goto ioport_try_again;
4294
                        } else if (AscFindSignature(iop) == ASC_FALSE) {
4295
                            printk(
4296
"AdvanSys SCSI: specified I/O Port 0x%X has no adapter\n", iop);
4297
                            /* Don't try this I/O port twice. */
4298
                            asc_ioport[ioport] = 0;
4299
                            goto ioport_try_again;
4300
                        } else {
4301
                            /*
4302
                             * If this isn't an ISA board, then it must be
4303
                             * a VL board. If currently looking an ISA
4304
                             * board is being looked for then try for
4305
                             * another ISA board in 'asc_ioport'.
4306
                             */
4307
                            if (asc_bus[bus] == ASC_IS_ISA &&
4308
                                (AscGetChipVersion(iop, ASC_IS_ISA) &
4309
                                 ASC_CHIP_VER_ISA_BIT) == 0) {
4310
                                 /*
4311
                                 * Don't clear 'asc_ioport[ioport]'. Try
4312
                                 * this board again for VL. Increment
4313
                                 * 'ioport' past this board.
4314
                                 */
4315
                                 ioport++;
4316
                                 goto ioport_try_again;
4317
                            }
4318
                        }
4319
                        /*
4320
                         * This board appears good, don't try the I/O port
4321
                         * again by clearing its value. Increment 'ioport'
4322
                         * for the next iteration.
4323
                         */
4324
                        asc_ioport[ioport++] = 0;
4325
                    }
4326
                }
4327
                break;
4328
 
4329
            case ASC_IS_EISA:
4330
                iop = AscSearchIOPortAddr(iop, asc_bus[bus]);
4331
                break;
4332
 
4333
#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
4334
#ifdef ASC_CONFIG_PCI
4335
            case ASC_IS_PCI:
4336
                if (asc_srch_pci_dev(&pciDevice) != PCI_DEVICE_FOUND) {
4337
                    iop = 0;
4338
                } else {
4339
                    ASC_DBG2(2,
4340
                        "advansys_detect: slotFound %d, busNumber %d\n",
4341
                        pciDevice.slotFound, pciDevice.busNumber);
4342
                    asc_get_pci_cfg(&pciDevice, &pciConfig);
4343
                    iop = pciConfig.baseAddress[0] & PCI_IOADDRESS_MASK;
4344
                    ASC_DBG2(1,
4345
                        "advansys_detect: vendorID %X, deviceID %X\n",
4346
                        pciConfig.vendorID, pciConfig.deviceID);
4347
                    ASC_DBG2(2, "advansys_detect: iop %X, irqLine %d\n",
4348
                        iop, pciConfig.irqLine);
4349
                }
4350
                break;
4351
#endif /* ASC_CONFIG_PCI */
4352
#else /* version >= v2.1.93 */ 
4353
#ifdef CONFIG_PCI
4354
            case ASC_IS_PCI:
4355
                while (pci_device_id_cnt < ASC_PCI_DEVICE_ID_CNT) {
4356
                    if ((pci_devp = pci_find_device(ASC_PCI_VENDORID,
4357
                         pci_device_id[pci_device_id_cnt], pci_devp)) == NULL) {
4358
                        pci_device_id_cnt++;
4359
                    } else {
4360
                        break;
4361
                    }
4362
                }
4363
                if (pci_devp == NULL) {
4364
                    iop = 0;
4365
                } else {
4366
                    ASC_DBG2(2,
4367
                        "advansys_detect: devfn %d, bus number %d\n",
4368
                        pci_devp->devfn, pci_devp->bus->number);
4369
                    iop = pci_devp->base_address[0] & PCI_IOADDRESS_MASK;
4370
                    ASC_DBG2(1,
4371
                        "advansys_detect: vendorID %X, deviceID %X\n",
4372
                        pci_devp->vendor, pci_devp->device);
4373
                    ASC_DBG2(2, "advansys_detect: iop %X, irqLine %d\n",
4374
                        iop, pci_devp->irq);
4375
                }
4376
                break;
4377
#endif /* CONFIG_PCI */
4378
#endif /* version >= v2.1.93 */ 
4379
 
4380
            default:
4381
                ASC_PRINT1("advansys_detect: unknown bus type: %d\n",
4382
                    asc_bus[bus]);
4383
                break;
4384
            }
4385
            ASC_DBG1(1, "advansys_detect: iop %x\n", iop);
4386
 
4387
            /*
4388
             * Adapter not found, try next bus type.
4389
             */
4390
            if (iop == 0) {
4391
                break;
4392
            }
4393
 
4394
            /*
4395
             * Adapter found.
4396
             *
4397
             * Register the adapter, get its configuration, and
4398
             * initialize it.
4399
             */
4400
            ASC_DBG(2, "advansys_detect: scsi_register()\n");
4401
            shp = scsi_register(tpnt, sizeof(asc_board_t));
4402
 
4403
            /* Save a pointer to the Scsi_host of each board found. */
4404
            asc_host[asc_board_count++] = shp;
4405
 
4406
            /* Initialize private per board data */
4407
            boardp = ASC_BOARDP(shp);
4408
            memset(boardp, 0, sizeof(asc_board_t));
4409
            boardp->id = asc_board_count - 1;
4410
 
4411
            /*
4412
             * Handle both narrow and wide boards.
4413
             *
4414
             * If a Wide board was detected, set the board structure
4415
             * wide board flag. Set-up the board structure based on
4416
             * the board type.
4417
             */
4418
#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
4419
#ifdef ASC_CONFIG_PCI
4420
            if (asc_bus[bus] == ASC_IS_PCI &&
4421
                 pciConfig.deviceID == ASC_PCI_DEVICE_ID_2300) {
4422
                boardp->flags |= ASC_IS_WIDE_BOARD;
4423
            }
4424
#endif /* ASC_CONFIG_PCI */
4425
#else /* version >= v2.1.93 */ 
4426
#ifdef CONFIG_PCI
4427
            if (asc_bus[bus] == ASC_IS_PCI &&
4428
                 pci_devp->device == ASC_PCI_DEVICE_ID_2300) {
4429
                boardp->flags |= ASC_IS_WIDE_BOARD;
4430
            }
4431
#endif /* CONFIG_PCI */
4432
#endif /* version >= v2.1.93 */ 
4433
 
4434
            if (ASC_NARROW_BOARD(boardp)) {
4435
                ASC_DBG(1, "advansys_detect: narrow board\n");
4436
                asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
4437
                asc_dvc_varp->bus_type = asc_bus[bus];
4438
                asc_dvc_varp->drv_ptr = (ulong) boardp;
4439
                asc_dvc_varp->cfg = &boardp->dvc_cfg.asc_dvc_cfg;
4440
                asc_dvc_varp->cfg->overrun_buf = &overrun_buf[0];
4441
                asc_dvc_varp->iop_base = iop;
4442
                asc_dvc_varp->isr_callback = (Ptr2Func) asc_isr_callback;
4443
            } else {
4444
                ASC_DBG(1, "advansys_detect: wide board\n");
4445
                adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
4446
                adv_dvc_varp->drv_ptr = (ulong) boardp;
4447
                adv_dvc_varp->cfg = &boardp->dvc_cfg.adv_dvc_cfg;
4448
                adv_dvc_varp->isr_callback = (Ptr2Func) adv_isr_callback;
4449
 
4450
#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0)
4451
                adv_dvc_varp->iop_base = iop;
4452
#else /* version >= v1,3,0 */
4453
                /*
4454
                 * Map the board's registers into virtual memory for
4455
                 * PCI slave access. Only memory accesses are used to
4456
                 * access the board's registers.
4457
                 *
4458
                 * Note: The PCI register base address is not always
4459
                 * page aligned, but the address passed to ioremap()
4460
                 * must be page aligned. It is guaranteed that the
4461
                 * PCI register base address will not cross a page
4462
                 * boundary.
4463
                 */
4464
#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
4465
#ifdef ASC_CONFIG_PCI
4466
                pci_memory_address = pciConfig.baseAddress[1];
4467
                if ((boardp->ioremap_addr =
4468
                    ioremap(pci_memory_address & PAGE_MASK,
4469
                         PAGE_SIZE)) == 0) {
4470
                   ASC_PRINT3(
4471
"advansys_detect: board %d: ioremap(%lx, %d) returned NULL\n",
4472
                   boardp->id, pci_memory_address, ADV_CONDOR_IOLEN);
4473
                   scsi_unregister(shp);
4474
                   asc_board_count--;
4475
                   continue;
4476
                }
4477
                adv_dvc_varp->iop_base = (AdvPortAddr)
4478
                    (boardp->ioremap_addr +
4479
                     (pci_memory_address - (pci_memory_address & PAGE_MASK)));
4480
#endif /* ASC_CONFIG_PCI */
4481
#else /* version >= v2.1.93 */ 
4482
#ifdef CONFIG_PCI
4483
                pci_memory_address = pci_devp->base_address[1];
4484
                if ((boardp->ioremap_addr =
4485
                    ioremap(pci_memory_address & PAGE_MASK,
4486
                         PAGE_SIZE)) == 0) {
4487
                   ASC_PRINT3(
4488
"advansys_detect: board %d: ioremap(%lx, %d) returned NULL\n",
4489
                   boardp->id, pci_memory_address, ADV_CONDOR_IOLEN);
4490
                   scsi_unregister(shp);
4491
                   asc_board_count--;
4492
                   continue;
4493
                }
4494
                adv_dvc_varp->iop_base = (AdvPortAddr)
4495
                    (boardp->ioremap_addr +
4496
                     (pci_memory_address - (pci_memory_address & PAGE_MASK)));
4497
#endif /* CONFIG_PCI */
4498
#endif /* version >= v2.1.93 */ 
4499
#endif /* version >= v1,3,0 */
4500
 
4501
                /*
4502
                 * Even though it isn't used to access the board in
4503
                 * kernels greater than or equal to v1.3.0, save
4504
                 * the I/O Port address so that it can be reported and
4505
                 * displayed.
4506
                 */
4507
                boardp->ioport = iop;
4508
            }
4509
 
4510
#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
4511
            /*
4512
             * Allocate buffer for printing information from
4513
             * /proc/scsi/advansys/[0...].
4514
             */
4515
            if ((boardp->prtbuf =
4516
                kmalloc(ASC_PRTBUF_SIZE, GFP_ATOMIC)) == NULL) {
4517
                ASC_PRINT3(
4518
"advansys_detect: board %d: kmalloc(%d, %d) returned NULL\n",
4519
                    boardp->id, ASC_PRTBUF_SIZE, GFP_ATOMIC);
4520
                scsi_unregister(shp);
4521
                asc_board_count--;
4522
                continue;
4523
            }
4524
#endif /* version >= v1.3.0 */
4525
 
4526
            if (ASC_NARROW_BOARD(boardp)) {
4527
                /*
4528
                 * Set the board bus type and PCI IRQ before
4529
                 * calling AscInitGetConfig().
4530
                 */
4531
                switch (asc_dvc_varp->bus_type) {
4532
                case ASC_IS_ISA:
4533
                    shp->unchecked_isa_dma = TRUE;
4534
                    share_irq = FALSE;
4535
                    break;
4536
                case ASC_IS_VL:
4537
                    shp->unchecked_isa_dma = FALSE;
4538
                    share_irq = FALSE;
4539
                    break;
4540
                case ASC_IS_EISA:
4541
                    shp->unchecked_isa_dma = FALSE;
4542
                    share_irq = TRUE;
4543
                    break;
4544
#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
4545
#ifdef ASC_CONFIG_PCI
4546
                case ASC_IS_PCI:
4547
                    shp->irq = asc_dvc_varp->irq_no = pciConfig.irqLine;
4548
                    asc_dvc_varp->cfg->pci_device_id = pciConfig.deviceID;
4549
                    asc_dvc_varp->cfg->pci_slot_info =
4550
                        ASC_PCI_MKID(pciDevice.busNumber,
4551
                            pciDevice.slotFound,
4552
                            pciDevice.devFunc);
4553
                    shp->unchecked_isa_dma = FALSE;
4554
                    share_irq = TRUE;
4555
                    break;
4556
#endif /* ASC_CONFIG_PCI */
4557
#else /* version >= v2.1.93 */ 
4558
#ifdef CONFIG_PCI
4559
                case ASC_IS_PCI:
4560
                    shp->irq = asc_dvc_varp->irq_no = pci_devp->irq;
4561
                    asc_dvc_varp->cfg->pci_device_id = pci_devp->device;
4562
                    asc_dvc_varp->cfg->pci_slot_info =
4563
                        ASC_PCI_MKID(pci_devp->bus->number,
4564
                            PCI_SLOT(pci_devp->devfn),
4565
                            PCI_FUNC(pci_devp->devfn));
4566
                    shp->unchecked_isa_dma = FALSE;
4567
                    share_irq = TRUE;
4568
                    break;
4569
#endif /* CONFIG_PCI */
4570
#endif /* version >= v2.1.93 */ 
4571
                default:
4572
                    ASC_PRINT2(
4573
"advansys_detect: board %d: unknown adapter type: %d\n",
4574
                        boardp->id, asc_dvc_varp->bus_type);
4575
                    shp->unchecked_isa_dma = TRUE;
4576
                    share_irq = FALSE;
4577
                    break;
4578
                }
4579
            } else {
4580
                /*
4581
                 * For Wide boards set PCI information before calling
4582
                 * AdvInitGetConfig().
4583
                 */
4584
#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
4585
#ifdef ASC_CONFIG_PCI
4586
                shp->irq = adv_dvc_varp->irq_no = pciConfig.irqLine;
4587
                adv_dvc_varp->cfg->pci_device_id = pciConfig.deviceID;
4588
                adv_dvc_varp->cfg->pci_slot_info =
4589
                ASC_PCI_MKID(pciDevice.busNumber,
4590
                    pciDevice.slotFound,
4591
                    pciDevice.devFunc);
4592
                shp->unchecked_isa_dma = FALSE;
4593
                share_irq = TRUE;
4594
#endif /* ASC_CONFIG_PCI */
4595
#else /* version >= v2.1.93 */ 
4596
#ifdef CONFIG_PCI
4597
                shp->irq = adv_dvc_varp->irq_no = pci_devp->irq;
4598
                adv_dvc_varp->cfg->pci_device_id = pci_devp->device;
4599
                adv_dvc_varp->cfg->pci_slot_info =
4600
                ASC_PCI_MKID(pci_devp->bus->number,
4601
                    PCI_SLOT(pci_devp->devfn),
4602
                    PCI_FUNC(pci_devp->devfn));
4603
                shp->unchecked_isa_dma = FALSE;
4604
                share_irq = TRUE;
4605
#endif /* CONFIG_PCI */
4606
#endif /* version >= v2.1.93 */ 
4607
            }
4608
 
4609
            /*
4610
             * Read the board configuration.
4611
             */
4612
            if (ASC_NARROW_BOARD(boardp)) {
4613
                 /*
4614
                  * NOTE: AscInitGetConfig() may change the board's
4615
                  * bus_type value. The asc_bus[bus] value should no
4616
                  * longer be used. If the bus_type field must be
4617
                  * referenced only use the bit-wise AND operator "&".
4618
                  */
4619
                 ASC_DBG(2, "advansys_detect: AscInitGetConfig()\n");
4620
                switch(ret = AscInitGetConfig(asc_dvc_varp)) {
4621
                case 0:    /* No error */
4622
                    break;
4623
                case ASC_WARN_IO_PORT_ROTATE:
4624
                    ASC_PRINT1(
4625
"AscInitGetConfig: board %d: I/O port address modified\n",
4626
                        boardp->id);
4627
                    break;
4628
                case ASC_WARN_AUTO_CONFIG:
4629
                    ASC_PRINT1(
4630
"AscInitGetConfig: board %d: I/O port increment switch enabled\n",
4631
                        boardp->id);
4632
                    break;
4633
                case ASC_WARN_EEPROM_CHKSUM:
4634
                    ASC_PRINT1(
4635
"AscInitGetConfig: board %d: EEPROM checksum error\n",
4636
                        boardp->id);
4637
                    break;
4638
                case ASC_WARN_IRQ_MODIFIED:
4639
                    ASC_PRINT1(
4640
"AscInitGetConfig: board %d: IRQ modified\n",
4641
                        boardp->id);
4642
                    break;
4643
                case ASC_WARN_CMD_QNG_CONFLICT:
4644
                    ASC_PRINT1(
4645
"AscInitGetConfig: board %d: tag queuing enabled w/o disconnects\n",
4646
                        boardp->id);
4647
                    break;
4648
                default:
4649
                    ASC_PRINT2(
4650
"AscInitGetConfig: board %d: unknown warning: %x\n",
4651
                        boardp->id, ret);
4652
                    break;
4653
                }
4654
                if ((err_code = asc_dvc_varp->err_code) != 0) {
4655
                    ASC_PRINT3(
4656
"AscInitGetConfig: board %d error: init_state %x, err_code %x\n",
4657
                        boardp->id, asc_dvc_varp->init_state,
4658
                        asc_dvc_varp->err_code);
4659
                }
4660
            } else {
4661
                ASC_DBG(2, "advansys_detect: AdvInitGetConfig()\n");
4662
                if ((ret = AdvInitGetConfig(adv_dvc_varp)) != 0) {
4663
                    ASC_PRINT2("AdvInitGetConfig: board %d: warning: %x\n",
4664
                        boardp->id, ret);
4665
                }
4666
                if ((err_code = adv_dvc_varp->err_code) != 0) {
4667
                    ASC_PRINT2(
4668
"AdvInitGetConfig: board %d error: err_code %x\n",
4669
                        boardp->id, adv_dvc_varp->err_code);
4670
                }
4671
            }
4672
 
4673
            if (err_code != 0) {
4674
#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
4675
                kfree(boardp->prtbuf);
4676
#endif /* version >= v1.3.0 */
4677
                scsi_unregister(shp);
4678
                asc_board_count--;
4679
                continue;
4680
            }
4681
 
4682
            /*
4683
             * Save the EEPROM configuration so that it can be displayed
4684
             * from /proc/scsi/advansys/[0...].
4685
             */
4686
            if (ASC_NARROW_BOARD(boardp)) {
4687
 
4688
                ASCEEP_CONFIG *ep;
4689
 
4690
                /*
4691
                 * Set the adapter's target id bit in the 'init_tidmask' field.
4692
                 */
4693
                boardp->init_tidmask |=
4694
                    ADV_TID_TO_TIDMASK(asc_dvc_varp->cfg->chip_scsi_id);
4695
 
4696
                /*
4697
                 * Save EEPROM settings for the board.
4698
                 */
4699
                ep = &boardp->eep_config.asc_eep;
4700
 
4701
                ep->init_sdtr = asc_dvc_varp->cfg->sdtr_enable;
4702
                ep->disc_enable = asc_dvc_varp->cfg->disc_enable;
4703
                ep->use_cmd_qng = asc_dvc_varp->cfg->cmd_qng_enabled;
4704
                ep->isa_dma_speed = asc_dvc_varp->cfg->isa_dma_speed;
4705
                ep->start_motor = asc_dvc_varp->start_motor;
4706
                ep->cntl = asc_dvc_varp->dvc_cntl;
4707
                ep->no_scam = asc_dvc_varp->no_scam;
4708
                ep->max_total_qng = asc_dvc_varp->max_total_qng;
4709
                ep->chip_scsi_id = asc_dvc_varp->cfg->chip_scsi_id;
4710
                /* 'max_tag_qng' is set to the same value for every device. */
4711
                ep->max_tag_qng = asc_dvc_varp->cfg->max_tag_qng[0];
4712
                ep->adapter_info[0] = asc_dvc_varp->cfg->adapter_info[0];
4713
                ep->adapter_info[1] = asc_dvc_varp->cfg->adapter_info[1];
4714
                ep->adapter_info[2] = asc_dvc_varp->cfg->adapter_info[2];
4715
                ep->adapter_info[3] = asc_dvc_varp->cfg->adapter_info[3];
4716
                ep->adapter_info[4] = asc_dvc_varp->cfg->adapter_info[4];
4717
                ep->adapter_info[5] = asc_dvc_varp->cfg->adapter_info[5];
4718
                ep->adapter_info[6] = asc_dvc_varp->cfg->adapter_info[6];
4719
 
4720
               /*
4721
                * Modify board configuration.
4722
                */
4723
                ASC_DBG(2, "advansys_detect: AscInitSetConfig()\n");
4724
                switch (ret = AscInitSetConfig(asc_dvc_varp)) {
4725
                case 0:    /* No error. */
4726
                    break;
4727
                case ASC_WARN_IO_PORT_ROTATE:
4728
                    ASC_PRINT1(
4729
"AscInitSetConfig: board %d: I/O port address modified\n",
4730
                        boardp->id);
4731
                    break;
4732
                case ASC_WARN_AUTO_CONFIG:
4733
                    ASC_PRINT1(
4734
"AscInitSetConfig: board %d: I/O port increment switch enabled\n",
4735
                        boardp->id);
4736
                    break;
4737
                case ASC_WARN_EEPROM_CHKSUM:
4738
                    ASC_PRINT1(
4739
"AscInitSetConfig: board %d: EEPROM checksum error\n",
4740
                        boardp->id);
4741
                    break;
4742
                case ASC_WARN_IRQ_MODIFIED:
4743
                    ASC_PRINT1(
4744
"AscInitSetConfig: board %d: IRQ modified\n",
4745
                        boardp->id);
4746
                    break;
4747
                case ASC_WARN_CMD_QNG_CONFLICT:
4748
                    ASC_PRINT1(
4749
"AscInitSetConfig: board %d: tag queuing w/o disconnects\n",
4750
                        boardp->id);
4751
                    break;
4752
                default:
4753
                    ASC_PRINT2(
4754
"AscInitSetConfig: board %d: unknown warning: %x\n",
4755
                        boardp->id, ret);
4756
                    break;
4757
                }
4758
                if (asc_dvc_varp->err_code != 0) {
4759
                    ASC_PRINT3(
4760
"AscInitSetConfig: board %d error: init_state %x, err_code %x\n",
4761
                        boardp->id, asc_dvc_varp->init_state,
4762
                        asc_dvc_varp->err_code);
4763
#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
4764
                    kfree(boardp->prtbuf);
4765
#endif /* version >= v1.3.0 */
4766
                    scsi_unregister(shp);
4767
                    asc_board_count--;
4768
                    continue;
4769
                }
4770
 
4771
                /*
4772
                 * Finish initializing the 'Scsi_Host' structure.
4773
                 */
4774
                /* AscInitSetConfig() will set the IRQ for non-PCI boards. */
4775
                if ((asc_dvc_varp->bus_type & ASC_IS_PCI) == 0) {
4776
                    shp->irq = asc_dvc_varp->irq_no;
4777
                }
4778
            } else {
4779
 
4780
                ADVEEP_CONFIG *ep;
4781
 
4782
                /*
4783
                 * Save Wide EEP Configuration Information.
4784
                 */
4785
                ep = &boardp->eep_config.adv_eep;
4786
 
4787
                ep->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
4788
                ep->max_host_qng = adv_dvc_varp->max_host_qng;
4789
                ep->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
4790
                ep->termination = adv_dvc_varp->cfg->termination;
4791
                ep->disc_enable = adv_dvc_varp->cfg->disc_enable;
4792
                ep->bios_ctrl = adv_dvc_varp->bios_ctrl;
4793
                ep->wdtr_able = adv_dvc_varp->wdtr_able;
4794
                ep->sdtr_able = adv_dvc_varp->sdtr_able;
4795
                ep->ultra_able = adv_dvc_varp->ultra_able;
4796
                ep->tagqng_able = adv_dvc_varp->tagqng_able;
4797
                ep->start_motor = adv_dvc_varp->start_motor;
4798
                ep->scsi_reset_delay = adv_dvc_varp->scsi_reset_wait;
4799
                ep->bios_boot_delay = adv_dvc_varp->cfg->bios_boot_wait;
4800
                ep->serial_number_word1 = adv_dvc_varp->cfg->serial1;
4801
                ep->serial_number_word2 = adv_dvc_varp->cfg->serial2;
4802
                ep->serial_number_word3 = adv_dvc_varp->cfg->serial3;
4803
 
4804
                /*
4805
                 * Set the adapter's target id bit in the 'init_tidmask' field.
4806
                 */
4807
                boardp->init_tidmask |=
4808
                    ADV_TID_TO_TIDMASK(adv_dvc_varp->chip_scsi_id);
4809
 
4810
                /*
4811
                 * Finish initializing the 'Scsi_Host' structure.
4812
                 */
4813
                shp->irq = adv_dvc_varp->irq_no;
4814
            }
4815
 
4816
#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
4817
            /*
4818
             * Channels are numbered beginning with 0. For AdvanSys One host
4819
             * structure supports one channel. Multi-channel boards have a
4820
             * separate host structure for each channel.
4821
             */
4822
            shp->max_channel = 0;
4823
#endif /* version >= v1.3.89 */
4824
            if (ASC_NARROW_BOARD(boardp)) {
4825
                shp->max_id = ASC_MAX_TID + 1;
4826
                shp->max_lun = ASC_MAX_LUN + 1;
4827
 
4828
                shp->io_port = asc_dvc_varp->iop_base;
4829
                shp->n_io_port = ASC_IOADR_GAP;
4830
                shp->this_id = asc_dvc_varp->cfg->chip_scsi_id;
4831
 
4832
                /* Set maximum number of queues the adapter can handle. */
4833
                shp->can_queue = asc_dvc_varp->max_total_qng;
4834
            } else {
4835
                shp->max_id = ADV_MAX_TID + 1;
4836
                shp->max_lun = ADV_MAX_LUN + 1;
4837
 
4838
                /*
4839
                 * Save the I/O Port address and length even though the
4840
                 * in v1.3.0 and greater kernels the region is not used
4841
                 * by a Wide board. Instead the board is accessed with
4842
                 * Memory Mapped I/O.
4843
                 */
4844
                shp->io_port = iop;
4845
                shp->n_io_port = ADV_CONDOR_IOLEN;
4846
 
4847
                shp->this_id = adv_dvc_varp->chip_scsi_id;
4848
 
4849
                /* Set maximum number of queues the adapter can handle. */
4850
                shp->can_queue = adv_dvc_varp->max_host_qng;
4851
            }
4852
 
4853
#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,89)
4854
            /*
4855
             * In old kernels without tag queuing support and with memory
4856
             * allocation problems set a conservative 'cmd_per_lun' value.
4857
             */
4858
#ifdef MODULE
4859
            shp->cmd_per_lun = 1;
4860
#else /* MODULE */
4861
            shp->cmd_per_lun = 4;
4862
#endif /* MODULE */
4863
            ASC_DBG1(1, "advansys_detect: cmd_per_lun: %d\n", shp->cmd_per_lun);
4864
#else /* version >= v1.3.89 */
4865
            /*
4866
             * Following v1.3.89, 'cmd_per_lun' is no longer needed
4867
             * and should be set to zero.
4868
             *
4869
             * But because of a bug introduced in v1.3.89 if the driver is
4870
             * compiled as a module and 'cmd_per_lun' is zero, the Mid-Level
4871
             * SCSI function 'allocate_device' will panic. To allow the driver
4872
             * to work as a module in these kernels set 'cmd_per_lun' to 1.
4873
             */
4874
#ifdef MODULE
4875
            shp->cmd_per_lun = 1;
4876
#else /* MODULE */
4877
            shp->cmd_per_lun = 0;
4878
#endif /* MODULE */
4879
            /*
4880
             * Use the host 'select_queue_depths' function to determine
4881
             * the number of commands to queue per device.
4882
             */
4883
            shp->select_queue_depths = advansys_select_queue_depths;
4884
#endif /* version >= v1.3.89 */
4885
 
4886
            /*
4887
             * Set the maximum number of scatter-gather elements the
4888
             * adapter can handle.
4889
             */
4890
            if (ASC_NARROW_BOARD(boardp)) {
4891
                /*
4892
                 * Allow two commands with 'sg_tablesize' scatter-gather
4893
                 * elements to be executed simultaneously. This value is
4894
                 * the theoretical hardware limit. It may be decreased
4895
                 * below.
4896
                 */
4897
                shp->sg_tablesize =
4898
                    (((asc_dvc_varp->max_total_qng - 2) / 2) *
4899
                    ASC_SG_LIST_PER_Q) + 1;
4900
            } else {
4901
                shp->sg_tablesize = ADV_MAX_SG_LIST;
4902
            }
4903
 
4904
#ifdef MODULE
4905
            /*
4906
             * If the driver is compiled as a module, set a limit on the
4907
             * 'sg_tablesize' value to prevent memory allocation failures.
4908
             * Memory allocation errors are more likely to occur at module
4909
             * load time, then at driver initialization time.
4910
             */
4911
            if (shp->sg_tablesize > 64) {
4912
                shp->sg_tablesize = 64;
4913
            }
4914
#endif /* MODULE */
4915
 
4916
            /*
4917
             * The value of 'sg_tablesize' can not exceed the SCSI
4918
             * mid-level driver definition of SG_ALL. SG_ALL also
4919
             * must not be exceeded, because it is used to define the
4920
             * size of the scatter-gather table in 'struct asc_sg_head'.
4921
             */
4922
            if (shp->sg_tablesize > SG_ALL) {
4923
                shp->sg_tablesize = SG_ALL;
4924
            }
4925
 
4926
            ASC_DBG1(1, "advansys_detect: sg_tablesize: %d\n",
4927
                shp->sg_tablesize);
4928
 
4929
            /* BIOS start address. */
4930
            if (ASC_NARROW_BOARD(boardp)) {
4931
                shp->base = (char *) ((ulong) AscGetChipBiosAddress(
4932
                                                asc_dvc_varp->iop_base,
4933
                                                asc_dvc_varp->bus_type));
4934
            } else {
4935
                /*
4936
                 * Fill-in BIOS board variables. The Wide BIOS saves
4937
                 * information in LRAM that is used by the driver.
4938
                 */
4939
                AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_SIGNATURE,
4940
                    boardp->bios_signature);
4941
                AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_VERSION,
4942
                    boardp->bios_version);
4943
                AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_CODESEG,
4944
                    boardp->bios_codeseg);
4945
                AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_CODELEN,
4946
                    boardp->bios_codelen);
4947
 
4948
                ASC_DBG2(1,
4949
                    "advansys_detect: bios_signature %x, bios_version %x\n",
4950
                    boardp->bios_signature, boardp->bios_version);
4951
 
4952
                ASC_DBG2(1,
4953
                    "advansys_detect: bios_codeseg %x, bios_codelen %x\n",
4954
                    boardp->bios_codeseg, boardp->bios_codelen);
4955
 
4956
                /*
4957
                 * If the BIOS saved a valid signature, then fill in
4958
                 * the BIOS code segment base address.
4959
                 */
4960
                if (boardp->bios_signature == 0x55AA) {
4961
                    /*
4962
                     * Convert x86 realmode code segment to a linear
4963
                     * address by shifting left 4.
4964
                     */
4965
                    shp->base = (uchar *) (boardp->bios_codeseg << 4);
4966
                } else {
4967
                    shp->base = 0;
4968
                }
4969
            }
4970
 
4971
            /*
4972
             * Register Board Resources - I/O Port, DMA, IRQ
4973
             */
4974
 
4975
            /* Register I/O port range. */
4976
            ASC_DBG(2, "advansys_detect: request_region()\n");
4977
            request_region(shp->io_port, shp->n_io_port, "advansys");
4978
 
4979
            /* Register DMA Channel for Narrow boards. */
4980
            shp->dma_channel = NO_ISA_DMA; /* Default to no ISA DMA. */
4981
            if (ASC_NARROW_BOARD(boardp)) {
4982
                /* Register DMA channel for ISA bus. */
4983
                if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
4984
                    shp->dma_channel = asc_dvc_varp->cfg->isa_dma_channel;
4985
                    if ((ret =
4986
                         request_dma(shp->dma_channel, "advansys")) != 0) {
4987
                        ASC_PRINT3(
4988
"advansys_detect: board %d: request_dma() %d failed %d\n",
4989
                            boardp->id, shp->dma_channel, ret);
4990
                        release_region(shp->io_port, shp->n_io_port);
4991
#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
4992
                        kfree(boardp->prtbuf);
4993
#endif /* version >= v1.3.0 */
4994
                        scsi_unregister(shp);
4995
                        asc_board_count--;
4996
                        continue;
4997
                    }
4998
                    AscEnableIsaDma(shp->dma_channel);
4999
                }
5000
            }
5001
 
5002
            /* Register IRQ Number. */
5003
            ASC_DBG1(2, "advansys_detect: request_irq() %d\n", shp->irq);
5004
#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,70)
5005
            if ((ret = request_irq(shp->irq, advansys_interrupt,
5006
                            SA_INTERRUPT, "advansys")) != 0)
5007
#else /* version >= v1.3.70 */
5008
           /*
5009
            * If request_irq() fails with the SA_INTERRUPT flag set,
5010
            * then try again without the SA_INTERRUPT flag set. This
5011
            * allows IRQ sharing to work even with other drivers that
5012
            * do not set the SA_INTERRUPT flag.
5013
            *
5014
            * If SA_INTERRUPT is not set, then interrupts are enabled
5015
            * before the driver interrupt function is called.
5016
            */
5017
            if (((ret = request_irq(shp->irq, advansys_interrupt,
5018
                            SA_INTERRUPT | (share_irq == TRUE ? SA_SHIRQ : 0),
5019
                            "advansys", boardp)) != 0) &&
5020
                ((ret = request_irq(shp->irq, advansys_interrupt,
5021
                            (share_irq == TRUE ? SA_SHIRQ : 0),
5022
                            "advansys", boardp)) != 0))
5023
#endif /* version >= v1.3.70 */
5024
            {
5025
                if (ret == -EBUSY) {
5026
                    ASC_PRINT2(
5027
"advansys_detect: board %d: request_irq(): IRQ %d already in use.\n",
5028
                        boardp->id, shp->irq);
5029
                } else if (ret == -EINVAL) {
5030
                    ASC_PRINT2(
5031
"advansys_detect: board %d: request_irq(): IRQ %d not valid.\n",
5032
                        boardp->id, shp->irq);
5033
                } else {
5034
                    ASC_PRINT3(
5035
"advansys_detect: board %d: request_irq(): IRQ %d failed with %d\n",
5036
                        boardp->id, shp->irq, ret);
5037
                }
5038
                release_region(shp->io_port, shp->n_io_port);
5039
#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
5040
                iounmap(boardp->ioremap_addr);
5041
#endif /* version >= v1,3,0 */
5042
                if (shp->dma_channel != NO_ISA_DMA) {
5043
                    free_dma(shp->dma_channel);
5044
                }
5045
#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
5046
                kfree(boardp->prtbuf);
5047
#endif /* version >= v1.3.0 */
5048
                scsi_unregister(shp);
5049
                asc_board_count--;
5050
                continue;
5051
            }
5052
 
5053
            /*
5054
             * Initialize board RISC chip and enable interrupts.
5055
             */
5056
            if (ASC_NARROW_BOARD(boardp)) {
5057
                ASC_DBG(2, "advansys_detect: AscInitAsc1000Driver()\n");
5058
                warn_code = AscInitAsc1000Driver(asc_dvc_varp);
5059
                err_code = asc_dvc_varp->err_code;
5060
 
5061
                if (warn_code || err_code) {
5062
                    ASC_PRINT4(
5063
"AscInitAsc1000Driver: board %d: error: init_state %x, warn %x error %x\n",
5064
                        boardp->id, asc_dvc_varp->init_state,
5065
                        warn_code, err_code);
5066
                }
5067
            } else {
5068
                int             req_cnt;
5069
                adv_req_t       *reqp = NULL;
5070
                int             sg_cnt;
5071
                adv_sgblk_t     *sgp = NULL;
5072
 
5073
#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0)
5074
                req_cnt = sizeof(adv_req_buf)/sizeof(adv_req_t);
5075
                sg_cnt = sizeof(adv_sgblk_buf)/sizeof(adv_sgblk_t);
5076
                reqp = (adv_req_t *) &adv_req_buf[0];
5077
                sgp = (adv_sgblk_t *) &adv_sgblk_buf[0];
5078
#else /* version >= v1.3.0 */
5079
                /*
5080
                 * Allocate up to 'max_host_qng' request structures for
5081
                 * the Wide board.
5082
                 */
5083
                for (req_cnt = adv_dvc_varp->max_host_qng;
5084
                    req_cnt > 0; req_cnt--) {
5085
 
5086
                    reqp = (adv_req_t *)
5087
                        kmalloc(sizeof(adv_req_t) * req_cnt, GFP_ATOMIC);
5088
 
5089
                    ASC_DBG3(1,
5090
                        "advansys_detect: reqp %x, req_cnt %d, bytes %d\n",
5091
                        (unsigned) reqp, req_cnt, sizeof(adv_req_t) * req_cnt);
5092
 
5093
                    if (reqp != NULL) {
5094
                        break;
5095
                    }
5096
                }
5097
 
5098
                /*
5099
                 * Allocate up to ADV_TOT_SG_LIST request structures for
5100
                 * the Wide board.
5101
                 */
5102
                for (sg_cnt = ADV_TOT_SG_LIST; sg_cnt > 0; sg_cnt--) {
5103
 
5104
                    sgp = (adv_sgblk_t *)
5105
                        kmalloc(sizeof(adv_sgblk_t) * sg_cnt, GFP_ATOMIC);
5106
 
5107
                    ASC_DBG3(1,
5108
                        "advansys_detect: sgp %x, sg_cnt %d, bytes %d\n",
5109
                        (unsigned) sgp, sg_cnt, sizeof(adv_sgblk_t) * sg_cnt);
5110
 
5111
                    if (sgp != NULL) {
5112
                        break;
5113
                    }
5114
                }
5115
#endif /* version >= v1.3.0 */
5116
 
5117
                /*
5118
                 * If no request structures or scatter-gather structures could
5119
                 * be allocated, then return an error. Otherwise continue with
5120
                 * initialization.
5121
                 */
5122
                if (reqp == NULL) {
5123
                    ASC_PRINT1(
5124
"advansys_detect: board %d: error: failed to kmalloc() adv_req_t buffer.\n",
5125
                        boardp->id);
5126
                    err_code = ADV_ERROR;
5127
                } else if (sgp == NULL) {
5128
                    kfree(reqp);
5129
                    ASC_PRINT1(
5130
"advansys_detect: board %d: error: failed to kmalloc() adv_sgblk_t buffer.\n",
5131
                        boardp->id);
5132
                    err_code = ADV_ERROR;
5133
                } else {
5134
 
5135
                    /*
5136
                     * Save original pointer for kfree() in case the
5137
                     * driver is built as a module and can be unloaded.
5138
                     */
5139
                    boardp->orig_reqp = reqp;
5140
 
5141
                    /*
5142
                     * Point 'adv_reqp' to the request structures and
5143
                     * link them together.
5144
                     */
5145
                    req_cnt--;
5146
                    reqp[req_cnt].next_reqp = NULL;
5147
                    for (; req_cnt > 0; req_cnt--) {
5148
                        reqp[req_cnt - 1].next_reqp = &reqp[req_cnt];
5149
                    }
5150
                    boardp->adv_reqp = &reqp[0];
5151
 
5152
                    /*
5153
                     * Save original pointer for kfree() in case the
5154
                     * driver is built as a module and can be unloaded.
5155
                     */
5156
                    boardp->orig_sgblkp = sgp;
5157
 
5158
                    /*
5159
                     * Point 'adv_sgblkp' to the request structures and
5160
                     * link them together.
5161
                     */
5162
                    sg_cnt--;
5163
                    sgp[sg_cnt].next_sgblkp = NULL;
5164
                    for (; sg_cnt > 0; sg_cnt--) {
5165
                        sgp[sg_cnt - 1].next_sgblkp = &sgp[sg_cnt];
5166
                    }
5167
                    boardp->adv_sgblkp = &sgp[0];
5168
 
5169
                    ASC_DBG(2, "advansys_detect: AdvInitAsc3550Driver()\n");
5170
                    warn_code = AdvInitAsc3550Driver(adv_dvc_varp);
5171
                    err_code = adv_dvc_varp->err_code;
5172
 
5173
                    if (warn_code || err_code) {
5174
                        ASC_PRINT3(
5175
"AdvInitAsc3550Driver: board %d: error: warn %x, error %x\n",
5176
                            boardp->id, warn_code, adv_dvc_varp->err_code);
5177
                    }
5178
                }
5179
            }
5180
 
5181
            if (err_code != 0) {
5182
                release_region(shp->io_port, shp->n_io_port);
5183
                if (ASC_WIDE_BOARD(boardp)) {
5184
#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
5185
                    iounmap(boardp->ioremap_addr);
5186
#endif /* version >= v1,3,0 */
5187
                    if (boardp->orig_reqp) {
5188
                        kfree(boardp->orig_reqp);
5189
                        boardp->orig_reqp = boardp->adv_reqp = NULL;
5190
                    }
5191
                    if (boardp->orig_sgblkp) {
5192
                        kfree(boardp->orig_sgblkp);
5193
                        boardp->orig_sgblkp = boardp->adv_sgblkp = NULL;
5194
                    }
5195
                }
5196
                if (shp->dma_channel != NO_ISA_DMA) {
5197
                    free_dma(shp->dma_channel);
5198
                }
5199
#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
5200
                kfree(boardp->prtbuf);
5201
#endif /* version >= v1.3.0 */
5202
#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,70)
5203
                free_irq(shp->irq);
5204
#else /* version >= v1.3.70 */
5205
                free_irq(shp->irq, boardp);
5206
#endif /* version >= v1.3.70 */
5207
                scsi_unregister(shp);
5208
                asc_board_count--;
5209
                continue;
5210
            }
5211
            ASC_DBG_PRT_SCSI_HOST(2, shp);
5212
        }
5213
    }
5214
    ASC_DBG1(1, "advansys_detect: done: asc_board_count %d\n", asc_board_count);
5215
    return asc_board_count;
5216
}
5217
 
5218
/*
5219
 * advansys_release()
5220
 *
5221
 * Release resources allocated for a single AdvanSys adapter.
5222
 */
5223
int
5224
advansys_release(struct Scsi_Host *shp)
5225
{
5226
    asc_board_t    *boardp;
5227
 
5228
    ASC_DBG(1, "advansys_release: begin\n");
5229
    boardp = ASC_BOARDP(shp);
5230
#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,70)
5231
    free_irq(shp->irq);
5232
#else /* version >= v1.3.70 */
5233
    free_irq(shp->irq, boardp);
5234
#endif /* version >= v1.3.70 */
5235
    if (shp->dma_channel != NO_ISA_DMA) {
5236
        ASC_DBG(1, "advansys_release: free_dma()\n");
5237
        free_dma(shp->dma_channel);
5238
    }
5239
    release_region(shp->io_port, shp->n_io_port);
5240
    if (ASC_WIDE_BOARD(boardp)) {
5241
#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
5242
        iounmap(boardp->ioremap_addr);
5243
#endif /* version >= v1,3,0 */
5244
        if (boardp->orig_reqp) {
5245
            kfree(boardp->orig_reqp);
5246
            boardp->orig_reqp = boardp->adv_reqp = NULL;
5247
        }
5248
        if (boardp->orig_sgblkp) {
5249
            kfree(boardp->orig_sgblkp);
5250
            boardp->orig_sgblkp = boardp->adv_sgblkp = NULL;
5251
        }
5252
    }
5253
#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
5254
    ASC_ASSERT(boardp->prtbuf != NULL);
5255
    kfree(boardp->prtbuf);
5256
#endif /* version >= v1.3.0 */
5257
    scsi_unregister(shp);
5258
    ASC_DBG(1, "advansys_release: end\n");
5259
    return 0;
5260
}
5261
 
5262
/*
5263
 * advansys_info()
5264
 *
5265
 * Return suitable for printing on the console with the argument
5266
 * adapter's configuration information.
5267
 *
5268
 * Note: The information line should not exceed ASC_INFO_SIZE bytes,
5269
 * otherwise the static 'info' array will be overrun.
5270
 */
5271
const char *
5272
advansys_info(struct Scsi_Host *shp)
5273
{
5274
    static char     info[ASC_INFO_SIZE];
5275
    asc_board_t     *boardp;
5276
    ASC_DVC_VAR     *asc_dvc_varp;
5277
    ADV_DVC_VAR     *adv_dvc_varp;
5278
    char            *busname;
5279
 
5280
    boardp = ASC_BOARDP(shp);
5281
    if (ASC_NARROW_BOARD(boardp)) {
5282
        asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
5283
        ASC_DBG(1, "advansys_info: begin\n");
5284
        if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
5285
            if ((asc_dvc_varp->bus_type & ASC_IS_ISAPNP) == ASC_IS_ISAPNP) {
5286
                busname = "ISA PnP";
5287
            } else {
5288
                busname = "ISA";
5289
            }
5290
            sprintf(info,
5291
#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,92)
5292
"AdvanSys SCSI %s: %s %u CDB: BIOS %X, IO %X/%X, IRQ %u, DMA %u",
5293
#else /* version >= v2.1.92 */ 
5294
"AdvanSys SCSI %s: %s %u CDB: BIOS %X, IO %lX/%X, IRQ %u, DMA %u",
5295
#endif /* version >= v2.1.92 */ 
5296
                ASC_VERSION, busname, asc_dvc_varp->max_total_qng,
5297
                (unsigned) shp->base,
5298
                shp->io_port, shp->n_io_port - 1,
5299
                shp->irq, shp->dma_channel);
5300
        } else if (asc_dvc_varp->bus_type & ASC_IS_PCI) {
5301
            if ((asc_dvc_varp->bus_type & ASC_IS_PCI_ULTRA)
5302
                == ASC_IS_PCI_ULTRA) {
5303
                busname = "PCI Ultra";
5304
            } else {
5305
                busname = "PCI";
5306
            }
5307
            sprintf(info,
5308
#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,92)
5309
                "AdvanSys SCSI %s: %s %u CDB: IO %X/%X, IRQ %u",
5310
#else /* version >= v2.1.92 */ 
5311
                "AdvanSys SCSI %s: %s %u CDB: IO %lX/%X, IRQ %u",
5312
#endif /* version >= v2.1.92 */ 
5313
                ASC_VERSION, busname, asc_dvc_varp->max_total_qng,
5314
                shp->io_port, shp->n_io_port - 1, shp->irq);
5315
        } else {
5316
            if (asc_dvc_varp->bus_type & ASC_IS_VL) {
5317
                busname = "VL";
5318
            } else if (asc_dvc_varp->bus_type & ASC_IS_EISA) {
5319
                busname = "EISA";
5320
            } else {
5321
                busname = "?";
5322
                ASC_PRINT2(
5323
    "advansys_info: board %d: unknown bus type %d\n",
5324
                    boardp->id, asc_dvc_varp->bus_type);
5325
            }
5326
            sprintf(info,
5327
#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,92)
5328
                "AdvanSys SCSI %s: %s %u CDB: BIOS %X, IO %X/%X, IRQ %u",
5329
#else /* version >= v2.1.92 */ 
5330
                "AdvanSys SCSI %s: %s %u CDB: BIOS %X, IO %lX/%X, IRQ %u",
5331
#endif /* version >= v2.1.92 */ 
5332
                ASC_VERSION, busname, asc_dvc_varp->max_total_qng,
5333
                (unsigned) shp->base, shp->io_port - 1,
5334
                shp->n_io_port, shp->irq);
5335
        }
5336
    } else {
5337
        /*
5338
         * Wide Adapter Information
5339
         *
5340
         * Memory-mapped I/O is used instead of I/O space to access
5341
         * the adapter, but display the I/O Port range. The Memory
5342
         * I/O address is displayed through the driver /proc file.
5343
         */
5344
        adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
5345
        if (boardp->bios_signature == 0x55AA) {
5346
            sprintf(info,
5347
"AdvanSys SCSI %s: PCI Ultra-Wide: BIOS %X/%X, IO %X/%X, IRQ %u",
5348
                ASC_VERSION,
5349
                boardp->bios_codeseg << 4,
5350
                boardp->bios_codelen > 0 ?
5351
                (boardp->bios_codelen << 9) - 1 : 0,
5352
                (unsigned) boardp->ioport, ADV_CONDOR_IOLEN - 1,
5353
                shp->irq);
5354
        } else {
5355
            sprintf(info,
5356
"AdvanSys SCSI %s: PCI Ultra-Wide: IO %X/%X, IRQ %u",
5357
                ASC_VERSION,
5358
                (unsigned) boardp->ioport,
5359
                (ADV_CONDOR_IOLEN - 1),
5360
                shp->irq);
5361
        }
5362
    }
5363
    ASC_ASSERT(strlen(info) < ASC_INFO_SIZE);
5364
    ASC_DBG(1, "advansys_info: end\n");
5365
    return info;
5366
}
5367
 
5368
/*
5369
 * advansys_command() - polled I/O entrypoint.
5370
 *
5371
 * Apparently host drivers shouldn't return until the command
5372
 * is finished.
5373
 *
5374
 * Note: This is an old interface that is no longer used by the SCSI
5375
 * mid-level driver. The new interface, advansys_queuecommand(),
5376
 * currently handles all requests.
5377
 */
5378
int
5379
advansys_command(Scsi_Cmnd *scp)
5380
{
5381
    ASC_DBG1(1, "advansys_command: scp %x\n", (unsigned) scp);
5382
    ASC_STATS(scp->host, command);
5383
    scp->SCp.Status = 0; /* Set to a known state */
5384
    advansys_queuecommand(scp, advansys_command_done);
5385
    while (scp->SCp.Status == 0) {
5386
        continue;
5387
    }
5388
    ASC_DBG1(1, "advansys_command: result %x\n", scp->result);
5389
    return scp->result;
5390
}
5391
 
5392
/*
5393
 * advansys_queuecommand() - interrupt-driven I/O entrypoint.
5394
 *
5395
 * This function always returns 0. Command return status is saved
5396
 * in the 'scp' result field.
5397
 */
5398
int
5399
advansys_queuecommand(Scsi_Cmnd *scp, void (*done)(Scsi_Cmnd *))
5400
{
5401
    struct Scsi_Host    *shp;
5402
    asc_board_t         *boardp;
5403
    int                 flags;
5404
    Scsi_Cmnd           *done_scp;
5405
 
5406
    shp = scp->host;
5407
    boardp = ASC_BOARDP(shp);
5408
    ASC_STATS(shp, queuecommand);
5409
 
5410
    /*
5411
     * Disable interrupts to preserve request ordering and provide
5412
     * mutually exclusive access to global structures used to initiate
5413
     * a request.
5414
     */
5415
    save_flags(flags);
5416
    cli();
5417
 
5418
    /*
5419
     * Block new commands while handling a reset or abort request.
5420
     */
5421
    if (boardp->flags & (ASC_HOST_IN_RESET | ASC_HOST_IN_ABORT)) {
5422
        if (boardp->flags & ASC_HOST_IN_RESET) {
5423
            ASC_DBG1(1,
5424
                "advansys_queuecommand: scp %x blocked for reset request\n",
5425
                (unsigned) scp);
5426
            scp->result = HOST_BYTE(DID_RESET);
5427
        } else {
5428
            ASC_DBG1(1,
5429
                "advansys_queuecommand: scp %x blocked for abort request\n",
5430
                (unsigned) scp);
5431
            scp->result = HOST_BYTE(DID_ABORT);
5432
        }
5433
 
5434
        /*
5435
         * Add blocked requests to the board's 'done' queue. The queued
5436
         * requests will be completed at the end of the abort or reset
5437
         * handling.
5438
         */
5439
        asc_enqueue(&boardp->done, scp, ASC_BACK);
5440
        restore_flags(flags);
5441
        return 0;
5442
    }
5443
 
5444
    /*
5445
     * Attempt to execute any waiting commands for the board.
5446
     */
5447
    if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
5448
        ASC_DBG(1,
5449
            "advansys_queuecommand: before asc_execute_queue() waiting\n");
5450
        asc_execute_queue(&boardp->waiting);
5451
    }
5452
 
5453
    /*
5454
     * Save the function pointer to Linux mid-level 'done' function
5455
     * and attempt to execute the command.
5456
     *
5457
     * If ASC_ERROR is returned the request has been added to the
5458
     * board's 'active' queue and will be completed by the interrupt
5459
     * handler.
5460
     *
5461
     * If ASC_BUSY is returned add the request to the board's per
5462
     * target waiting list.
5463
     *
5464
     * If an error occurred, the request will have been placed on the
5465
     * board's 'done' queue and must be completed before returning.
5466
     */
5467
    scp->scsi_done = done;
5468
    switch (asc_execute_scsi_cmnd(scp)) {
5469
    case ASC_NOERROR:
5470
        break;
5471
    case ASC_BUSY:
5472
        asc_enqueue(&boardp->waiting, scp, ASC_BACK);
5473
        break;
5474
    case ASC_ERROR:
5475
    default:
5476
        done_scp = asc_dequeue_list(&boardp->done, NULL, ASC_TID_ALL);
5477
        /* Interrupts could be enabled here. */
5478
        asc_scsi_done_list(done_scp);
5479
        break;
5480
    }
5481
 
5482
    restore_flags(flags);
5483
    return 0;
5484
}
5485
 
5486
/*
5487
 * advansys_abort()
5488
 *
5489
 * Abort the command specified by 'scp'.
5490
 */
5491
int
5492
advansys_abort(Scsi_Cmnd *scp)
5493
{
5494
    struct Scsi_Host    *shp;
5495
    asc_board_t         *boardp;
5496
    ASC_DVC_VAR         *asc_dvc_varp;
5497
    ADV_DVC_VAR         *adv_dvc_varp;
5498
    int                 flags;
5499
    int                 do_scsi_done;
5500
    int                 scp_found;
5501
    Scsi_Cmnd           *done_scp = NULL;
5502
    int                 ret;
5503
 
5504
    /* Save current flags and disable interrupts. */
5505
    save_flags(flags);
5506
    cli();
5507
 
5508
    ASC_DBG1(1, "advansys_abort: scp %x\n", (unsigned) scp);
5509
 
5510
#ifdef ADVANSYS_STATS
5511
    if (scp->host != NULL) {
5512
        ASC_STATS(scp->host, abort);
5513
    }
5514
#endif /* ADVANSYS_STATS */
5515
 
5516
#ifdef ADVANSYS_ASSERT
5517
    do_scsi_done = ASC_ERROR;
5518
    scp_found = ASC_ERROR;
5519
    ret = ASC_ERROR;
5520
#endif /* ADVANSYS_ASSERT */
5521
 
5522
#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
5523
    if (scp->serial_number != scp->serial_number_at_timeout) {
5524
        ASC_PRINT1(
5525
"advansys_abort: timeout serial number changed for request %x\n",
5526
            (unsigned) scp);
5527
        do_scsi_done = ASC_FALSE;
5528
        scp_found = ASC_FALSE;
5529
        ret = SCSI_ABORT_NOT_RUNNING;
5530
    } else
5531
#endif /* version >= v1.3.89 */
5532
    if ((shp = scp->host) == NULL) {
5533
        scp->result = HOST_BYTE(DID_ERROR);
5534
        do_scsi_done = ASC_TRUE;
5535
        scp_found = ASC_FALSE;
5536
        ret = SCSI_ABORT_ERROR;
5537
    } else if ((boardp = ASC_BOARDP(shp))->flags &
5538
                (ASC_HOST_IN_RESET | ASC_HOST_IN_ABORT)) {
5539
        ASC_PRINT2(
5540
"advansys_abort: board %d: Nested host reset or abort, flags 0x%x\n",
5541
            boardp->id, boardp->flags);
5542
        do_scsi_done = ASC_TRUE;
5543
        if ((asc_rmqueue(&boardp->active, scp) == ASC_TRUE) ||
5544
            (asc_rmqueue(&boardp->waiting, scp) == ASC_TRUE)) {
5545
            scp_found = ASC_TRUE;
5546
        } else {
5547
            scp_found = ASC_FALSE;
5548
        }
5549
        scp->result = HOST_BYTE(DID_ERROR);
5550
        ret = SCSI_ABORT_ERROR;
5551
    } else {
5552
        /* Set abort flag to avoid nested reset or abort requests. */
5553
        boardp->flags |= ASC_HOST_IN_ABORT;
5554
 
5555
        do_scsi_done = ASC_TRUE;
5556
        if (asc_rmqueue(&boardp->waiting, scp) == ASC_TRUE) {
5557
            /*
5558
             * If asc_rmqueue() found the command on the waiting
5559
             * queue, it had not been sent to the device. After
5560
             * the queue is removed, no other handling is required.
5561
             */
5562
            ASC_DBG1(1, "advansys_abort: scp %x found on waiting queue\n",
5563
                (unsigned) scp);
5564
            scp_found = ASC_TRUE;
5565
            scp->result = HOST_BYTE(DID_ABORT);
5566
            ret = SCSI_ABORT_SUCCESS;
5567
        } else if (asc_isqueued(&boardp->active, scp) == ASC_TRUE) {
5568
            /*
5569
             * If asc_isqueued() found the command on the active
5570
             * queue, it has been sent to the device. The command
5571
             * will be returned through the interrupt handler after
5572
             * it has been aborted.
5573
             */
5574
 
5575
            if (ASC_NARROW_BOARD(boardp)) {
5576
                /*
5577
                 * Narrow Board
5578
                 */
5579
                asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
5580
                scp->result = HOST_BYTE(DID_ABORT);
5581
 
5582
                sti(); /* Enable interrupts for AscAbortSRB(). */
5583
                ASC_DBG1(1, "advansys_abort: before AscAbortSRB(), scp %x\n",
5584
                    (unsigned) scp);
5585
                switch (AscAbortSRB(asc_dvc_varp, (ulong) scp)) {
5586
                case ASC_TRUE:
5587
                    /* asc_isr_callback() will be called */
5588
                    ASC_DBG(1, "advansys_abort: AscAbortSRB() TRUE\n");
5589
                    ret = SCSI_ABORT_PENDING;
5590
                    break;
5591
                case ASC_FALSE:
5592
                    /* Request has apparently already completed. */
5593
                    ASC_DBG(1, "advansys_abort: AscAbortSRB() FALSE\n");
5594
                    ret = SCSI_ABORT_NOT_RUNNING;
5595
                    break;
5596
                case ASC_ERROR:
5597
                default:
5598
                    ASC_DBG(1, "advansys_abort: AscAbortSRB() ERROR\n");
5599
                    ret = SCSI_ABORT_ERROR;
5600
                    break;
5601
                }
5602
                cli();
5603
            } else {
5604
                /*
5605
                 * Wide Board
5606
                 */
5607
                adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
5608
                scp->result = HOST_BYTE(DID_ABORT);
5609
 
5610
                ASC_DBG1(1, "advansys_abort: before AdvAbortSRB(), scp %x\n",
5611
                    (unsigned) scp);
5612
                switch (AdvAbortSRB(adv_dvc_varp, (ulong) scp)) {
5613
                case ASC_TRUE:
5614
                    /* asc_isr_callback() will be called */
5615
                    ASC_DBG(1, "advansys_abort: AdvAbortSRB() TRUE\n");
5616
                    ret = SCSI_ABORT_PENDING;
5617
                    break;
5618
                case ASC_FALSE:
5619
                    /* Request has apparently already completed. */
5620
                    ASC_DBG(1, "advansys_abort: AdvAbortSRB() FALSE\n");
5621
                    ret = SCSI_ABORT_NOT_RUNNING;
5622
                    break;
5623
                case ASC_ERROR:
5624
                default:
5625
                    ASC_DBG(1, "advansys_abort: AdvAbortSRB() ERROR\n");
5626
                    ret = SCSI_ABORT_ERROR;
5627
                    break;
5628
                }
5629
                /*
5630
                 * Ensure all requests completed by the microcode have
5631
                 * been processed by calling AdvISR().
5632
                 */
5633
                (void) AdvISR(adv_dvc_varp);
5634
            }
5635
 
5636
            /*
5637
             * The request will either still be on the active queue
5638
             * or have been added to the board's done queue.
5639
             */
5640
            if (asc_rmqueue(&boardp->active, scp) == ASC_TRUE) {
5641
                scp->result = HOST_BYTE(DID_ABORT);
5642
                scp_found = ASC_TRUE;
5643
            } else {
5644
                scp_found = asc_rmqueue(&boardp->done, scp);
5645
                ASC_ASSERT(scp_found == ASC_TRUE);
5646
            }
5647
 
5648
        } else {
5649
            /*
5650
             * The command was not found on the active or waiting queues.
5651
             */
5652
            do_scsi_done = ASC_TRUE;
5653
            scp_found = ASC_FALSE;
5654
            ret = SCSI_ABORT_NOT_RUNNING;
5655
        }
5656
 
5657
        /* Clear abort flag. */
5658
        boardp->flags &= ~ASC_HOST_IN_ABORT;
5659
 
5660
        /*
5661
         * Because the ASC_HOST_IN_ABORT flag causes both
5662
         * 'advansys_interrupt' and 'asc_isr_callback' to
5663
         * queue requests to the board's 'done' queue and
5664
         * prevents waiting commands from being executed,
5665
         * these queued requests must be handled here.
5666
         */
5667
        done_scp = asc_dequeue_list(&boardp->done, NULL, ASC_TID_ALL);
5668
 
5669
        /*
5670
         * Start any waiting commands for the board.
5671
         */
5672
        if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
5673
            ASC_DBG(1, "advansys_interrupt: before asc_execute_queue()\n");
5674
            asc_execute_queue(&boardp->waiting);
5675
        }
5676
    }
5677
 
5678
    /* Interrupts could be enabled here. */
5679
 
5680
    /*
5681
     * Complete the request to be aborted, unless it has been
5682
     * restarted as detected above, even if it was not found on
5683
     * the device active or waiting queues.
5684
     */
5685
    ASC_ASSERT(do_scsi_done != ASC_ERROR);
5686
    ASC_ASSERT(scp_found != ASC_ERROR);
5687
    if (do_scsi_done == ASC_TRUE) {
5688
        if (scp->scsi_done == NULL) {
5689
            ASC_PRINT1(
5690
"advansys_abort: aborted request scsi_done() is NULL, %x\n",
5691
                (unsigned) scp);
5692
        } else {
5693
            if (scp_found == ASC_FALSE) {
5694
                ASC_PRINT1(
5695
"advansys_abort: abort request not active or waiting, completing anyway %x\n",
5696
                    (unsigned) scp);
5697
            }
5698
            ASC_STATS(scp->host, done);
5699
            scp->scsi_done(scp);
5700
        }
5701
    }
5702
 
5703
    /*
5704
     * It is possible for the request done function to re-enable
5705
     * interrupts without confusing the driver. But here interrupts
5706
     * aren't enabled until all requests have been completed.
5707
     */
5708
    if (done_scp != NULL) {
5709
        asc_scsi_done_list(done_scp);
5710
    }
5711
 
5712
    ASC_DBG1(1, "advansys_abort: ret %d\n", ret);
5713
 
5714
    /* Re-enable interrupts, if they were enabled on entry. */
5715
    restore_flags(flags);
5716
 
5717
    ASC_ASSERT(ret != ASC_ERROR);
5718
    return ret;
5719
}
5720
 
5721
/*
5722
 * advansys_reset()
5723
 *
5724
 * Reset the device associated with the command 'scp'.
5725
 */
5726
int
5727
#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,89)
5728
advansys_reset(Scsi_Cmnd *scp)
5729
#else /* version >= v1.3.89 */
5730
advansys_reset(Scsi_Cmnd *scp, unsigned int reset_flags)
5731
#endif /* version >= v1.3.89 */
5732
{
5733
    struct Scsi_Host     *shp;
5734
    asc_board_t          *boardp;
5735
    ASC_DVC_VAR          *asc_dvc_varp;
5736
    ADV_DVC_VAR          *adv_dvc_varp;
5737
    int                  flags;
5738
    Scsi_Cmnd            *done_scp = NULL, *last_scp = NULL;
5739
    Scsi_Cmnd            *tscp, *new_last_scp;
5740
    int                  do_scsi_done;
5741
    int                  scp_found;
5742
    int                  status;
5743
    int                  target;
5744
    int                  ret;
5745
    int                  device_reset = ASC_FALSE;
5746
 
5747
    /* Save current flags and disable interrupts. */
5748
    save_flags(flags);
5749
    cli();
5750
 
5751
    ASC_DBG1(1, "advansys_reset: %x\n", (unsigned) scp);
5752
 
5753
#ifdef ADVANSYS_STATS
5754
    if (scp->host != NULL) {
5755
        ASC_STATS(scp->host, reset);
5756
    }
5757
#endif /* ADVANSYS_STATS */
5758
 
5759
#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
5760
    if ((reset_flags & SCSI_RESET_ASYNCHRONOUS) &&
5761
        (scp->serial_number != scp->serial_number_at_timeout)) {
5762
        ASC_PRINT1(
5763
"advansys_reset: timeout serial number changed for request %x\n",
5764
            (unsigned) scp);
5765
        do_scsi_done = ASC_FALSE;
5766
        scp_found = ASC_FALSE;
5767
        ret = SCSI_RESET_NOT_RUNNING;
5768
    } else
5769
#endif /* version >= v1.3.89 */
5770
    if ((shp = scp->host) == NULL) {
5771
        scp->result = HOST_BYTE(DID_ERROR);
5772
        do_scsi_done = ASC_TRUE;
5773
        scp_found = ASC_FALSE;
5774
        ret = SCSI_RESET_ERROR;
5775
    } else if ((boardp = ASC_BOARDP(shp))->flags &
5776
                (ASC_HOST_IN_RESET | ASC_HOST_IN_ABORT)) {
5777
        ASC_PRINT2(
5778
"advansys_reset: board %d: Nested host reset or abort, flags 0x%x\n",
5779
            boardp->id, boardp->flags);
5780
        do_scsi_done = ASC_TRUE;
5781
        if ((asc_rmqueue(&boardp->active, scp) == ASC_TRUE) ||
5782
            (asc_rmqueue(&boardp->waiting, scp) == ASC_TRUE)) {
5783
            scp_found = ASC_TRUE;
5784
        } else {
5785
            scp_found = ASC_FALSE;
5786
        }
5787
        scp->result = HOST_BYTE(DID_ERROR);
5788
        ret = SCSI_RESET_ERROR;
5789
    } else if (jiffies >= boardp->last_reset &&
5790
               jiffies < (boardp->last_reset + (10 * HZ))) {
5791
        /*
5792
         * Don't allow a reset to be attempted within 10 seconds
5793
         * of the last reset.
5794
         *
5795
         * If 'jiffies' wrapping occurs, the reset request will go
5796
         * through, because a wrapped 'jiffies' would not pass the
5797
         * test above.
5798
         */
5799
        ASC_DBG(1,
5800
            "advansys_reset: reset within 10 sec of last reset ignored\n");
5801
        do_scsi_done = ASC_TRUE;
5802
        if ((asc_rmqueue(&boardp->active, scp) == ASC_TRUE) ||
5803
            (asc_rmqueue(&boardp->waiting, scp) == ASC_TRUE)) {
5804
            scp_found = ASC_TRUE;
5805
        } else {
5806
            scp_found = ASC_FALSE;
5807
        }
5808
        scp->result = HOST_BYTE(DID_ERROR);
5809
        ret = SCSI_RESET_ERROR;
5810
    } else {
5811
        do_scsi_done = ASC_TRUE;
5812
 
5813
        /* Set reset flag to avoid nested reset or abort requests. */
5814
        boardp->flags |= ASC_HOST_IN_RESET;
5815
 
5816
        /*
5817
          * If the request is on the target waiting or active queue
5818
         * or the board done queue, then remove it and note that it
5819
         * was found.
5820
         */
5821
        if (asc_rmqueue(&boardp->active, scp) == ASC_TRUE) {
5822
            ASC_DBG(1, "advansys_reset: active scp_found = TRUE\n");
5823
            scp_found = ASC_TRUE;
5824
        } else if (asc_rmqueue(&boardp->waiting, scp) == ASC_TRUE) {
5825
            ASC_DBG(1, "advansys_reset: waiting scp_found = TRUE\n");
5826
            scp_found = ASC_TRUE;
5827
        } else if (asc_rmqueue(&boardp->done, scp) == ASC_TRUE) {
5828
            scp_found = ASC_TRUE;
5829
        } else {
5830
            scp_found = ASC_FALSE;
5831
        }
5832
 
5833
 
5834
        if (ASC_NARROW_BOARD(boardp)) {
5835
            /*
5836
             * Narrow Board
5837
             *
5838
             * If the suggest reset bus flags are set, then reset the bus.
5839
             * Otherwise only reset the device.
5840
             */
5841
            asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
5842
#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
5843
            if (reset_flags &
5844
                (SCSI_RESET_SUGGEST_BUS_RESET |
5845
                 SCSI_RESET_SUGGEST_HOST_RESET)) {
5846
#endif /* version >= v1.3.89 */
5847
 
5848
                /*
5849
                 * Reset the target's SCSI bus.
5850
                 */
5851
                ASC_DBG(1, "advansys_reset: before AscResetSB()\n");
5852
                sti();    /* Enable interrupts for AscResetSB(). */
5853
                status = AscResetSB(asc_dvc_varp);
5854
                cli();
5855
                switch (status) {
5856
                case ASC_TRUE:
5857
                    ASC_DBG(1, "advansys_reset: AscResetSB() success\n");
5858
                    ret = SCSI_RESET_SUCCESS;
5859
                    break;
5860
                case ASC_ERROR:
5861
                default:
5862
                    ASC_DBG(1, "advansys_reset: AscResetSB() failed\n");
5863
                    ret = SCSI_RESET_ERROR;
5864
                    break;
5865
                }
5866
 
5867
#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
5868
            } else {
5869
                /*
5870
                 * Reset the specified device. If the device reset fails,
5871
                 * then reset the SCSI bus.
5872
                 */
5873
 
5874
                ASC_DBG1(1,
5875
                    "advansys_reset: before AscResetDevice(), target %d\n",
5876
                    scp->target);
5877
                sti();    /* Enable interrupts for AscResetDevice(). */
5878
                status = AscResetDevice(asc_dvc_varp, scp->target);
5879
                cli();
5880
 
5881
                switch (status) {
5882
                case ASC_TRUE:
5883
                    ASC_DBG(1, "advansys_reset: AscResetDevice() success\n");
5884
                    device_reset = ASC_TRUE;
5885
                    ret = SCSI_RESET_SUCCESS;
5886
                    break;
5887
                case ASC_ERROR:
5888
                default:
5889
                    ASC_DBG(1,
5890
"advansys_reset: AscResetDevice() failed; Calling AscResetSB()\n");
5891
                    sti();    /* Enable interrupts for AscResetSB(). */
5892
                    status = AscResetSB(asc_dvc_varp);
5893
                    cli();
5894
                    switch (status) {
5895
                    case ASC_TRUE:
5896
                        ASC_DBG(1, "advansys_reset: AscResetSB() TRUE\n");
5897
                        ret = SCSI_RESET_SUCCESS;
5898
                        break;
5899
                    case ASC_ERROR:
5900
                    default:
5901
                        ASC_DBG(1, "advansys_reset: AscResetSB() ERROR\n");
5902
                        ret = SCSI_RESET_ERROR;
5903
                        break;
5904
                    }
5905
                    break;
5906
                }
5907
            }
5908
#endif /* version >= v1.3.89 */
5909
        } else {
5910
            /*
5911
             * Wide Board
5912
             *
5913
             * If the suggest reset bus flags are set, then reset the bus.
5914
             * Otherwise only reset the device.
5915
             */
5916
            adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
5917
#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
5918
            if (reset_flags &
5919
                (SCSI_RESET_SUGGEST_BUS_RESET |
5920
                 SCSI_RESET_SUGGEST_HOST_RESET)) {
5921
#endif /* version >= v1.3.89 */
5922
 
5923
                /*
5924
                 * Reset the target's SCSI bus.
5925
                 */
5926
                ASC_DBG(1, "advansys_reset: before AdvResetSB()\n");
5927
                switch (AdvResetSB(adv_dvc_varp)) {
5928
                case ASC_TRUE:
5929
                    ASC_DBG(1, "advansys_reset: AdvResetSB() success\n");
5930
                    ret = SCSI_RESET_SUCCESS;
5931
                    break;
5932
                case ASC_FALSE:
5933
                default:
5934
                    ASC_DBG(1, "advansys_reset: AdvResetSB() failed\n");
5935
                    ret = SCSI_RESET_ERROR;
5936
                    break;
5937
                }
5938
                /*
5939
                 * Ensure all requests completed by the microcode have
5940
                 * been processed by calling AdvISR().
5941
                 */
5942
                (void) AdvISR(adv_dvc_varp);
5943
#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
5944
            } else {
5945
                /*
5946
                 * Reset the specified device. If the device reset fails,
5947
                 * then reset the SCSI bus.
5948
                 */
5949
 
5950
                ASC_DBG1(1,
5951
                    "advansys_reset: before AdvResetDevice(), target %d\n",
5952
                    scp->target);
5953
 
5954
                switch (AdvResetDevice(adv_dvc_varp, scp->target)) {
5955
                case ASC_TRUE:
5956
                    ASC_DBG(1, "advansys_reset: AdvResetDevice() success\n");
5957
                    device_reset = ASC_TRUE;
5958
                    ret = SCSI_RESET_SUCCESS;
5959
                    break;
5960
                case ASC_FALSE:
5961
                default:
5962
                    ASC_DBG(1,
5963
"advansys_reset: AdvResetDevice() failed; Calling AdvResetSB()\n");
5964
 
5965
                    switch (AdvResetSB(adv_dvc_varp)) {
5966
                    case ASC_TRUE:
5967
                        ASC_DBG(1, "advansys_reset: AdvResetSB() TRUE\n");
5968
                        ret = SCSI_RESET_SUCCESS;
5969
                        break;
5970
                    case ASC_FALSE:
5971
                    default:
5972
                        ASC_DBG(1, "advansys_reset: AdvResetSB() ERROR\n");
5973
                        ret = SCSI_RESET_ERROR;
5974
                        break;
5975
                    }
5976
                    break;
5977
                }
5978
                /*
5979
                 * Ensure all requests completed by the microcode have
5980
                 * been processed by calling AdvISR().
5981
                 */
5982
                (void) AdvISR(adv_dvc_varp);
5983
            }
5984
#endif /* version >= v1.3.89 */
5985
        }
5986
 
5987
        /*
5988
         * Because the ASC_HOST_IN_RESET flag causes both
5989
         * 'advansys_interrupt' and 'asc_isr_callback' to
5990
         * queue requests to the board's 'done' queue and
5991
         * prevents waiting commands from being executed,
5992
         * these queued requests must be handled here.
5993
         */
5994
        done_scp = asc_dequeue_list(&boardp->done, &last_scp,
5995
                                    ASC_TID_ALL);
5996
 
5997
        /*
5998
         * If a device reset was performed dequeue all waiting
5999
         * and active requests for the device and set the request
6000
         * status to DID_RESET.
6001
         *
6002
         * If a SCSI bus reset was performed dequeue all waiting
6003
         * and active requests for all devices and set the request
6004
         * status to DID_RESET.
6005
         */
6006
        if (device_reset == ASC_TRUE) {
6007
            target = scp->target;
6008
        } else {
6009
            target = ASC_TID_ALL;
6010
        }
6011
 
6012
        /*
6013
         * Add active requests to 'done_scp' and set the request status
6014
         * to DID_RESET.
6015
         */
6016
        if (done_scp == NULL) {
6017
            done_scp = asc_dequeue_list(&boardp->active, &last_scp, target);
6018
            for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) {
6019
                tscp->result = HOST_BYTE(DID_RESET);
6020
            }
6021
        } else {
6022
            ASC_ASSERT(last_scp != NULL);
6023
            REQPNEXT(last_scp) = asc_dequeue_list(&boardp->active,
6024
                &new_last_scp, target);
6025
            if (new_last_scp != NULL) {
6026
                ASC_ASSERT(REQPNEXT(last_scp) != NULL);
6027
                for (tscp = REQPNEXT(last_scp); tscp; tscp = REQPNEXT(tscp)) {
6028
                    tscp->result = HOST_BYTE(DID_RESET);
6029
                }
6030
                last_scp = new_last_scp;
6031
            }
6032
        }
6033
 
6034
        /*
6035
         * Add waiting requests to 'done_scp' and set the request status
6036
         * to DID_RESET.
6037
         */
6038
        if (done_scp == NULL) {
6039
            done_scp = asc_dequeue_list(&boardp->waiting, &last_scp, target);
6040
            for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) {
6041
                tscp->result = HOST_BYTE(DID_RESET);
6042
            }
6043
        } else {
6044
            ASC_ASSERT(last_scp != NULL);
6045
            REQPNEXT(last_scp) = asc_dequeue_list(&boardp->waiting,
6046
                &new_last_scp, target);
6047
            if (new_last_scp != NULL) {
6048
                ASC_ASSERT(REQPNEXT(last_scp) != NULL);
6049
                for (tscp = REQPNEXT(last_scp); tscp; tscp = REQPNEXT(tscp)) {
6050
                    tscp->result = HOST_BYTE(DID_RESET);
6051
                }
6052
                last_scp = new_last_scp;
6053
            }
6054
        }
6055
 
6056
        /* Save the time of the most recently completed reset. */
6057
        boardp->last_reset = jiffies;
6058
 
6059
        /* Clear reset flag. */
6060
        boardp->flags &= ~ASC_HOST_IN_RESET;
6061
 
6062
        /*
6063
         * Start any waiting commands for the board.
6064
         */
6065
        if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
6066
            ASC_DBG(1, "advansys_interrupt: before asc_execute_queue()\n");
6067
            asc_execute_queue(&boardp->waiting);
6068
        }
6069
        ret = SCSI_RESET_SUCCESS;
6070
    }
6071
 
6072
    /* Interrupts could be enabled here. */
6073
 
6074
    ASC_ASSERT(do_scsi_done != ASC_ERROR);
6075
    ASC_ASSERT(scp_found != ASC_ERROR);
6076
    if (do_scsi_done == ASC_TRUE) {
6077
        if (scp->scsi_done == NULL) {
6078
            ASC_PRINT1(
6079
"advansys_reset: reset request scsi_done() is NULL, %x\n",
6080
                (unsigned) scp);
6081
        } else {
6082
            if (scp_found == ASC_FALSE) {
6083
                ASC_PRINT1(
6084
"advansys_reset: reset request not active or waiting, completing anyway %x\n",
6085
                    (unsigned) scp);
6086
            }
6087
            ASC_STATS(scp->host, done);
6088
            scp->scsi_done(scp);
6089
        }
6090
    }
6091
 
6092
    /*
6093
     * It is possible for the request done function to re-enable
6094
     * interrupts without confusing the driver. But here interrupts
6095
     * aren't enabled until requests have been completed.
6096
     */
6097
    if (done_scp != NULL) {
6098
        asc_scsi_done_list(done_scp);
6099
    }
6100
 
6101
    ASC_DBG1(1, "advansys_reset: ret %d\n", ret);
6102
 
6103
    /* Re-enable interrupts, if they were enabled on entry. */
6104
    restore_flags(flags);
6105
 
6106
    ASC_ASSERT(ret != ASC_ERROR);
6107
    return ret;
6108
}
6109
 
6110
/*
6111
 * advansys_biosparam()
6112
 *
6113
 * Translate disk drive geometry if the "BIOS greater than 1 GB"
6114
 * support is enabled for a drive.
6115
 *
6116
 * ip (information pointer) is an int array with the following definition:
6117
 * ip[0]: heads
6118
 * ip[1]: sectors
6119
 * ip[2]: cylinders
6120
 */
6121
int
6122
#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0)
6123
advansys_biosparam(Disk *dp, int dep, int ip[])
6124
#else /* version >= v1.3.0 */
6125
advansys_biosparam(Disk *dp, kdev_t dep, int ip[])
6126
#endif /* version >= v1.3.0 */
6127
{
6128
    asc_board_t     *boardp;
6129
 
6130
    ASC_DBG(1, "advansys_biosparam: begin\n");
6131
    ASC_STATS(dp->device->host, biosparam);
6132
    boardp = ASC_BOARDP(dp->device->host);
6133
    if (ASC_NARROW_BOARD(boardp)) {
6134
        if ((boardp->dvc_var.asc_dvc_var.dvc_cntl &
6135
             ASC_CNTL_BIOS_GT_1GB) && dp->capacity > 0x200000) {
6136
                ip[0] = 255;
6137
                ip[1] = 63;
6138
        } else {
6139
                ip[0] = 64;
6140
                ip[1] = 32;
6141
        }
6142
    } else {
6143
        if ((boardp->dvc_var.adv_dvc_var.bios_ctrl &
6144
             BIOS_CTRL_EXTENDED_XLAT) && dp->capacity > 0x200000) {
6145
                ip[0] = 255;
6146
                ip[1] = 63;
6147
        } else {
6148
                ip[0] = 64;
6149
                ip[1] = 32;
6150
        }
6151
    }
6152
    ip[2] = dp->capacity / (ip[0] * ip[1]);
6153
    ASC_DBG(1, "advansys_biosparam: end\n");
6154
    return 0;
6155
}
6156
 
6157
/*
6158
 * advansys_setup()
6159
 *
6160
 * This function is called from init/main.c at boot time.
6161
 * It it passed LILO parameters that can be set from the
6162
 * LILO command line or in /etc/lilo.conf.
6163
 *
6164
 * It is used by the AdvanSys driver to either disable I/O
6165
 * port scanning or to limit scanning to 1 - 4 I/O ports.
6166
 * Regardless of the option setting EISA and PCI boards
6167
 * will still be searched for and detected. This option
6168
 * only affects searching for ISA and VL boards.
6169
 *
6170
 * If ADVANSYS_DEBUG is defined the driver debug level may
6171
 * be set using the 5th (ASC_NUM_IOPORT_PROBE + 1) I/O Port.
6172
 *
6173
 * Examples:
6174
 * 1. Eliminate I/O port scanning:
6175
 *         boot: linux advansys=
6176
 *       or
6177
 *         boot: linux advansys=0x0
6178
 * 2. Limit I/O port scanning to one I/O port:
6179
 *        boot: linux advansys=0x110
6180
 * 3. Limit I/O port scanning to four I/O ports:
6181
 *        boot: linux advansys=0x110,0x210,0x230,0x330
6182
 * 4. If ADVANSYS_DEBUG, limit I/O port scanning to four I/O ports and
6183
 *    set the driver debug level to 2.
6184
 *        boot: linux advansys=0x110,0x210,0x230,0x330,0xdeb2
6185
 *
6186
 * ints[0] - number of arguments
6187
 * ints[1] - first argument
6188
 * ints[2] - second argument
6189
 * ...
6190
 */
6191
ASC_INITFUNC(
6192
void
6193
advansys_setup(char *str, int *ints)
6194
)
6195
{
6196
    int    i;
6197
 
6198
    if (asc_iopflag == ASC_TRUE) {
6199
        printk("AdvanSys SCSI: 'advansys' LILO option may appear only once\n");
6200
        return;
6201
    }
6202
 
6203
    asc_iopflag = ASC_TRUE;
6204
 
6205
    if (ints[0] > ASC_NUM_IOPORT_PROBE) {
6206
#ifdef ADVANSYS_DEBUG
6207
        if ((ints[0] == ASC_NUM_IOPORT_PROBE + 1) &&
6208
            (ints[ASC_NUM_IOPORT_PROBE + 1] >> 4 == 0xdeb)) {
6209
            asc_dbglvl = ints[ASC_NUM_IOPORT_PROBE + 1] & 0xf;
6210
        } else {
6211
#endif /* ADVANSYS_DEBUG */
6212
            printk("AdvanSys SCSI: only %d I/O ports accepted\n",
6213
                ASC_NUM_IOPORT_PROBE);
6214
#ifdef ADVANSYS_DEBUG
6215
        }
6216
#endif /* ADVANSYS_DEBUG */
6217
    }
6218
 
6219
#ifdef ADVANSYS_DEBUG
6220
    ASC_DBG1(1, "advansys_setup: ints[0] %d\n", ints[0]);
6221
    for (i = 1; i < ints[0]; i++) {
6222
        ASC_DBG2(1, " ints[%d] %x", i, ints[i]);
6223
    }
6224
    ASC_DBG(1, "\n");
6225
#endif /* ADVANSYS_DEBUG */
6226
 
6227
    for (i = 1; i <= ints[0] && i <= ASC_NUM_IOPORT_PROBE; i++) {
6228
        asc_ioport[i-1] = ints[i];
6229
        ASC_DBG2(1, "advansys_setup: asc_ioport[%d] %x\n",
6230
            i - 1, asc_ioport[i-1]);
6231
    }
6232
}
6233
 
6234
 
6235
/*
6236
 * --- Loadable Driver Support
6237
 */
6238
 
6239
#ifdef MODULE
6240
Scsi_Host_Template driver_template = ADVANSYS;
6241
# include "scsi_module.c"
6242
#endif /* MODULE */
6243
 
6244
 
6245
/*
6246
 * --- Miscellaneous Driver Functions
6247
 */
6248
 
6249
/*
6250
 * First-level interrupt handler.
6251
 *
6252
 * For versions > v1.3.70, 'dev_id' is a pointer to the interrupting
6253
 * adapter's asc_board_t. Because all boards are currently checked
6254
 * for interrupts on each interrupt, 'dev_id' is not referenced. 'dev_id'
6255
 * could be used to identify an interrupt passed to the AdvanSys driver,
6256
 * which is for a device sharing an interrupt with an AdvanSys adapter.
6257
 */
6258
STATIC void
6259
#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,70)
6260
advansys_interrupt(int irq, struct pt_regs *regs)
6261
#else /* version >= v1.3.70 */
6262
advansys_interrupt(int irq, void *dev_id, struct pt_regs *regs)
6263
#endif /* version >= v1.3.70 */
6264
{
6265
#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,95)
6266
    int             flags;
6267
#else /* version >= v2.1.95 */
6268
    unsigned long   flags;
6269
#endif /* version >= v2.1.95 */
6270
    int             i;
6271
    asc_board_t     *boardp;
6272
    Scsi_Cmnd       *done_scp = NULL, *last_scp = NULL;
6273
    Scsi_Cmnd       *new_last_scp;
6274
 
6275
#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,95)
6276
    /* Disable interrupts, if they aren't already disabled. */
6277
    save_flags(flags);
6278
    cli();
6279
#else /* version >= v2.1.95 */
6280
    /*
6281
     * Disable interrupts, if they aren't already disabled and acquire
6282
     * the I/O spinlock.
6283
     */
6284
    spin_lock_irqsave(&io_request_lock, flags);
6285
#endif /* version >= v2.1.95 */
6286
 
6287
    ASC_DBG(1, "advansys_interrupt: begin\n");
6288
 
6289
    /*
6290
     * Check for interrupts on all boards.
6291
     * AscISR() will call asc_isr_callback().
6292
     */
6293
    for (i = 0; i < asc_board_count; i++) {
6294
        boardp = ASC_BOARDP(asc_host[i]);
6295
        ASC_DBG2(2, "advansys_interrupt: i %d, boardp %lx\n",
6296
            i, (ulong) boardp)
6297
        if (ASC_NARROW_BOARD(boardp)) {
6298
            /*
6299
             * Narrow Board
6300
             */
6301
            if (AscIsIntPending(asc_host[i]->io_port)) {
6302
                ASC_STATS(asc_host[i], interrupt);
6303
                ASC_DBG(1, "advansys_interrupt: before AscISR()\n");
6304
                AscISR(&boardp->dvc_var.asc_dvc_var);
6305
            }
6306
        } else {
6307
            /*
6308
             * Wide Board
6309
             */
6310
            ASC_DBG(1, "advansys_interrupt: before AdvISR()\n");
6311
            if (AdvISR(&boardp->dvc_var.adv_dvc_var)) {
6312
                ASC_STATS(asc_host[i], interrupt);
6313
            }
6314
        }
6315
 
6316
        /*
6317
         * Start waiting requests and create a list of completed requests.
6318
         *
6319
         * If a reset or abort request is being performed for the board,
6320
         * the reset or abort handler will complete pending requests after
6321
         * it has completed.
6322
         */
6323
        if ((boardp->flags & (ASC_HOST_IN_RESET | ASC_HOST_IN_ABORT)) == 0) {
6324
            ASC_DBG2(1, "advansys_interrupt: done_scp %lx, last_scp %lx\n",
6325
                (ulong) done_scp, (ulong) last_scp);
6326
 
6327
            /* Start any waiting commands for the board. */
6328
            if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
6329
                ASC_DBG(1, "advansys_interrupt: before asc_execute_queue()\n");
6330
                asc_execute_queue(&boardp->waiting);
6331
            }
6332
 
6333
             /*
6334
              * Add to the list of requests that must be completed.
6335
              *
6336
              * 'done_scp' will always be NULL on the first iteration
6337
              * of this loop. 'last_scp' is set at the same time as
6338
              * 'done_scp'.
6339
              */
6340
            if (done_scp == NULL) {
6341
                done_scp = asc_dequeue_list(&boardp->done, &last_scp,
6342
                    ASC_TID_ALL);
6343
            } else {
6344
                ASC_ASSERT(last_scp != NULL);
6345
                REQPNEXT(last_scp) = asc_dequeue_list(&boardp->done,
6346
                    &new_last_scp, ASC_TID_ALL);
6347
                if (new_last_scp != NULL) {
6348
                    ASC_ASSERT(REQPNEXT(last_scp) != NULL);
6349
                    last_scp = new_last_scp;
6350
                }
6351
            }
6352
        }
6353
    }
6354
 
6355
    /* Interrupts could be enabled here. */
6356
 
6357
    /*
6358
     * It is possible for the request done function to re-enable
6359
     * interrupts without confusing the driver. But here the
6360
     * original flags aren't restored until all requests have been
6361
     * completed.
6362
     */
6363
    asc_scsi_done_list(done_scp);
6364
 
6365
#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,95)
6366
    /*
6367
     * Restore the original flags which will enable interrupts
6368
     * if and only if they were enabled on entry.
6369
     */
6370
    restore_flags(flags);
6371
#else /* version >= v2.1.95 */
6372
    /*
6373
     * Release the I/O spinlock and restore the original flags
6374
     * which will enable interrupts if and only if they were
6375
     * enabled on entry.
6376
     */
6377
    spin_unlock_irqrestore(&io_request_lock, flags);
6378
#endif /* version >= v2.1.95 */
6379
 
6380
    ASC_DBG(1, "advansys_interrupt: end\n");
6381
    return;
6382
}
6383
 
6384
#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
6385
/*
6386
 * Set the number of commands to queue per device for the
6387
 * specified host adapter.
6388
 */
6389
STATIC void
6390
advansys_select_queue_depths(struct Scsi_Host *shp, Scsi_Device *devicelist)
6391
{
6392
    Scsi_Device        *device;
6393
    asc_board_t        *boardp;
6394
 
6395
    boardp = ASC_BOARDP(shp);
6396
    boardp->flags |= ASC_SELECT_QUEUE_DEPTHS;
6397
    for (device = devicelist; device != NULL; device = device->next) {
6398
        if (device->host != shp) {
6399
            continue;
6400
        }
6401
        /*
6402
         * Save a pointer to the device and set its initial/maximum
6403
         * queue depth.
6404
         */
6405
        boardp->device[device->id] = device;
6406
        if (ASC_NARROW_BOARD(boardp)) {
6407
            device->queue_depth =
6408
                boardp->dvc_var.asc_dvc_var.max_dvc_qng[device->id];
6409
        } else {
6410
            device->queue_depth =
6411
                boardp->dvc_var.adv_dvc_var.max_dvc_qng;
6412
        }
6413
        ASC_DBG3(1, "advansys_select_queue_depths: shp %x, id %d, depth %d\n",
6414
            (unsigned) shp, device->id, device->queue_depth);
6415
    }
6416
}
6417
#endif /* version >= v1.3.89 */
6418
 
6419
/*
6420
 * Function used only with polled I/O requests that are initiated by
6421
 * advansys_command().
6422
 */
6423
STATIC void
6424
advansys_command_done(Scsi_Cmnd *scp)
6425
{
6426
    ASC_DBG1(1, "advansys_command_done: scp %x\n", (unsigned) scp);
6427
    scp->SCp.Status = 1;
6428
}
6429
 
6430
/*
6431
 * Complete all requests on the singly linked list pointed
6432
 * to by 'scp'.
6433
 *
6434
 * Interrupts can be enabled on entry.
6435
 */
6436
STATIC void
6437
asc_scsi_done_list(Scsi_Cmnd *scp)
6438
{
6439
    Scsi_Cmnd    *tscp;
6440
 
6441
    ASC_DBG(2, "asc_scsi_done_list: begin\n");
6442
    while (scp != NULL) {
6443
        ASC_DBG1(3, "asc_scsi_done_list: scp %x\n", (unsigned) scp);
6444
        tscp = REQPNEXT(scp);
6445
        REQPNEXT(scp) = NULL;
6446
        ASC_STATS(scp->host, done);
6447
        ASC_ASSERT(scp->scsi_done != NULL);
6448
        scp->scsi_done(scp);
6449
        scp = tscp;
6450
    }
6451
    ASC_DBG(2, "asc_scsi_done_list: done\n");
6452
    return;
6453
}
6454
 
6455
/*
6456
 * Execute a single 'Scsi_Cmnd'.
6457
 *
6458
 * The function 'done' is called when the request has been completed.
6459
 *
6460
 * Scsi_Cmnd:
6461
 *
6462
 *  host - board controlling device
6463
 *  device - device to send command
6464
 *  target - target of device
6465
 *  lun - lun of device
6466
 *  cmd_len - length of SCSI CDB
6467
 *  cmnd - buffer for SCSI 8, 10, or 12 byte CDB
6468
 *  use_sg - if non-zero indicates scatter-gather request with use_sg elements
6469
 *
6470
 *  if (use_sg == 0) {
6471
 *    request_buffer - buffer address for request
6472
 *    request_bufflen - length of request buffer
6473
 *  } else {
6474
 *    request_buffer - pointer to scatterlist structure
6475
 *  }
6476
 *
6477
 *  sense_buffer - sense command buffer
6478
 *
6479
 *  result (4 bytes of an int):
6480
 *    Byte Meaning
6481
 *    0 SCSI Status Byte Code
6482
 *    1 SCSI One Byte Message Code
6483
 *    2 Host Error Code
6484
 *    3 Mid-Level Error Code
6485
 *
6486
 *  host driver fields:
6487
 *    SCp - Scsi_Pointer used for command processing status
6488
 *    scsi_done - used to save caller's done function
6489
 *    host_scribble - used for pointer to another Scsi_Cmnd
6490
 *
6491
 * If this function returns ASC_NOERROR or ASC_ERROR the request
6492
 * has been enqueued on the board's 'done' queue and must be
6493
 * completed by the caller.
6494
 *
6495
 * If ASC_BUSY is returned the request must be enqueued by the
6496
 * caller and re-tried later.
6497
 */
6498
STATIC int
6499
asc_execute_scsi_cmnd(Scsi_Cmnd *scp)
6500
{
6501
    asc_board_t        *boardp;
6502
    ASC_DVC_VAR        *asc_dvc_varp;
6503
    ADV_DVC_VAR        *adv_dvc_varp;
6504
    ADV_SCSI_REQ_Q     *adv_scsiqp;
6505
    Scsi_Device        *device;
6506
    int                ret;
6507
 
6508
    ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
6509
    ASC_DBG2(1, "asc_execute_scsi_cmnd: scp %x, done %x\n",
6510
        (unsigned) scp, (unsigned) scp->scsi_done);
6511
 
6512
    boardp = ASC_BOARDP(scp->host);
6513
    device = boardp->device[scp->target];
6514
 
6515
    if (ASC_NARROW_BOARD(boardp)) {
6516
        /*
6517
         * Build and execute Narrow Board request.
6518
         */
6519
 
6520
        asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
6521
 
6522
        /*
6523
         * Build Asc Library request structure using the
6524
         * global structures 'asc_scsi_req' and 'asc_sg_head'.
6525
         *
6526
         * asc_build_req() can not return ASC_BUSY.
6527
         */
6528
        if (asc_build_req(boardp, scp) == ASC_ERROR) {
6529
            ASC_STATS(scp->host, build_error);
6530
            return ASC_ERROR;
6531
        }
6532
 
6533
        /*
6534
         * Execute the command. If there is no error, add the command
6535
         * to the active queue.
6536
         */
6537
        switch (ret = AscExeScsiQueue(asc_dvc_varp, &asc_scsi_q)) {
6538
        case ASC_NOERROR:
6539
            ASC_STATS(scp->host, exe_noerror);
6540
            /*
6541
             * Increment monotonically increasing per device successful
6542
             * request counter. Wrapping doesn't matter.
6543
             */
6544
            boardp->reqcnt[scp->target]++;
6545
 
6546
#if ASC_QUEUE_FLOW_CONTROL
6547
            /*
6548
             * Conditionally increment the device queue depth.
6549
             *
6550
             * If no error occurred and there have been 100 consecutive
6551
             * successful requests and the current queue depth is less
6552
             * than the maximum queue depth, then increment the current
6553
             * queue depth.
6554
             */
6555
            if (boardp->nerrcnt[scp->target]++ > 100) {
6556
                boardp->nerrcnt[scp->target] = 0;
6557
                if (device != NULL &&
6558
                    (device->queue_curr_depth < device->queue_depth) &&
6559
                    (!(boardp->queue_full &
6560
                       ADV_TID_TO_TIDMASK(scp->target)) ||
6561
                     (boardp->queue_full_cnt[scp->target] >
6562
                      device->queue_curr_depth))) {
6563
                    device->queue_curr_depth++;
6564
                }
6565
            }
6566
#endif /* ASC_QUEUE_FLOW_CONTROL */
6567
            asc_enqueue(&boardp->active, scp, ASC_BACK);
6568
            ASC_DBG(1,
6569
                "asc_execute_scsi_cmnd: AscExeScsiQueue(), ASC_NOERROR\n");
6570
            break;
6571
        case ASC_BUSY:
6572
            /* Caller must enqueue request and retry later. */
6573
            ASC_STATS(scp->host, exe_busy);
6574
#if ASC_QUEUE_FLOW_CONTROL
6575
            /*
6576
             * Clear consecutive no error counter and if possible decrement
6577
             * queue depth.
6578
             */
6579
            boardp->nerrcnt[scp->target] = 0;
6580
            if (device != NULL && device->queue_curr_depth > 1) {
6581
                device->queue_curr_depth--;
6582
            }
6583
#endif /* ASC_QUEUE_FLOW_CONTROL */
6584
            break;
6585
        case ASC_ERROR:
6586
            ASC_PRINT2(
6587
"asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() ASC_ERROR, err_code %x\n",
6588
                boardp->id, asc_dvc_varp->err_code);
6589
            ASC_STATS(scp->host, exe_error);
6590
#if ASC_QUEUE_FLOW_CONTROL
6591
            /* Clear consecutive no error counter. */
6592
            boardp->nerrcnt[scp->target] = 0;
6593
#endif /* ASC_QUEUE_FLOW_CONTROL */
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 %x\n",
6600
                boardp->id, asc_dvc_varp->err_code);
6601
            ASC_STATS(scp->host, exe_unknown);
6602
#if ASC_QUEUE_FLOW_CONTROL
6603
            /* Clear consecutive no error counter. */
6604
            boardp->nerrcnt[scp->target] = 0;
6605
#endif /* ASC_QUEUE_FLOW_CONTROL */
6606
            scp->result = HOST_BYTE(DID_ERROR);
6607
            asc_enqueue(&boardp->done, scp, ASC_BACK);
6608
            break;
6609
        }
6610
    } else {
6611
        /*
6612
         * Build and execute Wide Board request.
6613
         */
6614
        adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
6615
 
6616
        /*
6617
         * Build and get a pointer to an Adv Library request structure.
6618
         *
6619
         * If the request is successfully built then send  it below,
6620
         * otherwise return with an error.
6621
         */
6622
        switch (adv_build_req(boardp, scp, &adv_scsiqp)) {
6623
        case ASC_NOERROR:
6624
            ASC_DBG(3, "asc_execute_scsi_cmnd: adv_build_req ASC_NOERROR\n");
6625
            break;
6626
        case ASC_BUSY:
6627
            ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req ASC_BUSY\n");
6628
            return ASC_BUSY;
6629
        case ASC_ERROR:
6630
        default:
6631
            ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req ASC_ERROR\n");
6632
            ASC_STATS(scp->host, build_error);
6633
            return ASC_ERROR;
6634
        }
6635
 
6636
        /*
6637
         * Execute the command. If there is no error, add the command
6638
         * to the active queue.
6639
         */
6640
        switch (ret = AdvExeScsiQueue(adv_dvc_varp, adv_scsiqp)) {
6641
        case ASC_NOERROR:
6642
            ASC_STATS(scp->host, exe_noerror);
6643
            /*
6644
             * Increment monotonically increasing per device successful
6645
             * request counter. Wrapping doesn't matter.
6646
             */
6647
            boardp->reqcnt[scp->target]++;
6648
            asc_enqueue(&boardp->active, scp, ASC_BACK);
6649
            ASC_DBG(1,
6650
                "asc_execute_scsi_cmnd: AdvExeScsiQueue(), ASC_NOERROR\n");
6651
            break;
6652
        case ASC_BUSY:
6653
            /* Caller must enqueue request and retry later. */
6654
            ASC_STATS(scp->host, exe_busy);
6655
            break;
6656
        case ASC_ERROR:
6657
            ASC_PRINT2(
6658
"asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() ASC_ERROR, err_code %x\n",
6659
                boardp->id, adv_dvc_varp->err_code);
6660
            ASC_STATS(scp->host, exe_error);
6661
            scp->result = HOST_BYTE(DID_ERROR);
6662
            asc_enqueue(&boardp->done, scp, ASC_BACK);
6663
            break;
6664
        default:
6665
            ASC_PRINT2(
6666
"asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() unknown, err_code %x\n",
6667
                boardp->id, adv_dvc_varp->err_code);
6668
            ASC_STATS(scp->host, exe_unknown);
6669
            scp->result = HOST_BYTE(DID_ERROR);
6670
            asc_enqueue(&boardp->done, scp, ASC_BACK);
6671
            break;
6672
        }
6673
    }
6674
 
6675
    ASC_DBG(1, "asc_execute_scsi_cmnd: end\n");
6676
    ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
6677
    return ret;
6678
}
6679
 
6680
/*
6681
 * Build a request structure for the Asc Library (Narrow Board).
6682
 *
6683
 * The global structures 'asc_scsi_q' and 'asc_sg_head' are
6684
 * used to build the request.
6685
 *
6686
 * If an error occurs, then return ASC_ERROR.
6687
 */
6688
STATIC int
6689
asc_build_req(asc_board_t *boardp, Scsi_Cmnd *scp)
6690
{
6691
    /*
6692
     * Mutually exclusive access is required to 'asc_scsi_q' and
6693
     * 'asc_sg_head' until after the request is started.
6694
     */
6695
    memset(&asc_scsi_q, 0, sizeof(ASC_SCSI_Q));
6696
 
6697
    /*
6698
     * Point the ASC_SCSI_Q to the 'Scsi_Cmnd'.
6699
     */
6700
    asc_scsi_q.q2.srb_ptr = (ulong) scp;
6701
 
6702
    /*
6703
     * Build the ASC_SCSI_Q request.
6704
     */
6705
    ASC_ASSERT(scp->cmd_len <= ASC_MAX_CDB_LEN);
6706
    if (scp->cmd_len > ASC_MAX_CDB_LEN) {
6707
        scp->cmd_len = ASC_MAX_CDB_LEN;
6708
    }
6709
    asc_scsi_q.cdbptr = &scp->cmnd[0];
6710
    asc_scsi_q.q2.cdb_len = scp->cmd_len;
6711
    asc_scsi_q.q1.target_id = ASC_TID_TO_TARGET_ID(scp->target);
6712
    asc_scsi_q.q1.target_lun = scp->lun;
6713
    asc_scsi_q.q2.target_ix = ASC_TIDLUN_TO_IX(scp->target, scp->lun);
6714
#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
6715
    asc_scsi_q.q1.sense_addr = (ulong) &scp->sense_buffer[0];
6716
#else /* version >= v2.0.0 */
6717
    asc_scsi_q.q1.sense_addr = virt_to_bus(&scp->sense_buffer[0]);
6718
#endif /* version >= v2.0.0 */
6719
    asc_scsi_q.q1.sense_len = sizeof(scp->sense_buffer);
6720
 
6721
    /*
6722
     * If there are any outstanding requests for the current target,
6723
     * then every 255th request send an ORDERED request. This heuristic
6724
     * tries to retain the benefit of request sorting while preventing
6725
     * request starvation. 255 is the max number of tags or pending commands
6726
     * a device may have outstanding.
6727
     *
6728
     * The request count is incremented below for every successfully
6729
     * started request.
6730
     *
6731
     */
6732
    if ((boardp->dvc_var.asc_dvc_var.cur_dvc_qng[scp->target] > 0) &&
6733
        (boardp->reqcnt[scp->target] % 255) == 0) {
6734
        asc_scsi_q.q2.tag_code = M2_QTAG_MSG_ORDERED;
6735
    } else {
6736
        asc_scsi_q.q2.tag_code = M2_QTAG_MSG_SIMPLE;
6737
    }
6738
 
6739
    /*
6740
     * Build ASC_SCSI_Q for a contiguous buffer or a scatter-gather
6741
     * buffer command.
6742
     */
6743
    if (scp->use_sg == 0) {
6744
        /*
6745
         * CDB request of single contiguous buffer.
6746
         */
6747
        ASC_STATS(scp->host, cont_cnt);
6748
#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
6749
        asc_scsi_q.q1.data_addr = (ulong) scp->request_buffer;
6750
#else /* version >= v2.0.0 */
6751
        asc_scsi_q.q1.data_addr = virt_to_bus(scp->request_buffer);
6752
#endif /* version >= v2.0.0 */
6753
        asc_scsi_q.q1.data_cnt = scp->request_bufflen;
6754
        ASC_STATS_ADD(scp->host, cont_xfer,
6755
                      ASC_CEILING(scp->request_bufflen, 512));
6756
        asc_scsi_q.q1.sg_queue_cnt = 0;
6757
        asc_scsi_q.sg_head = NULL;
6758
    } else {
6759
        /*
6760
         * CDB scatter-gather request list.
6761
         */
6762
        int                     sgcnt;
6763
        struct scatterlist      *slp;
6764
 
6765
        if (scp->use_sg > scp->host->sg_tablesize) {
6766
            ASC_PRINT3(
6767
"asc_build_req: board %d: use_sg %d > sg_tablesize %d\n",
6768
                boardp->id, scp->use_sg, scp->host->sg_tablesize);
6769
            scp->result = HOST_BYTE(DID_ERROR);
6770
            asc_enqueue(&boardp->done, scp, ASC_BACK);
6771
            return ASC_ERROR;
6772
        }
6773
 
6774
        ASC_STATS(scp->host, sg_cnt);
6775
 
6776
        /*
6777
         * Use global ASC_SG_HEAD structure and set the ASC_SCSI_Q
6778
         * structure to point to it.
6779
         */
6780
        memset(&asc_sg_head, 0, sizeof(ASC_SG_HEAD));
6781
 
6782
        asc_scsi_q.q1.cntl |= QC_SG_HEAD;
6783
        asc_scsi_q.sg_head = &asc_sg_head;
6784
        asc_scsi_q.q1.data_cnt = 0;
6785
        asc_scsi_q.q1.data_addr = 0;
6786
        asc_sg_head.entry_cnt = asc_scsi_q.q1.sg_queue_cnt = scp->use_sg;
6787
        ASC_STATS_ADD(scp->host, sg_elem, asc_sg_head.entry_cnt);
6788
 
6789
        /*
6790
         * Convert scatter-gather list into ASC_SG_HEAD list.
6791
         */
6792
        slp = (struct scatterlist *) scp->request_buffer;
6793
        for (sgcnt = 0; sgcnt < scp->use_sg; sgcnt++, slp++) {
6794
#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
6795
            asc_sg_head.sg_list[sgcnt].addr = (ulong) slp->address;
6796
#else /* version >= v2.0.0 */
6797
            asc_sg_head.sg_list[sgcnt].addr = virt_to_bus(slp->address);
6798
#endif /* version >= v2.0.0 */
6799
            asc_sg_head.sg_list[sgcnt].bytes = slp->length;
6800
            ASC_STATS_ADD(scp->host, sg_xfer, ASC_CEILING(slp->length, 512));
6801
        }
6802
    }
6803
 
6804
    ASC_DBG_PRT_ASC_SCSI_Q(2, &asc_scsi_q);
6805
    ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
6806
 
6807
    return ASC_NOERROR;
6808
}
6809
 
6810
/*
6811
 * Build a request structure for the Adv Library (Wide Board).
6812
 *
6813
 * If an adv_req_t can not be allocated to issue the request,
6814
 * then return ASC_BUSY. If an error occurs, then return ASC_ERROR.
6815
 */
6816
STATIC int
6817
adv_build_req(asc_board_t *boardp, Scsi_Cmnd *scp,
6818
    ADV_SCSI_REQ_Q **adv_scsiqpp)
6819
{
6820
    adv_req_t           *reqp;
6821
    ADV_SCSI_REQ_Q      *scsiqp;
6822
    int                 i;
6823
 
6824
    /*
6825
     * Allocate an adv_req_t structure from the board to execute
6826
     * the command.
6827
     */
6828
    if (boardp->adv_reqp == NULL) {
6829
        ASC_DBG(1, "adv_build_req: no free adv_req_t\n");
6830
        ASC_STATS(scp->host, adv_build_noreq);
6831
        return ASC_BUSY;
6832
    } else {
6833
        reqp = boardp->adv_reqp;
6834
        boardp->adv_reqp = reqp->next_reqp;
6835
        reqp->next_reqp = NULL;
6836
    }
6837
 
6838
    /*
6839
     * Get 4-byte aligned ADV_SCSI_REQ_Q and ADV_SG_BLOCK pointers.
6840
     */
6841
    scsiqp = (ADV_SCSI_REQ_Q *) ADV_DWALIGN(&reqp->scsi_req_q);
6842
    memset(scsiqp, 0, sizeof(ADV_SCSI_REQ_Q));
6843
 
6844
    /*
6845
     * Set the ADV_SCSI_REQ_Q 'srb_ptr' to point to the adv_req_t structure.
6846
     */
6847
    scsiqp->srb_ptr = (ulong) reqp;
6848
 
6849
    /*
6850
     * Set the adv_req_t 'cmndp' to point to the Scsi_Cmnd structure.
6851
     */
6852
    reqp->cmndp = scp;
6853
 
6854
    /*
6855
     * Build the ADV_SCSI_REQ_Q request.
6856
     */
6857
 
6858
    /*
6859
     * Set CDB length and copy it to the request structure.
6860
     */
6861
    ASC_ASSERT(scp->cmd_len <= ASC_MAX_CDB_LEN);
6862
    if (scp->cmd_len > ASC_MAX_CDB_LEN) {
6863
        scp->cmd_len = ASC_MAX_CDB_LEN;
6864
    }
6865
    scsiqp->cdb_len = scp->cmd_len;
6866
    for (i = 0; i < scp->cmd_len; i++) {
6867
        scsiqp->cdb[i] = scp->cmnd[i];
6868
    }
6869
 
6870
    scsiqp->target_id = scp->target;
6871
    scsiqp->target_lun = scp->lun;
6872
 
6873
    scsiqp->vsense_addr = (ulong) &scp->sense_buffer[0];
6874
#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
6875
    scsiqp->sense_addr = (ulong) &scp->sense_buffer[0];
6876
#else /* version >= v2.0.0 */
6877
    scsiqp->sense_addr = virt_to_bus(&scp->sense_buffer[0]);
6878
#endif /* version >= v2.0.0 */
6879
    scsiqp->sense_len = sizeof(scp->sense_buffer);
6880
 
6881
    /*
6882
     * Build ADV_SCSI_REQ_Q for a contiguous buffer or a scatter-gather
6883
     * buffer command.
6884
     */
6885
    scsiqp->data_cnt = scp->request_bufflen;
6886
    scsiqp->vdata_addr = (ulong) scp->request_buffer;
6887
#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
6888
    scsiqp->data_addr = (ulong) scp->request_buffer;
6889
#else /* version >= v2.0.0 */
6890
    scsiqp->data_addr = virt_to_bus(scp->request_buffer);
6891
#endif /* version >= v2.0.0 */
6892
 
6893
    if (scp->use_sg == 0) {
6894
        /*
6895
         * CDB request of single contiguous buffer.
6896
         */
6897
        reqp->sgblkp = NULL;
6898
        scsiqp->sg_list_ptr = NULL;
6899
        ASC_STATS(scp->host, cont_cnt);
6900
        ASC_STATS_ADD(scp->host, cont_xfer,
6901
                      ASC_CEILING(scp->request_bufflen, 512));
6902
    } else {
6903
        /*
6904
         * CDB scatter-gather request list.
6905
         */
6906
        if (scp->use_sg > ADV_MAX_SG_LIST) {
6907
            ASC_PRINT3(
6908
"adv_build_req: board %d: use_sg %d > ADV_MAX_SG_LIST %d\n",
6909
                boardp->id, scp->use_sg, scp->host->sg_tablesize);
6910
            scp->result = HOST_BYTE(DID_ERROR);
6911
            asc_enqueue(&boardp->done, scp, ASC_BACK);
6912
 
6913
            /*
6914
             * Free the 'adv_req_t' structure by adding it back to the
6915
             * board free list.
6916
             */
6917
            reqp->next_reqp = boardp->adv_reqp;
6918
            boardp->adv_reqp = reqp;
6919
 
6920
            return ASC_ERROR;
6921
        }
6922
 
6923
        /*
6924
         * Allocate an 'adv_sgblk_t' structure from the board to
6925
         * execute the command.
6926
         */
6927
        if (boardp->adv_sgblkp == NULL) {
6928
            ASC_DBG(1, "adv_build_req: no free adv_sgblk_t\n");
6929
            ASC_STATS(scp->host, adv_build_nosg);
6930
            /*
6931
             * Free the 'adv_req_t' structure by adding it back to the
6932
             * board free list.
6933
             */
6934
            reqp->next_reqp = boardp->adv_reqp;
6935
            boardp->adv_reqp = reqp;
6936
            return ASC_BUSY;
6937
        } else {
6938
            reqp->sgblkp = boardp->adv_sgblkp;
6939
            boardp->adv_sgblkp = reqp->sgblkp->next_sgblkp;
6940
            reqp->sgblkp->next_sgblkp = NULL;
6941
        }
6942
 
6943
        /*
6944
         * Build scatter-gather list.
6945
         */
6946
        scsiqp->sg_list_ptr = (ADV_SG_BLOCK *)
6947
            ADV_DWALIGN(&reqp->sgblkp->sg_block[0]);
6948
 
6949
        memset(scsiqp->sg_list_ptr, 0, sizeof(ADV_SG_BLOCK) *
6950
            (ADV_NUM_SG_BLOCK + ADV_NUM_PAGE_CROSSING));
6951
 
6952
        if (adv_get_sglist(&boardp->dvc_var.adv_dvc_var, scsiqp, scp) ==
6953
            ADV_ERROR) {
6954
 
6955
            /*
6956
             * Free the adv_sgblk_t structure, if any, by adding it back
6957
             * to the board free list.
6958
             */
6959
            ASC_ASSERT(reqp->sgblkp != NULL);
6960
            reqp->sgblkp->next_sgblkp = boardp->adv_sgblkp;
6961
            boardp->adv_sgblkp = reqp->sgblkp;
6962
 
6963
            /*
6964
             * Free the adv_req_t structure by adding it back to the
6965
             * board free list.
6966
             */
6967
            reqp->next_reqp = boardp->adv_reqp;
6968
            boardp->adv_reqp = reqp;
6969
 
6970
            return ADV_ERROR;
6971
        }
6972
 
6973
        ASC_STATS(scp->host, sg_cnt);
6974
        ASC_STATS_ADD(scp->host, sg_elem, scp->use_sg);
6975
    }
6976
 
6977
    ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
6978
    ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
6979
 
6980
    *adv_scsiqpp = scsiqp;
6981
 
6982
    return ASC_NOERROR;
6983
}
6984
 
6985
/*
6986
 * Build scatter-gather list for Adv Library (Wide Board).
6987
 *
6988
 * Return:
6989
 *      ADV_SUCCESS(1) - SG List successfully created
6990
 *      ADV_ERROR(-1) - SG List creation failed
6991
 */
6992
STATIC int
6993
adv_get_sglist(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp,
6994
    Scsi_Cmnd *scp)
6995
{
6996
    ADV_SG_BLOCK        *sg_block;              /* virtual address of a SG */
6997
    ulong               sg_block_next_addr;     /* block and its next */
6998
    ulong               sg_block_physical_addr;
6999
    int                 sg_block_index, i;      /* how many SG entries */
7000
    struct scatterlist  *slp;
7001
    int                 sg_elem_cnt;
7002
 
7003
    slp = (struct scatterlist *) scp->request_buffer;
7004
    sg_elem_cnt = scp->use_sg;
7005
 
7006
    sg_block = scsiqp->sg_list_ptr;
7007
    sg_block_next_addr = (ulong) sg_block;    /* allow math operation */
7008
    sg_block_physical_addr =
7009
#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
7010
        (ulong) scsiqp->sg_list_ptr;
7011
#else /* version >= v2.0.0 */
7012
        virt_to_bus(scsiqp->sg_list_ptr);
7013
#endif /* version >= v2.0.0 */
7014
    ADV_ASSERT(ADV_DWALIGN(sg_block_physical_addr) ==
7015
                   sg_block_physical_addr);
7016
    scsiqp->sg_real_addr = sg_block_physical_addr;
7017
 
7018
    sg_block_index = 0;
7019
    do
7020
    {
7021
        sg_block->first_entry_no = sg_block_index;
7022
        for (i = 0; i < NO_OF_SG_PER_BLOCK; i++)
7023
        {
7024
            sg_block->sg_list[i].sg_addr =
7025
#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
7026
                (ulong) slp->address;
7027
#else /* version >= v2.0.0 */
7028
                virt_to_bus(slp->address);
7029
#endif /* version >= v2.0.0 */
7030
            sg_block->sg_list[i].sg_count = slp->length;
7031
            ASC_STATS_ADD(scp->host, sg_xfer, ASC_CEILING(slp->length, 512));
7032
 
7033
            if (--sg_elem_cnt == 0)
7034
            {   /* last entry, get out */
7035
                scsiqp->sg_entry_cnt = sg_block_index + i + 1;
7036
                sg_block->last_entry_no = sg_block_index + i;
7037
                sg_block->sg_ptr = 0L;    /* next link = NULL */
7038
                return ADV_SUCCESS;
7039
            }
7040
            slp++;
7041
        }
7042
        sg_block_next_addr += sizeof(ADV_SG_BLOCK);
7043
        sg_block_physical_addr += sizeof(ADV_SG_BLOCK);
7044
        ADV_ASSERT(ADV_DWALIGN(sg_block_physical_addr) ==
7045
                       sg_block_physical_addr);
7046
 
7047
        sg_block_index += NO_OF_SG_PER_BLOCK;
7048
        sg_block->sg_ptr = (ADV_SG_BLOCK *) sg_block_physical_addr;
7049
        sg_block->last_entry_no = sg_block_index - 1;
7050
        sg_block = (ADV_SG_BLOCK *) sg_block_next_addr; /* virtual addr */
7051
    }
7052
    while (1);
7053
    /* NOTREACHED */
7054
}
7055
 
7056
/*
7057
 * asc_isr_callback() - Second Level Interrupt Handler called by AscISR().
7058
 *
7059
 * Interrupt callback function for the Narrow SCSI Asc Library.
7060
 */
7061
STATIC void
7062
asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
7063
{
7064
    asc_board_t         *boardp;
7065
    Scsi_Cmnd           *scp;
7066
    struct Scsi_Host    *shp;
7067
    int                 underrun = ASC_FALSE;
7068
    int                 i;
7069
 
7070
    ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
7071
    ASC_DBG2(1, "asc_isr_callback: asc_dvc_varp %x, qdonep %x\n",
7072
        (unsigned) asc_dvc_varp, (unsigned) qdonep);
7073
    ASC_DBG_PRT_ASC_QDONE_INFO(2, qdonep);
7074
 
7075
    /*
7076
     * Get the Scsi_Cmnd structure and Scsi_Host structure for the
7077
     * command that has been completed.
7078
     */
7079
    scp = (Scsi_Cmnd *) qdonep->d2.srb_ptr;
7080
    ASC_DBG1(1, "asc_isr_callback: scp %x\n", (unsigned) scp);
7081
 
7082
    if (scp == NULL) {
7083
        ASC_PRINT("asc_isr_callback: scp is NULL\n");
7084
        return;
7085
    }
7086
    ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
7087
 
7088
    /*
7089
     * If the request's host pointer is not valid, display a
7090
     * message and return.
7091
     */
7092
    shp = scp->host;
7093
    for (i = 0; i < asc_board_count; i++) {
7094
        if (asc_host[i] == shp) {
7095
            break;
7096
        }
7097
    }
7098
    if (i == asc_board_count) {
7099
        ASC_PRINT2("asc_isr_callback: scp %x has bad host pointer, host %x\n",
7100
            (unsigned) scp, (unsigned) shp);
7101
        return;
7102
    }
7103
 
7104
    ASC_STATS(shp, callback);
7105
    ASC_DBG1(1, "asc_isr_callback: shp %x\n", (unsigned) shp);
7106
 
7107
    /*
7108
     * If the request isn't found on the active queue, it may
7109
     * have been removed to handle a reset or abort request.
7110
     * Display a message and return.
7111
     */
7112
    boardp = ASC_BOARDP(shp);
7113
    ASC_ASSERT(asc_dvc_varp == &boardp->dvc_var.asc_dvc_var);
7114
    if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) {
7115
        ASC_PRINT2("asc_isr_callback: board %d: scp %x not on active queue\n",
7116
            boardp->id, (unsigned) scp);
7117
        return;
7118
    }
7119
 
7120
    /*
7121
     * Check for an underrun condition.
7122
     */
7123
    if (scp->request_bufflen != 0 && qdonep->remain_bytes != 0 &&
7124
        qdonep->remain_bytes <= scp->request_bufflen != 0) {
7125
        ASC_DBG1(1, "asc_isr_callback: underrun condition %u bytes\n",
7126
        (unsigned) qdonep->remain_bytes);
7127
        underrun = ASC_TRUE;
7128
    }
7129
 
7130
    /*
7131
     * 'qdonep' contains the command's ending status.
7132
     */
7133
    switch (qdonep->d3.done_stat) {
7134
    case QD_NO_ERROR:
7135
        ASC_DBG(2, "asc_isr_callback: QD_NO_ERROR\n");
7136
        switch (qdonep->d3.host_stat) {
7137
        case QHSTA_NO_ERROR:
7138
            scp->result = 0;
7139
            break;
7140
        default:
7141
            /* QHSTA error occurred */
7142
            scp->result = HOST_BYTE(DID_ERROR);
7143
            break;
7144
        }
7145
 
7146
        /*
7147
         * If an INQUIRY command completed successfully, then call
7148
         * the AscInquiryHandling() function to set-up the device.
7149
         */
7150
        if (scp->cmnd[0] == SCSICMD_Inquiry && scp->lun == 0 &&
7151
            (scp->request_bufflen - qdonep->remain_bytes) >= 8)
7152
        {
7153
            AscInquiryHandling(asc_dvc_varp, scp->target & 0x7,
7154
                (ASC_SCSI_INQUIRY *) scp->request_buffer);
7155
        }
7156
 
7157
        /*
7158
         * If there was an underrun without any other error,
7159
         * set DID_ERROR to indicate the underrun error.
7160
         *
7161
         * Note: There is no way yet to indicate the number
7162
         * of underrun bytes.
7163
         */
7164
        if (scp->result == 0 && underrun == ASC_TRUE) {
7165
            scp->result = HOST_BYTE(DID_UNDERRUN);
7166
        }
7167
        break;
7168
 
7169
    case QD_WITH_ERROR:
7170
        ASC_DBG(2, "asc_isr_callback: QD_WITH_ERROR\n");
7171
        switch (qdonep->d3.host_stat) {
7172
        case QHSTA_NO_ERROR:
7173
            if (qdonep->d3.scsi_stat == SS_CHK_CONDITION) {
7174
                ASC_DBG(2, "asc_isr_callback: SS_CHK_CONDITION\n");
7175
                ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
7176
                    sizeof(scp->sense_buffer));
7177
                /*
7178
                 * Note: The 'status_byte()' macro used by target drivers
7179
                 * defined in scsi.h shifts the status byte returned by
7180
                 * host drivers right by 1 bit. This is why target drivers
7181
                 * also use right shifted status byte definitions. For
7182
                 * instance target drivers use CHECK_CONDITION, defined to
7183
                 * 0x1, instead of the SCSI defined check condition value
7184
                 * of 0x2. Host drivers are supposed to return the status
7185
                 * byte as it is defined by SCSI.
7186
                 */
7187
                scp->result = DRIVER_BYTE(DRIVER_SENSE) |
7188
                    STATUS_BYTE(qdonep->d3.scsi_stat);
7189
            } else {
7190
                scp->result = STATUS_BYTE(qdonep->d3.scsi_stat);
7191
            }
7192
            break;
7193
 
7194
        default:
7195
            /* QHSTA error occurred */
7196
            ASC_DBG1(1, "asc_isr_callback: host_stat %x\n",
7197
                qdonep->d3.host_stat);
7198
            scp->result = HOST_BYTE(DID_BAD_TARGET);
7199
            break;
7200
        }
7201
        break;
7202
 
7203
    case QD_ABORTED_BY_HOST:
7204
        ASC_DBG(1, "asc_isr_callback: QD_ABORTED_BY_HOST\n");
7205
        scp->result = HOST_BYTE(DID_ABORT) | MSG_BYTE(qdonep->d3.scsi_msg) |
7206
                STATUS_BYTE(qdonep->d3.scsi_stat);
7207
        break;
7208
 
7209
    default:
7210
        ASC_DBG1(1, "asc_isr_callback: done_stat %x\n", qdonep->d3.done_stat);
7211
        scp->result = HOST_BYTE(DID_ERROR) | MSG_BYTE(qdonep->d3.scsi_msg) |
7212
                STATUS_BYTE(qdonep->d3.scsi_stat);
7213
        break;
7214
    }
7215
 
7216
    /*
7217
     * If the 'init_tidmask' bit isn't already set for the target and the
7218
     * current request finished normally, then set the bit for the target
7219
     * to indicate that a device is present.
7220
     */
7221
    if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->target)) == 0 &&
7222
        qdonep->d3.done_stat == QD_NO_ERROR &&
7223
        qdonep->d3.host_stat == QHSTA_NO_ERROR) {
7224
        boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->target);
7225
    }
7226
 
7227
    /*
7228
     * Because interrupts may be enabled by the 'Scsi_Cmnd' done
7229
     * function, add the command to the end of the board's done queue.
7230
     * The done function for the command will be called from
7231
     * advansys_interrupt().
7232
     */
7233
    asc_enqueue(&boardp->done, scp, ASC_BACK);
7234
 
7235
    return;
7236
}
7237
 
7238
/*
7239
 * adv_isr_callback() - Second Level Interrupt Handler called by AdvISR().
7240
 *
7241
 * Callback function for the Wide SCSI Adv Library.
7242
 */
7243
STATIC void
7244
adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp)
7245
{
7246
    asc_board_t         *boardp;
7247
    adv_req_t           *reqp;
7248
    Scsi_Cmnd           *scp;
7249
    struct Scsi_Host    *shp;
7250
    int                 underrun = ASC_FALSE;
7251
    int                 i;
7252
 
7253
    ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
7254
    ASC_DBG2(1, "adv_isr_callback: adv_dvc_varp %x, scsiqp %x\n",
7255
        (unsigned) adv_dvc_varp, (unsigned) scsiqp);
7256
    ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
7257
 
7258
    /*
7259
     * Get the adv_req_t structure for the command that has been
7260
     * completed. The adv_req_t structure actually contains the
7261
     * completed ADV_SCSI_REQ_Q structure.
7262
     */
7263
    reqp = (adv_req_t *) scsiqp->srb_ptr;
7264
    ASC_DBG1(1, "adv_isr_callback: reqp %x\n", (unsigned) reqp);
7265
    if (reqp == NULL) {
7266
        ASC_PRINT("adv_isr_callback: reqp is NULL\n");
7267
        return;
7268
    }
7269
 
7270
    /*
7271
     * Get the Scsi_Cmnd structure and Scsi_Host structure for the
7272
     * command that has been completed.
7273
     *
7274
     * Note: The adv_req_t request structure and adv_sgblk_t structure,
7275
     * if any, * dropped, because a board structure pointer can not be
7276
     * determined.
7277
     */
7278
    scp = reqp->cmndp;
7279
    ASC_DBG1(1, "adv_isr_callback: scp %x\n", (unsigned) scp);
7280
    if (scp == NULL) {
7281
        ASC_PRINT("adv_isr_callback: scp is NULL; adv_req_t dropped.\n");
7282
        return;
7283
    }
7284
    ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
7285
 
7286
    /*
7287
     * If the request's host pointer is not valid, display a message
7288
     * and return.
7289
     */
7290
    shp = scp->host;
7291
    for (i = 0; i < asc_board_count; i++) {
7292
        if (asc_host[i] == shp) {
7293
            break;
7294
        }
7295
    }
7296
    /*
7297
     * Note: If the host structure is not found, the adv_req_t request
7298
     * structure and adv_sgblk_t structure, if any, is dropped.
7299
     */
7300
    if (i == asc_board_count) {
7301
        ASC_PRINT2("adv_isr_callback: scp %x has bad host pointer, host %x\n",
7302
            (unsigned) scp, (unsigned) shp);
7303
        return;
7304
    }
7305
 
7306
    ASC_STATS(shp, callback);
7307
    ASC_DBG1(1, "adv_isr_callback: shp %x\n", (unsigned) shp);
7308
 
7309
    /*
7310
     * If the request isn't found on the active queue, it may have been
7311
     * removed to handle a reset or abort request. Display a message and
7312
     * return.
7313
     *
7314
     * Note: Because the structure may still be in use don't attempt
7315
     * to free the adv_req_t and adv_sgblk_t, if any, structures.
7316
     */
7317
    boardp = ASC_BOARDP(shp);
7318
    ASC_ASSERT(adv_dvc_varp == &boardp->dvc_var.adv_dvc_var);
7319
    if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) {
7320
        ASC_PRINT2("adv_isr_callback: board %d: scp %x not on active queue\n",
7321
            boardp->id, (unsigned) scp);
7322
        return;
7323
    }
7324
 
7325
    /*
7326
     * Check for an underrun condition.
7327
     */
7328
    if (scp->request_bufflen != 0 && scsiqp->data_cnt != 0) {
7329
        ASC_DBG1(1, "adv_isr_callback: underrun condition %lu bytes\n",
7330
        scsiqp->data_cnt);
7331
        underrun = ASC_TRUE;
7332
    }
7333
 
7334
    /*
7335
     * 'done_status' contains the command's ending status.
7336
     */
7337
    switch (scsiqp->done_status) {
7338
    case QD_NO_ERROR:
7339
        ASC_DBG(2, "adv_isr_callback: QD_NO_ERROR\n");
7340
        switch (scsiqp->host_status) {
7341
        case QHSTA_NO_ERROR:
7342
            scp->result = 0;
7343
            break;
7344
        default:
7345
            /* QHSTA error occurred. */
7346
            ASC_DBG1(2, "adv_isr_callback: host_status %x\n",
7347
                scsiqp->host_status);
7348
            scp->result = HOST_BYTE(DID_ERROR);
7349
            break;
7350
        }
7351
        /*
7352
         * If there was an underrun without any other error,
7353
         * set DID_ERROR to indicate the underrun error.
7354
         *
7355
         * Note: There is no way yet to indicate the number
7356
         * of underrun bytes.
7357
         */
7358
        if (scp->result == 0 && underrun == ASC_TRUE) {
7359
                scp->result = HOST_BYTE(DID_UNDERRUN);
7360
        }
7361
        break;
7362
 
7363
    case QD_WITH_ERROR:
7364
        ASC_DBG(2, "adv_isr_callback: QD_WITH_ERROR\n");
7365
        switch (scsiqp->host_status) {
7366
        case QHSTA_NO_ERROR:
7367
            if (scsiqp->scsi_status == SS_CHK_CONDITION) {
7368
                ASC_DBG(2, "adv_isr_callback: SS_CHK_CONDITION\n");
7369
                ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
7370
                    sizeof(scp->sense_buffer));
7371
                /*
7372
                 * Note: The 'status_byte()' macro used by target drivers
7373
                 * defined in scsi.h shifts the status byte returned by
7374
                 * host drivers right by 1 bit. This is why target drivers
7375
                 * also use right shifted status byte definitions. For
7376
                 * instance target drivers use CHECK_CONDITION, defined to
7377
                 * 0x1, instead of the SCSI defined check condition value
7378
                 * of 0x2. Host drivers are supposed to return the status
7379
                 * byte as it is defined by SCSI.
7380
                 */
7381
                scp->result = DRIVER_BYTE(DRIVER_SENSE) |
7382
                    STATUS_BYTE(scsiqp->scsi_status);
7383
            } else {
7384
                scp->result = STATUS_BYTE(scsiqp->scsi_status);
7385
            }
7386
            break;
7387
 
7388
        default:
7389
            /* Some other QHSTA error occurred. */
7390
            ASC_DBG1(1, "adv_isr_callback: host_status %x\n",
7391
                scsiqp->host_status);
7392
            scp->result = HOST_BYTE(DID_BAD_TARGET);
7393
            break;
7394
        }
7395
        break;
7396
 
7397
    case QD_ABORTED_BY_HOST:
7398
        ASC_DBG(1, "adv_isr_callback: QD_ABORTED_BY_HOST\n");
7399
        scp->result = HOST_BYTE(DID_ABORT) | STATUS_BYTE(scsiqp->scsi_status);
7400
        break;
7401
 
7402
    default:
7403
        ASC_DBG1(1, "adv_isr_callback: done_status %x\n", scsiqp->done_status);
7404
        scp->result = HOST_BYTE(DID_ERROR) | STATUS_BYTE(scsiqp->scsi_status);
7405
        break;
7406
    }
7407
 
7408
    /*
7409
     * If the 'init_tidmask' bit isn't already set for the target and the
7410
     * current request finished normally, then set the bit for the target
7411
     * to indicate that a device is present.
7412
     */
7413
    if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->target)) == 0 &&
7414
        scsiqp->done_status == QD_NO_ERROR &&
7415
        scsiqp->host_status == QHSTA_NO_ERROR) {
7416
        boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->target);
7417
    }
7418
 
7419
    /*
7420
     * Because interrupts may be enabled by the 'Scsi_Cmnd' done
7421
     * function, add the command to the end of the board's done queue.
7422
     * The done function for the command will be called from
7423
     * advansys_interrupt().
7424
     */
7425
    asc_enqueue(&boardp->done, scp, ASC_BACK);
7426
 
7427
    /*
7428
     * Free the adv_sgblk_t structure, if any, by adding it back
7429
     * to the board free list.
7430
     */
7431
    if (reqp->sgblkp != NULL) {
7432
        reqp->sgblkp->next_sgblkp = boardp->adv_sgblkp;
7433
        boardp->adv_sgblkp = reqp->sgblkp;
7434
    }
7435
 
7436
    /*
7437
     * Free the adv_req_t structure used with the command by adding
7438
     * it back to the board free list.
7439
     */
7440
    reqp->next_reqp = boardp->adv_reqp;
7441
    boardp->adv_reqp = reqp;
7442
 
7443
    ASC_DBG(1, "adv_isr_callback: done\n");
7444
 
7445
    return;
7446
}
7447
 
7448
#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
7449
#ifdef ASC_CONFIG_PCI
7450
/*
7451
 * Search for an AdvanSys PCI device in the PCI configuration space.
7452
 */
7453
ASC_INITFUNC(
7454
STATIC int
7455
asc_srch_pci_dev(PCI_DEVICE *pciDevice)
7456
)
7457
{
7458
    int                        ret = PCI_DEVICE_NOT_FOUND;
7459
 
7460
    ASC_DBG(2, "asc_srch_pci_dev: begin\n");
7461
 
7462
    if (pci_scan_method == -1) {
7463
        pci_scan_method = asc_scan_method();
7464
    }
7465
    pciDevice->type = pci_scan_method;
7466
    ASC_DBG1(2, "asc_srch_pci_dev: type %d\n", pciDevice->type);
7467
 
7468
    ret = asc_pci_find_dev(pciDevice);
7469
    ASC_DBG1(2, "asc_srch_pci_dev: asc_pci_find_dev() return %d\n", ret);
7470
    if (ret == PCI_DEVICE_FOUND) {
7471
        pciDevice->slotNumber = pciDevice->slotFound + 1;
7472
        pciDevice->startSlot = pciDevice->slotFound + 1;
7473
    } else {
7474
        if (pciDevice->bridge > pciDevice->busNumber) {
7475
            ASC_DBG2(2, "asc_srch_pci_dev: bridge %x, busNumber %x\n",
7476
                pciDevice->bridge, pciDevice->busNumber);
7477
            pciDevice->busNumber++;
7478
            pciDevice->slotNumber = 0;
7479
            pciDevice->startSlot = 0;
7480
            pciDevice->endSlot = 0x0f;
7481
            ret = asc_srch_pci_dev(pciDevice);
7482
            ASC_DBG1(2, "asc_srch_pci_dev: recursive call return %d\n", ret);
7483
        }
7484
    }
7485
 
7486
    ASC_DBG1(2, "asc_srch_pci_dev: return %d\n", ret);
7487
    return ret;
7488
}
7489
 
7490
/*
7491
 * Determine the access method to be used for 'pciDevice'.
7492
 */
7493
ASC_INITFUNC(
7494
STATIC uchar
7495
asc_scan_method(void)
7496
)
7497
{
7498
    ushort      data;
7499
    PCI_DATA    pciData;
7500
    uchar       type;
7501
    uchar       slot;
7502
 
7503
    ASC_DBG(2, "asc_scan_method: begin\n");
7504
    memset(&pciData, 0, sizeof(pciData));
7505
    for (type = 1; type < 3; type++) {
7506
        pciData.type = type;
7507
        for (slot = 0; slot < PCI_MAX_SLOT; slot++) {
7508
            pciData.slot = slot;
7509
            data = asc_get_cfg_word(&pciData);
7510
            if ((data != 0xFFFF) && (data != 0x0000)) {
7511
                ASC_DBG2(4, "asc_scan_method: data %x, type %d\n", data, type);
7512
                return (type);
7513
            }
7514
        }
7515
    }
7516
    ASC_DBG1(4, "asc_scan_method: type %d\n", type);
7517
    return (type);
7518
}
7519
 
7520
/*
7521
 * Check for an AdvanSys PCI device in 'pciDevice'.
7522
 *
7523
 * Return PCI_DEVICE_FOUND if found, otherwise return PCI_DEVICE_NOT_FOUND.
7524
 */
7525
ASC_INITFUNC(
7526
STATIC int
7527
asc_pci_find_dev(PCI_DEVICE *pciDevice)
7528
)
7529
{
7530
    PCI_DATA    pciData;
7531
    ushort      vendorid, deviceid;
7532
    uchar       classcode, subclass;
7533
    uchar       lslot;
7534
 
7535
    ASC_DBG(3, "asc_pci_find_dev: begin\n");
7536
    pciData.type = pciDevice->type;
7537
    pciData.bus = pciDevice->busNumber;
7538
    pciData.func = pciDevice->devFunc;
7539
    lslot = pciDevice->startSlot;
7540
    for (; lslot < pciDevice->endSlot; lslot++) {
7541
        pciData.slot = lslot;
7542
        pciData.offset = VENDORID_OFFSET;
7543
        vendorid = asc_get_cfg_word(&pciData);
7544
        ASC_DBG1(3, "asc_pci_find_dev: vendorid %x\n", vendorid);
7545
        if (vendorid != 0xffff) {
7546
            pciData.offset = DEVICEID_OFFSET;
7547
            deviceid = asc_get_cfg_word(&pciData);
7548
            ASC_DBG1(3, "asc_pci_find_dev: deviceid %x\n", deviceid);
7549
            if ((vendorid == ASC_PCI_VENDORID) &&
7550
                ((deviceid == ASC_PCI_DEVICE_ID_1100) ||
7551
                 (deviceid == ASC_PCI_DEVICE_ID_1200) ||
7552
                 (deviceid == ASC_PCI_DEVICE_ID_1300) ||
7553
                 (deviceid == ASC_PCI_DEVICE_ID_2300))) {
7554
                pciDevice->slotFound = lslot;
7555
                ASC_DBG(3, "asc_pci_find_dev: PCI_DEVICE_FOUND\n");
7556
                return PCI_DEVICE_FOUND;
7557
            } else {
7558
                pciData.offset = SUBCLASS_OFFSET;
7559
                subclass = asc_get_cfg_byte(&pciData);
7560
                pciData.offset = CLASSCODE_OFFSET;
7561
                classcode = asc_get_cfg_byte(&pciData);
7562
                if ((classcode & PCI_BASE_CLASS_BRIDGE_DEVICE) &&
7563
                    (subclass & PCI_SUB_CLASS_PCI_TO_PCI_BRIDGE_CONTROLLER)) {
7564
                    pciDevice->bridge++;
7565
                }
7566
                ASC_DBG2(3, "asc_pci_find_dev: subclass %x, classcode %x\n",
7567
                    subclass, classcode);
7568
            }
7569
        }
7570
    }
7571
    return PCI_DEVICE_NOT_FOUND;
7572
}
7573
 
7574
/*
7575
 * Read PCI configuration data into 'pciConfig'.
7576
 */
7577
ASC_INITFUNC(
7578
STATIC void
7579
asc_get_pci_cfg(PCI_DEVICE *pciDevice, PCI_CONFIG_SPACE *pciConfig)
7580
)
7581
{
7582
    PCI_DATA    pciData;
7583
    uchar       counter;
7584
    uchar       *localConfig;
7585
 
7586
    ASC_DBG1(4, "asc_get_pci_cfg: slotFound %d\n ",
7587
        pciDevice->slotFound);
7588
 
7589
    pciData.type = pciDevice->type;
7590
    pciData.bus = pciDevice->busNumber;
7591
    pciData.slot = pciDevice->slotFound;
7592
    pciData.func = pciDevice->devFunc;
7593
    localConfig = (uchar *) pciConfig;
7594
 
7595
    for (counter = 0; counter < sizeof(PCI_CONFIG_SPACE); counter++) {
7596
        pciData.offset = counter;
7597
        *localConfig = asc_get_cfg_byte(&pciData);
7598
        ASC_DBG1(4, "asc_get_pci_cfg: byte %x\n", *localConfig);
7599
        localConfig++;
7600
    }
7601
    ASC_DBG1(4, "asc_get_pci_cfg: counter %d\n", counter);
7602
}
7603
 
7604
/*
7605
 * Read a word (16 bits) from the PCI configuration space.
7606
 *
7607
 * The configuration mechanism is checked for the correct access method.
7608
 */
7609
ASC_INITFUNC(
7610
STATIC ushort
7611
asc_get_cfg_word(PCI_DATA *pciData)
7612
)
7613
{
7614
    ushort   tmp;
7615
    ulong    address;
7616
    ulong    lbus = pciData->bus;
7617
    ulong    lslot = pciData->slot;
7618
    ulong    lfunc = pciData->func;
7619
    uchar    t2CFA, t2CF8;
7620
    ulong    t1CF8, t1CFC;
7621
 
7622
    ASC_DBG4(4, "asc_get_cfg_word: type %d, bus %lu, slot %lu, func %lu\n",
7623
        pciData->type, lbus, lslot, lfunc);
7624
 
7625
    /*
7626
     * Check type of configuration mechanism.
7627
     */
7628
    if (pciData->type == 2) {
7629
        /*
7630
         * Save registers to be restored later.
7631
         */
7632
        t2CFA = inp(0xCFA);    /* save PCI bus register */
7633
        t2CF8 = inp(0xCF8);    /* save config space enable register */
7634
 
7635
        /*
7636
         * Write the bus and enable registers.
7637
         */
7638
        /* set for type 1 cycle, if needed */
7639
        outp(0xCFA, pciData->bus);
7640
        /* set the function number */
7641
        outp(0xCF8, 0x10 | (pciData->func << 1)) ;
7642
 
7643
        /*
7644
         * Read the configuration space type 2 locations.
7645
         */
7646
        tmp = (ushort) inpw(0xC000 | ((pciData->slot << 8) + pciData->offset));
7647
 
7648
        outp(0xCFA, t2CFA);    /* save PCI bus register */
7649
        outp(0xCF8, t2CF8);    /* save config space enable register */
7650
    } else {
7651
        /*
7652
         * Type 1 or 3 configuration mechanism.
7653
         *
7654
         * Save the CONFIG_ADDRESS and CONFIG_DATA register values.
7655
         */
7656
        t1CF8 = inpl(0xCF8);
7657
        t1CFC = inpl(0xCFC);
7658
 
7659
        /*
7660
         * enable <31>, bus = <23:16>, slot = <15:11>,
7661
         * func = <10:8>, reg = <7:2>
7662
         */
7663
        address = (ulong) ((lbus << 16) | (lslot << 11) |
7664
            (lfunc << 8) | (pciData->offset & 0xFC) | 0x80000000L);
7665
 
7666
        /*
7667
         * Write out the address to CONFIG_ADDRESS.
7668
         */
7669
        outpl(0xCF8, address);
7670
 
7671
        /*
7672
         * Read in word from CONFIG_DATA.
7673
         */
7674
        tmp = (ushort) ((inpl(0xCFC) >>
7675
                 ((pciData->offset & 2) * 8)) & 0xFFFF);
7676
 
7677
        /*
7678
         * Restore registers.
7679
         */
7680
        outpl(0xCF8, t1CF8);
7681
        outpl(0xCFC, t1CFC);
7682
    }
7683
    ASC_DBG1(4, "asc_get_cfg_word: config data: %x\n", tmp);
7684
    return tmp;
7685
}
7686
 
7687
/*
7688
 * Reads a byte from the PCI configuration space.
7689
 *
7690
 * The configuration mechanism is checked for the correct access method.
7691
 */
7692
ASC_INITFUNC(
7693
STATIC uchar
7694
asc_get_cfg_byte(PCI_DATA *pciData)
7695
)
7696
{
7697
    uchar tmp;
7698
    ulong address;
7699
    ulong lbus = pciData->bus, lslot = pciData->slot, lfunc = pciData->func;
7700
    uchar t2CFA, t2CF8;
7701
    ulong t1CF8, t1CFC;
7702
 
7703
    ASC_DBG1(4, "asc_get_cfg_byte: type: %d\n", pciData->type);
7704
 
7705
    /*
7706
     * Check type of configuration mechanism.
7707
     */
7708
    if (pciData->type == 2) {
7709
        /*
7710
         * Save registers to be restored later.
7711
         */
7712
        t2CFA = inp(0xCFA);    /* save PCI bus register */
7713
        t2CF8 = inp(0xCF8);    /* save config space enable register */
7714
 
7715
        /*
7716
         * Write the bus and enable registers.
7717
         */
7718
        /* set for type 1 cycle, if needed */
7719
        outp(0xCFA, pciData->bus);
7720
        /* set the function number */
7721
        outp(0xCF8, 0x10 | (pciData->func << 1));
7722
 
7723
        /*
7724
         * Read configuration space type 2 locations.
7725
         */
7726
        tmp = inp(0xC000 | ((pciData->slot << 8) + pciData->offset));
7727
 
7728
        /*
7729
         * Restore registers.
7730
         */
7731
        outp(0xCF8, t2CF8);    /* restore the enable register */
7732
        outp(0xCFA, t2CFA);    /* restore PCI bus register */
7733
    } else {
7734
        /*
7735
         * Type 1 or 3 configuration mechanism.
7736
         *
7737
         * Save CONFIG_ADDRESS and CONFIG_DATA register values.
7738
         */
7739
        t1CF8 = inpl(0xCF8);
7740
        t1CFC = inpl(0xCFC);
7741
 
7742
        /*
7743
         * enable <31>, bus = <23:16>, slot = <15:11>, func = <10:8>,
7744
         * reg = <7:2>
7745
         */
7746
        address = (ulong) ((lbus << 16) | (lslot << 11) |
7747
            (lfunc << 8) | (pciData->offset & 0xFC) | 0x80000000L);
7748
 
7749
        /*
7750
         * Write out address to CONFIG_ADDRESS.
7751
         */
7752
        outpl(0xCF8, address);
7753
 
7754
        /*
7755
         * Read in word from CONFIG_DATA.
7756
         */
7757
        tmp = (uchar) ((inpl(0xCFC) >> ((pciData->offset & 3) * 8)) & 0xFF);
7758
 
7759
        /*
7760
         * Restore registers.
7761
         */
7762
        outpl(0xCF8, t1CF8);
7763
        outpl(0xCFC, t1CFC);
7764
    }
7765
    ASC_DBG1(4, "asc_get_cfg_byte: config data: %x\n", tmp);
7766
    return tmp;
7767
}
7768
 
7769
/*
7770
 * Write a byte to the PCI configuration space.
7771
 */
7772
ASC_INITFUNC(
7773
STATIC void
7774
asc_put_cfg_byte(PCI_DATA *pciData, uchar byte_data)
7775
)
7776
{
7777
    ulong tmpl;
7778
    ulong address;
7779
    ulong lbus = pciData->bus, lslot = pciData->slot, lfunc = pciData->func;
7780
    uchar t2CFA, t2CF8;
7781
    ulong t1CF8, t1CFC;
7782
 
7783
    ASC_DBG2(4, "asc_put_cfg_byte: type: %d, byte_data %x\n",
7784
        pciData->type, byte_data);
7785
 
7786
    /*
7787
     * Check type of configuration mechanism.
7788
     */
7789
    if (pciData->type == 2) {
7790
 
7791
        /*
7792
         * Save registers to be restored later.
7793
         */
7794
        t2CFA = inp(0xCFA);    /* save PCI bus register */
7795
        t2CF8 = inp(0xCF8);    /* save config space enable register */
7796
 
7797
        /*
7798
         * Write bus and enable registers.
7799
         */
7800
        outp(0xCFA, pciData->bus);
7801
 
7802
        /*
7803
         * Set the function number.
7804
         */
7805
        outp(0xCF8, 0x10 | (pciData->func << 1));
7806
 
7807
        /*
7808
         * Write the configuration space type 2 locations.
7809
         */
7810
        outp(0xC000 | ((pciData->slot << 8) + pciData->offset), byte_data);
7811
 
7812
        /*
7813
         * Restore registers.
7814
         */
7815
        outp(0xCF8, t2CF8);    /* restore the enable register */
7816
        outp(0xCFA, t2CFA);    /* restore PCI bus register    */
7817
    } else {
7818
 
7819
        /*
7820
         * Type 1 or 3 configuration mechanism.
7821
         *
7822
         * Save the CONFIG_ADDRESS and CONFIG_DATA register values.
7823
         */
7824
        t1CF8 = inpl(0xCF8);
7825
        t1CFC = inpl(0xCFC);
7826
 
7827
        /*
7828
         * enable <31>, bus = <23:16>, slot = <15:11>, func = <10:8>,
7829
         * reg = <7:2>
7830
         */
7831
        address = (ulong) ((lbus << 16) | (lslot << 11) | (lfunc << 8) |
7832
                (pciData->offset & 0xFC) | 0x80000000L);
7833
        /*
7834
         * Write out address to CONFIG_ADDRESS.
7835
         */
7836
        outpl(0xCF8, address);
7837
 
7838
        /*
7839
         * Write double word to CONFIG_DATA preserving the bytes
7840
         * in the double not written.
7841
         */
7842
        tmpl = inpl(0xCFC) & ~(0xFF << ((pciData->offset & 3) * 8));
7843
        outpl(0xCFC, tmpl | (byte_data << ((pciData->offset & 3) * 8)));
7844
 
7845
        /*
7846
         * Restore registers.
7847
         */
7848
        outpl(0xCF8, t1CF8);
7849
        outpl(0xCFC, t1CFC);
7850
    }
7851
    ASC_DBG(4, "asc_put_cfg_byte: end\n");
7852
}
7853
#endif /* ASC_CONFIG_PCI */
7854
#endif /* version < v2.1.93 */
7855
 
7856
/*
7857
 * Add a 'REQP' to the end of specified queue. Set 'tidmask'
7858
 * to indicate a command is queued for the device.
7859
 *
7860
 * 'flag' may be either ASC_FRONT or ASC_BACK.
7861
 *
7862
 * 'REQPNEXT(reqp)' returns reqp's next pointer.
7863
 */
7864
STATIC void
7865
asc_enqueue(asc_queue_t *ascq, REQP reqp, int flag)
7866
{
7867
    int        tid;
7868
 
7869
    ASC_DBG3(3, "asc_enqueue: ascq %x, reqp %x, flag %d\n",
7870
        (unsigned) ascq, (unsigned) reqp, flag);
7871
    ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
7872
    ASC_ASSERT(reqp != NULL);
7873
    ASC_ASSERT(flag == ASC_FRONT || flag == ASC_BACK);
7874
    tid = REQPTID(reqp);
7875
    ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
7876
    if (flag == ASC_FRONT) {
7877
        REQPNEXT(reqp) = ascq->q_first[tid];
7878
        ascq->q_first[tid] = reqp;
7879
        /* If the queue was empty, set the last pointer. */
7880
        if (ascq->q_last[tid] == NULL) {
7881
            ascq->q_last[tid] = reqp;
7882
        }
7883
    } else { /* ASC_BACK */
7884
        if (ascq->q_last[tid] != NULL) {
7885
            REQPNEXT(ascq->q_last[tid]) = reqp;
7886
        }
7887
        ascq->q_last[tid] = reqp;
7888
        REQPNEXT(reqp) = NULL;
7889
        /* If the queue was empty, set the first pointer. */
7890
        if (ascq->q_first[tid] == NULL) {
7891
            ascq->q_first[tid] = reqp;
7892
        }
7893
    }
7894
    /* The queue has at least one entry, set its bit. */
7895
    ascq->q_tidmask |= ADV_TID_TO_TIDMASK(tid);
7896
#ifdef ADVANSYS_STATS
7897
    /* Maintain request queue statistics. */
7898
    ascq->q_tot_cnt[tid]++;
7899
    ascq->q_cur_cnt[tid]++;
7900
    if (ascq->q_cur_cnt[tid] > ascq->q_max_cnt[tid]) {
7901
        ascq->q_max_cnt[tid] = ascq->q_cur_cnt[tid];
7902
        ASC_DBG2(2, "asc_enqueue: new q_max_cnt[%d] %d\n",
7903
            tid, ascq->q_max_cnt[tid]);
7904
    }
7905
    REQPTIME(reqp) = REQTIMESTAMP();
7906
#endif /* ADVANSYS_STATS */
7907
    ASC_DBG1(3, "asc_enqueue: reqp %x\n", (unsigned) reqp);
7908
    return;
7909
}
7910
 
7911
/*
7912
 * Return first queued 'REQP' on the specified queue for
7913
 * the specified target device. Clear the 'tidmask' bit for
7914
 * the device if no more commands are left queued for it.
7915
 *
7916
 * 'REQPNEXT(reqp)' returns reqp's next pointer.
7917
 */
7918
STATIC REQP
7919
asc_dequeue(asc_queue_t *ascq, int tid)
7920
{
7921
    REQP    reqp;
7922
 
7923
    ASC_DBG2(3, "asc_dequeue: ascq %x, tid %d\n", (unsigned) ascq, tid);
7924
    ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
7925
    ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
7926
    if ((reqp = ascq->q_first[tid]) != NULL) {
7927
        ASC_ASSERT(ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid));
7928
        ascq->q_first[tid] = REQPNEXT(reqp);
7929
        /* If the queue is empty, clear its bit and the last pointer. */
7930
        if (ascq->q_first[tid] == NULL) {
7931
            ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
7932
            ASC_ASSERT(ascq->q_last[tid] == reqp);
7933
            ascq->q_last[tid] = NULL;
7934
        }
7935
#ifdef ADVANSYS_STATS
7936
        /* Maintain request queue statistics. */
7937
        ascq->q_cur_cnt[tid]--;
7938
        ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0);
7939
        REQTIMESTAT("asc_dequeue", ascq, reqp, tid);
7940
#endif /* ADVANSYS_STATS */
7941
    }
7942
    ASC_DBG1(3, "asc_dequeue: reqp %x\n", (unsigned) reqp);
7943
    return reqp;
7944
}
7945
 
7946
/*
7947
 * Return a pointer to a singly linked list of all the requests queued
7948
 * for 'tid' on the 'asc_queue_t' pointed to by 'ascq'.
7949
 *
7950
 * If 'lastpp' is not NULL, '*lastpp' will be set to point to the
7951
 * the last request returned in the singly linked list.
7952
 *
7953
 * 'tid' should either be a valid target id or if it is ASC_TID_ALL,
7954
 * then all queued requests are concatenated into one list and
7955
 * returned.
7956
 *
7957
 * Note: If 'lastpp' is used to append a new list to the end of
7958
 * an old list, only change the old list last pointer if '*lastpp'
7959
 * (or the function return value) is not NULL, i.e. use a temporary
7960
 * variable for 'lastpp' and check its value after the function return
7961
 * before assigning it to the list last pointer.
7962
 *
7963
 * Unfortunately collecting queuing time statistics adds overhead to
7964
 * the function that isn't inherent to the function's algorithm.
7965
 */
7966
STATIC REQP
7967
asc_dequeue_list(asc_queue_t *ascq, REQP *lastpp, int tid)
7968
{
7969
    REQP    firstp, lastp;
7970
    int     i;
7971
 
7972
    ASC_DBG2(3, "asc_dequeue_list: ascq %x, tid %d\n", (unsigned) ascq, tid);
7973
    ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
7974
    ASC_ASSERT((tid == ASC_TID_ALL) || (tid >= 0 && tid <= ADV_MAX_TID));
7975
 
7976
    /*
7977
     * If 'tid' is not ASC_TID_ALL, return requests only for
7978
     * the specified 'tid'. If 'tid' is ASC_TID_ALL, return all
7979
     * requests for all tids.
7980
     */
7981
    if (tid != ASC_TID_ALL) {
7982
        /* Return all requests for the specified 'tid'. */
7983
        if ((ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid)) == 0) {
7984
            /* List is empty; Set first and last return pointers to NULL. */
7985
            firstp = lastp = NULL;
7986
        } else {
7987
            firstp = ascq->q_first[tid];
7988
            lastp = ascq->q_last[tid];
7989
            ascq->q_first[tid] = ascq->q_last[tid] = NULL;
7990
            ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
7991
#ifdef ADVANSYS_STATS
7992
            {
7993
                REQP reqp;
7994
                ascq->q_cur_cnt[tid] = 0;
7995
                for (reqp = firstp; reqp; reqp = REQPNEXT(reqp)) {
7996
                    REQTIMESTAT("asc_dequeue_list", ascq, reqp, tid);
7997
                }
7998
            }
7999
#endif /* ADVANSYS_STATS */
8000
        }
8001
    } else {
8002
        /* Return all requests for all tids. */
8003
        firstp = lastp = NULL;
8004
        for (i = 0; i <= ADV_MAX_TID; i++) {
8005
            if (ascq->q_tidmask & ADV_TID_TO_TIDMASK(i)) {
8006
                if (firstp == NULL) {
8007
                    firstp = ascq->q_first[i];
8008
                    lastp = ascq->q_last[i];
8009
                } else {
8010
                    ASC_ASSERT(lastp != NULL);
8011
                    REQPNEXT(lastp) = ascq->q_first[i];
8012
                    lastp = ascq->q_last[i];
8013
                }
8014
                ascq->q_first[i] = ascq->q_last[i] = NULL;
8015
                ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(i);
8016
#ifdef ADVANSYS_STATS
8017
                ascq->q_cur_cnt[i] = 0;
8018
#endif /* ADVANSYS_STATS */
8019
            }
8020
        }
8021
#ifdef ADVANSYS_STATS
8022
        {
8023
            REQP reqp;
8024
            for (reqp = firstp; reqp; reqp = REQPNEXT(reqp)) {
8025
                REQTIMESTAT("asc_dequeue_list", ascq, reqp, reqp->target);
8026
            }
8027
        }
8028
#endif /* ADVANSYS_STATS */
8029
    }
8030
    if (lastpp) {
8031
        *lastpp = lastp;
8032
    }
8033
    ASC_DBG1(3, "asc_dequeue_list: firstp %x\n", (unsigned) firstp);
8034
    return firstp;
8035
}
8036
 
8037
/*
8038
 * Remove the specified 'REQP' from the specified queue for
8039
 * the specified target device. Clear the 'tidmask' bit for the
8040
 * device if no more commands are left queued for it.
8041
 *
8042
 * 'REQPNEXT(reqp)' returns reqp's the next pointer.
8043
 *
8044
 * Return ASC_TRUE if the command was found and removed,
8045
 * otherwise return ASC_FALSE.
8046
 */
8047
STATIC int
8048
asc_rmqueue(asc_queue_t *ascq, REQP reqp)
8049
{
8050
    REQP        currp, prevp;
8051
    int         tid;
8052
    int         ret = ASC_FALSE;
8053
 
8054
    ASC_DBG2(3, "asc_rmqueue: ascq %x, reqp %x\n",
8055
        (unsigned) ascq, (unsigned) reqp);
8056
    ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
8057
    ASC_ASSERT(reqp != NULL);
8058
 
8059
    tid = REQPTID(reqp);
8060
    ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
8061
 
8062
    /*
8063
     * Handle the common case of 'reqp' being the first
8064
     * entry on the queue.
8065
     */
8066
    if (reqp == ascq->q_first[tid]) {
8067
        ret = ASC_TRUE;
8068
        ascq->q_first[tid] = REQPNEXT(reqp);
8069
        /* If the queue is now empty, clear its bit and the last pointer. */
8070
        if (ascq->q_first[tid] == NULL) {
8071
            ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
8072
            ASC_ASSERT(ascq->q_last[tid] == reqp);
8073
            ascq->q_last[tid] = NULL;
8074
        }
8075
    } else if (ascq->q_first[tid] != NULL) {
8076
        ASC_ASSERT(ascq->q_last[tid] != NULL);
8077
        /*
8078
         * Because the case of 'reqp' being the first entry has been
8079
         * handled above and it is known the queue is not empty, if
8080
         * 'reqp' is found on the queue it is guaranteed the queue will
8081
         * not become empty and that 'q_first[tid]' will not be changed.
8082
         *
8083
         * Set 'prevp' to the first entry, 'currp' to the second entry,
8084
         * and search for 'reqp'.
8085
         */
8086
        for (prevp = ascq->q_first[tid], currp = REQPNEXT(prevp);
8087
             currp; prevp = currp, currp = REQPNEXT(currp)) {
8088
            if (currp == reqp) {
8089
                ret = ASC_TRUE;
8090
                REQPNEXT(prevp) = REQPNEXT(currp);
8091
                REQPNEXT(reqp) = NULL;
8092
                if (ascq->q_last[tid] == reqp) {
8093
                    ascq->q_last[tid] = prevp;
8094
                }
8095
                break;
8096
            }
8097
        }
8098
    }
8099
#ifdef ADVANSYS_STATS
8100
    /* Maintain request queue statistics. */
8101
    if (ret == ASC_TRUE) {
8102
        ascq->q_cur_cnt[tid]--;
8103
        REQTIMESTAT("asc_rmqueue", ascq, reqp, tid);
8104
    }
8105
    ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0);
8106
#endif /* ADVANSYS_STATS */
8107
    ASC_DBG2(3, "asc_rmqueue: reqp %x, ret %d\n", (unsigned) reqp, ret);
8108
    return ret;
8109
}
8110
 
8111
/*
8112
 * If the specified 'REQP' is queued on the specified queue for
8113
 * the specified target device, return ASC_TRUE.
8114
 */
8115
STATIC int
8116
asc_isqueued(asc_queue_t *ascq, REQP reqp)
8117
{
8118
    REQP        treqp;
8119
    int            tid;
8120
    int            ret = ASC_FALSE;
8121
 
8122
    ASC_DBG2(3, "asc_isqueued: ascq %x, reqp %x\n",
8123
        (unsigned) ascq, (unsigned) reqp);
8124
    ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
8125
    ASC_ASSERT(reqp != NULL);
8126
 
8127
    tid = REQPTID(reqp);
8128
    ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
8129
 
8130
    for (treqp = ascq->q_first[tid]; treqp; treqp = REQPNEXT(treqp)) {
8131
        ASC_ASSERT(ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid));
8132
        if (treqp == reqp) {
8133
            ret = ASC_TRUE;
8134
            break;
8135
        }
8136
    }
8137
    ASC_DBG1(3, "asc_isqueued: ret %x\n", ret);
8138
    return ret;
8139
}
8140
 
8141
/*
8142
 * Execute as many queued requests as possible for the specified queue.
8143
 *
8144
 * Calls asc_execute_scsi_cmnd() to execute a REQP/Scsi_Cmnd.
8145
 */
8146
STATIC void
8147
asc_execute_queue(asc_queue_t *ascq)
8148
{
8149
    ADV_SCSI_BIT_ID_TYPE    scan_tidmask;
8150
    REQP                    reqp;
8151
    int                     i;
8152
 
8153
    ASC_DBG1(1, "asc_execute_queue: ascq %x\n", (unsigned) ascq);
8154
    ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
8155
    /*
8156
     * Execute queued commands for devices attached to
8157
     * the current board in round-robin fashion.
8158
     */
8159
    scan_tidmask = ascq->q_tidmask;
8160
    do {
8161
        for (i = 0; i <= ADV_MAX_TID; i++) {
8162
            if (scan_tidmask & ADV_TID_TO_TIDMASK(i)) {
8163
                if ((reqp = asc_dequeue(ascq, i)) == NULL) {
8164
                    scan_tidmask &= ~ADV_TID_TO_TIDMASK(i);
8165
                } else if (asc_execute_scsi_cmnd((Scsi_Cmnd *) reqp)
8166
                            == ASC_BUSY) {
8167
                    scan_tidmask &= ~ADV_TID_TO_TIDMASK(i);
8168
                    /* Put the request back at front of the list. */
8169
                    asc_enqueue(ascq, reqp, ASC_FRONT);
8170
                }
8171
            }
8172
        }
8173
    } while (scan_tidmask);
8174
    return;
8175
}
8176
 
8177
#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
8178
/*
8179
 * asc_prt_board_devices()
8180
 *
8181
 * Print driver information for devices attached to the board.
8182
 *
8183
 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
8184
 * cf. asc_prt_line().
8185
 *
8186
 * Return the number of characters copied into 'cp'. No more than
8187
 * 'cplen' characters will be copied to 'cp'.
8188
 */
8189
STATIC int
8190
asc_prt_board_devices(struct Scsi_Host *shp, char *cp, int cplen)
8191
{
8192
    asc_board_t        *boardp;
8193
    int                leftlen;
8194
    int                totlen;
8195
    int                len;
8196
    int                chip_scsi_id;
8197
    int                i;
8198
 
8199
    boardp = ASC_BOARDP(shp);
8200
    leftlen = cplen;
8201
    totlen = len = 0;
8202
 
8203
    len = asc_prt_line(cp, leftlen,
8204
"\nDevice Information for AdvanSys SCSI Host %d:\n", shp->host_no);
8205
    ASC_PRT_NEXT();
8206
 
8207
    if (ASC_NARROW_BOARD(boardp)) {
8208
        chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
8209
    } else {
8210
        chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
8211
    }
8212
 
8213
    len = asc_prt_line(cp, leftlen, "Target IDs Detected:");
8214
    ASC_PRT_NEXT();
8215
    for (i = 0; i <= ADV_MAX_TID; i++) {
8216
        if (boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) {
8217
            len = asc_prt_line(cp, leftlen, " %X,", i);
8218
            ASC_PRT_NEXT();
8219
        }
8220
    }
8221
    len = asc_prt_line(cp, leftlen, " (%X=Host Adapter)\n", chip_scsi_id);
8222
    ASC_PRT_NEXT();
8223
 
8224
    return totlen;
8225
}
8226
 
8227
/*
8228
 * Display Wide Board BIOS Information.
8229
 */
8230
STATIC int
8231
asc_prt_adv_bios(struct Scsi_Host *shp, char *cp, int cplen)
8232
{
8233
    asc_board_t        *boardp;
8234
    int                leftlen;
8235
    int                totlen;
8236
    int                len;
8237
    int                upgrade = ASC_FALSE;
8238
    ushort             major, minor, letter;
8239
 
8240
    boardp = ASC_BOARDP(shp);
8241
    leftlen = cplen;
8242
    totlen = len = 0;
8243
 
8244
    len = asc_prt_line(cp, leftlen, "\nROM BIOS Version: ");
8245
    ASC_PRT_NEXT();
8246
 
8247
    /*
8248
     * If the BIOS saved a valid signature, then fill in
8249
     * the BIOS code segment base address.
8250
     */
8251
    if (boardp->bios_signature != 0x55AA) {
8252
        len = asc_prt_line(cp, leftlen, "Pre-3.1\n");
8253
        ASC_PRT_NEXT();
8254
        upgrade = ASC_TRUE;
8255
    } else {
8256
        major = (boardp->bios_version >> 12) & 0xF;
8257
        minor = (boardp->bios_version >> 8) & 0xF;
8258
        letter = (boardp->bios_version & 0xFF);
8259
 
8260
        len = asc_prt_line(cp, leftlen, "%d.%d%c\n",
8261
            major, minor, letter >= 26 ? '?' : letter + 'A');
8262
        ASC_PRT_NEXT();
8263
 
8264
        /* Current available ROM BIOS release is 3.1C. */
8265
        if (major < 3 || (major <= 3 && minor < 1) ||
8266
            (major <= 3 && minor <= 1 && letter < ('C'- 'A'))) {
8267
            upgrade = ASC_TRUE;
8268
        }
8269
    }
8270
    if (upgrade == ASC_TRUE) {
8271
        len = asc_prt_line(cp, leftlen,
8272
"Newer version of ROM BIOS available: ftp://ftp.advansys.com/pub\n");
8273
            ASC_PRT_NEXT();
8274
    }
8275
 
8276
    return totlen;
8277
}
8278
 
8279
/*
8280
 * Add serial number to information bar if signature AAh
8281
 * is found in at bit 15-9 (7 bits) of word 1.
8282
 *
8283
 * Serial Number consists fo 12 alpha-numeric digits.
8284
 *
8285
 *       1 - Product type (A,B,C,D..)  Word0: 15-13 (3 bits)
8286
 *       2 - MFG Location (A,B,C,D..)  Word0: 12-10 (3 bits)
8287
 *     3-4 - Product ID (0-99)         Word0: 9-0 (10 bits)
8288
 *       5 - Product revision (A-J)    Word0:  "         "
8289
 *
8290
 *           Signature                 Word1: 15-9 (7 bits)
8291
 *       6 - Year (0-9)                Word1: 8-6 (3 bits) & Word2: 15 (1 bit)
8292
 *     7-8 - Week of the year (1-52)   Word1: 5-0 (6 bits)
8293
 *
8294
 *    9-12 - Serial Number (A001-Z999) Word2: 14-0 (15 bits)
8295
 *
8296
 * Note 1: Only production cards will have a serial number.
8297
 *
8298
 * Note 2: Signature is most significant 7 bits (0xFE).
8299
 *
8300
 * Returns ASC_TRUE if serial number found, otherwise returns ASC_FALSE.
8301
 */
8302
STATIC int
8303
asc_get_eeprom_string(ushort *serialnum, uchar *cp)
8304
{
8305
    ushort      w, num;
8306
 
8307
    if ((serialnum[1] & 0xFE00) != ((ushort) 0xAA << 8)) {
8308
        return ASC_FALSE;
8309
    } else {
8310
        /*
8311
         * First word - 6 digits.
8312
         */
8313
        w = serialnum[0];
8314
 
8315
        /* Product type - 1st digit. */
8316
        if ((*cp = 'A' + ((w & 0xE000) >> 13)) == 'H') {
8317
            /* Product type is P=Prototype */
8318
            *cp += 0x8;
8319
        }
8320
        cp++;
8321
 
8322
        /* Manufacturing location - 2nd digit. */
8323
        *cp++ = 'A' + ((w & 0x1C00) >> 10);
8324
 
8325
        /* Product ID - 3rd, 4th digits. */
8326
        num = w & 0x3FF;
8327
        *cp++ = '0' + (num / 100);
8328
        num %= 100;
8329
        *cp++ = '0' + (num / 10);
8330
 
8331
        /* Product revision - 5th digit. */
8332
        *cp++ = 'A' + (num % 10);
8333
 
8334
        /*
8335
         * Second word
8336
         */
8337
        w = serialnum[1];
8338
 
8339
        /*
8340
         * Year - 6th digit.
8341
         *
8342
         * If bit 15 of third word is set, then the
8343
         * last digit of the year is greater than 7.
8344
         */
8345
        if (serialnum[2] & 0x8000) {
8346
            *cp++ = '8' + ((w & 0x1C0) >> 6);
8347
        } else {
8348
            *cp++ = '0' + ((w & 0x1C0) >> 6);
8349
        }
8350
 
8351
        /* Week of year - 7th, 8th digits. */
8352
        num = w & 0x003F;
8353
        *cp++ = '0' + num / 10;
8354
        num %= 10;
8355
        *cp++ = '0' + num;
8356
 
8357
        /*
8358
         * Third word
8359
         */
8360
        w = serialnum[2] & 0x7FFF;
8361
 
8362
        /* Serial number - 9th digit. */
8363
        *cp++ = 'A' + (w / 1000);
8364
 
8365
        /* 10th, 11th, 12th digits. */
8366
        num = w % 1000;
8367
        *cp++ = '0' + num / 100;
8368
        num %= 100;
8369
        *cp++ = '0' + num / 10;
8370
        num %= 10;
8371
        *cp++ = '0' + num;
8372
 
8373
        *cp = '\0';     /* Null Terminate the string. */
8374
        return ASC_TRUE;
8375
    }
8376
}
8377
 
8378
/*
8379
 * asc_prt_asc_board_eeprom()
8380
 *
8381
 * Print board EEPROM configuration.
8382
 *
8383
 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
8384
 * cf. asc_prt_line().
8385
 *
8386
 * Return the number of characters copied into 'cp'. No more than
8387
 * 'cplen' characters will be copied to 'cp'.
8388
 */
8389
STATIC int
8390
asc_prt_asc_board_eeprom(struct Scsi_Host *shp, char *cp, int cplen)
8391
{
8392
    asc_board_t        *boardp;
8393
    ASC_DVC_VAR        *asc_dvc_varp;
8394
    int                leftlen;
8395
    int                totlen;
8396
    int                len;
8397
    ASCEEP_CONFIG      *ep;
8398
    int                i;
8399
    int                isa_dma_speed[] = { 10, 8, 7, 6, 5, 4, 3, 2 };
8400
    uchar              serialstr[13];
8401
 
8402
    boardp = ASC_BOARDP(shp);
8403
    asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
8404
    ep = &boardp->eep_config.asc_eep;
8405
 
8406
    leftlen = cplen;
8407
    totlen = len = 0;
8408
 
8409
    len = asc_prt_line(cp, leftlen,
8410
"\nEEPROM Settings for AdvanSys SCSI Host %d:\n", shp->host_no);
8411
    ASC_PRT_NEXT();
8412
 
8413
    if (asc_get_eeprom_string((ushort *) &ep->adapter_info[0], serialstr) ==
8414
        ASC_TRUE) {
8415
        len = asc_prt_line(cp, leftlen, " Serial Number: %s\n", serialstr);
8416
        ASC_PRT_NEXT();
8417
    } else {
8418
        if (ep->adapter_info[5] == 0xBB) {
8419
            len = asc_prt_line(cp, leftlen,
8420
                " Default Settings Used for EEPROM-less Adapter.\n");
8421
            ASC_PRT_NEXT();
8422
        } else {
8423
            len = asc_prt_line(cp, leftlen,
8424
                " Serial Number Signature Not Present.\n");
8425
            ASC_PRT_NEXT();
8426
        }
8427
    }
8428
 
8429
    len = asc_prt_line(cp, leftlen,
8430
" Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
8431
        ep->chip_scsi_id, ep->max_total_qng, ep->max_tag_qng);
8432
    ASC_PRT_NEXT();
8433
 
8434
    len = asc_prt_line(cp, leftlen,
8435
" cntl %x, no_scam %x\n",
8436
        ep->cntl, ep->no_scam);
8437
    ASC_PRT_NEXT();
8438
 
8439
    len = asc_prt_line(cp, leftlen,
8440
" Target ID:           ");
8441
    ASC_PRT_NEXT();
8442
    for (i = 0; i <= ASC_MAX_TID; i++) {
8443
        len = asc_prt_line(cp, leftlen, " %d", i);
8444
        ASC_PRT_NEXT();
8445
    }
8446
    len = asc_prt_line(cp, leftlen, "\n");
8447
    ASC_PRT_NEXT();
8448
 
8449
    len = asc_prt_line(cp, leftlen,
8450
" Disconnects:         ");
8451
    ASC_PRT_NEXT();
8452
    for (i = 0; i <= ASC_MAX_TID; i++) {
8453
        len = asc_prt_line(cp, leftlen, " %c",
8454
            (ep->disc_enable & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8455
        ASC_PRT_NEXT();
8456
    }
8457
    len = asc_prt_line(cp, leftlen, "\n");
8458
    ASC_PRT_NEXT();
8459
 
8460
    len = asc_prt_line(cp, leftlen,
8461
" Command Queuing:     ");
8462
    ASC_PRT_NEXT();
8463
    for (i = 0; i <= ASC_MAX_TID; i++) {
8464
        len = asc_prt_line(cp, leftlen, " %c",
8465
            (ep->use_cmd_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8466
        ASC_PRT_NEXT();
8467
    }
8468
    len = asc_prt_line(cp, leftlen, "\n");
8469
    ASC_PRT_NEXT();
8470
 
8471
    len = asc_prt_line(cp, leftlen,
8472
" Start Motor:         ");
8473
    ASC_PRT_NEXT();
8474
    for (i = 0; i <= ASC_MAX_TID; i++) {
8475
        len = asc_prt_line(cp, leftlen, " %c",
8476
            (ep->start_motor & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8477
        ASC_PRT_NEXT();
8478
    }
8479
    len = asc_prt_line(cp, leftlen, "\n");
8480
    ASC_PRT_NEXT();
8481
 
8482
    len = asc_prt_line(cp, leftlen,
8483
" Synchronous Transfer:");
8484
    ASC_PRT_NEXT();
8485
    for (i = 0; i <= ASC_MAX_TID; i++) {
8486
        len = asc_prt_line(cp, leftlen, " %c",
8487
            (ep->init_sdtr & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8488
        ASC_PRT_NEXT();
8489
    }
8490
    len = asc_prt_line(cp, leftlen, "\n");
8491
    ASC_PRT_NEXT();
8492
 
8493
    if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
8494
        len = asc_prt_line(cp, leftlen,
8495
" Host ISA DMA speed:   %d MB/S\n",
8496
            isa_dma_speed[ep->isa_dma_speed]);
8497
        ASC_PRT_NEXT();
8498
    }
8499
 
8500
     return totlen;
8501
}
8502
 
8503
/*
8504
 * asc_prt_adv_board_eeprom()
8505
 *
8506
 * Print board EEPROM configuration.
8507
 *
8508
 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
8509
 * cf. asc_prt_line().
8510
 *
8511
 * Return the number of characters copied into 'cp'. No more than
8512
 * 'cplen' characters will be copied to 'cp'.
8513
 */
8514
STATIC int
8515
asc_prt_adv_board_eeprom(struct Scsi_Host *shp, char *cp, int cplen)
8516
{
8517
    asc_board_t        *boardp;
8518
    ADV_DVC_VAR        *adv_dvc_varp;
8519
    int                leftlen;
8520
    int                totlen;
8521
    int                len;
8522
    int                i;
8523
    char               *termstr;
8524
    uchar              serialstr[13];
8525
    ADVEEP_CONFIG      *ep;
8526
 
8527
    boardp = ASC_BOARDP(shp);
8528
    adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
8529
    ep = &boardp->eep_config.adv_eep;
8530
 
8531
    leftlen = cplen;
8532
    totlen = len = 0;
8533
 
8534
    len = asc_prt_line(cp, leftlen,
8535
"\nEEPROM Settings for AdvanSys SCSI Host %d:\n", shp->host_no);
8536
    ASC_PRT_NEXT();
8537
 
8538
    if (asc_get_eeprom_string(&ep->serial_number_word1, serialstr) ==
8539
        ASC_TRUE) {
8540
        len = asc_prt_line(cp, leftlen, " Serial Number: %s\n", serialstr);
8541
        ASC_PRT_NEXT();
8542
    } else {
8543
        len = asc_prt_line(cp, leftlen,
8544
            " Serial Number Signature Not Present.\n");
8545
        ASC_PRT_NEXT();
8546
    }
8547
 
8548
    len = asc_prt_line(cp, leftlen,
8549
" Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
8550
        ep->adapter_scsi_id, ep->max_host_qng, ep->max_dvc_qng);
8551
    ASC_PRT_NEXT();
8552
 
8553
    switch (ep->termination) {
8554
        case 1:
8555
            termstr = "Low Off/High Off";
8556
            break;
8557
        case 2:
8558
            termstr = "Low Off/High On";
8559
            break;
8560
        case 3:
8561
            termstr = "Low On/High On";
8562
            break;
8563
        default:
8564
        case 0:
8565
            termstr = "Automatic";
8566
            break;
8567
    }
8568
 
8569
    len = asc_prt_line(cp, leftlen,
8570
" termination: %u (%s), bios_ctrl: %x\n",
8571
        ep->termination, termstr, ep->bios_ctrl);
8572
    ASC_PRT_NEXT();
8573
 
8574
    len = asc_prt_line(cp, leftlen,
8575
" Target ID:           ");
8576
    ASC_PRT_NEXT();
8577
    for (i = 0; i <= ADV_MAX_TID; i++) {
8578
        len = asc_prt_line(cp, leftlen, " %X", i);
8579
        ASC_PRT_NEXT();
8580
    }
8581
    len = asc_prt_line(cp, leftlen, "\n");
8582
    ASC_PRT_NEXT();
8583
 
8584
    len = asc_prt_line(cp, leftlen,
8585
" Disconnects:         ");
8586
    ASC_PRT_NEXT();
8587
    for (i = 0; i <= ADV_MAX_TID; i++) {
8588
        len = asc_prt_line(cp, leftlen, " %c",
8589
            (ep->disc_enable & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8590
        ASC_PRT_NEXT();
8591
    }
8592
    len = asc_prt_line(cp, leftlen, "\n");
8593
    ASC_PRT_NEXT();
8594
 
8595
    len = asc_prt_line(cp, leftlen,
8596
" Command Queuing:     ");
8597
    ASC_PRT_NEXT();
8598
    for (i = 0; i <= ADV_MAX_TID; i++) {
8599
        len = asc_prt_line(cp, leftlen, " %c",
8600
            (ep->tagqng_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8601
        ASC_PRT_NEXT();
8602
    }
8603
    len = asc_prt_line(cp, leftlen, "\n");
8604
    ASC_PRT_NEXT();
8605
 
8606
    len = asc_prt_line(cp, leftlen,
8607
" Start Motor:         ");
8608
    ASC_PRT_NEXT();
8609
    for (i = 0; i <= ADV_MAX_TID; i++) {
8610
        len = asc_prt_line(cp, leftlen, " %c",
8611
            (ep->start_motor & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8612
        ASC_PRT_NEXT();
8613
    }
8614
    len = asc_prt_line(cp, leftlen, "\n");
8615
    ASC_PRT_NEXT();
8616
 
8617
    len = asc_prt_line(cp, leftlen,
8618
" Synchronous Transfer:");
8619
    ASC_PRT_NEXT();
8620
    for (i = 0; i <= ADV_MAX_TID; i++) {
8621
        len = asc_prt_line(cp, leftlen, " %c",
8622
            (ep->sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8623
        ASC_PRT_NEXT();
8624
    }
8625
    len = asc_prt_line(cp, leftlen, "\n");
8626
    ASC_PRT_NEXT();
8627
 
8628
    len = asc_prt_line(cp, leftlen,
8629
" Ultra Transfer:      ");
8630
    ASC_PRT_NEXT();
8631
    for (i = 0; i <= ADV_MAX_TID; i++) {
8632
        len = asc_prt_line(cp, leftlen, " %c",
8633
            (ep->ultra_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8634
        ASC_PRT_NEXT();
8635
    }
8636
    len = asc_prt_line(cp, leftlen, "\n");
8637
    ASC_PRT_NEXT();
8638
 
8639
    len = asc_prt_line(cp, leftlen,
8640
" Wide Transfer:       ");
8641
    ASC_PRT_NEXT();
8642
    for (i = 0; i <= ADV_MAX_TID; i++) {
8643
        len = asc_prt_line(cp, leftlen, " %c",
8644
            (ep->wdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8645
        ASC_PRT_NEXT();
8646
    }
8647
    len = asc_prt_line(cp, leftlen, "\n");
8648
    ASC_PRT_NEXT();
8649
 
8650
    return totlen;
8651
}
8652
 
8653
/*
8654
 * asc_prt_driver_conf()
8655
 *
8656
 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
8657
 * cf. asc_prt_line().
8658
 *
8659
 * Return the number of characters copied into 'cp'. No more than
8660
 * 'cplen' characters will be copied to 'cp'.
8661
 */
8662
STATIC int
8663
asc_prt_driver_conf(struct Scsi_Host *shp, char *cp, int cplen)
8664
{
8665
    asc_board_t            *boardp;
8666
    int                    leftlen;
8667
    int                    totlen;
8668
    int                    len;
8669
    int                    chip_scsi_id;
8670
#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
8671
    int                    i;
8672
#endif /* version >= v1.3.89 */
8673
 
8674
    boardp = ASC_BOARDP(shp);
8675
 
8676
    leftlen = cplen;
8677
    totlen = len = 0;
8678
 
8679
    len = asc_prt_line(cp, leftlen,
8680
"\nLinux Driver Configuration and Information for AdvanSys SCSI Host %d:\n",
8681
        shp->host_no);
8682
    ASC_PRT_NEXT();
8683
 
8684
    len = asc_prt_line(cp, leftlen,
8685
#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,89)
8686
" host_busy %u, last_reset %u, max_id %u, max_lun %u\n",
8687
        shp->host_busy, shp->last_reset, shp->max_id, shp->max_lun);
8688
#else /* version >= v1.3.89 */
8689
" host_busy %u, last_reset %u, max_id %u, max_lun %u, max_channel %u\n",
8690
        shp->host_busy, shp->last_reset, shp->max_id, shp->max_lun,
8691
        shp->max_channel);
8692
#endif /* version >= v1.3.89 */
8693
    ASC_PRT_NEXT();
8694
 
8695
    len = asc_prt_line(cp, leftlen,
8696
#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,57)
8697
" can_queue %d, this_id %d, sg_tablesize %u, cmd_per_lun %u\n",
8698
        shp->can_queue, shp->this_id, shp->sg_tablesize, shp->cmd_per_lun);
8699
#else /* version >= v1.3.57 */
8700
" unique_id %d, can_queue %d, this_id %d, sg_tablesize %u, cmd_per_lun %u\n",
8701
        shp->unique_id, shp->can_queue, shp->this_id, shp->sg_tablesize,
8702
        shp->cmd_per_lun);
8703
#endif /* version >= v1.3.57 */
8704
    ASC_PRT_NEXT();
8705
 
8706
    len = asc_prt_line(cp, leftlen,
8707
#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,57)
8708
" unchecked_isa_dma %d, loaded_as_module %d\n",
8709
        shp->unchecked_isa_dma, shp->loaded_as_module);
8710
#else /* version >= v1.3.57 */
8711
" unchecked_isa_dma %d, use_clustering %d, loaded_as_module %d\n",
8712
        shp->unchecked_isa_dma, shp->use_clustering, shp->loaded_as_module);
8713
#endif /* version >= v1.3.57 */
8714
    ASC_PRT_NEXT();
8715
 
8716
    len = asc_prt_line(cp, leftlen, " flags %x, last_reset %x, jiffies %x\n",
8717
        boardp->flags, boardp->last_reset, jiffies);
8718
    ASC_PRT_NEXT();
8719
 
8720
    if (ASC_NARROW_BOARD(boardp)) {
8721
        chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
8722
    } else {
8723
        chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
8724
    }
8725
 
8726
#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
8727
    if (boardp->flags & ASC_SELECT_QUEUE_DEPTHS) {
8728
        len = asc_prt_line(cp, leftlen, " queue_depth:");
8729
        ASC_PRT_NEXT();
8730
        for (i = 0; i <= ADV_MAX_TID; i++) {
8731
            if ((chip_scsi_id == i) ||
8732
                ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8733
                continue;
8734
            }
8735
            if (boardp->device[i] == NULL) {
8736
                continue;
8737
            }
8738
            len = asc_prt_line(cp, leftlen, " %X:%d",
8739
                i, boardp->device[i]->queue_depth);
8740
            ASC_PRT_NEXT();
8741
        }
8742
        len = asc_prt_line(cp, leftlen, "\n");
8743
        ASC_PRT_NEXT();
8744
    }
8745
#endif /* version >= v1.3.89 */
8746
 
8747
#if ASC_QUEUE_FLOW_CONTROL
8748
    if (ASC_NARROW_BOARD(boardp)) {
8749
        len = asc_prt_line(cp, leftlen, " queue_curr_depth:");
8750
        ASC_PRT_NEXT();
8751
        /* Use ASC_MAX_TID for Narrow Board. */
8752
        for (i = 0; i <= ASC_MAX_TID; i++) {
8753
            if ((boardp->asc_dvc_cfg.chip_scsi_id == i) ||
8754
                ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8755
                continue;
8756
            }
8757
            if (boardp->device[i] == NULL) {
8758
                continue;
8759
            }
8760
            len = asc_prt_line(cp, leftlen, " %d:%d",
8761
                i, boardp->device[i]->queue_curr_depth);
8762
            ASC_PRT_NEXT();
8763
        }
8764
        len = asc_prt_line(cp, leftlen, "\n");
8765
        ASC_PRT_NEXT();
8766
 
8767
        len = asc_prt_line(cp, leftlen, " queue_count:");
8768
        ASC_PRT_NEXT();
8769
        /* Use ASC_MAX_TID for Narrow Board. */
8770
        for (i = 0; i <= ASC_MAX_TID; i++) {
8771
            if ((boardp->asc_dvc_cfg.chip_scsi_id == i) ||
8772
                ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8773
                continue;
8774
            }
8775
            if (boardp->device[i] == NULL) {
8776
                continue;
8777
            }
8778
            len = asc_prt_line(cp, leftlen, " %d:%d",
8779
                i, boardp->device[i]->queue_count);
8780
            ASC_PRT_NEXT();
8781
        }
8782
        len = asc_prt_line(cp, leftlen, "\n");
8783
        ASC_PRT_NEXT();
8784
    }
8785
#endif /* ASC_QUEUE_FLOW_CONTROL */
8786
 
8787
    return totlen;
8788
}
8789
 
8790
/*
8791
 * asc_prt_asc_board_info()
8792
 *
8793
 * Print dynamic board configuration information.
8794
 *
8795
 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
8796
 * cf. asc_prt_line().
8797
 *
8798
 * Return the number of characters copied into 'cp'. No more than
8799
 * 'cplen' characters will be copied to 'cp'.
8800
 */
8801
STATIC int
8802
asc_prt_asc_board_info(struct Scsi_Host *shp, char *cp, int cplen)
8803
{
8804
    asc_board_t            *boardp;
8805
    int                    leftlen;
8806
    int                    totlen;
8807
    int                    len;
8808
    ASC_DVC_VAR            *v;
8809
    ASC_DVC_CFG            *c;
8810
    int                    i;
8811
 
8812
    boardp = ASC_BOARDP(shp);
8813
    v = &boardp->dvc_var.asc_dvc_var;
8814
    c = &boardp->dvc_cfg.asc_dvc_cfg;
8815
 
8816
    leftlen = cplen;
8817
    totlen = len = 0;
8818
 
8819
    len = asc_prt_line(cp, leftlen,
8820
"\nAsc Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
8821
    shp->host_no);
8822
    ASC_PRT_NEXT();
8823
 
8824
    len = asc_prt_line(cp, leftlen,
8825
" chip_version %u, lib_version %x, lib_serial_no %u, mcode_date %x\n",
8826
        c->chip_version, c->lib_version, c->lib_serial_no, c->mcode_date);
8827
    ASC_PRT_NEXT();
8828
 
8829
    len = asc_prt_line(cp, leftlen,
8830
" mcode_version %x, err_code %u\n",
8831
         c->mcode_version, v->err_code);
8832
    ASC_PRT_NEXT();
8833
 
8834
    /* Current number of commands waiting for the host. */
8835
    len = asc_prt_line(cp, leftlen,
8836
" Total Command Pending: %d\n", v->cur_total_qng);
8837
    ASC_PRT_NEXT();
8838
 
8839
    len = asc_prt_line(cp, leftlen,
8840
" Command Queuing:");
8841
    ASC_PRT_NEXT();
8842
    for (i = 0; i <= ASC_MAX_TID; i++) {
8843
        if ((boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id == i) ||
8844
            ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8845
            continue;
8846
        }
8847
        len = asc_prt_line(cp, leftlen, " %d:%c",
8848
            i, (v->use_tagged_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8849
        ASC_PRT_NEXT();
8850
    }
8851
    len = asc_prt_line(cp, leftlen, "\n");
8852
    ASC_PRT_NEXT();
8853
 
8854
    /* Current number of commands waiting for a device. */
8855
    len = asc_prt_line(cp, leftlen,
8856
" Command Queue Pending:");
8857
    ASC_PRT_NEXT();
8858
    for (i = 0; i <= ASC_MAX_TID; i++) {
8859
        if ((boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id == i) ||
8860
            ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8861
            continue;
8862
        }
8863
        len = asc_prt_line(cp, leftlen, " %d:%u", i, v->cur_dvc_qng[i]);
8864
        ASC_PRT_NEXT();
8865
    }
8866
    len = asc_prt_line(cp, leftlen, "\n");
8867
    ASC_PRT_NEXT();
8868
 
8869
    /* Current limit on number of commands that can be sent to a device. */
8870
    len = asc_prt_line(cp, leftlen,
8871
" Command Queue Limit:");
8872
    ASC_PRT_NEXT();
8873
    for (i = 0; i <= ASC_MAX_TID; i++) {
8874
        if ((boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id == i) ||
8875
            ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8876
            continue;
8877
        }
8878
        len = asc_prt_line(cp, leftlen, " %d:%u", i, v->max_dvc_qng[i]);
8879
        ASC_PRT_NEXT();
8880
    }
8881
    len = asc_prt_line(cp, leftlen, "\n");
8882
    ASC_PRT_NEXT();
8883
 
8884
    /* Indicate whether the device has returned queue full status. */
8885
    len = asc_prt_line(cp, leftlen,
8886
" Command Queue Full:");
8887
    ASC_PRT_NEXT();
8888
    for (i = 0; i <= ASC_MAX_TID; i++) {
8889
        if ((boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id == i) ||
8890
            ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8891
            continue;
8892
        }
8893
        if (boardp->queue_full & ADV_TID_TO_TIDMASK(i)) {
8894
            len = asc_prt_line(cp, leftlen, " %d:Y-%d",
8895
                i, boardp->queue_full_cnt[i]);
8896
        } else {
8897
            len = asc_prt_line(cp, leftlen, " %d:N", i);
8898
        }
8899
        ASC_PRT_NEXT();
8900
    }
8901
    len = asc_prt_line(cp, leftlen, "\n");
8902
    ASC_PRT_NEXT();
8903
 
8904
    len = asc_prt_line(cp, leftlen,
8905
" Synchronous Transfer:");
8906
    ASC_PRT_NEXT();
8907
    for (i = 0; i <= ASC_MAX_TID; i++) {
8908
        if ((boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id == i) ||
8909
            ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8910
            continue;
8911
        }
8912
        len = asc_prt_line(cp, leftlen, " %d:%c",
8913
            i, (v->sdtr_done & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8914
        ASC_PRT_NEXT();
8915
    }
8916
    len = asc_prt_line(cp, leftlen, "\n");
8917
    ASC_PRT_NEXT();
8918
 
8919
    for (i = 0; i <= ASC_MAX_TID; i++) {
8920
        uchar syn_period_ix;
8921
 
8922
        if ((boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id == i) ||
8923
            ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8924
            continue;
8925
        }
8926
        if ((v->sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
8927
            continue;
8928
        }
8929
        syn_period_ix = (boardp->sdtr_data[i] >> 4) & (v->max_sdtr_index - 1);
8930
        len = asc_prt_line(cp, leftlen, "  %d:", i);
8931
        ASC_PRT_NEXT();
8932
 
8933
        len = asc_prt_line(cp, leftlen,
8934
            " Transfer Period Factor: %d (%d.%d Mhz),",
8935
            v->sdtr_period_tbl[syn_period_ix],
8936
            250 / v->sdtr_period_tbl[syn_period_ix],
8937
            ASC_TENTHS(250, v->sdtr_period_tbl[syn_period_ix]));
8938
        ASC_PRT_NEXT();
8939
 
8940
        len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d\n",
8941
            boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET);
8942
        ASC_PRT_NEXT();
8943
    }
8944
 
8945
    return totlen;
8946
}
8947
 
8948
/*
8949
 * asc_prt_adv_board_info()
8950
 *
8951
 * Print dynamic board configuration information.
8952
 *
8953
 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
8954
 * cf. asc_prt_line().
8955
 *
8956
 * Return the number of characters copied into 'cp'. No more than
8957
 * 'cplen' characters will be copied to 'cp'.
8958
 */
8959
STATIC int
8960
asc_prt_adv_board_info(struct Scsi_Host *shp, char *cp, int cplen)
8961
{
8962
    asc_board_t            *boardp;
8963
    int                    leftlen;
8964
    int                    totlen;
8965
    int                    len;
8966
    int                    i;
8967
    ADV_DVC_VAR            *v;
8968
    ADV_DVC_CFG            *c;
8969
    AdvPortAddr            iop_base;
8970
    ushort                 chip_scsi_id;
8971
    ushort                 lramword;
8972
    uchar                  lrambyte;
8973
    ushort                 sdtr_able;
8974
    ushort                 period;
8975
 
8976
    boardp = ASC_BOARDP(shp);
8977
    v = &boardp->dvc_var.adv_dvc_var;
8978
    c = &boardp->dvc_cfg.adv_dvc_cfg;
8979
    iop_base = v->iop_base;
8980
    chip_scsi_id = v->chip_scsi_id;
8981
 
8982
    leftlen = cplen;
8983
    totlen = len = 0;
8984
 
8985
    len = asc_prt_line(cp, leftlen,
8986
"\nAdv Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
8987
    shp->host_no);
8988
    ASC_PRT_NEXT();
8989
 
8990
    len = asc_prt_line(cp, leftlen,
8991
" iop_base %lx, cable_detect: %X, err_code %u, idle_cmd_done %u\n",
8992
         v->iop_base,
8993
         AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1) & CABLE_DETECT,
8994
         v->err_code, v->idle_cmd_done);
8995
    ASC_PRT_NEXT();
8996
 
8997
    len = asc_prt_line(cp, leftlen,
8998
" chip_version %u, lib_version %x, mcode_date %x, mcode_version %x\n",
8999
        c->chip_version, c->lib_version, c->mcode_date, c->mcode_version);
9000
    ASC_PRT_NEXT();
9001
 
9002
    AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, lramword);
9003
    len = asc_prt_line(cp, leftlen,
9004
" Queuing Enabled:");
9005
    ASC_PRT_NEXT();
9006
    for (i = 0; i <= ADV_MAX_TID; i++) {
9007
        if ((chip_scsi_id == i) ||
9008
            ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
9009
            continue;
9010
        }
9011
 
9012
        len = asc_prt_line(cp, leftlen, " %X:%c",
9013
            i, (lramword & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
9014
        ASC_PRT_NEXT();
9015
    }
9016
    len = asc_prt_line(cp, leftlen, "\n");
9017
    ASC_PRT_NEXT();
9018
 
9019
    len = asc_prt_line(cp, leftlen,
9020
" Queue Limit:");
9021
    ASC_PRT_NEXT();
9022
    for (i = 0; i <= ADV_MAX_TID; i++) {
9023
        if ((chip_scsi_id == i) ||
9024
            ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
9025
            continue;
9026
        }
9027
 
9028
        AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + i, lrambyte);
9029
 
9030
        len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
9031
        ASC_PRT_NEXT();
9032
    }
9033
    len = asc_prt_line(cp, leftlen, "\n");
9034
    ASC_PRT_NEXT();
9035
 
9036
    len = asc_prt_line(cp, leftlen,
9037
" Command Pending:");
9038
    ASC_PRT_NEXT();
9039
    for (i = 0; i <= ADV_MAX_TID; i++) {
9040
        if ((chip_scsi_id == i) ||
9041
            ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
9042
            continue;
9043
        }
9044
 
9045
        AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_QUEUED_CMD + i, lrambyte);
9046
 
9047
        len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
9048
        ASC_PRT_NEXT();
9049
    }
9050
    len = asc_prt_line(cp, leftlen, "\n");
9051
    ASC_PRT_NEXT();
9052
 
9053
    AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, lramword);
9054
    len = asc_prt_line(cp, leftlen,
9055
" Wide Enabled:");
9056
    ASC_PRT_NEXT();
9057
    for (i = 0; i <= ADV_MAX_TID; i++) {
9058
        if ((chip_scsi_id == i) ||
9059
            ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
9060
            continue;
9061
        }
9062
 
9063
        len = asc_prt_line(cp, leftlen, " %X:%c",
9064
            i, (lramword & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
9065
        ASC_PRT_NEXT();
9066
    }
9067
    len = asc_prt_line(cp, leftlen, "\n");
9068
    ASC_PRT_NEXT();
9069
 
9070
    len = asc_prt_line(cp, leftlen,
9071
" Transfer Bit Width:");
9072
    ASC_PRT_NEXT();
9073
    for (i = 0; i <= ADV_MAX_TID; i++) {
9074
        if ((chip_scsi_id == i) ||
9075
            ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
9076
            continue;
9077
        }
9078
 
9079
        AdvReadWordLram(iop_base, ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
9080
            lramword);
9081
        len = asc_prt_line(cp, leftlen, " %X:%d",
9082
            i, (lramword & 0x8000) ? 16 : 8);
9083
        ASC_PRT_NEXT();
9084
    }
9085
    len = asc_prt_line(cp, leftlen, "\n");
9086
    ASC_PRT_NEXT();
9087
 
9088
    AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
9089
    len = asc_prt_line(cp, leftlen,
9090
" Synchronous Enabled:");
9091
    ASC_PRT_NEXT();
9092
    for (i = 0; i <= ADV_MAX_TID; i++) {
9093
        if ((chip_scsi_id == i) ||
9094
            ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
9095
            continue;
9096
        }
9097
 
9098
        len = asc_prt_line(cp, leftlen, " %X:%c",
9099
            i, (sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
9100
        ASC_PRT_NEXT();
9101
    }
9102
    len = asc_prt_line(cp, leftlen, "\n");
9103
    ASC_PRT_NEXT();
9104
 
9105
    for (i = 0; i <= ADV_MAX_TID; i++) {
9106
 
9107
        AdvReadWordLram(iop_base, ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
9108
            lramword);
9109
        lramword &= ~0x8000;
9110
 
9111
        if ((chip_scsi_id == i) ||
9112
            ((sdtr_able & ADV_TID_TO_TIDMASK(i)) == 0) ||
9113
            (lramword == 0)) {
9114
            continue;
9115
        }
9116
 
9117
        len = asc_prt_line(cp, leftlen, "  %X:", i);
9118
        ASC_PRT_NEXT();
9119
 
9120
        period = (((lramword >> 8) * 25) + 50)/4;
9121
 
9122
        len = asc_prt_line(cp, leftlen,
9123
            " Transfer Period Factor: %d (%d.%d Mhz),",
9124
            period, 250/period, ASC_TENTHS(250, period));
9125
        ASC_PRT_NEXT();
9126
 
9127
        len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d\n",
9128
            lramword & 0x1F);
9129
        ASC_PRT_NEXT();
9130
    }
9131
 
9132
    return totlen;
9133
}
9134
 
9135
/*
9136
 * asc_proc_copy()
9137
 *
9138
 * Copy proc information to a read buffer taking into account the current
9139
 * read offset in the file and the remaining space in the read buffer.
9140
 */
9141
STATIC int
9142
asc_proc_copy(off_t advoffset, off_t offset, char *curbuf, int leftlen,
9143
              char *cp, int cplen)
9144
{
9145
    int cnt = 0;
9146
 
9147
    ASC_DBG3(2, "asc_proc_copy: offset %d, advoffset %d, cplen %d\n",
9148
            (unsigned) offset, (unsigned) advoffset, cplen);
9149
    if (offset <= advoffset) {
9150
        /* Read offset below current offset, copy everything. */
9151
        cnt = ASC_MIN(cplen, leftlen);
9152
        ASC_DBG3(2, "asc_proc_copy: curbuf %x, cp %x, cnt %d\n",
9153
                (unsigned) curbuf, (unsigned) cp, cnt);
9154
        memcpy(curbuf, cp, cnt);
9155
    } else if (offset < advoffset + cplen) {
9156
        /* Read offset within current range, partial copy. */
9157
        cnt = (advoffset + cplen) - offset;
9158
        cp = (cp + cplen) - cnt;
9159
        cnt = ASC_MIN(cnt, leftlen);
9160
        ASC_DBG3(2, "asc_proc_copy: curbuf %x, cp %x, cnt %d\n",
9161
                (unsigned) curbuf, (unsigned) cp, cnt);
9162
        memcpy(curbuf, cp, cnt);
9163
    }
9164
    return cnt;
9165
}
9166
 
9167
/*
9168
 * asc_prt_line()
9169
 *
9170
 * If 'cp' is NULL print to the console, otherwise print to a buffer.
9171
 *
9172
 * Return 0 if printing to the console, otherwise return the number of
9173
 * bytes written to the buffer.
9174
 *
9175
 * Note: If any single line is greater than ASC_PRTLINE_SIZE bytes the stack
9176
 * will be corrupted. 's[]' is defined to be ASC_PRTLINE_SIZE bytes.
9177
 */
9178
STATIC int
9179
asc_prt_line(char *buf, int buflen, char *fmt, ...)
9180
{
9181
    va_list        args;
9182
    int            ret;
9183
    char        s[ASC_PRTLINE_SIZE];
9184
 
9185
    va_start(args, fmt);
9186
    ret = vsprintf(s, fmt, args);
9187
    ASC_ASSERT(ret < ASC_PRTLINE_SIZE);
9188
    if (buf == NULL) {
9189
        (void) printk(s);
9190
        ret = 0;
9191
    } else {
9192
        ret = ASC_MIN(buflen, ret);
9193
        memcpy(buf, s, ret);
9194
    }
9195
    va_end(args);
9196
    return ret;
9197
}
9198
#endif /* version >= v1.3.0 */
9199
 
9200
 
9201
/*
9202
 * --- Functions Required by the Asc Library
9203
 */
9204
 
9205
/*
9206
 * Delay for 'n' milliseconds. Don't use the 'jiffies'
9207
 * global variable which is incremented once every 5 ms
9208
 * from a timer interrupt, because this function may be
9209
 * called when interrupts are disabled.
9210
 */
9211
STATIC void
9212
DvcSleepMilliSecond(ulong n)
9213
{
9214
    ulong i;
9215
 
9216
    ASC_DBG1(4, "DvcSleepMilliSecond: %lu\n", n);
9217
    for (i = 0; i < n; i++) {
9218
        udelay(1000);
9219
    }
9220
}
9221
 
9222
STATIC int
9223
DvcEnterCritical(void)
9224
{
9225
    int    flags;
9226
 
9227
    save_flags(flags);
9228
    cli();
9229
    return flags;
9230
}
9231
 
9232
STATIC void
9233
DvcLeaveCritical(int flags)
9234
{
9235
    restore_flags(flags);
9236
}
9237
 
9238
STATIC ulong
9239
DvcGetSGList(ASC_DVC_VAR *asc_dvc_sg, uchar *buf_addr, ulong buf_len,
9240
             ASC_SG_HEAD *asc_sg_head_ptr)
9241
{
9242
    ulong buf_size;
9243
 
9244
    buf_size = buf_len;
9245
    asc_sg_head_ptr->entry_cnt = 1;
9246
#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
9247
    asc_sg_head_ptr->sg_list[0].addr = (ulong) buf_addr;
9248
#else /* version >= v2.0.0 */
9249
    asc_sg_head_ptr->sg_list[0].addr = virt_to_bus(buf_addr);
9250
#endif /* version >= v2.0.0 */
9251
    asc_sg_head_ptr->sg_list[0].bytes = buf_size;
9252
    return buf_size;
9253
}
9254
 
9255
/*
9256
 * void
9257
 * DvcPutScsiQ(PortAddr iop_base, ushort s_addr, ushort *outbuf, int words)
9258
 *
9259
 * Calling/Exit State:
9260
 *    none
9261
 *
9262
 * Description:
9263
 *     Output an ASC_SCSI_Q structure to the chip
9264
 */
9265
STATIC void
9266
DvcPutScsiQ(PortAddr iop_base, ushort s_addr, ushort *outbuf, int words)
9267
{
9268
    int    i;
9269
 
9270
    ASC_DBG_PRT_HEX(2, "DvcPutScsiQ", (uchar *) outbuf, 2 * words);
9271
    AscSetChipLramAddr(iop_base, s_addr);
9272
    for (i = 0; i < words; i++, outbuf++) {
9273
        if (i == 2 || i == 10) {
9274
            continue;
9275
        }
9276
        AscSetChipLramDataNoSwap(iop_base, *outbuf);
9277
    }
9278
}
9279
 
9280
/*
9281
 * void
9282
 * DvcGetQinfo(PortAddr iop_base, ushort s_addr, ushort *inbuf, int words)
9283
 *
9284
 * Calling/Exit State:
9285
 *    none
9286
 *
9287
 * Description:
9288
 *     Input an ASC_QDONE_INFO structure from the chip
9289
 */
9290
STATIC void
9291
DvcGetQinfo(PortAddr iop_base, ushort s_addr, ushort *inbuf, int words)
9292
{
9293
    int    i;
9294
 
9295
    AscSetChipLramAddr(iop_base, s_addr);
9296
    for (i = 0; i < words; i++, inbuf++) {
9297
        if (i == 5) {
9298
            continue;
9299
        }
9300
        *inbuf = AscGetChipLramDataNoSwap(iop_base);
9301
    }
9302
    ASC_DBG_PRT_HEX(2, "DvcGetQinfo", (uchar *) inbuf, 2 * words);
9303
}
9304
 
9305
/*
9306
 * void    DvcOutPortWords(ushort iop_base, ushort &outbuf, int words)
9307
 *
9308
 * Calling/Exit State:
9309
 *    none
9310
 *
9311
 * Description:
9312
 *     output a buffer to an i/o port address
9313
 */
9314
STATIC void
9315
DvcOutPortWords(ushort iop_base, ushort *outbuf, int words)
9316
{
9317
    int    i;
9318
 
9319
    for (i = 0; i < words; i++, outbuf++)
9320
        outpw(iop_base, *outbuf);
9321
}
9322
 
9323
/*
9324
 * void    DvcInPortWords(ushort iop_base, ushort &outbuf, int words)
9325
 *
9326
 * Calling/Exit State:
9327
 *    none
9328
 *
9329
 * Description:
9330
 *     input a buffer from an i/o port address
9331
 */
9332
STATIC void
9333
DvcInPortWords(ushort iop_base, ushort *inbuf, int words)
9334
{
9335
    int    i;
9336
 
9337
    for (i = 0; i < words; i++, inbuf++)
9338
        *inbuf = inpw(iop_base);
9339
}
9340
 
9341
/*
9342
 * void DvcOutPortDWords(PortAddr port, ulong *pdw, int dwords)
9343
 *
9344
 * Calling/Exit State:
9345
 *    none
9346
 *
9347
 * Description:
9348
 *     output a buffer of 32-bit integers to an i/o port address in
9349
 *  16 bit integer units
9350
 */
9351
STATIC void
9352
DvcOutPortDWords(PortAddr port, ulong *pdw, int dwords)
9353
{
9354
    int        i;
9355
    int        words;
9356
    ushort    *pw;
9357
 
9358
    pw = (ushort *) pdw;
9359
    words = dwords << 1;
9360
    for(i = 0; i < words; i++, pw++) {
9361
        outpw(port, *pw);
9362
    }
9363
    return;
9364
}
9365
 
9366
/*
9367
 * Read a PCI configuration byte.
9368
 */
9369
ASC_INITFUNC(
9370
STATIC uchar
9371
DvcReadPCIConfigByte(
9372
        ASC_DVC_VAR asc_ptr_type *asc_dvc,
9373
        ushort offset)
9374
)
9375
{
9376
#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
9377
#ifdef ASC_CONFIG_PCI
9378
    PCI_DATA    pciData;
9379
 
9380
    pciData.bus = ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info);
9381
    pciData.slot = ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info);
9382
    pciData.func = ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info);
9383
    pciData.offset = offset;
9384
    pciData.type = pci_scan_method;
9385
    return asc_get_cfg_byte(&pciData);
9386
#else /* ASC_CONFIG_PCI */
9387
    return 0;
9388
#endif /* ASC_CONFIG_PCI */
9389
#else /* version >= v2.1.93 */ 
9390
#ifdef CONFIG_PCI
9391
    uchar byte_data;
9392
    pcibios_read_config_byte(ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info),
9393
        PCI_DEVFN(ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info),
9394
            ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info)),
9395
        offset, &byte_data);
9396
    return byte_data;
9397
#else /* CONFIG_PCI */
9398
    return 0;
9399
#endif /* CONFIG_PCI */
9400
#endif /* version >= v2.1.93 */ 
9401
}
9402
 
9403
/*
9404
 * Write a PCI configuration byte.
9405
 */
9406
ASC_INITFUNC(
9407
STATIC void
9408
DvcWritePCIConfigByte(
9409
        ASC_DVC_VAR asc_ptr_type *asc_dvc,
9410
        ushort offset,
9411
        uchar  byte_data)
9412
)
9413
{
9414
#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
9415
#ifdef ASC_CONFIG_PCI
9416
    PCI_DATA    pciData;
9417
 
9418
    pciData.bus = ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info);
9419
    pciData.slot = ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info);
9420
    pciData.func = ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info);
9421
    pciData.offset = offset;
9422
    pciData.type = pci_scan_method;
9423
    asc_put_cfg_byte(&pciData, byte_data);
9424
#endif /* ASC_CONFIG_PCI */
9425
#else /* version >= v2.1.93 */ 
9426
#ifdef CONFIG_PCI
9427
    pcibios_write_config_byte(ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info),
9428
        PCI_DEVFN(ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info),
9429
            ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info)),
9430
        offset, byte_data);
9431
#endif /* CONFIG_PCI */
9432
#endif /* version >= v2.1.93 */ 
9433
}
9434
 
9435
/*
9436
 * Return the BIOS address of the adapter at the specified
9437
 * I/O port and with the specified bus type.
9438
 */
9439
ASC_INITFUNC(
9440
STATIC ushort
9441
AscGetChipBiosAddress(
9442
        PortAddr iop_base,
9443
        ushort bus_type
9444
)
9445
)
9446
{
9447
    ushort  cfg_lsw ;
9448
    ushort  bios_addr ;
9449
 
9450
    /*
9451
     * The PCI BIOS is re-located by the motherboard BIOS. Because
9452
     * of this the driver can not determine where a PCI BIOS is
9453
     * loaded and executes.
9454
     */
9455
    if (bus_type & ASC_IS_PCI)
9456
    {
9457
        return(0);
9458
    }
9459
 
9460
    if((bus_type & ASC_IS_EISA) != 0)
9461
    {
9462
        cfg_lsw = AscGetEisaChipCfg(iop_base) ;
9463
        cfg_lsw &= 0x000F ;
9464
        bios_addr = (ushort)(ASC_BIOS_MIN_ADDR  +
9465
                                (cfg_lsw * ASC_BIOS_BANK_SIZE)) ;
9466
        return(bios_addr) ;
9467
    }/* if */
9468
 
9469
    cfg_lsw = AscGetChipCfgLsw(iop_base) ;
9470
 
9471
    /*
9472
    *  ISA PnP uses the top bit as the 32K BIOS flag
9473
    */
9474
    if (bus_type == ASC_IS_ISAPNP)
9475
    {
9476
        cfg_lsw &= 0x7FFF;
9477
    }/* if */
9478
 
9479
    bios_addr = (ushort)(((cfg_lsw >> 12) * ASC_BIOS_BANK_SIZE) +
9480
            ASC_BIOS_MIN_ADDR) ;
9481
    return(bios_addr) ;
9482
}
9483
 
9484
 
9485
/*
9486
 * --- Functions Required by the Adv Library
9487
 */
9488
 
9489
/*
9490
 * DvcGetPhyAddr()
9491
 *
9492
 * Return the physical address of 'vaddr' and set '*lenp' to the
9493
 * number of physically contiguous bytes that follow 'vaddr'.
9494
 * 'flag' indicates the type of structure whose physical address
9495
 * is being translated.
9496
 *
9497
 * Note: Because Linux currently doesn't page the kernel and all
9498
 * kernel buffers are physically contiguous, leave '*lenp' unchanged.
9499
 */
9500
ulong
9501
DvcGetPhyAddr(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq,
9502
        uchar *vaddr, long *lenp, int flag)
9503
{
9504
    ulong                paddr;
9505
 
9506
#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
9507
    paddr = (ulong) vaddr;
9508
#else /* version >= v2.0.0 */
9509
    paddr = virt_to_bus(vaddr);
9510
#endif /* version >= v2.0.0 */
9511
 
9512
    ASC_DBG4(4,
9513
        "DvcGetPhyAddr: vaddr 0x%lx, lenp 0x%lx *lenp %lu, paddr 0x%lx\n",
9514
        (ulong) vaddr, (ulong) lenp, (ulong) *((ulong *) lenp), paddr);
9515
 
9516
    return paddr;
9517
}
9518
 
9519
/*
9520
 * Read a PCI configuration byte.
9521
 */
9522
ASC_INITFUNC(
9523
STATIC uchar
9524
DvcAdvReadPCIConfigByte(
9525
        ADV_DVC_VAR *asc_dvc,
9526
        ushort offset)
9527
)
9528
{
9529
#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
9530
#ifdef ASC_CONFIG_PCI
9531
    PCI_DATA    pciData;
9532
 
9533
    pciData.bus = ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info);
9534
    pciData.slot = ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info);
9535
    pciData.func = ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info);
9536
    pciData.offset = offset;
9537
    pciData.type = pci_scan_method;
9538
    return asc_get_cfg_byte(&pciData);
9539
#else /* ASC_CONFIG_PCI */
9540
    return 0;
9541
#endif /* ASC_CONFIG_PCI */
9542
#else /* version >= v2.1.93 */ 
9543
#ifdef CONFIG_PCI
9544
    uchar byte_data;
9545
    pcibios_read_config_byte(ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info),
9546
        PCI_DEVFN(ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info),
9547
            ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info)),
9548
        offset, &byte_data);
9549
    return byte_data;
9550
#else /* CONFIG_PCI */
9551
    return 0;
9552
#endif /* CONFIG_PCI */
9553
#endif /* version >= v2.1.93 */ 
9554
}
9555
 
9556
/*
9557
 * Write a PCI configuration byte.
9558
 */
9559
ASC_INITFUNC(
9560
STATIC void
9561
DvcAdvWritePCIConfigByte(
9562
        ADV_DVC_VAR *asc_dvc,
9563
        ushort offset,
9564
        uchar  byte_data)
9565
)
9566
{
9567
#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
9568
#ifdef ASC_CONFIG_PCI
9569
    PCI_DATA    pciData;
9570
 
9571
    pciData.bus = ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info);
9572
    pciData.slot = ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info);
9573
    pciData.func = ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info);
9574
    pciData.offset = offset;
9575
    pciData.type = pci_scan_method;
9576
    asc_put_cfg_byte(&pciData, byte_data);
9577
#endif /* ASC_CONFIG_PCI */
9578
#else /* version >= v2.1.93 */ 
9579
#ifdef CONFIG_PCI
9580
    pcibios_write_config_byte(ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info),
9581
        PCI_DEVFN(ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info),
9582
            ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info)),
9583
        offset, byte_data);
9584
#endif /* CONFIG_PCI */
9585
#endif /* version >= v2.1.93 */ 
9586
}
9587
 
9588
/*
9589
 * --- Tracing and Debugging Functions
9590
 */
9591
 
9592
#ifdef ADVANSYS_STATS
9593
/*
9594
 * asc_prt_board_stats()
9595
 *
9596
 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
9597
 * cf. asc_prt_line().
9598
 *
9599
 * Return the number of characters copied into 'cp'. No more than
9600
 * 'cplen' characters will be copied to 'cp'.
9601
 */
9602
STATIC int
9603
asc_prt_board_stats(struct Scsi_Host *shp, char *cp, int cplen)
9604
{
9605
    int                    leftlen;
9606
    int                    totlen;
9607
    int                    len;
9608
    struct asc_stats       *s;
9609
    int                    i;
9610
    ushort                 chip_scsi_id;
9611
    asc_board_t            *boardp;
9612
    asc_queue_t            *active;
9613
    asc_queue_t            *waiting;
9614
 
9615
    leftlen = cplen;
9616
    totlen = len = 0;
9617
 
9618
    boardp = ASC_BOARDP(shp);
9619
    s = &boardp->asc_stats;
9620
 
9621
    len = asc_prt_line(cp, leftlen,
9622
"\nLinux Driver Statistics for AdvanSys SCSI Host %d:\n", shp->host_no);
9623
    ASC_PRT_NEXT();
9624
 
9625
    len = asc_prt_line(cp, leftlen,
9626
" command %lu, queuecommand %lu, abort %lu, reset %lu, biosparam %lu\n",
9627
        s->command, s->queuecommand, s->abort, s->reset, s->biosparam);
9628
    ASC_PRT_NEXT();
9629
 
9630
    len = asc_prt_line(cp, leftlen,
9631
" interrupt %lu, callback %lu, done %lu\n",
9632
        s->interrupt, s->callback, s->done);
9633
    ASC_PRT_NEXT();
9634
 
9635
    len = asc_prt_line(cp, leftlen,
9636
" exe_noerror %lu, exe_busy %lu, exe_error %lu, exe_unknown %lu\n",
9637
        s->exe_noerror, s->exe_busy, s->exe_error, s->exe_unknown);
9638
    ASC_PRT_NEXT();
9639
 
9640
    if (ASC_NARROW_BOARD(boardp)) {
9641
        len = asc_prt_line(cp, leftlen,
9642
" build_error %lu\n",
9643
         s->build_error);
9644
    } else {
9645
        len = asc_prt_line(cp, leftlen,
9646
" build_error %lu, build_noreq %lu, build_nosg %lu\n",
9647
         s->build_error, s->adv_build_noreq, s->adv_build_nosg);
9648
    }
9649
    ASC_PRT_NEXT();
9650
 
9651
    /*
9652
     * Display data transfer statistics.
9653
     */
9654
    if (s->cont_cnt > 0) {
9655
        len = asc_prt_line(cp, leftlen, " cont_cnt %lu, ", s->cont_cnt);
9656
        ASC_PRT_NEXT();
9657
 
9658
        len = asc_prt_line(cp, leftlen, "cont_xfer %lu.%01lu kb ",
9659
                    s->cont_xfer/2,
9660
                    ASC_TENTHS(s->cont_xfer, 2));
9661
        ASC_PRT_NEXT();
9662
 
9663
        /* Contiguous transfer average size */
9664
        len = asc_prt_line(cp, leftlen, "avg_xfer %lu.%01lu kb\n",
9665
                    (s->cont_xfer/2)/s->cont_cnt,
9666
                    ASC_TENTHS((s->cont_xfer/2), s->cont_cnt));
9667
        ASC_PRT_NEXT();
9668
    }
9669
 
9670
    if (s->sg_cnt > 0) {
9671
 
9672
        len = asc_prt_line(cp, leftlen, " sg_cnt %lu, sg_elem %lu, ",
9673
                    s->sg_cnt, s->sg_elem);
9674
        ASC_PRT_NEXT();
9675
 
9676
        len = asc_prt_line(cp, leftlen, "sg_xfer %lu.%01lu kb\n",
9677
                    s->sg_xfer/2,
9678
                    ASC_TENTHS(s->sg_xfer, 2));
9679
        ASC_PRT_NEXT();
9680
 
9681
        /* Scatter gather transfer statistics */
9682
        len = asc_prt_line(cp, leftlen, " avg_num_elem %lu.%01lu, ",
9683
                    s->sg_elem/s->sg_cnt,
9684
                    ASC_TENTHS(s->sg_elem, s->sg_cnt));
9685
        ASC_PRT_NEXT();
9686
 
9687
        len = asc_prt_line(cp, leftlen, "avg_elem_size %lu.%01lu kb, ",
9688
                    (s->sg_xfer/2)/s->sg_elem,
9689
                    ASC_TENTHS((s->sg_xfer/2), s->sg_elem));
9690
        ASC_PRT_NEXT();
9691
 
9692
        len = asc_prt_line(cp, leftlen, "avg_xfer_size %lu.%01lu kb\n",
9693
                    (s->sg_xfer/2)/s->sg_cnt,
9694
                    ASC_TENTHS((s->sg_xfer/2), s->sg_cnt));
9695
        ASC_PRT_NEXT();
9696
    }
9697
 
9698
    /*
9699
     * Display request queuing statistics.
9700
     */
9701
    len = asc_prt_line(cp, leftlen,
9702
" Active and Waiting Request Queues (Time Unit: %d HZ):\n", HZ);
9703
    ASC_PRT_NEXT();
9704
 
9705
    active = &ASC_BOARDP(shp)->active;
9706
    waiting = &ASC_BOARDP(shp)->waiting;
9707
 
9708
    if (ASC_NARROW_BOARD(boardp)) {
9709
        chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
9710
    } else {
9711
        chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
9712
    }
9713
 
9714
    for (i = 0; i <= ADV_MAX_TID; i++) {
9715
 
9716
        if ((chip_scsi_id == i) ||
9717
            ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
9718
            continue;
9719
        }
9720
 
9721
        if (active->q_tot_cnt[i] > 0 || waiting->q_tot_cnt[i] > 0) {
9722
            len = asc_prt_line(cp, leftlen, " target %d\n", i);
9723
            ASC_PRT_NEXT();
9724
 
9725
            len = asc_prt_line(cp, leftlen,
9726
"   active: cnt [cur %d, max %d, tot %u], time [min %d, max %d, avg %lu.%01lu]\n",
9727
                active->q_cur_cnt[i], active->q_max_cnt[i],
9728
                active->q_tot_cnt[i],
9729
                active->q_min_tim[i], active->q_max_tim[i],
9730
                (active->q_tot_cnt[i] == 0) ? 0 :
9731
                (active->q_tot_tim[i]/active->q_tot_cnt[i]),
9732
                (active->q_tot_cnt[i] == 0) ? 0 :
9733
                ASC_TENTHS(active->q_tot_tim[i], active->q_tot_cnt[i]));
9734
            ASC_PRT_NEXT();
9735
 
9736
            len = asc_prt_line(cp, leftlen,
9737
"   waiting: cnt [cur %d, max %d, tot %u], time [min %u, max %u, avg %lu.%01lu]\n",
9738
                waiting->q_cur_cnt[i], waiting->q_max_cnt[i],
9739
                waiting->q_tot_cnt[i],
9740
                waiting->q_min_tim[i], waiting->q_max_tim[i],
9741
                (waiting->q_tot_cnt[i] == 0) ? 0 :
9742
                (waiting->q_tot_tim[i]/waiting->q_tot_cnt[i]),
9743
                (waiting->q_tot_cnt[i] == 0) ? 0 :
9744
                ASC_TENTHS(waiting->q_tot_tim[i], waiting->q_tot_cnt[i]));
9745
            ASC_PRT_NEXT();
9746
        }
9747
    }
9748
 
9749
     return totlen;
9750
}
9751
#endif /* ADVANSYS_STATS */
9752
 
9753
#ifdef ADVANSYS_DEBUG
9754
/*
9755
 * asc_prt_scsi_host()
9756
 */
9757
STATIC void
9758
asc_prt_scsi_host(struct Scsi_Host *s)
9759
{
9760
    asc_board_t         *boardp;
9761
 
9762
    boardp = ASC_BOARDP(s);
9763
 
9764
    printk("Scsi_Host at addr %x\n", (unsigned) s);
9765
    printk(
9766
" next %x, extra_bytes %u, host_busy %u, host_no %d, last_reset %d,\n",
9767
        (unsigned) s->next, s->extra_bytes, s->host_busy, s->host_no,
9768
        (unsigned) s->last_reset);
9769
 
9770
    printk(
9771
" host_wait %x, host_queue %x, hostt %x, block %x,\n",
9772
        (unsigned) s->host_wait, (unsigned) s->host_queue,
9773
        (unsigned) s->hostt, (unsigned) s->block);
9774
 
9775
    printk(
9776
" wish_block %d, base %x, io_port %d, n_io_port %d, irq %d, dma_channel %d,\n",
9777
        s->wish_block, (unsigned) s->base, s->io_port, s->n_io_port,
9778
        s->irq, s->dma_channel);
9779
 
9780
    printk(
9781
" this_id %d, can_queue %d,\n", s->this_id, s->can_queue);
9782
 
9783
    printk(
9784
" cmd_per_lun %d, sg_tablesize %d, unchecked_isa_dma %d, loaded_as_module %d\n",
9785
        s->cmd_per_lun, s->sg_tablesize, s->unchecked_isa_dma,
9786
        s->loaded_as_module);
9787
 
9788
    if (ASC_NARROW_BOARD(boardp)) {
9789
        asc_prt_asc_dvc_var(&ASC_BOARDP(s)->dvc_var.asc_dvc_var);
9790
        asc_prt_asc_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.asc_dvc_cfg);
9791
    } else {
9792
        asc_prt_adv_dvc_var(&ASC_BOARDP(s)->dvc_var.adv_dvc_var);
9793
        asc_prt_adv_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.adv_dvc_cfg);
9794
    }
9795
}
9796
 
9797
/*
9798
 * asc_prt_scsi_cmnd()
9799
 */
9800
STATIC void
9801
asc_prt_scsi_cmnd(Scsi_Cmnd *s)
9802
{
9803
    printk("Scsi_Cmnd at addr %x\n", (unsigned) s);
9804
 
9805
#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0)
9806
    printk(
9807
" host %x, device %x, target %u, lun %u\n",
9808
        (unsigned) s->host, (unsigned) s->device, s->target, s->lun);
9809
#else /* version >= v1.3.0 */
9810
    printk(
9811
" host %x, device %x, target %u, lun %u, channel %u,\n",
9812
        (unsigned) s->host, (unsigned) s->device, s->target, s->lun,
9813
        s->channel);
9814
#endif /* version >= v1.3.0 */
9815
 
9816
    asc_prt_hex(" CDB", s->cmnd, s->cmd_len);
9817
 
9818
    printk(
9819
" use_sg %u, sglist_len %u, abort_reason %x\n",
9820
        s->use_sg, s->sglist_len, s->abort_reason);
9821
 
9822
#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,89)
9823
    printk(
9824
" retries %d, allowed %d\n",
9825
         s->retries, s->allowed);
9826
#else /* version >= v1.3.89 */
9827
    printk(
9828
" serial_number %x, serial_number_at_timeout %x, retries %d, allowed %d\n",
9829
        (unsigned) s->serial_number, (unsigned) s->serial_number_at_timeout,
9830
         s->retries, s->allowed);
9831
#endif /* version >= v1.3.89 */
9832
 
9833
    printk(
9834
" timeout_per_command %d, timeout_total %d, timeout %d\n",
9835
        s->timeout_per_command, s->timeout_total, s->timeout);
9836
 
9837
    printk(
9838
" internal_timeout %u, flags %u, this_count %d\n",
9839
        s->internal_timeout, s->flags, s->this_count);
9840
 
9841
    printk(
9842
" scsi_done %x, done %x, host_scribble %x, result %x\n",
9843
        (unsigned) s->scsi_done, (unsigned) s->done,
9844
        (unsigned) s->host_scribble, s->result);
9845
 
9846
    printk(
9847
" tag %u, pid %u\n",
9848
        (unsigned) s->tag, (unsigned) s->pid);
9849
}
9850
 
9851
/*
9852
 * asc_prt_asc_dvc_var()
9853
 */
9854
STATIC void
9855
asc_prt_asc_dvc_var(ASC_DVC_VAR *h)
9856
{
9857
    printk("ASC_DVC_VAR at addr %x\n", (unsigned) h);
9858
 
9859
    printk(
9860
" iop_base %x, err_code %x, dvc_cntl %x, bug_fix_cntl %d,\n",
9861
        h->iop_base, h->err_code, h->dvc_cntl, h->bug_fix_cntl);
9862
 
9863
    printk(
9864
" bus_type %d, isr_callback %x, exe_callback %x, init_sdtr %x,\n",
9865
        h->bus_type, (unsigned) h->isr_callback, (unsigned) h->exe_callback,
9866
        (unsigned) h->init_sdtr);
9867
 
9868
    printk(
9869
" sdtr_done %x, use_tagged_qng %x, unit_not_ready %x, chip_no %x,\n",
9870
        (unsigned) h->sdtr_done, (unsigned) h->use_tagged_qng,
9871
        (unsigned) h->unit_not_ready, (unsigned) h->chip_no);
9872
 
9873
    printk(
9874
" queue_full_or_busy %x, start_motor %x, scsi_reset_wait %x, irq_no %x,\n",
9875
        (unsigned) h->queue_full_or_busy, (unsigned) h->start_motor,
9876
        (unsigned) h->scsi_reset_wait, (unsigned) h->irq_no);
9877
 
9878
    printk(
9879
" is_in_int %x, max_total_qng %x, cur_total_qng %x, in_critical_cnt %x,\n",
9880
        (unsigned) h->is_in_int, (unsigned) h->max_total_qng,
9881
        (unsigned) h->cur_total_qng, (unsigned) h->in_critical_cnt);
9882
 
9883
    printk(
9884
" last_q_shortage %x, init_state %x, no_scam %x, pci_fix_asyn_xfer %x,\n",
9885
        (unsigned) h->last_q_shortage, (unsigned) h->init_state,
9886
        (unsigned) h->no_scam, (unsigned) h->pci_fix_asyn_xfer);
9887
 
9888
    printk(
9889
" cfg %x, saved_ptr2func %x\n",
9890
        (unsigned) h->cfg, (unsigned) h->saved_ptr2func);
9891
}
9892
 
9893
/*
9894
 * asc_prt_asc_dvc_cfg()
9895
 */
9896
STATIC void
9897
asc_prt_asc_dvc_cfg(ASC_DVC_CFG *h)
9898
{
9899
    printk("ASC_DVC_CFG at addr %x\n", (unsigned) h);
9900
 
9901
    printk(
9902
" can_tagged_qng %x, cmd_qng_enabled %x, disc_enable %x, sdtr_enable %x,\n",
9903
            h->can_tagged_qng, h->cmd_qng_enabled, h->disc_enable,
9904
            h->sdtr_enable);
9905
 
9906
    printk(
9907
" chip_scsi_id %d, isa_dma_speed %d, isa_dma_channel %d, chip_version %d,\n",
9908
             h->chip_scsi_id, h->isa_dma_speed, h->isa_dma_channel,
9909
             h->chip_version);
9910
 
9911
    printk(
9912
" pci_device_id %d, lib_serial_no %x, lib_version %x, mcode_date %x,\n",
9913
          h->pci_device_id, h->lib_serial_no, h->lib_version, h->mcode_date);
9914
 
9915
    printk(
9916
" mcode_version %d, overrun_buf %x\n",
9917
            h->mcode_version, (unsigned) h->overrun_buf);
9918
}
9919
 
9920
/*
9921
 * asc_prt_asc_scsi_q()
9922
 */
9923
STATIC void
9924
asc_prt_asc_scsi_q(ASC_SCSI_Q *q)
9925
{
9926
    ASC_SG_HEAD    *sgp;
9927
    int i;
9928
 
9929
    printk("ASC_SCSI_Q at addr %x\n", (unsigned) q);
9930
 
9931
    printk(
9932
" target_ix %u, target_lun %u, srb_ptr %x, tag_code %u,\n",
9933
            q->q2.target_ix, q->q1.target_lun,
9934
            (unsigned) q->q2.srb_ptr, q->q2.tag_code);
9935
 
9936
    printk(
9937
" data_addr %x, data_cnt %lu, sense_addr %x, sense_len %u,\n",
9938
            (unsigned) q->q1.data_addr, q->q1.data_cnt,
9939
            (unsigned) q->q1.sense_addr, q->q1.sense_len);
9940
 
9941
    printk(
9942
" cdbptr %x, cdb_len %u, sg_head %x, sg_queue_cnt %u\n",
9943
            (unsigned) q->cdbptr, q->q2.cdb_len,
9944
            (unsigned) q->sg_head, q->q1.sg_queue_cnt);
9945
 
9946
    if (q->sg_head) {
9947
        sgp = q->sg_head;
9948
        printk("ASC_SG_HEAD at addr %x\n", (unsigned) sgp);
9949
        printk(" entry_cnt %u, queue_cnt %u\n", sgp->entry_cnt, sgp->queue_cnt);
9950
        for (i = 0; i < sgp->entry_cnt; i++) {
9951
            printk(" [%u]: addr %x, bytes %lu\n",
9952
                i, (unsigned) sgp->sg_list[i].addr, sgp->sg_list[i].bytes);
9953
        }
9954
 
9955
    }
9956
}
9957
 
9958
/*
9959
 * asc_prt_asc_qdone_info()
9960
 */
9961
STATIC void
9962
asc_prt_asc_qdone_info(ASC_QDONE_INFO *q)
9963
{
9964
    printk("ASC_QDONE_INFO at addr %x\n", (unsigned) q);
9965
    printk(
9966
" srb_ptr %x, target_ix %u, cdb_len %u, tag_code %u, done_stat %x\n",
9967
            (unsigned) q->d2.srb_ptr, q->d2.target_ix, q->d2.cdb_len,
9968
            q->d2.tag_code, q->d3.done_stat);
9969
    printk(
9970
" host_stat %x, scsi_stat %x, scsi_msg %x\n",
9971
            q->d3.host_stat, q->d3.scsi_stat, q->d3.scsi_msg);
9972
}
9973
 
9974
/*
9975
 * asc_prt_adv_dvc_var()
9976
 *
9977
 * Display an ADV_DVC_VAR structure.
9978
 */
9979
STATIC void
9980
asc_prt_adv_dvc_var(ADV_DVC_VAR *h)
9981
{
9982
    printk(" ADV_DVC_VAR at addr 0x%lx\n", (ulong) h);
9983
 
9984
    printk(
9985
"  iop_base 0x%lx, err_code 0x%x, ultra_able 0x%x\n",
9986
        (ulong) h->iop_base, h->err_code, (unsigned) h->ultra_able);
9987
 
9988
    printk(
9989
"  isr_callback 0x%x, sdtr_able 0x%x, wdtr_able 0x%x\n",
9990
        (unsigned) h->isr_callback, (unsigned) h->wdtr_able,
9991
        (unsigned) h->sdtr_able);
9992
 
9993
    printk(
9994
"  start_motor 0x%x, scsi_reset_wait 0x%x, irq_no 0x%x,\n",
9995
        (unsigned) h->start_motor,
9996
        (unsigned) h->scsi_reset_wait, (unsigned) h->irq_no);
9997
 
9998
    printk(
9999
"  max_host_qng 0x%x, cur_host_qng 0x%x, max_dvc_qng 0x%x\n",
10000
        (unsigned) h->max_host_qng, (unsigned) h->cur_host_qng,
10001
        (unsigned) h->max_dvc_qng);
10002
 
10003
    printk(
10004
"  no_scam 0x%x, tagqng_able 0x%x, chip_scsi_id 0x%x, cfg 0x%lx\n",
10005
        (unsigned) h->no_scam, (unsigned) h->tagqng_able,
10006
        (unsigned) h->chip_scsi_id, (ulong) h->cfg);
10007
 
10008
}
10009
 
10010
/*
10011
 * asc_prt_adv_dvc_cfg()
10012
 *
10013
 * Display an ADV_DVC_CFG structure.
10014
 */
10015
STATIC void
10016
asc_prt_adv_dvc_cfg(ADV_DVC_CFG *h)
10017
{
10018
    printk(" ADV_DVC_CFG at addr 0x%lx\n", (ulong) h);
10019
 
10020
    printk(
10021
"  disc_enable 0x%x, termination 0x%x\n",
10022
        h->disc_enable, h->termination);
10023
 
10024
    printk(
10025
"  chip_version 0x%x, mcode_date 0x%x\n",
10026
        h->chip_version, h->mcode_date);
10027
 
10028
    printk(
10029
"  mcode_version 0x%x, pci_device_id 0x%x, lib_version 0x%x\n",
10030
       h->mcode_version, h->pci_device_id, h->lib_version);
10031
 
10032
    printk(
10033
"  control_flag 0x%x, pci_slot_info 0x%x\n",
10034
       h->control_flag, h->pci_slot_info);
10035
}
10036
 
10037
/*
10038
 * asc_prt_adv_scsi_req_q()
10039
 *
10040
 * Display an ADV_SCSI_REQ_Q structure.
10041
 */
10042
STATIC void
10043
asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *q)
10044
{
10045
    int                 i;
10046
    struct asc_sg_block *sg_ptr;
10047
 
10048
    printk("ADV_SCSI_REQ_Q at addr %x\n", (unsigned) q);
10049
 
10050
    printk(
10051
"  target_id %u, target_lun %u, srb_ptr 0x%lx, a_flag 0x%x\n",
10052
            q->target_id, q->target_lun, q->srb_ptr, q->a_flag);
10053
 
10054
    printk("  cntl 0x%x, data_addr 0x%lx, vdata_addr 0x%lx\n",
10055
            q->cntl, q->data_addr, q->vdata_addr);
10056
 
10057
    printk(
10058
"  data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
10059
            q->data_cnt, q->sense_addr, q->sense_len);
10060
 
10061
    printk(
10062
"  cdb_len %u, done_status 0x%x, host_status 0x%x, scsi_status 0x%x\n",
10063
            q->cdb_len, q->done_status, q->host_status, q->scsi_status);
10064
 
10065
    printk(
10066
"  vsense_addr 0x%lx, scsiq_ptr 0x%lx, ux_wk_data_cnt %lu\n",
10067
            (ulong) q->vsense_addr, (ulong) q->scsiq_ptr,
10068
            (ulong) q->ux_wk_data_cnt);
10069
 
10070
    printk(
10071
"  sg_list_ptr 0x%lx, sg_real_addr 0x%lx, sg_entry_cnt %u\n",
10072
            (ulong) q->sg_list_ptr, (ulong) q->sg_real_addr, q->sg_entry_cnt);
10073
 
10074
    printk(
10075
"  ux_sg_ix %u, orig_sense_len %u\n",
10076
            q->ux_sg_ix, q->orig_sense_len);
10077
 
10078
    /* Display the request's ADV_SG_BLOCK structures. */
10079
    for (sg_ptr = q->sg_list_ptr, i = 0; sg_ptr != NULL;
10080
        sg_ptr = sg_ptr->sg_ptr, i++) {
10081
        /*
10082
         * 'sg_ptr' is a physical address. Convert it to a virtual
10083
         * address by indexing 'i' into the virtual address array
10084
         * 'sg_list_ptr'.
10085
         *
10086
         * At the end of the each iteration of the loop 'sg_ptr' is
10087
         * converted back into a physical address by setting 'sg_ptr'
10088
         *  to the next pointer 'sg_ptr->sg_ptr'.
10089
         */
10090
        sg_ptr = &(((ADV_SG_BLOCK *) (q->sg_list_ptr))[i]);
10091
        asc_prt_adv_sgblock(i, sg_ptr);
10092
    }
10093
}
10094
 
10095
/*
10096
 * asc_prt_adv_sgblock()
10097
 *
10098
 * Display an ADV_SG_BLOCK structure.
10099
 */
10100
STATIC void
10101
asc_prt_adv_sgblock(int sgblockno, ADV_SG_BLOCK *b)
10102
{
10103
    int i, s;
10104
 
10105
    /* Calculate starting entry number for the current block. */
10106
    s = sgblockno * NO_OF_SG_PER_BLOCK;
10107
 
10108
    printk(" ADV_SG_BLOCK at addr 0x%lx (sgblockno %lu)\n",
10109
        (ulong) b, (ulong) sgblockno);
10110
    printk(
10111
"  first_entry_no %lu, last_entry_no %lu, sg_ptr 0x%lx\n",
10112
        (ulong) b->first_entry_no, (ulong) b->last_entry_no, (ulong) b->sg_ptr);
10113
    ASC_ASSERT(b->first_entry_no - s >= 0);
10114
    ASC_ASSERT(b->last_entry_no - s >= 0);
10115
    ASC_ASSERT(b->last_entry_no - s <= NO_OF_SG_PER_BLOCK);
10116
    ASC_ASSERT(b->first_entry_no - s <= NO_OF_SG_PER_BLOCK);
10117
    ASC_ASSERT(b->first_entry_no - s <= NO_OF_SG_PER_BLOCK);
10118
    ASC_ASSERT(b->first_entry_no - s <= b->last_entry_no - s);
10119
    for (i = b->first_entry_no - s; i <= b->last_entry_no - s; i++) {
10120
        printk("  [%lu]: sg_addr 0x%lx, sg_count 0x%lx\n",
10121
            (ulong) i, (ulong) b->sg_list[i].sg_addr,
10122
            (ulong) b->sg_list[i].sg_count);
10123
    }
10124
}
10125
 
10126
/*
10127
 * asc_prt_hex()
10128
 *
10129
 * Print hexadecimal output in 4 byte groupings 32 bytes
10130
 * or 8 double-words per line.
10131
 */
10132
STATIC void
10133
asc_prt_hex(char *f, uchar *s, int l)
10134
{
10135
    int            i;
10136
    int            j;
10137
    int            k;
10138
    int            m;
10139
 
10140
    printk("%s: (%d bytes)\n", f, l);
10141
 
10142
    for (i = 0; i < l; i += 32) {
10143
 
10144
        /* Display a maximum of 8 double-words per line. */
10145
        if ((k = (l - i) / 4) >= 8) {
10146
            k = 8;
10147
            m = 0;
10148
        } else {
10149
            m = (l - i) % 4 ;
10150
        }
10151
 
10152
        for (j = 0; j < k; j++) {
10153
            printk(" %2.2X%2.2X%2.2X%2.2X",
10154
                (unsigned) s[i+(j*4)], (unsigned) s[i+(j*4)+1],
10155
                (unsigned) s[i+(j*4)+2], (unsigned) s[i+(j*4)+3]);
10156
        }
10157
 
10158
        switch (m) {
10159
        case 0:
10160
        default:
10161
            break;
10162
        case 1:
10163
            printk(" %2.2X",
10164
                (unsigned) s[i+(j*4)]);
10165
            break;
10166
        case 2:
10167
            printk(" %2.2X%2.2X",
10168
                (unsigned) s[i+(j*4)],
10169
                (unsigned) s[i+(j*4)+1]);
10170
            break;
10171
        case 3:
10172
            printk(" %2.2X%2.2X%2.2X",
10173
                (unsigned) s[i+(j*4)+1],
10174
                (unsigned) s[i+(j*4)+2],
10175
                (unsigned) s[i+(j*4)+3]);
10176
            break;
10177
        }
10178
 
10179
        printk("\n");
10180
    }
10181
}
10182
#endif /* ADVANSYS_DEBUG */
10183
 
10184
#ifdef ADVANSYS_ASSERT
10185
/*
10186
 * interrupts_enabled()
10187
 *
10188
 * Return 1 if interrupts are enabled, otherwise return 0.
10189
 */
10190
STATIC int
10191
interrupts_enabled(void)
10192
{
10193
    int flags;
10194
 
10195
    save_flags(flags);
10196
    if (flags & 0x0200) {
10197
        return ASC_TRUE;
10198
    } else {
10199
        return ASC_FALSE;
10200
    }
10201
}
10202
#endif /* ADVANSYS_ASSERT */
10203
 
10204
 
10205
/*
10206
 * --- Asc Library Functions
10207
 */
10208
 
10209
ASC_INITFUNC(
10210
STATIC ushort
10211
AscGetEisaChipCfg(
10212
                     PortAddr iop_base
10213
)
10214
)
10215
{
10216
    PortAddr            eisa_cfg_iop;
10217
 
10218
    eisa_cfg_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
10219
      (PortAddr) (ASC_EISA_CFG_IOP_MASK);
10220
    return (inpw(eisa_cfg_iop));
10221
}
10222
 
10223
ASC_INITFUNC(
10224
STATIC uchar
10225
AscSetChipScsiID(
10226
                    PortAddr iop_base,
10227
                    uchar new_host_id
10228
)
10229
)
10230
{
10231
    ushort              cfg_lsw;
10232
 
10233
    if (AscGetChipScsiID(iop_base) == new_host_id) {
10234
        return (new_host_id);
10235
    }
10236
    cfg_lsw = AscGetChipCfgLsw(iop_base);
10237
    cfg_lsw &= 0xF8FF;
10238
    cfg_lsw |= (ushort) ((new_host_id & ASC_MAX_TID) << 8);
10239
    AscSetChipCfgLsw(iop_base, cfg_lsw);
10240
    return (AscGetChipScsiID(iop_base));
10241
}
10242
 
10243
ASC_INITFUNC(
10244
STATIC uchar
10245
AscGetChipScsiCtrl(
10246
                      PortAddr iop_base
10247
)
10248
)
10249
{
10250
    uchar               sc;
10251
 
10252
    AscSetBank(iop_base, 1);
10253
    sc = inp(iop_base + IOP_REG_SC);
10254
    AscSetBank(iop_base, 0);
10255
    return (sc);
10256
}
10257
 
10258
ASC_INITFUNC(
10259
STATIC uchar
10260
AscGetChipVersion(
10261
                     PortAddr iop_base,
10262
                     ushort bus_type
10263
)
10264
)
10265
{
10266
    if ((bus_type & ASC_IS_EISA) != 0) {
10267
        PortAddr            eisa_iop;
10268
        uchar               revision;
10269
        eisa_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
10270
          (PortAddr) ASC_EISA_REV_IOP_MASK;
10271
        revision = inp(eisa_iop);
10272
        return ((uchar) ((ASC_CHIP_MIN_VER_EISA - 1) + revision));
10273
    }
10274
    return (AscGetChipVerNo(iop_base));
10275
}
10276
 
10277
ASC_INITFUNC(
10278
STATIC ushort
10279
AscGetChipBusType(
10280
                     PortAddr iop_base
10281
)
10282
)
10283
{
10284
    ushort              chip_ver;
10285
 
10286
    chip_ver = AscGetChipVerNo(iop_base);
10287
    if (
10288
           (chip_ver >= ASC_CHIP_MIN_VER_VL)
10289
           && (chip_ver <= ASC_CHIP_MAX_VER_VL)
10290
) {
10291
        if (
10292
               ((iop_base & 0x0C30) == 0x0C30)
10293
               || ((iop_base & 0x0C50) == 0x0C50)
10294
) {
10295
            return (ASC_IS_EISA);
10296
        }
10297
        return (ASC_IS_VL);
10298
    }
10299
    if ((chip_ver >= ASC_CHIP_MIN_VER_ISA) &&
10300
        (chip_ver <= ASC_CHIP_MAX_VER_ISA)) {
10301
        if (chip_ver >= ASC_CHIP_MIN_VER_ISA_PNP) {
10302
            return (ASC_IS_ISAPNP);
10303
        }
10304
        return (ASC_IS_ISA);
10305
    } else if ((chip_ver >= ASC_CHIP_MIN_VER_PCI) &&
10306
               (chip_ver <= ASC_CHIP_MAX_VER_PCI)) {
10307
        return (ASC_IS_PCI);
10308
    }
10309
    return (0);
10310
}
10311
 
10312
ASC_INITFUNC(
10313
STATIC ulong
10314
AscLoadMicroCode(
10315
                    PortAddr iop_base,
10316
                    ushort s_addr,
10317
                    ushort *mcode_buf,
10318
                    ushort mcode_size
10319
)
10320
)
10321
{
10322
    ulong               chksum;
10323
    ushort              mcode_word_size;
10324
    ushort              mcode_chksum;
10325
 
10326
    mcode_word_size = (ushort) (mcode_size >> 1);
10327
    AscMemWordSetLram(iop_base, s_addr, 0, mcode_word_size);
10328
    AscMemWordCopyToLram(iop_base, s_addr, mcode_buf, mcode_word_size);
10329
    chksum = AscMemSumLramWord(iop_base, s_addr, mcode_word_size);
10330
    mcode_chksum = (ushort) AscMemSumLramWord(iop_base,
10331
                                              (ushort) ASC_CODE_SEC_BEG,
10332
          (ushort) ((mcode_size - s_addr - (ushort) ASC_CODE_SEC_BEG) / 2));
10333
    AscWriteLramWord(iop_base, ASCV_MCODE_CHKSUM_W, mcode_chksum);
10334
    AscWriteLramWord(iop_base, ASCV_MCODE_SIZE_W, mcode_size);
10335
    return (chksum);
10336
}
10337
 
10338
ASC_INITFUNC(
10339
STATIC int
10340
AscFindSignature(
10341
                    PortAddr iop_base
10342
)
10343
)
10344
{
10345
    ushort              sig_word;
10346
 
10347
    if (AscGetChipSignatureByte(iop_base) == (uchar) ASC_1000_ID1B) {
10348
        sig_word = AscGetChipSignatureWord(iop_base);
10349
        if ((sig_word == (ushort) ASC_1000_ID0W) ||
10350
            (sig_word == (ushort) ASC_1000_ID0W_FIX)) {
10351
            return (1);
10352
        }
10353
    }
10354
    return (0);
10355
}
10356
 
10357
STATIC uchar _isa_pnp_inited ASC_INITDATA = 0;
10358
STATIC PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] ASC_INITDATA =
10359
{
10360
    0x100, ASC_IOADR_1, 0x120, ASC_IOADR_2, 0x140, ASC_IOADR_3, ASC_IOADR_4,
10361
    ASC_IOADR_5, ASC_IOADR_6, ASC_IOADR_7, ASC_IOADR_8
10362
};
10363
 
10364
ASC_INITFUNC(
10365
STATIC PortAddr
10366
AscSearchIOPortAddr(
10367
                       PortAddr iop_beg,
10368
                       ushort bus_type
10369
)
10370
)
10371
{
10372
    if (bus_type & ASC_IS_VL) {
10373
        while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) {
10374
            if (AscGetChipVersion(iop_beg, bus_type) <= ASC_CHIP_MAX_VER_VL) {
10375
                return (iop_beg);
10376
            }
10377
        }
10378
        return (0);
10379
    }
10380
    if (bus_type & ASC_IS_ISA) {
10381
        if (_isa_pnp_inited == 0) {
10382
            AscSetISAPNPWaitForKey();
10383
            _isa_pnp_inited++;
10384
        }
10385
        while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) {
10386
            if ((AscGetChipVersion(iop_beg, bus_type) & ASC_CHIP_VER_ISA_BIT) != 0) {
10387
                return (iop_beg);
10388
            }
10389
        }
10390
        return (0);
10391
    }
10392
    if (bus_type & ASC_IS_EISA) {
10393
        if ((iop_beg = AscSearchIOPortAddrEISA(iop_beg)) != 0) {
10394
            return (iop_beg);
10395
        }
10396
        return (0);
10397
    }
10398
    return (0);
10399
}
10400
 
10401
ASC_INITFUNC(
10402
STATIC PortAddr
10403
AscSearchIOPortAddr11(
10404
                         PortAddr s_addr
10405
)
10406
)
10407
{
10408
    int                 i;
10409
    PortAddr            iop_base;
10410
 
10411
    for (i = 0; i < ASC_IOADR_TABLE_MAX_IX; i++) {
10412
        if (_asc_def_iop_base[i] > s_addr) {
10413
            break;
10414
        }
10415
    }
10416
    for (; i < ASC_IOADR_TABLE_MAX_IX; i++) {
10417
        iop_base = _asc_def_iop_base[i];
10418
        if (check_region(iop_base, ASC_IOADR_GAP) != 0) {
10419
            ASC_DBG1(1,
10420
               "AscSearchIOPortAddr11: check_region() failed I/O port %x\n",
10421
                     iop_base);
10422
            continue;
10423
        }
10424
        ASC_DBG1(1, "AscSearchIOPortAddr11: probing I/O port %x\n", iop_base);
10425
        if (AscFindSignature(iop_base)) {
10426
            return (iop_base);
10427
        }
10428
    }
10429
    return (0);
10430
}
10431
 
10432
ASC_INITFUNC(
10433
STATIC void
10434
AscToggleIRQAct(
10435
                   PortAddr iop_base
10436
)
10437
)
10438
{
10439
    AscSetChipStatus(iop_base, CIW_IRQ_ACT);
10440
    AscSetChipStatus(iop_base, 0);
10441
    return;
10442
}
10443
 
10444
ASC_INITFUNC(
10445
STATIC void
10446
AscSetISAPNPWaitForKey(
10447
    void)
10448
)
10449
{
10450
    outp(ASC_ISA_PNP_PORT_ADDR, 0x02);
10451
    outp(ASC_ISA_PNP_PORT_WRITE, 0x02);
10452
    return;
10453
}
10454
 
10455
ASC_INITFUNC(
10456
STATIC uchar
10457
AscGetChipIRQ(
10458
                 PortAddr iop_base,
10459
                 ushort bus_type
10460
)
10461
)
10462
{
10463
    ushort              cfg_lsw;
10464
    uchar               chip_irq;
10465
 
10466
    if ((bus_type & ASC_IS_EISA) != 0) {
10467
        cfg_lsw = AscGetEisaChipCfg(iop_base);
10468
        chip_irq = (uchar) (((cfg_lsw >> 8) & 0x07) + 10);
10469
        if ((chip_irq == 13) || (chip_irq > 15)) {
10470
            return (0);
10471
        }
10472
        return (chip_irq);
10473
    }
10474
    if ((bus_type & ASC_IS_VL) != 0) {
10475
        cfg_lsw = AscGetChipCfgLsw(iop_base);
10476
        chip_irq = (uchar) (((cfg_lsw >> 2) & 0x07));
10477
        if ((chip_irq == 0) ||
10478
            (chip_irq == 4) ||
10479
            (chip_irq == 7)) {
10480
            return (0);
10481
        }
10482
        return ((uchar) (chip_irq + (ASC_MIN_IRQ_NO - 1)));
10483
    }
10484
    cfg_lsw = AscGetChipCfgLsw(iop_base);
10485
    chip_irq = (uchar) (((cfg_lsw >> 2) & 0x03));
10486
    if (chip_irq == 3)
10487
        chip_irq += (uchar) 2;
10488
    return ((uchar) (chip_irq + ASC_MIN_IRQ_NO));
10489
}
10490
 
10491
ASC_INITFUNC(
10492
STATIC uchar
10493
AscSetChipIRQ(
10494
                 PortAddr iop_base,
10495
                 uchar irq_no,
10496
                 ushort bus_type
10497
)
10498
)
10499
{
10500
    ushort              cfg_lsw;
10501
 
10502
    if ((bus_type & ASC_IS_VL) != 0) {
10503
        if (irq_no != 0) {
10504
            if ((irq_no < ASC_MIN_IRQ_NO) || (irq_no > ASC_MAX_IRQ_NO)) {
10505
                irq_no = 0;
10506
            } else {
10507
                irq_no -= (uchar) ((ASC_MIN_IRQ_NO - 1));
10508
            }
10509
        }
10510
        cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base) & 0xFFE3);
10511
        cfg_lsw |= (ushort) 0x0010;
10512
        AscSetChipCfgLsw(iop_base, cfg_lsw);
10513
        AscToggleIRQAct(iop_base);
10514
        cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base) & 0xFFE0);
10515
        cfg_lsw |= (ushort) ((irq_no & 0x07) << 2);
10516
        AscSetChipCfgLsw(iop_base, cfg_lsw);
10517
        AscToggleIRQAct(iop_base);
10518
        return (AscGetChipIRQ(iop_base, bus_type));
10519
    }
10520
    if ((bus_type & (ASC_IS_ISA)) != 0) {
10521
        if (irq_no == 15)
10522
            irq_no -= (uchar) 2;
10523
        irq_no -= (uchar) ASC_MIN_IRQ_NO;
10524
        cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base) & 0xFFF3);
10525
        cfg_lsw |= (ushort) ((irq_no & 0x03) << 2);
10526
        AscSetChipCfgLsw(iop_base, cfg_lsw);
10527
        return (AscGetChipIRQ(iop_base, bus_type));
10528
    }
10529
    return (0);
10530
}
10531
 
10532
ASC_INITFUNC(
10533
STATIC void
10534
AscEnableIsaDma(
10535
                   uchar dma_channel
10536
)
10537
)
10538
{
10539
    if (dma_channel < 4) {
10540
        outp(0x000B, (ushort) (0xC0 | dma_channel));
10541
        outp(0x000A, dma_channel);
10542
    } else if (dma_channel < 8) {
10543
        outp(0x00D6, (ushort) (0xC0 | (dma_channel - 4)));
10544
        outp(0x00D4, (ushort) (dma_channel - 4));
10545
    }
10546
    return;
10547
}
10548
 
10549
STATIC int
10550
AscIsrChipHalted(
10551
                    REG ASC_DVC_VAR asc_ptr_type * asc_dvc
10552
)
10553
{
10554
    EXT_MSG             ext_msg;
10555
    EXT_MSG             out_msg;
10556
    ushort              halt_q_addr;
10557
    int                 sdtr_accept;
10558
    ushort              int_halt_code;
10559
    ASC_SCSI_BIT_ID_TYPE scsi_busy;
10560
    ASC_SCSI_BIT_ID_TYPE target_id;
10561
    PortAddr            iop_base;
10562
    uchar               tag_code;
10563
    uchar               q_status;
10564
    uchar               halt_qp;
10565
    uchar               sdtr_data;
10566
    uchar               target_ix;
10567
    uchar               q_cntl, tid_no;
10568
    uchar               cur_dvc_qng;
10569
    uchar               asyn_sdtr;
10570
    uchar               scsi_status;
10571
    asc_board_t            *boardp;
10572
 
10573
    ASC_ASSERT(asc_dvc->drv_ptr != 0);
10574
    boardp = (asc_board_t *) asc_dvc->drv_ptr;
10575
 
10576
    iop_base = asc_dvc->iop_base;
10577
    int_halt_code = AscReadLramWord(iop_base, ASCV_HALTCODE_W);
10578
 
10579
    halt_qp = AscReadLramByte(iop_base, ASCV_CURCDB_B);
10580
    halt_q_addr = ASC_QNO_TO_QADDR(halt_qp);
10581
    target_ix = AscReadLramByte(iop_base,
10582
                   (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TARGET_IX));
10583
    q_cntl = AscReadLramByte(iop_base,
10584
                        (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL));
10585
    tid_no = ASC_TIX_TO_TID(target_ix);
10586
    target_id = (uchar) ASC_TID_TO_TARGET_ID(tid_no);
10587
    if (asc_dvc->pci_fix_asyn_xfer & target_id) {
10588
 
10589
        asyn_sdtr = ASYN_SDTR_DATA_FIX_PCI_REV_AB;
10590
    } else {
10591
        asyn_sdtr = 0;
10592
    }
10593
    if (int_halt_code == ASC_HALT_DISABLE_ASYN_USE_SYN_FIX) {
10594
        if (asc_dvc->pci_fix_asyn_xfer & target_id) {
10595
            AscSetChipSDTR(iop_base, 0, tid_no);
10596
            boardp->sdtr_data[tid_no] = 0;
10597
        }
10598
        AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10599
        return (0);
10600
    } else if (int_halt_code == ASC_HALT_ENABLE_ASYN_USE_SYN_FIX) {
10601
        if (asc_dvc->pci_fix_asyn_xfer & target_id) {
10602
            AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
10603
            boardp->sdtr_data[tid_no] = asyn_sdtr;
10604
        }
10605
        AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10606
        return (0);
10607
    } else if (int_halt_code == ASC_HALT_EXTMSG_IN) {
10608
 
10609
        AscMemWordCopyFromLram(iop_base,
10610
                               ASCV_MSGIN_BEG,
10611
                               (ushort *) & ext_msg,
10612
                               (ushort) (sizeof (EXT_MSG) >> 1));
10613
 
10614
        if (ext_msg.msg_type == MS_EXTEND &&
10615
            ext_msg.msg_req == MS_SDTR_CODE &&
10616
            ext_msg.msg_len == MS_SDTR_LEN) {
10617
            sdtr_accept = TRUE;
10618
            if ((ext_msg.req_ack_offset > ASC_SYN_MAX_OFFSET)) {
10619
 
10620
                sdtr_accept = FALSE;
10621
                ext_msg.req_ack_offset = ASC_SYN_MAX_OFFSET;
10622
            }
10623
            if ((ext_msg.xfer_period <
10624
                 asc_dvc->sdtr_period_tbl[asc_dvc->host_init_sdtr_index]) ||
10625
                (ext_msg.xfer_period >
10626
                 asc_dvc->sdtr_period_tbl[asc_dvc->max_sdtr_index])) {
10627
                sdtr_accept = FALSE;
10628
                ext_msg.xfer_period =
10629
                    asc_dvc->sdtr_period_tbl[asc_dvc->host_init_sdtr_index];
10630
            }
10631
            if (sdtr_accept) {
10632
                sdtr_data = AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
10633
                                           ext_msg.req_ack_offset);
10634
                if ((sdtr_data == 0xFF)) {
10635
 
10636
                    q_cntl |= QC_MSG_OUT;
10637
                    asc_dvc->init_sdtr &= ~target_id;
10638
                    asc_dvc->sdtr_done &= ~target_id;
10639
                    AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
10640
                    boardp->sdtr_data[tid_no] = asyn_sdtr;
10641
                }
10642
            }
10643
            if (ext_msg.req_ack_offset == 0) {
10644
 
10645
                q_cntl &= ~QC_MSG_OUT;
10646
                asc_dvc->init_sdtr &= ~target_id;
10647
                asc_dvc->sdtr_done &= ~target_id;
10648
                AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
10649
            } else {
10650
                if (sdtr_accept && (q_cntl & QC_MSG_OUT)) {
10651
 
10652
                    q_cntl &= ~QC_MSG_OUT;
10653
                    asc_dvc->sdtr_done |= target_id;
10654
                    asc_dvc->init_sdtr |= target_id;
10655
                    asc_dvc->pci_fix_asyn_xfer &= ~target_id;
10656
                    sdtr_data = AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
10657
                                               ext_msg.req_ack_offset);
10658
                    AscSetChipSDTR(iop_base, sdtr_data, tid_no);
10659
                    boardp->sdtr_data[tid_no] = sdtr_data;
10660
                } else {
10661
 
10662
                    q_cntl |= QC_MSG_OUT;
10663
                    AscMsgOutSDTR(asc_dvc,
10664
                                  ext_msg.xfer_period,
10665
                                  ext_msg.req_ack_offset);
10666
                    asc_dvc->pci_fix_asyn_xfer &= ~target_id;
10667
                    sdtr_data = AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
10668
                                               ext_msg.req_ack_offset);
10669
                    AscSetChipSDTR(iop_base, sdtr_data, tid_no);
10670
                    boardp->sdtr_data[tid_no] = sdtr_data;
10671
                    asc_dvc->sdtr_done |= target_id;
10672
                    asc_dvc->init_sdtr |= target_id;
10673
                }
10674
            }
10675
 
10676
            AscWriteLramByte(iop_base,
10677
                         (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
10678
                             q_cntl);
10679
            AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10680
            return (0);
10681
        } else if (ext_msg.msg_type == MS_EXTEND &&
10682
                   ext_msg.msg_req == MS_WDTR_CODE &&
10683
                   ext_msg.msg_len == MS_WDTR_LEN) {
10684
 
10685
            ext_msg.wdtr_width = 0;
10686
            AscMemWordCopyToLram(iop_base,
10687
                                 ASCV_MSGOUT_BEG,
10688
                                 (ushort *) & ext_msg,
10689
                                 (ushort) (sizeof (EXT_MSG) >> 1));
10690
            q_cntl |= QC_MSG_OUT;
10691
            AscWriteLramByte(iop_base,
10692
                         (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
10693
                             q_cntl);
10694
            AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10695
            return (0);
10696
        } else {
10697
 
10698
            ext_msg.msg_type = M1_MSG_REJECT;
10699
            AscMemWordCopyToLram(iop_base,
10700
                                 ASCV_MSGOUT_BEG,
10701
                                 (ushort *) & ext_msg,
10702
                                 (ushort) (sizeof (EXT_MSG) >> 1));
10703
            q_cntl |= QC_MSG_OUT;
10704
            AscWriteLramByte(iop_base,
10705
                         (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
10706
                             q_cntl);
10707
            AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10708
            return (0);
10709
        }
10710
    } else if (int_halt_code == ASC_HALT_CHK_CONDITION) {
10711
 
10712
        q_cntl |= QC_REQ_SENSE;
10713
 
10714
        if ((asc_dvc->init_sdtr & target_id) != 0) {
10715
 
10716
            asc_dvc->sdtr_done &= ~target_id;
10717
 
10718
            sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
10719
            q_cntl |= QC_MSG_OUT;
10720
            AscMsgOutSDTR(asc_dvc,
10721
                          asc_dvc->sdtr_period_tbl[(sdtr_data >> 4) &
10722
                           (uchar) (asc_dvc->max_sdtr_index - 1)],
10723
                          (uchar) (sdtr_data & (uchar) ASC_SYN_MAX_OFFSET));
10724
        }
10725
 
10726
        AscWriteLramByte(iop_base,
10727
                         (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
10728
                         q_cntl);
10729
 
10730
        tag_code = AscReadLramByte(iop_base,
10731
                    (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TAG_CODE));
10732
        tag_code &= 0xDC;
10733
        if (
10734
               (asc_dvc->pci_fix_asyn_xfer & target_id)
10735
               && !(asc_dvc->pci_fix_asyn_xfer_always & target_id)
10736
) {
10737
 
10738
            tag_code |= (ASC_TAG_FLAG_DISABLE_DISCONNECT
10739
                         | ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX);
10740
 
10741
        }
10742
        AscWriteLramByte(iop_base,
10743
                     (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TAG_CODE),
10744
                         tag_code);
10745
 
10746
        q_status = AscReadLramByte(iop_base,
10747
                      (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_STATUS));
10748
        q_status |= (QS_READY | QS_BUSY);
10749
        AscWriteLramByte(iop_base,
10750
                       (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_STATUS),
10751
                         q_status);
10752
 
10753
        scsi_busy = AscReadLramByte(iop_base,
10754
                                    (ushort) ASCV_SCSIBUSY_B);
10755
        scsi_busy &= ~target_id;
10756
        AscWriteLramByte(iop_base, (ushort) ASCV_SCSIBUSY_B, scsi_busy);
10757
 
10758
        AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10759
        return (0);
10760
    } else if (int_halt_code == ASC_HALT_SDTR_REJECTED) {
10761
 
10762
        AscMemWordCopyFromLram(iop_base,
10763
                               ASCV_MSGOUT_BEG,
10764
                               (ushort *) & out_msg,
10765
                               (ushort) (sizeof (EXT_MSG) >> 1));
10766
 
10767
        if ((out_msg.msg_type == MS_EXTEND) &&
10768
            (out_msg.msg_len == MS_SDTR_LEN) &&
10769
            (out_msg.msg_req == MS_SDTR_CODE)) {
10770
 
10771
            asc_dvc->init_sdtr &= ~target_id;
10772
            asc_dvc->sdtr_done &= ~target_id;
10773
            AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
10774
            boardp->sdtr_data[tid_no] = asyn_sdtr;
10775
        }
10776
        q_cntl &= ~QC_MSG_OUT;
10777
        AscWriteLramByte(iop_base,
10778
                         (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
10779
                         q_cntl);
10780
        AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10781
        return (0);
10782
    } else if (int_halt_code == ASC_HALT_SS_QUEUE_FULL) {
10783
 
10784
        scsi_status = AscReadLramByte(iop_base,
10785
          (ushort) ((ushort) halt_q_addr + (ushort) ASC_SCSIQ_SCSI_STATUS));
10786
        cur_dvc_qng = AscReadLramByte(iop_base,
10787
                     (ushort) ((ushort) ASC_QADR_BEG + (ushort) target_ix));
10788
        if ((cur_dvc_qng > 0) &&
10789
            (asc_dvc->cur_dvc_qng[tid_no] > 0)) {
10790
 
10791
            scsi_busy = AscReadLramByte(iop_base,
10792
                                        (ushort) ASCV_SCSIBUSY_B);
10793
            scsi_busy |= target_id;
10794
            AscWriteLramByte(iop_base,
10795
                             (ushort) ASCV_SCSIBUSY_B, scsi_busy);
10796
            asc_dvc->queue_full_or_busy |= target_id;
10797
 
10798
            if (scsi_status == SS_QUEUE_FULL) {
10799
                if (cur_dvc_qng > ASC_MIN_TAGGED_CMD) {
10800
                    cur_dvc_qng -= 1;
10801
                    asc_dvc->max_dvc_qng[tid_no] = cur_dvc_qng;
10802
 
10803
                    AscWriteLramByte(iop_base,
10804
                          (ushort) ((ushort) ASCV_MAX_DVC_QNG_BEG +
10805
                           (ushort) tid_no),
10806
                          cur_dvc_qng);
10807
 
10808
                    /*
10809
                     * Set the device queue depth to the number of
10810
                     * active requests when the QUEUE FULL condition
10811
                     * was encountered.
10812
                     */
10813
                    boardp->queue_full |= target_id;
10814
                    boardp->queue_full_cnt[tid_no] = cur_dvc_qng;
10815
#if ASC_QUEUE_FLOW_CONTROL
10816
                    if (boardp->device[tid_no] != NULL &&
10817
                        boardp->device[tid_no]->queue_curr_depth >
10818
                        cur_dvc_qng) {
10819
                        boardp->device[tid_no]->queue_curr_depth =
10820
                            cur_dvc_qng;
10821
                    }
10822
#endif /* ASC_QUEUE_FLOW_CONTROL */
10823
                }
10824
            }
10825
        }
10826
        AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10827
        return (0);
10828
    }
10829
    return (0);
10830
}
10831
 
10832
STATIC uchar
10833
_AscCopyLramScsiDoneQ(
10834
                         PortAddr iop_base,
10835
                         ushort q_addr,
10836
                         REG ASC_QDONE_INFO * scsiq,
10837
                         ulong max_dma_count
10838
)
10839
{
10840
    ushort              _val;
10841
    uchar               sg_queue_cnt;
10842
 
10843
    DvcGetQinfo(iop_base,
10844
                (ushort) (q_addr + (ushort) ASC_SCSIQ_DONE_INFO_BEG),
10845
                (ushort *) scsiq,
10846
              (ushort) ((sizeof (ASC_SCSIQ_2) + sizeof (ASC_SCSIQ_3)) / 2));
10847
    _val = AscReadLramWord(iop_base,
10848
                           (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS));
10849
    scsiq->q_status = (uchar) _val;
10850
    scsiq->q_no = (uchar) (_val >> 8);
10851
    _val = AscReadLramWord(iop_base,
10852
                           (ushort) (q_addr + (ushort) ASC_SCSIQ_B_CNTL));
10853
    scsiq->cntl = (uchar) _val;
10854
    sg_queue_cnt = (uchar) (_val >> 8);
10855
    _val = AscReadLramWord(iop_base,
10856
                        (ushort) (q_addr + (ushort) ASC_SCSIQ_B_SENSE_LEN));
10857
    scsiq->sense_len = (uchar) _val;
10858
    scsiq->extra_bytes = (uchar) (_val >> 8);
10859
    scsiq->remain_bytes = AscReadLramWord(iop_base,
10860
                 (ushort) (q_addr + (ushort) ASC_SCSIQ_DW_REMAIN_XFER_CNT));
10861
    scsiq->remain_bytes &= max_dma_count;
10862
    return (sg_queue_cnt);
10863
}
10864
 
10865
STATIC int
10866
AscIsrQDone(
10867
               REG ASC_DVC_VAR asc_ptr_type * asc_dvc
10868
)
10869
{
10870
    uchar               next_qp;
10871
    uchar               n_q_used;
10872
    uchar               sg_list_qp;
10873
    uchar               sg_queue_cnt;
10874
    uchar               q_cnt;
10875
    uchar               done_q_tail;
10876
    uchar               tid_no;
10877
    ASC_SCSI_BIT_ID_TYPE scsi_busy;
10878
    ASC_SCSI_BIT_ID_TYPE target_id;
10879
    PortAddr            iop_base;
10880
    ushort              q_addr;
10881
    ushort              sg_q_addr;
10882
    uchar               cur_target_qng;
10883
    ASC_QDONE_INFO      scsiq_buf;
10884
    REG ASC_QDONE_INFO *scsiq;
10885
    int                 false_overrun;
10886
    ASC_ISR_CALLBACK    asc_isr_callback;
10887
 
10888
    iop_base = asc_dvc->iop_base;
10889
    asc_isr_callback = (ASC_ISR_CALLBACK) asc_dvc->isr_callback;
10890
    n_q_used = 1;
10891
    scsiq = (ASC_QDONE_INFO *) & scsiq_buf;
10892
    done_q_tail = (uchar) AscGetVarDoneQTail(iop_base);
10893
    q_addr = ASC_QNO_TO_QADDR(done_q_tail);
10894
    next_qp = AscReadLramByte(iop_base,
10895
                              (ushort) (q_addr + (ushort) ASC_SCSIQ_B_FWD));
10896
    if (next_qp != ASC_QLINK_END) {
10897
        AscPutVarDoneQTail(iop_base, next_qp);
10898
        q_addr = ASC_QNO_TO_QADDR(next_qp);
10899
        sg_queue_cnt = _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq,
10900
            asc_dvc->max_dma_count);
10901
        AscWriteLramByte(iop_base,
10902
                         (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS),
10903
             (uchar) (scsiq->q_status & (uchar) ~ (QS_READY | QS_ABORTED)));
10904
        tid_no = ASC_TIX_TO_TID(scsiq->d2.target_ix);
10905
        target_id = ASC_TIX_TO_TARGET_ID(scsiq->d2.target_ix);
10906
        if ((scsiq->cntl & QC_SG_HEAD) != 0) {
10907
            sg_q_addr = q_addr;
10908
            sg_list_qp = next_qp;
10909
            for (q_cnt = 0; q_cnt < sg_queue_cnt; q_cnt++) {
10910
                sg_list_qp = AscReadLramByte(iop_base,
10911
                           (ushort) (sg_q_addr + (ushort) ASC_SCSIQ_B_FWD));
10912
                sg_q_addr = ASC_QNO_TO_QADDR(sg_list_qp);
10913
                if (sg_list_qp == ASC_QLINK_END) {
10914
                    AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SG_Q_LINKS);
10915
                    scsiq->d3.done_stat = QD_WITH_ERROR;
10916
                    scsiq->d3.host_stat = QHSTA_D_QDONE_SG_LIST_CORRUPTED;
10917
                    goto FATAL_ERR_QDONE;
10918
                }
10919
                AscWriteLramByte(iop_base,
10920
                         (ushort) (sg_q_addr + (ushort) ASC_SCSIQ_B_STATUS),
10921
                                 QS_FREE);
10922
            }
10923
            n_q_used = sg_queue_cnt + 1;
10924
            AscPutVarDoneQTail(iop_base, sg_list_qp);
10925
        }
10926
        if (asc_dvc->queue_full_or_busy & target_id) {
10927
            cur_target_qng = AscReadLramByte(iop_base,
10928
            (ushort) ((ushort) ASC_QADR_BEG + (ushort) scsiq->d2.target_ix));
10929
            if (cur_target_qng < asc_dvc->max_dvc_qng[tid_no]) {
10930
                scsi_busy = AscReadLramByte(iop_base,
10931
                                            (ushort) ASCV_SCSIBUSY_B);
10932
                scsi_busy &= ~target_id;
10933
                AscWriteLramByte(iop_base,
10934
                                 (ushort) ASCV_SCSIBUSY_B, scsi_busy);
10935
                asc_dvc->queue_full_or_busy &= ~target_id;
10936
            }
10937
        }
10938
        if (asc_dvc->cur_total_qng >= n_q_used) {
10939
            asc_dvc->cur_total_qng -= n_q_used;
10940
            if (asc_dvc->cur_dvc_qng[tid_no] != 0) {
10941
                asc_dvc->cur_dvc_qng[tid_no]--;
10942
            }
10943
        } else {
10944
            AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CUR_QNG);
10945
            scsiq->d3.done_stat = QD_WITH_ERROR;
10946
            goto FATAL_ERR_QDONE;
10947
        }
10948
        if ((scsiq->d2.srb_ptr == 0UL) ||
10949
            ((scsiq->q_status & QS_ABORTED) != 0)) {
10950
            return (0x11);
10951
        } else if (scsiq->q_status == QS_DONE) {
10952
            false_overrun = FALSE;
10953
            if (scsiq->extra_bytes != 0) {
10954
                scsiq->remain_bytes += (ulong) scsiq->extra_bytes;
10955
            }
10956
            if (scsiq->d3.done_stat == QD_WITH_ERROR) {
10957
                if (scsiq->d3.host_stat == QHSTA_M_DATA_OVER_RUN) {
10958
                    if ((scsiq->cntl & (QC_DATA_IN | QC_DATA_OUT)) == 0) {
10959
                        scsiq->d3.done_stat = QD_NO_ERROR;
10960
                        scsiq->d3.host_stat = QHSTA_NO_ERROR;
10961
                    } else if (false_overrun) {
10962
                        scsiq->d3.done_stat = QD_NO_ERROR;
10963
                        scsiq->d3.host_stat = QHSTA_NO_ERROR;
10964
                    }
10965
                } else if (scsiq->d3.host_stat ==
10966
                           QHSTA_M_HUNG_REQ_SCSI_BUS_RESET) {
10967
                    AscStopChip(iop_base);
10968
                    AscSetChipControl(iop_base,
10969
                        (uchar) (CC_SCSI_RESET | CC_HALT));
10970
                    DvcDelayNanoSecond(asc_dvc, 60000);
10971
                    AscSetChipControl(iop_base, CC_HALT);
10972
                    AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
10973
                    AscSetChipStatus(iop_base, 0);
10974
                    AscSetChipControl(iop_base, 0);
10975
                }
10976
            }
10977
            if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
10978
                (*asc_isr_callback) (asc_dvc, scsiq);
10979
            } else {
10980
                if ((AscReadLramByte(iop_base,
10981
                          (ushort) (q_addr + (ushort) ASC_SCSIQ_CDB_BEG)) ==
10982
                     SCSICMD_StartStopUnit)) {
10983
                    asc_dvc->unit_not_ready &= ~target_id;
10984
                    if (scsiq->d3.done_stat != QD_NO_ERROR) {
10985
                        asc_dvc->start_motor &= ~target_id;
10986
                    }
10987
                }
10988
            }
10989
            return (1);
10990
        } else {
10991
            AscSetLibErrorCode(asc_dvc, ASCQ_ERR_Q_STATUS);
10992
          FATAL_ERR_QDONE:
10993
            if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
10994
                (*asc_isr_callback) (asc_dvc, scsiq);
10995
            }
10996
            return (0x80);
10997
        }
10998
    }
10999
    return (0);
11000
}
11001
 
11002
STATIC int
11003
AscISR(
11004
          REG ASC_DVC_VAR asc_ptr_type * asc_dvc
11005
)
11006
{
11007
    ASC_CS_TYPE         chipstat;
11008
    PortAddr            iop_base;
11009
    ushort              saved_ram_addr;
11010
    uchar               ctrl_reg;
11011
    uchar               saved_ctrl_reg;
11012
    int                 int_pending;
11013
    int                 status;
11014
    uchar               host_flag;
11015
 
11016
    iop_base = asc_dvc->iop_base;
11017
    int_pending = FALSE;
11018
    if (((asc_dvc->init_state & ASC_INIT_STATE_END_LOAD_MC) == 0)
11019
        || (asc_dvc->isr_callback == 0)
11020
) {
11021
        return (ERR);
11022
    }
11023
    if (asc_dvc->in_critical_cnt != 0) {
11024
        AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_ON_CRITICAL);
11025
        return (ERR);
11026
    }
11027
    if (asc_dvc->is_in_int) {
11028
        AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_RE_ENTRY);
11029
        return (ERR);
11030
    }
11031
    asc_dvc->is_in_int = TRUE;
11032
    ctrl_reg = AscGetChipControl(iop_base);
11033
    saved_ctrl_reg = ctrl_reg & (~(CC_SCSI_RESET | CC_CHIP_RESET |
11034
                                   CC_SINGLE_STEP | CC_DIAG | CC_TEST));
11035
    chipstat = AscGetChipStatus(iop_base);
11036
    if (chipstat & CSW_SCSI_RESET_LATCH) {
11037
        if (!(asc_dvc->bus_type & (ASC_IS_VL | ASC_IS_EISA))) {
11038
            int_pending = TRUE;
11039
            asc_dvc->sdtr_done = 0;
11040
            saved_ctrl_reg &= (uchar) (~CC_HALT);
11041
            while (AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE) ;
11042
            AscSetChipControl(iop_base, (CC_CHIP_RESET | CC_HALT));
11043
            AscSetChipControl(iop_base, CC_HALT);
11044
            AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
11045
            AscSetChipStatus(iop_base, 0);
11046
            chipstat = AscGetChipStatus(iop_base);
11047
        }
11048
    }
11049
    saved_ram_addr = AscGetChipLramAddr(iop_base);
11050
    host_flag = AscReadLramByte(iop_base,
11051
        ASCV_HOST_FLAG_B) & (uchar) (~ASC_HOST_FLAG_IN_ISR);
11052
    AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
11053
                     (uchar) (host_flag | (uchar) ASC_HOST_FLAG_IN_ISR));
11054
    if ((chipstat & CSW_INT_PENDING)
11055
        || (int_pending)
11056
) {
11057
        AscAckInterrupt(iop_base);
11058
        int_pending = TRUE;
11059
        if ((chipstat & CSW_HALTED) &&
11060
            (ctrl_reg & CC_SINGLE_STEP)) {
11061
            if (AscIsrChipHalted(asc_dvc) == ERR) {
11062
                goto ISR_REPORT_QDONE_FATAL_ERROR;
11063
            } else {
11064
                saved_ctrl_reg &= (uchar) (~CC_HALT);
11065
            }
11066
        } else {
11067
          ISR_REPORT_QDONE_FATAL_ERROR:
11068
            if ((asc_dvc->dvc_cntl & ASC_CNTL_INT_MULTI_Q) != 0) {
11069
                while (((status = AscIsrQDone(asc_dvc)) & 0x01) != 0) {
11070
                }
11071
            } else {
11072
                do {
11073
                    if ((status = AscIsrQDone(asc_dvc)) == 1) {
11074
                        break;
11075
                    }
11076
                } while (status == 0x11);
11077
            }
11078
            if ((status & 0x80) != 0)
11079
                int_pending = ERR;
11080
        }
11081
    }
11082
    AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
11083
    AscSetChipLramAddr(iop_base, saved_ram_addr);
11084
    AscSetChipControl(iop_base, saved_ctrl_reg);
11085
    asc_dvc->is_in_int = FALSE;
11086
    return (int_pending);
11087
}
11088
 
11089
STATIC uchar _asc_mcode_buf[] ASC_INITDATA =
11090
{
11091
  0x01,  0x03,  0x01,  0x19,  0x0F,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
11092
  0x0F,  0x0F,  0x0F,  0x0F,  0x0F,  0x0F,  0x0F,  0x0F,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
11093
  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
11094
  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
11095
  0x00,  0x00,  0x00,  0x00,  0x91,  0x10,  0x0A,  0x05,  0x01,  0x00,  0x00,  0x00,  0x00,  0xFF,  0x00,  0x00,
11096
  0x00,  0x00,  0x00,  0x00,  0xFF,  0x80,  0xFF,  0xFF,  0x01,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
11097
  0x00,  0x00,  0x00,  0x23,  0x00,  0x24,  0x00,  0x00,  0x00,  0x07,  0x00,  0xFF,  0x00,  0x00,  0x00,  0x00,
11098
  0xFF,  0xFF,  0xFF,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xE2,  0x88,  0x00,  0x00,  0x00,  0x00,
11099
  0x80,  0x73,  0x48,  0x04,  0x36,  0x00,  0x00,  0xA2,  0xC2,  0x00,  0x80,  0x73,  0x03,  0x23,  0x36,  0x40,
11100
  0xB6,  0x00,  0x36,  0x00,  0x05,  0xD6,  0x0C,  0xD2,  0x12,  0xDA,  0x00,  0xA2,  0xC2,  0x00,  0x92,  0x80,
11101
  0x1E,  0x98,  0x50,  0x00,  0xF5,  0x00,  0x48,  0x98,  0xDF,  0x23,  0x36,  0x60,  0xB6,  0x00,  0x92,  0x80,
11102
  0x4F,  0x00,  0xF5,  0x00,  0x48,  0x98,  0xEF,  0x23,  0x36,  0x60,  0xB6,  0x00,  0x92,  0x80,  0x80,  0x62,
11103
  0x92,  0x80,  0x00,  0x46,  0x17,  0xEE,  0x13,  0xEA,  0x02,  0x01,  0x09,  0xD8,  0xCD,  0x04,  0x4D,  0x00,
11104
  0x00,  0xA3,  0xD6,  0x00,  0xA6,  0x97,  0x7F,  0x23,  0x04,  0x61,  0x84,  0x01,  0xE6,  0x84,  0xD2,  0xC1,
11105
  0x80,  0x73,  0xCD,  0x04,  0x4D,  0x00,  0x00,  0xA3,  0xE2,  0x01,  0xA6,  0x97,  0xCE,  0x81,  0x00,  0x33,
11106
  0x02,  0x00,  0xC0,  0x88,  0x80,  0x73,  0x80,  0x77,  0x00,  0x01,  0x01,  0xA1,  0x02,  0x01,  0x4F,  0x00,
11107
  0x84,  0x97,  0x07,  0xA6,  0x0C,  0x01,  0x00,  0x33,  0x03,  0x00,  0xC0,  0x88,  0x03,  0x03,  0x03,  0xDE,
11108
  0x00,  0x33,  0x05,  0x00,  0xC0,  0x88,  0xCE,  0x00,  0x69,  0x60,  0xCE,  0x00,  0x02,  0x03,  0x4A,  0x60,
11109
  0x00,  0xA2,  0x80,  0x01,  0x80,  0x63,  0x07,  0xA6,  0x2C,  0x01,  0x80,  0x81,  0x03,  0x03,  0x80,  0x63,
11110
  0xE2,  0x00,  0x07,  0xA6,  0x3C,  0x01,  0x00,  0x33,  0x04,  0x00,  0xC0,  0x88,  0x03,  0x07,  0x02,  0x01,
11111
  0x04,  0xCA,  0x0D,  0x23,  0x68,  0x98,  0x4D,  0x04,  0x04,  0x85,  0x05,  0xD8,  0x0D,  0x23,  0x68,  0x98,
11112
  0xCD,  0x04,  0x15,  0x23,  0xF6,  0x88,  0xFB,  0x23,  0x02,  0x61,  0x82,  0x01,  0x80,  0x63,  0x02,  0x03,
11113
  0x06,  0xA3,  0x6A,  0x01,  0x00,  0x33,  0x0A,  0x00,  0xC0,  0x88,  0x4E,  0x00,  0x07,  0xA3,  0x76,  0x01,
11114
  0x00,  0x33,  0x0B,  0x00,  0xC0,  0x88,  0xCD,  0x04,  0x36,  0x2D,  0x00,  0x33,  0x1A,  0x00,  0xC0,  0x88,
11115
  0x50,  0x04,  0x90,  0x81,  0x06,  0xAB,  0x8A,  0x01,  0x90,  0x81,  0x4E,  0x00,  0x07,  0xA3,  0x9A,  0x01,
11116
  0x50,  0x00,  0x00,  0xA3,  0x44,  0x01,  0x00,  0x05,  0x84,  0x81,  0x46,  0x97,  0x02,  0x01,  0x05,  0xC6,
11117
  0x04,  0x23,  0xA0,  0x01,  0x15,  0x23,  0xA1,  0x01,  0xC6,  0x81,  0xFD,  0x23,  0x02,  0x61,  0x82,  0x01,
11118
  0x0A,  0xDA,  0x4A,  0x00,  0x06,  0x61,  0x00,  0xA0,  0xBC,  0x01,  0x80,  0x63,  0xCD,  0x04,  0x36,  0x2D,
11119
  0x00,  0x33,  0x1B,  0x00,  0xC0,  0x88,  0x06,  0x23,  0x68,  0x98,  0xCD,  0x04,  0xE6,  0x84,  0x06,  0x01,
11120
  0x00,  0xA2,  0xDC,  0x01,  0x57,  0x60,  0x00,  0xA0,  0xE2,  0x01,  0xE6,  0x84,  0x80,  0x23,  0xA0,  0x01,
11121
  0xE6,  0x84,  0x80,  0x73,  0x4B,  0x00,  0x06,  0x61,  0x00,  0xA2,  0x08,  0x02,  0x04,  0x01,  0x0C,  0xDE,
11122
  0x02,  0x01,  0x03,  0xCC,  0x4F,  0x00,  0x84,  0x97,  0x04,  0x82,  0x08,  0x23,  0x02,  0x41,  0x82,  0x01,
11123
  0x4F,  0x00,  0x62,  0x97,  0x48,  0x04,  0x84,  0x80,  0xF0,  0x97,  0x00,  0x46,  0x56,  0x00,  0x03,  0xC0,
11124
  0x01,  0x23,  0xE8,  0x00,  0x81,  0x73,  0x06,  0x29,  0x03,  0x42,  0x06,  0xE2,  0x03,  0xEE,  0x67,  0xEB,
11125
  0x11,  0x23,  0xF6,  0x88,  0x04,  0x98,  0xF4,  0x80,  0x80,  0x73,  0x80,  0x77,  0x07,  0xA4,  0x32,  0x02,
11126
  0x7C,  0x95,  0x06,  0xA6,  0x3C,  0x02,  0x03,  0xA6,  0x4C,  0x04,  0xC0,  0x88,  0x04,  0x01,  0x03,  0xD8,
11127
  0xB2,  0x98,  0x6A,  0x96,  0x4E,  0x82,  0xFE,  0x95,  0x80,  0x67,  0x83,  0x03,  0x80,  0x63,  0xB6,  0x2D,
11128
  0x02,  0xA6,  0x78,  0x02,  0x07,  0xA6,  0x66,  0x02,  0x06,  0xA6,  0x6A,  0x02,  0x03,  0xA6,  0x6E,  0x02,
11129
  0x00,  0x33,  0x10,  0x00,  0xC0,  0x88,  0x7C,  0x95,  0x50,  0x82,  0x60,  0x96,  0x50,  0x82,  0x04,  0x23,
11130
  0xA0,  0x01,  0x14,  0x23,  0xA1,  0x01,  0x3C,  0x84,  0x04,  0x01,  0x0C,  0xDC,  0xE0,  0x23,  0x25,  0x61,
11131
  0xEF,  0x00,  0x14,  0x01,  0x4F,  0x04,  0xA8,  0x01,  0x6F,  0x00,  0xA5,  0x01,  0x03,  0x23,  0xA4,  0x01,
11132
  0x06,  0x23,  0x9C,  0x01,  0x24,  0x2B,  0x1C,  0x01,  0x02,  0xA6,  0xB6,  0x02,  0x07,  0xA6,  0x66,  0x02,
11133
  0x06,  0xA6,  0x6A,  0x02,  0x03,  0xA6,  0x20,  0x04,  0x01,  0xA6,  0xC0,  0x02,  0x00,  0xA6,  0xC0,  0x02,
11134
  0x00,  0x33,  0x12,  0x00,  0xC0,  0x88,  0x00,  0x0E,  0x80,  0x63,  0x00,  0x43,  0x00,  0xA0,  0x98,  0x02,
11135
  0x4D,  0x04,  0x04,  0x01,  0x0B,  0xDC,  0xE7,  0x23,  0x04,  0x61,  0x84,  0x01,  0x10,  0x31,  0x12,  0x35,
11136
  0x14,  0x01,  0xEC,  0x00,  0x6C,  0x38,  0x00,  0x3F,  0x00,  0x00,  0xF6,  0x82,  0x18,  0x23,  0x04,  0x61,
11137
  0x18,  0xA0,  0xEE,  0x02,  0x04,  0x01,  0x9C,  0xC8,  0x00,  0x33,  0x1F,  0x00,  0xC0,  0x88,  0x08,  0x31,
11138
  0x0A,  0x35,  0x0C,  0x39,  0x0E,  0x3D,  0x7E,  0x98,  0xB6,  0x2D,  0x01,  0xA6,  0x20,  0x03,  0x00,  0xA6,
11139
  0x20,  0x03,  0x07,  0xA6,  0x18,  0x03,  0x06,  0xA6,  0x1C,  0x03,  0x03,  0xA6,  0x20,  0x04,  0x02,  0xA6,
11140
  0x78,  0x02,  0x00,  0x33,  0x33,  0x00,  0xC0,  0x88,  0x7C,  0x95,  0xFA,  0x82,  0x60,  0x96,  0xFA,  0x82,
11141
  0x82,  0x98,  0x80,  0x42,  0x7E,  0x98,  0x60,  0xE4,  0x04,  0x01,  0x29,  0xC8,  0x31,  0x05,  0x07,  0x01,
11142
  0x00,  0xA2,  0x60,  0x03,  0x00,  0x43,  0x87,  0x01,  0x05,  0x05,  0x86,  0x98,  0x7E,  0x98,  0x00,  0xA6,
11143
  0x22,  0x03,  0x07,  0xA6,  0x58,  0x03,  0x03,  0xA6,  0x3C,  0x04,  0x06,  0xA6,  0x5C,  0x03,  0x01,  0xA6,
11144
  0x22,  0x03,  0x00,  0x33,  0x25,  0x00,  0xC0,  0x88,  0x7C,  0x95,  0x3E,  0x83,  0x60,  0x96,  0x3E,  0x83,
11145
  0x04,  0x01,  0x0C,  0xCE,  0x03,  0xC8,  0x00,  0x33,  0x42,  0x00,  0xC0,  0x88,  0x00,  0x01,  0x05,  0x05,
11146
  0xFF,  0xA2,  0x7E,  0x03,  0xB1,  0x01,  0x08,  0x23,  0xB2,  0x01,  0x3A,  0x83,  0x05,  0x05,  0x15,  0x01,
11147
  0x00,  0xA2,  0x9E,  0x03,  0xEC,  0x00,  0x6E,  0x00,  0x95,  0x01,  0x6C,  0x38,  0x00,  0x3F,  0x00,  0x00,
11148
  0x01,  0xA6,  0x9A,  0x03,  0x00,  0xA6,  0x9A,  0x03,  0x12,  0x84,  0x80,  0x42,  0x7E,  0x98,  0x01,  0xA6,
11149
  0xA8,  0x03,  0x00,  0xA6,  0xC0,  0x03,  0x12,  0x84,  0xA6,  0x98,  0x80,  0x42,  0x01,  0xA6,  0xA8,  0x03,
11150
  0x07,  0xA6,  0xB6,  0x03,  0xD8,  0x83,  0x7C,  0x95,  0xAC,  0x83,  0x00,  0x33,  0x2F,  0x00,  0xC0,  0x88,
11151
  0xA6,  0x98,  0x80,  0x42,  0x00,  0xA6,  0xC0,  0x03,  0x07,  0xA6,  0xCE,  0x03,  0xD8,  0x83,  0x7C,  0x95,
11152
  0xC4,  0x83,  0x00,  0x33,  0x26,  0x00,  0xC0,  0x88,  0x38,  0x2B,  0x80,  0x32,  0x80,  0x36,  0x04,  0x23,
11153
  0xA0,  0x01,  0x12,  0x23,  0xA1,  0x01,  0x12,  0x84,  0x06,  0xF0,  0x06,  0xA4,  0xF6,  0x03,  0x80,  0x6B,
11154
  0x05,  0x23,  0x83,  0x03,  0x80,  0x63,  0x03,  0xA6,  0x10,  0x04,  0x07,  0xA6,  0x08,  0x04,  0x06,  0xA6,
11155
  0x0C,  0x04,  0x00,  0x33,  0x17,  0x00,  0xC0,  0x88,  0x7C,  0x95,  0xF6,  0x83,  0x60,  0x96,  0xF6,  0x83,
11156
  0x20,  0x84,  0x06,  0xF0,  0x06,  0xA4,  0x20,  0x04,  0x80,  0x6B,  0x05,  0x23,  0x83,  0x03,  0x80,  0x63,
11157
  0xB6,  0x2D,  0x03,  0xA6,  0x3C,  0x04,  0x07,  0xA6,  0x34,  0x04,  0x06,  0xA6,  0x38,  0x04,  0x00,  0x33,
11158
  0x30,  0x00,  0xC0,  0x88,  0x7C,  0x95,  0x20,  0x84,  0x60,  0x96,  0x20,  0x84,  0x1D,  0x01,  0x06,  0xCC,
11159
  0x00,  0x33,  0x00,  0x84,  0xC0,  0x20,  0x00,  0x23,  0xEA,  0x00,  0x81,  0x62,  0xA2,  0x0D,  0x80,  0x63,
11160
  0x07,  0xA6,  0x5A,  0x04,  0x00,  0x33,  0x18,  0x00,  0xC0,  0x88,  0x03,  0x03,  0x80,  0x63,  0xA3,  0x01,
11161
  0x07,  0xA4,  0x64,  0x04,  0x23,  0x01,  0x00,  0xA2,  0x86,  0x04,  0x0A,  0xA0,  0x76,  0x04,  0xE0,  0x00,
11162
  0x00,  0x33,  0x1D,  0x00,  0xC0,  0x88,  0x0B,  0xA0,  0x82,  0x04,  0xE0,  0x00,  0x00,  0x33,  0x1E,  0x00,
11163
  0xC0,  0x88,  0x42,  0x23,  0xF6,  0x88,  0x00,  0x23,  0x22,  0xA3,  0xE6,  0x04,  0x08,  0x23,  0x22,  0xA3,
11164
  0xA2,  0x04,  0x28,  0x23,  0x22,  0xA3,  0xAE,  0x04,  0x02,  0x23,  0x22,  0xA3,  0xC4,  0x04,  0x42,  0x23,
11165
  0xF6,  0x88,  0x4A,  0x00,  0x06,  0x61,  0x00,  0xA0,  0xAE,  0x04,  0x45,  0x23,  0xF6,  0x88,  0x04,  0x98,
11166
  0x00,  0xA2,  0xC0,  0x04,  0xB2,  0x98,  0x00,  0x33,  0x00,  0x82,  0xC0,  0x20,  0x81,  0x62,  0xF0,  0x81,
11167
  0x47,  0x23,  0xF6,  0x88,  0x04,  0x01,  0x0B,  0xDE,  0x04,  0x98,  0xB2,  0x98,  0x00,  0x33,  0x00,  0x81,
11168
  0xC0,  0x20,  0x81,  0x62,  0x14,  0x01,  0x00,  0xA0,  0x08,  0x02,  0x43,  0x23,  0xF6,  0x88,  0x04,  0x23,
11169
  0xA0,  0x01,  0x44,  0x23,  0xA1,  0x01,  0x80,  0x73,  0x4D,  0x00,  0x03,  0xA3,  0xF4,  0x04,  0x00,  0x33,
11170
  0x27,  0x00,  0xC0,  0x88,  0x04,  0x01,  0x04,  0xDC,  0x02,  0x23,  0xA2,  0x01,  0x04,  0x23,  0xA0,  0x01,
11171
  0x04,  0x98,  0x26,  0x95,  0x4B,  0x00,  0xF6,  0x00,  0x4F,  0x04,  0x4F,  0x00,  0x00,  0xA3,  0x22,  0x05,
11172
  0x00,  0x05,  0x76,  0x00,  0x06,  0x61,  0x00,  0xA2,  0x1C,  0x05,  0x0A,  0x85,  0x46,  0x97,  0xCD,  0x04,
11173
  0x24,  0x85,  0x48,  0x04,  0x84,  0x80,  0x02,  0x01,  0x03,  0xDA,  0x80,  0x23,  0x82,  0x01,  0x34,  0x85,
11174
  0x02,  0x23,  0xA0,  0x01,  0x4A,  0x00,  0x06,  0x61,  0x00,  0xA2,  0x40,  0x05,  0x1D,  0x01,  0x04,  0xD6,
11175
  0xFF,  0x23,  0x86,  0x41,  0x4B,  0x60,  0xCB,  0x00,  0xFF,  0x23,  0x80,  0x01,  0x49,  0x00,  0x81,  0x01,
11176
  0x04,  0x01,  0x02,  0xC8,  0x30,  0x01,  0x80,  0x01,  0xF7,  0x04,  0x03,  0x01,  0x49,  0x04,  0x80,  0x01,
11177
  0xC9,  0x00,  0x00,  0x05,  0x00,  0x01,  0xFF,  0xA0,  0x60,  0x05,  0x77,  0x04,  0x01,  0x23,  0xEA,  0x00,
11178
  0x5D,  0x00,  0xFE,  0xC7,  0x00,  0x62,  0x00,  0x23,  0xEA,  0x00,  0x00,  0x63,  0x07,  0xA4,  0xF8,  0x05,
11179
  0x03,  0x03,  0x02,  0xA0,  0x8E,  0x05,  0xF4,  0x85,  0x00,  0x33,  0x2D,  0x00,  0xC0,  0x88,  0x04,  0xA0,
11180
  0xB8,  0x05,  0x80,  0x63,  0x00,  0x23,  0xDF,  0x00,  0x4A,  0x00,  0x06,  0x61,  0x00,  0xA2,  0xA4,  0x05,
11181
  0x1D,  0x01,  0x06,  0xD6,  0x02,  0x23,  0x02,  0x41,  0x82,  0x01,  0x50,  0x00,  0x62,  0x97,  0x04,  0x85,
11182
  0x04,  0x23,  0x02,  0x41,  0x82,  0x01,  0x04,  0x85,  0x08,  0xA0,  0xBE,  0x05,  0xF4,  0x85,  0x03,  0xA0,
11183
  0xC4,  0x05,  0xF4,  0x85,  0x01,  0xA0,  0xCE,  0x05,  0x88,  0x00,  0x80,  0x63,  0xCC,  0x86,  0x07,  0xA0,
11184
  0xEE,  0x05,  0x5F,  0x00,  0x00,  0x2B,  0xDF,  0x08,  0x00,  0xA2,  0xE6,  0x05,  0x80,  0x67,  0x80,  0x63,
11185
  0x01,  0xA2,  0x7A,  0x06,  0x7C,  0x85,  0x06,  0x23,  0x68,  0x98,  0x48,  0x23,  0xF6,  0x88,  0x07,  0x23,
11186
  0x80,  0x00,  0x06,  0x87,  0x80,  0x63,  0x7C,  0x85,  0x00,  0x23,  0xDF,  0x00,  0x00,  0x63,  0x4A,  0x00,
11187
  0x06,  0x61,  0x00,  0xA2,  0x36,  0x06,  0x1D,  0x01,  0x16,  0xD4,  0xC0,  0x23,  0x07,  0x41,  0x83,  0x03,
11188
  0x80,  0x63,  0x06,  0xA6,  0x1C,  0x06,  0x00,  0x33,  0x37,  0x00,  0xC0,  0x88,  0x1D,  0x01,  0x01,  0xD6,
11189
  0x20,  0x23,  0x63,  0x60,  0x83,  0x03,  0x80,  0x63,  0x02,  0x23,  0xDF,  0x00,  0x07,  0xA6,  0x7C,  0x05,
11190
  0xEF,  0x04,  0x6F,  0x00,  0x00,  0x63,  0x4B,  0x00,  0x06,  0x41,  0xCB,  0x00,  0x52,  0x00,  0x06,  0x61,
11191
  0x00,  0xA2,  0x4E,  0x06,  0x1D,  0x01,  0x03,  0xCA,  0xC0,  0x23,  0x07,  0x41,  0x00,  0x63,  0x1D,  0x01,
11192
  0x04,  0xCC,  0x00,  0x33,  0x00,  0x83,  0xC0,  0x20,  0x81,  0x62,  0x80,  0x23,  0x07,  0x41,  0x00,  0x63,
11193
  0x80,  0x67,  0x08,  0x23,  0x83,  0x03,  0x80,  0x63,  0x00,  0x63,  0x01,  0x23,  0xDF,  0x00,  0x06,  0xA6,
11194
  0x84,  0x06,  0x07,  0xA6,  0x7C,  0x05,  0x80,  0x67,  0x80,  0x63,  0x00,  0x33,  0x00,  0x40,  0xC0,  0x20,
11195
  0x81,  0x62,  0x00,  0x63,  0x00,  0x00,  0xFE,  0x95,  0x83,  0x03,  0x80,  0x63,  0x06,  0xA6,  0x94,  0x06,
11196
  0x07,  0xA6,  0x7C,  0x05,  0x00,  0x00,  0x01,  0xA0,  0x14,  0x07,  0x00,  0x2B,  0x40,  0x0E,  0x80,  0x63,
11197
  0x01,  0x00,  0x06,  0xA6,  0xAA,  0x06,  0x07,  0xA6,  0x7C,  0x05,  0x40,  0x0E,  0x80,  0x63,  0x00,  0x43,
11198
  0x00,  0xA0,  0xA2,  0x06,  0x06,  0xA6,  0xBC,  0x06,  0x07,  0xA6,  0x7C,  0x05,  0x80,  0x67,  0x40,  0x0E,
11199
  0x80,  0x63,  0x07,  0xA6,  0x7C,  0x05,  0x00,  0x23,  0xDF,  0x00,  0x00,  0x63,  0x07,  0xA6,  0xD6,  0x06,
11200
  0x00,  0x33,  0x2A,  0x00,  0xC0,  0x88,  0x03,  0x03,  0x80,  0x63,  0x89,  0x00,  0x0A,  0x2B,  0x07,  0xA6,
11201
  0xE8,  0x06,  0x00,  0x33,  0x29,  0x00,  0xC0,  0x88,  0x00,  0x43,  0x00,  0xA2,  0xF4,  0x06,  0xC0,  0x0E,
11202
  0x80,  0x63,  0xDE,  0x86,  0xC0,  0x0E,  0x00,  0x33,  0x00,  0x80,  0xC0,  0x20,  0x81,  0x62,  0x04,  0x01,
11203
  0x02,  0xDA,  0x80,  0x63,  0x7C,  0x85,  0x80,  0x7B,  0x80,  0x63,  0x06,  0xA6,  0x8C,  0x06,  0x00,  0x33,
11204
  0x2C,  0x00,  0xC0,  0x88,  0x0C,  0xA2,  0x2E,  0x07,  0xFE,  0x95,  0x83,  0x03,  0x80,  0x63,  0x06,  0xA6,
11205
  0x2C,  0x07,  0x07,  0xA6,  0x7C,  0x05,  0x00,  0x33,  0x3D,  0x00,  0xC0,  0x88,  0x00,  0x00,  0x80,  0x67,
11206
  0x83,  0x03,  0x80,  0x63,  0x0C,  0xA0,  0x44,  0x07,  0x07,  0xA6,  0x7C,  0x05,  0xBF,  0x23,  0x04,  0x61,
11207
  0x84,  0x01,  0xE6,  0x84,  0x00,  0x63,  0xF0,  0x04,  0x01,  0x01,  0xF1,  0x00,  0x00,  0x01,  0xF2,  0x00,
11208
  0x01,  0x05,  0x80,  0x01,  0x72,  0x04,  0x71,  0x00,  0x81,  0x01,  0x70,  0x04,  0x80,  0x05,  0x81,  0x05,
11209
  0x00,  0x63,  0xF0,  0x04,  0xF2,  0x00,  0x72,  0x04,  0x01,  0x01,  0xF1,  0x00,  0x70,  0x00,  0x81,  0x01,
11210
  0x70,  0x04,  0x71,  0x00,  0x81,  0x01,  0x72,  0x00,  0x80,  0x01,  0x71,  0x04,  0x70,  0x00,  0x80,  0x01,
11211
  0x70,  0x04,  0x00,  0x63,  0xF0,  0x04,  0xF2,  0x00,  0x72,  0x04,  0x00,  0x01,  0xF1,  0x00,  0x70,  0x00,
11212
  0x80,  0x01,  0x70,  0x04,  0x71,  0x00,  0x80,  0x01,  0x72,  0x00,  0x81,  0x01,  0x71,  0x04,  0x70,  0x00,
11213
  0x81,  0x01,  0x70,  0x04,  0x00,  0x63,  0x00,  0x23,  0xB3,  0x01,  0x83,  0x05,  0xA3,  0x01,  0xA2,  0x01,
11214
  0xA1,  0x01,  0x01,  0x23,  0xA0,  0x01,  0x00,  0x01,  0xC8,  0x00,  0x03,  0xA1,  0xC4,  0x07,  0x00,  0x33,
11215
  0x07,  0x00,  0xC0,  0x88,  0x80,  0x05,  0x81,  0x05,  0x04,  0x01,  0x11,  0xC8,  0x48,  0x00,  0xB0,  0x01,
11216
  0xB1,  0x01,  0x08,  0x23,  0xB2,  0x01,  0x05,  0x01,  0x48,  0x04,  0x00,  0x43,  0x00,  0xA2,  0xE4,  0x07,
11217
  0x00,  0x05,  0xDA,  0x87,  0x00,  0x01,  0xC8,  0x00,  0xFF,  0x23,  0x80,  0x01,  0x05,  0x05,  0x00,  0x63,
11218
  0xF7,  0x04,  0x1A,  0x09,  0xF6,  0x08,  0x6E,  0x04,  0x00,  0x02,  0x80,  0x43,  0x76,  0x08,  0x80,  0x02,
11219
  0x77,  0x04,  0x00,  0x63,  0xF7,  0x04,  0x1A,  0x09,  0xF6,  0x08,  0x6E,  0x04,  0x00,  0x02,  0x00,  0xA0,
11220
  0x14,  0x08,  0x16,  0x88,  0x00,  0x43,  0x76,  0x08,  0x80,  0x02,  0x77,  0x04,  0x00,  0x63,  0xF3,  0x04,
11221
  0x00,  0x23,  0xF4,  0x00,  0x74,  0x00,  0x80,  0x43,  0xF4,  0x00,  0xCF,  0x40,  0x00,  0xA2,  0x44,  0x08,
11222
  0x74,  0x04,  0x02,  0x01,  0xF7,  0xC9,  0xF6,  0xD9,  0x00,  0x01,  0x01,  0xA1,  0x24,  0x08,  0x04,  0x98,
11223
  0x26,  0x95,  0x24,  0x88,  0x73,  0x04,  0x00,  0x63,  0xF3,  0x04,  0x75,  0x04,  0x5A,  0x88,  0x02,  0x01,
11224
  0x04,  0xD8,  0x46,  0x97,  0x04,  0x98,  0x26,  0x95,  0x4A,  0x88,  0x75,  0x00,  0x00,  0xA3,  0x64,  0x08,
11225
  0x00,  0x05,  0x4E,  0x88,  0x73,  0x04,  0x00,  0x63,  0x80,  0x7B,  0x80,  0x63,  0x06,  0xA6,  0x76,  0x08,
11226
  0x00,  0x33,  0x3E,  0x00,  0xC0,  0x88,  0x80,  0x67,  0x83,  0x03,  0x80,  0x63,  0x00,  0x63,  0x38,  0x2B,
11227
  0x9C,  0x88,  0x38,  0x2B,  0x92,  0x88,  0x32,  0x09,  0x31,  0x05,  0x92,  0x98,  0x05,  0x05,  0xB2,  0x09,
11228
  0x00,  0x63,  0x00,  0x32,  0x00,  0x36,  0x00,  0x3A,  0x00,  0x3E,  0x00,  0x63,  0x80,  0x32,  0x80,  0x36,
11229
  0x80,  0x3A,  0x80,  0x3E,  0x00,  0x63,  0x38,  0x2B,  0x40,  0x32,  0x40,  0x36,  0x40,  0x3A,  0x40,  0x3E,
11230
  0x00,  0x63,  0x5A,  0x20,  0xC9,  0x40,  0x00,  0xA0,  0xB2,  0x08,  0x5D,  0x00,  0xFE,  0xC3,  0x00,  0x63,
11231
  0x80,  0x73,  0xE6,  0x20,  0x02,  0x23,  0xE8,  0x00,  0x82,  0x73,  0xFF,  0xFD,  0x80,  0x73,  0x13,  0x23,
11232
  0xF6,  0x88,  0x66,  0x20,  0xC0,  0x20,  0x04,  0x23,  0xA0,  0x01,  0xA1,  0x23,  0xA1,  0x01,  0x81,  0x62,
11233
  0xE0,  0x88,  0x80,  0x73,  0x80,  0x77,  0x68,  0x00,  0x00,  0xA2,  0x80,  0x00,  0x03,  0xC2,  0xF1,  0xC7,
11234
  0x41,  0x23,  0xF6,  0x88,  0x11,  0x23,  0xA1,  0x01,  0x04,  0x23,  0xA0,  0x01,  0xE6,  0x84,
11235
};
11236
 
11237
STATIC ushort _asc_mcode_size ASC_INITDATA = sizeof(_asc_mcode_buf);
11238
STATIC ulong _asc_mcode_chksum ASC_INITDATA = 0x012B5442UL;
11239
 
11240
#define ASC_SYN_OFFSET_ONE_DISABLE_LIST  16
11241
STATIC uchar _syn_offset_one_disable_cmd[ASC_SYN_OFFSET_ONE_DISABLE_LIST] =
11242
{
11243
    SCSICMD_Inquiry,
11244
    SCSICMD_RequestSense,
11245
    SCSICMD_ReadCapacity,
11246
    SCSICMD_ReadTOC,
11247
    SCSICMD_ModeSelect6,
11248
    SCSICMD_ModeSense6,
11249
    SCSICMD_ModeSelect10,
11250
    SCSICMD_ModeSense10,
11251
    0xFF,
11252
    0xFF,
11253
    0xFF,
11254
    0xFF,
11255
    0xFF,
11256
    0xFF,
11257
    0xFF,
11258
    0xFF
11259
};
11260
 
11261
STATIC int
11262
AscExeScsiQueue(
11263
                   REG ASC_DVC_VAR asc_ptr_type * asc_dvc,
11264
                   REG ASC_SCSI_Q * scsiq
11265
)
11266
{
11267
    PortAddr            iop_base;
11268
    int                 last_int_level;
11269
    int                 sta;
11270
    int                 n_q_required;
11271
    int                 disable_syn_offset_one_fix;
11272
    int                 i;
11273
    ulong               addr;
11274
    ASC_EXE_CALLBACK    asc_exe_callback;
11275
    ushort              sg_entry_cnt = 0;
11276
    ushort              sg_entry_cnt_minus_one = 0;
11277
    uchar               target_ix;
11278
    uchar               tid_no;
11279
    uchar               sdtr_data;
11280
    uchar               extra_bytes;
11281
    uchar               scsi_cmd;
11282
    uchar               disable_cmd;
11283
    ASC_SG_HEAD *sg_head;
11284
    ulong               data_cnt;
11285
 
11286
    iop_base = asc_dvc->iop_base;
11287
    sg_head = scsiq->sg_head;
11288
    asc_exe_callback = (ASC_EXE_CALLBACK) asc_dvc->exe_callback;
11289
    if (asc_dvc->err_code != 0)
11290
        return (ERR);
11291
    if (scsiq == (ASC_SCSI_Q *) 0L) {
11292
        AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SCSIQ_NULL_PTR);
11293
        return (ERR);
11294
    }
11295
    scsiq->q1.q_no = 0;
11296
    if ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES) == 0) {
11297
        scsiq->q1.extra_bytes = 0;
11298
    }
11299
    sta = 0;
11300
    target_ix = scsiq->q2.target_ix;
11301
    tid_no = ASC_TIX_TO_TID(target_ix);
11302
    n_q_required = 1;
11303
    if (scsiq->cdbptr[0] == SCSICMD_RequestSense) {
11304
        if ((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) {
11305
            asc_dvc->sdtr_done &= ~scsiq->q1.target_id ;
11306
            sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
11307
            AscMsgOutSDTR(asc_dvc,
11308
                          asc_dvc->sdtr_period_tbl[(sdtr_data >> 4) &
11309
                          (uchar) (asc_dvc->max_sdtr_index - 1)],
11310
                          (uchar) (sdtr_data & (uchar) ASC_SYN_MAX_OFFSET));
11311
            scsiq->q1.cntl |= (QC_MSG_OUT | QC_URGENT);
11312
        }
11313
    }
11314
    last_int_level = DvcEnterCritical();
11315
    if (asc_dvc->in_critical_cnt != 0) {
11316
        DvcLeaveCritical(last_int_level);
11317
        AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CRITICAL_RE_ENTRY);
11318
        return (ERR);
11319
    }
11320
    asc_dvc->in_critical_cnt++;
11321
    if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
11322
        if ((sg_entry_cnt = sg_head->entry_cnt) == 0) {
11323
            asc_dvc->in_critical_cnt--;
11324
            DvcLeaveCritical(last_int_level);
11325
            return (ERR);
11326
        }
11327
        if (sg_entry_cnt > ASC_MAX_SG_LIST) {
11328
            return (ERR);
11329
        }
11330
        if (sg_entry_cnt == 1) {
11331
            scsiq->q1.data_addr = sg_head->sg_list[0].addr;
11332
            scsiq->q1.data_cnt = sg_head->sg_list[0].bytes;
11333
            scsiq->q1.cntl &= ~(QC_SG_HEAD | QC_SG_SWAP_QUEUE);
11334
        }
11335
        sg_entry_cnt_minus_one = sg_entry_cnt - 1;
11336
    }
11337
    scsi_cmd = scsiq->cdbptr[0];
11338
    disable_syn_offset_one_fix = FALSE;
11339
    if ((asc_dvc->pci_fix_asyn_xfer & scsiq->q1.target_id) &&
11340
        !(asc_dvc->pci_fix_asyn_xfer_always & scsiq->q1.target_id)) {
11341
        if (scsiq->q1.cntl & QC_SG_HEAD) {
11342
            data_cnt = 0;
11343
            for (i = 0; i < sg_entry_cnt; i++) {
11344
                data_cnt += sg_head->sg_list[i].bytes;
11345
            }
11346
        } else {
11347
            data_cnt = scsiq->q1.data_cnt;
11348
        }
11349
        if (data_cnt != 0UL) {
11350
            if (data_cnt < 512UL) {
11351
                disable_syn_offset_one_fix = TRUE;
11352
            } else {
11353
                for (i = 0; i < ASC_SYN_OFFSET_ONE_DISABLE_LIST; i++) {
11354
                    disable_cmd = _syn_offset_one_disable_cmd[i];
11355
                    if (disable_cmd == 0xFF) {
11356
                        break;
11357
                    }
11358
                    if (scsi_cmd == disable_cmd) {
11359
                        disable_syn_offset_one_fix = TRUE;
11360
                        break;
11361
                    }
11362
                }
11363
            }
11364
        }
11365
    }
11366
    if (disable_syn_offset_one_fix) {
11367
        scsiq->q2.tag_code &= ~M2_QTAG_MSG_SIMPLE;
11368
        scsiq->q2.tag_code |= (ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX |
11369
                               ASC_TAG_FLAG_DISABLE_DISCONNECT);
11370
    } else {
11371
        scsiq->q2.tag_code &= 0x23;
11372
    }
11373
    if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
11374
        if (asc_dvc->bug_fix_cntl) {
11375
            if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
11376
                if ((scsi_cmd == SCSICMD_Read6) ||
11377
                    (scsi_cmd == SCSICMD_Read10)) {
11378
                    addr = sg_head->sg_list[sg_entry_cnt_minus_one].addr +
11379
                      sg_head->sg_list[sg_entry_cnt_minus_one].bytes;
11380
                    extra_bytes = (uchar) ((ushort) addr & 0x0003);
11381
                    if ((extra_bytes != 0) &&
11382
                        ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES)
11383
                         == 0)) {
11384
                        scsiq->q2.tag_code |= ASC_TAG_FLAG_EXTRA_BYTES;
11385
                        scsiq->q1.extra_bytes = extra_bytes;
11386
                        sg_head->sg_list[sg_entry_cnt_minus_one].bytes -=
11387
                            (ulong) extra_bytes;
11388
                    }
11389
                }
11390
            }
11391
        }
11392
        sg_head->entry_to_copy = sg_head->entry_cnt;
11393
        n_q_required = AscSgListToQueue(sg_entry_cnt);
11394
        if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, n_q_required) >=
11395
            (uint) n_q_required) || ((scsiq->q1.cntl & QC_URGENT) != 0)) {
11396
            if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
11397
                                        n_q_required)) == 1) {
11398
                asc_dvc->in_critical_cnt--;
11399
                if (asc_exe_callback != 0) {
11400
                    (*asc_exe_callback) (asc_dvc, scsiq);
11401
                }
11402
                DvcLeaveCritical(last_int_level);
11403
                return (sta);
11404
            }
11405
        }
11406
    } else {
11407
        if (asc_dvc->bug_fix_cntl) {
11408
            if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
11409
                if ((scsi_cmd == SCSICMD_Read6) ||
11410
                    (scsi_cmd == SCSICMD_Read10)) {
11411
                    addr = scsiq->q1.data_addr + scsiq->q1.data_cnt;
11412
                    extra_bytes = (uchar) ((ushort) addr & 0x0003);
11413
                    if ((extra_bytes != 0) &&
11414
                        ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES)
11415
                          == 0)) {
11416
                        if (((ushort) scsiq->q1.data_cnt & 0x01FF) == 0) {
11417
                            scsiq->q2.tag_code |= ASC_TAG_FLAG_EXTRA_BYTES;
11418
                            scsiq->q1.data_cnt -= (ulong) extra_bytes;
11419
                            scsiq->q1.extra_bytes = extra_bytes;
11420
                        }
11421
                    }
11422
                }
11423
            }
11424
        }
11425
        n_q_required = 1;
11426
        if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, 1) >= 1) ||
11427
            ((scsiq->q1.cntl & QC_URGENT) != 0)) {
11428
            if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
11429
                                        n_q_required)) == 1) {
11430
                asc_dvc->in_critical_cnt--;
11431
                if (asc_exe_callback != 0) {
11432
                    (*asc_exe_callback) (asc_dvc, scsiq);
11433
                }
11434
                DvcLeaveCritical(last_int_level);
11435
                return (sta);
11436
            }
11437
        }
11438
    }
11439
    asc_dvc->in_critical_cnt--;
11440
    DvcLeaveCritical(last_int_level);
11441
    return (sta);
11442
}
11443
 
11444
STATIC int
11445
AscSendScsiQueue(
11446
                    REG ASC_DVC_VAR asc_ptr_type * asc_dvc,
11447
                    REG ASC_SCSI_Q * scsiq,
11448
                    uchar n_q_required
11449
)
11450
{
11451
    PortAddr            iop_base;
11452
    uchar               free_q_head;
11453
    uchar               next_qp;
11454
    uchar               tid_no;
11455
    uchar               target_ix;
11456
    int                 sta;
11457
 
11458
    iop_base = asc_dvc->iop_base;
11459
    target_ix = scsiq->q2.target_ix;
11460
    tid_no = ASC_TIX_TO_TID(target_ix);
11461
    sta = 0;
11462
    free_q_head = (uchar) AscGetVarFreeQHead(iop_base);
11463
    if (n_q_required > 1) {
11464
        if ((next_qp = AscAllocMultipleFreeQueue(iop_base,
11465
                                       free_q_head, (uchar) (n_q_required)))
11466
            != (uchar) ASC_QLINK_END) {
11467
            asc_dvc->last_q_shortage = 0;
11468
            scsiq->sg_head->queue_cnt = n_q_required - 1;
11469
            scsiq->q1.q_no = free_q_head;
11470
            if ((sta = AscPutReadySgListQueue(asc_dvc, scsiq,
11471
                                              free_q_head)) == 1) {
11472
                AscPutVarFreeQHead(iop_base, next_qp);
11473
                asc_dvc->cur_total_qng += (uchar) (n_q_required);
11474
                asc_dvc->cur_dvc_qng[tid_no]++;
11475
            }
11476
            return (sta);
11477
        }
11478
    } else if (n_q_required == 1) {
11479
        if ((next_qp = AscAllocFreeQueue(iop_base,
11480
                                         free_q_head)) != ASC_QLINK_END) {
11481
            scsiq->q1.q_no = free_q_head;
11482
            if ((sta = AscPutReadyQueue(asc_dvc, scsiq,
11483
                                        free_q_head)) == 1) {
11484
                AscPutVarFreeQHead(iop_base, next_qp);
11485
                asc_dvc->cur_total_qng++;
11486
                asc_dvc->cur_dvc_qng[tid_no]++;
11487
            }
11488
            return (sta);
11489
        }
11490
    }
11491
    return (sta);
11492
}
11493
 
11494
STATIC int
11495
AscSgListToQueue(
11496
                    int sg_list
11497
)
11498
{
11499
    int                 n_sg_list_qs;
11500
 
11501
    n_sg_list_qs = ((sg_list - 1) / ASC_SG_LIST_PER_Q);
11502
    if (((sg_list - 1) % ASC_SG_LIST_PER_Q) != 0)
11503
        n_sg_list_qs++;
11504
    return (n_sg_list_qs + 1);
11505
}
11506
 
11507
 
11508
STATIC uint
11509
AscGetNumOfFreeQueue(
11510
                        REG ASC_DVC_VAR asc_ptr_type * asc_dvc,
11511
                        uchar target_ix,
11512
                        uchar n_qs
11513
)
11514
{
11515
    uint                cur_used_qs;
11516
    uint                cur_free_qs;
11517
    ASC_SCSI_BIT_ID_TYPE target_id;
11518
    uchar               tid_no;
11519
 
11520
    target_id = ASC_TIX_TO_TARGET_ID(target_ix);
11521
    tid_no = ASC_TIX_TO_TID(target_ix);
11522
    if ((asc_dvc->unit_not_ready & target_id) ||
11523
        (asc_dvc->queue_full_or_busy & target_id)) {
11524
        return (0);
11525
    }
11526
    if (n_qs == 1) {
11527
        cur_used_qs = (uint) asc_dvc->cur_total_qng +
11528
          (uint) asc_dvc->last_q_shortage +
11529
          (uint) ASC_MIN_FREE_Q;
11530
    } else {
11531
        cur_used_qs = (uint) asc_dvc->cur_total_qng +
11532
          (uint) ASC_MIN_FREE_Q;
11533
    }
11534
    if ((uint) (cur_used_qs + n_qs) <= (uint) asc_dvc->max_total_qng) {
11535
        cur_free_qs = (uint) asc_dvc->max_total_qng - cur_used_qs;
11536
        if (asc_dvc->cur_dvc_qng[tid_no] >=
11537
            asc_dvc->max_dvc_qng[tid_no]) {
11538
            return (0);
11539
        }
11540
        return (cur_free_qs);
11541
    }
11542
    if (n_qs > 1) {
11543
        if ((n_qs > asc_dvc->last_q_shortage) && (n_qs <= (asc_dvc->max_total_qng - ASC_MIN_FREE_Q))) {
11544
            asc_dvc->last_q_shortage = n_qs;
11545
        }
11546
    }
11547
    return (0);
11548
}
11549
 
11550
STATIC int
11551
AscPutReadyQueue(
11552
                    REG ASC_DVC_VAR asc_ptr_type * asc_dvc,
11553
                    REG ASC_SCSI_Q * scsiq,
11554
                    uchar q_no
11555
)
11556
{
11557
    ushort              q_addr;
11558
    uchar               tid_no;
11559
    uchar               sdtr_data;
11560
    uchar               syn_period_ix;
11561
    uchar               syn_offset;
11562
    PortAddr            iop_base;
11563
 
11564
    iop_base = asc_dvc->iop_base;
11565
    if (((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) &&
11566
        ((asc_dvc->sdtr_done & scsiq->q1.target_id) == 0)) {
11567
        tid_no = ASC_TIX_TO_TID(scsiq->q2.target_ix);
11568
        sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
11569
        syn_period_ix = (sdtr_data >> 4) & (asc_dvc->max_sdtr_index - 1);
11570
        syn_offset = sdtr_data & ASC_SYN_MAX_OFFSET;
11571
        AscMsgOutSDTR(asc_dvc,
11572
                      asc_dvc->sdtr_period_tbl[syn_period_ix],
11573
                      syn_offset);
11574
        scsiq->q1.cntl |= QC_MSG_OUT;
11575
    }
11576
    q_addr = ASC_QNO_TO_QADDR(q_no);
11577
    if ((scsiq->q1.target_id & asc_dvc->use_tagged_qng) == 0) {
11578
        scsiq->q2.tag_code &= ~M2_QTAG_MSG_SIMPLE;
11579
    }
11580
    scsiq->q1.status = QS_FREE;
11581
    AscMemWordCopyToLram(iop_base,
11582
                         (ushort) (q_addr + (ushort) ASC_SCSIQ_CDB_BEG),
11583
                         (ushort *) scsiq->cdbptr,
11584
                         (ushort) ((ushort) scsiq->q2.cdb_len >> 1));
11585
    DvcPutScsiQ(iop_base,
11586
                (ushort) (q_addr + (ushort) ASC_SCSIQ_CPY_BEG),
11587
                (ushort *) & scsiq->q1.cntl,
11588
      (ushort) ((((sizeof (ASC_SCSIQ_1) + sizeof (ASC_SCSIQ_2)) / 2) - 1)));
11589
    AscWriteLramWord(iop_base,
11590
                     (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS),
11591
             (ushort) (((ushort) scsiq->q1.q_no << 8) | (ushort) QS_READY));
11592
    return (1);
11593
}
11594
 
11595
STATIC int
11596
AscPutReadySgListQueue(
11597
                          REG ASC_DVC_VAR asc_ptr_type * asc_dvc,
11598
                          REG ASC_SCSI_Q * scsiq,
11599
                          uchar q_no
11600
)
11601
{
11602
    int                 sta;
11603
    int                 i;
11604
    ASC_SG_HEAD *sg_head;
11605
    ASC_SG_LIST_Q       scsi_sg_q;
11606
    ulong               saved_data_addr;
11607
    ulong               saved_data_cnt;
11608
    PortAddr            iop_base;
11609
    ushort              sg_list_dwords;
11610
    ushort              sg_index;
11611
    ushort              sg_entry_cnt;
11612
    ushort              q_addr;
11613
    uchar               next_qp;
11614
 
11615
    iop_base = asc_dvc->iop_base;
11616
    sg_head = scsiq->sg_head;
11617
    saved_data_addr = scsiq->q1.data_addr;
11618
    saved_data_cnt = scsiq->q1.data_cnt;
11619
    scsiq->q1.data_addr = sg_head->sg_list[0].addr;
11620
    scsiq->q1.data_cnt = sg_head->sg_list[0].bytes;
11621
    sg_entry_cnt = sg_head->entry_cnt - 1;
11622
    if (sg_entry_cnt != 0) {
11623
        scsiq->q1.cntl |= QC_SG_HEAD;
11624
        q_addr = ASC_QNO_TO_QADDR(q_no);
11625
        sg_index = 1;
11626
        scsiq->q1.sg_queue_cnt = sg_head->queue_cnt;
11627
        scsi_sg_q.sg_head_qp = q_no;
11628
        scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
11629
        for (i = 0; i < sg_head->queue_cnt; i++) {
11630
            scsi_sg_q.seq_no = i + 1;
11631
            if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
11632
                sg_list_dwords = (uchar) (ASC_SG_LIST_PER_Q * 2);
11633
                sg_entry_cnt -= ASC_SG_LIST_PER_Q;
11634
                if (i == 0) {
11635
                    scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q;
11636
                    scsi_sg_q.sg_cur_list_cnt = ASC_SG_LIST_PER_Q;
11637
                } else {
11638
                    scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q - 1;
11639
                    scsi_sg_q.sg_cur_list_cnt = ASC_SG_LIST_PER_Q - 1;
11640
                }
11641
            } else {
11642
                scsi_sg_q.cntl |= QCSG_SG_XFER_END;
11643
                sg_list_dwords = sg_entry_cnt << 1;
11644
                if (i == 0) {
11645
                    scsi_sg_q.sg_list_cnt = sg_entry_cnt;
11646
                    scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt;
11647
                } else {
11648
                    scsi_sg_q.sg_list_cnt = sg_entry_cnt - 1;
11649
                    scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt - 1;
11650
                }
11651
                sg_entry_cnt = 0;
11652
            }
11653
            next_qp = AscReadLramByte(iop_base,
11654
                                      (ushort) (q_addr + ASC_SCSIQ_B_FWD));
11655
            scsi_sg_q.q_no = next_qp;
11656
            q_addr = ASC_QNO_TO_QADDR(next_qp);
11657
            AscMemWordCopyToLram(iop_base,
11658
                                 (ushort) (q_addr + ASC_SCSIQ_SGHD_CPY_BEG),
11659
                                 (ushort *) & scsi_sg_q,
11660
                                 (ushort) (sizeof (ASC_SG_LIST_Q) >> 1));
11661
            AscMemDWordCopyToLram(iop_base,
11662
                                  (ushort) (q_addr + ASC_SGQ_LIST_BEG),
11663
                              (ulong *) & sg_head->sg_list[sg_index],
11664
                                  (ushort) sg_list_dwords);
11665
            sg_index += ASC_SG_LIST_PER_Q;
11666
        }
11667
    } else {
11668
        scsiq->q1.cntl &= ~QC_SG_HEAD;
11669
    }
11670
    sta = AscPutReadyQueue(asc_dvc, scsiq, q_no);
11671
    scsiq->q1.data_addr = saved_data_addr;
11672
    scsiq->q1.data_cnt = saved_data_cnt;
11673
    return (sta);
11674
}
11675
 
11676
STATIC int
11677
AscAbortSRB(
11678
               REG ASC_DVC_VAR asc_ptr_type * asc_dvc,
11679
               ulong srb_ptr
11680
)
11681
{
11682
    int                 sta;
11683
    ASC_SCSI_BIT_ID_TYPE saved_unit_not_ready;
11684
    PortAddr            iop_base;
11685
 
11686
    iop_base = asc_dvc->iop_base;
11687
    sta = ERR;
11688
    saved_unit_not_ready = asc_dvc->unit_not_ready;
11689
    asc_dvc->unit_not_ready = 0xFF;
11690
    AscWaitISRDone(asc_dvc);
11691
    if (AscStopQueueExe(iop_base) == 1) {
11692
        if (AscRiscHaltedAbortSRB(asc_dvc, srb_ptr) == 1) {
11693
            sta = 1;
11694
            AscCleanUpBusyQueue(iop_base);
11695
            AscStartQueueExe(iop_base);
11696
        } else {
11697
            sta = 0;
11698
            AscStartQueueExe(iop_base);
11699
        }
11700
    }
11701
    asc_dvc->unit_not_ready = saved_unit_not_ready;
11702
    return (sta);
11703
}
11704
 
11705
#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
11706
STATIC int
11707
AscResetDevice(
11708
                  REG ASC_DVC_VAR asc_ptr_type * asc_dvc,
11709
                  uchar target_ix
11710
)
11711
{
11712
    PortAddr            iop_base;
11713
    int                 sta;
11714
    uchar               tid_no;
11715
 
11716
    ASC_SCSI_BIT_ID_TYPE target_id;
11717
    int                 i;
11718
    ASC_SCSI_REQ_Q      scsiq_buf;
11719
    ASC_SCSI_REQ_Q *scsiq;
11720
    uchar       *buf;
11721
    ASC_SCSI_BIT_ID_TYPE saved_unit_not_ready;
11722
    iop_base = asc_dvc->iop_base;
11723
    tid_no = ASC_TIX_TO_TID(target_ix);
11724
    target_id = ASC_TID_TO_TARGET_ID(tid_no);
11725
    saved_unit_not_ready = asc_dvc->unit_not_ready;
11726
    asc_dvc->unit_not_ready = target_id;
11727
    sta = ERR;
11728
    AscWaitTixISRDone(asc_dvc, target_ix);
11729
    if (AscStopQueueExe(iop_base) == 1) {
11730
        if (AscRiscHaltedAbortTIX(asc_dvc, target_ix) == 1) {
11731
            AscCleanUpBusyQueue(iop_base);
11732
            AscStartQueueExe(iop_base);
11733
            AscWaitTixISRDone(asc_dvc, target_ix);
11734
            sta = TRUE;
11735
            scsiq = (ASC_SCSI_REQ_Q *) & scsiq_buf;
11736
            buf = (uchar *) & scsiq_buf;
11737
            for (i = 0; i < sizeof (ASC_SCSI_REQ_Q); i++) {
11738
                *buf++ = 0x00;
11739
            }
11740
            scsiq->r1.status = (uchar) QS_READY;
11741
            scsiq->r2.cdb_len = 6;
11742
            scsiq->r2.tag_code = M2_QTAG_MSG_SIMPLE;
11743
            scsiq->r1.target_id = target_id;
11744
            scsiq->r2.target_ix = ASC_TIDLUN_TO_IX(tid_no, 0);
11745
            scsiq->cdbptr = (uchar *) scsiq->cdb;
11746
            scsiq->r1.cntl = QC_NO_CALLBACK | QC_MSG_OUT | QC_URGENT;
11747
            AscWriteLramByte(asc_dvc->iop_base, ASCV_MSGOUT_BEG,
11748
                             M1_BUS_DVC_RESET);
11749
            asc_dvc->unit_not_ready &= ~target_id;
11750
            asc_dvc->sdtr_done |= target_id;
11751
            if (AscExeScsiQueue(asc_dvc, (ASC_SCSI_Q *) scsiq)
11752
                == 1) {
11753
                asc_dvc->unit_not_ready = target_id;
11754
                DvcSleepMilliSecond(1000);
11755
                _AscWaitQDone(iop_base, (ASC_SCSI_Q *) scsiq);
11756
                if (AscStopQueueExe(iop_base) == 1) {
11757
                    AscCleanUpDiscQueue(iop_base);
11758
                    AscStartQueueExe(iop_base);
11759
                    if (asc_dvc->pci_fix_asyn_xfer & target_id) {
11760
                        AscSetRunChipSynRegAtID(iop_base, tid_no,
11761
                                             ASYN_SDTR_DATA_FIX_PCI_REV_AB);
11762
                    }
11763
                    AscWaitTixISRDone(asc_dvc, target_ix);
11764
                }
11765
            } else {
11766
                sta = 0;
11767
            }
11768
            asc_dvc->sdtr_done &= ~target_id;
11769
        } else {
11770
            sta = ERR;
11771
            AscStartQueueExe(iop_base);
11772
        }
11773
    }
11774
    asc_dvc->unit_not_ready = saved_unit_not_ready;
11775
    return (sta);
11776
}
11777
#endif /* version >= v1.3.89 */
11778
 
11779
STATIC int
11780
AscResetSB(
11781
              REG ASC_DVC_VAR asc_ptr_type * asc_dvc
11782
)
11783
{
11784
    int                 sta;
11785
    int                 i;
11786
    PortAddr            iop_base;
11787
 
11788
    iop_base = asc_dvc->iop_base;
11789
    asc_dvc->unit_not_ready = 0xFF;
11790
    sta = TRUE;
11791
    AscWaitISRDone(asc_dvc);
11792
    AscStopQueueExe(iop_base);
11793
    asc_dvc->sdtr_done = 0;
11794
    AscResetChipAndScsiBus(asc_dvc);
11795
    DvcSleepMilliSecond((ulong) ((ushort) asc_dvc->scsi_reset_wait * 1000));
11796
    AscReInitLram(asc_dvc);
11797
    for (i = 0; i <= ASC_MAX_TID; i++) {
11798
        asc_dvc->cur_dvc_qng[i] = 0;
11799
        if (asc_dvc->pci_fix_asyn_xfer & (ASC_SCSI_BIT_ID_TYPE) (0x01 << i)) {
11800
            AscSetChipSynRegAtID(iop_base, i, ASYN_SDTR_DATA_FIX_PCI_REV_AB);
11801
        }
11802
    }
11803
    asc_dvc->err_code = 0;
11804
    AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
11805
    if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
11806
        sta = ERR;
11807
    }
11808
    if (AscStartChip(iop_base) == 0) {
11809
        sta = ERR;
11810
    }
11811
    AscStartQueueExe(iop_base);
11812
    asc_dvc->unit_not_ready = 0;
11813
    asc_dvc->queue_full_or_busy = 0;
11814
    return (sta);
11815
}
11816
 
11817
STATIC int
11818
AscSetRunChipSynRegAtID(
11819
                           PortAddr iop_base,
11820
                           uchar tid_no,
11821
                           uchar sdtr_data
11822
)
11823
{
11824
    int                 sta = FALSE;
11825
 
11826
    if (AscHostReqRiscHalt(iop_base)) {
11827
        sta = AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
11828
        AscStartChip(iop_base);
11829
        return (sta);
11830
    }
11831
    return (sta);
11832
}
11833
 
11834
STATIC int
11835
AscSetChipSynRegAtID(
11836
                        PortAddr iop_base,
11837
                        uchar id,
11838
                        uchar sdtr_data
11839
)
11840
{
11841
    ASC_SCSI_BIT_ID_TYPE org_id;
11842
    int                 i;
11843
    int                 sta = TRUE;
11844
 
11845
    AscSetBank(iop_base, 1);
11846
    org_id = AscReadChipDvcID(iop_base);
11847
    for (i = 0; i <= ASC_MAX_TID; i++) {
11848
        if (org_id == (0x01 << i))
11849
            break;
11850
    }
11851
    org_id = i;
11852
    AscWriteChipDvcID(iop_base, id);
11853
    if (AscReadChipDvcID(iop_base) == (0x01 << id)) {
11854
        AscSetBank(iop_base, 0);
11855
        AscSetChipSyn(iop_base, sdtr_data);
11856
        if (AscGetChipSyn(iop_base) != sdtr_data) {
11857
            sta = FALSE;
11858
        }
11859
    } else {
11860
        sta = FALSE;
11861
    }
11862
    AscSetBank(iop_base, 1);
11863
    AscWriteChipDvcID(iop_base, org_id);
11864
    AscSetBank(iop_base, 0);
11865
    return (sta);
11866
}
11867
 
11868
STATIC int
11869
AscReInitLram(
11870
                 REG ASC_DVC_VAR asc_ptr_type * asc_dvc
11871
)
11872
{
11873
    AscInitLram(asc_dvc);
11874
    AscInitQLinkVar(asc_dvc);
11875
    return (0);
11876
}
11877
 
11878
STATIC ushort
11879
AscInitLram(
11880
               REG ASC_DVC_VAR asc_ptr_type * asc_dvc
11881
)
11882
{
11883
    uchar               i;
11884
    ushort              s_addr;
11885
    PortAddr            iop_base;
11886
    ushort              warn_code;
11887
 
11888
    iop_base = asc_dvc->iop_base;
11889
    warn_code = 0;
11890
    AscMemWordSetLram(iop_base, ASC_QADR_BEG, 0,
11891
               (ushort) (((int) (asc_dvc->max_total_qng + 2 + 1) * 64) >> 1)
11892
);
11893
    i = ASC_MIN_ACTIVE_QNO;
11894
    s_addr = ASC_QADR_BEG + ASC_QBLK_SIZE;
11895
    AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_FWD),
11896
                     (uchar) (i + 1));
11897
    AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_BWD),
11898
                     (uchar) (asc_dvc->max_total_qng));
11899
    AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_QNO),
11900
                     (uchar) i);
11901
    i++;
11902
    s_addr += ASC_QBLK_SIZE;
11903
    for (; i < asc_dvc->max_total_qng; i++, s_addr += ASC_QBLK_SIZE) {
11904
        AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_FWD),
11905
                         (uchar) (i + 1));
11906
        AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_BWD),
11907
                         (uchar) (i - 1));
11908
        AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_QNO),
11909
                         (uchar) i);
11910
    }
11911
    AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_FWD),
11912
                     (uchar) ASC_QLINK_END);
11913
    AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_BWD),
11914
                     (uchar) (asc_dvc->max_total_qng - 1));
11915
    AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_QNO),
11916
                     (uchar) asc_dvc->max_total_qng);
11917
    i++;
11918
    s_addr += ASC_QBLK_SIZE;
11919
    for (; i <= (uchar) (asc_dvc->max_total_qng + 3);
11920
         i++, s_addr += ASC_QBLK_SIZE) {
11921
        AscWriteLramByte(iop_base,
11922
                         (ushort) (s_addr + (ushort) ASC_SCSIQ_B_FWD), i);
11923
        AscWriteLramByte(iop_base,
11924
                         (ushort) (s_addr + (ushort) ASC_SCSIQ_B_BWD), i);
11925
        AscWriteLramByte(iop_base,
11926
                         (ushort) (s_addr + (ushort) ASC_SCSIQ_B_QNO), i);
11927
    }
11928
    return (warn_code);
11929
}
11930
 
11931
STATIC ushort
11932
AscInitQLinkVar(
11933
                   REG ASC_DVC_VAR asc_ptr_type * asc_dvc
11934
)
11935
{
11936
    PortAddr            iop_base;
11937
    int                 i;
11938
    ushort              lram_addr;
11939
 
11940
    iop_base = asc_dvc->iop_base;
11941
    AscPutRiscVarFreeQHead(iop_base, 1);
11942
    AscPutRiscVarDoneQTail(iop_base, asc_dvc->max_total_qng);
11943
    AscPutVarFreeQHead(iop_base, 1);
11944
    AscPutVarDoneQTail(iop_base, asc_dvc->max_total_qng);
11945
    AscWriteLramByte(iop_base, ASCV_BUSY_QHEAD_B,
11946
                     (uchar) ((int) asc_dvc->max_total_qng + 1));
11947
    AscWriteLramByte(iop_base, ASCV_DISC1_QHEAD_B,
11948
                     (uchar) ((int) asc_dvc->max_total_qng + 2));
11949
    AscWriteLramByte(iop_base, (ushort) ASCV_TOTAL_READY_Q_B,
11950
                     asc_dvc->max_total_qng);
11951
    AscWriteLramWord(iop_base, ASCV_ASCDVC_ERR_CODE_W, 0);
11952
    AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
11953
    AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 0);
11954
    AscWriteLramByte(iop_base, ASCV_SCSIBUSY_B, 0);
11955
    AscWriteLramByte(iop_base, ASCV_WTM_FLAG_B, 0);
11956
    AscPutQDoneInProgress(iop_base, 0);
11957
    lram_addr = ASC_QADR_BEG;
11958
    for (i = 0; i < 32; i++, lram_addr += 2) {
11959
        AscWriteLramWord(iop_base, lram_addr, 0);
11960
    }
11961
    return (0);
11962
}
11963
 
11964
STATIC int
11965
AscSetLibErrorCode(
11966
                      REG ASC_DVC_VAR asc_ptr_type * asc_dvc,
11967
                      ushort err_code
11968
)
11969
{
11970
    if (asc_dvc->err_code == 0) {
11971
        asc_dvc->err_code = err_code;
11972
        AscWriteLramWord(asc_dvc->iop_base, ASCV_ASCDVC_ERR_CODE_W,
11973
                         err_code);
11974
    }
11975
    return (err_code);
11976
}
11977
 
11978
 
11979
#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
11980
STATIC int
11981
_AscWaitQDone(
11982
                 PortAddr iop_base,
11983
                 REG ASC_SCSI_Q * scsiq
11984
)
11985
{
11986
    ushort              q_addr;
11987
    uchar               q_status;
11988
    int                 count = 0;
11989
 
11990
    while (scsiq->q1.q_no == 0) ;
11991
    q_addr = ASC_QNO_TO_QADDR(scsiq->q1.q_no);
11992
    do {
11993
        q_status = AscReadLramByte(iop_base, q_addr + ASC_SCSIQ_B_STATUS);
11994
        DvcSleepMilliSecond(100L);
11995
        if (count++ > 30) {
11996
            return (0);
11997
        }
11998
    } while ((q_status & QS_READY) != 0);
11999
    return (1);
12000
}
12001
#endif /* version >= v1.3.89 */
12002
 
12003
STATIC uchar
12004
AscMsgOutSDTR(
12005
                 REG ASC_DVC_VAR asc_ptr_type * asc_dvc,
12006
                 uchar sdtr_period,
12007
                 uchar sdtr_offset
12008
)
12009
{
12010
    EXT_MSG             sdtr_buf;
12011
    uchar               sdtr_period_index;
12012
    PortAddr            iop_base;
12013
 
12014
    iop_base = asc_dvc->iop_base;
12015
    sdtr_buf.msg_type = MS_EXTEND;
12016
    sdtr_buf.msg_len = MS_SDTR_LEN;
12017
    sdtr_buf.msg_req = MS_SDTR_CODE;
12018
    sdtr_buf.xfer_period = sdtr_period;
12019
    sdtr_offset &= ASC_SYN_MAX_OFFSET;
12020
    sdtr_buf.req_ack_offset = sdtr_offset;
12021
    if ((sdtr_period_index =
12022
         AscGetSynPeriodIndex(asc_dvc, sdtr_period)) <=
12023
        asc_dvc->max_sdtr_index) {
12024
        AscMemWordCopyToLram(iop_base,
12025
                             ASCV_MSGOUT_BEG,
12026
                             (ushort *) & sdtr_buf,
12027
                             (ushort) (sizeof (EXT_MSG) >> 1));
12028
        return ((sdtr_period_index << 4) | sdtr_offset);
12029
    } else {
12030
 
12031
        sdtr_buf.req_ack_offset = 0;
12032
        AscMemWordCopyToLram(iop_base,
12033
                             ASCV_MSGOUT_BEG,
12034
                             (ushort *) & sdtr_buf,
12035
                             (ushort) (sizeof (EXT_MSG) >> 1));
12036
        return (0);
12037
    }
12038
}
12039
 
12040
STATIC uchar
12041
AscCalSDTRData(
12042
                  REG ASC_DVC_VAR asc_ptr_type * asc_dvc,
12043
                  uchar sdtr_period,
12044
                  uchar syn_offset
12045
)
12046
{
12047
    uchar               byte;
12048
    uchar               sdtr_period_ix;
12049
 
12050
    sdtr_period_ix = AscGetSynPeriodIndex(asc_dvc, sdtr_period);
12051
    if (
12052
           (sdtr_period_ix > asc_dvc->max_sdtr_index)
12053
) {
12054
        return (0xFF);
12055
    }
12056
    byte = (sdtr_period_ix << 4) | (syn_offset & ASC_SYN_MAX_OFFSET);
12057
    return (byte);
12058
}
12059
 
12060
STATIC void
12061
AscSetChipSDTR(
12062
                  PortAddr iop_base,
12063
                  uchar sdtr_data,
12064
                  uchar tid_no
12065
)
12066
{
12067
    AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
12068
    AscPutMCodeSDTRDoneAtID(iop_base, tid_no, sdtr_data);
12069
    return;
12070
}
12071
 
12072
STATIC uchar
12073
AscGetSynPeriodIndex(
12074
                        ASC_DVC_VAR asc_ptr_type * asc_dvc,
12075
                        ruchar syn_time
12076
)
12077
{
12078
    ruchar             *period_table;
12079
    int                 max_index;
12080
    int                 min_index;
12081
    int                 i;
12082
 
12083
    period_table = asc_dvc->sdtr_period_tbl;
12084
    max_index = (int) asc_dvc->max_sdtr_index;
12085
    min_index = (int)asc_dvc->host_init_sdtr_index ;
12086
    if ((syn_time <= period_table[max_index])) {
12087
        for (i = min_index; i < (max_index - 1); i++) {
12088
            if (syn_time <= period_table[i]) {
12089
                return ((uchar) i);
12090
            }
12091
        }
12092
        return ((uchar) max_index);
12093
    } else {
12094
        return ((uchar) (max_index + 1));
12095
    }
12096
}
12097
 
12098
STATIC uchar
12099
AscAllocFreeQueue(
12100
                     PortAddr iop_base,
12101
                     uchar free_q_head
12102
)
12103
{
12104
    ushort              q_addr;
12105
    uchar               next_qp;
12106
    uchar               q_status;
12107
 
12108
    q_addr = ASC_QNO_TO_QADDR(free_q_head);
12109
    q_status = (uchar) AscReadLramByte(iop_base,
12110
                                    (ushort) (q_addr + ASC_SCSIQ_B_STATUS));
12111
    next_qp = AscReadLramByte(iop_base,
12112
                              (ushort) (q_addr + ASC_SCSIQ_B_FWD));
12113
    if (((q_status & QS_READY) == 0) && (next_qp != ASC_QLINK_END)) {
12114
        return (next_qp);
12115
    }
12116
    return (ASC_QLINK_END);
12117
}
12118
 
12119
STATIC uchar
12120
AscAllocMultipleFreeQueue(
12121
                             PortAddr iop_base,
12122
                             uchar free_q_head,
12123
                             uchar n_free_q
12124
)
12125
{
12126
    uchar               i;
12127
 
12128
    for (i = 0; i < n_free_q; i++) {
12129
        if ((free_q_head = AscAllocFreeQueue(iop_base, free_q_head))
12130
            == ASC_QLINK_END) {
12131
            return (ASC_QLINK_END);
12132
        }
12133
    }
12134
    return (free_q_head);
12135
}
12136
 
12137
STATIC int
12138
AscRiscHaltedAbortSRB(
12139
                         REG ASC_DVC_VAR asc_ptr_type * asc_dvc,
12140
                         ulong srb_ptr
12141
)
12142
{
12143
    PortAddr            iop_base;
12144
    ushort              q_addr;
12145
    uchar               q_no;
12146
    ASC_QDONE_INFO      scsiq_buf;
12147
    ASC_QDONE_INFO *scsiq;
12148
    ASC_ISR_CALLBACK    asc_isr_callback;
12149
    int                 last_int_level;
12150
 
12151
    iop_base = asc_dvc->iop_base;
12152
    asc_isr_callback = (ASC_ISR_CALLBACK) asc_dvc->isr_callback;
12153
    last_int_level = DvcEnterCritical();
12154
    scsiq = (ASC_QDONE_INFO *) & scsiq_buf;
12155
    for (q_no = ASC_MIN_ACTIVE_QNO; q_no <= asc_dvc->max_total_qng;
12156
         q_no++) {
12157
        q_addr = ASC_QNO_TO_QADDR(q_no);
12158
        scsiq->d2.srb_ptr = AscReadLramDWord(iop_base,
12159
                           (ushort) (q_addr + (ushort) ASC_SCSIQ_D_SRBPTR));
12160
        if (scsiq->d2.srb_ptr == srb_ptr) {
12161
            _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq, asc_dvc->max_dma_count);
12162
            if (((scsiq->q_status & QS_READY) != 0)
12163
                 && ((scsiq->q_status & QS_ABORTED) == 0)
12164
                 && ((scsiq->cntl & QCSG_SG_XFER_LIST) == 0)) {
12165
                scsiq->q_status |= QS_ABORTED;
12166
                scsiq->d3.done_stat = QD_ABORTED_BY_HOST;
12167
                AscWriteLramDWord(iop_base,
12168
                            (ushort) (q_addr + (ushort) ASC_SCSIQ_D_SRBPTR),
12169
                                  0L);
12170
                AscWriteLramByte(iop_base,
12171
                            (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS),
12172
                                 scsiq->q_status);
12173
                (*asc_isr_callback) (asc_dvc, scsiq);
12174
                return (1);
12175
            }
12176
        }
12177
    }
12178
    DvcLeaveCritical(last_int_level);
12179
    return (0);
12180
}
12181
 
12182
#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
12183
STATIC int
12184
AscRiscHaltedAbortTIX(
12185
                         REG ASC_DVC_VAR asc_ptr_type * asc_dvc,
12186
                         uchar target_ix
12187
)
12188
{
12189
    PortAddr            iop_base;
12190
    ushort              q_addr;
12191
    uchar               q_no;
12192
    ASC_QDONE_INFO      scsiq_buf;
12193
    ASC_QDONE_INFO *scsiq;
12194
    ASC_ISR_CALLBACK    asc_isr_callback;
12195
    int                 last_int_level;
12196
 
12197
    iop_base = asc_dvc->iop_base;
12198
    asc_isr_callback = (ASC_ISR_CALLBACK) asc_dvc->isr_callback;
12199
    last_int_level = DvcEnterCritical();
12200
    scsiq = (ASC_QDONE_INFO *) & scsiq_buf;
12201
    for (q_no = ASC_MIN_ACTIVE_QNO; q_no <= asc_dvc->max_total_qng;
12202
         q_no++) {
12203
        q_addr = ASC_QNO_TO_QADDR(q_no);
12204
        _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq, asc_dvc->max_dma_count);
12205
        if (((scsiq->q_status & QS_READY) != 0) &&
12206
            ((scsiq->q_status & QS_ABORTED) == 0) &&
12207
            ((scsiq->cntl & QCSG_SG_XFER_LIST) == 0)) {
12208
            if (scsiq->d2.target_ix == target_ix) {
12209
                scsiq->q_status |= QS_ABORTED;
12210
                scsiq->d3.done_stat = QD_ABORTED_BY_HOST;
12211
                AscWriteLramDWord(iop_base,
12212
                            (ushort) (q_addr + (ushort) ASC_SCSIQ_D_SRBPTR),
12213
                                  0L);
12214
                AscWriteLramByte(iop_base,
12215
                            (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS),
12216
                                 scsiq->q_status);
12217
                (*asc_isr_callback) (asc_dvc, scsiq);
12218
            }
12219
        }
12220
    }
12221
    DvcLeaveCritical(last_int_level);
12222
    return (1);
12223
}
12224
#endif /* version >= v1.3.89 */
12225
 
12226
STATIC int
12227
AscHostReqRiscHalt(
12228
                      PortAddr iop_base
12229
)
12230
{
12231
    int                 count = 0;
12232
    int                 sta = 0;
12233
    uchar               saved_stop_code;
12234
 
12235
    if (AscIsChipHalted(iop_base))
12236
        return (1);
12237
    saved_stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
12238
    AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
12239
                     ASC_STOP_HOST_REQ_RISC_HALT | ASC_STOP_REQ_RISC_STOP
12240
);
12241
    do {
12242
        if (AscIsChipHalted(iop_base)) {
12243
            sta = 1;
12244
            break;
12245
        }
12246
        DvcSleepMilliSecond(100);
12247
    } while (count++ < 20);
12248
    AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, saved_stop_code);
12249
    return (sta);
12250
}
12251
 
12252
STATIC int
12253
AscStopQueueExe(
12254
                   PortAddr iop_base
12255
)
12256
{
12257
    int                 count = 0;
12258
 
12259
    if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) == 0) {
12260
        AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
12261
                         ASC_STOP_REQ_RISC_STOP);
12262
        do {
12263
            if (
12264
                   AscReadLramByte(iop_base, ASCV_STOP_CODE_B) &
12265
                   ASC_STOP_ACK_RISC_STOP) {
12266
                return (1);
12267
            }
12268
            DvcSleepMilliSecond(100);
12269
        } while (count++ < 20);
12270
    }
12271
    return (0);
12272
}
12273
 
12274
STATIC int
12275
AscStartQueueExe(
12276
                    PortAddr iop_base
12277
)
12278
{
12279
    if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) != 0) {
12280
        AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 0);
12281
    }
12282
    return (1);
12283
}
12284
 
12285
STATIC int
12286
AscCleanUpBusyQueue(
12287
                       PortAddr iop_base
12288
)
12289
{
12290
    int                 count;
12291
    uchar               stop_code;
12292
 
12293
    count = 0;
12294
    if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) != 0) {
12295
        AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
12296
                         ASC_STOP_CLEAN_UP_BUSY_Q);
12297
        do {
12298
            stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
12299
            if ((stop_code & ASC_STOP_CLEAN_UP_BUSY_Q) == 0)
12300
                break;
12301
            DvcSleepMilliSecond(100);
12302
        } while (count++ < 20);
12303
    }
12304
    return (1);
12305
}
12306
 
12307
#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
12308
STATIC int
12309
AscCleanUpDiscQueue(
12310
                       PortAddr iop_base
12311
)
12312
{
12313
    int                 count;
12314
    uchar               stop_code;
12315
 
12316
    count = 0;
12317
    if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) != 0) {
12318
        AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
12319
                         ASC_STOP_CLEAN_UP_DISC_Q);
12320
        do {
12321
            stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
12322
            if ((stop_code & ASC_STOP_CLEAN_UP_DISC_Q) == 0)
12323
                break;
12324
            DvcSleepMilliSecond(100);
12325
        } while (count++ < 20);
12326
    }
12327
    return (1);
12328
}
12329
#endif /* version >= v1.3.89 */
12330
 
12331
STATIC int
12332
AscWaitTixISRDone(
12333
                     ASC_DVC_VAR asc_ptr_type * asc_dvc,
12334
                     uchar target_ix
12335
)
12336
{
12337
    uchar               cur_req;
12338
    uchar               tid_no;
12339
    int                 i = 0;
12340
 
12341
    tid_no = ASC_TIX_TO_TID(target_ix);
12342
    while (i++ < 10) {
12343
        if ((cur_req = asc_dvc->cur_dvc_qng[tid_no]) == 0) {
12344
            break;
12345
        }
12346
        DvcSleepMilliSecond(1000L);
12347
        if (asc_dvc->cur_dvc_qng[tid_no] == cur_req) {
12348
            break;
12349
        }
12350
    }
12351
    return (1);
12352
}
12353
 
12354
STATIC int
12355
AscWaitISRDone(
12356
                  REG ASC_DVC_VAR asc_ptr_type * asc_dvc
12357
)
12358
{
12359
    int                 tid;
12360
 
12361
    for (tid = 0; tid <= ASC_MAX_TID; tid++) {
12362
        AscWaitTixISRDone(asc_dvc, ASC_TID_TO_TIX(tid));
12363
    }
12364
    return (1);
12365
}
12366
 
12367
STATIC ulong
12368
AscGetOnePhyAddr(
12369
                    REG ASC_DVC_VAR asc_ptr_type * asc_dvc,
12370
                    uchar * buf_addr,
12371
                    ulong buf_size
12372
)
12373
{
12374
    ASC_MIN_SG_HEAD     sg_head;
12375
 
12376
    sg_head.entry_cnt = ASC_MIN_SG_LIST;
12377
    if (DvcGetSGList(asc_dvc, (uchar *) buf_addr,
12378
                  buf_size, (ASC_SG_HEAD *) & sg_head) != buf_size) {
12379
        return (0L);
12380
    }
12381
    if (sg_head.entry_cnt > 1) {
12382
        return (0L);
12383
    }
12384
    return (sg_head.sg_list[0].addr);
12385
}
12386
 
12387
STATIC void
12388
DvcDelayMicroSecond(ADV_DVC_VAR *asc_dvc, ushort micro_sec)
12389
{
12390
    udelay(micro_sec);
12391
}
12392
 
12393
STATIC void
12394
DvcDelayNanoSecond(ASC_DVC_VAR asc_ptr_type * asc_dvc, ulong nano_sec)
12395
{
12396
    udelay((nano_sec + 999)/1000);
12397
}
12398
 
12399
ASC_INITFUNC(
12400
STATIC ulong
12401
AscGetEisaProductID(
12402
                       PortAddr iop_base
12403
)
12404
)
12405
{
12406
    PortAddr            eisa_iop;
12407
    ushort              product_id_high, product_id_low;
12408
    ulong               product_id;
12409
 
12410
    eisa_iop = ASC_GET_EISA_SLOT(iop_base) | ASC_EISA_PID_IOP_MASK;
12411
    product_id_low = inpw(eisa_iop);
12412
    product_id_high = inpw(eisa_iop + 2);
12413
    product_id = ((ulong) product_id_high << 16) | (ulong) product_id_low;
12414
    return (product_id);
12415
}
12416
 
12417
ASC_INITFUNC(
12418
STATIC PortAddr
12419
AscSearchIOPortAddrEISA(
12420
                           PortAddr iop_base
12421
)
12422
)
12423
{
12424
    ulong               eisa_product_id;
12425
 
12426
    if (iop_base == 0) {
12427
        iop_base = ASC_EISA_MIN_IOP_ADDR;
12428
    } else {
12429
        if (iop_base == ASC_EISA_MAX_IOP_ADDR)
12430
            return (0);
12431
        if ((iop_base & 0x0050) == 0x0050) {
12432
            iop_base += ASC_EISA_BIG_IOP_GAP;
12433
        } else {
12434
            iop_base += ASC_EISA_SMALL_IOP_GAP;
12435
        }
12436
    }
12437
    while (iop_base <= ASC_EISA_MAX_IOP_ADDR) {
12438
        eisa_product_id = AscGetEisaProductID(iop_base);
12439
        if ((eisa_product_id == ASC_EISA_ID_740) ||
12440
            (eisa_product_id == ASC_EISA_ID_750)) {
12441
            if (AscFindSignature(iop_base)) {
12442
                inpw(iop_base + 4);
12443
                return (iop_base);
12444
            }
12445
        }
12446
        if (iop_base == ASC_EISA_MAX_IOP_ADDR)
12447
            return (0);
12448
        if ((iop_base & 0x0050) == 0x0050) {
12449
            iop_base += ASC_EISA_BIG_IOP_GAP;
12450
        } else {
12451
            iop_base += ASC_EISA_SMALL_IOP_GAP;
12452
        }
12453
    }
12454
    return (0);
12455
}
12456
 
12457
STATIC int
12458
AscStartChip(
12459
                PortAddr iop_base
12460
)
12461
{
12462
    AscSetChipControl(iop_base, 0);
12463
    if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
12464
        return (0);
12465
    }
12466
    return (1);
12467
}
12468
 
12469
STATIC int
12470
AscStopChip(
12471
               PortAddr iop_base
12472
)
12473
{
12474
    uchar               cc_val;
12475
 
12476
    cc_val = AscGetChipControl(iop_base) & (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG));
12477
    AscSetChipControl(iop_base, (uchar) (cc_val | CC_HALT));
12478
    AscSetChipIH(iop_base, INS_HALT);
12479
    AscSetChipIH(iop_base, INS_RFLAG_WTM);
12480
    if ((AscGetChipStatus(iop_base) & CSW_HALTED) == 0) {
12481
        return (0);
12482
    }
12483
    return (1);
12484
}
12485
 
12486
STATIC int
12487
AscIsChipHalted(
12488
                   PortAddr iop_base
12489
)
12490
{
12491
    if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
12492
        if ((AscGetChipControl(iop_base) & CC_HALT) != 0) {
12493
            return (1);
12494
        }
12495
    }
12496
    return (0);
12497
}
12498
 
12499
STATIC void
12500
AscSetChipIH(
12501
                PortAddr iop_base,
12502
                ushort ins_code
12503
)
12504
{
12505
    AscSetBank(iop_base, 1);
12506
    AscWriteChipIH(iop_base, ins_code);
12507
    AscSetBank(iop_base, 0);
12508
    return;
12509
}
12510
 
12511
STATIC void
12512
AscAckInterrupt(
12513
                   PortAddr iop_base
12514
)
12515
{
12516
    uchar               host_flag;
12517
    uchar               risc_flag;
12518
    ushort              loop;
12519
 
12520
    loop = 0;
12521
    do {
12522
        risc_flag = AscReadLramByte(iop_base, ASCV_RISC_FLAG_B);
12523
        if (loop++ > 0x7FFF) {
12524
            break;
12525
        }
12526
    } while ((risc_flag & ASC_RISC_FLAG_GEN_INT) != 0);
12527
    host_flag = AscReadLramByte(iop_base, ASCV_HOST_FLAG_B) & (~ASC_HOST_FLAG_ACK_INT);
12528
    AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
12529
                     (uchar) (host_flag | ASC_HOST_FLAG_ACK_INT));
12530
    AscSetChipStatus(iop_base, CIW_INT_ACK);
12531
    loop = 0;
12532
    while (AscGetChipStatus(iop_base) & CSW_INT_PENDING) {
12533
        AscSetChipStatus(iop_base, CIW_INT_ACK);
12534
        if (loop++ > 3) {
12535
            break;
12536
        }
12537
    }
12538
    AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
12539
    return;
12540
}
12541
 
12542
STATIC void
12543
AscDisableInterrupt(
12544
                       PortAddr iop_base
12545
)
12546
{
12547
    ushort              cfg;
12548
 
12549
    cfg = AscGetChipCfgLsw(iop_base);
12550
    AscSetChipCfgLsw(iop_base, cfg & (~ASC_CFG0_HOST_INT_ON));
12551
    return;
12552
}
12553
 
12554
STATIC void
12555
AscEnableInterrupt(
12556
                      PortAddr iop_base
12557
)
12558
{
12559
    ushort              cfg;
12560
 
12561
    cfg = AscGetChipCfgLsw(iop_base);
12562
    AscSetChipCfgLsw(iop_base, cfg | ASC_CFG0_HOST_INT_ON);
12563
    return;
12564
}
12565
 
12566
 
12567
 
12568
STATIC void
12569
AscSetBank(
12570
              PortAddr iop_base,
12571
              uchar bank
12572
)
12573
{
12574
    uchar               val;
12575
 
12576
    val = AscGetChipControl(iop_base) &
12577
      (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG | CC_SCSI_RESET | CC_CHIP_RESET));
12578
    if (bank == 1) {
12579
        val |= CC_BANK_ONE;
12580
    } else if (bank == 2) {
12581
        val |= CC_DIAG | CC_BANK_ONE;
12582
    } else {
12583
        val &= ~CC_BANK_ONE;
12584
    }
12585
    AscSetChipControl(iop_base, val);
12586
    return;
12587
}
12588
 
12589
STATIC int
12590
AscResetChipAndScsiBus(
12591
                          ASC_DVC_VAR *asc_dvc
12592
)
12593
{
12594
    PortAddr    iop_base;
12595
 
12596
    iop_base = asc_dvc->iop_base;
12597
    while (AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE) ;
12598
    AscStopChip(iop_base);
12599
    AscSetChipControl(iop_base, CC_CHIP_RESET | CC_SCSI_RESET | CC_HALT);
12600
    DvcDelayNanoSecond(asc_dvc, 60000);
12601
    AscSetChipIH(iop_base, INS_RFLAG_WTM);
12602
    AscSetChipIH(iop_base, INS_HALT);
12603
    AscSetChipControl(iop_base, CC_CHIP_RESET | CC_HALT);
12604
    AscSetChipControl(iop_base, CC_HALT);
12605
    DvcSleepMilliSecond(200);
12606
    AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
12607
    AscSetChipStatus(iop_base, 0);
12608
    return (AscIsChipHalted(iop_base));
12609
}
12610
 
12611
ASC_INITFUNC(
12612
STATIC ulong
12613
AscGetMaxDmaCount(
12614
                     ushort bus_type
12615
)
12616
)
12617
{
12618
    if (bus_type & ASC_IS_ISA)
12619
        return (ASC_MAX_ISA_DMA_COUNT);
12620
    else if (bus_type & (ASC_IS_EISA | ASC_IS_VL))
12621
        return (ASC_MAX_VL_DMA_COUNT);
12622
    return (ASC_MAX_PCI_DMA_COUNT);
12623
}
12624
 
12625
ASC_INITFUNC(
12626
STATIC ushort
12627
AscGetIsaDmaChannel(
12628
                       PortAddr iop_base
12629
)
12630
)
12631
{
12632
    ushort              channel;
12633
 
12634
    channel = AscGetChipCfgLsw(iop_base) & 0x0003;
12635
    if (channel == 0x03)
12636
        return (0);
12637
    else if (channel == 0x00)
12638
        return (7);
12639
    return (channel + 4);
12640
}
12641
 
12642
ASC_INITFUNC(
12643
STATIC ushort
12644
AscSetIsaDmaChannel(
12645
                       PortAddr iop_base,
12646
                       ushort dma_channel
12647
)
12648
)
12649
{
12650
    ushort              cfg_lsw;
12651
    uchar               value;
12652
 
12653
    if ((dma_channel >= 5) && (dma_channel <= 7)) {
12654
        if (dma_channel == 7)
12655
            value = 0x00;
12656
        else
12657
            value = dma_channel - 4;
12658
        cfg_lsw = AscGetChipCfgLsw(iop_base) & 0xFFFC;
12659
        cfg_lsw |= value;
12660
        AscSetChipCfgLsw(iop_base, cfg_lsw);
12661
        return (AscGetIsaDmaChannel(iop_base));
12662
    }
12663
    return (0);
12664
}
12665
 
12666
ASC_INITFUNC(
12667
STATIC uchar
12668
AscSetIsaDmaSpeed(
12669
                     PortAddr iop_base,
12670
                     uchar speed_value
12671
)
12672
)
12673
{
12674
    speed_value &= 0x07;
12675
    AscSetBank(iop_base, 1);
12676
    AscWriteChipDmaSpeed(iop_base, speed_value);
12677
    AscSetBank(iop_base, 0);
12678
    return (AscGetIsaDmaSpeed(iop_base));
12679
}
12680
 
12681
ASC_INITFUNC(
12682
STATIC uchar
12683
AscGetIsaDmaSpeed(
12684
                     PortAddr iop_base
12685
)
12686
)
12687
{
12688
    uchar               speed_value;
12689
 
12690
    AscSetBank(iop_base, 1);
12691
    speed_value = AscReadChipDmaSpeed(iop_base);
12692
    speed_value &= 0x07;
12693
    AscSetBank(iop_base, 0);
12694
    return (speed_value);
12695
}
12696
 
12697
ASC_INITFUNC(
12698
STATIC ushort
12699
AscReadPCIConfigWord(
12700
    ASC_DVC_VAR asc_ptr_type *asc_dvc,
12701
    ushort pci_config_offset)
12702
)
12703
{
12704
    uchar       lsb, msb;
12705
 
12706
    lsb = DvcReadPCIConfigByte(asc_dvc, pci_config_offset);
12707
    msb = DvcReadPCIConfigByte(asc_dvc, pci_config_offset + 1);
12708
    return ((ushort) ((msb << 8) | lsb));
12709
}
12710
 
12711
ASC_INITFUNC(
12712
STATIC ushort
12713
AscInitGetConfig(
12714
        ASC_DVC_VAR asc_ptr_type * asc_dvc
12715
)
12716
)
12717
{
12718
    ushort              warn_code;
12719
    PortAddr            iop_base;
12720
    ushort              PCIDeviceID;
12721
    ushort              PCIVendorID;
12722
    uchar               PCIRevisionID;
12723
    uchar               prevCmdRegBits;
12724
 
12725
    warn_code = 0;
12726
    iop_base = asc_dvc->iop_base;
12727
    asc_dvc->init_state = ASC_INIT_STATE_BEG_GET_CFG;
12728
    if (asc_dvc->err_code != 0) {
12729
        return (UW_ERR);
12730
    }
12731
    if (asc_dvc->bus_type == ASC_IS_PCI) {
12732
        PCIVendorID = AscReadPCIConfigWord(asc_dvc,
12733
                                    AscPCIConfigVendorIDRegister);
12734
 
12735
        PCIDeviceID = AscReadPCIConfigWord(asc_dvc,
12736
                                    AscPCIConfigDeviceIDRegister);
12737
 
12738
        PCIRevisionID = DvcReadPCIConfigByte(asc_dvc,
12739
                                    AscPCIConfigRevisionIDRegister);
12740
 
12741
        if (PCIVendorID != ASC_PCI_VENDORID) {
12742
            warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
12743
        }
12744
        prevCmdRegBits = DvcReadPCIConfigByte(asc_dvc,
12745
                                    AscPCIConfigCommandRegister);
12746
 
12747
        if ((prevCmdRegBits & AscPCICmdRegBits_IOMemBusMaster) !=
12748
            AscPCICmdRegBits_IOMemBusMaster) {
12749
            DvcWritePCIConfigByte(asc_dvc,
12750
                            AscPCIConfigCommandRegister,
12751
                            (prevCmdRegBits |
12752
                             AscPCICmdRegBits_IOMemBusMaster));
12753
 
12754
            if ((DvcReadPCIConfigByte(asc_dvc,
12755
                                AscPCIConfigCommandRegister)
12756
                 & AscPCICmdRegBits_IOMemBusMaster)
12757
                != AscPCICmdRegBits_IOMemBusMaster) {
12758
                warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
12759
            }
12760
        }
12761
        if ((PCIDeviceID == ASC_PCI_DEVICEID_1200A) ||
12762
            (PCIDeviceID == ASC_PCI_DEVICEID_1200B)) {
12763
            DvcWritePCIConfigByte(asc_dvc,
12764
                            AscPCIConfigLatencyTimer, 0x00);
12765
            if (DvcReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer)
12766
                != 0x00) {
12767
                warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
12768
            }
12769
        } else if (PCIDeviceID == ASC_PCI_DEVICEID_ULTRA) {
12770
            if (DvcReadPCIConfigByte(asc_dvc,
12771
                                AscPCIConfigLatencyTimer) < 0x20) {
12772
                DvcWritePCIConfigByte(asc_dvc,
12773
                                    AscPCIConfigLatencyTimer, 0x20);
12774
 
12775
                if (DvcReadPCIConfigByte(asc_dvc,
12776
                                    AscPCIConfigLatencyTimer) < 0x20) {
12777
                    warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
12778
                }
12779
            }
12780
        }
12781
    }
12782
 
12783
    if (AscFindSignature(iop_base)) {
12784
        warn_code |= AscInitAscDvcVar(asc_dvc);
12785
        warn_code |= AscInitFromEEP(asc_dvc);
12786
        asc_dvc->init_state |= ASC_INIT_STATE_END_GET_CFG;
12787
        if (asc_dvc->scsi_reset_wait > ASC_MAX_SCSI_RESET_WAIT) {
12788
            asc_dvc->scsi_reset_wait = ASC_MAX_SCSI_RESET_WAIT;
12789
        }
12790
    } else {
12791
        asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
12792
    }
12793
    return(warn_code);
12794
}
12795
 
12796
ASC_INITFUNC(
12797
STATIC ushort
12798
AscInitSetConfig(
12799
                    ASC_DVC_VAR asc_ptr_type * asc_dvc
12800
)
12801
)
12802
{
12803
    ushort              warn_code = 0;
12804
 
12805
    asc_dvc->init_state |= ASC_INIT_STATE_BEG_SET_CFG;
12806
    if (asc_dvc->err_code != 0)
12807
        return (UW_ERR);
12808
    if (AscFindSignature(asc_dvc->iop_base)) {
12809
        warn_code |= AscInitFromAscDvcVar(asc_dvc);
12810
        asc_dvc->init_state |= ASC_INIT_STATE_END_SET_CFG;
12811
    } else {
12812
        asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
12813
    }
12814
    return (warn_code);
12815
}
12816
 
12817
ASC_INITFUNC(
12818
STATIC ushort
12819
AscInitFromAscDvcVar(
12820
                        ASC_DVC_VAR asc_ptr_type * asc_dvc
12821
)
12822
)
12823
{
12824
    PortAddr            iop_base;
12825
    ushort              cfg_msw;
12826
    ushort              warn_code;
12827
    ushort              pci_device_id;
12828
 
12829
    iop_base = asc_dvc->iop_base;
12830
    pci_device_id = asc_dvc->cfg->pci_device_id;
12831
    warn_code = 0;
12832
    cfg_msw = AscGetChipCfgMsw(iop_base);
12833
    if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
12834
        cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
12835
        warn_code |= ASC_WARN_CFG_MSW_RECOVER;
12836
        AscSetChipCfgMsw(iop_base, cfg_msw);
12837
    }
12838
    if ((asc_dvc->cfg->cmd_qng_enabled & asc_dvc->cfg->disc_enable) !=
12839
        asc_dvc->cfg->cmd_qng_enabled) {
12840
        asc_dvc->cfg->disc_enable = asc_dvc->cfg->cmd_qng_enabled;
12841
        warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
12842
    }
12843
    if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
12844
        warn_code |= ASC_WARN_AUTO_CONFIG;
12845
    }
12846
    if ((asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL)) != 0) {
12847
        if (AscSetChipIRQ(iop_base, asc_dvc->irq_no, asc_dvc->bus_type)
12848
            != asc_dvc->irq_no) {
12849
            asc_dvc->err_code |= ASC_IERR_SET_IRQ_NO;
12850
        }
12851
    }
12852
    if (asc_dvc->bus_type & ASC_IS_PCI) {
12853
        cfg_msw &= 0xFFC0;
12854
        AscSetChipCfgMsw(iop_base, cfg_msw);
12855
        if ((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) {
12856
        } else {
12857
            if ((pci_device_id == ASC_PCI_DEVICE_ID_REV_A) ||
12858
                (pci_device_id == ASC_PCI_DEVICE_ID_REV_B)) {
12859
                asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_IF_NOT_DWB;
12860
                asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN;
12861
            }
12862
        }
12863
    } else if (asc_dvc->bus_type == ASC_IS_ISAPNP) {
12864
        if (AscGetChipVersion(iop_base, asc_dvc->bus_type)
12865
            == ASC_CHIP_VER_ASYN_BUG) {
12866
            asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN;
12867
        }
12868
    }
12869
    if (AscSetChipScsiID(iop_base, asc_dvc->cfg->chip_scsi_id) !=
12870
        asc_dvc->cfg->chip_scsi_id) {
12871
        asc_dvc->err_code |= ASC_IERR_SET_SCSI_ID;
12872
    }
12873
    if (asc_dvc->bus_type & ASC_IS_ISA) {
12874
        AscSetIsaDmaChannel(iop_base, asc_dvc->cfg->isa_dma_channel);
12875
        AscSetIsaDmaSpeed(iop_base, asc_dvc->cfg->isa_dma_speed);
12876
    }
12877
    return (warn_code);
12878
}
12879
 
12880
ASC_INITFUNC(
12881
STATIC ushort
12882
AscInitAsc1000Driver(
12883
                        ASC_DVC_VAR asc_ptr_type * asc_dvc
12884
)
12885
)
12886
{
12887
    ushort              warn_code;
12888
    PortAddr            iop_base;
12889
    extern ushort       _asc_mcode_size;
12890
    extern ulong        _asc_mcode_chksum;
12891
    extern uchar        _asc_mcode_buf[];
12892
 
12893
    iop_base = asc_dvc->iop_base;
12894
    warn_code = 0;
12895
    if ((asc_dvc->dvc_cntl & ASC_CNTL_RESET_SCSI) &&
12896
        !(asc_dvc->init_state & ASC_INIT_RESET_SCSI_DONE)) {
12897
        AscResetChipAndScsiBus(asc_dvc);
12898
        DvcSleepMilliSecond((ulong) ((ushort) asc_dvc->scsi_reset_wait * 1000));
12899
    }
12900
    asc_dvc->init_state |= ASC_INIT_STATE_BEG_LOAD_MC;
12901
    if (asc_dvc->err_code != 0)
12902
        return (UW_ERR);
12903
    if (!AscFindSignature(asc_dvc->iop_base)) {
12904
        asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
12905
        return (warn_code);
12906
    }
12907
    AscDisableInterrupt(iop_base);
12908
    warn_code |= AscInitLram(asc_dvc);
12909
    if (asc_dvc->err_code != 0)
12910
        return (UW_ERR);
12911
    if (AscLoadMicroCode(iop_base, 0, (ushort *) _asc_mcode_buf,
12912
                         _asc_mcode_size) != _asc_mcode_chksum) {
12913
        asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
12914
        return (warn_code);
12915
    }
12916
    warn_code |= AscInitMicroCodeVar(asc_dvc);
12917
    asc_dvc->init_state |= ASC_INIT_STATE_END_LOAD_MC;
12918
    AscEnableInterrupt(iop_base);
12919
    return (warn_code);
12920
}
12921
 
12922
ASC_INITFUNC(
12923
STATIC ushort
12924
AscInitAscDvcVar(
12925
                    ASC_DVC_VAR asc_ptr_type * asc_dvc
12926
)
12927
)
12928
{
12929
    int                 i;
12930
    PortAddr            iop_base;
12931
    ushort              warn_code;
12932
    uchar               chip_version;
12933
 
12934
    iop_base = asc_dvc->iop_base;
12935
    warn_code = 0;
12936
    asc_dvc->err_code = 0;
12937
    if ((asc_dvc->bus_type &
12938
         (ASC_IS_ISA | ASC_IS_PCI | ASC_IS_EISA | ASC_IS_VL)) == 0) {
12939
        asc_dvc->err_code |= ASC_IERR_NO_BUS_TYPE;
12940
    }
12941
    AscSetChipControl(iop_base, CC_HALT);
12942
    AscSetChipStatus(iop_base, 0);
12943
    asc_dvc->bug_fix_cntl = 0;
12944
    asc_dvc->pci_fix_asyn_xfer = 0;
12945
    asc_dvc->pci_fix_asyn_xfer_always = 0;
12946
    asc_dvc->init_state = 0;
12947
    asc_dvc->sdtr_done = 0;
12948
    asc_dvc->cur_total_qng = 0;
12949
    asc_dvc->is_in_int = 0;
12950
    asc_dvc->in_critical_cnt = 0;
12951
    asc_dvc->last_q_shortage = 0;
12952
    asc_dvc->use_tagged_qng = 0;
12953
    asc_dvc->no_scam = 0;
12954
    asc_dvc->unit_not_ready = 0;
12955
    asc_dvc->queue_full_or_busy = 0;
12956
    asc_dvc->redo_scam = 0 ;
12957
    asc_dvc->res2 = 0 ;
12958
    asc_dvc->host_init_sdtr_index = 0 ;
12959
    asc_dvc->res7 = 0 ;
12960
    asc_dvc->res8 = 0 ;
12961
    asc_dvc->cfg->can_tagged_qng = 0 ;
12962
    asc_dvc->cfg->cmd_qng_enabled = 0;
12963
    asc_dvc->dvc_cntl = ASC_DEF_DVC_CNTL;
12964
    asc_dvc->init_sdtr = 0;
12965
    asc_dvc->max_total_qng = ASC_DEF_MAX_TOTAL_QNG;
12966
    asc_dvc->scsi_reset_wait = 3;
12967
    asc_dvc->start_motor = ASC_SCSI_WIDTH_BIT_SET;
12968
    asc_dvc->max_dma_count = AscGetMaxDmaCount(asc_dvc->bus_type);
12969
    asc_dvc->cfg->sdtr_enable = ASC_SCSI_WIDTH_BIT_SET;
12970
    asc_dvc->cfg->disc_enable = ASC_SCSI_WIDTH_BIT_SET;
12971
    asc_dvc->cfg->chip_scsi_id = ASC_DEF_CHIP_SCSI_ID;
12972
    asc_dvc->cfg->lib_serial_no = ASC_LIB_SERIAL_NUMBER;
12973
    asc_dvc->cfg->lib_version = (ASC_LIB_VERSION_MAJOR << 8) |
12974
      ASC_LIB_VERSION_MINOR;
12975
    chip_version = AscGetChipVersion(iop_base, asc_dvc->bus_type);
12976
    asc_dvc->cfg->chip_version = chip_version;
12977
    asc_dvc->sdtr_period_tbl[0] = SYN_XFER_NS_0;
12978
    asc_dvc->sdtr_period_tbl[1] = SYN_XFER_NS_1;
12979
    asc_dvc->sdtr_period_tbl[2] = SYN_XFER_NS_2;
12980
    asc_dvc->sdtr_period_tbl[3] = SYN_XFER_NS_3;
12981
    asc_dvc->sdtr_period_tbl[4] = SYN_XFER_NS_4;
12982
    asc_dvc->sdtr_period_tbl[5] = SYN_XFER_NS_5;
12983
    asc_dvc->sdtr_period_tbl[6] = SYN_XFER_NS_6;
12984
    asc_dvc->sdtr_period_tbl[7] = SYN_XFER_NS_7;
12985
    asc_dvc->max_sdtr_index = 7;
12986
    if ((asc_dvc->bus_type & ASC_IS_PCI) &&
12987
        (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3150)) {
12988
        asc_dvc->bus_type = ASC_IS_PCI_ULTRA;
12989
        asc_dvc->sdtr_period_tbl[0] = SYN_ULTRA_XFER_NS_0;
12990
        asc_dvc->sdtr_period_tbl[1] = SYN_ULTRA_XFER_NS_1;
12991
        asc_dvc->sdtr_period_tbl[2] = SYN_ULTRA_XFER_NS_2;
12992
        asc_dvc->sdtr_period_tbl[3] = SYN_ULTRA_XFER_NS_3;
12993
        asc_dvc->sdtr_period_tbl[4] = SYN_ULTRA_XFER_NS_4;
12994
        asc_dvc->sdtr_period_tbl[5] = SYN_ULTRA_XFER_NS_5;
12995
        asc_dvc->sdtr_period_tbl[6] = SYN_ULTRA_XFER_NS_6;
12996
        asc_dvc->sdtr_period_tbl[7] = SYN_ULTRA_XFER_NS_7;
12997
        asc_dvc->sdtr_period_tbl[8] = SYN_ULTRA_XFER_NS_8;
12998
        asc_dvc->sdtr_period_tbl[9] = SYN_ULTRA_XFER_NS_9;
12999
        asc_dvc->sdtr_period_tbl[10] = SYN_ULTRA_XFER_NS_10;
13000
        asc_dvc->sdtr_period_tbl[11] = SYN_ULTRA_XFER_NS_11;
13001
        asc_dvc->sdtr_period_tbl[12] = SYN_ULTRA_XFER_NS_12;
13002
        asc_dvc->sdtr_period_tbl[13] = SYN_ULTRA_XFER_NS_13;
13003
        asc_dvc->sdtr_period_tbl[14] = SYN_ULTRA_XFER_NS_14;
13004
        asc_dvc->sdtr_period_tbl[15] = SYN_ULTRA_XFER_NS_15;
13005
        asc_dvc->max_sdtr_index = 15;
13006
        if (chip_version == ASC_CHIP_VER_PCI_ULTRA_3150)
13007
        {
13008
            AscSetExtraControl(iop_base,
13009
                (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
13010
        } else if (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3050) {
13011
            AscSetExtraControl(iop_base,
13012
                (SEC_ACTIVE_NEGATE | SEC_ENABLE_FILTER));
13013
        }
13014
    }
13015
    if (asc_dvc->bus_type == ASC_IS_PCI) {
13016
           AscSetExtraControl(iop_base, (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
13017
    }
13018
 
13019
    asc_dvc->cfg->isa_dma_speed = ASC_DEF_ISA_DMA_SPEED;
13020
    if (AscGetChipBusType(iop_base) == ASC_IS_ISAPNP) {
13021
        AscSetChipIFC(iop_base, IFC_INIT_DEFAULT);
13022
        asc_dvc->bus_type = ASC_IS_ISAPNP;
13023
    }
13024
    if ((asc_dvc->bus_type & ASC_IS_ISA) != 0) {
13025
        asc_dvc->cfg->isa_dma_channel = (uchar) AscGetIsaDmaChannel(iop_base);
13026
    }
13027
    for (i = 0; i <= ASC_MAX_TID; i++) {
13028
        asc_dvc->cur_dvc_qng[i] = 0;
13029
        asc_dvc->max_dvc_qng[i] = ASC_MAX_SCSI1_QNG;
13030
        asc_dvc->scsiq_busy_head[i] = (ASC_SCSI_Q *) 0L;
13031
        asc_dvc->scsiq_busy_tail[i] = (ASC_SCSI_Q *) 0L;
13032
        asc_dvc->cfg->max_tag_qng[i] = ASC_MAX_INRAM_TAG_QNG;
13033
    }
13034
    return (warn_code);
13035
}
13036
 
13037
ASC_INITFUNC(
13038
STATIC ushort
13039
AscInitFromEEP(
13040
                  ASC_DVC_VAR asc_ptr_type * asc_dvc
13041
)
13042
)
13043
{
13044
    ASCEEP_CONFIG       eep_config_buf;
13045
    ASCEEP_CONFIG       *eep_config;
13046
    PortAddr            iop_base;
13047
    ushort              chksum;
13048
    ushort              warn_code;
13049
    ushort              cfg_msw, cfg_lsw;
13050
    int                 i;
13051
    int                 write_eep = 0;
13052
 
13053
    iop_base = asc_dvc->iop_base;
13054
    warn_code = 0;
13055
    AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0x00FE);
13056
    AscStopQueueExe(iop_base);
13057
    if ((AscStopChip(iop_base) == FALSE) ||
13058
        (AscGetChipScsiCtrl(iop_base) != 0)) {
13059
        asc_dvc->init_state |= ASC_INIT_RESET_SCSI_DONE;
13060
        AscResetChipAndScsiBus(asc_dvc);
13061
        DvcSleepMilliSecond((ulong) ((ushort) asc_dvc->scsi_reset_wait * 1000));
13062
    }
13063
    if (AscIsChipHalted(iop_base) == FALSE) {
13064
        asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
13065
        return (warn_code);
13066
    }
13067
    AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
13068
    if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
13069
        asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
13070
        return (warn_code);
13071
    }
13072
    eep_config = (ASCEEP_CONFIG *) & eep_config_buf;
13073
    cfg_msw = AscGetChipCfgMsw(iop_base);
13074
    cfg_lsw = AscGetChipCfgLsw(iop_base);
13075
    if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
13076
        cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
13077
        warn_code |= ASC_WARN_CFG_MSW_RECOVER;
13078
        AscSetChipCfgMsw(iop_base, cfg_msw);
13079
    }
13080
    chksum = AscGetEEPConfig(iop_base, eep_config, asc_dvc->bus_type);
13081
    if (chksum == 0) {
13082
        chksum = 0xaa55;
13083
    }
13084
    if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
13085
        warn_code |= ASC_WARN_AUTO_CONFIG;
13086
        if (asc_dvc->cfg->chip_version == 3) {
13087
            if (eep_config->cfg_lsw != cfg_lsw) {
13088
                warn_code |= ASC_WARN_EEPROM_RECOVER;
13089
                eep_config->cfg_lsw = AscGetChipCfgLsw(iop_base);
13090
            }
13091
            if (eep_config->cfg_msw != cfg_msw) {
13092
                warn_code |= ASC_WARN_EEPROM_RECOVER;
13093
                eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
13094
            }
13095
        }
13096
    }
13097
    eep_config->cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
13098
    eep_config->cfg_lsw |= ASC_CFG0_HOST_INT_ON;
13099
    if (chksum != eep_config->chksum) {
13100
            if (AscGetChipVersion(iop_base, asc_dvc->bus_type) ==
13101
                    ASC_CHIP_VER_PCI_ULTRA_3050 )
13102
            {
13103
                eep_config->init_sdtr = 0xFF;
13104
                eep_config->disc_enable = 0xFF;
13105
                eep_config->start_motor = 0xFF;
13106
                eep_config->use_cmd_qng = 0;
13107
                eep_config->max_total_qng = 0xF0;
13108
                eep_config->max_tag_qng = 0x20;
13109
                eep_config->cntl = 0xBFFF;
13110
                eep_config->chip_scsi_id = 7;
13111
                eep_config->no_scam = 0;
13112
                eep_config->adapter_info[0] = 0;
13113
                eep_config->adapter_info[1] = 0;
13114
                eep_config->adapter_info[2] = 0;
13115
                eep_config->adapter_info[3] = 0;
13116
                eep_config->adapter_info[4] = 0;
13117
                /* Indicate EEPROM-less board. */
13118
                eep_config->adapter_info[5] = 0xBB;
13119
            } else {
13120
                write_eep = 1 ;
13121
                warn_code |= ASC_WARN_EEPROM_CHKSUM ;
13122
            }
13123
    }
13124
    asc_dvc->cfg->sdtr_enable = eep_config->init_sdtr ;
13125
    asc_dvc->cfg->disc_enable = eep_config->disc_enable;
13126
    asc_dvc->cfg->cmd_qng_enabled = eep_config->use_cmd_qng;
13127
    asc_dvc->cfg->isa_dma_speed = eep_config->isa_dma_speed;
13128
    asc_dvc->start_motor = eep_config->start_motor;
13129
    asc_dvc->dvc_cntl = eep_config->cntl;
13130
    asc_dvc->no_scam = eep_config->no_scam;
13131
    asc_dvc->cfg->adapter_info[0] = eep_config->adapter_info[0];
13132
    asc_dvc->cfg->adapter_info[1] = eep_config->adapter_info[1];
13133
    asc_dvc->cfg->adapter_info[2] = eep_config->adapter_info[2];
13134
    asc_dvc->cfg->adapter_info[3] = eep_config->adapter_info[3];
13135
    asc_dvc->cfg->adapter_info[4] = eep_config->adapter_info[4];
13136
    asc_dvc->cfg->adapter_info[5] = eep_config->adapter_info[5];
13137
    if (!AscTestExternalLram(asc_dvc)) {
13138
        if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA)) {
13139
            eep_config->max_total_qng = ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG;
13140
            eep_config->max_tag_qng = ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG;
13141
        } else {
13142
            eep_config->cfg_msw |= 0x0800;
13143
            cfg_msw |= 0x0800;
13144
            AscSetChipCfgMsw(iop_base, cfg_msw);
13145
            eep_config->max_total_qng = ASC_MAX_PCI_INRAM_TOTAL_QNG;
13146
            eep_config->max_tag_qng = ASC_MAX_INRAM_TAG_QNG;
13147
        }
13148
    } else {
13149
    }
13150
    if (eep_config->max_total_qng < ASC_MIN_TOTAL_QNG) {
13151
        eep_config->max_total_qng = ASC_MIN_TOTAL_QNG;
13152
    }
13153
    if (eep_config->max_total_qng > ASC_MAX_TOTAL_QNG) {
13154
        eep_config->max_total_qng = ASC_MAX_TOTAL_QNG;
13155
    }
13156
    if (eep_config->max_tag_qng > eep_config->max_total_qng) {
13157
        eep_config->max_tag_qng = eep_config->max_total_qng;
13158
    }
13159
    if (eep_config->max_tag_qng < ASC_MIN_TAG_Q_PER_DVC) {
13160
        eep_config->max_tag_qng = ASC_MIN_TAG_Q_PER_DVC;
13161
    }
13162
    asc_dvc->max_total_qng = eep_config->max_total_qng;
13163
    if ((eep_config->use_cmd_qng & eep_config->disc_enable) !=
13164
        eep_config->use_cmd_qng) {
13165
        eep_config->disc_enable = eep_config->use_cmd_qng;
13166
        warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
13167
    }
13168
    if (asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL | ASC_IS_EISA)) {
13169
        asc_dvc->irq_no = AscGetChipIRQ(iop_base, asc_dvc->bus_type);
13170
    }
13171
    eep_config->chip_scsi_id &= ASC_MAX_TID;
13172
    asc_dvc->cfg->chip_scsi_id = eep_config->chip_scsi_id;
13173
    if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) &&
13174
        !(asc_dvc->dvc_cntl & ASC_CNTL_SDTR_ENABLE_ULTRA)) {
13175
        asc_dvc->host_init_sdtr_index = ASC_SDTR_ULTRA_PCI_10MB_INDEX;
13176
    }
13177
 
13178
    for (i = 0; i <= ASC_MAX_TID; i++) {
13179
        asc_dvc->dos_int13_table[i] = eep_config->dos_int13_table[i];
13180
        asc_dvc->cfg->max_tag_qng[i] = eep_config->max_tag_qng;
13181
        asc_dvc->cfg->sdtr_period_offset[i] =
13182
            (uchar) (ASC_DEF_SDTR_OFFSET |
13183
                     (asc_dvc->host_init_sdtr_index << 4));
13184
    }
13185
    eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
13186
    if (write_eep) {
13187
        (void) AscSetEEPConfig(iop_base, eep_config, asc_dvc->bus_type);
13188
    }
13189
    return (warn_code);
13190
}
13191
 
13192
ASC_INITFUNC(
13193
STATIC ushort
13194
AscInitMicroCodeVar(
13195
                       ASC_DVC_VAR asc_ptr_type * asc_dvc
13196
)
13197
)
13198
{
13199
    int                 i;
13200
    ushort              warn_code;
13201
    PortAddr            iop_base;
13202
    ulong               phy_addr;
13203
 
13204
    iop_base = asc_dvc->iop_base;
13205
    warn_code = 0;
13206
    for (i = 0; i <= ASC_MAX_TID; i++) {
13207
        AscPutMCodeInitSDTRAtID(iop_base, i,
13208
                                asc_dvc->cfg->sdtr_period_offset[i]
13209
);
13210
    }
13211
    AscInitQLinkVar(asc_dvc);
13212
    AscWriteLramByte(iop_base, ASCV_DISC_ENABLE_B,
13213
                     asc_dvc->cfg->disc_enable);
13214
    AscWriteLramByte(iop_base, ASCV_HOSTSCSI_ID_B,
13215
                     ASC_TID_TO_TARGET_ID(asc_dvc->cfg->chip_scsi_id));
13216
    if ((phy_addr = AscGetOnePhyAddr(asc_dvc,
13217
                                 (uchar *) asc_dvc->cfg->overrun_buf,
13218
                                     ASC_OVERRUN_BSIZE)) == 0L) {
13219
        asc_dvc->err_code |= ASC_IERR_GET_PHY_ADDR;
13220
    } else {
13221
        phy_addr = (phy_addr & 0xFFFFFFF8UL) + 8;
13222
        AscWriteLramDWord(iop_base, ASCV_OVERRUN_PADDR_D, phy_addr);
13223
        AscWriteLramDWord(iop_base, ASCV_OVERRUN_BSIZE_D,
13224
                          ASC_OVERRUN_BSIZE - 8);
13225
    }
13226
    asc_dvc->cfg->mcode_date = AscReadLramWord(iop_base,
13227
                                               (ushort) ASCV_MC_DATE_W);
13228
    asc_dvc->cfg->mcode_version = AscReadLramWord(iop_base,
13229
                                                  (ushort) ASCV_MC_VER_W);
13230
    AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
13231
    if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
13232
        asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
13233
        return (warn_code);
13234
    }
13235
    if (AscStartChip(iop_base) != 1) {
13236
        asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
13237
        return (warn_code);
13238
    }
13239
    return (warn_code);
13240
}
13241
 
13242
ASC_INITFUNC(
13243
STATIC int
13244
AscTestExternalLram(
13245
                       ASC_DVC_VAR asc_ptr_type * asc_dvc
13246
)
13247
)
13248
{
13249
    PortAddr            iop_base;
13250
    ushort              q_addr;
13251
    ushort              saved_word;
13252
    int                 sta;
13253
 
13254
    iop_base = asc_dvc->iop_base;
13255
    sta = 0;
13256
    q_addr = ASC_QNO_TO_QADDR(241);
13257
    saved_word = AscReadLramWord(iop_base, q_addr);
13258
    AscSetChipLramAddr(iop_base, q_addr);
13259
    AscSetChipLramData(iop_base, 0x55AA);
13260
    DvcSleepMilliSecond(10);
13261
    AscSetChipLramAddr(iop_base, q_addr);
13262
    if (AscGetChipLramData(iop_base) == 0x55AA) {
13263
        sta = 1;
13264
        AscWriteLramWord(iop_base, q_addr, saved_word);
13265
    }
13266
    return (sta);
13267
}
13268
 
13269
ASC_INITFUNC(
13270
STATIC int
13271
AscWriteEEPCmdReg(
13272
                     PortAddr iop_base,
13273
                     uchar cmd_reg
13274
)
13275
)
13276
{
13277
    uchar               read_back;
13278
    int                 retry;
13279
 
13280
    retry = 0;
13281
    while (TRUE) {
13282
        AscSetChipEEPCmd(iop_base, cmd_reg);
13283
        DvcSleepMilliSecond(1);
13284
        read_back = AscGetChipEEPCmd(iop_base);
13285
        if (read_back == cmd_reg) {
13286
            return (1);
13287
        }
13288
        if (retry++ > ASC_EEP_MAX_RETRY) {
13289
            return (0);
13290
        }
13291
    }
13292
}
13293
 
13294
ASC_INITFUNC(
13295
STATIC int
13296
AscWriteEEPDataReg(
13297
                      PortAddr iop_base,
13298
                      ushort data_reg
13299
)
13300
)
13301
{
13302
    ushort              read_back;
13303
    int                 retry;
13304
 
13305
    retry = 0;
13306
    while (TRUE) {
13307
        AscSetChipEEPData(iop_base, data_reg);
13308
        DvcSleepMilliSecond(1);
13309
        read_back = AscGetChipEEPData(iop_base);
13310
        if (read_back == data_reg) {
13311
            return (1);
13312
        }
13313
        if (retry++ > ASC_EEP_MAX_RETRY) {
13314
            return (0);
13315
        }
13316
    }
13317
}
13318
 
13319
ASC_INITFUNC(
13320
STATIC void
13321
AscWaitEEPRead(
13322
                  void
13323
)
13324
)
13325
{
13326
    DvcSleepMilliSecond(1);
13327
    return;
13328
}
13329
 
13330
ASC_INITFUNC(
13331
STATIC void
13332
AscWaitEEPWrite(
13333
                   void
13334
)
13335
)
13336
{
13337
    DvcSleepMilliSecond(20);
13338
    return;
13339
}
13340
 
13341
ASC_INITFUNC(
13342
STATIC ushort
13343
AscReadEEPWord(
13344
                  PortAddr iop_base,
13345
                  uchar addr
13346
)
13347
)
13348
{
13349
    ushort              read_wval;
13350
    uchar               cmd_reg;
13351
 
13352
    AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
13353
    AscWaitEEPRead();
13354
    cmd_reg = addr | ASC_EEP_CMD_READ;
13355
    AscWriteEEPCmdReg(iop_base, cmd_reg);
13356
    AscWaitEEPRead();
13357
    read_wval = AscGetChipEEPData(iop_base);
13358
    AscWaitEEPRead();
13359
    return (read_wval);
13360
}
13361
 
13362
ASC_INITFUNC(
13363
STATIC ushort
13364
AscWriteEEPWord(
13365
                   PortAddr iop_base,
13366
                   uchar addr,
13367
                   ushort word_val
13368
)
13369
)
13370
{
13371
    ushort              read_wval;
13372
 
13373
    read_wval = AscReadEEPWord(iop_base, addr);
13374
    if (read_wval != word_val) {
13375
        AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_ABLE);
13376
        AscWaitEEPRead();
13377
        AscWriteEEPDataReg(iop_base, word_val);
13378
        AscWaitEEPRead();
13379
        AscWriteEEPCmdReg(iop_base,
13380
                          (uchar) ((uchar) ASC_EEP_CMD_WRITE | addr));
13381
        AscWaitEEPWrite();
13382
        AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
13383
        AscWaitEEPRead();
13384
        return (AscReadEEPWord(iop_base, addr));
13385
    }
13386
    return (read_wval);
13387
}
13388
 
13389
ASC_INITFUNC(
13390
STATIC ushort
13391
AscGetEEPConfig(
13392
                   PortAddr iop_base,
13393
                   ASCEEP_CONFIG * cfg_buf, ushort bus_type
13394
)
13395
)
13396
{
13397
    ushort              wval;
13398
    ushort              sum;
13399
    ushort      *wbuf;
13400
    int                 cfg_beg;
13401
    int                 cfg_end;
13402
    int                 s_addr;
13403
    int                 isa_pnp_wsize;
13404
 
13405
    wbuf = (ushort *) cfg_buf;
13406
    sum = 0;
13407
    isa_pnp_wsize = 0;
13408
    for (s_addr = 0; s_addr < (2 + isa_pnp_wsize); s_addr++, wbuf++) {
13409
        wval = AscReadEEPWord(iop_base, (uchar) s_addr);
13410
        sum += wval;
13411
        *wbuf = wval;
13412
    }
13413
    if (bus_type & ASC_IS_VL) {
13414
        cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
13415
        cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
13416
    } else {
13417
        cfg_beg = ASC_EEP_DVC_CFG_BEG;
13418
        cfg_end = ASC_EEP_MAX_DVC_ADDR;
13419
    }
13420
    for (s_addr = cfg_beg; s_addr <= (cfg_end - 1);
13421
         s_addr++, wbuf++) {
13422
        wval = AscReadEEPWord(iop_base, (uchar) s_addr);
13423
        sum += wval;
13424
        *wbuf = wval;
13425
    }
13426
    *wbuf = AscReadEEPWord(iop_base, (uchar) s_addr);
13427
    return (sum);
13428
}
13429
 
13430
ASC_INITFUNC(
13431
STATIC int
13432
AscSetEEPConfigOnce(
13433
                       PortAddr iop_base,
13434
                       ASCEEP_CONFIG * cfg_buf, ushort bus_type
13435
)
13436
)
13437
{
13438
    int                 n_error;
13439
    ushort      *wbuf;
13440
    ushort              sum;
13441
    int                 s_addr;
13442
    int                 cfg_beg;
13443
    int                 cfg_end;
13444
 
13445
    wbuf = (ushort *) cfg_buf;
13446
    n_error = 0;
13447
    sum = 0;
13448
    for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
13449
        sum += *wbuf;
13450
        if (*wbuf != AscWriteEEPWord(iop_base, (uchar) s_addr, *wbuf)) {
13451
            n_error++;
13452
        }
13453
    }
13454
    if (bus_type & ASC_IS_VL) {
13455
        cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
13456
        cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
13457
    } else {
13458
        cfg_beg = ASC_EEP_DVC_CFG_BEG;
13459
        cfg_end = ASC_EEP_MAX_DVC_ADDR;
13460
    }
13461
    for (s_addr = cfg_beg; s_addr <= (cfg_end - 1);
13462
         s_addr++, wbuf++) {
13463
        sum += *wbuf;
13464
        if (*wbuf != AscWriteEEPWord(iop_base, (uchar) s_addr, *wbuf)) {
13465
            n_error++;
13466
        }
13467
    }
13468
    *wbuf = sum;
13469
    if (sum != AscWriteEEPWord(iop_base, (uchar) s_addr, sum)) {
13470
        n_error++;
13471
    }
13472
    wbuf = (ushort *) cfg_buf;
13473
    for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
13474
        if (*wbuf != AscReadEEPWord(iop_base, (uchar) s_addr)) {
13475
            n_error++;
13476
        }
13477
    }
13478
    for (s_addr = cfg_beg; s_addr <= cfg_end;
13479
         s_addr++, wbuf++) {
13480
        if (*wbuf != AscReadEEPWord(iop_base, (uchar) s_addr)) {
13481
            n_error++;
13482
        }
13483
    }
13484
    return (n_error);
13485
}
13486
 
13487
ASC_INITFUNC(
13488
STATIC int
13489
AscSetEEPConfig(
13490
                   PortAddr iop_base,
13491
                   ASCEEP_CONFIG * cfg_buf, ushort bus_type
13492
)
13493
)
13494
{
13495
    int            retry;
13496
    int            n_error;
13497
 
13498
    retry = 0;
13499
    while (TRUE) {
13500
        if ((n_error = AscSetEEPConfigOnce(iop_base, cfg_buf,
13501
                                           bus_type)) == 0) {
13502
            break;
13503
        }
13504
        if (++retry > ASC_EEP_MAX_RETRY) {
13505
            break;
13506
        }
13507
    }
13508
    return (n_error);
13509
}
13510
 
13511
STATIC void
13512
AscAsyncFix(
13513
               ASC_DVC_VAR asc_ptr_type *asc_dvc,
13514
               uchar tid_no,
13515
               ASC_SCSI_INQUIRY *inq)
13516
{
13517
    uchar                dvc_type;
13518
    ASC_SCSI_BIT_ID_TYPE tid_bits;
13519
 
13520
    dvc_type = inq->byte0.peri_dvc_type;
13521
    tid_bits = ASC_TIX_TO_TARGET_ID(tid_no);
13522
 
13523
    if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ASYN_USE_SYN) {
13524
        if (!(asc_dvc->init_sdtr & tid_bits)) {
13525
            if ((dvc_type == SCSI_TYPE_CDROM) &&
13526
                (AscCompareString((uchar *) inq->vendor_id,
13527
                    (uchar *) "HP ", 3) == 0)) {
13528
                asc_dvc->pci_fix_asyn_xfer_always |= tid_bits;
13529
            }
13530
            asc_dvc->pci_fix_asyn_xfer |= tid_bits;
13531
            if ((dvc_type == SCSI_TYPE_PROC) ||
13532
                (dvc_type == SCSI_TYPE_SCANNER)) {
13533
                asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
13534
            }
13535
            if ((dvc_type == SCSI_TYPE_SASD) &&
13536
                (AscCompareString((uchar *) inq->vendor_id,
13537
                 (uchar *) "TANDBERG", 8) == 0) &&
13538
                (AscCompareString((uchar *) inq->product_id,
13539
                 (uchar *) " TDC 36", 7) == 0)) {
13540
                asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
13541
            }
13542
            if ((dvc_type == SCSI_TYPE_SASD) &&
13543
                (AscCompareString((uchar *) inq->vendor_id,
13544
                 (uchar *) "WANGTEK ", 8) == 0)) {
13545
                asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
13546
            }
13547
 
13548
            if ((dvc_type == SCSI_TYPE_CDROM) &&
13549
                (AscCompareString((uchar *) inq->vendor_id,
13550
                 (uchar *) "NEC     ", 8) == 0) &&
13551
                (AscCompareString((uchar *) inq->product_id,
13552
                 (uchar *) "CD-ROM DRIVE    ", 16) == 0)) {
13553
                asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
13554
            }
13555
 
13556
            if ((dvc_type == SCSI_TYPE_CDROM) &&
13557
                (AscCompareString((uchar *) inq->vendor_id,
13558
                 (uchar *) "YAMAHA", 6) == 0) &&
13559
                (AscCompareString((uchar *) inq->product_id,
13560
                 (uchar *) "CDR400", 6) == 0)) {
13561
                asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
13562
            }
13563
            if (asc_dvc->pci_fix_asyn_xfer & tid_bits) {
13564
                AscSetRunChipSynRegAtID(asc_dvc->iop_base, tid_no,
13565
                                        ASYN_SDTR_DATA_FIX_PCI_REV_AB);
13566
            }
13567
        }
13568
    }
13569
    return;
13570
}
13571
 
13572
STATIC int
13573
AscTagQueuingSafe(ASC_SCSI_INQUIRY *inq)
13574
{
13575
    if ((inq->add_len >= 32) &&
13576
        (AscCompareString((uchar *) inq->vendor_id,
13577
            (uchar *) "QUANTUM XP34301", 15) == 0) &&
13578
        (AscCompareString((uchar *) inq->product_rev_level,
13579
            (uchar *) "1071", 4) == 0))
13580
    {
13581
        return 0;
13582
    }
13583
    return 1;
13584
}
13585
 
13586
STATIC void
13587
AscInquiryHandling(ASC_DVC_VAR asc_ptr_type *asc_dvc,
13588
                   uchar tid_no, ASC_SCSI_INQUIRY *inq)
13589
{
13590
    ASC_SCSI_BIT_ID_TYPE tid_bit = ASC_TIX_TO_TARGET_ID(tid_no);
13591
    ASC_SCSI_BIT_ID_TYPE orig_init_sdtr, orig_use_tagged_qng;
13592
 
13593
    orig_init_sdtr = asc_dvc->init_sdtr;
13594
    orig_use_tagged_qng = asc_dvc->use_tagged_qng;
13595
 
13596
    asc_dvc->init_sdtr &= ~tid_bit;
13597
    asc_dvc->cfg->can_tagged_qng &= ~tid_bit;
13598
    asc_dvc->use_tagged_qng &= ~tid_bit;
13599
 
13600
    if (inq->byte3.rsp_data_fmt >= 2 || inq->byte2.ansi_apr_ver >= 2) {
13601
        if ((asc_dvc->cfg->sdtr_enable & tid_bit) && inq->byte7.Sync) {
13602
            asc_dvc->init_sdtr |= tid_bit;
13603
        }
13604
        if ((asc_dvc->cfg->cmd_qng_enabled & tid_bit) && inq->byte7.CmdQue) {
13605
            if (AscTagQueuingSafe(inq)) {
13606
                asc_dvc->use_tagged_qng |= tid_bit;
13607
                asc_dvc->cfg->can_tagged_qng |= tid_bit;
13608
            }
13609
        }
13610
    }
13611
    if (orig_use_tagged_qng != asc_dvc->use_tagged_qng) {
13612
        AscWriteLramByte(asc_dvc->iop_base, ASCV_DISC_ENABLE_B,
13613
                         asc_dvc->cfg->disc_enable);
13614
        AscWriteLramByte(asc_dvc->iop_base, ASCV_USE_TAGGED_QNG_B,
13615
                         asc_dvc->use_tagged_qng);
13616
        AscWriteLramByte(asc_dvc->iop_base, ASCV_CAN_TAGGED_QNG_B,
13617
                         asc_dvc->cfg->can_tagged_qng);
13618
 
13619
        asc_dvc->max_dvc_qng[tid_no] =
13620
          asc_dvc->cfg->max_tag_qng[tid_no];
13621
        AscWriteLramByte(asc_dvc->iop_base,
13622
                         (ushort) (ASCV_MAX_DVC_QNG_BEG + tid_no),
13623
                         asc_dvc->max_dvc_qng[tid_no]);
13624
    }
13625
    if (orig_init_sdtr != asc_dvc->init_sdtr) {
13626
        AscAsyncFix(asc_dvc, tid_no, inq);
13627
    }
13628
    return;
13629
}
13630
 
13631
STATIC int
13632
AscCompareString(
13633
                    ruchar * str1,
13634
                    ruchar * str2,
13635
                    int len
13636
)
13637
{
13638
    int                 i;
13639
    int                 diff;
13640
 
13641
    for (i = 0; i < len; i++) {
13642
        diff = (int) (str1[i] - str2[i]);
13643
        if (diff != 0)
13644
            return (diff);
13645
    }
13646
    return (0);
13647
}
13648
 
13649
STATIC uchar
13650
AscReadLramByte(
13651
                   PortAddr iop_base,
13652
                   ushort addr
13653
)
13654
{
13655
    uchar               byte_data;
13656
    ushort              word_data;
13657
 
13658
    if (isodd_word(addr)) {
13659
        AscSetChipLramAddr(iop_base, addr - 1);
13660
        word_data = AscGetChipLramData(iop_base);
13661
        byte_data = (uchar) ((word_data >> 8) & 0xFF);
13662
    } else {
13663
        AscSetChipLramAddr(iop_base, addr);
13664
        word_data = AscGetChipLramData(iop_base);
13665
        byte_data = (uchar) (word_data & 0xFF);
13666
    }
13667
    return (byte_data);
13668
}
13669
 
13670
STATIC ushort
13671
AscReadLramWord(
13672
                   PortAddr iop_base,
13673
                   ushort addr
13674
)
13675
{
13676
    ushort              word_data;
13677
 
13678
    AscSetChipLramAddr(iop_base, addr);
13679
    word_data = AscGetChipLramData(iop_base);
13680
    return (word_data);
13681
}
13682
 
13683
STATIC ulong
13684
AscReadLramDWord(
13685
                    PortAddr iop_base,
13686
                    ushort addr
13687
)
13688
{
13689
    ushort              val_low, val_high;
13690
    ulong               dword_data;
13691
 
13692
    AscSetChipLramAddr(iop_base, addr);
13693
    val_low = AscGetChipLramData(iop_base);
13694
    val_high = AscGetChipLramData(iop_base);
13695
    dword_data = ((ulong) val_high << 16) | (ulong) val_low;
13696
    return (dword_data);
13697
}
13698
 
13699
STATIC void
13700
AscWriteLramWord(
13701
                    PortAddr iop_base,
13702
                    ushort addr,
13703
                    ushort word_val
13704
)
13705
{
13706
    AscSetChipLramAddr(iop_base, addr);
13707
    AscSetChipLramData(iop_base, word_val);
13708
    return;
13709
}
13710
 
13711
STATIC void
13712
AscWriteLramDWord(
13713
                     PortAddr iop_base,
13714
                     ushort addr,
13715
                     ulong dword_val
13716
)
13717
{
13718
    ushort              word_val;
13719
 
13720
    AscSetChipLramAddr(iop_base, addr);
13721
    word_val = (ushort) dword_val;
13722
    AscSetChipLramData(iop_base, word_val);
13723
    word_val = (ushort) (dword_val >> 16);
13724
    AscSetChipLramData(iop_base, word_val);
13725
    return;
13726
}
13727
 
13728
STATIC void
13729
AscWriteLramByte(
13730
                    PortAddr iop_base,
13731
                    ushort addr,
13732
                    uchar byte_val
13733
)
13734
{
13735
    ushort              word_data;
13736
 
13737
    if (isodd_word(addr)) {
13738
        addr--;
13739
        word_data = AscReadLramWord(iop_base, addr);
13740
        word_data &= 0x00FF;
13741
        word_data |= (((ushort) byte_val << 8) & 0xFF00);
13742
    } else {
13743
        word_data = AscReadLramWord(iop_base, addr);
13744
        word_data &= 0xFF00;
13745
        word_data |= ((ushort) byte_val & 0x00FF);
13746
    }
13747
    AscWriteLramWord(iop_base, addr, word_data);
13748
    return;
13749
}
13750
 
13751
STATIC void
13752
AscMemWordCopyToLram(
13753
                        PortAddr iop_base,
13754
                        ushort s_addr,
13755
                        ushort * s_buffer,
13756
                        int words
13757
)
13758
{
13759
    AscSetChipLramAddr(iop_base, s_addr);
13760
    DvcOutPortWords(iop_base + IOP_RAM_DATA, s_buffer, words);
13761
    return;
13762
}
13763
 
13764
STATIC void
13765
AscMemDWordCopyToLram(
13766
                         PortAddr iop_base,
13767
                         ushort s_addr,
13768
                         ulong * s_buffer,
13769
                         int dwords
13770
)
13771
{
13772
    AscSetChipLramAddr(iop_base, s_addr);
13773
    DvcOutPortDWords(iop_base + IOP_RAM_DATA, s_buffer, dwords);
13774
    return;
13775
}
13776
 
13777
STATIC void
13778
AscMemWordCopyFromLram(
13779
                          PortAddr iop_base,
13780
                          ushort s_addr,
13781
                          ushort * d_buffer,
13782
                          int words
13783
)
13784
{
13785
    AscSetChipLramAddr(iop_base, s_addr);
13786
    DvcInPortWords(iop_base + IOP_RAM_DATA, d_buffer, words);
13787
    return;
13788
}
13789
 
13790
STATIC ulong
13791
AscMemSumLramWord(
13792
                     PortAddr iop_base,
13793
                     ushort s_addr,
13794
                     rint words
13795
)
13796
{
13797
    ulong               sum;
13798
    int                 i;
13799
 
13800
    sum = 0L;
13801
    for (i = 0; i < words; i++, s_addr += 2) {
13802
        sum += AscReadLramWord(iop_base, s_addr);
13803
    }
13804
    return (sum);
13805
}
13806
 
13807
STATIC void
13808
AscMemWordSetLram(
13809
                     PortAddr iop_base,
13810
                     ushort s_addr,
13811
                     ushort set_wval,
13812
                     rint words
13813
)
13814
{
13815
    rint             i;
13816
 
13817
    AscSetChipLramAddr(iop_base, s_addr);
13818
    for (i = 0; i < words; i++) {
13819
        AscSetChipLramData(iop_base, set_wval);
13820
    }
13821
    return;
13822
}
13823
 
13824
 
13825
/*
13826
 * --- Adv Library Functions
13827
 */
13828
 
13829
/* a_qswap.h */
13830
STATIC unsigned char _adv_mcode_buf[] ASC_INITDATA = {
13831
  0x9C,  0xF0,  0x80,  0x01,  0x00,  0xF0,  0x44,  0x0A,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
13832
  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
13833
  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x72,  0x01,  0xD6,  0x11,  0x00,  0x00,  0x70,  0x01,
13834
  0x30,  0x01,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x90,  0x10,  0x2D,  0x03,  0x00,  0x00,  0x00,  0x00,
13835
  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
13836
  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
13837
  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
13838
  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
13839
  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
13840
  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
13841
  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
13842
  0x48,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
13843
  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
13844
  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,
13845
  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
13846
  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
13847
  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
13848
  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
13849
  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x78,  0x56,  0x34,  0x12,
13850
  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
13851
  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
13852
  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
13853
  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
13854
  0x00,  0x00,  0x04,  0xF7,  0x70,  0x01,  0x0C,  0x1C,  0x06,  0xF7,  0x02,  0x00,  0x00,  0xF2,  0xD6,  0x0A,
13855
  0x04,  0xF7,  0x70,  0x01,  0x06,  0xF7,  0x02,  0x00,  0x3E,  0x57,  0x3C,  0x56,  0x0C,  0x1C,  0x00,  0xFC,
13856
  0xA6,  0x00,  0x01,  0x58,  0xAA,  0x13,  0x20,  0xF0,  0xA6,  0x03,  0x06,  0xEC,  0xB9,  0x00,  0x0E,  0x47,
13857
  0x03,  0xE6,  0x10,  0x00,  0xCE,  0x45,  0x02,  0x13,  0x3E,  0x57,  0x06,  0xEA,  0xB9,  0x00,  0x47,  0x4B,
13858
  0x03,  0xF6,  0xE0,  0x00,  0x00,  0xF2,  0x68,  0x0A,  0x01,  0x48,  0x4E,  0x12,  0x03,  0xF6,  0xC0,  0x00,
13859
  0x00,  0xF2,  0x68,  0x0A,  0x41,  0x58,  0x03,  0xF6,  0xD0,  0x00,  0x00,  0xF2,  0x68,  0x0A,  0x49,  0x44,
13860
  0x59,  0xF0,  0x0A,  0x02,  0x03,  0xF6,  0xE0,  0x00,  0x00,  0xF2,  0x68,  0x0A,  0x44,  0x58,  0x00,  0xF2,
13861
  0xE2,  0x0D,  0x02,  0xCC,  0x4A,  0xE4,  0x01,  0x00,  0x55,  0xF0,  0x08,  0x03,  0x45,  0xF4,  0x02,  0x00,
13862
  0x83,  0x5A,  0x04,  0xCC,  0x01,  0x4A,  0x12,  0x12,  0x00,  0xF2,  0xE2,  0x0D,  0x00,  0xCD,  0x48,  0xE4,
13863
  0x01,  0x00,  0xE9,  0x13,  0x00,  0xF2,  0xC6,  0x0F,  0xFA,  0x10,  0x0E,  0x47,  0x03,  0xE6,  0x10,  0x00,
13864
  0xCE,  0x45,  0x02,  0x13,  0x3E,  0x57,  0xCE,  0x47,  0x97,  0x13,  0x04,  0xEC,  0xB4,  0x00,  0x00,  0xF2,
13865
  0xE2,  0x0D,  0x00,  0xCD,  0x48,  0xE4,  0x00,  0x00,  0x12,  0x12,  0x3E,  0x57,  0x06,  0xCC,  0x45,  0xF4,
13866
  0x02,  0x00,  0x83,  0x5A,  0x00,  0xCC,  0x00,  0xEA,  0xB4,  0x00,  0x92,  0x10,  0x00,  0xF0,  0x8C,  0x01,
13867
  0x43,  0xF0,  0x5C,  0x02,  0x44,  0xF0,  0x60,  0x02,  0x45,  0xF0,  0x64,  0x02,  0x46,  0xF0,  0x68,  0x02,
13868
  0x47,  0xF0,  0x6E,  0x02,  0x48,  0xF0,  0x9E,  0x02,  0xB9,  0x54,  0x62,  0x10,  0x00,  0x1C,  0x5A,  0x10,
13869
  0x02,  0x1C,  0x56,  0x10,  0x1E,  0x1C,  0x52,  0x10,  0x00,  0xF2,  0x1E,  0x11,  0x50,  0x10,  0x06,  0xFC,
13870
  0xA8,  0x00,  0x03,  0xF6,  0xBE,  0x00,  0x00,  0xF2,  0x4E,  0x0A,  0x8C,  0x10,  0x01,  0xF6,  0x01,  0x00,
13871
  0x01,  0xFA,  0xA8,  0x00,  0x00,  0xF2,  0x2C,  0x0B,  0x06,  0x10,  0xB9,  0x54,  0x01,  0xFA,  0xA8,  0x00,
13872
  0x03,  0xF6,  0xBE,  0x00,  0x00,  0xF2,  0x58,  0x0A,  0x01,  0xFC,  0xA8,  0x00,  0x20,  0x10,  0x58,  0x1C,
13873
  0x00,  0xF2,  0x1C,  0x0B,  0x5A,  0x1C,  0x01,  0xF6,  0x01,  0x00,  0x38,  0x54,  0x00,  0xFA,  0xA6,  0x00,
13874
  0x01,  0xFA,  0xA8,  0x00,  0x20,  0x1C,  0x00,  0xF0,  0x72,  0x01,  0x01,  0xF6,  0x01,  0x00,  0x38,  0x54,
13875
  0x00,  0xFA,  0xA6,  0x00,  0x01,  0xFA,  0xA8,  0x00,  0x20,  0x1C,  0x00,  0xF0,  0x80,  0x01,  0x03,  0xF6,
13876
  0xE0,  0x00,  0x00,  0xF2,  0x68,  0x0A,  0x01,  0x48,  0x0A,  0x13,  0x00,  0xF2,  0x38,  0x10,  0x00,  0xF2,
13877
  0x54,  0x0F,  0x24,  0x10,  0x03,  0xF6,  0xC0,  0x00,  0x00,  0xF2,  0x68,  0x0A,  0x02,  0xF6,  0xD0,  0x00,
13878
  0x02,  0x57,  0x03,  0x59,  0x01,  0xCC,  0x49,  0x44,  0x5B,  0xF0,  0x04,  0x03,  0x00,  0xF2,  0x9C,  0x0F,
13879
  0x00,  0xF0,  0x80,  0x01,  0x00,  0xF2,  0x14,  0x10,  0x0C,  0x1C,  0x02,  0x4B,  0xBF,  0x57,  0x9E,  0x43,
13880
  0x77,  0x57,  0x07,  0x4B,  0x20,  0xF0,  0xA6,  0x03,  0x40,  0x1C,  0x1E,  0xF0,  0x30,  0x03,  0x26,  0xF0,
13881
  0x2C,  0x03,  0xA0,  0xF0,  0x1A,  0x03,  0x11,  0xF0,  0xA6,  0x03,  0x12,  0x10,  0x9F,  0xF0,  0x3E,  0x03,
13882
  0x46,  0x1C,  0x82,  0xE7,  0x05,  0x00,  0x9E,  0xE7,  0x11,  0x00,  0x00,  0xF0,  0x06,  0x0A,  0x0C,  0x1C,
13883
  0x48,  0x1C,  0x46,  0x1C,  0x38,  0x54,  0x00,  0xEC,  0xBA,  0x00,  0x08,  0x44,  0x00,  0xEA,  0xBA,  0x00,
13884
  0x03,  0xF6,  0xC0,  0x00,  0x00,  0xF2,  0x68,  0x0A,  0x08,  0x44,  0x00,  0x4C,  0x82,  0xE7,  0x02,  0x00,
13885
  0x00,  0xF2,  0x12,  0x11,  0x00,  0xF2,  0x12,  0x11,  0x85,  0xF0,  0x70,  0x03,  0x00,  0xF2,  0x60,  0x0B,
13886
  0x06,  0xF0,  0x80,  0x03,  0x09,  0xF0,  0x24,  0x09,  0x1E,  0xF0,  0xFC,  0x09,  0x00,  0xF0,  0x02,  0x0A,
13887
  0x00,  0xFC,  0xBE,  0x00,  0x98,  0x57,  0x55,  0xF0,  0xAC,  0x04,  0x01,  0xE6,  0x0C,  0x00,  0x00,  0xF2,
13888
  0x4E,  0x0D,  0x00,  0xF2,  0x12,  0x11,  0x00,  0xF2,  0xBC,  0x11,  0x00,  0xF2,  0xC8,  0x11,  0x01,  0xF0,
13889
  0x7C,  0x02,  0x00,  0xF0,  0x8A,  0x02,  0x46,  0x1C,  0x0C,  0x1C,  0x67,  0x1B,  0xBF,  0x57,  0x77,  0x57,
13890
  0x02,  0x4B,  0x48,  0x1C,  0x32,  0x1C,  0x00,  0xF2,  0x92,  0x0D,  0x30,  0x1C,  0x96,  0xF0,  0xBC,  0x03,
13891
  0xB1,  0xF0,  0xC0,  0x03,  0x1E,  0xF0,  0xFC,  0x09,  0x85,  0xF0,  0x02,  0x0A,  0x00,  0xFC,  0xBE,  0x00,
13892
  0x98,  0x57,  0x14,  0x12,  0x01,  0xE6,  0x0C,  0x00,  0x00,  0xF2,  0x4E,  0x0D,  0x00,  0xF2,  0x12,  0x11,
13893
  0x01,  0xF0,  0x7C,  0x02,  0x00,  0xF0,  0x8A,  0x02,  0x03,  0xF6,  0xE0,  0x00,  0x00,  0xF2,  0x68,  0x0A,
13894
  0x01,  0x48,  0x55,  0xF0,  0x98,  0x04,  0x03,  0x82,  0x03,  0xFC,  0xA0,  0x00,  0x9B,  0x57,  0x40,  0x12,
13895
  0x69,  0x18,  0x00,  0xF2,  0x12,  0x11,  0x85,  0xF0,  0x42,  0x04,  0x69,  0x08,  0x00,  0xF2,  0x12,  0x11,
13896
  0x85,  0xF0,  0x02,  0x0A,  0x68,  0x08,  0x4C,  0x44,  0x28,  0x12,  0x44,  0x48,  0x03,  0xF6,  0xE0,  0x00,
13897
  0x00,  0xF2,  0x68,  0x0A,  0x45,  0x58,  0x00,  0xF2,  0xF6,  0x0D,  0x00,  0xCC,  0x01,  0x48,  0x55,  0xF0,
13898
  0x98,  0x04,  0x4C,  0x44,  0xEF,  0x13,  0x00,  0xF2,  0xC6,  0x0F,  0x00,  0xF2,  0x14,  0x10,  0x08,  0x10,
13899
  0x68,  0x18,  0x45,  0x5A,  0x00,  0xF2,  0xF6,  0x0D,  0x04,  0x80,  0x18,  0xE4,  0x10,  0x00,  0x28,  0x12,
13900
  0x01,  0xE6,  0x06,  0x00,  0x04,  0x80,  0x18,  0xE4,  0x01,  0x00,  0x04,  0x12,  0x01,  0xE6,  0x0D,  0x00,
13901
  0x00,  0xF2,  0x4E,  0x0D,  0x00,  0xF2,  0x12,  0x11,  0x04,  0xE6,  0x02,  0x00,  0x9E,  0xE7,  0x15,  0x00,
13902
  0x01,  0xF0,  0x1C,  0x0A,  0x00,  0xF0,  0x02,  0x0A,  0x69,  0x08,  0x05,  0x80,  0x48,  0xE4,  0x00,  0x00,
13903
  0x0C,  0x12,  0x00,  0xE6,  0x11,  0x00,  0x00,  0xEA,  0xB8,  0x00,  0x00,  0xF2,  0xB6,  0x10,  0x82,  0xE7,
13904
  0x02,  0x00,  0x1C,  0x90,  0x40,  0x5C,  0x00,  0x16,  0x01,  0xE6,  0x06,  0x00,  0x00,  0xF2,  0x4E,  0x0D,
13905
  0x01,  0xF0,  0x80,  0x01,  0x1E,  0xF0,  0x80,  0x01,  0x00,  0xF0,  0xA0,  0x04,  0x42,  0x5B,  0x06,  0xF7,
13906
  0x03,  0x00,  0x46,  0x59,  0xBF,  0x57,  0x77,  0x57,  0x01,  0xE6,  0x80,  0x00,  0x07,  0x80,  0x31,  0x44,
13907
  0x04,  0x80,  0x18,  0xE4,  0x20,  0x00,  0x56,  0x13,  0x20,  0x80,  0x48,  0xE4,  0x03,  0x00,  0x4E,  0x12,
13908
  0x00,  0xFC,  0xA2,  0x00,  0x98,  0x57,  0x55,  0xF0,  0x1C,  0x05,  0x31,  0xE4,  0x40,  0x00,  0x00,  0xFC,
13909
  0xA0,  0x00,  0x98,  0x57,  0x36,  0x12,  0x4C,  0x1C,  0x00,  0xF2,  0x12,  0x11,  0x89,  0x48,  0x00,  0xF2,
13910
  0x12,  0x11,  0x86,  0xF0,  0x2E,  0x05,  0x82,  0xE7,  0x06,  0x00,  0x1B,  0x80,  0x48,  0xE4,  0x22,  0x00,
13911
  0x5B,  0xF0,  0x0C,  0x05,  0x48,  0xE4,  0x20,  0x00,  0x59,  0xF0,  0x10,  0x05,  0x00,  0xE6,  0x20,  0x00,
13912
  0x09,  0x48,  0x00,  0xF2,  0x12,  0x11,  0x86,  0xF0,  0x2E,  0x05,  0x83,  0x80,  0x04,  0x10,  0x00,  0xF2,
13913
  0xA2,  0x0D,  0x00,  0xE6,  0x01,  0x00,  0x00,  0xEA,  0x26,  0x01,  0x01,  0xEA,  0x27,  0x01,  0x04,  0x80,
13914
  0x18,  0xE4,  0x10,  0x00,  0x36,  0x12,  0xB9,  0x54,  0x00,  0xF2,  0xF6,  0x0E,  0x01,  0xE6,  0x06,  0x00,
13915
  0x04,  0x80,  0x18,  0xE4,  0x01,  0x00,  0x04,  0x12,  0x01,  0xE6,  0x0D,  0x00,  0x00,  0xF2,  0x4E,  0x0D,
13916
  0x00,  0xF2,  0x12,  0x11,  0x00,  0xF2,  0xBC,  0x11,  0x00,  0xF2,  0xC8,  0x11,  0x04,  0xE6,  0x02,  0x00,
13917
  0x9E,  0xE7,  0x15,  0x00,  0x01,  0xF0,  0x1C,  0x0A,  0x00,  0xF0,  0x02,  0x0A,  0x00,  0xFC,  0x20,  0x01,
13918
  0x98,  0x57,  0x34,  0x12,  0x00,  0xFC,  0x24,  0x01,  0x98,  0x57,  0x2C,  0x13,  0xB9,  0x54,  0x00,  0xF2,
13919
  0xF6,  0x0E,  0x86,  0xF0,  0xA8,  0x05,  0x03,  0xF6,  0x01,  0x00,  0x00,  0xF2,  0x8C,  0x0E,  0x85,  0xF0,
13920
  0x9E,  0x05,  0x82,  0xE7,  0x03,  0x00,  0x00,  0xF2,  0x60,  0x0B,  0x82,  0xE7,  0x02,  0x00,  0x00,  0xFC,
13921
  0x24,  0x01,  0xB0,  0x57,  0x00,  0xFA,  0x24,  0x01,  0x00,  0xFC,  0x9E,  0x00,  0x98,  0x57,  0x5A,  0x12,
13922
  0x00,  0xFC,  0xB6,  0x00,  0x98,  0x57,  0x52,  0x13,  0x03,  0xE6,  0x0C,  0x00,  0x00,  0xFC,  0x9C,  0x00,
13923
  0x98,  0x57,  0x04,  0x13,  0x03,  0xE6,  0x19,  0x00,  0x05,  0xE6,  0x08,  0x00,  0x00,  0xF6,  0x00,  0x01,
13924
  0x00,  0x57,  0x00,  0x57,  0x03,  0x58,  0x00,  0xDC,  0x18,  0xF4,  0x00,  0x80,  0x04,  0x13,  0x05,  0xE6,
13925
  0x0F,  0x00,  0xB9,  0x54,  0x00,  0xF2,  0xF6,  0x0E,  0x86,  0xF0,  0x0A,  0x06,  0x00,  0xF2,  0xBA,  0x0E,
13926
  0x85,  0xF0,  0x00,  0x06,  0x82,  0xE7,  0x03,  0x00,  0x00,  0xF2,  0x60,  0x0B,  0x82,  0xE7,  0x02,  0x00,
13927
  0x00,  0xFC,  0xB6,  0x00,  0xB0,  0x57,  0x00,  0xFA,  0xB6,  0x00,  0x01,  0xF6,  0x01,  0x00,  0x00,  0xF2,
13928
  0xF6,  0x0E,  0x9C,  0x32,  0x4E,  0x1C,  0x32,  0x1C,  0x00,  0xF2,  0x92,  0x0D,  0x30,  0x1C,  0x82,  0xE7,
13929
  0x04,  0x00,  0xB1,  0xF0,  0x22,  0x06,  0x0A,  0xF0,  0x3E,  0x06,  0x05,  0xF0,  0xD6,  0x06,  0x06,  0xF0,
13930
  0xDC,  0x06,  0x09,  0xF0,  0x24,  0x09,  0x1E,  0xF0,  0xFC,  0x09,  0x00,  0xF0,  0x02,  0x0A,  0x04,  0x80,
13931
  0x18,  0xE4,  0x20,  0x00,  0x30,  0x12,  0x09,  0xE7,  0x03,  0x00,  0x00,  0xF2,  0x12,  0x11,  0x21,  0x80,
13932
  0x18,  0xE4,  0xE0,  0x00,  0x09,  0x48,  0x00,  0xF2,  0x12,  0x11,  0x09,  0xE7,  0x00,  0x00,  0x00,  0xF2,
13933
  0x12,  0x11,  0x09,  0xE7,  0x00,  0x00,  0x00,  0xF2,  0x12,  0x11,  0x99,  0xA4,  0x00,  0xF2,  0x12,  0x11,
13934
  0x09,  0xE7,  0x00,  0x00,  0x9A,  0x10,  0x04,  0x80,  0x18,  0xE4,  0x02,  0x00,  0x34,  0x12,  0x09,  0xE7,
13935
  0x1B,  0x00,  0x00,  0xF2,  0x12,  0x11,  0x21,  0x80,  0x18,  0xE4,  0xE0,  0x00,  0x09,  0x48,  0x00,  0xF2,
13936
  0x12,  0x11,  0x09,  0xE7,  0x00,  0x00,  0x00,  0xF2,  0x12,  0x11,  0x09,  0xE7,  0x00,  0x00,  0x00,  0xF2,
13937
  0x12,  0x11,  0x09,  0xE7,  0x01,  0x00,  0x00,  0xF2,  0x12,  0x11,  0x09,  0xE7,  0x00,  0x00,  0x00,  0xF0,
13938
  0x0C,  0x09,  0xBB,  0x55,  0x9A,  0x81,  0x03,  0xF7,  0x20,  0x00,  0x09,  0x6F,  0x93,  0x45,  0x55,  0xF0,
13939
  0xE2,  0x06,  0xB1,  0xF0,  0xC2,  0x06,  0x0A,  0xF0,  0xBA,  0x06,  0x09,  0xF0,  0x24,  0x09,  0x1E,  0xF0,
13940
  0xFC,  0x09,  0x00,  0xF0,  0x02,  0x0A,  0x00,  0xF2,  0x60,  0x0B,  0x47,  0x10,  0x09,  0xE7,  0x08,  0x00,
13941
  0x41,  0x10,  0x05,  0x80,  0x48,  0xE4,  0x00,  0x00,  0x1E,  0x12,  0x00,  0xE6,  0x11,  0x00,  0x00,  0xEA,
13942
  0xB8,  0x00,  0x00,  0xF2,  0xB6,  0x10,  0x2C,  0x90,  0xAE,  0x90,  0x08,  0x50,  0x8A,  0x50,  0x38,  0x54,
13943
  0x1F,  0x40,  0x00,  0xF2,  0xB4,  0x0D,  0x08,  0x10,  0x08,  0x90,  0x8A,  0x90,  0x30,  0x50,  0xB2,  0x50,
13944
  0x9C,  0x32,  0x0C,  0x92,  0x8E,  0x92,  0x38,  0x54,  0x04,  0x80,  0x30,  0xE4,  0x08,  0x00,  0x04,  0x40,
13945
  0x0C,  0x1C,  0x00,  0xF6,  0x03,  0x00,  0xB1,  0xF0,  0x26,  0x07,  0x9E,  0xF0,  0x3A,  0x07,  0x01,  0x48,
13946
  0x55,  0xF0,  0xFC,  0x09,  0x0C,  0x1C,  0x10,  0x44,  0xED,  0x10,  0x0B,  0xF0,  0x5E,  0x07,  0x0C,  0xF0,
13947
  0x62,  0x07,  0x05,  0xF0,  0x52,  0x07,  0x06,  0xF0,  0x58,  0x07,  0x09,  0xF0,  0x24,  0x09,  0x00,  0xF0,
13948
  0x02,  0x0A,  0x00,  0xF2,  0x60,  0x0B,  0xCF,  0x10,  0x09,  0xE7,  0x08,  0x00,  0xC9,  0x10,  0x2E,  0x1C,
13949
  0x02,  0x10,  0x2C,  0x1C,  0xAA,  0xF0,  0x64,  0x07,  0xAC,  0xF0,  0x72,  0x07,  0x40,  0x10,  0x34,  0x1C,
13950
  0xF3,  0x10,  0xAD,  0xF0,  0x7C,  0x07,  0xC8,  0x10,  0x36,  0x1C,  0xE9,  0x10,  0x2B,  0xF0,  0x82,  0x08,
13951
  0x6B,  0x18,  0x18,  0xF4,  0x00,  0xFE,  0x20,  0x12,  0x01,  0x58,  0xD2,  0xF0,  0x82,  0x08,  0x76,  0x18,
13952
  0x18,  0xF4,  0x03,  0x00,  0xEC,  0x12,  0x00,  0xFC,  0x22,  0x01,  0x18,  0xF4,  0x01,  0x00,  0xE2,  0x12,
13953
  0x0B,  0xF0,  0x64,  0x07,  0x0C,  0xF0,  0x64,  0x07,  0x36,  0x1C,  0x34,  0x1C,  0xB7,  0x10,  0x38,  0x54,
13954
  0xB9,  0x54,  0x84,  0x80,  0x19,  0xE4,  0x20,  0x00,  0xB2,  0x13,  0x85,  0x80,  0x81,  0x48,  0x66,  0x12,
13955
  0x04,  0x80,  0x18,  0xE4,  0x08,  0x00,  0x58,  0x13,  0x1F,  0x80,  0x08,  0x44,  0xC8,  0x44,  0x9F,  0x12,
13956
  0x1F,  0x40,  0x34,  0x91,  0xB6,  0x91,  0x44,  0x55,  0xE5,  0x55,  0x02,  0xEC,  0xB8,  0x00,  0x02,  0x49,
13957
  0xBB,  0x55,  0x82,  0x81,  0xC0,  0x55,  0x48,  0xF4,  0x0F,  0x00,  0x5A,  0xF0,  0x1A,  0x08,  0x4A,  0xE4,
13958
  0x17,  0x00,  0xD5,  0xF0,  0xFA,  0x07,  0x02,  0xF6,  0x0F,  0x00,  0x02,  0xF4,  0x02,  0x00,  0x02,  0xEA,
13959
  0xB8,  0x00,  0x04,  0x91,  0x86,  0x91,  0x02,  0x4B,  0x2C,  0x90,  0x08,  0x50,  0x2E,  0x90,  0x0A,  0x50,
13960
  0x2C,  0x51,  0xAE,  0x51,  0x00,  0xF2,  0xB6,  0x10,  0x38,  0x54,  0x00,  0xF2,  0xB4,  0x0D,  0x56,  0x10,
13961
  0x34,  0x91,  0xB6,  0x91,  0x0C,  0x10,  0x04,  0x80,  0x18,  0xE4,  0x08,  0x00,  0x41,  0x12,  0x0C,  0x91,
13962
  0x8E,  0x91,  0x04,  0x80,  0x18,  0xE4,  0xF7,  0x00,  0x04,  0x40,  0x30,  0x90,  0xB2,  0x90,  0x36,  0x10,
13963
  0x02,  0x80,  0x48,  0xE4,  0x10,  0x00,  0x31,  0x12,  0x82,  0xE7,  0x10,  0x00,  0x84,  0x80,  0x19,  0xE4,
13964
  0x20,  0x00,  0x10,  0x13,  0x0C,  0x90,  0x8E,  0x90,  0x5D,  0xF0,  0x78,  0x07,  0x0C,  0x58,  0x8D,  0x58,
13965
  0x00,  0xF0,  0x64,  0x07,  0x38,  0x54,  0xB9,  0x54,  0x19,  0x80,  0xF1,  0x10,  0x3A,  0x55,  0x19,  0x81,
13966
  0xBB,  0x55,  0x10,  0x90,  0x92,  0x90,  0x10,  0x58,  0x91,  0x58,  0x14,  0x59,  0x95,  0x59,  0x00,  0xF0,
13967
  0x64,  0x07,  0x04,  0x80,  0x18,  0xE4,  0x20,  0x00,  0x06,  0x12,  0x6C,  0x19,  0x19,  0x41,  0x7C,  0x10,
13968
  0x6C,  0x19,  0x0C,  0x51,  0xED,  0x19,  0x8E,  0x51,  0x6B,  0x18,  0x18,  0xF4,  0x00,  0xFF,  0x02,  0x13,
13969
  0x6A,  0x10,  0x01,  0x58,  0xD2,  0xF0,  0xC0,  0x08,  0x76,  0x18,  0x18,  0xF4,  0x03,  0x00,  0x0A,  0x12,
13970
  0x00,  0xFC,  0x22,  0x01,  0x18,  0xF4,  0x01,  0x00,  0x06,  0x13,  0x9E,  0xE7,  0x16,  0x00,  0x4C,  0x10,
13971
  0xD1,  0xF0,  0xCA,  0x08,  0x9E,  0xE7,  0x17,  0x00,  0x42,  0x10,  0xD0,  0xF0,  0xD4,  0x08,  0x9E,  0xE7,
13972
  0x19,  0x00,  0x38,  0x10,  0xCF,  0xF0,  0xDE,  0x08,  0x9E,  0xE7,  0x20,  0x00,  0x2E,  0x10,  0xCE,  0xF0,
13973
  0xE8,  0x08,  0x9E,  0xE7,  0x21,  0x00,  0x24,  0x10,  0xCD,  0xF0,  0xF2,  0x08,  0x9E,  0xE7,  0x22,  0x00,
13974
  0x1A,  0x10,  0xCC,  0xF0,  0x04,  0x09,  0x84,  0x80,  0x19,  0xE4,  0x04,  0x00,  0x06,  0x12,  0x9E,  0xE7,
13975
  0x12,  0x00,  0x08,  0x10,  0xCB,  0xF0,  0x0C,  0x09,  0x9E,  0xE7,  0x24,  0x00,  0xB1,  0xF0,  0x0C,  0x09,
13976
  0x05,  0xF0,  0x1E,  0x09,  0x09,  0xF0,  0x24,  0x09,  0x1E,  0xF0,  0xFC,  0x09,  0xE4,  0x10,  0x00,  0xF2,
13977
  0x60,  0x0B,  0xE9,  0x10,  0x9C,  0x32,  0x82,  0xE7,  0x20,  0x00,  0x32,  0x1C,  0xE9,  0x09,  0x00,  0xF2,
13978
  0x12,  0x11,  0x85,  0xF0,  0x02,  0x0A,  0x69,  0x08,  0x01,  0xF0,  0x44,  0x09,  0x1E,  0xF0,  0xFC,  0x09,
13979
  0x00,  0xF0,  0x38,  0x09,  0x30,  0x44,  0x06,  0x12,  0x9E,  0xE7,  0x42,  0x00,  0xB8,  0x10,  0x04,  0xF6,
13980
  0x01,  0x00,  0xB3,  0x45,  0x74,  0x12,  0x04,  0x80,  0x18,  0xE4,  0x20,  0x00,  0x22,  0x13,  0x4B,  0xE4,
13981
  0x02,  0x00,  0x36,  0x12,  0x4B,  0xE4,  0x28,  0x00,  0xAC,  0x13,  0x00,  0xF2,  0xBC,  0x11,  0x00,  0xF2,
13982
  0xC8,  0x11,  0x03,  0xF6,  0xD0,  0x00,  0xFA,  0x14,  0x82,  0xE7,  0x01,  0x00,  0x00,  0xF0,  0x80,  0x01,
13983
  0x9E,  0xE7,  0x44,  0x00,  0x4B,  0xE4,  0x02,  0x00,  0x06,  0x12,  0x03,  0xE6,  0x02,  0x00,  0x76,  0x10,
13984
  0x00,  0xF2,  0xA2,  0x0D,  0x03,  0xE6,  0x02,  0x00,  0x6C,  0x10,  0x00,  0xF2,  0xA2,  0x0D,  0x19,  0x82,
13985
  0x34,  0x46,  0x0A,  0x13,  0x03,  0xE6,  0x02,  0x00,  0x9E,  0xE7,  0x43,  0x00,  0x68,  0x10,  0x04,  0x80,
13986
  0x30,  0xE4,  0x20,  0x00,  0x04,  0x40,  0x00,  0xF2,  0xBC,  0x11,  0x00,  0xF2,  0xC8,  0x11,  0x82,  0xE7,
13987
  0x01,  0x00,  0x06,  0xF7,  0x02,  0x00,  0x00,  0xF0,  0x08,  0x03,  0x04,  0x80,  0x18,  0xE4,  0x20,  0x00,
13988
  0x06,  0x12,  0x03,  0xE6,  0x02,  0x00,  0x3E,  0x10,  0x04,  0x80,  0x18,  0xE4,  0x02,  0x00,  0x3A,  0x12,
13989
  0x04,  0x80,  0x18,  0xE4,  0xFD,  0x00,  0x04,  0x40,  0x1C,  0x1C,  0x9D,  0xF0,  0xEA,  0x09,  0x1C,  0x1C,
13990
  0x9D,  0xF0,  0xF0,  0x09,  0xC1,  0x10,  0x9E,  0xE7,  0x13,  0x00,  0x0A,  0x10,  0x9E,  0xE7,  0x41,  0x00,
13991
  0x04,  0x10,  0x9E,  0xE7,  0x24,  0x00,  0x00,  0xFC,  0xBE,  0x00,  0x98,  0x57,  0xD5,  0xF0,  0x8A,  0x02,
13992
  0x04,  0xE6,  0x04,  0x00,  0x06,  0x10,  0x04,  0xE6,  0x04,  0x00,  0x9D,  0x41,  0x1C,  0x42,  0x9F,  0xE7,
13993
  0x00,  0x00,  0x06,  0xF7,  0x02,  0x00,  0x03,  0xF6,  0xE0,  0x00,  0x3C,  0x14,  0x44,  0x58,  0x45,  0x58,
13994
  0x00,  0xF2,  0xF6,  0x0D,  0x00,  0xF2,  0x7E,  0x10,  0x00,  0xF2,  0xC6,  0x0F,  0x3C,  0x14,  0x1E,  0x1C,
13995
  0x00,  0xF0,  0x80,  0x01,  0x12,  0x1C,  0x22,  0x1C,  0xD2,  0x14,  0x00,  0xF0,  0x72,  0x01,  0x83,  0x59,
13996
  0x03,  0xDC,  0x73,  0x57,  0x80,  0x5D,  0x00,  0x16,  0x83,  0x59,  0x03,  0xDC,  0x38,  0x54,  0x70,  0x57,
13997
  0x33,  0x54,  0x3B,  0x54,  0x80,  0x5D,  0x00,  0x16,  0x03,  0x57,  0x83,  0x59,  0x38,  0x54,  0x00,  0xCC,
13998
  0x00,  0x16,  0x03,  0x57,  0x83,  0x59,  0x00,  0x4C,  0x00,  0x16,  0x02,  0x80,  0x48,  0xE4,  0x01,  0x00,
13999
  0x0E,  0x12,  0x48,  0xE4,  0x05,  0x00,  0x08,  0x12,  0x00,  0xF2,  0xBC,  0x11,  0x00,  0xF2,  0xC8,  0x11,
14000
  0xC1,  0x5A,  0x3A,  0x55,  0x02,  0xEC,  0xB5,  0x00,  0x45,  0x59,  0x00,  0xF2,  0xF6,  0x0D,  0x83,  0x58,
14001
  0x30,  0xE7,  0x00,  0x00,  0x10,  0x4D,  0x30,  0xE7,  0x40,  0x00,  0x10,  0x4F,  0x38,  0x90,  0xBA,  0x90,
14002
  0x10,  0x5C,  0x80,  0x5C,  0x83,  0x5A,  0x10,  0x4E,  0x04,  0xEA,  0xB5,  0x00,  0x43,  0x5B,  0x03,  0xF4,
14003
  0xE0,  0x00,  0x83,  0x59,  0x04,  0xCC,  0x01,  0x4A,  0x0A,  0x12,  0x45,  0x5A,  0x00,  0xF2,  0xF6,  0x0D,
14004
  0x00,  0xF2,  0x38,  0x10,  0x00,  0x16,  0x08,  0x1C,  0x00,  0xFC,  0xAC,  0x00,  0x06,  0x58,  0x67,  0x18,
14005
  0x18,  0xF4,  0x8F,  0xE1,  0x01,  0xFC,  0xAE,  0x00,  0x19,  0xF4,  0x70,  0x1E,  0xB0,  0x54,  0x07,  0x58,
14006
  0x00,  0xFC,  0xB0,  0x00,  0x08,  0x58,  0x00,  0xFC,  0xB2,  0x00,  0x09,  0x58,  0x0A,  0x1C,  0x00,  0xE6,
14007
  0x0F,  0x00,  0x00,  0xEA,  0xB9,  0x00,  0x38,  0x54,  0x00,  0xFA,  0x24,  0x01,  0x00,  0xFA,  0xB6,  0x00,
14008
  0x18,  0x1C,  0x14,  0x1C,  0x10,  0x1C,  0x32,  0x1C,  0x12,  0x1C,  0x00,  0x16,  0x3E,  0x57,  0x0C,  0x14,
14009
  0x0E,  0x47,  0x07,  0xE6,  0x10,  0x00,  0xCE,  0x47,  0xF5,  0x13,  0x00,  0x16,  0x00,  0xF2,  0xA2,  0x0D,
14010
  0x02,  0x4B,  0x03,  0xF6,  0xE0,  0x00,  0x00,  0xF2,  0x68,  0x0A,  0x01,  0x48,  0x20,  0x12,  0x44,  0x58,
14011
  0x45,  0x58,  0x9E,  0xE7,  0x15,  0x00,  0x9C,  0xE7,  0x04,  0x00,  0x00,  0xF2,  0xF6,  0x0D,  0x00,  0xF2,
14012
  0x7E,  0x10,  0x00,  0xF2,  0xC6,  0x0F,  0x00,  0xF2,  0x7A,  0x0A,  0x1E,  0x1C,  0xD5,  0x10,  0x00,  0x16,
14013
  0x69,  0x08,  0x48,  0xE4,  0x04,  0x00,  0x64,  0x12,  0x48,  0xE4,  0x02,  0x00,  0x20,  0x12,  0x48,  0xE4,
14014
  0x03,  0x00,  0x1A,  0x12,  0x48,  0xE4,  0x08,  0x00,  0x14,  0x12,  0x48,  0xE4,  0x01,  0x00,  0xF0,  0x12,
14015
  0x48,  0xE4,  0x07,  0x00,  0x12,  0x12,  0x01,  0xE6,  0x07,  0x00,  0x00,  0xF2,  0x4E,  0x0D,  0x00,  0xF2,
14016
  0x12,  0x11,  0x05,  0xF0,  0x60,  0x0B,  0x00,  0x16,  0x00,  0xE6,  0x01,  0x00,  0x00,  0xEA,  0x99,  0x00,
14017
  0x02,  0x80,  0x48,  0xE4,  0x03,  0x00,  0xE7,  0x12,  0x48,  0xE4,  0x06,  0x00,  0xE1,  0x12,  0x01,  0xE6,
14018
  0x06,  0x00,  0x00,  0xF2,  0x4E,  0x0D,  0x00,  0xF2,  0x12,  0x11,  0x04,  0xE6,  0x02,  0x00,  0x9E,  0xE7,
14019
  0x15,  0x00,  0x01,  0xF0,  0x1C,  0x0A,  0x00,  0xF0,  0x02,  0x0A,  0x00,  0x16,  0x02,  0x80,  0x48,  0xE4,
14020
  0x10,  0x00,  0x1C,  0x12,  0x82,  0xE7,  0x08,  0x00,  0x3C,  0x56,  0x03,  0x82,  0x00,  0xF2,  0xE2,  0x0D,
14021
  0x30,  0xE7,  0x08,  0x00,  0x04,  0xF7,  0x70,  0x01,  0x06,  0xF7,  0x02,  0x00,  0x00,  0xF0,  0x80,  0x01,
14022
  0x6C,  0x19,  0xED,  0x19,  0x5D,  0xF0,  0xD4,  0x0B,  0x44,  0x55,  0xE5,  0x55,  0x59,  0xF0,  0x52,  0x0C,
14023
  0x04,  0x55,  0xA5,  0x55,  0x1F,  0x80,  0x01,  0xEC,  0xB8,  0x00,  0x82,  0x48,  0x82,  0x80,  0x49,  0x44,
14024
  0x2E,  0x13,  0x01,  0xEC,  0xB8,  0x00,  0x41,  0xE4,  0x02,  0x00,  0x01,  0xEA,  0xB8,  0x00,  0x49,  0xE4,
14025
  0x11,  0x00,  0x59,  0xF0,  0x2E,  0x0C,  0x01,  0xE6,  0x17,  0x00,  0x01,  0xEA,  0xB8,  0x00,  0x02,  0x4B,
14026
  0x88,  0x90,  0xAC,  0x50,  0x8A,  0x90,  0xAE,  0x50,  0x01,  0xEC,  0xB8,  0x00,  0x82,  0x48,  0x82,  0x80,
14027
  0x10,  0x44,  0x02,  0x4B,  0x1F,  0x40,  0xC0,  0x44,  0x00,  0xF2,  0xB4,  0x0D,  0x04,  0x55,  0xA5,  0x55,
14028
  0x9F,  0x10,  0x0C,  0x51,  0x8E,  0x51,  0x30,  0x90,  0xB2,  0x90,  0x00,  0x56,  0xA1,  0x56,  0x30,  0x50,
14029
  0xB2,  0x50,  0x34,  0x90,  0xB6,  0x90,  0x40,  0x56,  0xE1,  0x56,  0x34,  0x50,  0xB6,  0x50,  0x65,  0x10,
14030
  0xB1,  0xF0,  0x70,  0x0C,  0x85,  0xF0,  0xCA,  0x0B,  0xE9,  0x09,  0x4B,  0xE4,  0x03,  0x00,  0x78,  0x12,
14031
  0x4B,  0xE4,  0x02,  0x00,  0x01,  0x13,  0xB1,  0xF0,  0x86,  0x0C,  0x85,  0xF0,  0xCA,  0x0B,  0x69,  0x08,
14032
  0x48,  0xE4,  0x03,  0x00,  0xD5,  0xF0,  0x86,  0x0B,  0x00,  0xF2,  0x12,  0x11,  0x85,  0xF0,  0xCA,  0x0B,
14033
  0xE8,  0x09,  0x3C,  0x56,  0x00,  0xFC,  0x20,  0x01,  0x98,  0x57,  0x02,  0x13,  0xBB,  0x45,  0x4B,  0xE4,
14034
  0x00,  0x00,  0x08,  0x12,  0x03,  0xE6,  0x01,  0x00,  0x04,  0xF6,  0x00,  0x80,  0xA8,  0x14,  0xD2,  0x14,
14035
  0x30,  0x1C,  0x02,  0x80,  0x48,  0xE4,  0x03,  0x00,  0x10,  0x13,  0x00,  0xFC,  0xB6,  0x00,  0x98,  0x57,
14036
  0x02,  0x13,  0x4C,  0x1C,  0x3E,  0x1C,  0x00,  0xF0,  0x8E,  0x0B,  0x00,  0xFC,  0x24,  0x01,  0xB0,  0x57,
14037
  0x00,  0xFA,  0x24,  0x01,  0x4C,  0x1C,  0x3E,  0x1C,  0x00,  0xF2,  0x12,  0x11,  0x86,  0xF0,  0x8E,  0x0B,
14038
  0x00,  0xF2,  0x8C,  0x0E,  0x00,  0xF0,  0x8E,  0x0B,  0xB1,  0xF0,  0xF8,  0x0C,  0x85,  0xF0,  0x86,  0x0B,
14039
  0x69,  0x08,  0x48,  0xE4,  0x01,  0x00,  0xD5,  0xF0,  0x86,  0x0B,  0xFC,  0x14,  0x42,  0x58,  0x6C,  0x14,
14040
  0x80,  0x14,  0x30,  0x1C,  0x4A,  0xF4,  0x02,  0x00,  0x55,  0xF0,  0x86,  0x0B,  0x4A,  0xF4,  0x01,  0x00,
14041
  0x0E,  0x12,  0x02,  0x80,  0x48,  0xE4,  0x03,  0x00,  0x06,  0x13,  0x3E,  0x1C,  0x00,  0xF0,  0x8E,  0x0B,
14042
  0x00,  0xFC,  0xB6,  0x00,  0xB0,  0x57,  0x00,  0xFA,  0xB6,  0x00,  0x4C,  0x1C,  0x3E,  0x1C,  0x00,  0xF2,
14043
  0x12,  0x11,  0x86,  0xF0,  0x8E,  0x0B,  0x00,  0xF2,  0xBA,  0x0E,  0x00,  0xF0,  0x8E,  0x0B,  0x4C,  0x1C,
14044
  0xB1,  0xF0,  0x50,  0x0D,  0x85,  0xF0,  0x5C,  0x0D,  0x69,  0x08,  0xF3,  0x10,  0x86,  0xF0,  0x64,  0x0D,
14045
  0x4E,  0x1C,  0x89,  0x48,  0x00,  0x16,  0x00,  0xF6,  0x00,  0x01,  0x00,  0x57,  0x00,  0x57,  0x03,  0x58,
14046
  0x00,  0xDC,  0x18,  0xF4,  0xFF,  0x7F,  0x30,  0x56,  0x00,  0x5C,  0x00,  0x16,  0x00,  0xF6,  0x00,  0x01,
14047
  0x00,  0x57,  0x00,  0x57,  0x03,  0x58,  0x00,  0xDC,  0x18,  0xF4,  0x00,  0x80,  0x30,  0x56,  0x00,  0x5C,
14048
  0x00,  0x16,  0x00,  0xF6,  0x00,  0x01,  0x00,  0x57,  0x00,  0x57,  0x03,  0x58,  0x00,  0xDC,  0x0B,  0x58,
14049
  0x00,  0x16,  0x03,  0xF6,  0x24,  0x01,  0x00,  0xF2,  0x58,  0x0A,  0x03,  0xF6,  0xB6,  0x00,  0x00,  0xF2,
14050
  0x58,  0x0A,  0x00,  0x16,  0x02,  0xEC,  0xB8,  0x00,  0x02,  0x49,  0x18,  0xF4,  0xFF,  0x00,  0x00,  0x54,
14051
  0x00,  0x54,  0x00,  0x54,  0x00,  0xF4,  0x08,  0x00,  0xE1,  0x18,  0x80,  0x54,  0x03,  0x58,  0x00,  0xDD,
14052
  0x01,  0xDD,  0x02,  0xDD,  0x03,  0xDC,  0x02,  0x4B,  0x30,  0x50,  0xB2,  0x50,  0x34,  0x51,  0xB6,  0x51,
14053
  0x00,  0x16,  0x45,  0x5A,  0x1D,  0xF4,  0xFF,  0x00,  0x85,  0x56,  0x85,  0x56,  0x85,  0x56,  0x05,  0xF4,
14054
  0x02,  0x12,  0x83,  0x5A,  0x00,  0x16,  0x1D,  0xF4,  0xFF,  0x00,  0x85,  0x56,  0x85,  0x56,  0x85,  0x56,
14055
  0x05,  0xF4,  0x00,  0x12,  0x83,  0x5A,  0x00,  0x16,  0x38,  0x54,  0xBB,  0x55,  0x3C,  0x56,  0xBD,  0x56,
14056
  0x00,  0xF2,  0x12,  0x11,  0x85,  0xF0,  0x82,  0x0E,  0xE9,  0x09,  0xC1,  0x59,  0x00,  0xF2,  0x12,  0x11,
14057
  0x85,  0xF0,  0x82,  0x0E,  0xE8,  0x0A,  0x83,  0x55,  0x83,  0x55,  0x4B,  0xF4,  0x90,  0x01,  0x5C,  0xF0,
14058
  0x36,  0x0E,  0xBD,  0x56,  0x40,  0x10,  0x4B,  0xF4,  0x30,  0x00,  0x59,  0xF0,  0x48,  0x0E,  0x01,  0xF6,
14059
  0x0C,  0x00,  0x00,  0xF6,  0x01,  0x00,  0x2E,  0x10,  0x02,  0xFC,  0x9C,  0x00,  0x9A,  0x57,  0x14,  0x13,
14060
  0x4B,  0xF4,  0x64,  0x00,  0x59,  0xF0,  0x64,  0x0E,  0x03,  0xF6,  0x64,  0x00,  0x01,  0xF6,  0x19,  0x00,
14061
  0x00,  0xF6,  0x01,  0x00,  0x43,  0xF4,  0x33,  0x00,  0x56,  0xF0,  0x76,  0x0E,  0x04,  0xF4,  0x00,  0x01,
14062
  0x43,  0xF4,  0x19,  0x00,  0xF3,  0x10,  0xB4,  0x56,  0xC3,  0x58,  0x02,  0xFC,  0x9E,  0x00,  0x9A,  0x57,
14063
  0x08,  0x13,  0x3C,  0x56,  0x00,  0xF6,  0x02,  0x00,  0x00,  0x16,  0x00,  0x16,  0x09,  0xE7,  0x01,  0x00,
14064
  0x00,  0xF2,  0x12,  0x11,  0x86,  0xF0,  0xB8,  0x0E,  0x09,  0xE7,  0x02,  0x00,  0x00,  0xF2,  0x12,  0x11,
14065
  0x86,  0xF0,  0xB8,  0x0E,  0x09,  0xE7,  0x03,  0x00,  0x00,  0xF2,  0x12,  0x11,  0x86,  0xF0,  0xB8,  0x0E,
14066
  0x4E,  0x1C,  0x89,  0x49,  0x00,  0xF2,  0x12,  0x11,  0x00,  0x16,  0x09,  0xE7,  0x01,  0x00,  0x00,  0xF2,
14067
  0x12,  0x11,  0x86,  0xF0,  0xF2,  0x0E,  0x09,  0xE7,  0x03,  0x00,  0x00,  0xF2,  0x12,  0x11,  0x86,  0xF0,
14068
  0xF2,  0x0E,  0x09,  0xE7,  0x01,  0x00,  0x00,  0xF2,  0x12,  0x11,  0x86,  0xF0,  0xF2,  0x0E,  0x89,  0x49,
14069
  0x00,  0xF2,  0x12,  0x11,  0x86,  0xF0,  0xF2,  0x0E,  0x4E,  0x1C,  0x89,  0x4A,  0x00,  0xF2,  0x12,  0x11,
14070
  0x00,  0x16,  0x3C,  0x56,  0x00,  0x16,  0x00,  0xEC,  0x26,  0x01,  0x48,  0xE4,  0x01,  0x00,  0x1E,  0x13,
14071
  0x38,  0x44,  0x00,  0xEA,  0x26,  0x01,  0x49,  0xF4,  0x00,  0x00,  0x04,  0x12,  0x4E,  0x1C,  0x02,  0x10,
14072
  0x4C,  0x1C,  0x01,  0xEC,  0x27,  0x01,  0x89,  0x48,  0x00,  0xF2,  0x12,  0x11,  0x02,  0x14,  0x00,  0x16,
14073
  0x85,  0xF0,  0x52,  0x0F,  0x38,  0x54,  0x00,  0xEA,  0x99,  0x00,  0x00,  0xF2,  0x60,  0x0B,  0x02,  0x80,
14074
  0x48,  0xE4,  0x06,  0x00,  0x1C,  0x13,  0x00,  0xEC,  0x99,  0x00,  0x48,  0xE4,  0x01,  0x00,  0x0A,  0x12,
14075
  0x04,  0x80,  0x30,  0xE4,  0x01,  0x00,  0x04,  0x40,  0x08,  0x10,  0x04,  0x80,  0x18,  0xE4,  0xFE,  0x00,
14076
  0x04,  0x40,  0x00,  0x16,  0x02,  0xF6,  0xE0,  0x00,  0x02,  0x57,  0x03,  0x59,  0x01,  0xCC,  0x81,  0x48,
14077
  0x22,  0x12,  0x00,  0x4E,  0x83,  0x5A,  0x90,  0x4C,  0x20,  0xE7,  0x00,  0x00,  0xC3,  0x58,  0x1B,  0xF4,
14078
  0xFF,  0x00,  0x83,  0x55,  0x83,  0x55,  0x83,  0x55,  0x03,  0xF4,  0x00,  0x12,  0x8B,  0x55,  0x83,  0x59,
14079
  0x00,  0x4E,  0x00,  0x16,  0x00,  0x4E,  0x02,  0xF6,  0xF0,  0x00,  0x02,  0x57,  0x03,  0x59,  0x00,  0x4E,
14080
  0x83,  0x5A,  0x30,  0xE7,  0x00,  0x00,  0x20,  0xE7,  0x00,  0x00,  0x00,  0x16,  0x02,  0xF6,  0xF0,  0x00,
14081
  0x02,  0x57,  0x03,  0x59,  0x01,  0xCC,  0x00,  0x4E,  0x83,  0x5A,  0x30,  0xE7,  0x00,  0x00,  0x80,  0x4C,
14082
  0xC3,  0x58,  0x1B,  0xF4,  0xFF,  0x00,  0x83,  0x55,  0x83,  0x55,  0x83,  0x55,  0x03,  0xF4,  0x00,  0x12,
14083
  0x83,  0x59,  0x00,  0x4E,  0x00,  0x16,  0x03,  0xF6,  0xE0,  0x00,  0x03,  0x57,  0x83,  0x59,  0x3A,  0x55,
14084
  0x02,  0xCC,  0x45,  0x5A,  0x00,  0xF2,  0xF6,  0x0D,  0xC0,  0x5A,  0x40,  0x5C,  0x38,  0x54,  0x00,  0xCD,
14085
  0x01,  0xCC,  0x4A,  0x46,  0x0A,  0x13,  0x83,  0x59,  0x00,  0x4C,  0x01,  0x48,  0x16,  0x13,  0x0C,  0x10,
14086
  0xC5,  0x58,  0x00,  0xF2,  0xF6,  0x0D,  0x00,  0x4C,  0x01,  0x48,  0x08,  0x13,  0x05,  0xF6,  0xF0,  0x00,
14087
  0x05,  0x57,  0x08,  0x10,  0x45,  0x58,  0x00,  0xF2,  0xF6,  0x0D,  0x8D,  0x56,  0x83,  0x5A,  0x80,  0x4C,
14088
  0x05,  0x17,  0x00,  0x16,  0x02,  0x4B,  0x06,  0xF7,  0x04,  0x00,  0x62,  0x0B,  0x03,  0x82,  0x00,  0xF2,
14089
  0xE2,  0x0D,  0x02,  0x80,  0x00,  0x4C,  0x45,  0xF4,  0x02,  0x00,  0x52,  0x14,  0x06,  0xF7,  0x02,  0x00,
14090
  0x06,  0x14,  0x00,  0xF2,  0x54,  0x0F,  0x00,  0x16,  0x02,  0x4B,  0x01,  0xF6,  0xFF,  0x00,  0x38,  0x1C,
14091
  0x05,  0xF4,  0x04,  0x00,  0x83,  0x5A,  0x18,  0xDF,  0x19,  0xDF,  0x1D,  0xF7,  0x3C,  0x00,  0xB8,  0xF0,
14092
  0x4E,  0x10,  0x9C,  0x14,  0x01,  0x48,  0x1C,  0x13,  0x0E,  0xF7,  0x3C,  0x00,  0x03,  0xF7,  0x04,  0x00,
14093
  0xAF,  0x19,  0x03,  0x42,  0x45,  0xF4,  0x02,  0x00,  0x83,  0x5A,  0x02,  0xCC,  0x02,  0x41,  0x45,  0xF4,
14094
  0x02,  0x00,  0x00,  0x16,  0x91,  0x44,  0xD5,  0xF0,  0x3E,  0x10,  0x00,  0xF0,  0x9E,  0x02,  0x01,  0xF6,
14095
  0xFF,  0x00,  0x38,  0x1C,  0x05,  0xF4,  0x04,  0x00,  0x83,  0x5A,  0x18,  0xDF,  0x19,  0xDF,  0x0E,  0xF7,
14096
  0x3C,  0x00,  0x03,  0xF7,  0x04,  0x00,  0x0F,  0x79,  0x1C,  0xF7,  0x3C,  0x00,  0xB8,  0xF0,  0x9C,  0x10,
14097
  0x4E,  0x14,  0x01,  0x48,  0x06,  0x13,  0x45,  0xF4,  0x04,  0x00,  0x00,  0x16,  0x91,  0x44,  0xD5,  0xF0,
14098
  0x82,  0x10,  0x00,  0xF0,  0x9E,  0x02,  0x02,  0xF6,  0xFF,  0x00,  0x38,  0x1C,  0x2C,  0xBC,  0xAE,  0xBC,
14099
  0xE2,  0x08,  0x00,  0xEC,  0xB8,  0x00,  0x02,  0x48,  0x1D,  0xF7,  0x80,  0x00,  0xB8,  0xF0,  0xCC,  0x10,
14100
  0x1E,  0x14,  0x01,  0x48,  0x0E,  0x13,  0x0E,  0xF7,  0x80,  0x00,  0x38,  0x54,  0x03,  0x58,  0xAF,  0x19,
14101
  0x82,  0x48,  0x00,  0x16,  0x82,  0x48,  0x12,  0x45,  0xD5,  0xF0,  0xBA,  0x10,  0x00,  0xF0,  0x9E,  0x02,
14102
  0x39,  0xF0,  0xF8,  0x10,  0x38,  0x44,  0x00,  0x16,  0x7E,  0x18,  0x18,  0xF4,  0x03,  0x00,  0x04,  0x13,
14103
  0x61,  0x18,  0x00,  0x16,  0x38,  0x1C,  0x00,  0xFC,  0x22,  0x01,  0x18,  0xF4,  0x01,  0x00,  0xF1,  0x12,
14104
  0xE3,  0x10,  0x30,  0x44,  0x30,  0x44,  0x30,  0x44,  0xB1,  0xF0,  0x18,  0x11,  0x00,  0x16,  0x3E,  0x57,
14105
  0x03,  0xF6,  0xE0,  0x00,  0x03,  0x57,  0x83,  0x59,  0x04,  0xCC,  0x01,  0x4A,  0x6A,  0x12,  0x45,  0x5A,
14106
  0x00,  0xF2,  0xF6,  0x0D,  0x02,  0x4B,  0x70,  0x14,  0x34,  0x13,  0x02,  0x80,  0x48,  0xE4,  0x08,  0x00,
14107
  0x18,  0x12,  0x9C,  0xE7,  0x02,  0x00,  0x9E,  0xE7,  0x15,  0x00,  0x00,  0xF2,  0xC6,  0x0F,  0x00,  0xF2,
14108
  0x7A,  0x0A,  0x1E,  0x1C,  0x01,  0xF6,  0x01,  0x00,  0x00,  0x16,  0x30,  0xE4,  0x10,  0x00,  0x04,  0x40,
14109
  0x00,  0xF2,  0xE2,  0x0D,  0x20,  0xE7,  0x01,  0x00,  0x01,  0xF6,  0x01,  0x00,  0x00,  0x16,  0x04,  0xDC,
14110
  0x01,  0x4A,  0x24,  0x12,  0x45,  0x5A,  0x00,  0xF2,  0xF6,  0x0D,  0x43,  0x5B,  0x06,  0xEC,  0x98,  0x00,
14111
  0x00,  0xF2,  0x38,  0x10,  0xC6,  0x59,  0x20,  0x14,  0x0A,  0x13,  0x00,  0xF2,  0xC6,  0x0F,  0x00,  0xF2,
14112
  0x14,  0x10,  0xA7,  0x10,  0x83,  0x5A,  0xD7,  0x10,  0x0E,  0x47,  0x07,  0xE6,  0x10,  0x00,  0xCE,  0x47,
14113
  0x5A,  0xF0,  0x20,  0x11,  0xB9,  0x54,  0x00,  0x16,  0x14,  0x90,  0x96,  0x90,  0x02,  0xFC,  0xA8,  0x00,
14114
  0x03,  0xFC,  0xAA,  0x00,  0x48,  0x55,  0x02,  0x13,  0xC9,  0x55,  0x00,  0x16,  0x00,  0xEC,  0xBA,  0x00,
14115
  0x10,  0x44,  0x00,  0xEA,  0xBA,  0x00,  0x00,  0x16,  0x03,  0xF6,  0xC0,  0x00,  0x00,  0xF2,  0x68,  0x0A,
14116
  0x10,  0x44,  0x00,  0x4C,  0x00,  0x16
14117
};
14118
 
14119
unsigned short _adv_mcode_size ASC_INITDATA =
14120
    sizeof(_adv_mcode_buf); /* 0x11D6 */
14121
unsigned long  _adv_mcode_chksum ASC_INITDATA = 0x03494981UL;
14122
 
14123
/* a_init.c */
14124
/*
14125
 * EEPROM Configuration.
14126
 *
14127
 * All drivers should use this structure to set the default EEPROM
14128
 * configuration. The BIOS now uses this structure when it is built.
14129
 * Additional structure information can be found in a_condor.h where
14130
 * the structure is defined.
14131
 */
14132
STATIC ADVEEP_CONFIG
14133
Default_EEPROM_Config ASC_INITDATA = {
14134
    ADV_EEPROM_BIOS_ENABLE,     /* cfg_msw */
14135
    0x0000,                     /* cfg_lsw */
14136
    0xFFFF,                     /* disc_enable */
14137
    0xFFFF,                     /* wdtr_able */
14138
    0xFFFF,                     /* sdtr_able */
14139
    0xFFFF,                     /* start_motor */
14140
    0xFFFF,                     /* tagqng_able */
14141
    0xFFFF,                     /* bios_scan */
14142
    0,                          /* scam_tolerant */
14143
    7,                          /* adapter_scsi_id */
14144
    0,                          /* bios_boot_delay */
14145
    3,                          /* scsi_reset_delay */
14146
    0,                          /* bios_id_lun */
14147
    0,                          /* termination */
14148
    0,                          /* reserved1 */
14149
    0xFFEF,                     /* bios_ctrl */
14150
    0xFFFF,                     /* ultra_able */
14151
    0,                          /* reserved2 */
14152
    ASC_DEF_MAX_HOST_QNG,       /* max_host_qng */
14153
    ASC_DEF_MAX_DVC_QNG,        /* max_dvc_qng */
14154
    0,                          /* dvc_cntl */
14155
    0,                          /* bug_fix */
14156
    0,                          /* serial_number_word1 */
14157
    0,                          /* serial_number_word2 */
14158
    0,                          /* serial_number_word3 */
14159
    0,                          /* check_sum */
14160
    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, /* oem_name[16] */
14161
    0,                          /* dvc_err_code */
14162
    0,                          /* adv_err_code */
14163
    0,                          /* adv_err_addr */
14164
    0,                          /* saved_dvc_err_code */
14165
    0,                          /* saved_adv_err_code */
14166
    0,                          /* saved_adv_err_addr */
14167
 
14168
};
14169
 
14170
/*
14171
 * Initialize the ADV_DVC_VAR structure.
14172
 *
14173
 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
14174
 *
14175
 * For a non-fatal error return a warning code. If there are no warnings
14176
 * then 0 is returned.
14177
 */
14178
ASC_INITFUNC(
14179
int
14180
AdvInitGetConfig(ADV_DVC_VAR *asc_dvc)
14181
)
14182
{
14183
    ushort      warn_code;
14184
    AdvPortAddr iop_base;
14185
    uchar       pci_cmd_reg;
14186
    int         status;
14187
 
14188
    warn_code = 0;
14189
    asc_dvc->err_code = 0;
14190
    iop_base = asc_dvc->iop_base;
14191
 
14192
    /*
14193
     * PCI Command Register
14194
     */
14195
 
14196
    if (((pci_cmd_reg = DvcAdvReadPCIConfigByte(asc_dvc,
14197
                            AscPCIConfigCommandRegister))
14198
         & AscPCICmdRegBits_BusMastering)
14199
        != AscPCICmdRegBits_BusMastering)
14200
    {
14201
        pci_cmd_reg |= AscPCICmdRegBits_BusMastering;
14202
 
14203
        DvcAdvWritePCIConfigByte(asc_dvc,
14204
                AscPCIConfigCommandRegister, pci_cmd_reg);
14205
 
14206
        if (((DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigCommandRegister))
14207
             & AscPCICmdRegBits_BusMastering)
14208
            != AscPCICmdRegBits_BusMastering)
14209
        {
14210
            warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
14211
        }
14212
    }
14213
 
14214
    /*
14215
     * PCI Latency Timer
14216
     *
14217
     * If the "latency timer" register is 0x20 or above, then we don't need
14218
     * to change it.  Otherwise, set it to 0x20 (i.e. set it to 0x20 if it
14219
     * comes up less than 0x20).
14220
     */
14221
    if (DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer) < 0x20) {
14222
        DvcAdvWritePCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer, 0x20);
14223
        if (DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer) < 0x20)
14224
        {
14225
            warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
14226
        }
14227
    }
14228
 
14229
    /*
14230
     * Save the state of the PCI Configuration Command Register
14231
     * "Parity Error Response Control" Bit. If the bit is clear (0),
14232
     * in AdvInitAsc3550Driver() tell the microcode to ignore DMA
14233
     * parity errors.
14234
     */
14235
    asc_dvc->cfg->control_flag = 0;
14236
    if (((DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigCommandRegister)
14237
         & AscPCICmdRegBits_ParErrRespCtrl)) == 0)
14238
    {
14239
        asc_dvc->cfg->control_flag |= CONTROL_FLAG_IGNORE_PERR;
14240
    }
14241
 
14242
    asc_dvc->cur_host_qng = 0;
14243
 
14244
    asc_dvc->cfg->lib_version = (ADV_LIB_VERSION_MAJOR << 8) |
14245
      ADV_LIB_VERSION_MINOR;
14246
    asc_dvc->cfg->chip_version =
14247
      AdvGetChipVersion(iop_base, asc_dvc->bus_type);
14248
 
14249
    /*
14250
     * Reset the chip to start and allow register writes.
14251
     */
14252
    if (AdvFindSignature(iop_base) == 0)
14253
    {
14254
        asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
14255
        return ADV_ERROR;
14256
    }
14257
    else {
14258
 
14259
        AdvResetChip(asc_dvc);
14260
 
14261
        if ((status = AdvInitFromEEP(asc_dvc)) == ADV_ERROR)
14262
        {
14263
            return ADV_ERROR;
14264
        }
14265
        warn_code |= status;
14266
 
14267
        /*
14268
         * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
14269
         * Resets should be performed.
14270
         */
14271
        if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS)
14272
        {
14273
            AdvResetSCSIBus(asc_dvc);
14274
        }
14275
    }
14276
 
14277
    return warn_code;
14278
}
14279
 
14280
/*
14281
 * Initialize the ASC3550.
14282
 *
14283
 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
14284
 *
14285
 * For a non-fatal error return a warning code. If there are no warnings
14286
 * then 0 is returned.
14287
 */
14288
ASC_INITFUNC(
14289
int
14290
AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
14291
)
14292
{
14293
    AdvPortAddr iop_base;
14294
    ushort      warn_code;
14295
    ulong       sum;
14296
    int         begin_addr;
14297
    int         end_addr;
14298
    int         code_sum;
14299
    int         word;
14300
    int         rql_addr;                   /* RISC Queue List address */
14301
    int         i;
14302
    ushort      scsi_cfg1;
14303
    uchar       biosmem[ASC_MC_BIOSLEN];    /* BIOS RISC Memory 0x40-0x8F. */
14304
 
14305
    /* If there is already an error, don't continue. */
14306
    if (asc_dvc->err_code != 0)
14307
    {
14308
        return ADV_ERROR;
14309
    }
14310
 
14311
    warn_code = 0;
14312
    iop_base = asc_dvc->iop_base;
14313
 
14314
    /*
14315
     * Save the RISC memory BIOS region before writing the microcode.
14316
     * The BIOS may already be loaded and using its RISC LRAM region
14317
     * so its region must be saved and restored.
14318
     *
14319
     * Note: This code makes the assumption, which is currently true,
14320
     * that a chip reset does not clear RISC LRAM.
14321
     */
14322
    for (i = 0; i < ASC_MC_BIOSLEN; i++)
14323
    {
14324
        AdvReadByteLram(iop_base, ASC_MC_BIOSMEM + i, biosmem[i]);
14325
    }
14326
 
14327
    /*
14328
     * Load the Microcode
14329
     *
14330
     * Write the microcode image to RISC memory starting at address 0.
14331
     */
14332
    AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
14333
    for (word = 0; word < _adv_mcode_size; word += 2)
14334
    {
14335
        AdvWriteWordAutoIncLram(iop_base,
14336
            *((ushort *) (&_adv_mcode_buf[word])));
14337
    }
14338
 
14339
    /*
14340
     * Clear the rest of Condor's Internal RAM (8KB).
14341
     */
14342
    for (; word < ADV_CONDOR_MEMSIZE; word += 2)
14343
    {
14344
        AdvWriteWordAutoIncLram(iop_base, 0);
14345
    }
14346
 
14347
    /*
14348
     * Verify the microcode checksum.
14349
     */
14350
    sum = 0;
14351
    AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
14352
    for (word = 0; word < _adv_mcode_size; word += 2)
14353
    {
14354
        sum += AdvReadWordAutoIncLram(iop_base);
14355
    }
14356
 
14357
    if (sum != _adv_mcode_chksum)
14358
    {
14359
        asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
14360
        return ADV_ERROR;
14361
    }
14362
 
14363
    /*
14364
     * Restore the RISC memory BIOS region.
14365
     */
14366
    for (i = 0; i < ASC_MC_BIOSLEN; i++)
14367
    {
14368
        AdvWriteByteLram(iop_base, ASC_MC_BIOSMEM + i, biosmem[i]);
14369
    }
14370
 
14371
    /*
14372
     * Calculate and write the microcode code checksum to the microcode
14373
     * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
14374
     */
14375
    AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
14376
    AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
14377
    code_sum = 0;
14378
    for (word = begin_addr; word < end_addr; word += 2)
14379
    {
14380
        code_sum += *((ushort *) (&_adv_mcode_buf[word]));
14381
    }
14382
    AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
14383
 
14384
    /*
14385
     * Read microcode version and date.
14386
     */
14387
    AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE, asc_dvc->cfg->mcode_date);
14388
    AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM, asc_dvc->cfg->mcode_version);
14389
 
14390
    /*
14391
     * Initialize microcode operating variables
14392
     */
14393
    AdvWriteWordLram(iop_base, ASC_MC_ADAPTER_SCSI_ID,
14394
                       asc_dvc->chip_scsi_id);
14395
 
14396
    /*
14397
     * If the PCI Configuration Command Register "Parity Error Response
14398
     * Control" Bit was clear (0), then set the microcode variable
14399
     * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
14400
     * to ignore DMA parity errors.
14401
     */
14402
    if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR)
14403
    {
14404
        /*
14405
         * Note: Don't remove the use of a temporary variable in
14406
         * the following code, otherwise the Microsoft C compiler
14407
         * will turn the following lines into a no-op.
14408
         */
14409
        AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
14410
        word |= CONTROL_FLAG_IGNORE_PERR;
14411
        AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
14412
    }
14413
 
14414
    /*
14415
     * Set default microcode operating variables for WDTR, SDTR, and
14416
     * command tag queuing based on the EEPROM configuration values.
14417
     *
14418
     * These ADV_DVC_VAR fields and the microcode variables will be
14419
     * changed in AdvInquiryHandling() if it is found a device is
14420
     * incapable of a particular feature.
14421
     */
14422
 
14423
    /*
14424
     * Set the microcode ULTRA target mask from EEPROM value. The
14425
     * SDTR target mask overrides the ULTRA target mask in the
14426
     * microcode so it is safe to set this value without determining
14427
     * whether the device supports SDTR.
14428
     *
14429
     * Note: There is no way to know whether a device supports ULTRA
14430
     * speed without attempting a SDTR ULTRA speed negotiation with
14431
     * the device. The device will reject the speed if it does not
14432
     * support it by responding with an SDTR message containing a
14433
     * slower speed.
14434
     */
14435
    AdvWriteWordLram(iop_base, ASC_MC_ULTRA_ABLE, asc_dvc->ultra_able);
14436
    AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE, asc_dvc->cfg->disc_enable);
14437
 
14438
 
14439
    /*
14440
     * Set SCSI_CFG0 Microcode Default Value.
14441
     *
14442
     * The microcode will set the SCSI_CFG0 register using this value
14443
     * after it is started below.
14444
     */
14445
    AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
14446
        PARITY_EN | SEL_TMO_LONG | OUR_ID_EN | asc_dvc->chip_scsi_id);
14447
 
14448
    /*
14449
     * Determine SCSI_CFG1 Microcode Default Value.
14450
     *
14451
     * The microcode will set the SCSI_CFG1 register using this value
14452
     * after it is started below.
14453
     */
14454
 
14455
    /* Read current SCSI_CFG1 Register value. */
14456
    scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
14457
 
14458
    /*
14459
     * If all three connectors are in use, return an error.
14460
     */
14461
    if ((scsi_cfg1 & CABLE_ILLEGAL_A) == 0 ||
14462
        (scsi_cfg1 & CABLE_ILLEGAL_B) == 0)
14463
    {
14464
        asc_dvc->err_code |= ASC_IERR_ILLEGAL_CONNECTION;
14465
        return ADV_ERROR;
14466
    }
14467
 
14468
    /*
14469
     * If the internal narrow cable is reversed all of the SCSI_CTRL
14470
     * register signals will be set. Check for and return an error if
14471
     * this condition is found.
14472
     */
14473
    if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07)
14474
    {
14475
        asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
14476
        return ADV_ERROR;
14477
    }
14478
 
14479
    /*
14480
     * If this is a differential board and a single-ended device
14481
     * is attached to one of the connectors, return an error.
14482
     */
14483
    if ((scsi_cfg1 & DIFF_MODE) && (scsi_cfg1 & DIFF_SENSE) == 0)
14484
    {
14485
        asc_dvc->err_code |= ASC_IERR_SINGLE_END_DEVICE;
14486
        return ADV_ERROR;
14487
    }
14488
 
14489
    /*
14490
     * If automatic termination control is enabled, then set the
14491
     * termination value based on a table listed in a_condor.h.
14492
     *
14493
     * If manual termination was specified with an EEPROM setting
14494
     * then 'termination' was set-up in AdvInitFromEEP() and
14495
     * is ready to be 'ored' into SCSI_CFG1.
14496
     */
14497
    if (asc_dvc->cfg->termination == 0)
14498
    {
14499
        /*
14500
         * The software always controls termination by setting TERM_CTL_SEL.
14501
         * If TERM_CTL_SEL were set to 0, the hardware would set termination.
14502
         */
14503
        asc_dvc->cfg->termination |= TERM_CTL_SEL;
14504
 
14505
        switch(scsi_cfg1 & CABLE_DETECT)
14506
        {
14507
            /* TERM_CTL_H: on, TERM_CTL_L: on */
14508
            case 0x3: case 0x7: case 0xB: case 0xD: case 0xE: case 0xF:
14509
                asc_dvc->cfg->termination |= (TERM_CTL_H | TERM_CTL_L);
14510
                break;
14511
 
14512
            /* TERM_CTL_H: on, TERM_CTL_L: off */
14513
            case 0x1: case 0x5: case 0x9: case 0xA: case 0xC:
14514
                asc_dvc->cfg->termination |= TERM_CTL_H;
14515
                break;
14516
 
14517
            /* TERM_CTL_H: off, TERM_CTL_L: off */
14518
            case 0x2: case 0x6:
14519
                break;
14520
        }
14521
    }
14522
 
14523
    /*
14524
     * Clear any set TERM_CTL_H and TERM_CTL_L bits.
14525
     */
14526
    scsi_cfg1 &= ~TERM_CTL;
14527
 
14528
    /*
14529
     * Invert the TERM_CTL_H and TERM_CTL_L bits and then
14530
     * set 'scsi_cfg1'. The TERM_POL bit does not need to be
14531
     * referenced, because the hardware internally inverts
14532
     * the Termination High and Low bits if TERM_POL is set.
14533
     */
14534
    scsi_cfg1 |= (TERM_CTL_SEL | (~asc_dvc->cfg->termination & TERM_CTL));
14535
 
14536
    /*
14537
     * Set SCSI_CFG1 Microcode Default Value
14538
     *
14539
     * Set filter value and possibly modified termination control
14540
     * bits in the Microcode SCSI_CFG1 Register Value.
14541
     *
14542
     * The microcode will set the SCSI_CFG1 register using this value
14543
     * after it is started below.
14544
     */
14545
    AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1,
14546
                       FLTR_11_TO_20NS | scsi_cfg1);
14547
 
14548
    /*
14549
     * Set SEL_MASK Microcode Default Value
14550
     *
14551
     * The microcode will set the SEL_MASK register using this value
14552
     * after it is started below.
14553
     */
14554
    AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
14555
                        ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
14556
 
14557
    /*
14558
     * Link all the RISC Queue Lists together in a doubly-linked
14559
     * NULL terminated list.
14560
     *
14561
     * Skip the NULL (0) queue which is not used.
14562
     */
14563
    for (i = 1, rql_addr = ASC_MC_RISC_Q_LIST_BASE + ASC_MC_RISC_Q_LIST_SIZE;
14564
         i < ASC_MC_RISC_Q_TOTAL_CNT;
14565
         i++, rql_addr += ASC_MC_RISC_Q_LIST_SIZE)
14566
    {
14567
        /*
14568
         * Set the current RISC Queue List's RQL_FWD and RQL_BWD pointers
14569
         * in a one word write and set the state (RQL_STATE) to free.
14570
         */
14571
        AdvWriteWordLram(iop_base, rql_addr, ((i + 1) + ((i - 1) << 8)));
14572
        AdvWriteByteLram(iop_base, rql_addr + RQL_STATE, ASC_MC_QS_FREE);
14573
    }
14574
 
14575
    /*
14576
     * Set the Host and RISC Queue List pointers.
14577
     *
14578
     * Both sets of pointers are initialized with the same values:
14579
     * ASC_MC_RISC_Q_FIRST(0x01) and ASC_MC_RISC_Q_LAST (0xFF).
14580
     */
14581
    AdvWriteByteLram(iop_base, ASC_MC_HOST_NEXT_READY, ASC_MC_RISC_Q_FIRST);
14582
    AdvWriteByteLram(iop_base, ASC_MC_HOST_NEXT_DONE, ASC_MC_RISC_Q_LAST);
14583
 
14584
    AdvWriteByteLram(iop_base, ASC_MC_RISC_NEXT_READY, ASC_MC_RISC_Q_FIRST);
14585
    AdvWriteByteLram(iop_base, ASC_MC_RISC_NEXT_DONE, ASC_MC_RISC_Q_LAST);
14586
 
14587
    /*
14588
     * Finally, set up the last RISC Queue List (255) with
14589
     * a NULL forward pointer.
14590
     */
14591
    AdvWriteWordLram(iop_base, rql_addr, (ASC_MC_NULL_Q + ((i - 1) << 8)));
14592
    AdvWriteByteLram(iop_base, rql_addr + RQL_STATE, ASC_MC_QS_FREE);
14593
 
14594
    AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
14595
         (ADV_INTR_ENABLE_HOST_INTR | ADV_INTR_ENABLE_GLOBAL_INTR));
14596
 
14597
    /*
14598
     * Note: Don't remove the use of a temporary variable in
14599
     * the following code, otherwise the Microsoft C compiler
14600
     * will turn the following lines into a no-op.
14601
     */
14602
    AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
14603
    AdvWriteWordRegister(iop_base, IOPW_PC, word);
14604
 
14605
    /* finally, finally, gentlemen, start your engine */
14606
    AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
14607
 
14608
    return warn_code;
14609
}
14610
 
14611
/*
14612
 * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
14613
 * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
14614
 * all of this is done.
14615
 *
14616
 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
14617
 *
14618
 * For a non-fatal error return a warning code. If there are no warnings
14619
 * then 0 is returned.
14620
 *
14621
 * Note: Chip is stopped on entry.
14622
 */
14623
ASC_INITFUNC(
14624
STATIC int
14625
AdvInitFromEEP(ADV_DVC_VAR *asc_dvc)
14626
)
14627
{
14628
    AdvPortAddr         iop_base;
14629
    ushort              warn_code;
14630
    ADVEEP_CONFIG       eep_config;
14631
    int                 i;
14632
 
14633
    iop_base = asc_dvc->iop_base;
14634
 
14635
    warn_code = 0;
14636
 
14637
    /*
14638
     * Read the board's EEPROM configuration.
14639
     *
14640
     * Set default values if a bad checksum is found.
14641
     */
14642
    if (AdvGetEEPConfig(iop_base, &eep_config) != eep_config.check_sum)
14643
    {
14644
        warn_code |= ASC_WARN_EEPROM_CHKSUM;
14645
 
14646
        /*
14647
         * Set EEPROM default values.
14648
         */
14649
        for (i = 0; i < sizeof(ADVEEP_CONFIG); i++)
14650
        {
14651
            *((uchar *) &eep_config + i) =
14652
                *((uchar *) &Default_EEPROM_Config + i);
14653
        }
14654
 
14655
        /*
14656
         * Assume the 6 byte board serial number that was read
14657
         * from EEPROM is correct even if the EEPROM checksum
14658
         * failed.
14659
         */
14660
        eep_config.serial_number_word3 =
14661
            AdvReadEEPWord(iop_base, ASC_EEP_DVC_CFG_END - 1);
14662
        eep_config.serial_number_word2 =
14663
            AdvReadEEPWord(iop_base, ASC_EEP_DVC_CFG_END - 2);
14664
        eep_config.serial_number_word1 =
14665
            AdvReadEEPWord(iop_base, ASC_EEP_DVC_CFG_END - 3);
14666
        AdvSetEEPConfig(iop_base, &eep_config);
14667
    }
14668
 
14669
    /*
14670
     * Set ADV_DVC_VAR and ADV_DVC_CFG variables from the
14671
     * EEPROM configuration that was read.
14672
     *
14673
     * This is the mapping of EEPROM fields to Adv Library fields.
14674
     */
14675
    asc_dvc->wdtr_able = eep_config.wdtr_able;
14676
    asc_dvc->sdtr_able = eep_config.sdtr_able;
14677
    asc_dvc->ultra_able = eep_config.ultra_able;
14678
    asc_dvc->tagqng_able = eep_config.tagqng_able;
14679
    asc_dvc->cfg->disc_enable = eep_config.disc_enable;
14680
    asc_dvc->max_host_qng = eep_config.max_host_qng;
14681
    asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
14682
    asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
14683
    asc_dvc->start_motor = eep_config.start_motor;
14684
    asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
14685
    asc_dvc->cfg->bios_boot_wait = eep_config.bios_boot_delay;
14686
    asc_dvc->bios_ctrl = eep_config.bios_ctrl;
14687
    asc_dvc->no_scam = eep_config.scam_tolerant;
14688
    asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
14689
    asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
14690
    asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
14691
 
14692
    /*
14693
     * Set the host maximum queuing (max. 253, min. 16) and the per device
14694
     * maximum queuing (max. 63, min. 4).
14695
     */
14696
    if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG)
14697
    {
14698
        eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
14699
    } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG)
14700
    {
14701
        /* If the value is zero, assume it is uninitialized. */
14702
        if (eep_config.max_host_qng == 0)
14703
        {
14704
            eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
14705
        } else
14706
        {
14707
            eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
14708
        }
14709
    }
14710
 
14711
    if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG)
14712
    {
14713
        eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
14714
    } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG)
14715
    {
14716
        /* If the value is zero, assume it is uninitialized. */
14717
        if (eep_config.max_dvc_qng == 0)
14718
        {
14719
            eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
14720
        } else
14721
        {
14722
            eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
14723
        }
14724
    }
14725
 
14726
    /*
14727
     * If 'max_dvc_qng' is greater than 'max_host_qng', then
14728
     * set 'max_dvc_qng' to 'max_host_qng'.
14729
     */
14730
    if (eep_config.max_dvc_qng > eep_config.max_host_qng)
14731
    {
14732
        eep_config.max_dvc_qng = eep_config.max_host_qng;
14733
    }
14734
 
14735
    /*
14736
     * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_CFG 'max_dvc_qng'
14737
     * values based on possibly adjusted EEPROM values.
14738
     */
14739
    asc_dvc->max_host_qng = eep_config.max_host_qng;
14740
    asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
14741
 
14742
 
14743
    /*
14744
     * If the EEPROM 'termination' field is set to automatic (0), then set
14745
     * the ADV_DVC_CFG 'termination' field to automatic also.
14746
     *
14747
     * If the termination is specified with a non-zero 'termination'
14748
     * value check that a legal value is set and set the ADV_DVC_CFG
14749
     * 'termination' field appropriately.
14750
     */
14751
    if (eep_config.termination == 0)
14752
    {
14753
        asc_dvc->cfg->termination = 0;    /* auto termination */
14754
    } else
14755
    {
14756
        /* Enable manual control with low off / high off. */
14757
        if (eep_config.termination == 1)
14758
        {
14759
            asc_dvc->cfg->termination = TERM_CTL_SEL;
14760
 
14761
        /* Enable manual control with low off / high on. */
14762
        } else if (eep_config.termination == 2)
14763
        {
14764
            asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H;
14765
 
14766
        /* Enable manual control with low on / high on. */
14767
        } else if (eep_config.termination == 3)
14768
        {
14769
            asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H | TERM_CTL_L;
14770
        } else
14771
        {
14772
            /*
14773
             * The EEPROM 'termination' field contains a bad value. Use
14774
             * automatic termination instead.
14775
             */
14776
            asc_dvc->cfg->termination = 0;
14777
            warn_code |= ASC_WARN_EEPROM_TERMINATION;
14778
        }
14779
    }
14780
 
14781
    return warn_code;
14782
}
14783
 
14784
/*
14785
 * Read EEPROM configuration into the specified buffer.
14786
 *
14787
 * Return a checksum based on the EEPROM configuration read.
14788
 */
14789
ASC_INITFUNC(
14790
STATIC ushort
14791
AdvGetEEPConfig(AdvPortAddr iop_base, ADVEEP_CONFIG *cfg_buf)
14792
)
14793
{
14794
    ushort              wval, chksum;
14795
    ushort              *wbuf;
14796
    int                 eep_addr;
14797
 
14798
    wbuf = (ushort *) cfg_buf;
14799
    chksum = 0;
14800
 
14801
    for (eep_addr = ASC_EEP_DVC_CFG_BEGIN;
14802
         eep_addr < ASC_EEP_DVC_CFG_END;
14803
         eep_addr++, wbuf++)
14804
    {
14805
        wval = AdvReadEEPWord(iop_base, eep_addr);
14806
        chksum += wval;
14807
        *wbuf = wval;
14808
    }
14809
    *wbuf = AdvReadEEPWord(iop_base, eep_addr);
14810
    wbuf++;
14811
    for (eep_addr = ASC_EEP_DVC_CTL_BEGIN;
14812
         eep_addr < ASC_EEP_MAX_WORD_ADDR;
14813
         eep_addr++, wbuf++)
14814
    {
14815
        *wbuf = AdvReadEEPWord(iop_base, eep_addr);
14816
    }
14817
    return chksum;
14818
}
14819
 
14820
/*
14821
 * Read the EEPROM from specified location
14822
 */
14823
ASC_INITFUNC(
14824
STATIC ushort
14825
AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr)
14826
)
14827
{
14828
    AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
14829
        ASC_EEP_CMD_READ | eep_word_addr);
14830
    AdvWaitEEPCmd(iop_base);
14831
    return AdvReadWordRegister(iop_base, IOPW_EE_DATA);
14832
}
14833
 
14834
/*
14835
 * Wait for EEPROM command to complete
14836
 */
14837
ASC_INITFUNC(
14838
STATIC void
14839
AdvWaitEEPCmd(AdvPortAddr iop_base)
14840
)
14841
{
14842
    int eep_delay_ms;
14843
 
14844
    for (eep_delay_ms = 0; eep_delay_ms < ASC_EEP_DELAY_MS; eep_delay_ms++)
14845
    {
14846
        if (AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE)
14847
        {
14848
            break;
14849
        }
14850
        DvcSleepMilliSecond(1);
14851
    }
14852
    if ((AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE) == 0)
14853
    {
14854
        ADV_ASSERT(0);
14855
    }
14856
    return;
14857
}
14858
 
14859
/*
14860
 * Write the EEPROM from 'cfg_buf'.
14861
 */
14862
ASC_INITFUNC(
14863
STATIC void
14864
AdvSetEEPConfig(AdvPortAddr iop_base, ADVEEP_CONFIG *cfg_buf)
14865
)
14866
{
14867
    ushort       *wbuf;
14868
    ushort       addr, chksum;
14869
 
14870
    wbuf = (ushort *) cfg_buf;
14871
    chksum = 0;
14872
 
14873
    AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
14874
    AdvWaitEEPCmd(iop_base);
14875
 
14876
    /*
14877
     * Write EEPROM from word 0 to word 15
14878
     */
14879
    for (addr = ASC_EEP_DVC_CFG_BEGIN;
14880
         addr < ASC_EEP_DVC_CFG_END; addr++, wbuf++)
14881
    {
14882
        chksum += *wbuf;
14883
        AdvWriteWordRegister(iop_base, IOPW_EE_DATA, *wbuf);
14884
        AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
14885
        AdvWaitEEPCmd(iop_base);
14886
        DvcSleepMilliSecond(ASC_EEP_DELAY_MS);
14887
    }
14888
 
14889
    /*
14890
     * Write EEPROM checksum at word 18
14891
     */
14892
    AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
14893
    AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
14894
    AdvWaitEEPCmd(iop_base);
14895
    wbuf++;        /* skip over check_sum */
14896
 
14897
    /*
14898
     * Write EEPROM OEM name at words 19 to 26
14899
     */
14900
    for (addr = ASC_EEP_DVC_CTL_BEGIN;
14901
         addr < ASC_EEP_MAX_WORD_ADDR; addr++, wbuf++)
14902
    {
14903
        AdvWriteWordRegister(iop_base, IOPW_EE_DATA, *wbuf);
14904
        AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
14905
        AdvWaitEEPCmd(iop_base);
14906
    }
14907
    AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
14908
    AdvWaitEEPCmd(iop_base);
14909
    return;
14910
}
14911
 
14912
/*
14913
 * This function resets the chip and SCSI bus
14914
 *
14915
 * It is up to the caller to add a delay to let the bus settle after
14916
 * calling this function.
14917
 *
14918
 * The SCSI_CFG0, SCSI_CFG1, and MEM_CFG registers are set-up in
14919
 * AdvInitAsc3550Driver(). Here when doing a write to one of these
14920
 * registers read first and then write.
14921
 *
14922
 * Note: A SCSI Bus Reset can not be done until after the EEPROM
14923
 * configuration is read to determine whether SCSI Bus Resets
14924
 * should be performed.
14925
 */
14926
ASC_INITFUNC(
14927
STATIC void
14928
AdvResetChip(ADV_DVC_VAR *asc_dvc)
14929
)
14930
{
14931
    AdvPortAddr    iop_base;
14932
    ushort         word;
14933
    uchar          byte;
14934
 
14935
    iop_base = asc_dvc->iop_base;
14936
 
14937
    /*
14938
     * Reset Chip.
14939
     */
14940
    AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_RESET);
14941
    DvcSleepMilliSecond(100);
14942
    AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_WR_IO_REG);
14943
 
14944
    /*
14945
     * Initialize Chip registers.
14946
     *
14947
     * Note: Don't remove the use of a temporary variable in the following
14948
     * code, otherwise the Microsoft C compiler will turn the following lines
14949
     * into a no-op.
14950
     */
14951
    byte = AdvReadByteRegister(iop_base, IOPB_MEM_CFG);
14952
    byte |= RAM_SZ_8KB;
14953
    AdvWriteByteRegister(iop_base, IOPB_MEM_CFG, byte);
14954
 
14955
    word = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
14956
    word &= ~BIG_ENDIAN;
14957
    AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1, word);
14958
 
14959
    /*
14960
     * Setting the START_CTL_EMFU 3:2 bits sets a FIFO threshold
14961
     * of 128 bytes. This register is only accessible to the host.
14962
     */
14963
    AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
14964
        START_CTL_EMFU | READ_CMD_MRM);
14965
}
14966
 
14967
/* a_advlib.c */
14968
/*
14969
 * Description:
14970
 *      Send a SCSI request to the ASC3550 chip
14971
 *
14972
 * If there is no SG list for the request, set 'sg_entry_cnt' to 0.
14973
 *
14974
 * If 'sg_real_addr' is non-zero on entry, AscGetSGList() will not be
14975
 * called. It is assumed the caller has already initialized 'sg_real_addr'.
14976
 *
14977
 * Return:
14978
 *      ADV_SUCCESS(1) - the request is in the mailbox
14979
 *      ADV_BUSY(0) - total request count > 253, try later
14980
 *      ADV_ERROR(-1) - invalid scsi request Q
14981
 */
14982
STATIC int
14983
AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc,
14984
                ADV_SCSI_REQ_Q *scsiq)
14985
{
14986
    if (scsiq == (ADV_SCSI_REQ_Q *) 0L)
14987
    {
14988
        /* 'scsiq' should never be NULL. */
14989
        ADV_ASSERT(0);
14990
        return ADV_ERROR;
14991
    }
14992
 
14993
    return AdvSendScsiCmd(asc_dvc, scsiq);
14994
}
14995
 
14996
/*
14997
 * Reset SCSI Bus and purge all outstanding requests.
14998
 *
14999
 * Return Value:
15000
 *      ADV_TRUE(1) - All requests are purged and SCSI Bus is reset.
15001
 *
15002
 * Note: Should always return ADV_TRUE.
15003
 */
15004
STATIC int
15005
AdvResetSB(ADV_DVC_VAR *asc_dvc)
15006
{
15007
    int         status;
15008
 
15009
    status = AdvSendIdleCmd(asc_dvc, (ushort) IDLE_CMD_SCSI_RESET, 0L, 0);
15010
 
15011
    AdvResetSCSIBus(asc_dvc);
15012
 
15013
    return status;
15014
}
15015
 
15016
/*
15017
 * Reset SCSI Bus and delay.
15018
 */
15019
STATIC void
15020
AdvResetSCSIBus(ADV_DVC_VAR *asc_dvc)
15021
{
15022
    AdvPortAddr    iop_base;
15023
    ushort         scsi_ctrl;
15024
 
15025
    iop_base = asc_dvc->iop_base;
15026
 
15027
    /*
15028
     * The microcode currently sets the SCSI Bus Reset signal while
15029
     * handling the AscSendIdleCmd() IDLE_CMD_SCSI_RESET command above.
15030
     * But the SCSI Bus Reset Hold Time in the microcode is not deterministic
15031
     * (it may in fact be for less than the SCSI Spec. minimum of 25 us).
15032
     * Therefore on return the Adv Library sets the SCSI Bus Reset signal
15033
     * for ASC_SCSI_RESET_HOLD_TIME_US, which is defined to be greater
15034
     * than 25 us.
15035
     */
15036
    scsi_ctrl = AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL);
15037
    AdvWriteWordRegister(iop_base, IOPW_SCSI_CTRL,
15038
        scsi_ctrl | ADV_SCSI_CTRL_RSTOUT);
15039
    DvcDelayMicroSecond(asc_dvc, (ushort) ASC_SCSI_RESET_HOLD_TIME_US);
15040
    AdvWriteWordRegister(iop_base, IOPW_SCSI_CTRL,
15041
        scsi_ctrl & ~ADV_SCSI_CTRL_RSTOUT);
15042
 
15043
    DvcSleepMilliSecond((ulong) asc_dvc->scsi_reset_wait * 1000);
15044
}
15045
 
15046
 
15047
/*
15048
 * Adv Library Interrupt Service Routine
15049
 *
15050
 *  This function is called by a driver's interrupt service routine.
15051
 *  The function disables and re-enables interrupts.
15052
 *
15053
 *  When a microcode idle command is completed, the ADV_DVC_VAR
15054
 *  'idle_cmd_done' field is set to ADV_TRUE.
15055
 *
15056
 *  Note: AdvISR() can be called when interrupts are disabled or even
15057
 *  when there is no hardware interrupt condition present. It will
15058
 *  always check for completed idle commands and microcode requests.
15059
 *  This is an important feature that shouldn't be changed because it
15060
 *  allows commands to be completed from polling mode loops.
15061
 *
15062
 * Return:
15063
 *   ADV_TRUE(1) - interrupt was pending
15064
 *   ADV_FALSE(0) - no interrupt was pending
15065
 */
15066
STATIC int
15067
AdvISR(ADV_DVC_VAR *asc_dvc)
15068
{
15069
    AdvPortAddr                 iop_base;
15070
    uchar                       int_stat;
15071
    ushort                      next_done_loc, target_bit;
15072
    int                         completed_q;
15073
    int                         flags;
15074
    ADV_SCSI_REQ_Q              *scsiq;
15075
    ASC_REQ_SENSE               *sense_data;
15076
    int                         ret;
15077
 
15078
    flags = DvcEnterCritical();
15079
    iop_base = asc_dvc->iop_base;
15080
 
15081
    if (AdvIsIntPending(iop_base))
15082
    {
15083
        ret = ADV_TRUE;
15084
    } else
15085
    {
15086
        ret = ADV_FALSE;
15087
    }
15088
 
15089
    /* Reading the register clears the interrupt. */
15090
    int_stat = AdvReadByteRegister(iop_base, IOPB_INTR_STATUS_REG);
15091
 
15092
    if (int_stat & ADV_INTR_STATUS_INTRB)
15093
    {
15094
        asc_dvc->idle_cmd_done = ADV_TRUE;
15095
    }
15096
 
15097
    /*
15098
     * Notify the driver of a hardware detected SCSI Bus Reset.
15099
     */
15100
    if (int_stat & ADV_INTR_STATUS_INTRC)
15101
    {
15102
        if (asc_dvc->sbreset_callback != 0)
15103
        {
15104
            (*(ADV_SBRESET_CALLBACK) asc_dvc->sbreset_callback)(asc_dvc);
15105
        }
15106
    }
15107
 
15108
    /*
15109
     * ASC_MC_HOST_NEXT_DONE (0x129) is actually the last completed RISC
15110
     * Queue List request. Its forward pointer (RQL_FWD) points to the
15111
     * current completed RISC Queue List request.
15112
     */
15113
    AdvReadByteLram(iop_base, ASC_MC_HOST_NEXT_DONE, next_done_loc);
15114
    next_done_loc = ASC_MC_RISC_Q_LIST_BASE +
15115
        (next_done_loc * ASC_MC_RISC_Q_LIST_SIZE) + RQL_FWD;
15116
 
15117
    AdvReadByteLram(iop_base, next_done_loc, completed_q);
15118
 
15119
    /* Loop until all completed Q's are processed. */
15120
    while (completed_q != ASC_MC_NULL_Q)
15121
    {
15122
        AdvWriteByteLram(iop_base, ASC_MC_HOST_NEXT_DONE, completed_q);
15123
 
15124
        next_done_loc = ASC_MC_RISC_Q_LIST_BASE +
15125
          (completed_q * ASC_MC_RISC_Q_LIST_SIZE);
15126
 
15127
        /*
15128
         * Read the ADV_SCSI_REQ_Q virtual address pointer from
15129
         * the RISC list entry. The microcode has changed the
15130
         * ADV_SCSI_REQ_Q physical address to its virtual address.
15131
         *
15132
         * Refer to comments at the end of AdvSendScsiCmd() for
15133
         * more information on the RISC list structure.
15134
         */
15135
        {
15136
            ushort lsw, msw;
15137
            AdvReadWordLram(iop_base, next_done_loc + RQL_PHYADDR, lsw);
15138
            AdvReadWordLram(iop_base, next_done_loc + RQL_PHYADDR + 2, msw);
15139
 
15140
            scsiq = (ADV_SCSI_REQ_Q *) (((ulong) msw << 16) | lsw);
15141
        }
15142
        ADV_ASSERT(scsiq != NULL);
15143
 
15144
        target_bit = ADV_TID_TO_TIDMASK(scsiq->target_id);
15145
 
15146
        /*
15147
         * Clear request microcode control flag.
15148
         */
15149
        scsiq->cntl = 0;
15150
 
15151
        /*
15152
         * Check Condition handling
15153
         */
15154
        if ((scsiq->done_status == QD_WITH_ERROR) &&
15155
            (scsiq->scsi_status == SS_CHK_CONDITION) &&
15156
            (sense_data = (ASC_REQ_SENSE *) scsiq->vsense_addr) != 0 &&
15157
            (scsiq->orig_sense_len - scsiq->sense_len) >= ASC_MIN_SENSE_LEN)
15158
        {
15159
            /*
15160
             * Command returned with a check condition and valid
15161
             * sense data.
15162
             */
15163
        }
15164
        /*
15165
         * If the command that completed was a SCSI INQUIRY and
15166
         * LUN 0 was sent the command, then process the INQUIRY
15167
         * command information for the device.
15168
         */
15169
        else if (scsiq->done_status == QD_NO_ERROR &&
15170
                   scsiq->cdb[0] == SCSICMD_Inquiry &&
15171
                   scsiq->target_lun == 0)
15172
        {
15173
            AdvInquiryHandling(asc_dvc, scsiq);
15174
        }
15175
 
15176
 
15177
        /* Change the RISC Queue List state to free. */
15178
        AdvWriteByteLram(iop_base, next_done_loc + RQL_STATE, ASC_MC_QS_FREE);
15179
 
15180
        /* Get the RISC Queue List forward pointer. */
15181
        AdvReadByteLram(iop_base, next_done_loc + RQL_FWD, completed_q);
15182
 
15183
        /*
15184
         * Notify the driver of the completed request by passing
15185
         * the ADV_SCSI_REQ_Q pointer to its callback function.
15186
         */
15187
        ADV_ASSERT(asc_dvc->cur_host_qng > 0);
15188
        asc_dvc->cur_host_qng--;
15189
        scsiq->a_flag |= ADV_SCSIQ_DONE;
15190
        (*(ADV_ISR_CALLBACK) asc_dvc->isr_callback)(asc_dvc, scsiq);
15191
        /*
15192
         * Note: After the driver callback function is called, 'scsiq'
15193
         * can no longer be referenced.
15194
         *
15195
         * Fall through and continue processing other completed
15196
         * requests...
15197
         */
15198
 
15199
        /*
15200
         * Disable interrupts again in case the driver inadvertently
15201
         * enabled interrupts in its callback function.
15202
         *
15203
         * The DvcEnterCritical() return value is ignored, because
15204
         * the 'flags' saved when AdvISR() was first entered will be
15205
         * used to restore the interrupt flag on exit.
15206
         */
15207
        (void) DvcEnterCritical();
15208
    }
15209
    DvcLeaveCritical(flags);
15210
    return ret;
15211
}
15212
 
15213
/*
15214
 * Send an idle command to the chip and wait for completion.
15215
 *
15216
 * Interrupts do not have to be enabled on entry.
15217
 *
15218
 * Return Values:
15219
 *   ADV_TRUE - command completed successfully
15220
 *   ADV_FALSE - command failed
15221
 */
15222
STATIC int
15223
AdvSendIdleCmd(ADV_DVC_VAR *asc_dvc,
15224
               ushort idle_cmd,
15225
               ulong idle_cmd_parameter,
15226
               int flags)
15227
{
15228
    int         last_int_level;
15229
    ulong       i;
15230
    AdvPortAddr iop_base;
15231
    int         ret;
15232
 
15233
    asc_dvc->idle_cmd_done = 0;
15234
 
15235
    last_int_level = DvcEnterCritical();
15236
    iop_base = asc_dvc->iop_base;
15237
 
15238
    /*
15239
     * Write the idle command value after the idle command parameter
15240
     * has been written to avoid a race condition. If the order is not
15241
     * followed, the microcode may process the idle command before the
15242
     * parameters have been written to LRAM.
15243
     */
15244
    AdvWriteDWordLram(iop_base, ASC_MC_IDLE_PARA_STAT, idle_cmd_parameter);
15245
    AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD, idle_cmd);
15246
    DvcLeaveCritical(last_int_level);
15247
 
15248
    /*
15249
     * If the 'flags' argument contains the ADV_NOWAIT flag, then
15250
     * return with success.
15251
     */
15252
    if (flags & ADV_NOWAIT)
15253
    {
15254
        return ADV_TRUE;
15255
    }
15256
 
15257
    for (i = 0; i < SCSI_WAIT_10_SEC * SCSI_MS_PER_SEC; i++)
15258
    {
15259
        /*
15260
         * 'idle_cmd_done' is set by AdvISR().
15261
         */
15262
        if (asc_dvc->idle_cmd_done)
15263
        {
15264
            break;
15265
        }
15266
        DvcSleepMilliSecond(1);
15267
 
15268
        /*
15269
         * If interrupts were disabled on entry to AdvSendIdleCmd(),
15270
         * then they will still be disabled here. Call AdvISR() to
15271
         * check for the idle command completion.
15272
         */
15273
        (void) AdvISR(asc_dvc);
15274
    }
15275
 
15276
    last_int_level = DvcEnterCritical();
15277
 
15278
    if (asc_dvc->idle_cmd_done == ADV_FALSE)
15279
    {
15280
        ADV_ASSERT(0); /* The idle command should never timeout. */
15281
        return ADV_FALSE;
15282
    } else
15283
    {
15284
        AdvReadWordLram(iop_base, ASC_MC_IDLE_PARA_STAT, ret);
15285
        return ret;
15286
    }
15287
}
15288
 
15289
/*
15290
 * Send the SCSI request block to the adapter
15291
 *
15292
 * Each of the 255 Adv Library/Microcode RISC Lists or mailboxes has the
15293
 * following structure:
15294
 *
15295
 * 0: RQL_FWD - RISC list forward pointer (1 byte)
15296
 * 1: RQL_BWD - RISC list backward pointer (1 byte)
15297
 * 2: RQL_STATE - RISC list state byte - free, ready, done, aborted (1 byte)
15298
 * 3: RQL_TID - request target id (1 byte)
15299
 * 4: RQL_PHYADDR - ADV_SCSI_REQ_Q physical pointer (4 bytes)
15300
 *
15301
 * Return:
15302
 *      ADV_SUCCESS(1) - the request is in the mailbox
15303
 *      ADV_BUSY(0) - total request count > 253, try later
15304
 */
15305
STATIC int
15306
AdvSendScsiCmd(
15307
    ADV_DVC_VAR *asc_dvc,
15308
    ADV_SCSI_REQ_Q  *scsiq)
15309
{
15310
    ushort                 next_ready_loc;
15311
    uchar                  next_ready_loc_fwd;
15312
    int                    last_int_level;
15313
    AdvPortAddr            iop_base;
15314
    long                   req_size;
15315
    ulong                  q_phy_addr;
15316
 
15317
    /*
15318
     * The ADV_SCSI_REQ_Q 'target_id' field should never be equal
15319
     * to the host adapter ID or exceed ADV_MAX_TID.
15320
     */
15321
    if (scsiq->target_id == asc_dvc->chip_scsi_id ||
15322
        scsiq->target_id > ADV_MAX_TID)
15323
    {
15324
        scsiq->host_status = QHSTA_M_INVALID_DEVICE;
15325
        scsiq->done_status = QD_WITH_ERROR;
15326
        return ADV_ERROR;
15327
    }
15328
 
15329
    iop_base = asc_dvc->iop_base;
15330
 
15331
    last_int_level = DvcEnterCritical();
15332
 
15333
    if (asc_dvc->cur_host_qng >= asc_dvc->max_host_qng)
15334
    {
15335
        DvcLeaveCritical(last_int_level);
15336
        return ADV_BUSY;
15337
    } else
15338
    {
15339
        ADV_ASSERT(asc_dvc->cur_host_qng < ASC_MC_RISC_Q_TOTAL_CNT);
15340
        asc_dvc->cur_host_qng++;
15341
    }
15342
 
15343
    /*
15344
     * Clear the ADV_SCSI_REQ_Q done flag.
15345
     */
15346
    scsiq->a_flag &= ~ADV_SCSIQ_DONE;
15347
 
15348
    /*
15349
     * Save the original sense buffer length.
15350
     *
15351
     * After the request completes 'sense_len' will be set to the residual
15352
     * byte count of the Auto-Request Sense if a command returns CHECK
15353
     * CONDITION and the Sense Data is valid indicated by 'host_status' not
15354
     * being set to QHSTA_M_AUTO_REQ_SENSE_FAIL. To determine the valid
15355
     * Sense Data Length subtract 'sense_len' from 'orig_sense_len'.
15356
     */
15357
    scsiq->orig_sense_len = scsiq->sense_len;
15358
 
15359
    AdvReadByteLram(iop_base, ASC_MC_HOST_NEXT_READY, next_ready_loc);
15360
    next_ready_loc = ASC_MC_RISC_Q_LIST_BASE +
15361
        (next_ready_loc * ASC_MC_RISC_Q_LIST_SIZE);
15362
 
15363
    /*
15364
     * Write the physical address of the Q to the mailbox.
15365
     * We need to skip the first four bytes, because the microcode
15366
     * uses them internally for linking Q's together.
15367
     */
15368
    req_size = sizeof(ADV_SCSI_REQ_Q);
15369
    q_phy_addr = DvcGetPhyAddr(asc_dvc, scsiq,
15370
                    (uchar *) scsiq, &req_size,
15371
                    ADV_IS_SCSIQ_FLAG);
15372
    ADV_ASSERT(ADV_DWALIGN(q_phy_addr) == q_phy_addr);
15373
    ADV_ASSERT(req_size >= sizeof(ADV_SCSI_REQ_Q));
15374
 
15375
    scsiq->scsiq_ptr = (ADV_SCSI_REQ_Q *) scsiq;
15376
 
15377
    /*
15378
     * The RISC list structure, which 'next_ready_loc' is a pointer
15379
     * to in microcode LRAM, has the format detailed in the comment
15380
     * header for this function.
15381
     *
15382
     * Write the ADV_SCSI_REQ_Q physical pointer to 'next_ready_loc' request.
15383
     */
15384
    AdvWriteDWordLram(iop_base, next_ready_loc + RQL_PHYADDR, q_phy_addr);
15385
 
15386
    /* Write target_id to 'next_ready_loc' request. */
15387
    AdvWriteByteLram(iop_base, next_ready_loc + RQL_TID, scsiq->target_id);
15388
 
15389
    /*
15390
     * Set the ASC_MC_HOST_NEXT_READY (0x128) microcode variable to
15391
     * the 'next_ready_loc' request forward pointer.
15392
     *
15393
     * Do this *before* changing the 'next_ready_loc' queue to QS_READY.
15394
     * After the state is changed to QS_READY 'RQL_FWD' will be changed
15395
     * by the microcode.
15396
     *
15397
     * NOTE: The temporary variable 'next_ready_loc_fwd' is required to
15398
     * prevent some compilers from optimizing out 'AdvReadByteLram()' if
15399
     * it were used as the 3rd argument to 'AdvWriteByteLram()'.
15400
     */
15401
    AdvReadByteLram(iop_base, next_ready_loc + RQL_FWD, next_ready_loc_fwd);
15402
    AdvWriteByteLram(iop_base, ASC_MC_HOST_NEXT_READY, next_ready_loc_fwd);
15403
 
15404
    /*
15405
     * Change the state of 'next_ready_loc' request from QS_FREE to
15406
     * QS_READY which will cause the microcode to pick it up and
15407
     * execute it.
15408
     *
15409
     * Can't reference 'next_ready_loc' after changing the request
15410
     * state to QS_READY. The microcode now owns the request.
15411
     */
15412
    AdvWriteByteLram(iop_base, next_ready_loc + RQL_STATE, ASC_MC_QS_READY);
15413
 
15414
    DvcLeaveCritical(last_int_level);
15415
    return ADV_SUCCESS;
15416
}
15417
 
15418
/*
15419
 * Inquiry Information Byte 7 Handling
15420
 *
15421
 * Handle SCSI Inquiry Command information for a device by setting
15422
 * microcode operating variables that affect WDTR, SDTR, and Tag
15423
 * Queuing.
15424
 */
15425
STATIC void
15426
AdvInquiryHandling(
15427
    ADV_DVC_VAR          *asc_dvc,
15428
    ADV_SCSI_REQ_Q       *scsiq)
15429
{
15430
    AdvPortAddr          iop_base;
15431
    uchar                tid;
15432
    ASC_SCSI_INQUIRY     *inq;
15433
    ushort               tidmask;
15434
    ushort               cfg_word;
15435
 
15436
    /*
15437
     * AdvInquiryHandling() requires up to INQUIRY information Byte 7
15438
     * to be available.
15439
     *
15440
     * If less than 8 bytes of INQUIRY information were requested or less
15441
     * than 8 bytes were transferred, then return. cdb[4] is the request
15442
     * length and the ADV_SCSI_REQ_Q 'data_cnt' field is set by the
15443
     * microcode to the transfer residual count.
15444
     */
15445
    if (scsiq->cdb[4] < 8 || (scsiq->cdb[4] - scsiq->data_cnt) < 8)
15446
    {
15447
        return;
15448
    }
15449
 
15450
    iop_base = asc_dvc->iop_base;
15451
    tid = scsiq->target_id;
15452
    inq = (ASC_SCSI_INQUIRY *) scsiq->vdata_addr;
15453
 
15454
    /*
15455
     * WDTR, SDTR, and Tag Queuing cannot be enabled for old devices.
15456
     */
15457
    if (inq->byte3.rsp_data_fmt < 2 && inq->byte2.ansi_apr_ver < 2)
15458
    {
15459
        return;
15460
    } else
15461
    {
15462
        /*
15463
         * INQUIRY Byte 7 Handling
15464
         *
15465
         * Use a device's INQUIRY byte 7 to determine whether it
15466
         * supports WDTR, SDTR, and Tag Queuing. If the feature
15467
         * is enabled in the EEPROM and the device supports the
15468
         * feature, then enable it in the microcode.
15469
         */
15470
 
15471
        tidmask = ADV_TID_TO_TIDMASK(tid);
15472
 
15473
        /*
15474
         * Wide Transfers
15475
         *
15476
         * If the EEPROM enabled WDTR for the device and the device
15477
         * supports wide bus (16 bit) transfers, then turn on the
15478
         * device's 'wdtr_able' bit and write the new value to the
15479
         * microcode.
15480
         */
15481
        if ((asc_dvc->wdtr_able & tidmask) && inq->byte7.WBus16)
15482
        {
15483
            AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
15484
            if ((cfg_word & tidmask) == 0)
15485
            {
15486
                cfg_word |= tidmask;
15487
                AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
15488
 
15489
                /*
15490
                 * Clear the microcode "WDTR negotiation" done indicator
15491
                 * for the target to cause it to negotiate with the new
15492
                 * setting set above.
15493
                 */
15494
                AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
15495
                cfg_word &= ~tidmask;
15496
                AdvWriteWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
15497
            }
15498
        }
15499
 
15500
        /*
15501
         * Synchronous Transfers
15502
         *
15503
         * If the EEPROM enabled SDTR for the device and the device
15504
         * supports synchronous transfers, then turn on the device's
15505
         * 'sdtr_able' bit. Write the new value to the microcode.
15506
         */
15507
        if ((asc_dvc->sdtr_able & tidmask) && inq->byte7.Sync)
15508
        {
15509
            AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
15510
            if ((cfg_word & tidmask) == 0)
15511
            {
15512
                cfg_word |= tidmask;
15513
                AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
15514
 
15515
                /*
15516
                 * Clear the microcode "SDTR negotiation" done indicator
15517
                 * for the target to cause it to negotiate with the new
15518
                 * setting set above.
15519
                 */
15520
                AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
15521
                cfg_word &= ~tidmask;
15522
                AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
15523
            }
15524
        }
15525
 
15526
        /*
15527
         * If the EEPROM enabled Tag Queuing for device and the
15528
         * device supports Tag Queuing, then turn on the device's
15529
         * 'tagqng_enable' bit in the microcode and set the microcode
15530
         * maximum command count to the ADV_DVC_VAR 'max_dvc_qng'
15531
         * value.
15532
         *
15533
         * Tag Queuing is disabled for the BIOS which runs in polled
15534
         * mode and would see no benefit from Tag Queuing. Also by
15535
         * disabling Tag Queuing in the BIOS devices with Tag Queuing
15536
         * bugs will at least work with the BIOS.
15537
         */
15538
        if ((asc_dvc->tagqng_able & tidmask) && inq->byte7.CmdQue)
15539
        {
15540
            AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
15541
            cfg_word |= tidmask;
15542
            AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
15543
            AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
15544
                asc_dvc->max_dvc_qng);
15545
        }
15546
    }
15547
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.