]> git.pld-linux.org Git - packages/kernel.git/blob - linux-2.4.4-aacraid-043001.patch
- obsolete
[packages/kernel.git] / linux-2.4.4-aacraid-043001.patch
1 diff -burN linux-2.4.4/MAINTAINERS linux/MAINTAINERS
2 --- linux-2.4.4/MAINTAINERS     Wed Apr 25 16:35:25 2001
3 +++ linux/MAINTAINERS   Mon Apr 30 09:43:33 2001
4 @@ -113,6 +113,14 @@
5  W:     http://www.uni-karlsruhe.de/~Robert.Siemer/Private/
6  S:     Maintained
7  
8 +AACRAID SCSI RAID DRIVER
9 +P:     Adaptec OEM Raid Solutions
10 +M:     linux-aacraid-devel@domsch.com
11 +L:     linux-aacraid-devel@domsch.com
12 +L:     linux-aacraid-announce@domsch.com
13 +W:     http://domsch.com/linux
14 +S:     Supported
15 +
16  ACPI
17  P:     Andy Grover
18  M:     andrew.grover@intel.com
19 diff -burN linux-2.4.4/arch/i386/defconfig linux/arch/i386/defconfig
20 --- linux-2.4.4/arch/i386/defconfig     Fri Apr 27 16:41:16 2001
21 +++ linux/arch/i386/defconfig   Mon Apr 30 09:43:33 2001
22 @@ -283,6 +283,7 @@
23  # CONFIG_SCSI_AHA152X is not set
24  # CONFIG_SCSI_AHA1542 is not set
25  # CONFIG_SCSI_AHA1740 is not set
26 +# CONFIG_SCSI_AACRAID is not set
27  # CONFIG_SCSI_AIC7XXX is not set
28  # CONFIG_SCSI_AIC7XXX_OLD is not set
29  # CONFIG_SCSI_ADVANSYS is not set
30 diff -burN linux-2.4.4/drivers/scsi/Config.in linux/drivers/scsi/Config.in
31 --- linux-2.4.4/drivers/scsi/Config.in  Sun Mar  4 16:30:18 2001
32 +++ linux/drivers/scsi/Config.in        Mon Apr 30 09:43:33 2001
33 @@ -50,6 +50,7 @@
34  dep_tristate 'Adaptec AHA152X/2825 support' CONFIG_SCSI_AHA152X $CONFIG_SCSI
35  dep_tristate 'Adaptec AHA1542 support' CONFIG_SCSI_AHA1542 $CONFIG_SCSI
36  dep_tristate 'Adaptec AHA1740 support' CONFIG_SCSI_AHA1740 $CONFIG_SCSI
37 +dep_tristate 'Adaptec AACRAID support' CONFIG_SCSI_AACRAID $CONFIG_SCSI
38  source drivers/scsi/aic7xxx/Config.in
39  if [ "$CONFIG_SCSI_AIC7XXX" != "y" ]; then
40     dep_tristate 'Old Adaptec AIC7xxx support' CONFIG_SCSI_AIC7XXX_OLD $CONFIG_SCSI
41 diff -burN linux-2.4.4/drivers/scsi/Makefile linux/drivers/scsi/Makefile
42 --- linux-2.4.4/drivers/scsi/Makefile   Mon Mar 26 17:36:30 2001
43 +++ linux/drivers/scsi/Makefile Mon Apr 30 09:43:33 2001
44 @@ -64,6 +64,7 @@
45  ifeq ($(CONFIG_SCSI_AIC7XXX),y)
46  obj-$(CONFIG_SCSI_AIC7XXX)     += aic7xxx/aic7xxx_drv.o
47  endif
48 +obj-$(CONFIG_SCSI_AACRAID)     += aacraid.o
49  obj-$(CONFIG_SCSI_AIC7XXX_OLD) += aic7xxx_old.o
50  obj-$(CONFIG_SCSI_IPS)         += ips.o
51  obj-$(CONFIG_SCSI_FD_MCS)      += fd_mcs.o
52 @@ -184,3 +185,7 @@
53  sim710_u.h: sim710_d.h
54  
55  sim710.o : sim710_d.h
56 +
57 +aacraid.o:
58 +       cd aacraid; make
59 +
60 diff -burN linux-2.4.4/drivers/scsi/aacraid/ChangeLog linux/drivers/scsi/aacraid/ChangeLog
61 --- linux-2.4.4/drivers/scsi/aacraid/ChangeLog  Wed Dec 31 18:00:00 1969
62 +++ linux/drivers/scsi/aacraid/ChangeLog        Mon Apr 30 09:46:47 2001
63 @@ -0,0 +1,5 @@
64 +2001-04-30  Matt Domsch <Matt_Domsch@dell.com>
65 +* Started with linux-2.4.3-aacraid-030101.patch
66 +* Applied against 2.4.4.
67 +* Added scsi_set_pci_device() call in linit.c
68 +       
69 diff -burN linux-2.4.4/drivers/scsi/aacraid/Makefile linux/drivers/scsi/aacraid/Makefile
70 --- linux-2.4.4/drivers/scsi/aacraid/Makefile   Wed Dec 31 18:00:00 1969
71 +++ linux/drivers/scsi/aacraid/Makefile Mon Apr 30 09:43:33 2001
72 @@ -0,0 +1,169 @@
73 +#
74 +# Makefile aacraid Raid Controller
75 +#
76 +
77 +###############################################################################
78 +### SOURCE FILES DEFINES
79 +###############################################################################
80 +
81 +CFILES_DRIVER=\
82 +       ./aachba.c \
83 +       ./aacid.c \
84 +       ./commctrl.c \
85 +       ./comminit.c \
86 +       ./commsup.c \
87 +       ./dpcsup.c \
88 +       ./linit.c \
89 +       ./osddi.c \
90 +       ./osfuncs.c \
91 +       ./ossup.c \
92 +       ./port.c \
93 +       ./rx.c \
94 +       ./sap1sup.c
95 +
96 +IFILES_DRIVER=\
97 +       ./include/AacGenericTypes.h \
98 +       ./include/aac_unix_defs.h \
99 +       ./include/adapter.h \
100 +       ./include/afacomm.h \
101 +       ./include/aifstruc.h \
102 +       ./include/build_number.h \
103 +       ./include/commdata.h \
104 +       ./include/commerr.h \
105 +       ./include/commfibcontext.h \
106 +       ./include/comprocs.h \
107 +       ./include/comproto.h \
108 +       ./include/comstruc.h \
109 +       ./include/comsup.h \
110 +       ./include/fsact.h \
111 +       ./include/fsafs.h  \
112 +       ./include/fsaioctl.h \
113 +       ./include/fsaport.h \
114 +       ./include/fsatypes.h \
115 +       ./include/linit.h \
116 +       ./include/monkerapi.h \
117 +       ./include/nodetype.h \
118 +       ./include/nvramioctl.h \
119 +       ./include/osheaders.h \
120 +       ./include/ostypes.h \
121 +       ./include/pcisup.h \
122 +       ./include/perfpack.h \
123 +       ./include/port.h \
124 +       ./include/protocol.h \
125 +       ./include/revision.h \
126 +       ./include/rxcommon.h \
127 +       ./include/rx.h \
128 +       ./include/sap1common.h \
129 +       ./include/sap1.h \
130 +       ./include/version.h
131 +
132 +ALL_SOURCE=\
133 +       ${CFILES_DRIVER} \
134 +       ${IFILES_DRIVER} 
135 +
136 +###############################################################################
137 +### OBJECT FILES DEFINES
138 +###############################################################################
139 +
140 +
141 +OFILES_DRIVER=\
142 +       linit.o \
143 +       osfuncs.o \
144 +       osddi.o \
145 +       aachba.o \
146 +       commctrl.o \
147 +       comminit.o \
148 +       commsup.o \
149 +       dpcsup.o \
150 +       ossup.o \
151 +       port.o \
152 +       rx.o \
153 +       sap1sup.o
154 +
155 +TARGET_OFILES= ${OFILES_DRIVER} aacid.o
156 +
157 +###############################################################################
158 +### GENERAL DEFINES
159 +###############################################################################
160 +
161 +#  Remember that we're doing a chdir one level lower, so we need an extra ../
162 +INCS= \
163 +       -I./include \
164 +       -I../../../include -I..
165 +
166 +WARNINGS= -w -Wall -Wno-unused -Wno-switch -Wno-missing-prototypes -Wno-implicit
167 +
168 +
169 +COMMON_FLAGS=\
170 +       -D__KERNEL__=1 -DUNIX -DCVLOCK_USE_SPINLOCK -DLINUX \
171 +       ${INCS} \
172 +       ${WARNINGS}
173 +
174 +AACFLAGS=${CFLAGS} ${COMMON_FLAGS} ${EXTRA_FLAGS}
175 +
176 +###############################################################################
177 +### DO GENERAL STUFF
178 +###############################################################################
179 +
180 +.SUFFIXES:
181 +.SUFFIXES: .c .o .h .a
182 +
183 +all: source ${TARGET_OFILES} aacraid.o
184 +
185 +source: ${ALL_SOURCE}
186 +
187 +clean:
188 +       rm *.o
189 +
190 +###############################################################################
191 +### DRIVER LINKS
192 +###############################################################################
193 +
194 +aacraid.o: source ${TARGET_OFILES}
195 +       ld -r -o $@ $(TARGET_OFILES)
196 +       cp -r aacraid.o ../
197 +
198 +###############################################################################
199 +### SIMPLE COMPILES
200 +###############################################################################
201 +
202 +linit.o: ./linit.c
203 +       $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o linit.o ./linit.c
204 +
205 +aachba.o: ./aachba.c
206 +       $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o aachba.o ./aachba.c
207 +
208 +osddi.o: ./osddi.c
209 +       $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o osddi.o ./osddi.c
210 +
211 +osfuncs.o: ./osfuncs.c
212 +       $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o osfuncs.o ./osfuncs.c
213 +
214 +commctrl.o:  ./commctrl.c
215 +       $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o commctrl.o ./commctrl.c
216 +
217 +comminit.o:  ./comminit.c
218 +       $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o comminit.o ./comminit.c
219 +
220 +commsup.o:  ./commsup.c
221 +       $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o commsup.o ./commsup.c
222 +
223 +dpcsup.o:  ./dpcsup.c
224 +       $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o dpcsup.o ./dpcsup.c
225 +
226 +aacid.o:  ./aacid.c
227 +       $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o aacid.o ./aacid.c
228 +
229 +port.o:  ./port.c
230 +       $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o port.o ./port.c
231 +
232 +ossup.o:  ./ossup.c
233 +       $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o ossup.o ./ossup.c
234 +
235 +rx.o:  ./rx.c
236 +       $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o rx.o ./rx.c
237 +
238 +sap1sup.o: ./sap1sup.c
239 +       $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o sap1sup.o ./sap1sup.c
240 +
241 +
242 diff -burN linux-2.4.4/drivers/scsi/aacraid/README linux/drivers/scsi/aacraid/README
243 --- linux-2.4.4/drivers/scsi/aacraid/README     Wed Dec 31 18:00:00 1969
244 +++ linux/drivers/scsi/aacraid/README   Mon Apr 30 09:43:33 2001
245 @@ -0,0 +1,46 @@
246 +                               AACRAID Driver for Linux
247 +
248 +Introduction
249 +-------------------------
250 +The aacraid driver adds support for Adaptec (http://www.adaptec.com)
251 +OEM based RAID controllers.
252 +
253 +It is important to note the amount of test time the 2.4.x driver
254 +received. Though not a great deal has changed between 2.2 and 2.4
255 +for this version, it has not recevied a great deal of test time.
256 +
257 +A new driver version is in the works and that version will be
258 +submitted to the standard distribution kernel. The previous
259 +2.2 version was submitted but rejected due to the large
260 +amount of code reduncdancy and NTisms. This driver was
261 +initially ported from NT to Solaris and then to Linux.
262 +
263 +The new version is being written on Unix for Unix and
264 +should be much easier to read and a great deal cleaner.
265 +
266 +Supported Cards/Chipsets
267 +-------------------------
268 +       Dell Computer Corporation PERC 2 Quad Channel
269 +       Dell Computer Corporation PERC 2/Si
270 +       Dell Computer Corporation PERC 3/Si
271 +       Dell Computer Corporation PERC 3/Di
272 +       HP NetRAID-4M
273 +
274 +Not Supported Devices
275 +-------------------------
276 +       Any and All Adaptec branded raid controllers.
277 +
278 +People
279 +-------------------------
280 +       Adaptec Unix OEM Product Group
281 +
282 +Mailing List
283 +-------------------------
284 +please see http://domsch.com/linux for information
285 +on mailing lists. There is both a development and
286 +an announcment list. Due to the overwhelming amount
287 +of mail I receive about this driver, I can not
288 +answer questions individually and requests should
289 +be directed to the list server. Thanks.
290 +
291 +Modified by Brian Boerner February 2001
292 diff -burN linux-2.4.4/drivers/scsi/aacraid/aachba.c linux/drivers/scsi/aacraid/aachba.c
293 --- linux-2.4.4/drivers/scsi/aacraid/aachba.c   Wed Dec 31 18:00:00 1969
294 +++ linux/drivers/scsi/aacraid/aachba.c Mon Apr 30 09:43:34 2001
295 @@ -0,0 +1,1874 @@
296 +/*++
297 + * Adaptec aacraid device driver for Linux.
298 + *
299 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
300 + *
301 + * This program is free software; you can redistribute it and/or modify
302 + * it under the terms of the GNU General Public License as published by
303 + * the Free Software Foundation; either version 2, or (at your option)
304 + * any later version.
305 + *
306 + * This program is distributed in the hope that it will be useful,
307 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
308 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
309 + * GNU General Public License for more details.
310 + *
311 + * You should have received a copy of the GNU General Public License
312 + * along with this program; see the file COPYING.  If not, write to
313 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
314 + *
315 + * Module Name:
316 + *   aachba.c
317 + *
318 + * Abstract: driver...
319 + *
320 +--*/
321 +
322 +static char *ident_aachba = "aacraid_ident aachba.c 1.0.6 2000/10/09 Adaptec, Inc.";
323 +
324 +/*------------------------------------------------------------------------------
325 + *              I N C L U D E S
326 + *----------------------------------------------------------------------------*/
327 +#include "osheaders.h"
328 +#include "AacGenericTypes.h"
329 +#include "aac_unix_defs.h"
330 +#include "comstruc.h"
331 +#include "monkerapi.h"
332 +#include "protocol.h"
333 +#include "fsafs.h"
334 +#include "fsact.h"
335 +#include "fsaioctl.h"
336 +
337 +#include "sap1common.h"
338 +#include "fsaport.h"
339 +#include "pcisup.h"
340 +#include "sap1.h"
341 +#include "nodetype.h"
342 +#include "comsup.h"
343 +#include "afacomm.h"
344 +#include "adapter.h"
345 +
346 +/*------------------------------------------------------------------------------
347 + *              D E F I N E S
348 + *----------------------------------------------------------------------------*/
349 +/*     SCSI Commands */
350 +#define        SS_TEST                 0x00    /* Test unit ready */
351 +#define SS_REZERO              0x01    /* Rezero unit */
352 +#define        SS_REQSEN               0x03    /* Request Sense */
353 +#define SS_REASGN              0x07    /* Reassign blocks */
354 +#define        SS_READ                 0x08    /* Read 6   */
355 +#define        SS_WRITE                0x0A    /* Write 6  */
356 +#define        SS_INQUIR               0x12    /* inquiry */
357 +#define        SS_ST_SP                0x1B    /* Start/Stop unit */
358 +#define        SS_LOCK                 0x1E    /* prevent/allow medium removal */
359 +#define SS_RESERV              0x16    /* Reserve */
360 +#define SS_RELES               0x17    /* Release */
361 +#define SS_MODESEN             0x1A    /* Mode Sense 6 */
362 +#define        SS_RDCAP                0x25    /* Read Capacity */
363 +#define        SM_READ                 0x28    /* Read 10  */
364 +#define        SM_WRITE                0x2A    /* Write 10 */
365 +#define SS_SEEK                        0x2B    /* Seek */
366 +
367 +/* values for inqd_pdt: Peripheral device type in plain English */
368 +#define        INQD_PDT_DA     0x00    /* Direct-access (DISK) device */
369 +#define        INQD_PDT_PROC   0x03    /* Processor device */
370 +#define        INQD_PDT_CHNGR  0x08    /* Changer (jukebox, scsi2) */
371 +#define        INQD_PDT_COMM   0x09    /* Communication device (scsi2) */
372 +#define        INQD_PDT_NOLUN2 0x1f    /* Unknown Device (scsi2) */
373 +#define        INQD_PDT_NOLUN  0x7f    /* Logical Unit Not Present */
374 +
375 +#define        INQD_PDT_DMASK  0x1F    /* Peripheral Device Type Mask */
376 +#define        INQD_PDT_QMASK  0xE0    /* Peripheral Device Qualifer Mask */
377 +
378 +#define        TARGET_LUN_TO_CONTAINER(Target, Lun)    (((Lun) << 4) | Target)
379 +#define CONTAINER_TO_TARGET(Container)          ((Container) & 0xf)
380 +#define CONTAINER_TO_LUN(Container)             ((Container) >> 4)
381 +
382 +#define MAX_FIB_DATA (sizeof(FIB) - sizeof(FIB_HEADER))
383 +
384 +#define MAX_DRIVER_SG_SEGMENT_COUNT 17
385 +
386 +// ------------------------------------------------------
387 +// Sense keys
388 +//
389 +#define SENKEY_NO_SENSE      0x00 //
390 +#define SENKEY_UNDEFINED     0x01 //
391 +#define SENKEY_NOT_READY     0x02 //
392 +#define SENKEY_MEDIUM_ERR    0x03 //
393 +#define SENKEY_HW_ERR        0x04 //
394 +#define SENKEY_ILLEGAL       0x05 //
395 +#define SENKEY_ATTENTION     0x06 //
396 +#define SENKEY_PROTECTED     0x07 //
397 +#define SENKEY_BLANK         0x08 //
398 +#define SENKEY_V_UNIQUE      0x09 //
399 +#define SENKEY_CPY_ABORT     0x0A //
400 +#define SENKEY_ABORT         0x0B //
401 +#define SENKEY_EQUAL         0x0C //
402 +#define SENKEY_VOL_OVERFLOW  0x0D //
403 +#define SENKEY_MISCOMP       0x0E //
404 +#define SENKEY_RESERVED      0x0F //
405 +
406 +// ------------------------------------------------------
407 +// Sense codes
408 +//
409 +#define SENCODE_NO_SENSE                        0x00
410 +#define SENCODE_END_OF_DATA                     0x00
411 +#define SENCODE_BECOMING_READY                  0x04
412 +#define SENCODE_INIT_CMD_REQUIRED               0x04
413 +#define SENCODE_PARAM_LIST_LENGTH_ERROR         0x1A
414 +#define SENCODE_INVALID_COMMAND                 0x20
415 +#define SENCODE_LBA_OUT_OF_RANGE                0x21
416 +#define SENCODE_INVALID_CDB_FIELD               0x24
417 +#define SENCODE_LUN_NOT_SUPPORTED               0x25
418 +#define SENCODE_INVALID_PARAM_FIELD             0x26
419 +#define SENCODE_PARAM_NOT_SUPPORTED             0x26
420 +#define SENCODE_PARAM_VALUE_INVALID             0x26
421 +#define SENCODE_RESET_OCCURRED                  0x29
422 +#define SENCODE_LUN_NOT_SELF_CONFIGURED_YET     0x3E
423 +#define SENCODE_INQUIRY_DATA_CHANGED            0x3F
424 +#define SENCODE_SAVING_PARAMS_NOT_SUPPORTED     0x39
425 +#define SENCODE_DIAGNOSTIC_FAILURE              0x40
426 +#define SENCODE_INTERNAL_TARGET_FAILURE         0x44
427 +#define SENCODE_INVALID_MESSAGE_ERROR           0x49
428 +#define SENCODE_LUN_FAILED_SELF_CONFIG          0x4c
429 +#define SENCODE_OVERLAPPED_COMMAND              0x4E
430 +
431 +// ------------------------------------------------------
432 +// Additional sense codes
433 +//
434 +#define ASENCODE_NO_SENSE                       0x00
435 +#define ASENCODE_END_OF_DATA                    0x05
436 +#define ASENCODE_BECOMING_READY                 0x01
437 +#define ASENCODE_INIT_CMD_REQUIRED              0x02
438 +#define ASENCODE_PARAM_LIST_LENGTH_ERROR        0x00
439 +#define ASENCODE_INVALID_COMMAND                0x00
440 +#define ASENCODE_LBA_OUT_OF_RANGE               0x00
441 +#define ASENCODE_INVALID_CDB_FIELD              0x00
442 +#define ASENCODE_LUN_NOT_SUPPORTED              0x00
443 +#define ASENCODE_INVALID_PARAM_FIELD            0x00
444 +#define ASENCODE_PARAM_NOT_SUPPORTED            0x01
445 +#define ASENCODE_PARAM_VALUE_INVALID            0x02
446 +#define ASENCODE_RESET_OCCURRED                 0x00
447 +#define ASENCODE_LUN_NOT_SELF_CONFIGURED_YET    0x00
448 +#define ASENCODE_INQUIRY_DATA_CHANGED           0x03
449 +#define ASENCODE_SAVING_PARAMS_NOT_SUPPORTED    0x00
450 +#define ASENCODE_DIAGNOSTIC_FAILURE             0x80
451 +#define ASENCODE_INTERNAL_TARGET_FAILURE        0x00
452 +#define ASENCODE_INVALID_MESSAGE_ERROR          0x00
453 +#define ASENCODE_LUN_FAILED_SELF_CONFIG         0x00
454 +#define ASENCODE_OVERLAPPED_COMMAND             0x00
455 +
456 +#define BYTE0( x ) ( unsigned char )( x )
457 +#define BYTE1( x ) ( unsigned char )( x >> 8  )
458 +#define BYTE2( x ) ( unsigned char )( x >> 16 )
459 +#define BYTE3( x ) ( unsigned char )( x >> 24 )
460 +
461 +/*------------------------------------------------------------------------------
462 + *              S T R U C T S / T Y P E D E F S
463 + *----------------------------------------------------------------------------*/
464 +/* SCSI inquiry data */
465 +struct inquiry_data {
466 +       unchar inqd_pdt;     /* Peripheral qualifier | Peripheral Device Type  */
467 +       unchar inqd_dtq;     /* RMB | Device Type Qualifier  */
468 +       unchar inqd_ver;     /* ISO version | ECMA version | ANSI-approved version */
469 +       unchar inqd_rdf;     /* AENC | TrmIOP | Response data format */
470 +       unchar inqd_len;     /* Additional length (n-4) */
471 +       unchar inqd_pad1[2]; /* Reserved - must be zero */
472 +       unchar inqd_pad2;    /* RelAdr | WBus32 | WBus16 |  Sync  | Linked |Reserved| CmdQue | SftRe */
473 +       unchar inqd_vid[8];  /* Vendor ID */
474 +       unchar inqd_pid[16]; /* Product ID */
475 +       unchar inqd_prl[4];  /* Product Revision Level */
476 +};
477 +
478 +struct sense_data {
479 +       unchar error_code;              // 70h (current errors), 71h(deferred errors)
480 +       unchar valid:1;                 // A valid bit of one indicates that the information 
481 +                                       // field contains valid information as defined in the
482 +                                       // SCSI-2 Standard.
483 +       
484 +       unchar segment_number;  // Only used for COPY, COMPARE, or COPY AND VERIFY 
485 +                               // commands
486 +       
487 +       unchar sense_key:4;             // Sense Key
488 +       unchar reserved:1;
489 +       unchar ILI:1;                   // Incorrect Length Indicator
490 +       unchar EOM:1;                   // End Of Medium - reserved for random access devices
491 +       unchar filemark:1;              // Filemark - reserved for random access devices
492 +       
493 +       unchar information[4];  // for direct-access devices, contains the unsigned 
494 +                               // logical block address or residue associated with 
495 +                               // the sense key 
496 +       unchar add_sense_len;   // number of additional sense bytes to follow this field
497 +       unchar cmnd_info[4];    // not used
498 +       unchar ASC;             // Additional Sense Code
499 +       unchar ASCQ;            // Additional Sense Code Qualifier
500 +       unchar FRUC;            // Field Replaceable Unit Code - not used
501 +       
502 +       unchar bit_ptr:3;       // indicates which byte of the CDB or parameter data
503 +                               // was in error
504 +       unchar BPV:1;           // bit pointer valid (BPV): 1- indicates that 
505 +                               // the bit_ptr field has valid value
506 +       unchar reserved2:2;
507 +       unchar CD:1;            // command data bit: 1- illegal parameter in CDB.
508 +                               //                   0- illegal parameter in data.
509 +       unchar SKSV:1;
510 +       
511 +       unchar field_ptr[2];    // byte of the CDB or parameter data in error
512 +};
513 +
514 +/*------------------------------------------------------------------------------
515 + *              G L O B A L S
516 + *----------------------------------------------------------------------------*/
517 +/*------------------------------------------------------------------------------
518 + *              M O D U L E   G L O B A L S
519 + *----------------------------------------------------------------------------*/
520 +static fsadev_t *g_fsa_dev_array[8];   // SCSI Device Instance Pointers
521 +static struct sense_data g_sense_data[MAXIMUM_NUM_CONTAINERS];
522 +
523 +/*------------------------------------------------------------------------------
524 + *              F U N C T I O N   P R O T O T Y P E S
525 + *----------------------------------------------------------------------------*/
526 +AAC_STATUS AacHba_OpenAdapter( PVOID AdapterArg);
527 +AAC_STATUS AacHba_CloseAdapter( PVOID AdapterArg);
528 +BOOLEAN AacHba_HandleAif( PVOID AdapterArg, PFIB_CONTEXT FibContext);
529 +BOOLEAN AacHba_AdapterDeviceControl ( PVOID AdapterArg, 
530 +       PAFA_IOCTL_CMD IoctlCmdPtr, int * ReturnStatus);
531 +
532 +void AacHba_CompleteScsi( 
533 +       Scsi_Cmnd *scsi_cmnd_ptr );
534 +
535 +void AacHba_CompleteScsiNoLock( 
536 +       Scsi_Cmnd *scsi_cmnd_ptr );
537 +
538 +static void AacHba_ReadCallback( 
539 +       void *Context, 
540 +       PFIB_CONTEXT FibContext, 
541 +       int FibStatus );
542 +
543 +static void AacHba_WriteCallback( 
544 +       void *Context, 
545 +       PFIB_CONTEXT FibContext, 
546 +       int FibStatus );
547 +
548 +int AacHba_DoScsiRead(
549 +       Scsi_Cmnd *scsi_cmnd_ptr,
550 +       int ContainerId,
551 +       int wait );
552 +
553 +int AacHba_DoScsiWrite(
554 +       Scsi_Cmnd *scsi_cmnd_ptr,
555 +       int ContainerId,
556 +       int wait );
557 +
558 +int AacHba_QueryDisk(
559 +       PVOID AdapterArg,               // CommonExtensionPtr
560 +       IN PAFA_IOCTL_CMD IoctlCmdPtr );
561 +
562 +int AacHba_ForceDeleteDisk(
563 +       PVOID AdapterArg,               // CommonExtensionPtr
564 +       IN PAFA_IOCTL_CMD IoctlCmdPtr );
565 +
566 +int AacHba_DeleteDisk(
567 +       PVOID AdapterArg,
568 +       IN PAFA_IOCTL_CMD IoctlCmdPtr );
569 +
570 +void AacHba_DetachAdapter(
571 +       IN PVOID AdapterArg );
572 +
573 +BOOLEAN AacCommDetachAdapter(
574 +       IN PAFA_COMM_ADAPTER Adapter );
575 +
576 +void AacHba_SetSenseData(
577 +       char * sense_buf,
578 +       unchar sense_key,
579 +       unchar sense_code,
580 +       unchar a_sense_code,
581 +       unchar incorrect_length,
582 +       unchar bit_pointer,
583 +       unsigned field_pointer,
584 +       unsigned long residue );
585 +
586 +static void get_sd_devname(
587 +       long disknum, 
588 +       char * buffer);
589 +
590 +// Keep these here for the time being - #REVIEW#
591 +int
592 +AfaCommAdapterDeviceControl (
593 +       IN PVOID AdapterArg,
594 +       IN PAFA_IOCTL_CMD       IoctlCmdPtr
595 +       );
596 +
597 +AAC_STATUS
598 +AfaCommRegisterNewClassDriver(
599 +       IN PAFA_COMM_ADAPTER    Adapter,
600 +       IN PAFA_NEW_CLASS_DRIVER        NewClassDriver,
601 +       OUT PAFA_NEW_CLASS_DRIVER_RESPONSE NewClassDriverResponse
602 +       );
603 +
604 +void
605 +SetInqDataStr (int, void *, int);
606 +/*------------------------------------------------------------------------------
607 + *              F U N C T I O N S
608 + *----------------------------------------------------------------------------*/
609 +
610 +/*------------------------------------------------------------------------------
611 +       AacHba_ClassDriverInit()
612 +
613 +               Setup 'core' class driver to answer ioctl's
614 + *----------------------------------------------------------------------------*/
615 +int AacHba_ClassDriverInit(
616 +       PCI_MINIPORT_COMMON_EXTENSION * CommonExtensionPtr)
617 +/*----------------------------------------------------------------------------*/
618 +{
619 +    AFA_NEW_CLASS_DRIVER                               NewClassDriver;
620 +       AFA_NEW_CLASS_DRIVER_RESPONSE           NewClassDriverResponse;
621 +       PAFA_COMM_ADAPTER                                       Adapter;
622 +
623 +       Adapter = (AFA_COMM_ADAPTER *)CommonExtensionPtr->Adapter;
624 +
625 +       RtlZeroMemory( &NewClassDriver, sizeof( AFA_NEW_CLASS_DRIVER ) );
626 +       
627 +       // ClassDriverExtension is the first argument passed to class driver functions below
628 +       NewClassDriver.ClassDriverExtension = CommonExtensionPtr;
629 +       
630 +       NewClassDriver.OpenAdapter = AacHba_OpenAdapter;
631 +       NewClassDriver.CloseAdapter = AacHba_CloseAdapter;
632 +       NewClassDriver.DeviceControl = AacHba_AdapterDeviceControl;
633 +       NewClassDriver.HandleAif = AacHba_HandleAif;
634 +       AfaCommRegisterNewClassDriver( Adapter, &NewClassDriver, &NewClassDriverResponse );
635 +
636 +       return(0);
637 +}
638 +
639 +
640 +/*------------------------------------------------------------------------------
641 +       AacHba_ProbeContainers()
642 +
643 +               Make a list of all containers in the system.
644 +------------------------------------------------------------------------------*/
645 +int AacHba_ProbeContainers (PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr)
646 +{
647 +       fsadev_t                                                *fsa_dev_ptr;
648 +       int                                                             Index, Status;
649 +       PMNTINFO                                                DiskInfo;
650 +       PMNTINFORESPONSE                                DiskInfoResponse;
651 +       PFIB_CONTEXT                                    FibContext;
652 +       AFA_COMM_ADAPTER                                *Adapter;
653 +       unsigned                                                instance;
654 +       char                            *bufp;
655 +       int                             size;
656 +
657 +
658 +       Adapter = ( AFA_COMM_ADAPTER * )CommonExtensionPtr->Adapter;
659 +       fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
660 +       instance = CommonExtensionPtr->OsDep.scsi_host_ptr->unique_id;
661 +
662 +       if( !( FibContext = Adapter->CommFuncs.AllocateFib( Adapter ) ) )
663 +       {
664 +               cmn_err( CE_WARN, "AacHba_ProbeContainers: AllocateFib failed" );
665 +               return( STATUS_UNSUCCESSFUL );
666 +       }
667 +
668 +    for ( Index = 0; Index < MAXIMUM_NUM_CONTAINERS; Index++ ) 
669 +       {
670 +               Adapter->CommFuncs.InitializeFib( FibContext );
671 +
672 +               DiskInfo = ( PMNTINFO )Adapter->CommFuncs.GetFibData( FibContext );
673 +
674 +               DiskInfo->Command  = VM_NameServe;
675 +               DiskInfo->MntCount = Index;
676 +               DiskInfo->MntType  = FT_FILESYS;
677 +               
678 +               Status =  Adapter->CommFuncs.SendFib(   ContainerCommand,
679 +                                                       FibContext,
680 +                                                       sizeof(MNTINFO),
681 +                                                       FsaNormal,
682 +                                                       TRUE,
683 +                                                       NULL,
684 +                                                       TRUE,
685 +                                                       NULL,
686 +                                                       NULL );
687 +               if ( Status ) 
688 +               {
689 +                       cmn_err( CE_WARN, "ProbeContainers: SendFIb Failed" );
690 +                       break;
691 +               }
692 +
693 +               DiskInfoResponse = ( PMNTINFORESPONSE )Adapter->CommFuncs.GetFibData( FibContext );
694 +               
695 +
696 +               if ( ( DiskInfoResponse->Status == ST_OK ) &&
697 +                       ( DiskInfoResponse->MntTable[0].VolType != CT_NONE ) ) 
698 +               {
699 +
700 +
701 +                       fsa_dev_ptr->ContainerValid[Index] = TRUE;
702 +                       fsa_dev_ptr->ContainerType[Index]  = DiskInfoResponse->MntTable[0].VolType;
703 +                       fsa_dev_ptr->ContainerSize[Index]  = DiskInfoResponse->MntTable[0].Capacity;
704 +
705 +                       if (DiskInfoResponse->MntTable[0].ContentState & FSCS_READONLY)
706 +                               fsa_dev_ptr->ContainerReadOnly[Index] = TRUE;
707 +               }
708 +               
709 +               Adapter->CommFuncs.CompleteFib( FibContext );
710 +
711 +               // If there are no more containers, then stop asking.
712 +               if ((Index + 1) >= DiskInfoResponse->MntRespCount)
713 +                       break;
714 +    } // end for()
715 +
716 +       Adapter->CommFuncs.FreeFib( FibContext );
717 +
718 +       g_fsa_dev_array[instance] = fsa_dev_ptr;
719 +       return( Status );
720 +}
721 +
722 +
723 +/*------------------------------------------------------------------------------
724 +       AacHba_ProbeContainer()
725 +
726 +               Probe a single container.
727 + *----------------------------------------------------------------------------*/
728 +int AacHba_ProbeContainer( 
729 +       PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr,
730 +       int ContainerId )
731 +/*----------------------------------------------------------------------------*/
732 +{
733 +       fsadev_t                                                *fsa_dev_ptr;
734 +    int                                                                Status;
735 +    PMNTINFO                                           DiskInfo;
736 +    PMNTINFORESPONSE                           DiskInfoResponse;
737 +       PFIB_CONTEXT                                    FibContext;
738 +       AFA_COMM_ADAPTER                                *Adapter;
739 +       unsigned                                                instance;
740 +       
741 +       Adapter = ( AFA_COMM_ADAPTER * )CommonExtensionPtr->Adapter;
742 +       fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
743 +       instance = CommonExtensionPtr->OsDep.scsi_host_ptr->unique_id;
744 +
745 +       if( !( FibContext = Adapter->CommFuncs.AllocateFib( Adapter ) ) )
746 +       {
747 +               cmn_err( CE_WARN, "AacHba_ProbeContainers: AllocateFib failed" );
748 +               return( STATUS_UNSUCCESSFUL );
749 +       }
750 +
751 +       Adapter->CommFuncs.InitializeFib( FibContext );
752 +
753 +       DiskInfo = ( PMNTINFO )Adapter->CommFuncs.GetFibData( FibContext );
754 +
755 +       DiskInfo->Command  = VM_NameServe;
756 +       DiskInfo->MntCount = ContainerId;
757 +       DiskInfo->MntType  = FT_FILESYS;
758 +               
759 +       Status =  Adapter->CommFuncs.SendFib (ContainerCommand,
760 +                                             FibContext,
761 +                                             sizeof(MNTINFO),
762 +                                             FsaNormal,
763 +                                             TRUE,
764 +                                             NULL,
765 +                                             TRUE,
766 +                                             NULL,
767 +                                             NULL );
768 +       if ( Status ) 
769 +       {
770 +               cmn_err( CE_WARN, "ProbeContainers: SendFIb Failed" );
771 +               Adapter->CommFuncs.CompleteFib( FibContext );
772 +               Adapter->CommFuncs.FreeFib( FibContext );
773 +               return( Status );
774 +       }
775 +
776 +       DiskInfoResponse = ( PMNTINFORESPONSE )Adapter->CommFuncs.GetFibData( FibContext );
777 +               
778 +
779 +       if ( ( DiskInfoResponse->Status == ST_OK ) &&
780 +               ( DiskInfoResponse->MntTable[0].VolType != CT_NONE ) ) 
781 +       {
782 +
783 +               fsa_dev_ptr->ContainerValid[ContainerId] = TRUE;
784 +               fsa_dev_ptr->ContainerType[ContainerId]  = DiskInfoResponse->MntTable[0].VolType;
785 +               fsa_dev_ptr->ContainerSize[ContainerId]  = DiskInfoResponse->MntTable[0].Capacity;
786 +               if (DiskInfoResponse->MntTable[0].ContentState & FSCS_READONLY)
787 +                       fsa_dev_ptr->ContainerReadOnly[ContainerId] = TRUE;
788 +       }
789 +               
790 +       Adapter->CommFuncs.CompleteFib( FibContext );
791 +       Adapter->CommFuncs.FreeFib( FibContext );
792 +
793 +       return( Status );
794 +}
795 +
796 +
797 +/*------------------------------------------------------------------------------
798 +       AacHba_CompleteScsi()
799 +
800 +               Call SCSI completion routine after acquiring io_request_lock
801 +
802 +       Preconditions:
803 +       Postconditions:
804 + *----------------------------------------------------------------------------*/
805 +void AacHba_CompleteScsi( 
806 +       Scsi_Cmnd *scsi_cmnd_ptr )
807 +{
808 +       unsigned long cpu_flags;
809 +
810 +       spin_lock_irqsave( &io_request_lock, cpu_flags );
811 +       scsi_cmnd_ptr->scsi_done( scsi_cmnd_ptr );
812 +       spin_unlock_irqrestore( &io_request_lock, cpu_flags );
813 +}
814 +
815 +
816 +/*------------------------------------------------------------------------------
817 +       AacHba_CompleteScsiNoLock()
818 +
819 +               Call SCSI completion routine
820 +
821 +       Preconditions:
822 +       Postconditions:
823 + *----------------------------------------------------------------------------*/
824 +void AacHba_CompleteScsiNoLock( 
825 +       Scsi_Cmnd *scsi_cmnd_ptr )
826 +{
827 +       scsi_cmnd_ptr->scsi_done( scsi_cmnd_ptr );
828 +}
829 +
830 +/*------------------------------------------------------------------------------
831 +       AacHba_DoScsiCmd()
832 +
833 +               Process SCSI command
834 +
835 +       Preconditions:
836 +       Postconditions:
837 +               Returns 0 on success, -1 on failure
838 + *----------------------------------------------------------------------------*/
839 +int AacHba_DoScsiCmd(
840 +       Scsi_Cmnd *scsi_cmnd_ptr,
841 +       int wait )
842 +{
843 +       int                     ContainerId = 0;
844 +       fsadev_t        *fsa_dev_ptr;
845 +       PCI_MINIPORT_COMMON_EXTENSION   *CommonExtensionPtr;
846 +       int MiniPortIndex;
847 +
848 +       CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
849 +       MiniPortIndex = CommonExtensionPtr->OsDep.MiniPortIndex;
850 +
851 +       fsa_dev_ptr = g_fsa_dev_array[ scsi_cmnd_ptr->host->unique_id ];
852 +
853 +       // If the bus, target or lun is out of range, return fail
854 +       // Test does not apply to ID 16, the pseudo id for the controller itself.
855 +       if ( scsi_cmnd_ptr->target != scsi_cmnd_ptr->host->this_id ) 
856 +       {
857 +               if( ( scsi_cmnd_ptr->channel > 0 ) ||
858 +                       ( scsi_cmnd_ptr->target > 15 ) || 
859 +                       ( scsi_cmnd_ptr->lun > 7 ) )
860 +               {
861 +                       cmn_err( CE_DEBUG, "The bus, target or lun is out of range = %d, %d, %d",
862 +                               scsi_cmnd_ptr->channel,
863 +                               scsi_cmnd_ptr->target, 
864 +                               scsi_cmnd_ptr->lun );
865 +                       scsi_cmnd_ptr->result = DID_BAD_TARGET << 16;
866 +
867 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
868 +
869 +                       return ( -1 );
870 +               }
871 +
872 +               ContainerId = TARGET_LUN_TO_CONTAINER( scsi_cmnd_ptr->target, scsi_cmnd_ptr->lun );
873 +
874 +
875 +               // If the target container doesn't exist, it may have been newly created
876 +               if( fsa_dev_ptr->ContainerValid[ContainerId] == 0 )
877 +               {       
878 +                       switch( scsi_cmnd_ptr->cmnd[0] )
879 +                       {
880 +                               case SS_INQUIR:
881 +                               case SS_RDCAP:
882 +                               case SS_TEST:
883 +                                       spin_unlock_irq( &io_request_lock );
884 +                                       AacHba_ProbeContainer( CommonExtensionPtr, ContainerId );               
885 +                                       spin_lock_irq( &io_request_lock );
886 +                               default:
887 +                                       break;
888 +                       }
889 +               }
890 +
891 +               // If the target container still doesn't exist, return failure
892 +               if( fsa_dev_ptr->ContainerValid[ContainerId] == 0 )
893 +               {       
894 +
895 +                       scsi_cmnd_ptr->result = DID_BAD_TARGET << 16;
896 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
897 +
898 +                       return ( -1 );
899 +               }
900 +       }
901 +       else    // the command is for the controller itself
902 +               if( ( scsi_cmnd_ptr->cmnd[0] != SS_INQUIR )     && // only INQUIRY & TUR cmnd supported for controller 
903 +                       ( scsi_cmnd_ptr->cmnd[0] != SS_TEST ) )
904 +               {
905 +                       cmn_err( CE_WARN, "Only INQUIRY & TUR command supported for controller, rcvd = 0x%x", 
906 +                               scsi_cmnd_ptr->cmnd[0] );
907 +
908 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
909 +                       
910 +                       AacHba_SetSenseData( (char *)&g_sense_data[ ContainerId ],
911 +                               SENKEY_ILLEGAL, SENCODE_INVALID_COMMAND, ASENCODE_INVALID_COMMAND, 
912 +                               0, 0, 0, 0 );
913 +
914 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
915 +
916 +                       return ( -1 );
917 +               }
918 +
919 +       // Handle commands here that don't really require going out to the adapter
920 +       switch ( scsi_cmnd_ptr->cmnd[0] ) 
921 +       {
922 +               case SS_INQUIR:
923 +               {
924 +                       struct inquiry_data *inq_data_ptr;
925 +               
926 +                       cmn_err( CE_DEBUG, "INQUIRY command, ID: %d", scsi_cmnd_ptr->target );
927 +                       inq_data_ptr = ( struct inquiry_data * )scsi_cmnd_ptr->request_buffer;
928 +                       bzero( inq_data_ptr, sizeof( struct inquiry_data ) );
929 +
930 +                       inq_data_ptr->inqd_ver = 2;             // claim compliance to SCSI-2
931 +
932 +                       inq_data_ptr->inqd_dtq = 0x80;  // set RMB bit to one indicating 
933 +                                                                                       // that the medium is removable
934 +                       inq_data_ptr->inqd_rdf = 2;             // A response data format value of
935 +                                                                                       // two indicates that the data shall 
936 +                                                                                       // be in the format specified in SCSI-2
937 +                       inq_data_ptr->inqd_len = 31;
938 +
939 +                       // Set the Vendor, Product, and Revision Level see: <vendor>.c i.e. aac.c
940 +                       SetInqDataStr(  MiniPortIndex, 
941 +                                                       (void *)(inq_data_ptr->inqd_vid),
942 +                                                       fsa_dev_ptr->ContainerType[ContainerId]);
943 +
944 +                       if ( scsi_cmnd_ptr->target == scsi_cmnd_ptr->host->this_id )
945 +                               inq_data_ptr->inqd_pdt = INQD_PDT_PROC; // Processor device
946 +                       else
947 +                               inq_data_ptr->inqd_pdt = INQD_PDT_DA;   // Direct/random access device
948 +
949 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
950 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
951 +
952 +                       return ( 0 );
953 +               }
954 +
955 +               case SS_RDCAP:
956 +               {
957 +                       int capacity;
958 +                       char *cp;
959 +
960 +                       cmn_err( CE_DEBUG, "READ CAPACITY command" );
961 +                       capacity = fsa_dev_ptr->ContainerSize[ContainerId];
962 +                       cp = scsi_cmnd_ptr->request_buffer;
963 +                       cp[0] = ( capacity >> 24 ) & 0xff;
964 +                       cp[1] = ( capacity >> 16 ) & 0xff;
965 +                       cp[2] = ( capacity >>  8 ) & 0xff;
966 +                       cp[3] = ( capacity >>  0 ) & 0xff;
967 +                       cp[4] = 0;
968 +                       cp[5] = 0;
969 +                       cp[6] = 2;
970 +                       cp[7] = 0;
971 +       
972 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
973 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
974 +
975 +                       return ( 0 );
976 +               }
977 +
978 +               case SS_MODESEN:
979 +               {
980 +                       char *mode_buf;
981 +
982 +                       cmn_err( CE_DEBUG, "MODE SENSE command" );
983 +                       mode_buf = scsi_cmnd_ptr->request_buffer;
984 +                       mode_buf[0] = 0;        // Mode data length (MSB)
985 +                       mode_buf[1] = 6;        // Mode data length (LSB)
986 +                       mode_buf[2] = 0;        // Medium type - default
987 +                       mode_buf[3] = 0;        // Device-specific param, bit 8: 0/1 = write enabled/protected
988 +                       mode_buf[4] = 0;        // reserved
989 +                       mode_buf[5] = 0;        // reserved
990 +                       mode_buf[6] = 0;        // Block descriptor length (MSB)
991 +                       mode_buf[7] = 0;        // Block descriptor length (LSB)
992 +       
993 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
994 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
995 +
996 +                       return ( 0 );
997 +               }
998 +
999 +
1000 +               // These commands are all No-Ops
1001 +               case SS_TEST:
1002 +                       cmn_err( CE_DEBUG, "TEST UNIT READY command" );
1003 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1004 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1005 +                       return ( 0 );
1006 +
1007 +               case SS_REQSEN:
1008 +                       cmn_err( CE_DEBUG, "REQUEST SENSE command" );
1009 +
1010 +                       memcpy( scsi_cmnd_ptr->sense_buffer, &g_sense_data[ContainerId],
1011 +                               sizeof( struct sense_data ) );
1012 +                       bzero( &g_sense_data[ContainerId], sizeof( struct sense_data ) );
1013 +
1014 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1015 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1016 +                       return ( 0 );
1017 +
1018 +               case SS_LOCK:
1019 +                       cmn_err(CE_DEBUG, "LOCK command");
1020 +
1021 +                       if( scsi_cmnd_ptr->cmnd[4] )
1022 +                               fsa_dev_ptr->ContainerLocked[ContainerId] = 1;
1023 +                       else
1024 +                               fsa_dev_ptr->ContainerLocked[ContainerId] = 0;
1025 +
1026 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1027 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1028 +                       return ( 0 );
1029 +
1030 +               case SS_RESERV:
1031 +                       cmn_err( CE_DEBUG, "RESERVE command" );
1032 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1033 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1034 +                       return ( 0 );
1035 +
1036 +               case SS_RELES:
1037 +                       cmn_err( CE_DEBUG, "RELEASE command" );
1038 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1039 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1040 +                       return ( 0 );
1041 +
1042 +               case SS_REZERO:
1043 +                       cmn_err( CE_DEBUG, "REZERO command" );
1044 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1045 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1046 +                       return ( 0 );
1047 +
1048 +               case SS_REASGN:
1049 +                       cmn_err( CE_DEBUG, "REASSIGN command" );
1050 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1051 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1052 +                       return ( 0 );
1053 +
1054 +               case SS_SEEK:
1055 +                       cmn_err( CE_DEBUG, "SEEK command" );
1056 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1057 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1058 +                       return ( 0 );
1059 +
1060 +               case SS_ST_SP:
1061 +                       cmn_err( CE_DEBUG, "START/STOP command" );
1062 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1063 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1064 +                       return ( 0 );
1065 +       }
1066 +
1067 +       switch ( scsi_cmnd_ptr->cmnd[0] ) 
1068 +       {
1069 +               case SS_READ:
1070 +               case SM_READ:
1071 +                       // Hack to keep track of ordinal number of the device that corresponds
1072 +                       // to a container. Needed to convert containers to /dev/sd device names
1073 +                       fsa_dev_ptr->ContainerDevNo[ContainerId] = 
1074 +                               DEVICE_NR( scsi_cmnd_ptr->request.rq_dev );
1075 +
1076 +                       return( AacHba_DoScsiRead( scsi_cmnd_ptr, ContainerId,  wait ) );
1077 +                       break;
1078 +
1079 +               case SS_WRITE:
1080 +               case SM_WRITE:
1081 +
1082 +                       return( AacHba_DoScsiWrite( scsi_cmnd_ptr, ContainerId,  wait ) );
1083 +                       break;
1084 +       }
1085 +       //
1086 +       // Unhandled commands
1087 +       //
1088 +       cmn_err( CE_WARN, "Unhandled SCSI Command: 0x%x", scsi_cmnd_ptr->cmnd[0] );
1089 +       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1090 +
1091 +       AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1092 +               SENKEY_ILLEGAL, SENCODE_INVALID_COMMAND, ASENCODE_INVALID_COMMAND, 
1093 +               0, 0, 0, 0 );
1094 +
1095 +       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1096 +       return ( -1 );
1097 +}
1098 +
1099 +
1100 +/*------------------------------------------------------------------------------
1101 +       AacHba_DoScsiRead()
1102 +               
1103 +               Handles SCSI READ requests
1104 +
1105 +       Preconditions:
1106 +       Postconditions:
1107 +               Returns 0 on success, -1 on failure
1108 + *----------------------------------------------------------------------------*/
1109 +int AacHba_DoScsiRead(
1110 +       Scsi_Cmnd *scsi_cmnd_ptr,
1111 +       int ContainerId,
1112 +       int wait )
1113 +/*----------------------------------------------------------------------------*/
1114 +{
1115 +       u_long                          lba;
1116 +       u_long                          count;
1117 +       u_long                          byte_count;
1118 +       int                                     Status;
1119 +
1120 +       PBLOCKREAD                      BlockReadDisk;
1121 +       PBLOCKREADRESPONSE      BlockReadResponse;
1122 +       uint16_t                        FibSize;
1123 +       PCI_MINIPORT_COMMON_EXTENSION   *CommonExtension;
1124 +       AFA_COMM_ADAPTER                                *Adapter;
1125 +       PFIB_CONTEXT                                    cmd_fibcontext;
1126 +
1127 +       CommonExtension = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
1128 +       Adapter         = ( AFA_COMM_ADAPTER * )CommonExtension->Adapter;
1129 +
1130 +       // Get block address and transfer length
1131 +       if ( scsi_cmnd_ptr->cmnd[0] == SS_READ ) // 6 byte command
1132 +       {
1133 +               cmn_err( CE_DEBUG, "aachba: received a read(6) command on target %d", ContainerId );
1134 +
1135 +               lba = ( ( scsi_cmnd_ptr->cmnd[1] & 0x1F ) << 16 ) | 
1136 +                       ( scsi_cmnd_ptr->cmnd[2] << 8 ) |
1137 +                       scsi_cmnd_ptr->cmnd[3];
1138 +               count = scsi_cmnd_ptr->cmnd[4];
1139 +
1140 +               if ( count == 0 )
1141 +                       count = 256;
1142 +       } 
1143 +       else 
1144 +       {               
1145 +               cmn_err( CE_DEBUG, "aachba: received a read(10) command on target %d", ContainerId );
1146 +               
1147 +               lba = ( scsi_cmnd_ptr->cmnd[2] << 24 ) | ( scsi_cmnd_ptr->cmnd[3] << 16 ) | 
1148 +                       ( scsi_cmnd_ptr->cmnd[4] << 8 ) | scsi_cmnd_ptr->cmnd[5];
1149 +
1150 +               count = ( scsi_cmnd_ptr->cmnd[7] << 8 ) | scsi_cmnd_ptr->cmnd[8];
1151 +       }       
1152 +       cmn_err( CE_DEBUG, "AacHba_DoScsiRead[cpu %d]: lba = %lu, t = %ld", smp_processor_id(), lba, jiffies );
1153 +
1154 +       //-------------------------------------------------------------------------
1155 +       // Alocate and initialize a Fib
1156 +       //  Setup BlockRead command
1157 +       if( !( cmd_fibcontext = Adapter->CommFuncs.AllocateFib( Adapter ) ) )
1158 +       {
1159 +               cmn_err( CE_WARN, "AacHba_DoScsiRead: AllocateFib failed\n" );
1160 +               scsi_cmnd_ptr->result = DID_ERROR << 16;
1161 +               AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1162 +               return ( -1 );
1163 +       }
1164 +
1165 +    Adapter->CommFuncs.InitializeFib( cmd_fibcontext );
1166 +
1167 +       BlockReadDisk = ( PBLOCKREAD )Adapter->CommFuncs.GetFibData( cmd_fibcontext );
1168 +       BlockReadDisk->Command     = VM_CtBlockRead;
1169 +       BlockReadDisk->ContainerId = ContainerId;
1170 +       BlockReadDisk->BlockNumber = lba;
1171 +       BlockReadDisk->ByteCount   = count * 512;
1172 +       BlockReadDisk->SgMap.SgCount = 1;
1173 +
1174 +       if( BlockReadDisk->ByteCount > ( 64 * 1024 ) )
1175 +       {
1176 +               cmn_err( CE_WARN, "AacHba_DoScsiRead: READ request is larger than 64K" );
1177 +               scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1178 +
1179 +               AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1180 +                               SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD, 
1181 +                               0, 0, 7, 0 );
1182 +
1183 +               goto err_return;
1184 +       }
1185 +
1186 +       //-------------------------------------------------------------------------
1187 +       // Build Scatter/Gather list
1188 +       //
1189 +       if ( scsi_cmnd_ptr->use_sg )    // use scatter/gather list
1190 +       {
1191 +               struct scatterlist *scatterlist_ptr;
1192 +               int segment;
1193 +               
1194 +               scatterlist_ptr = ( struct scatterlist * )scsi_cmnd_ptr->request_buffer;
1195 +
1196 +               byte_count = 0;
1197 +               for( segment = 0; segment< scsi_cmnd_ptr->use_sg; segment++ ) 
1198 +               {
1199 +                       BlockReadDisk->SgMap.SgEntry[segment].SgAddress = 
1200 +                               ( void * )OsVirtToPhys( scatterlist_ptr[segment].address );
1201 +                       BlockReadDisk->SgMap.SgEntry[segment].SgByteCount = 
1202 +                               scatterlist_ptr[segment].length;
1203 +
1204 +#ifdef DEBUG_SGBUFFER
1205 +                       memset( scatterlist_ptr[segment].address, 0xa5, 
1206 +                               scatterlist_ptr[segment].length );
1207 +#endif
1208 +
1209 +                       byte_count += scatterlist_ptr[segment].length;
1210 +                       
1211 +                       if( BlockReadDisk->SgMap.SgEntry[segment].SgByteCount > ( 64 * 1024 ) )
1212 +                       {
1213 +                               cmn_err( CE_WARN, "AacHba_DoScsiRead: Segment byte count is larger than 64K" );
1214 +                               scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1215 +
1216 +                               AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1217 +                                       SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD, 
1218 +                                       0, 0, 7, 0 );
1219 +
1220 +                               goto err_return;
1221 +                       }
1222 +                       /*
1223 +                       cmn_err(CE_DEBUG, "SgEntry[%d].SgAddress = 0x%x, Byte count = 0x%x", 
1224 +                                       segment,
1225 +                                       BlockReadDisk->SgMap.SgEntry[segment].SgAddress,
1226 +                                       BlockReadDisk->SgMap.SgEntry[segment].SgByteCount);
1227 +                       */
1228 +               }
1229 +               BlockReadDisk->SgMap.SgCount = scsi_cmnd_ptr->use_sg;
1230 +
1231 +               if( BlockReadDisk->SgMap.SgCount > MAX_DRIVER_SG_SEGMENT_COUNT ) 
1232 +               {
1233 +                       cmn_err( CE_WARN, "AacHba_DoScsiRead: READ request with SgCount > %d", 
1234 +                               MAX_DRIVER_SG_SEGMENT_COUNT );
1235 +                       scsi_cmnd_ptr->result = DID_ERROR << 16;
1236 +                       goto err_return;
1237 +               }
1238 +       }       
1239 +       else            // one piece of contiguous phys mem
1240 +       {
1241 +               BlockReadDisk->SgMap.SgEntry[0].SgAddress = 
1242 +                       ( void * )OsVirtToPhys( scsi_cmnd_ptr->request_buffer );
1243 +               BlockReadDisk->SgMap.SgEntry[0].SgByteCount = scsi_cmnd_ptr->request_bufflen;
1244 +
1245 +               byte_count = scsi_cmnd_ptr->request_bufflen;
1246 +
1247 +               if( BlockReadDisk->SgMap.SgEntry[0].SgByteCount > ( 64 * 1024 ) )
1248 +               {
1249 +                       cmn_err( CE_WARN, "AacHba_DoScsiRead: Single segment byte count is larger than 64K" );
1250 +                       cmn_err( CE_WARN, "AacHba_DoScsiRead: ByteCount: %d", BlockReadDisk->ByteCount);
1251 +                       cmn_err( CE_WARN, "AacHba_DoScsiRead: SG ELEMENTS: %d", scsi_cmnd_ptr->use_sg);
1252 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1253 +
1254 +                       AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1255 +                               SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD, 
1256 +                               0, 0, 7, 0 );
1257 +
1258 +                       goto err_return;
1259 +               }
1260 +       }
1261 +
1262 +       if( byte_count != BlockReadDisk->ByteCount )
1263 +               cmn_err( CE_WARN, "AacHba_DoScsiRead: byte_count != BlockReadDisk->ByteCount" );
1264 +
1265 +       //-------------------------------------------------------------------------
1266 +       // Now send the Fib to the adapter
1267 +       //
1268 +       FibSize = sizeof( BLOCKREAD ) + ( ( BlockReadDisk->SgMap.SgCount - 1 ) * sizeof( SGENTRY ) );
1269 +
1270 +       if( wait ) 
1271 +       {
1272 +               Status = Adapter->CommFuncs.SendFib( ContainerCommand,
1273 +                                                                                        cmd_fibcontext,
1274 +                                                                                        FibSize,
1275 +                                                                                        FsaNormal,
1276 +                                                                                        TRUE,
1277 +                                                                                        NULL,
1278 +                                                                                        TRUE,
1279 +                                                                                        NULL,
1280 +                                                                                        NULL);
1281 +
1282 +               BlockReadResponse = ( PBLOCKREADRESPONSE )
1283 +                       Adapter->CommFuncs.GetFibData( cmd_fibcontext );        
1284 +
1285 +               Adapter->CommFuncs.CompleteFib( cmd_fibcontext );
1286 +               Adapter->CommFuncs.FreeFib( cmd_fibcontext );
1287 +               
1288 +               if( BlockReadResponse->Status != ST_OK )
1289 +               {
1290 +                       cmn_err( CE_WARN, "AacHba_DoScsiRead: BlockReadCommand failed with status: %d", 
1291 +                               BlockReadResponse->Status );
1292 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1293 +
1294 +                       AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1295 +                               SENKEY_HW_ERR, SENCODE_INTERNAL_TARGET_FAILURE, ASENCODE_INTERNAL_TARGET_FAILURE, 
1296 +                               0, 0, 0, 0 );
1297 +
1298 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1299 +                       return ( -1 );
1300 +               }
1301 +               else
1302 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1303 +
1304 +               AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1305 +               return ( 0 );
1306 +       } 
1307 +       else 
1308 +       {
1309 +               Status = Adapter->CommFuncs.SendFib( ContainerCommand,
1310 +                                                                                        cmd_fibcontext,
1311 +                                                                                        FibSize,
1312 +                                                                                        FsaNormal,
1313 +                                                                                        FALSE,
1314 +                                                                                        NULL,
1315 +                                                                                        TRUE,
1316 +                                                                                        ( PFIB_CALLBACK )AacHba_ReadCallback,
1317 +                                                                                        ( void *)scsi_cmnd_ptr );
1318 +               // don't call done func here
1319 +               return ( 0 );
1320 +       }
1321 +
1322 +err_return:
1323 +       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1324 +
1325 +       Adapter->CommFuncs.CompleteFib( cmd_fibcontext );
1326 +       Adapter->CommFuncs.FreeFib( cmd_fibcontext );
1327 +
1328 +       return ( -1 );
1329 +}
1330 +
1331 +
1332 +/*------------------------------------------------------------------------------
1333 +       AacHba_DoScsiWrite()
1334 +
1335 +               Handles SCSI WRITE requests
1336 +       
1337 +       Preconditions:
1338 +       Postconditions:
1339 +               Returns 0 on success, -1 on failure
1340 + *----------------------------------------------------------------------------*/
1341 +int AacHba_DoScsiWrite(
1342 +       Scsi_Cmnd *scsi_cmnd_ptr,
1343 +       int ContainerId,
1344 +       int wait )
1345 +/*----------------------------------------------------------------------------*/
1346 +{
1347 +       u_long                          lba;
1348 +       u_long                          count;
1349 +       u_long                          byte_count;
1350 +       int                                     Status;
1351 +
1352 +       PBLOCKWRITE                                             BlockWriteDisk;
1353 +       PBLOCKWRITERESPONSE                             BlockWriteResponse;
1354 +       uint16_t                                                FibSize;
1355 +       PCI_MINIPORT_COMMON_EXTENSION   *CommonExtension;
1356 +       AFA_COMM_ADAPTER                                *Adapter;
1357 +       PFIB_CONTEXT                                    cmd_fibcontext;
1358 +
1359 +       CommonExtension = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
1360 +       Adapter         = ( AFA_COMM_ADAPTER * )CommonExtension->Adapter;
1361 +
1362 +       // Get block address and transfer length
1363 +       if ( scsi_cmnd_ptr->cmnd[0] == SS_WRITE ) // 6 byte command
1364 +       {
1365 +               lba = ( ( scsi_cmnd_ptr->cmnd[1] & 0x1F ) << 16 ) | 
1366 +                       ( scsi_cmnd_ptr->cmnd[2] << 8 ) |
1367 +                       scsi_cmnd_ptr->cmnd[3];
1368 +               count = scsi_cmnd_ptr->cmnd[4];
1369 +
1370 +               if ( count == 0 )
1371 +                       count = 256;
1372 +       } 
1373 +       else 
1374 +       {               
1375 +               cmn_err( CE_DEBUG, "aachba: received a write(10) command on target %d", ContainerId );
1376 +               
1377 +               lba = ( scsi_cmnd_ptr->cmnd[2] << 24 ) | ( scsi_cmnd_ptr->cmnd[3] << 16 ) | 
1378 +                       ( scsi_cmnd_ptr->cmnd[4] << 8 ) | scsi_cmnd_ptr->cmnd[5];
1379 +
1380 +               count = ( scsi_cmnd_ptr->cmnd[7] << 8 ) | scsi_cmnd_ptr->cmnd[8];
1381 +
1382 +       }       
1383 +       cmn_err( CE_DEBUG, "AacHba_DoScsiWrite[cpu %d]: lba = %lu, t = %ld", smp_processor_id(), lba, jiffies );
1384 +
1385 +       //-------------------------------------------------------------------------
1386 +       // Alocate and initialize a Fib
1387 +       //  Setup BlockWrite command
1388 +       if( !( cmd_fibcontext = Adapter->CommFuncs.AllocateFib( Adapter ) ) ) 
1389 +       {
1390 +               cmn_err( CE_WARN, "AacHba_DoScsiWrite: AllocateFib failed\n" );
1391 +               scsi_cmnd_ptr->result = DID_ERROR << 16;
1392 +               AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1393 +               return ( -1 );
1394 +       }
1395 +
1396 +    Adapter->CommFuncs.InitializeFib( cmd_fibcontext );
1397 +
1398 +       BlockWriteDisk = (PBLOCKWRITE) Adapter->CommFuncs.GetFibData( cmd_fibcontext );
1399 +       BlockWriteDisk->Command     = VM_CtBlockWrite;
1400 +       BlockWriteDisk->ContainerId = ContainerId;
1401 +       BlockWriteDisk->BlockNumber = lba;
1402 +       BlockWriteDisk->ByteCount   = count * 512;
1403 +       BlockWriteDisk->SgMap.SgCount = 1;
1404 +
1405 +
1406 +       if ( BlockWriteDisk->ByteCount > ( 64 * 1024 ) )
1407 +         {
1408 +                 struct scatterlist *scatterlist_ptr;
1409 +                 int segment;
1410 +                 scatterlist_ptr = (struct scatterlist *)scsi_cmnd_ptr->request_buffer;
1411 +
1412 +                 cmn_err( CE_WARN, "\n");
1413 +                 cmn_err( CE_WARN, "AacHba_`DoScsiWrite: WRITE request is larger than 64K");
1414 +                 cmn_err( CE_WARN, "AacHba_DoScsiWrite: ByteCount: %d", BlockWriteDisk->ByteCount);
1415 +/*               cmn_err( CE_WARN, "AacHba_DoScsiWrite: SG ELEMENTS: %d", scsi_cmnd_ptr->use_sg); */
1416 +/*               cmn_err( CE_WARN, "Dump SG Element Size..."); */
1417 +/*               for( segment = 0; segment < scsi_cmnd_ptr->use_sg; segment++ )  */
1418 +/*               { */
1419 +/*                       cmn_err (CE_WARN, "SG Segment %d: %d", segment, scatterlist_ptr[segment].length); */
1420 +/*               } */
1421 +/*               cmn_err (CE_WARN, "\n"); */
1422 +
1423 +               scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1424 +
1425 +               AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1426 +                               SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD, 
1427 +                               0, 0, 7, 0 );
1428 +
1429 +               goto err_return;
1430 +       }
1431 +
1432 +       //-------------------------------------------------------------------------
1433 +       // Build Scatter/Gather list
1434 +       //
1435 +       if ( scsi_cmnd_ptr->use_sg )    // use scatter/gather list
1436 +       {
1437 +               struct scatterlist *scatterlist_ptr;
1438 +               int segment;
1439 +               
1440 +               scatterlist_ptr = ( struct scatterlist * )scsi_cmnd_ptr->request_buffer;
1441 +
1442 +               byte_count = 0;
1443 +               for( segment = 0; segment< scsi_cmnd_ptr->use_sg; segment++ ) 
1444 +               {
1445 +                       BlockWriteDisk->SgMap.SgEntry[segment].SgAddress = 
1446 +                               ( HOSTADDRESS )OsVirtToPhys( scatterlist_ptr[segment].address );
1447 +                       BlockWriteDisk->SgMap.SgEntry[segment].SgByteCount = 
1448 +                               scatterlist_ptr[segment].length;
1449 +                       
1450 +                       byte_count += scatterlist_ptr[segment].length;
1451 +
1452 +                       if ( BlockWriteDisk->SgMap.SgEntry[segment].SgByteCount > ( 64 * 1024 ) )
1453 +                       {
1454 +                               cmn_err( CE_WARN, "AacHba_DoScsiWrite: Segment byte count is larger than 64K" );
1455 +                               scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1456 +
1457 +                               AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1458 +                                       SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD, 
1459 +                                       0, 0, 7, 0 );
1460 +
1461 +                               goto err_return;
1462 +                       }
1463 +
1464 +                       /*
1465 +                       cmn_err(CE_DEBUG, "SgEntry[%d].SgAddress = 0x%x, Byte count = 0x%x", 
1466 +                                       segment,
1467 +                                       BlockWriteDisk->SgMap.SgEntry[segment].SgAddress,
1468 +                                       BlockWriteDisk->SgMap.SgEntry[segment].SgByteCount); 
1469 +                       */
1470 +               }
1471 +               BlockWriteDisk->SgMap.SgCount = scsi_cmnd_ptr->use_sg;
1472 +
1473 +               if( BlockWriteDisk->SgMap.SgCount > MAX_DRIVER_SG_SEGMENT_COUNT ) 
1474 +               {
1475 +                       cmn_err( CE_WARN, "AacHba_DoScsiWrite: WRITE request with SgCount > %d", 
1476 +                               MAX_DRIVER_SG_SEGMENT_COUNT );
1477 +                       scsi_cmnd_ptr->result = DID_ERROR << 16;
1478 +                       goto err_return;
1479 +               }
1480 +       } 
1481 +       else            // one piece of contiguous phys mem
1482 +       {
1483 +               BlockWriteDisk->SgMap.SgEntry[0].SgAddress = 
1484 +                       ( HOSTADDRESS )OsVirtToPhys( scsi_cmnd_ptr->request_buffer );
1485 +               BlockWriteDisk->SgMap.SgEntry[0].SgByteCount = scsi_cmnd_ptr->request_bufflen;
1486 +
1487 +               byte_count = scsi_cmnd_ptr->request_bufflen;
1488 +
1489 +               if ( BlockWriteDisk->SgMap.SgEntry[0].SgByteCount > ( 64 * 1024 ) )
1490 +               {
1491 +                       cmn_err( CE_WARN, "AacHba_DoScsiWrite: Single segment byte count is larger than 64K" );
1492 +
1493 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1494 +                       AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1495 +                               SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD, 
1496 +                               0, 0, 7, 0 );
1497 +
1498 +                       goto err_return;
1499 +               }
1500 +       }
1501 +
1502 +       if( byte_count != BlockWriteDisk->ByteCount )
1503 +         cmn_err( CE_WARN, "AacHba_DoScsiWrite: byte_count != BlockReadDisk->ByteCount" );
1504 +
1505 +       //-------------------------------------------------------------------------
1506 +       // Now send the Fib to the adapter
1507 +       //
1508 +       FibSize = sizeof( BLOCKWRITE ) + ( ( BlockWriteDisk->SgMap.SgCount - 1 ) * sizeof( SGENTRY ) );
1509 +
1510 +       if( wait ) 
1511 +       {
1512 +               Status = Adapter->CommFuncs.SendFib( ContainerCommand,
1513 +                                                                                        cmd_fibcontext,
1514 +                                                                                        FibSize,
1515 +                                                                                        FsaNormal,
1516 +                                                                                        TRUE,
1517 +                                                                                        NULL,
1518 +                                                                                        TRUE,
1519 +                                                                                        NULL,
1520 +                                                                                        NULL );
1521 +
1522 +               BlockWriteResponse = ( PBLOCKWRITERESPONSE ) 
1523 +                       Adapter->CommFuncs.GetFibData( cmd_fibcontext );        
1524 +
1525 +               Adapter->CommFuncs.CompleteFib(  cmd_fibcontext );
1526 +               Adapter->CommFuncs.FreeFib(  cmd_fibcontext );
1527 +
1528 +               if( BlockWriteResponse->Status != ST_OK )
1529 +               {
1530 +                       cmn_err( CE_WARN, "AacHba_DoScsiWrite: BlockWriteCommand failed with status: %d\n", 
1531 +                               BlockWriteResponse->Status );
1532 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;;
1533 +                       AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1534 +                               SENKEY_HW_ERR, SENCODE_INTERNAL_TARGET_FAILURE, ASENCODE_INTERNAL_TARGET_FAILURE, 
1535 +                               0, 0, 0, 0 );
1536 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1537 +                       return ( -1 );
1538 +               }
1539 +               else
1540 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1541 +
1542 +               AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1543 +               return ( 0 );
1544 +       } 
1545 +       else 
1546 +       {
1547 +               Status = Adapter->CommFuncs.SendFib( ContainerCommand,
1548 +                                                                                        cmd_fibcontext,
1549 +                                                                                        FibSize,
1550 +                                                                                        FsaNormal,
1551 +                                                                                        FALSE,
1552 +                                                                                        NULL,
1553 +                                                                                        TRUE,
1554 +                                                                                        ( PFIB_CALLBACK )AacHba_WriteCallback,
1555 +                                                                                        ( void * )scsi_cmnd_ptr );
1556 +
1557 +               // don't call done func here - it should be called by the WriteCallback
1558 +               return ( 0 );
1559 +       }
1560 +
1561 +err_return:
1562 +       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1563 +
1564 +       Adapter->CommFuncs.CompleteFib( cmd_fibcontext );
1565 +       Adapter->CommFuncs.FreeFib( cmd_fibcontext );
1566 +
1567 +       return ( -1 );
1568 +}
1569 +
1570 +
1571 +/*------------------------------------------------------------------------------
1572 +       AacHba_ReadCallback()
1573 + *----------------------------------------------------------------------------*/
1574 +void AacHba_ReadCallback(  
1575 +       VOID                    *Context,
1576 +       PFIB_CONTEXT    FibContext,
1577 +       int                             FibStatus )
1578 +/*----------------------------------------------------------------------------*/
1579 +{
1580 +       PCI_MINIPORT_COMMON_EXTENSION   *CommonExtension;
1581 +       AFA_COMM_ADAPTER                                *Adapter;
1582 +       BLOCKREADRESPONSE                               *BlockReadResponse;
1583 +       Scsi_Cmnd * scsi_cmnd_ptr;
1584 +       u_long                                                  lba;
1585 +       int                     ContainerId;
1586 +
1587 +       scsi_cmnd_ptr = ( Scsi_Cmnd * )Context;
1588 +
1589 +       CommonExtension = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
1590 +       Adapter         = ( AFA_COMM_ADAPTER * )CommonExtension->Adapter;
1591 +
1592 +       ContainerId = TARGET_LUN_TO_CONTAINER( scsi_cmnd_ptr->target, scsi_cmnd_ptr->lun );
1593 +       
1594 +       lba = ( ( scsi_cmnd_ptr->cmnd[1] & 0x1F ) << 16 ) | 
1595 +                       ( scsi_cmnd_ptr->cmnd[2] << 8 ) |
1596 +                       scsi_cmnd_ptr->cmnd[3];
1597 +       cmn_err( CE_DEBUG, "AacHba_ReadCallback[cpu %d]: lba = %ld, t = %ld", smp_processor_id(), lba, jiffies );
1598 +
1599 +       if( FibContext == 0 ) 
1600 +       {
1601 +               cmn_err( CE_WARN, "AacHba_ReadCallback: no fib context" );
1602 +               scsi_cmnd_ptr->result = DID_ERROR << 16;
1603 +               AacHba_CompleteScsi( scsi_cmnd_ptr );
1604 +               return;
1605 +       }
1606 +
1607 +    BlockReadResponse = ( PBLOCKREADRESPONSE )Adapter->CommFuncs.GetFibData( FibContext );
1608 +
1609 +       if ( BlockReadResponse->Status == ST_OK ) 
1610 +               scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1611 +       else 
1612 +       {
1613 +               cmn_err( CE_WARN, "AacHba_ReadCallback: read failed, status = %d\n", 
1614 +                       BlockReadResponse->Status );
1615 +               scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1616 +               AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1617 +                       SENKEY_HW_ERR, SENCODE_INTERNAL_TARGET_FAILURE, ASENCODE_INTERNAL_TARGET_FAILURE, 
1618 +                       0, 0, 0, 0 );
1619 +       }
1620 +
1621 +#ifdef DEBUG_SGBUFFER
1622 +       if ( scsi_cmnd_ptr->use_sg )    // use scatter/gather list
1623 +       {
1624 +               struct scatterlist *scatterlist_ptr;
1625 +               int i, segment, count;
1626 +               char *ptr;
1627 +               
1628 +               scatterlist_ptr = ( struct scatterlist * )scsi_cmnd_ptr->request_buffer;
1629 +
1630 +               for( segment = 0; segment < scsi_cmnd_ptr->use_sg; segment++ ) 
1631 +               {
1632 +                       count = 0;
1633 +                       ptr = scatterlist_ptr[segment].address;
1634 +                       for( i = 0; i < scatterlist_ptr[segment].length; i++ )
1635 +                       {
1636 +                               if( *( ptr++ ) == 0xa5 )
1637 +                                       count++;
1638 +                       }
1639 +                       if( count == scatterlist_ptr[segment].length )
1640 +                               cmn_err( CE_WARN, "AacHba_ReadCallback: segment %d not filled", segment );
1641 +
1642 +               }
1643 +       }
1644 +#endif
1645 +
1646 +       Adapter->CommFuncs.CompleteFib( FibContext );
1647 +       Adapter->CommFuncs.FreeFib( FibContext );
1648 +
1649 +       AacHba_CompleteScsi( scsi_cmnd_ptr );
1650 +}
1651 +
1652 +/*------------------------------------------------------------------------------
1653 +       AacHba_WriteCallback()
1654 + *----------------------------------------------------------------------------*/
1655 +void AacHba_WriteCallback(  
1656 +       VOID                    *Context,
1657 +       PFIB_CONTEXT    FibContext,
1658 +       int                             FibStatus )
1659 +/*----------------------------------------------------------------------------*/
1660 +{
1661 +       PCI_MINIPORT_COMMON_EXTENSION   *CommonExtension;
1662 +       AFA_COMM_ADAPTER                                *Adapter;
1663 +       BLOCKWRITERESPONSE                              *BlockWriteResponse;
1664 +       Scsi_Cmnd                                               *scsi_cmnd_ptr;
1665 +       u_long                                                  lba;
1666 +       int                     ContainerId;
1667 +
1668 +       scsi_cmnd_ptr = ( Scsi_Cmnd * )Context;
1669 +
1670 +       CommonExtension = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
1671 +       Adapter         = ( AFA_COMM_ADAPTER * )CommonExtension->Adapter;
1672 +       
1673 +       ContainerId = TARGET_LUN_TO_CONTAINER( scsi_cmnd_ptr->target, scsi_cmnd_ptr->lun );
1674 +
1675 +       lba = ( ( scsi_cmnd_ptr->cmnd[1] & 0x1F ) << 16 ) | 
1676 +                       ( scsi_cmnd_ptr->cmnd[2] << 8 ) |
1677 +                       scsi_cmnd_ptr->cmnd[3];
1678 +       cmn_err( CE_DEBUG, "AacHba_WriteCallback[cpu %d]: lba = %ld, t = %ld", smp_processor_id(), lba, jiffies );
1679 +       if( FibContext == 0 ) 
1680 +       {
1681 +               cmn_err( CE_WARN, "AacHba_WriteCallback: no fib context" );
1682 +               scsi_cmnd_ptr->result = DID_ERROR << 16;
1683 +               AacHba_CompleteScsi( scsi_cmnd_ptr );
1684 +               return;
1685 +       }
1686 +
1687 +    BlockWriteResponse = (PBLOCKWRITERESPONSE) Adapter->CommFuncs.GetFibData( FibContext );
1688 +       if (BlockWriteResponse->Status == ST_OK) 
1689 +               scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1690 +       else 
1691 +       {
1692 +               cmn_err( CE_WARN, "AacHba_WriteCallback: write failed, status = %d\n", 
1693 +                       BlockWriteResponse->Status );
1694 +               scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1695 +               AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1696 +                       SENKEY_HW_ERR, SENCODE_INTERNAL_TARGET_FAILURE, ASENCODE_INTERNAL_TARGET_FAILURE, 
1697 +                       0, 0, 0, 0 );
1698 +       }
1699 +
1700 +       Adapter->CommFuncs.CompleteFib( FibContext );
1701 +       Adapter->CommFuncs.FreeFib( FibContext );
1702 +
1703 +       AacHba_CompleteScsi( scsi_cmnd_ptr );
1704 +}
1705 +
1706 +
1707 +/*------------------------------------------------------------------------------
1708 +       AacHba_Ioctl()
1709 +
1710 +               Handle IOCTL requests
1711 +
1712 +       Preconditions:
1713 +       Postconditions:
1714 + *----------------------------------------------------------------------------*/
1715 +int AacHba_Ioctl(
1716 +       PCI_MINIPORT_COMMON_EXTENSION *CommonExtension,
1717 +       int cmd,
1718 +       void * arg )
1719 +/*----------------------------------------------------------------------------*/
1720 +{
1721 +       Sa_ADAPTER_EXTENSION              *AdapterExtension;
1722 +       AFA_IOCTL_CMD IoctlCmd;
1723 +       int status;
1724 +       
1725 +       AdapterExtension = ( Sa_ADAPTER_EXTENSION * )CommonExtension->MiniPort;
1726 +
1727 +       cmn_err( CE_DEBUG, "AacHba_Ioctl, type = %d", cmd );
1728 +       switch( cmd )
1729 +       {
1730 +         case FSACTL_SENDFIB:
1731 +                 cmn_err( CE_DEBUG, "FSACTL_SENDFIB" );
1732 +               break;
1733 +
1734 +         case FSACTL_AIF_THREAD:
1735 +                 cmn_err( CE_DEBUG, "FSACTL_AIF_THREAD" );
1736 +               break;
1737 +
1738 +         case FSACTL_NULL_IO_TEST:
1739 +                 cmn_err( CE_DEBUG, "FSACTL_NULL_IO_TEST" );
1740 +               break;
1741 +
1742 +         case FSACTL_SIM_IO_TEST:
1743 +                 cmn_err( CE_DEBUG, "FSACTL_SIM_IO_TEST" );
1744 +               break;
1745 +
1746 +         case FSACTL_GET_FIBTIMES:
1747 +                 cmn_err( CE_DEBUG, "FSACTL_GET_FIBTIMES" );
1748 +               break;
1749 +
1750 +         case FSACTL_ZERO_FIBTIMES:
1751 +                 cmn_err( CE_DEBUG, "FSACTL_ZERO_FIBTIMES");
1752 +               break;
1753 +
1754 +         case FSACTL_GET_VAR:
1755 +                 cmn_err( CE_DEBUG, "FSACTL_GET_VAR" );
1756 +               break;
1757 +
1758 +         case FSACTL_SET_VAR:
1759 +                 cmn_err( CE_DEBUG, "FSACTL_SET_VAR" );
1760 +               break;
1761 +
1762 +         case FSACTL_OPEN_ADAPTER_CONFIG:
1763 +                 cmn_err( CE_DEBUG, "FSACTL_OPEN_ADAPTER_CONFIG" );
1764 +               break;  
1765 +
1766 +         case FSACTL_CLOSE_ADAPTER_CONFIG:
1767 +                 cmn_err( CE_DEBUG, "FSACTL_CLOSE_ADAPTER_CONFIG" );
1768 +               break;
1769 +
1770 +         case FSACTL_QUERY_ADAPTER_CONFIG:
1771 +                 cmn_err( CE_DEBUG, "FSACTL_QUERY_ADAPTER_CONFIG" );
1772 +               break;
1773 +
1774 +         case FSACTL_OPEN_GET_ADAPTER_FIB:
1775 +                 cmn_err( CE_DEBUG, "FSACTL_OPEN_GET_ADAPTER_FIB" );
1776 +               break;
1777 +
1778 +         case FSACTL_GET_NEXT_ADAPTER_FIB:
1779 +                 cmn_err( CE_DEBUG, "FSACTL_GET_NEXT_ADAPTER_FIB" );
1780 +               break;
1781 +
1782 +         case FSACTL_CLOSE_GET_ADAPTER_FIB:
1783 +                 cmn_err( CE_DEBUG, "FSACTL_CLOSE_GET_ADAPTER_FIB" );
1784 +               break;
1785 +
1786 +         case FSACTL_MINIPORT_REV_CHECK:
1787 +                 cmn_err( CE_DEBUG, "FSACTL_MINIPORT_REV_CHECK" );
1788 +               break;
1789 +
1790 +         case FSACTL_OPENCLS_COMM_PERF_DATA:
1791 +                 cmn_err( CE_DEBUG, "FSACTL_OPENCLS_COMM_PERF_DATA" );
1792 +               break;
1793 +       
1794 +         case FSACTL_GET_COMM_PERF_DATA:
1795 +                 cmn_err( CE_DEBUG, "FSACTL_GET_COMM_PERF_DATA" );
1796 +               break;
1797 +
1798 +         case FSACTL_QUERY_DISK:
1799 +                 cmn_err( CE_DEBUG, "FSACTL_QUERY_DISK" );
1800 +               break;
1801 +               
1802 +         case FSACTL_DELETE_DISK:
1803 +                 cmn_err( CE_DEBUG, "FSACTL_DELETE_DISK" );
1804 +               break;
1805 +
1806 +         default:
1807 +                 cmn_err( CE_DEBUG, "Unknown ioctl: 0x%x", cmd );
1808 +       }
1809 +
1810 +       IoctlCmd.cmd = cmd;
1811 +       IoctlCmd.arg = ( intptr_t )arg;
1812 +       IoctlCmd.flag = 0;
1813 +       IoctlCmd.cred_p = 0;
1814 +       IoctlCmd.rval_p = 0;
1815 +
1816 +       status = AfaCommAdapterDeviceControl( CommonExtension->Adapter, &IoctlCmd );
1817 +       cmn_err( CE_DEBUG, "AAC_Ioctl, completion status = %d", status );
1818 +       return( status );
1819 +}
1820 +
1821 +
1822 +/*------------------------------------------------------------------------------
1823 +       AacHba_AdapterDeviceControl()
1824 +
1825 +       Preconditions:
1826 +       Postconditions:
1827 +               Returns TRUE if ioctl handled, FALSE otherwise
1828 +               *ReturnStatus set to completion status
1829 + *----------------------------------------------------------------------------*/
1830 +BOOLEAN AacHba_AdapterDeviceControl (
1831 +       PVOID AdapterArg,               // CommonExtensionPtr
1832 +       IN PAFA_IOCTL_CMD IoctlCmdPtr,
1833 +       OUT int * ReturnStatus )
1834 +/*----------------------------------------------------------------------------*/
1835 +{
1836 +       BOOLEAN Handled = TRUE; // start out handling it.
1837 +       int Status = EFAULT;
1838 +
1839 +       switch( IoctlCmdPtr->cmd )
1840 +       {
1841 +               case FSACTL_QUERY_DISK:
1842 +                       Status = AacHba_QueryDisk( AdapterArg, IoctlCmdPtr );
1843 +                       break;
1844 +
1845 +               case FSACTL_DELETE_DISK:
1846 +                       Status = AacHba_DeleteDisk( AdapterArg, IoctlCmdPtr );
1847 +                       break;
1848 +
1849 +               case FSACTL_FORCE_DELETE_DISK:
1850 +                       Status = AacHba_ForceDeleteDisk( AdapterArg, IoctlCmdPtr );
1851 +                       break;
1852 +
1853 +               case 2131:
1854 +                       if( AacHba_ProbeContainers( ( PCI_MINIPORT_COMMON_EXTENSION * )AdapterArg ) )
1855 +                               Status = -EFAULT;
1856 +                       break;
1857 +
1858 +               default:
1859 +                       Handled = FALSE;
1860 +                       break;
1861 +       }
1862 +
1863 +       *ReturnStatus = Status;
1864 +
1865 +       return( Handled );
1866 +}
1867 +
1868 +
1869 +/*------------------------------------------------------------------------------
1870 +       AacHba_QueryDisk()
1871 +
1872 +       Postconditions:
1873 +               Return values
1874 +               0       = OK
1875 +               -EFAULT = Bad address
1876 +               -EINVAL = Bad container number
1877 + *----------------------------------------------------------------------------*/
1878 +int AacHba_QueryDisk(
1879 +       PVOID AdapterArg,               // CommonExtensionPtr
1880 +       IN PAFA_IOCTL_CMD IoctlCmdPtr )
1881 +/*----------------------------------------------------------------------------*/
1882 +{
1883 +       UNIX_QUERY_DISK QueryDisk;
1884 +       PCI_MINIPORT_COMMON_EXTENSION   *CommonExtensionPtr;
1885 +       fsadev_t                                                *fsa_dev_ptr;
1886 +
1887 +       CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )AdapterArg;
1888 +       fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
1889 +
1890 +       if( copyin( IoctlCmdPtr->arg, &QueryDisk, sizeof( UNIX_QUERY_DISK ) ) )
1891 +               return( -EFAULT );
1892 +
1893 +       if (QueryDisk.ContainerNumber == -1)
1894 +               QueryDisk.ContainerNumber = TARGET_LUN_TO_CONTAINER( QueryDisk.Target, QueryDisk.Lun );
1895 +       else 
1896 +               if( ( QueryDisk.Bus == -1 ) && ( QueryDisk.Target == -1 ) && ( QueryDisk.Lun == -1 ) )
1897 +               {
1898 +                       if( QueryDisk.ContainerNumber > MAXIMUM_NUM_CONTAINERS )
1899 +                               return( -EINVAL );
1900 +
1901 +                       QueryDisk.Instance = CommonExtensionPtr->OsDep.scsi_host_ptr->host_no;
1902 +                       QueryDisk.Bus = 0;
1903 +                       QueryDisk.Target = CONTAINER_TO_TARGET( QueryDisk.ContainerNumber );
1904 +                       QueryDisk.Lun = CONTAINER_TO_LUN( QueryDisk.ContainerNumber );
1905 +               }
1906 +               else 
1907 +                       return( -EINVAL );
1908 +
1909 +       QueryDisk.Valid = fsa_dev_ptr->ContainerValid[QueryDisk.ContainerNumber];
1910 +       QueryDisk.Locked = fsa_dev_ptr->ContainerLocked[QueryDisk.ContainerNumber];
1911 +       QueryDisk.Deleted = fsa_dev_ptr->ContainerDeleted[QueryDisk.ContainerNumber];
1912 +
1913 +       if( fsa_dev_ptr->ContainerDevNo[QueryDisk.ContainerNumber] == -1 )
1914 +               QueryDisk.UnMapped = TRUE;
1915 +       else
1916 +               QueryDisk.UnMapped = FALSE;
1917 +
1918 +       get_sd_devname( fsa_dev_ptr->ContainerDevNo[QueryDisk.ContainerNumber], 
1919 +               QueryDisk.diskDeviceName );
1920 +
1921 +       if( copyout( &QueryDisk, IoctlCmdPtr->arg, sizeof( UNIX_QUERY_DISK ) ) )
1922 +               return( -EFAULT );
1923 +
1924 +       return( 0 );
1925 +}
1926 +
1927 +
1928 +/*------------------------------------------------------------------------------
1929 +       get_sd_devname()
1930 + *----------------------------------------------------------------------------*/
1931 +static void get_sd_devname(
1932 +       long disknum, 
1933 +       char * buffer)
1934 +/*----------------------------------------------------------------------------*/
1935 +{
1936 +       if( disknum < 0 )
1937 +       {
1938 +        sprintf(buffer, "%s", "");
1939 +               return;
1940 +       }
1941 +
1942 +   if( disknum < 26 )
1943 +        sprintf(buffer, "sd%c", 'a' + disknum);
1944 +    else {
1945 +        unsigned int min1;
1946 +        unsigned int min2;
1947 +        /*
1948 +         * For larger numbers of disks, we need to go to a new
1949 +         * naming scheme.
1950 +         */
1951 +        min1 = disknum / 26;
1952 +        min2 = disknum % 26;
1953 +        sprintf(buffer, "sd%c%c", 'a' + min1 - 1, 'a' + min2);
1954 +    }
1955 +}
1956 +
1957 +
1958 +/*------------------------------------------------------------------------------
1959 +       AacHba_ForceDeleteDisk()
1960 +
1961 +       Postconditions:
1962 +               Return values
1963 +               0       = OK
1964 +               -EFAULT = Bad address
1965 +               -EINVAL = Bad container number
1966 + *----------------------------------------------------------------------------*/
1967 +int AacHba_ForceDeleteDisk(
1968 +       PVOID AdapterArg,               // CommonExtensionPtr
1969 +       IN PAFA_IOCTL_CMD IoctlCmdPtr )
1970 +/*----------------------------------------------------------------------------*/
1971 +{
1972 +       DELETE_DISK      DeleteDisk;
1973 +       PCI_MINIPORT_COMMON_EXTENSION   *CommonExtensionPtr;
1974 +       fsadev_t                                                *fsa_dev_ptr;
1975 +
1976 +       CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )AdapterArg;
1977 +       fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
1978 +
1979 +       if ( copyin( IoctlCmdPtr->arg,  &DeleteDisk, sizeof( DELETE_DISK ) ) )
1980 +               return( -EFAULT );
1981 +
1982 +       if ( DeleteDisk.ContainerNumber > MAXIMUM_NUM_CONTAINERS ) 
1983 +               return( -EINVAL );
1984 +       
1985 +       // Mark this container as being deleted.
1986 +       fsa_dev_ptr->ContainerDeleted[DeleteDisk.ContainerNumber] = TRUE;
1987 +
1988 +       // Mark the container as no longer valid
1989 +       fsa_dev_ptr->ContainerValid[DeleteDisk.ContainerNumber] = 0;
1990 +
1991 +       return( 0 );
1992 +}
1993 +
1994 +
1995 +/*------------------------------------------------------------------------------
1996 +       AacHba_DeleteDisk()
1997 +
1998 +       Postconditions:
1999 +               Return values
2000 +               0       = OK
2001 +               -EFAULT = Bad address
2002 +               -EINVAL = Bad container number
2003 +               -EBUSY  = Device locked
2004 + *----------------------------------------------------------------------------*/
2005 +int AacHba_DeleteDisk(
2006 +       PVOID AdapterArg,
2007 +       IN PAFA_IOCTL_CMD IoctlCmdPtr )
2008 +/*----------------------------------------------------------------------------*/
2009 +{
2010 +       DELETE_DISK DeleteDisk;
2011 +       PCI_MINIPORT_COMMON_EXTENSION   *CommonExtensionPtr;
2012 +       fsadev_t                                                *fsa_dev_ptr;
2013 +
2014 +       CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )AdapterArg;
2015 +       fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
2016 +
2017 +       if( copyin( IoctlCmdPtr->arg, &DeleteDisk, sizeof( DELETE_DISK ) ) ) 
2018 +               return( -EFAULT );
2019 +
2020 +       if( DeleteDisk.ContainerNumber > MAXIMUM_NUM_CONTAINERS )
2021 +               return( -EINVAL );
2022 +       
2023 +       // If the container is locked, it can not be deleted by the API.
2024 +       if( fsa_dev_ptr->ContainerLocked[DeleteDisk.ContainerNumber] )
2025 +               return( -EBUSY );
2026 +       else 
2027 +       {       
2028 +               // Mark the container as no longer being valid.
2029 +               fsa_dev_ptr->ContainerValid[DeleteDisk.ContainerNumber] = 0;
2030 +               fsa_dev_ptr->ContainerDevNo[DeleteDisk.ContainerNumber] = -1;
2031 +               return(0);
2032 +       }       
2033 +}
2034 +
2035 +
2036 +/*------------------------------------------------------------------------------
2037 +       AacHba_OpenAdapter()
2038 + *----------------------------------------------------------------------------*/
2039 +AAC_STATUS AacHba_OpenAdapter(
2040 +       IN PVOID AdapterArg )
2041 +/*----------------------------------------------------------------------------*/
2042 +{
2043 +       return( STATUS_SUCCESS );
2044 +}
2045 +
2046 +
2047 +/*------------------------------------------------------------------------------
2048 +       AacHba_CloseAdapter()
2049 + *----------------------------------------------------------------------------*/
2050 +AAC_STATUS AacHba_CloseAdapter(
2051 +       IN PVOID AdapterArg )
2052 +/*----------------------------------------------------------------------------*/
2053 +{
2054 +       return( STATUS_SUCCESS );
2055 +}
2056 +
2057 +
2058 +/*------------------------------------------------------------------------------
2059 +       AacHba_DetachAdapter()
2060 + *----------------------------------------------------------------------------*/
2061 +void AacHba_DetachAdapter(
2062 +       IN PVOID AdapterArg )
2063 +/*----------------------------------------------------------------------------*/
2064 +{
2065 +       AacCommDetachAdapter( AdapterArg );
2066 +}
2067 +
2068 +
2069 +/*------------------------------------------------------------------------------
2070 +       AacHba_AbortScsiCommand()
2071 + *----------------------------------------------------------------------------*/
2072 +void AacHba_AbortScsiCommand(
2073 +       Scsi_Cmnd *scsi_cmnd_ptr )
2074 +/*----------------------------------------------------------------------------*/
2075 +{
2076 +       u_short interrupt_status;
2077 +       PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
2078 +
2079 +       CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
2080 +       interrupt_status = Sa_READ_USHORT( ( PSa_ADAPTER_EXTENSION )( CommonExtensionPtr->MiniPort ),
2081 +               DoorbellReg_p );
2082 +       cmn_err( CE_WARN, "interrupt_status = %d", interrupt_status );
2083 +       
2084 +       if( interrupt_status & DOORBELL_1) {    // Adapter -> Host Normal Command Ready
2085 +               cmn_err( CE_WARN, "DOORBELL_1: Adapter -> Host Normal Command Ready" );
2086 +       } 
2087 +
2088 +       if( interrupt_status & DOORBELL_2) {    // Adapter -> Host Normal Response Ready
2089 +               cmn_err( CE_WARN, "DOORBELL_2: Adapter -> Host Normal Response Ready" );
2090 +       }
2091 +
2092 +       if ( interrupt_status & DOORBELL_3) {   // Adapter -> Host Normal Command Not Full
2093 +               cmn_err( CE_WARN, "DOORBELL_3: Adapter -> Host Normal Command Not Full" );
2094 +       }
2095 +
2096 +       if ( interrupt_status & DOORBELL_4) {   // Adapter -> Host Normal Response Not Full
2097 +               cmn_err( CE_WARN, "DOORBELL_4: Adapter -> Host Normal Response Not Full" );
2098 +       }
2099 +
2100 +}
2101 +
2102 +
2103 +/*------------------------------------------------------------------------------
2104 +       AacHba_HandleAif()
2105 + *----------------------------------------------------------------------------*/
2106 +BOOLEAN AacHba_HandleAif(
2107 +       IN PVOID AdapterArg,
2108 +       IN PFIB_CONTEXT FibContext )
2109 +/*----------------------------------------------------------------------------*/
2110 +{
2111 +       return( FALSE );
2112 +}
2113 +
2114 +
2115 +/*------------------------------------------------------------------------------
2116 +       AacHba_SetSenseData()
2117 +               Fill in the sense data.
2118 +       Preconditions:
2119 +       Postconditions:
2120 + *----------------------------------------------------------------------------*/
2121 +void AacHba_SetSenseData(
2122 +       char * sense_buf,
2123 +       unchar sense_key,
2124 +       unchar sense_code,
2125 +       unchar a_sense_code,
2126 +       unchar incorrect_length,
2127 +       unchar bit_pointer,
2128 +       unsigned field_pointer,
2129 +       unsigned long residue )
2130 +/*----------------------------------------------------------------------------*/
2131 +{
2132 +       sense_buf[0] = 0xF0;                    // Sense data valid, err code 70h (current error)
2133 +       sense_buf[1] = 0;                                                               // Segment number, always zero
2134 +
2135 +       if( incorrect_length )
2136 +       {
2137 +               sense_buf[2] = sense_key | 0x20;                // Set the ILI bit | sense key
2138 +               sense_buf[3] = BYTE3(residue);
2139 +               sense_buf[4] = BYTE2(residue);
2140 +               sense_buf[5] = BYTE1(residue);
2141 +               sense_buf[6] = BYTE0(residue);
2142 +       }
2143 +       else
2144 +               sense_buf[2] = sense_key;                               // Sense key
2145 +
2146 +       if( sense_key == SENKEY_ILLEGAL )
2147 +               sense_buf[7] = 10;                                              // Additional sense length
2148 +       else
2149 +               sense_buf[7] = 6;                                               // Additional sense length
2150 +
2151 +       sense_buf[12] = sense_code;                             // Additional sense code
2152 +       sense_buf[13] = a_sense_code;                           // Additional sense code qualifier
2153 +       if( sense_key == SENKEY_ILLEGAL )
2154 +       {
2155 +               sense_buf[15] = 0;
2156 +
2157 +               if( sense_code == SENCODE_INVALID_PARAM_FIELD )
2158 +                       sense_buf[15] = 0x80;                           // Std sense key specific field
2159 +                                                                                               // Illegal parameter is in the parameter block
2160 +
2161 +               if( sense_code == SENCODE_INVALID_CDB_FIELD )
2162 +                       sense_buf[15] = 0xc0;                           // Std sense key specific field
2163 +                                                                                               // Illegal parameter is in the CDB block
2164 +               sense_buf[15] |= bit_pointer;
2165 +               sense_buf[16] = field_pointer >> 8;     // MSB
2166 +               sense_buf[17] = field_pointer;          // LSB
2167 +       }
2168 +}
2169 +
2170 diff -burN linux-2.4.4/drivers/scsi/aacraid/aacid.c linux/drivers/scsi/aacraid/aacid.c
2171 --- linux-2.4.4/drivers/scsi/aacraid/aacid.c    Wed Dec 31 18:00:00 1969
2172 +++ linux/drivers/scsi/aacraid/aacid.c  Mon Apr 30 09:43:34 2001
2173 @@ -0,0 +1,153 @@
2174 +/*++
2175 + * Adaptec aacraid device driver for Linux.
2176 + *
2177 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
2178 + *
2179 + * This program is free software; you can redistribute it and/or modify
2180 + * it under the terms of the GNU General Public License as published by
2181 + * the Free Software Foundation; either version 2, or (at your option)
2182 + * any later version.
2183 + *
2184 + * This program is distributed in the hope that it will be useful,
2185 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2186 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
2187 + * GNU General Public License for more details.
2188 + *
2189 + * You should have received a copy of the GNU General Public License
2190 + * along with this program; see the file COPYING.  If not, write to
2191 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
2192 + *
2193 + * Module Name:
2194 + *  aac.c
2195 + *
2196 + * Abstract: Data structures for controller specific info.
2197 + *
2198 +--*/
2199 +
2200 +static char *ident_aacid = "aacraid_ident aacid.c 1.0.6 2000/10/09 Adaptec, Inc.";
2201 +
2202 +#include "osheaders.h"
2203 +
2204 +#include "AacGenericTypes.h"
2205 +
2206 +#include "aac_unix_defs.h"
2207 +
2208 +#include "fsatypes.h"
2209 +#include "comstruc.h"
2210 +#include "fsaport.h"
2211 +#include "pcisup.h"
2212 +
2213 +#include "version.h"
2214 +
2215 +
2216 +/* Function Prototypes */
2217 +void InqStrCopy(char *a, char *b); /* ossup.c */
2218 +
2219 +/* Device name used to register and unregister
2220 +   the device in linit.c */
2221 +char devicestr[]="aac";
2222 +
2223 +char *container_types[] = {
2224 +        "None",
2225 +        "Volume",
2226 +        "Mirror",
2227 +        "Stripe",
2228 +        "RAID5",
2229 +        "SSRW",
2230 +        "SSRO",
2231 +        "Morph",
2232 +        "Legacy",
2233 +        "RAID4",
2234 +        "RAID10",             
2235 +        "RAID00",             
2236 +        "V-MIRRORS",          
2237 +        "PSEUDO R4",          
2238 +       "RAID50",
2239 +        "Unknown"
2240 +};
2241 +
2242 +/* Local Structure to set SCSI inquiry data strings */
2243 +typedef struct _INQSTR {
2244 +  char vid[8];         /* Vendor ID */
2245 +  char pid[16];        /* Product ID */
2246 +  char prl[4];         /* Product Revision Level */
2247 +} INQSTR, *INQSTRP;
2248 +
2249 +FSA_MINIPORT MiniPorts[];
2250 +
2251 +/* Function: SetInqDataStr
2252 + *
2253 + * Arguments: [1] pointer to void [1] int
2254 + *
2255 + * Purpose: Sets SCSI inquiry data strings for vendor, product
2256 + * and revision level. Allows strings to be set in platform dependant
2257 + * files instead of in OS dependant driver source.
2258 + */
2259 +void
2260 +SetInqDataStr (
2261 +  int MiniPortIndex,
2262 +  void *dataPtr,
2263 +  int tindex)
2264 +{
2265 +  INQSTRP InqStrPtr;
2266 +   char *findit;
2267 +   FSA_MINIPORT   *mp;
2268 +
2269 +   mp = &MiniPorts[MiniPortIndex];
2270 +   
2271 +    InqStrPtr = (INQSTRP)(dataPtr); /* cast dataPtr to type INQSTRP */
2272 +
2273 +    InqStrCopy (mp->Vendor, InqStrPtr->vid); 
2274 +    InqStrCopy (mp->Model,  InqStrPtr->pid); /* last six chars reserved for vol type */
2275 +
2276 +    findit = InqStrPtr->pid;
2277 +
2278 +    for ( ; *findit != ' '; findit++); /* walk till we find a space then incr by 1 */
2279 +        findit++;
2280 +       
2281 +    if (tindex < (sizeof(container_types)/sizeof(char *))){
2282 +      InqStrCopy (container_types[tindex], findit);
2283 +    }
2284 +   InqStrCopy ("0001", InqStrPtr->prl);
2285 +}
2286 +
2287 +int
2288 +SaInitDevice(
2289 +       IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
2290 +       IN ULONG AdapterNumber,
2291 +       IN ULONG PciBus,
2292 +       IN ULONG PciSlot
2293 +);
2294 +
2295 +int
2296 +RxInitDevice(
2297 +       IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
2298 +       IN ULONG AdapterNumber,
2299 +       IN ULONG PciBus,
2300 +       IN ULONG PciSlot
2301 +);
2302 +
2303 +
2304 +/*
2305 + * Because of the way Linux names scsi devices, the order in this table has
2306 + * become important.  Check for on-board Raid first, add-in cards second.
2307 + */
2308 +
2309 +FSA_MINIPORT MiniPorts[] = {
2310 +       { 0x1028, 0x0001, 0x1028, 0x0001, "afa", RxInitDevice, "percraid", "DELL    ", "PERCRAID        " }, /* PERC 3/Si */
2311 +       { 0x1028, 0x0002, 0x1028, 0x0002, "afa", RxInitDevice, "percraid", "DELL    ", "PERCRAID        " }, /* PERC 3/Di */
2312 +       { 0x1028, 0x0003, 0x1028, 0x0003, "afa", RxInitDevice, "percraid", "DELL    ", "PERCRAID        " }, /* PERC 3/Si */
2313 +       { 0x1028, 0x0004, 0x1028, 0x00d0, "afa", RxInitDevice, "percraid", "DELL    ", "PERCRAID        " }, /* PERC 3/Si */
2314 +       { 0x1028, 0x0002, 0x1028, 0x00d1, "afa", RxInitDevice, "percraid", "DELL    ", "PERCRAID        " }, /* PERC 3/Di */
2315 +       { 0x1028, 0x0002, 0x1028, 0x00d9, "afa", RxInitDevice, "percraid", "DELL    ", "PERCRAID        " }, /* PERC 3/Di */
2316 +       { 0x1028, 0x000a, 0x1028, 0x0106, "afa", RxInitDevice, "percraid", "DELL    ", "PERCRAID        " }, /* PERC 3/Di */
2317 +       { 0x1011, 0x0046, 0x9005, 0x1364, "afa", SaInitDevice, "percraid", "DELL    ", "PERCRAID        " }, /* Dell PERC2 "Quad Channel */
2318 +       { 0x1011, 0x0046, 0x103c, 0x10c2, "hpn", SaInitDevice, "hpnraid",  "HP      ", "NetRAID-4M      " }  /* HP NetRAID-4M */
2319 +};
2320 +
2321 +
2322 +#define NUM_MINIPORTS  (sizeof(MiniPorts) / sizeof(FSA_MINIPORT))
2323 +
2324 +int NumMiniPorts = NUM_MINIPORTS;
2325 +
2326 +char DescriptionString[] =     "AACxxx Raid Controller" FSA_VERSION_STRING ;
2327 diff -burN linux-2.4.4/drivers/scsi/aacraid/commctrl.c linux/drivers/scsi/aacraid/commctrl.c
2328 --- linux-2.4.4/drivers/scsi/aacraid/commctrl.c Wed Dec 31 18:00:00 1969
2329 +++ linux/drivers/scsi/aacraid/commctrl.c       Mon Apr 30 09:43:34 2001
2330 @@ -0,0 +1,1098 @@
2331 +/*++
2332 + * Adaptec aacraid device driver for Linux.
2333 + *
2334 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
2335 + *
2336 + * This program is free software; you can redistribute it and/or modify
2337 + * it under the terms of the GNU General Public License as published by
2338 + * the Free Software Foundation; either version 2, or (at your option)
2339 + * any later version.
2340 + *
2341 + * This program is distributed in the hope that it will be useful,
2342 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2343 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
2344 + * GNU General Public License for more details.
2345 + *
2346 + * You should have received a copy of the GNU General Public License
2347 + * along with this program; see the file COPYING.  If not, write to
2348 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
2349 + *
2350 + * Module Name:
2351 + *  commctrl.c
2352 + *
2353 + * Abstract: Contains all routines for control of the AFA comm layer
2354 + *
2355 +--*/
2356 +
2357 +static char *ident_commctrl = "aacraid_ident commctrl.c 1.0.7 2000/10/11 Adaptec, Inc.";
2358 +
2359 +#include "comprocs.h"
2360 +#include "osheaders.h"
2361 +#include "ostypes.h"
2362 +
2363 +
2364 +
2365 +
2366 +
2367 +typedef BOOLEAN BOOL;
2368 +#define inline /* _inline */
2369 +
2370 +#include <revision.h>
2371 +AAC_STATUS
2372 +FsaCtlCheckRevision(
2373 +       IN PAFA_COMM_ADAPTER    Adapter,
2374 +       IN PAFA_IOCTL_CMD               IoctlCmdPtr
2375 +       )
2376 +/*++
2377 +
2378 +Routine Description:
2379 +
2380 +       This routine validates the revision of the caller with the current revision
2381 +       of the filesystem.
2382 +
2383 +Arguments:
2384 +
2385 +       Adapter - Supplies which adapter is being processed.
2386 +
2387 +    Irp - Supplies the Irp being processed.
2388 +
2389 +       IrpContext - Supplies the IrpContext.
2390 +
2391 +Return Value:
2392 +
2393 +       AAC_STATUS
2394 +
2395 +--*/
2396 +
2397 +{
2398 +       RevCheck APIRevCheck;
2399 +       RevCheckResp APIRevCheckResp;
2400 +       RevComponent APICallingComponent;
2401 +       ULONG APIBuildNumber;
2402 +
2403 +       if (COPYIN( (caddr_t) IoctlCmdPtr->arg, (caddr_t) &APIRevCheck, sizeof(RevCheck), IoctlCmdPtr->flag )) {
2404 +               return (EFAULT);
2405 +       }
2406 +
2407 +       APICallingComponent = APIRevCheck.callingComponent;
2408 +       APIBuildNumber = APIRevCheck.callingRevision.buildNumber;
2409 +
2410 +       APIRevCheckResp.possiblyCompatible = RevCheckCompatibility( RevMiniportDriver , APICallingComponent, APIBuildNumber );
2411 +
2412 +       APIRevCheckResp.adapterSWRevision.external.ul = RevGetExternalRev();
2413 +       APIRevCheckResp.adapterSWRevision.buildNumber = RevGetBuildNumber();
2414 +
2415 +       if (COPYOUT( (caddr_t) &APIRevCheckResp, (caddr_t) IoctlCmdPtr->arg, sizeof(RevCheckResp), IoctlCmdPtr->flag )) {
2416 +               return (EFAULT);
2417 +       }
2418 +
2419 +       return (0);
2420 +}
2421 +
2422 +
2423 +int
2424 +AfaCommAdapterDeviceControl(
2425 +       IN PVOID AdapterArg,
2426 +       IN PAFA_IOCTL_CMD IoctlCmdPtr
2427 +       )
2428 +{
2429 +       PAFA_COMM_ADAPTER Adapter = (PAFA_COMM_ADAPTER) AdapterArg;
2430 +    int Status = ENOTTY;
2431 +//    PIO_STACK_LOCATION IrpSp;
2432 +       PAFA_CLASS_DRIVER ClassDriver;
2433 +
2434 +       //
2435 +       // First loop through all of the class drivers to give them a chance to handle
2436 +       // the Device control first.
2437 +       //
2438 +
2439 +       ClassDriver = Adapter->ClassDriverList;
2440 +
2441 +       while (ClassDriver) {
2442 +
2443 +               if (ClassDriver->DeviceControl) {
2444 +
2445 +                       if (ClassDriver->DeviceControl( ClassDriver->ClassDriverExtension, IoctlCmdPtr, &Status ) ) {
2446 +
2447 +                               return (Status);
2448 +
2449 +                       }
2450 +               }
2451 +
2452 +               ClassDriver = ClassDriver->Next;
2453 +       }
2454 +
2455 +    switch (IoctlCmdPtr->cmd) {
2456 +
2457 +
2458 +         case FSACTL_SENDFIB:
2459 +
2460 +               Status = AfaCommCtlSendFib( Adapter, IoctlCmdPtr );
2461 +               break;
2462 +
2463 +         case FSACTL_AIF_THREAD:
2464 +
2465 +               Status = AfaCommCtlAifThread( Adapter, IoctlCmdPtr );   
2466 +               break;
2467 +
2468 +
2469 +         case FSACTL_OPEN_GET_ADAPTER_FIB:
2470 +
2471 +               Status = FsaCtlOpenGetAdapterFib( Adapter, IoctlCmdPtr );
2472 +               break;
2473 +
2474 +         case FSACTL_GET_NEXT_ADAPTER_FIB:
2475 +
2476 +               Status = FsaCtlGetNextAdapterFib( Adapter, IoctlCmdPtr );
2477 +               break;
2478 +
2479 +         case FSACTL_CLOSE_GET_ADAPTER_FIB:
2480 +
2481 +               Status = FsaCtlCloseGetAdapterFib( Adapter, IoctlCmdPtr );
2482 +               break;
2483 +
2484 +         case FSACTL_MINIPORT_REV_CHECK:
2485 +        
2486 +               Status = FsaCtlCheckRevision( Adapter , IoctlCmdPtr );
2487 +               break;
2488 +
2489 +
2490 +      default:
2491 +         
2492 +               Status = ENOTTY;
2493 +               break;  
2494 +
2495 +       }
2496 +
2497 +
2498 +       return (Status);
2499 +}
2500 +
2501 +AAC_STATUS
2502 +AfaCommRegisterNewClassDriver(
2503 +       IN PAFA_COMM_ADAPTER    Adapter,
2504 +       IN PAFA_NEW_CLASS_DRIVER        NewClassDriver,
2505 +       OUT PAFA_NEW_CLASS_DRIVER_RESPONSE NewClassDriverResponse
2506 +       )
2507 +/*++
2508 +
2509 +Routine Description:
2510 +
2511 +       This routine registers a new class driver for the comm layer.
2512 +
2513 +       It will return a pointer to the communication functions for the class driver
2514 +       to use.
2515 +
2516 +Arguments:
2517 +
2518 +       Adapter - Supplies which adapter is being processed.
2519 +
2520 +    Irp - Supplies the Irp being processed.
2521 +
2522 +Return Value:
2523 +
2524 +       STATUS_SUCCESS           - Everything OK.
2525 +
2526 +--*/
2527 +{
2528 +       AAC_STATUS Status;
2529 +       PAFA_CLASS_DRIVER ClassDriver;
2530 +
2531 +
2532 +       ClassDriver = (PAFA_CLASS_DRIVER) OsAllocMemory( sizeof(AFA_CLASS_DRIVER), OS_ALLOC_MEM_SLEEP );
2533 +
2534 +       if (ClassDriver == NULL) {
2535 +
2536 +               Status = STATUS_INSUFFICIENT_RESOURCES;
2537 +
2538 +               return Status;
2539 +       }
2540 +
2541 +       //
2542 +       // If the class driver has sent in user Vars, then copy them into the global
2543 +       // area.
2544 +       //
2545 +
2546 +       if (NewClassDriver->NumUserVars) {
2547 +
2548 +               PFSA_USER_VAR   NewUserVars;
2549 +
2550 +               NewUserVars = OsAllocMemory( (FsaCommData.NumUserVars +
2551 +                                                                  NewClassDriver->NumUserVars) * sizeof(FSA_USER_VAR), OS_ALLOC_MEM_SLEEP );
2552 +
2553 +               //
2554 +               // First copy the existing into the new area.
2555 +               //
2556 +
2557 +               RtlCopyMemory( NewUserVars, FsaCommData.UserVars, FsaCommData.NumUserVars * sizeof(FSA_USER_VAR) );
2558 +
2559 +               //
2560 +               // Next copy the new vars passed in from class driver.
2561 +               //
2562 +
2563 +               RtlCopyMemory( (NewUserVars + FsaCommData.NumUserVars),
2564 +                                          NewClassDriver->UserVars,
2565 +                                          NewClassDriver->NumUserVars * sizeof(FSA_USER_VAR) );
2566 +
2567 +               //
2568 +               // Free up the old user vars.
2569 +               //
2570 +
2571 +               OsFreeMemory( FsaCommData.UserVars, FsaCommData.NumUserVars * sizeof(FSA_USER_VAR) );
2572 +
2573 +               //
2574 +               // Point the global to the new area.
2575 +               //
2576 +
2577 +               FsaCommData.UserVars = NewUserVars;
2578 +
2579 +               //
2580 +               // Update the total count.
2581 +               //
2582 +
2583 +               FsaCommData.NumUserVars += NewClassDriver->NumUserVars;
2584 +
2585 +       }
2586 +
2587 +       ClassDriver->OpenAdapter = NewClassDriver->OpenAdapter;
2588 +       ClassDriver->CloseAdapter = NewClassDriver->CloseAdapter;
2589 +       ClassDriver->DeviceControl = NewClassDriver->DeviceControl;
2590 +       ClassDriver->HandleAif = NewClassDriver->HandleAif;
2591 +       ClassDriver->ClassDriverExtension = NewClassDriver->ClassDriverExtension;
2592 +
2593 +       ClassDriver->Next = Adapter->ClassDriverList;
2594 +       Adapter->ClassDriverList = ClassDriver;
2595 +
2596 +       //
2597 +       // Now return the information needed by the class driver to communicate to us.
2598 +       //
2599 +
2600 +       NewClassDriverResponse->CommFuncs = &Adapter->CommFuncs;
2601 +       NewClassDriverResponse->CommPortExtension = Adapter;
2602 +       NewClassDriverResponse->MiniPortExtension = Adapter->AdapterExtension;
2603 +       NewClassDriverResponse->SpinLockCookie = Adapter->SpinLockCookie;
2604 +       NewClassDriverResponse->Dip = Adapter->Dip;
2605 +
2606 +       return (STATUS_SUCCESS);
2607 +
2608 +
2609 +}
2610 +
2611 +int
2612 +AfaCommCtlSendFib(
2613 +       IN PAFA_COMM_ADAPTER    Adapter,
2614 +       IN PAFA_IOCTL_CMD               IoctlCmdPtr
2615 +)
2616 +/*++
2617 +
2618 +Routine Description:
2619 +
2620 +       This routine sends a fib to the adapter on behalf of a user level
2621 +       program.
2622 +
2623 +Arguments:
2624 +
2625 +       Adapter - Supplies which adapter is being processed.
2626 +
2627 +       IoctlCmdPtr - Pointer to the arguments to the IOCTL call
2628 +
2629 +Return Value:
2630 +
2631 +       STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2632 +
2633 +       STATUS_INSUFFICIENT_RESOURCES - If a memory allocation failed.
2634 +
2635 +       STATUS_SUCCESS           - Everything OK.
2636 +
2637 +--*/
2638 +{
2639 +    PFIB KFib;
2640 +//    PMDL DmaMdl = NULL;
2641 +       PCOMM_FIB_CONTEXT FibContext;
2642 +       PSGMAP_CONTEXT SgMapContext;
2643 +       SGMAP_CONTEXT _SgMapContext;
2644 +    QUEUE_TYPES WhichQueue;
2645 +    PVOID UsersAddress;
2646 +       AAC_STATUS Status;
2647 +
2648 +       FibContext = AllocateFib( Adapter );
2649 +
2650 +    KFib = FibContext->Fib;
2651 +
2652 +       //
2653 +       // First copy in the header so that we can check the size field.
2654 +       //
2655 +
2656 +       if (COPYIN( (caddr_t) IoctlCmdPtr->arg, (caddr_t) KFib, sizeof(FIB_HEADER), IoctlCmdPtr->flag )) {
2657 +               FreeFib( FibContext );
2658 +               Status = EFAULT;
2659 +               return (Status);
2660 +       }
2661 +
2662 +       //
2663 +       //      Since we copy based on the fib header size, make sure that we
2664 +       //      will not overrun the buffer when we copy the memory. Return
2665 +       //      an error if we would.
2666 +       //
2667 +
2668 +       if (KFib->Header.Size > sizeof(FIB) - sizeof(FIB_HEADER)) {
2669 +               FreeFib( FibContext );
2670 +               Status = EINVAL;
2671 +               return Status;
2672 +
2673 +       }
2674 +
2675 +       if (COPYIN( (caddr_t) IoctlCmdPtr->arg, (caddr_t) KFib, KFib->Header.Size + sizeof(FIB_HEADER), IoctlCmdPtr->flag )) {
2676 +               FreeFib( FibContext );
2677 +               Status = EFAULT;
2678 +               return (Status);
2679 +       }
2680 +
2681 +    WhichQueue = AdapNormCmdQueue;
2682 +
2683 +
2684 +       if (KFib->Header.Command == TakeABreakPt) {
2685 +
2686 +               InterruptAdapter(Adapter);
2687 +
2688 +               //
2689 +               // Since we didn't really send a fib, zero out the state to allow 
2690 +               // cleanup code not to assert.
2691 +               //
2692 +
2693 +               KFib->Header.XferState = 0;
2694 +
2695 +
2696 +       } else {
2697 +       
2698 +               if (SendFib(KFib->Header.Command, FibContext, KFib->Header.Size , FsaNormal,
2699 +                                       TRUE, NULL, TRUE, NULL, NULL) != FSA_SUCCESS) {
2700 +               FsaCommPrint("User SendFib failed!.\n");
2701 +
2702 +
2703 +                       FreeFib( FibContext );
2704 +                       return (ENXIO);
2705 +               }
2706 +
2707 +           if (CompleteFib(FibContext) != FSA_SUCCESS) {
2708 +               FsaCommPrint("User Complete FIB failed.\n");
2709 +
2710 +                       FreeFib( FibContext );
2711 +                       return (ENXIO);
2712 +               }
2713 +
2714 +
2715 +    }
2716 +
2717 +
2718 +       //
2719 +       //      Make sure that the size returned by the adapter (which includes
2720 +       //      the header) is less than or equal to the size of a fib, so we
2721 +       //      don't corrupt application data. Then copy that size to the user
2722 +       //      buffer. (Don't try to add the header information again, since it
2723 +       //      was already included by the adapter.)
2724 +       //
2725 +    ASSERT(KFib->Header.Size <= sizeof(FIB));
2726 +
2727 +       if (COPYOUT( (caddr_t) KFib, (caddr_t) IoctlCmdPtr->arg, KFib->Header.Size, IoctlCmdPtr->flag )) {
2728 +               FreeFib( FibContext );
2729 +               Status = EFAULT;
2730 +               return (Status);
2731 +       }
2732 +
2733 +       FreeFib( FibContext );
2734 +
2735 +    return (0);
2736 +
2737 +}
2738 +
2739 +int
2740 +AfaCommCtlAifThread(
2741 +       IN PAFA_COMM_ADAPTER    Adapter,
2742 +       IN PAFA_IOCTL_CMD               IoctlCmdPtr
2743 +)
2744 +/*++
2745 +
2746 +Routine Description:
2747 +
2748 +       This routine will act as the AIF thread for this adapter.
2749 +
2750 +Arguments:
2751 +
2752 +       Adapter - Supplies which adapter is being processed.
2753 +
2754 +       IoctlCmdPtr - Pointer to the arguments to the IOCTL call
2755 +
2756 +Return Value:
2757 +
2758 +       STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2759 +
2760 +       STATUS_INSUFFICIENT_RESOURCES - If a memory allocation failed.
2761 +
2762 +       STATUS_SUCCESS           - Everything OK.
2763 +
2764 +--*/
2765 +{
2766 +       return (NormCommandThread(Adapter));
2767 +}
2768 +
2769 +
2770 +
2771 +#ifdef GATHER_FIB_TIMES
2772 +AAC_STATUS
2773 +AfaCommGetFibTimes(
2774 +       IN PAFA_COMM_ADAPTER    Adapter,
2775 +       IN PIRP                                 Irp
2776 +       )
2777 +/*++
2778 +
2779 +Routine Description:
2780 +
2781 +       This routine returns the gathered fibtimes to the user.
2782 +
2783 +Arguments:
2784 +
2785 +       Adapter - Supplies which adapter is being processed.
2786 +
2787 +    Irp - Supplies the Irp being processed.
2788 +
2789 +Return Value:
2790 +
2791 +       STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2792 +
2793 +       STATUS_INSUFFICIENT_RESOURCES - If a memory allocation failed.
2794 +
2795 +       STATUS_SUCCESS           - Everything OK.
2796 +
2797 +--*/
2798 +{
2799 +       PALL_FIB_TIMES AllFibTimes;
2800 +       PLARGE_INTEGER FreqPtr;
2801 +    PIO_STACK_LOCATION IrpSp;
2802 +
2803 +    //
2804 +    //  Get a pointer to the current Irp stack location
2805 +    //
2806 +
2807 +    IrpSp = IoGetCurrentIrpStackLocation( Irp );
2808 +
2809 +       FreqPtr = (PLARGE_INTEGER)IrpSp->Parameters.FileSystemControl.Type3InputBuffer;
2810 +
2811 +       *FreqPtr = Adapter->FibTimesFrequency;
2812 +
2813 +       AllFibTimes = (PALL_FIB_TIMES)((PUCHAR)FreqPtr + sizeof(LARGE_INTEGER));
2814 +
2815 +       RtlCopyMemory(AllFibTimes, Adapter->FibTimes, sizeof(ALL_FIB_TIMES));
2816 +
2817 +       Irp->IoStatus.Information = 0;
2818 +
2819 +       return (STATUS_SUCCESS);
2820 +
2821 +}
2822 +
2823 +AAC_STATUS
2824 +AfaCommZeroFibTimes(
2825 +       IN PAFA_COMM_ADAPTER    Adapter,
2826 +       IN PIRP                                 Irp
2827 +       )
2828 +/*++
2829 +
2830 +Routine Description:
2831 +
2832 +       This routine zero's the FibTimes structure within the adapter structure.
2833 +
2834 +Arguments:
2835 +
2836 +       Adapter - Supplies which adapter is being processed.
2837 +
2838 +    Irp - Supplies the Irp being processed.
2839 +
2840 +Return Value:
2841 +
2842 +       STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2843 +
2844 +       STATUS_INSUFFICIENT_RESOURCES - If a memory allocation failed.
2845 +
2846 +       STATUS_SUCCESS           - Everything OK.
2847 +
2848 +--*/
2849 +{
2850 +       PFIB_TIMES FibTimesPtr;
2851 +       int i;
2852 +    PIO_STACK_LOCATION IrpSp;
2853 +
2854 +    //
2855 +    //  Get a pointer to the current Irp stack location
2856 +    //
2857 +
2858 +    IrpSp = IoGetCurrentIrpStackLocation( Irp );
2859 +
2860 +       //
2861 +       // Initialize the Fib timing data structures
2862 +       //
2863 +       RtlZeroMemory(Adapter->FibTimes, sizeof(ALL_FIB_TIMES));
2864 +
2865 +       for (i = 0; i < MAX_FSACOMMAND_NUM; i++) {
2866 +
2867 +               FibTimesPtr = &Adapter->FibTimes->FileSys[i];
2868 +
2869 +               FibTimesPtr->Minimum.LowPart = 0xffffffff;
2870 +               FibTimesPtr->Minimum.HighPart = 0x7fffffff;
2871 +               FibTimesPtr->AdapterMinimum.LowPart = 0xffffffff;
2872 +               FibTimesPtr->AdapterMinimum.HighPart = 0x7fffffff;
2873 +       }
2874 +       for (i = 0; i < MAX_RW_FIB_TIMES; i++) {
2875 +
2876 +               FibTimesPtr = &Adapter->FibTimes->Read[i];
2877 +
2878 +               FibTimesPtr->Minimum.LowPart = 0xffffffff;
2879 +               FibTimesPtr->Minimum.HighPart = 0x7fffffff;
2880 +               FibTimesPtr->AdapterMinimum.LowPart = 0xffffffff;
2881 +               FibTimesPtr->AdapterMinimum.HighPart = 0x7fffffff;
2882 +       }
2883 +       for (i = 0; i < MAX_RW_FIB_TIMES; i++) {
2884 +
2885 +               FibTimesPtr = &Adapter->FibTimes->Write[i];
2886 +
2887 +               FibTimesPtr->Minimum.LowPart = 0xffffffff;
2888 +               FibTimesPtr->Minimum.HighPart = 0x7fffffff;
2889 +               FibTimesPtr->AdapterMinimum.LowPart = 0xffffffff;
2890 +               FibTimesPtr->AdapterMinimum.HighPart = 0x7fffffff;
2891 +       }
2892 +
2893 +       FibTimesPtr = &Adapter->FibTimes->Other;
2894 +
2895 +       FibTimesPtr->Minimum.LowPart = 0xffffffff;
2896 +       FibTimesPtr->Minimum.HighPart = 0x7fffffff;
2897 +       FibTimesPtr->AdapterMinimum.LowPart = 0xffffffff;
2898 +       FibTimesPtr->AdapterMinimum.HighPart = 0x7fffffff;
2899 +
2900 +       Irp->IoStatus.Information = 0;
2901 +
2902 +       return (STATUS_SUCCESS);
2903 +
2904 +}
2905 +#endif // GATHER_FIB_TIMES
2906 +
2907 +#ifndef unix_aif
2908 +int
2909 +FsaCtlOpenGetAdapterFib(
2910 +       IN PAFA_COMM_ADAPTER    Adapter,
2911 +       IN PAFA_IOCTL_CMD               IoctlCmdPtr
2912 +       )
2913 +/*++
2914 +
2915 +Routine Description:
2916 +
2917 +    This routine will get the next Fib, if available, from the AdapterFibContext
2918 +       passed in from the user.
2919 +
2920 +Arguments:
2921 +
2922 +       Adapter - Supplies which adapter is being processed.
2923 +
2924 +    Irp - Supplies the Irp being processed.
2925 +
2926 +Return Value:
2927 +
2928 +       STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2929 +
2930 +       STATUS_INSUFFICIENT_RESOURCES - If a memory allocation failed.
2931 +
2932 +       STATUS_SUCCESS           - Everything OK.
2933 +
2934 +--*/
2935 +{
2936 +       PGET_ADAPTER_FIB_CONTEXT AdapterFibContext;
2937 +//     HANDLE Event;
2938 +//    PKEVENT eventObject = (PKEVENT) NULL;
2939 +       int Status;
2940 +
2941 +       //
2942 +       // The context must be allocated from NonPagedPool because we need to use MmIsAddressValid.
2943 +       //
2944 +
2945 +       AdapterFibContext = OsAllocMemory(sizeof(GET_ADAPTER_FIB_CONTEXT), OS_ALLOC_MEM_SLEEP);
2946 +
2947 +       if (AdapterFibContext == NULL) {
2948 +
2949 +               Status = ENOMEM;
2950 +
2951 +       } else {
2952 +
2953 +               AdapterFibContext->NodeTypeCode = FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT;
2954 +               AdapterFibContext->NodeByteSize = sizeof(GET_ADAPTER_FIB_CONTEXT);
2955 +
2956 +
2957 +               //
2958 +               // Initialize the conditional variable use to wait for the next AIF.
2959 +               //
2960 +
2961 +               OsCv_init( &AdapterFibContext->UserEvent);
2962 +
2963 +               //
2964 +               // Set WaitingForFib to FALSE to indicate we are not in a WaitForSingleObject
2965 +               //
2966 +
2967 +               AdapterFibContext->WaitingForFib = FALSE;
2968 +
2969 +               //
2970 +               // Initialize the FibList and set the count of fibs on the list to 0.
2971 +               //
2972 +
2973 +               AdapterFibContext->FibCount = 0;
2974 +               InitializeListHead(&AdapterFibContext->FibList);
2975 +
2976 +               //
2977 +               // Overload FileObject with a time stamp.
2978 +               //
2979 +               AdapterFibContext->FileObject = (void *)OsGetSeconds();
2980 +
2981 +               //
2982 +               // Now add this context onto the adapter's AdapterFibContext list.
2983 +               //
2984 +
2985 +               OsCvLockAcquire(Adapter->AdapterFibMutex);
2986 +
2987 +               InsertTailList(&Adapter->AdapterFibContextList, &AdapterFibContext->NextContext);
2988 +
2989 +               OsCvLockRelease(Adapter->AdapterFibMutex);
2990 +
2991 +               if (COPYOUT( &AdapterFibContext, (caddr_t) IoctlCmdPtr->arg, sizeof(PGET_ADAPTER_FIB_CONTEXT), 
2992 +                                                IoctlCmdPtr->flag )) {
2993 +
2994 +                       Status = EFAULT;
2995 +                       
2996 +               } else {
2997 +               
2998 +                       Status = 0;
2999 +
3000 +               }       
3001 +
3002 +       }
3003 +
3004 +       return (Status);
3005 +}
3006 +
3007 +int
3008 +FsaCtlGetNextAdapterFib(
3009 +       IN PAFA_COMM_ADAPTER    Adapter,
3010 +       IN PAFA_IOCTL_CMD               IoctlCmdPtr
3011 +       )
3012 +/*++
3013 +
3014 +Routine Description:
3015 +
3016 +    This routine will get the next Fib, if available, from the AdapterFibContext
3017 +       passed in from the user.
3018 +
3019 +Arguments:
3020 +
3021 +       Adapter - Supplies which adapter is being processed.
3022 +
3023 +    Irp - Supplies the Irp being processed.
3024 +
3025 +Return Value:
3026 +
3027 +       STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
3028 +
3029 +       STATUS_NO_MORE_ENTRIES - There are no more Fibs for this AdapterFibContext.
3030 +
3031 +       STATUS_SUCCESS           - Everything OK.
3032 +
3033 +--*/
3034 +{
3035 +       GET_ADAPTER_FIB_IOCTL AdapterFibIoctl;
3036 +       PGET_ADAPTER_FIB_CONTEXT AdapterFibContext, aifcp;
3037 +       PFIB Fib;
3038 +       int Status;
3039 +       PLIST_ENTRY Entry;
3040 +       int found;
3041 +
3042 +       if (COPYIN( (caddr_t) IoctlCmdPtr->arg, (caddr_t) &AdapterFibIoctl,
3043 +                                       sizeof(GET_ADAPTER_FIB_IOCTL), IoctlCmdPtr->flag )) {
3044 +               return (EFAULT);
3045 +       }
3046 +
3047 +       //
3048 +       // Extract the AdapterFibContext from the Input parameters.
3049 +       //
3050 +
3051 +       AdapterFibContext = (PGET_ADAPTER_FIB_CONTEXT) AdapterFibIoctl.AdapterFibContext;
3052 +
3053 +       //
3054 +       // Verify that the HANDLE passed in was a valid AdapterFibContext
3055 +       //
3056 +       // Search the list of AdapterFibContext addresses on the adapter to be sure
3057 +       // this is a valid address
3058 +
3059 +       found = 0;
3060 +       Entry = Adapter->AdapterFibContextList.Flink;
3061 +
3062 +       while ( Entry != &Adapter->AdapterFibContextList ) {
3063 +                       aifcp = CONTAINING_RECORD ( Entry, GET_ADAPTER_FIB_CONTEXT, NextContext );
3064 +                       if ( AdapterFibContext == aifcp ) {   // We found a winner
3065 +                                       found = 1;
3066 +                                       break;
3067 +                       }
3068 +                       Entry = Entry->Flink;
3069 +       }
3070 +
3071 +       if ( found == 0 ) {
3072 +                       return ( EINVAL );;
3073 +       }
3074 +
3075 +       if ( (AdapterFibContext->NodeTypeCode != FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT) ||
3076 +                (AdapterFibContext->NodeByteSize != sizeof(GET_ADAPTER_FIB_CONTEXT)) ) {
3077 +
3078 +               return ( EINVAL );
3079 +
3080 +       }
3081 +
3082 +       Status = STATUS_SUCCESS;
3083 +
3084 +       OsCvLockAcquire(Adapter->AdapterFibMutex);
3085 +
3086 +       //
3087 +       // If there are no fibs to send back, then either wait or return EAGAIN
3088 +       //
3089 +return_fib:
3090 +
3091 +       if (!IsListEmpty(&AdapterFibContext->FibList)) {
3092 +
3093 +               PLIST_ENTRY Entry;
3094 +
3095 +               //
3096 +               // Pull the next fib from the FibList
3097 +               //
3098 +               Entry = RemoveHeadList(&AdapterFibContext->FibList);
3099 +
3100 +               Fib = CONTAINING_RECORD( Entry, FIB, Header.FibLinks );
3101 +
3102 +               AdapterFibContext->FibCount--;
3103 +
3104 +               if (COPYOUT( Fib, AdapterFibIoctl.AifFib, sizeof(FIB), IoctlCmdPtr->flag )) {
3105 +
3106 +                       OsCvLockRelease( Adapter->AdapterFibMutex );
3107 +                       OsFreeMemory( Fib, sizeof(Fib) );
3108 +                       return (EFAULT);
3109 +
3110 +               }       
3111 +
3112 +               //
3113 +               // Free the space occupied by this copy of the fib.
3114 +               //
3115 +
3116 +               OsFreeMemory(Fib, sizeof(FIB));
3117 +
3118 +        Status = 0;
3119 +
3120 +               //
3121 +               // Overload FileObject with a time stamp
3122 +               // 
3123 +               AdapterFibContext->FileObject = ( void * )OsGetSeconds();
3124 +
3125 +       } else {
3126 +
3127 +               if (AdapterFibIoctl.Wait) {
3128 +                       
3129 +                       if (OsCv_wait_sig( &AdapterFibContext->UserEvent, Adapter->AdapterFibMutex ) == 0) {
3130 +
3131 +                               Status = EINTR;
3132 +
3133 +                       } else {
3134 +                       
3135 +                               goto return_fib;
3136 +                               
3137 +                       }
3138 +               } else {
3139 +                                       
3140 +                       Status = EAGAIN;
3141 +
3142 +               }       
3143 +
3144 +       }
3145 +       OsCvLockRelease( Adapter->AdapterFibMutex );
3146 +
3147 +       return (Status);
3148 +}
3149 +
3150 +int
3151 +FsaCtlCloseGetAdapterFib(
3152 +       IN PAFA_COMM_ADAPTER    Adapter,
3153 +       IN PAFA_IOCTL_CMD               IoctlCmdPtr
3154 +       )
3155 +/*++
3156 +
3157 +Routine Description:
3158 +
3159 +    This routine will close down the AdapterFibContext passed in from the user.
3160 +
3161 +Arguments:
3162 +
3163 +       Adapter - Supplies which adapter is being processed.
3164 +
3165 +    Irp - Supplies the Irp being processed.
3166 +
3167 +Return Value:
3168 +
3169 +       STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
3170 +
3171 +       STATUS_SUCCESS           - Everything OK.
3172 +
3173 +--*/
3174 +{
3175 +       PGET_ADAPTER_FIB_CONTEXT AdapterFibContext, aifcp;
3176 +       AAC_STATUS Status;
3177 +
3178 +       PLIST_ENTRY Entry;
3179 +       int found;
3180 +
3181 +       //
3182 +       // Extract the AdapterFibContext from the Input parameters
3183 +       //
3184 +
3185 +       AdapterFibContext = (PGET_ADAPTER_FIB_CONTEXT) IoctlCmdPtr->arg;
3186 +
3187 +       if (AdapterFibContext == 0) {
3188 +               cmn_err(CE_WARN, "FsaCtlCloseGetAdapterFib: AdapterFibContext is NULL");
3189 +               return(EINVAL);
3190 +       }
3191 +
3192 +       //
3193 +       // Verify that the HANDLE passed in was a valid AdapterFibContext
3194 +       //
3195 +       // Search the list of AdapterFibContext addresses on the adapter to be sure
3196 +       // this is a valid address
3197 +
3198 +       found = 0;
3199 +       Entry = Adapter->AdapterFibContextList.Flink;
3200 +
3201 +       while ( Entry != &Adapter->AdapterFibContextList ) {
3202 +                       aifcp = CONTAINING_RECORD ( Entry, GET_ADAPTER_FIB_CONTEXT, NextContext );
3203 +                       if ( AdapterFibContext == aifcp ) {   // We found a winner
3204 +                                       found = 1;
3205 +                                       break;
3206 +                       }
3207 +                       Entry = Entry->Flink;
3208 +       }
3209 +
3210 +       if ( found == 0 ) {
3211 +               return ( 0 ); // Already Gone
3212 +       }
3213 +
3214 +       if ( (AdapterFibContext->NodeTypeCode != FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT) ||
3215 +                (AdapterFibContext->NodeByteSize != sizeof(GET_ADAPTER_FIB_CONTEXT)) ) {
3216 +
3217 +               return (EINVAL);
3218 +
3219 +       }
3220 +
3221 +       OsCvLockAcquire(Adapter->AdapterFibMutex);
3222 +
3223 +       Status = FsaCloseAdapterFibContext(Adapter, AdapterFibContext);
3224 +
3225 +       OsCvLockRelease(Adapter->AdapterFibMutex);
3226 +
3227 +       return (Status);
3228 +}
3229 +
3230 +int
3231 +FsaCloseAdapterFibContext(
3232 +       IN PAFA_COMM_ADAPTER                    Adapter,
3233 +       IN PGET_ADAPTER_FIB_CONTEXT             AdapterFibContext
3234 +       )
3235 +{
3236 +       int Status;
3237 +       PFIB Fib;
3238 +
3239 +       //
3240 +       // First free any FIBs that have not been consumed yet.
3241 +       //
3242 +
3243 +       while (!IsListEmpty(&AdapterFibContext->FibList)) {
3244 +
3245 +               PLIST_ENTRY Entry;
3246 +
3247 +               //
3248 +               // Pull the next fib from the FibList
3249 +               //
3250 +
3251 +               Entry = RemoveHeadList(&AdapterFibContext->FibList);
3252 +
3253 +               Fib = CONTAINING_RECORD( Entry, FIB, Header.FibLinks );
3254 +
3255 +               AdapterFibContext->FibCount--;
3256 +
3257 +               //
3258 +               // Free the space occupied by this copy of the fib.
3259 +               //
3260 +
3261 +               OsFreeMemory(Fib, sizeof(FIB));
3262 +       }
3263 +
3264 +       //
3265 +       // Remove the Context from the AdapterFibContext List
3266 +       //
3267 +
3268 +       RemoveEntryList(&AdapterFibContext->NextContext);
3269 +
3270 +       OsCv_destroy( &AdapterFibContext->UserEvent );
3271 +
3272 +       //
3273 +       // Invalidate context
3274 +       //
3275 +
3276 +       AdapterFibContext->NodeTypeCode = 0;
3277 +
3278 +       //
3279 +       // Free the space occupied by the Context
3280 +       //
3281 +
3282 +       OsFreeMemory(AdapterFibContext, sizeof(GET_ADAPTER_FIB_CONTEXT));
3283 +
3284 +       Status = STATUS_SUCCESS;
3285 +
3286 +    return Status;
3287 +}
3288 +#endif 
3289 +
3290 +AAC_STATUS
3291 +AfaCommOpenAdapter(
3292 +       IN PVOID Arg
3293 +       )
3294 +/*++
3295 +
3296 +Routine Description:
3297 +
3298 +       The routine will get called by the miniport each time a user issues a CreateFile on the DeviceObject
3299 +       for the adapter.
3300 +
3301 +       The main purpose of this routine is to set up any data structures that may be needed
3302 +       to handle any requests made on this DeviceObject.
3303 +
3304 +Arguments:
3305 +
3306 +       Adapter - Pointer to which adapter miniport was opened.
3307 +
3308 +
3309 +Return Value:
3310 +
3311 +       STATUS_SUCCESS
3312 +
3313 +--*/
3314 +
3315 +{
3316 +       PAFA_COMM_ADAPTER       Adapter = (PAFA_COMM_ADAPTER) Arg;
3317 +       AAC_STATUS Status = STATUS_SUCCESS;
3318 +       PAFA_CLASS_DRIVER ClassDriver;
3319 +
3320 +       ClassDriver = Adapter->ClassDriverList;
3321 +
3322 +       while (ClassDriver) {
3323 +
3324 +               if (ClassDriver->OpenAdapter) {
3325 +
3326 +                       Status = ClassDriver->OpenAdapter( ClassDriver->ClassDriverExtension );
3327 +
3328 +                       if (Status != STATUS_SUCCESS)
3329 +                               break;
3330 +               }
3331 +
3332 +               ClassDriver = ClassDriver->Next;
3333 +       }
3334 +
3335 +       return ( Status );
3336 +}
3337 +
3338 +AAC_STATUS
3339 +AfaCommCloseAdapter(
3340 +       IN PVOID Arg
3341 +       )
3342 +/*++
3343 +
3344 +Routine Description:
3345 +
3346 +       This routine will get called by the miniport each time a user issues a CloseHandle on the DeviceObject
3347 +       for the adapter.
3348 +
3349 +       The main purpose of this routine is to cleanup any data structures that have been set up
3350 +       while this FileObject has been opened.
3351 +
3352 +       This routine loops through all of the AdapterFibContext structures to determine if any need
3353 +       to be deleted for this FileObject.
3354 +
3355 +Arguments:
3356 +
3357 +       Adapter - Pointer to adapter miniport
3358 +
3359 +       Irp - Pointer to Irp that caused this close
3360 +
3361 +Return Value:
3362 +
3363 +       Status value returned from File system driver AdapterClose
3364 +
3365 +--*/
3366 +{
3367 +       PAFA_COMM_ADAPTER       Adapter = (PAFA_COMM_ADAPTER) Arg;
3368 +       PLIST_ENTRY Entry, NextEntry;
3369 +       PGET_ADAPTER_FIB_CONTEXT AdapterFibContext;
3370 +       AAC_STATUS Status = STATUS_SUCCESS;
3371 +       PAFA_CLASS_DRIVER ClassDriver;
3372 +
3373 +       OsCvLockAcquire(Adapter->AdapterFibMutex);
3374 +
3375 +       Entry = Adapter->AdapterFibContextList.Flink;
3376 +
3377 +       //
3378 +       // Loop through all of the AdapterFibContext, looking for any that
3379 +       // were created with the FileObject that is being closed.
3380 +       //
3381 +       while (Entry != &Adapter->AdapterFibContextList) {
3382 +
3383 +               //
3384 +               // Extract the AdapterFibContext
3385 +               //
3386 +               AdapterFibContext = CONTAINING_RECORD( Entry, GET_ADAPTER_FIB_CONTEXT, NextContext );
3387 +
3388 +               // 
3389 +               // Save the next entry because CloseAdapterFibContext will delete the AdapterFibContext
3390 +               //
3391 +               NextEntry = Entry->Flink;
3392 +
3393 +               Entry = NextEntry;
3394 +
3395 +       }
3396 +
3397 +#ifdef unix_config_file
3398 +       //
3399 +       // If this FileObject had the adapter open for configuration, then release it.
3400 +       //
3401 +       if ( Adapter->AdapterConfigFileObject == IrpSp->FileObject ) {
3402 +
3403 +               Adapter->AdapterConfigFileObject = NULL;
3404 +
3405 +       }
3406 +#endif
3407 +
3408 +       OsCvLockRelease(Adapter->AdapterFibMutex);
3409 +
3410 +       ClassDriver = Adapter->ClassDriverList;
3411 +
3412 +       while (ClassDriver) {
3413 +
3414 +               if (ClassDriver->CloseAdapter) {
3415 +
3416 +                       Status = ClassDriver->CloseAdapter( ClassDriver->ClassDriverExtension );
3417 +
3418 +                       if (Status != STATUS_SUCCESS)
3419 +                               break;
3420 +               }
3421 +
3422 +               ClassDriver = ClassDriver->Next;
3423 +       }
3424 +
3425 +       return ( Status );
3426 +
3427 +}
3428 +
3429 diff -burN linux-2.4.4/drivers/scsi/aacraid/comminit.c linux/drivers/scsi/aacraid/comminit.c
3430 --- linux-2.4.4/drivers/scsi/aacraid/comminit.c Wed Dec 31 18:00:00 1969
3431 +++ linux/drivers/scsi/aacraid/comminit.c       Mon Apr 30 09:43:34 2001
3432 @@ -0,0 +1,986 @@
3433 +/*++
3434 + * Adaptec aacraid device driver for Linux.
3435 + *
3436 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
3437 + *
3438 + * This program is free software; you can redistribute it and/or modify
3439 + * it under the terms of the GNU General Public License as published by
3440 + * the Free Software Foundation; either version 2, or (at your option)
3441 + * any later version.
3442 + *
3443 + * This program is distributed in the hope that it will be useful,
3444 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
3445 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
3446 + * GNU General Public License for more details.
3447 + *
3448 + * You should have received a copy of the GNU General Public License
3449 + * along with this program; see the file COPYING.  If not, write to
3450 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
3451 + *
3452 + * Module Name:
3453 + *  comminit.c
3454 + *
3455 + * Abstract: This supports the initialization of the host adapter commuication interface.
3456 + *    This is a platform dependent module for the pci cyclone board.
3457 + *
3458 + --*/
3459 +
3460 +static char *ident_comminit = "aacraid_ident comminit.c 1.0.6 2000/10/09 Adaptec, Inc.";
3461 +
3462 +#include "comprocs.h"
3463 +
3464 +#define BugCheckFileId                   (FSAFS_BUG_CHECK_COMMINIT)
3465 +
3466 +VOID
3467 +AfaCommBugcheckHandler(
3468 +               IN PVOID Buffer,
3469 +               IN ULONG Length
3470 +               );
3471 +
3472 +VOID
3473 +ThrottlePeriodEndDpcRtn(
3474 +       IN PKDPC Dpc,
3475 +       IN PVOID DeferredContext,
3476 +       IN PVOID SystemArgument1,
3477 +       IN PVOID SystemArgument2);
3478 +
3479 +FSA_COMM_DATA FsaCommData;
3480 +
3481 +AAC_STATUS
3482 +HardInterruptModeration1Changed(
3483 +       IN PVOID AdapterContext,
3484 +       IN ULONG NewValue
3485 +       )
3486 +{
3487 +       PAFA_COMM_ADAPTER Adapter = AdapterContext;
3488 +
3489 +       //
3490 +       // If we are using interrupt moderation, then disable the interrupt
3491 +       // until we need to use it.
3492 +       //
3493 +       if (FsaCommData.HardInterruptModeration1)
3494 +               DisableInterrupt( Adapter, AdapNormCmdNotFull, FALSE );
3495 +       else
3496 +               EnableInterrupt( Adapter, AdapNormCmdNotFull, FALSE );
3497 +
3498 +       return (STATUS_SUCCESS);
3499 +}
3500 +
3501 +AAC_STATUS
3502 +FsaFibTimeoutChanged(
3503 +       IN PVOID AdapterContext,
3504 +       IN ULONG NewValue
3505 +       )
3506 +{
3507 +       //
3508 +       // scale the new timeout from seconds to 100 nsec units
3509 +       //
3510 +//     FsaCommData.AdapterTimeout = RtlConvertLongToLargeInteger(-10*1000*1000*NewValue);
3511 +
3512 +       return (STATUS_SUCCESS);
3513 +}
3514 +
3515 +#ifdef GATHER_FIB_TIMES
3516 +extern int GatherFibTimes;
3517 +#endif
3518 +
3519 +FSA_USER_VAR FsaCommUserVars[] = {
3520 +#ifdef FIB_CHECKSUMS
3521 +    { "do_fib_checksums", (PULONG)&FsaCommData.do_fib_checksums, NULL },
3522 +#endif
3523 +#ifdef GATHER_FIB_TIMES
3524 +       { "GatherFibTimes", (PULONG)&GatherFibTimes, NULL },
3525 +#endif
3526 +       { "EnableAdapterTimeouts", (PULONG)&FsaCommData.EnableAdapterTimeouts, NULL},
3527 +       { "EnableInterruptModeration", (PULONG)&FsaCommData.EnableInterruptModeration, NULL },
3528 +       { "FsaDataFibsSent", (PULONG) &FsaCommData.FibsSent, NULL },
3529 +       { "FsaDataFibRecved", (PULONG) &FsaCommData.FibRecved, NULL },
3530 +       { "HardInterruptModeration", (PULONG)&FsaCommData.HardInterruptModeration, NULL},
3531 +       { "HardInterruptModeration1", (PULONG)&FsaCommData.HardInterruptModeration1, HardInterruptModeration1Changed},
3532 +       { "EnableFibTimeoutBreak", (PULONG)&FsaCommData.EnableFibTimeoutBreak, NULL},
3533 +       { "PeakFibsConsumed", (PULONG)&FsaCommData.PeakFibsConsumed, NULL },
3534 +       { "ZeroFibsConsumed", (PULONG)&FsaCommData.ZeroFibsConsumed, NULL },
3535 +       { "FibTimeoutSeconds", (PULONG) &FsaCommData.FibTimeoutSeconds, FsaFibTimeoutChanged },
3536 +};
3537 +
3538 +#define NUM_COMM_USER_VARS     (sizeof(FsaCommUserVars) / sizeof(FSA_USER_VAR) )
3539 +
3540 +\f
3541 +AAC_STATUS
3542 +AacCommDriverEntry(
3543 +    )
3544 +
3545 +/*++
3546 +
3547 +Routine Description:
3548 +
3549 +    This is the initialization routine for the FileArray Comm layer device driver.
3550 +
3551 +Arguments:
3552 +
3553 +    DriverObject - Pointer to driver object created by the system.
3554 +
3555 +Return Value:
3556 +
3557 +    AAC_STATUS - The function value is the final status from the initialization
3558 +        operation.
3559 +
3560 +--*/
3561 +
3562 +{
3563 +    AAC_STATUS Status;
3564 +       PVOID BugCheckBuffer;
3565 +
3566 +       RtlZeroMemory( &FsaCommData, sizeof(FSA_COMM_DATA) );
3567 +
3568 +
3569 +    //
3570 +    // Load the global timeout value for the adapter timeout
3571 +    // Also init the global that enables or disables adapter timeouts
3572 +    //
3573 +
3574 +//     FsaCommData.AdapterTimeout = RtlConvertLongToLargeInteger(-10*1000*1000*180);
3575 +
3576 +       FsaCommData.FibTimeoutSeconds = 180;
3577 +
3578 +       FsaCommData.EnableAdapterTimeouts = TRUE; 
3579 +
3580 +//     FsaCommData.QueueFreeTimeout = RtlConvertLongToLargeInteger(QUEUE_ENTRY_FREE_TIMEOUT);
3581 +
3582 +#ifdef unix_fib_timeout
3583 +       FsaCommData.FibTimeoutIncrement = (180 * 1000 * 1000 * 10) / KeQueryTimeIncrement();
3584 +#endif
3585 +
3586 +       FsaCommData.EnableInterruptModeration = FALSE;
3587 +
3588 +       //
3589 +       // Preload UserVars with all variables from the comm layer.  The class layers will
3590 +       // include theirs when they register.
3591 +       //
3592 +
3593 +       FsaCommData.UserVars = OsAllocMemory(NUM_COMM_USER_VARS * sizeof(FSA_USER_VAR), OS_ALLOC_MEM_SLEEP );
3594 +       FsaCommData.NumUserVars = NUM_COMM_USER_VARS;
3595 +
3596 +       RtlCopyMemory( FsaCommData.UserVars, &FsaCommUserVars, NUM_COMM_USER_VARS * sizeof(FSA_USER_VAR) );
3597 +
3598 +
3599 +#ifdef AACDISK
3600 +       //
3601 +       // Call the disk driver to initialize itself.
3602 +       //
3603 +
3604 +       AacDiskDriverEntry();
3605 +
3606 +#endif
3607 +
3608 +
3609 +
3610 +       return (STATUS_SUCCESS);
3611 +}
3612 +
3613 +
3614 +VOID
3615 +DetachNTQueue(
3616 +       IN PAFA_COMM_ADAPTER Adapter,
3617 +    IN OUT PCOMM_QUE Queue,
3618 +    IN QUEUE_TYPES WhichQueue
3619 +    )
3620 +/*++
3621 +
3622 +Routine Description:
3623 +
3624 +       This routine will release all of the resources used by a given queue.
3625 +
3626 +Arguments:
3627 +
3628 +       Adapter - Which adapter the queue belongs to
3629 +       Queue - Pointer to the queue itself
3630 +       WhichQueue - Identifies which of the host queues this is.
3631 +
3632 +Return Value:
3633 +
3634 +       NONE.
3635 +
3636 +--*/
3637 +{
3638 +    switch (WhichQueue) {
3639 +
3640 +        case HostNormCmdQueue:
3641 +
3642 +                       Os_remove_softintr( Queue->ConsumerRoutine );
3643 +                       OsSpinLockDestroy( Queue->QueueLock );
3644 +                       OsCv_destroy( &Queue->CommandReady );
3645 +                               
3646 +            break;
3647 +
3648 +        case HostHighCmdQueue:
3649 +
3650 +                       Os_remove_softintr( Queue->ConsumerRoutine );
3651 +                       OsSpinLockDestroy( Queue->QueueLock );
3652 +                       OsCv_destroy( &Queue->CommandReady );
3653 +                               
3654 +            break;
3655 +
3656 +        case HostNormRespQueue:
3657 +
3658 +                       Os_remove_softintr( Queue->ConsumerRoutine );
3659 +                       OsSpinLockDestroy( Queue->QueueLock );
3660 +            break;
3661 +
3662 +        case HostHighRespQueue:
3663 +
3664 +                       Os_remove_softintr( Queue->ConsumerRoutine );
3665 +                       OsSpinLockDestroy( Queue->QueueLock );
3666 +            break;
3667 +
3668 +        case AdapNormCmdQueue:
3669 +        case AdapHighCmdQueue:
3670 +        case AdapNormRespQueue:
3671 +        case AdapHighRespQueue:
3672 +                       OsCv_destroy( &Queue->QueueFull );
3673 +            break;
3674 +    }
3675 +}
3676 +    
3677 +VOID
3678 +InitializeNTQueue(
3679 +       IN PAFA_COMM_ADAPTER Adapter,
3680 +    IN OUT PCOMM_QUE Queue,
3681 +    IN QUEUE_TYPES WhichQueue
3682 +    )
3683 +/*++
3684 +
3685 +Routine Description:
3686 +
3687 +    Will initialize all entries in the queue that is NT specific.
3688 +
3689 +Arguments:
3690 +
3691 +Return Value:
3692 +
3693 +    Nothing there is nothing to allocate so nothing should fail
3694 +
3695 +--*/
3696 +{
3697 +    
3698 +       Queue->NumOutstandingIos = 0;
3699 +
3700 +       //
3701 +       // Store a pointer to the adapter structure.
3702 +       //
3703 +
3704 +       Queue->Adapter = Adapter;
3705 +
3706 +       InitializeListHead( &Queue->OutstandingIoQueue );
3707 +           
3708 +    switch (WhichQueue) {
3709 +
3710 +        case HostNormCmdQueue:
3711 +
3712 +                       OsCv_init( &Queue->CommandReady);
3713 +                       OsSpinLockInit( Queue->QueueLock, Adapter->SpinLockCookie);
3714 +                       if (ddi_add_softintr( Adapter->Dip, DDI_SOFTINT_HIGH, &Queue->ConsumerRoutine, NULL,
3715 +                                                                 NULL, (PUNIX_INTR_HANDLER)HostCommandNormDpc,
3716 +                                                                 (caddr_t)Queue ) != DDI_SUCCESS) {
3717 +
3718 +                               cmn_err(CE_CONT, "OS_addr_intr failed\n");                                      
3719 +                       }                                       
3720 +
3721 +            InitializeListHead(&Queue->CommandQueue);
3722 +
3723 +            break;
3724 +
3725 +        case HostHighCmdQueue:
3726 +
3727 +                       OsCv_init( &Queue->CommandReady);
3728 +                       OsSpinLockInit( Queue->QueueLock, Adapter->SpinLockCookie);
3729 +                       if (ddi_add_softintr( Adapter->Dip, DDI_SOFTINT_HIGH, &Queue->ConsumerRoutine, NULL,
3730 +                                                                 NULL, (PUNIX_INTR_HANDLER)HostCommandHighDpc,
3731 +                                                                 (caddr_t) Queue ) != DDI_SUCCESS) {
3732 +
3733 +                               cmn_err(CE_CONT, "OS_addr_intr failed\n");                                      
3734 +                       }                                       
3735 +
3736 +            InitializeListHead(&Queue->CommandQueue);
3737 +            break;
3738 +
3739 +        case HostNormRespQueue:
3740 +
3741 +                       OsSpinLockInit( Queue->QueueLock, Adapter->SpinLockCookie);
3742 +                       if (ddi_add_softintr( Adapter->Dip, DDI_SOFTINT_HIGH, &Queue->ConsumerRoutine, NULL,
3743 +                                                                 NULL, (PUNIX_INTR_HANDLER)HostResponseNormalDpc, 
3744 +                                                                 (caddr_t) Queue ) != DDI_SUCCESS) {
3745 +
3746 +                               cmn_err(CE_CONT, "OS_addr_intr failed\n");                                      
3747 +                       }                                       
3748 +            break;
3749 +
3750 +        case HostHighRespQueue:
3751 +
3752 +
3753 +                       OsSpinLockInit( Queue->QueueLock, Adapter->SpinLockCookie);
3754 +                       if (ddi_add_softintr( Adapter->Dip, DDI_SOFTINT_HIGH, &Queue->ConsumerRoutine, NULL,
3755 +                                                                 NULL, (PUNIX_INTR_HANDLER)HostResponseHighDpc, 
3756 +                                                                 (caddr_t) Queue ) != DDI_SUCCESS) {
3757 +
3758 +                               cmn_err(CE_CONT, "OS_addr_intr failed\n");                                      
3759 +                       }                                       
3760 +            break;
3761 +
3762 +        case AdapNormCmdQueue:
3763 +        case AdapHighCmdQueue:
3764 +        case AdapNormRespQueue:
3765 +        case AdapHighRespQueue:
3766 +
3767 +                       OsCv_init( &Queue->QueueFull);
3768 +            break;
3769 +    }
3770 +}
3771 +
3772 +BOOLEAN
3773 +StartFsaCommandThreads(PAFA_COMM_ADAPTER Adapter)
3774 +/*++
3775 +
3776 +Routine Description:
3777 +
3778 +    Create and start the command receiver threads.
3779 +
3780 +Arguments:
3781 +
3782 +
3783 +Return Value:
3784 +
3785 +    Nothing
3786 +
3787 +--*/
3788 +
3789 +{
3790 +    return(TRUE);
3791 +}
3792 +
3793 +
3794 +
3795 +/*++
3796 +
3797 +Routine Description:
3798 +
3799 +       This routine gets called to detach all resources that have been allocated for 
3800 +       this adapter.
3801 +
3802 +Arguments:
3803 +
3804 +       Adapter - Pointer to the adapter structure to detach.
3805 +
3806 +Return Value:
3807 +
3808 +    TRUE - All resources have been properly released.
3809 +    FALSE - An error occured while trying to release resources.
3810 +--*/
3811 +BOOLEAN
3812 +AacCommDetachAdapter (IN PAFA_COMM_ADAPTER     Adapter)
3813 +{
3814 +       PAFA_CLASS_DRIVER ClassDriver;
3815 +       //
3816 +       // First remove this adapter from the list of adapters.
3817 +       //
3818 +
3819 +       if (FsaCommData.AdapterList == Adapter) {
3820 +               
3821 +               FsaCommData.AdapterList = Adapter->NextAdapter;
3822 +
3823 +       } else {
3824 +
3825 +               PAFA_COMM_ADAPTER CurrentAdapter, NextAdapter;
3826 +       
3827 +               CurrentAdapter = FsaCommData.AdapterList;
3828 +               NextAdapter = CurrentAdapter->NextAdapter;
3829 +
3830 +               while (NextAdapter) {
3831 +                               
3832 +                       if (NextAdapter == Adapter) {
3833 +
3834 +                               CurrentAdapter->NextAdapter = NextAdapter->NextAdapter;
3835 +                               break;
3836 +                        
3837 +                       }
3838 +                       
3839 +                       CurrentAdapter = NextAdapter;
3840 +                       NextAdapter = CurrentAdapter->NextAdapter;
3841 +               }
3842 +       }                       
3843 +               
3844 +       //
3845 +       // First send a shutdown to the adapter.
3846 +       //
3847 +
3848 +       AfaCommShutdown( Adapter );
3849 +
3850 +       //
3851 +       // Destroy the FibContextZone for this adapter.  This will free up all
3852 +       // of the fib space used by this adapter.
3853 +       //
3854 +       
3855 +       FsaFreeFibContextZone( Adapter );
3856 +
3857 +       //
3858 +       // Destroy the mutex used for synch'ing adapter fibs.
3859 +       //
3860 +
3861 +       OsCvLockDestroy( Adapter->AdapterFibMutex );
3862 +
3863 +       //
3864 +       // Detach all of the host queues.
3865 +       //
3866 +
3867 +    DetachNTQueue( Adapter, &Adapter->CommRegion->AdapHighRespQue, AdapHighRespQueue );
3868 +    DetachNTQueue( Adapter, &Adapter->CommRegion->AdapNormRespQue, AdapNormRespQueue );
3869 +    DetachNTQueue( Adapter, &Adapter->CommRegion->HostHighRespQue, HostHighRespQueue );
3870 +    DetachNTQueue( Adapter, &Adapter->CommRegion->HostNormRespQue, HostNormRespQueue );
3871 +    DetachNTQueue( Adapter, &Adapter->CommRegion->AdapHighCmdQue, AdapHighCmdQueue );
3872 +    DetachNTQueue( Adapter, &Adapter->CommRegion->AdapNormCmdQue, AdapNormCmdQueue );
3873 +    DetachNTQueue( Adapter, &Adapter->CommRegion->HostHighCmdQue, HostHighCmdQueue );
3874 +       DetachNTQueue( Adapter, &Adapter->CommRegion->HostNormCmdQue, HostNormCmdQueue );
3875 +
3876 +       //
3877 +       // Destroy the mutex used to protect the FibContextZone
3878 +       //
3879 +
3880 +       OsSpinLockDestroy( Adapter->FibContextZoneSpinLock );
3881 +
3882 +       //
3883 +       // Call the miniport to free the space allocated for the shared comm queues
3884 +       // between the host and the adapter.
3885 +       //
3886 +
3887 +       FsaFreeAdapterCommArea( Adapter );
3888 +
3889 +       //
3890 +       // Free the memory used by the comm region for this adapter
3891 +       //
3892 +
3893 +       OsFreeMemory( Adapter->CommRegion, sizeof(COMM_REGION) );
3894 +
3895 +       //
3896 +       // Free the memory used by the adapter structure.
3897 +       //
3898 +       ClassDriver = Adapter->ClassDriverList;
3899 +       Adapter->ClassDriverList = Adapter->ClassDriverList->Next;
3900 +       OsFreeMemory( ClassDriver, sizeof(AFA_CLASS_DRIVER) );
3901 +       
3902 +       OsFreeMemory( Adapter, sizeof(AFA_COMM_ADAPTER) );
3903 +
3904 +       return (TRUE);
3905 +}
3906 +
3907 +PVOID
3908 +AfaCommInitNewAdapter (IN PFSA_NEW_ADAPTER NewAdapter)
3909 +{
3910 +       PVOID BugCheckBuffer;
3911 +       PAFA_COMM_ADAPTER Adapter;
3912 +       MAPFIB_CONTEXT MapFibContext;
3913 +       LARGE_INTEGER Time;
3914 +       char ErrorBuffer[60];
3915 +
3916 +       Adapter = (PAFA_COMM_ADAPTER) OsAllocMemory( sizeof(AFA_COMM_ADAPTER) , OS_ALLOC_MEM_SLEEP );
3917 +
3918 +       if (Adapter == NULL)
3919 +               return (NULL);
3920 +
3921 +       RtlZeroMemory(Adapter, sizeof(AFA_COMM_ADAPTER));
3922 +
3923 +
3924 +       //
3925 +       // Save the current adapter number and increment the total number.
3926 +       //
3927 +
3928 +       Adapter->AdapterNumber = FsaCommData.TotalAdapters++;
3929 +
3930 +
3931 +       //
3932 +       // Fill in the pointer back to the device specific structures.
3933 +       // The device specific driver has also passed a pointer for us to 
3934 +       // fill in with the Adapter object that we have created.
3935 +       //
3936 +
3937 +       Adapter->AdapterExtension = NewAdapter->AdapterExtension;
3938 +       Adapter->AdapterFuncs = NewAdapter->AdapterFuncs;
3939 +       Adapter->InterruptsBelowDpc = NewAdapter->AdapterInterruptsBelowDpc;
3940 +       Adapter->AdapterUserVars = NewAdapter->AdapterUserVars;
3941 +       Adapter->AdapterUserVarsSize = NewAdapter->AdapterUserVarsSize;
3942 +
3943 +       Adapter->Dip = NewAdapter->Dip;
3944 +
3945 +       //
3946 +       // Fill in Our address into the function dispatch table
3947 +       //
3948 +
3949 +       NewAdapter->AdapterFuncs->InterruptHost = AfaCommInterruptHost;
3950 +       NewAdapter->AdapterFuncs->OpenAdapter = AfaCommOpenAdapter;
3951 +       NewAdapter->AdapterFuncs->CloseAdapter = AfaCommCloseAdapter;
3952 +       NewAdapter->AdapterFuncs->DeviceControl = AfaCommAdapterDeviceControl;
3953 +
3954 +       //
3955 +       // Ok now init the communication subsystem
3956 +       //
3957 +
3958 +       Adapter->CommRegion = (PCOMM_REGION) OsAllocMemory(sizeof(COMM_REGION), OS_ALLOC_MEM_SLEEP);
3959 +       if (Adapter->CommRegion == NULL) {
3960 +               cmn_err(CE_WARN, "Error could not allocate comm region.\n");
3961 +               return (NULL);
3962 +       }
3963 +       RtlZeroMemory(Adapter->CommRegion, sizeof(COMM_REGION));
3964 +
3965 +       //
3966 +       // Get a pointer to the iblock_cookie
3967 +       //
3968 +
3969 +       ddi_get_soft_iblock_cookie( Adapter->Dip, DDI_SOFTINT_HIGH, &Adapter->SpinLockCookie );
3970 +
3971 +       if (!CommInit(Adapter)) {
3972 +               FsaCommPrint("Failed to init the commuication subsystem.\n");
3973 +               return(NULL);
3974 +       }
3975 +
3976 +
3977 +       //
3978 +       // Initialize the list of AdapterFibContext's.
3979 +       //
3980 +
3981 +       InitializeListHead(&Adapter->AdapterFibContextList);
3982 +
3983 +       //
3984 +       // Initialize the fast mutex used for synchronization of the adapter fibs
3985 +       //
3986 +
3987 +       Adapter->AdapterFibMutex = OsCvLockAlloc();
3988 +       OsCvLockInit(Adapter->AdapterFibMutex, NULL);
3989 +
3990 +    //
3991 +    // Allocate and start the FSA command threads. These threads will handle
3992 +    // command requests from the adapter. They will wait on an event then pull
3993 +    // all CDBs off the thread's queue. Each CDB will be given to a worker thread
3994 +    // upto a defined limit. When that limit is reached wait a event will be waited
3995 +    // on till a worker thread is finished.
3996 +    //
3997 +
3998 +    if (!StartFsaCommandThreads(Adapter)) {
3999 +           FsaCommPrint("Fsainit could not initilize the command receiver threads.\n");
4000 +               return (NULL);
4001 +    }
4002 +
4003 +#ifdef unix_crash_dump
4004 +       //
4005 +       // Allocate and map a fib for use by the synch path, which is used for crash
4006 +       // dumps.
4007 +       //
4008 +       // Allocate an entire page so that alignment is correct.
4009 +       //
4010 +
4011 +       Adapter->SyncFib = OsAllocMemory( PAGE_SIZE, OS_ALLOC_MEM_SLEEP );
4012 +       MapFibContext.Fib = Adapter->SyncFib;
4013 +       MapFibContext.Size = sizeof(FIB);
4014 +       MapFib( Adapter, &MapFibContext );
4015 +       Adapter->SyncFibPhysicalAddress = MapFibContext.LogicalFibAddress.LowPart;
4016 +#endif
4017 +
4018 +       Adapter->CommFuncs.SizeOfAfaCommFuncs = sizeof(AFACOMM_FUNCS);
4019 +
4020 +       Adapter->CommFuncs.AllocateFib = AllocateFib;
4021 +
4022 +       Adapter->CommFuncs.FreeFib = FreeFib;
4023 +       Adapter->CommFuncs.FreeFibFromDpc = FreeFibFromDpc;
4024 +       Adapter->CommFuncs.DeallocateFib = DeallocateFib;
4025 +
4026 +       Adapter->CommFuncs.InitializeFib = InitializeFib;
4027 +       Adapter->CommFuncs.GetFibData = FsaGetFibData;
4028 +       Adapter->CommFuncs.SendFib = SendFib;
4029 +       Adapter->CommFuncs.CompleteFib = CompleteFib;
4030 +       Adapter->CommFuncs.CompleteAdapterFib = CompleteAdapterFib;
4031 +
4032 +       Adapter->CommFuncs.SendSynchFib = SendSynchFib;
4033 +
4034 +       Adapter->CommFuncs.FreeDmaResources = Adapter->AdapterFuncs->FreeDmaResources;
4035 +       Adapter->CommFuncs.BuildSgMap = Adapter->AdapterFuncs->BuildSgMap;
4036 +
4037 +       //
4038 +       // Add this adapter in to our Adapter List.
4039 +       //
4040 +
4041 +       Adapter->NextAdapter = FsaCommData.AdapterList;
4042 +       FsaCommData.AdapterList = Adapter;
4043 +
4044 +       NewAdapter->Adapter = Adapter;
4045 +
4046 +//     AfaDiskInitNewAdapter( Adapter->AdapterNumber, Adapter );
4047 +
4048 +       return (Adapter);
4049 +}
4050 +
4051 +AAC_STATUS
4052 +CommInitialize(
4053 +       PAFA_COMM_ADAPTER Adapter
4054 +       )
4055 +{
4056 +    //
4057 +    //  Now allocate and initialize the zone structures used as our pool
4058 +    //  of FIB context records.  The size of the zone is based on the
4059 +    //  system memory size.  We also initialize the mutex used to protect
4060 +    //  the zone.
4061 +    //
4062 +       Adapter->FibContextZoneSpinLock = OsSpinLockAlloc();
4063 +       OsSpinLockInit( Adapter->FibContextZoneSpinLock, Adapter->SpinLockCookie );
4064 +
4065 +       Adapter->FibContextZoneExtendSize = 64;
4066 +
4067 +       return (STATUS_SUCCESS);
4068 +}
4069 +
4070 +
4071 +    
4072 +/*++
4073 +
4074 +Routine Description:
4075 +
4076 +    Initializes the data structures that are required for the FSA commuication
4077 +    interface to operate.
4078 +
4079 +Arguments:
4080 +
4081 +    None - all global or allocated data.
4082 +
4083 +Return Value:
4084 +
4085 +    TRUE - if we were able to init the commuication interface.
4086 +    FALSE - If there were errors initing. This is a fatal error.
4087 +--*/
4088 +BOOLEAN
4089 +CommInit(PAFA_COMM_ADAPTER Adapter)
4090 +{
4091 +    
4092 +    ULONG SizeOfHeaders = (sizeof(QUEUE_INDEX) * NUMBER_OF_COMM_QUEUES) * 2;
4093 +    ULONG SizeOfQueues = sizeof(QUEUE_ENTRY) * TOTAL_QUEUE_ENTRIES;
4094 +    PQUEUE_INDEX Headers;
4095 +    PQUEUE_ENTRY Queues;
4096 +       ULONG TotalSize;
4097 +       PCOMM_REGION CommRegion = Adapter->CommRegion;
4098 +
4099 +        CommInitialize( Adapter );
4100 +
4101 +       FsaCommPrint("CommInit: Queue entry size is 0x%x, Queue index size is 0x%x, Number of total entries is 0x%x, # queues = 0x%x.\n",
4102 +                         sizeof(QUEUE_ENTRY), sizeof(QUEUE_INDEX), TOTAL_QUEUE_ENTRIES, NUMBER_OF_COMM_QUEUES);
4103 +       //
4104 +       //
4105 +       // Allocate the physically contigous space for the commuication queue
4106 +       // headers. 
4107 +       //
4108 +
4109 +       TotalSize = SizeOfHeaders + SizeOfQueues;
4110 +
4111 +       if (!FsaAllocateAdapterCommArea(Adapter, (PVOID *)&Headers, TotalSize, QUEUE_ALIGNMENT))
4112 +               return (FALSE);
4113 +
4114 +       Queues = (PQUEUE_ENTRY)((PUCHAR)Headers + SizeOfHeaders);
4115 +
4116 +       if (ddi_add_softintr( Adapter->Dip, DDI_SOFTINT_HIGH, &CommRegion->QueueNotFullDpc, NULL,
4117 +                                                 NULL, (PUNIX_INTR_HANDLER)CommonNotFullDpc,
4118 +                                                 (caddr_t)CommRegion ) != DDI_SUCCESS) {
4119 +
4120 +         cmn_err(CE_CONT, "Os_addr_intr failed\n");                                    
4121 +       }                                       
4122 +
4123 +
4124 +    // Adapter to Host normal priority Command queue
4125 +
4126 +
4127 +    CommRegion->HostNormCmdQue.Headers.ProducerIndex = Headers++;
4128 +    CommRegion->HostNormCmdQue.Headers.ConsumerIndex = Headers++;
4129 +    *CommRegion->HostNormCmdQue.Headers.ProducerIndex = HOST_NORM_CMD_ENTRIES;
4130 +    *CommRegion->HostNormCmdQue.Headers.ConsumerIndex = HOST_NORM_CMD_ENTRIES;
4131 +
4132 +    CommRegion->HostNormCmdQue.SavedIrql = 0;
4133 +    CommRegion->HostNormCmdQue.BaseAddress = Queues;
4134 +    CommRegion->HostNormCmdQue.QueueEntries = HOST_NORM_CMD_ENTRIES;
4135 +
4136 +       CommRegion->HostNormCmdQue.QueueLock = OsSpinLockAlloc();
4137 +       if (CommRegion->HostNormCmdQue.QueueLock == NULL) {
4138 +               return (FALSE);
4139 +       }
4140 +    InitializeNTQueue(Adapter, &CommRegion->HostNormCmdQue, HostNormCmdQueue);
4141 +
4142 +    
4143 +    Queues += HOST_NORM_CMD_ENTRIES;
4144 +
4145 +    // Adapter to Host high priority command queue
4146 +    
4147 +    CommRegion->HostHighCmdQue.Headers.ProducerIndex = Headers++;
4148 +    CommRegion->HostHighCmdQue.Headers.ConsumerIndex = Headers++;
4149 +    *CommRegion->HostHighCmdQue.Headers.ProducerIndex = HOST_HIGH_CMD_ENTRIES;
4150 +    *CommRegion->HostHighCmdQue.Headers.ConsumerIndex = HOST_HIGH_CMD_ENTRIES;
4151 +
4152 +    CommRegion->HostHighCmdQue.SavedIrql = 0;
4153 +    CommRegion->HostHighCmdQue.BaseAddress = Queues;
4154 +    CommRegion->HostHighCmdQue.QueueEntries = HOST_HIGH_CMD_ENTRIES;
4155 +//     CommRegion->HostHighCmdQue.QueueLock = (PKSPIN_LOCK) ExAllocatePool(NonPagedPool, sizeof(KSPIN_LOCK));
4156 +       CommRegion->HostHighCmdQue.QueueLock = OsSpinLockAlloc();
4157 +       if (CommRegion->HostHighCmdQue.QueueLock == NULL) {
4158 +               return (FALSE);
4159 +       }
4160 +    InitializeNTQueue(Adapter, &CommRegion->HostHighCmdQue, HostHighCmdQueue);
4161 +    
4162 +    Queues += HOST_HIGH_CMD_ENTRIES;
4163 +
4164 +    // Host to adapter normal priority command queue
4165 +    
4166 +    CommRegion->AdapNormCmdQue.Headers.ProducerIndex = Headers++;
4167 +    CommRegion->AdapNormCmdQue.Headers.ConsumerIndex = Headers++;
4168 +    *CommRegion->AdapNormCmdQue.Headers.ProducerIndex = ADAP_NORM_CMD_ENTRIES;
4169 +    *CommRegion->AdapNormCmdQue.Headers.ConsumerIndex = ADAP_NORM_CMD_ENTRIES;
4170 +
4171 +    CommRegion->AdapNormCmdQue.SavedIrql = 0;    
4172 +    CommRegion->AdapNormCmdQue.BaseAddress = Queues;
4173 +    CommRegion->AdapNormCmdQue.QueueEntries = ADAP_NORM_CMD_ENTRIES;
4174 +    InitializeNTQueue(Adapter, &CommRegion->AdapNormCmdQue, AdapNormCmdQueue);
4175 +    
4176 +    Queues += ADAP_NORM_CMD_ENTRIES;
4177 +
4178 +    // host to adapter high priority command queue
4179 +    
4180 +    CommRegion->AdapHighCmdQue.Headers.ProducerIndex = Headers++;
4181 +    CommRegion->AdapHighCmdQue.Headers.ConsumerIndex = Headers++;
4182 +    *CommRegion->AdapHighCmdQue.Headers.ProducerIndex = ADAP_HIGH_CMD_ENTRIES;
4183 +    *CommRegion->AdapHighCmdQue.Headers.ConsumerIndex = ADAP_HIGH_CMD_ENTRIES;
4184 +
4185 +    CommRegion->AdapHighCmdQue.SavedIrql = 0;    
4186 +    CommRegion->AdapHighCmdQue.BaseAddress = Queues;
4187 +    CommRegion->AdapHighCmdQue.QueueEntries = ADAP_HIGH_CMD_ENTRIES;
4188 +    InitializeNTQueue(Adapter, &CommRegion->AdapHighCmdQue, AdapHighCmdQueue);
4189 +    
4190 +    Queues += ADAP_HIGH_CMD_ENTRIES;
4191 +
4192 +    // adapter to host normal priority response queue
4193 +    
4194 +    CommRegion->HostNormRespQue.Headers.ProducerIndex = Headers++;
4195 +    CommRegion->HostNormRespQue.Headers.ConsumerIndex = Headers++;
4196 +    *CommRegion->HostNormRespQue.Headers.ProducerIndex = HOST_NORM_RESP_ENTRIES;
4197 +    *CommRegion->HostNormRespQue.Headers.ConsumerIndex = HOST_NORM_RESP_ENTRIES;
4198 +
4199 +    CommRegion->HostNormRespQue.SavedIrql = 0;    
4200 +    CommRegion->HostNormRespQue.BaseAddress = Queues;
4201 +    CommRegion->HostNormRespQue.QueueEntries = HOST_NORM_RESP_ENTRIES;
4202 +//     CommRegion->HostNormRespQue.QueueLock = (PKSPIN_LOCK) ExAllocatePool(NonPagedPool, sizeof(KSPIN_LOCK));
4203 +       CommRegion->HostNormRespQue.QueueLock = OsSpinLockAlloc();
4204 +       if (CommRegion->HostNormRespQue.QueueLock == NULL) {
4205 +               return (FALSE);
4206 +       }
4207 +    InitializeNTQueue(Adapter, &CommRegion->HostNormRespQue, HostNormRespQueue);
4208 +    
4209 +    Queues += HOST_NORM_RESP_ENTRIES;
4210 +
4211 +    // adapter to host high priority response queue
4212 +    
4213 +    CommRegion->HostHighRespQue.Headers.ProducerIndex = Headers++;
4214 +    CommRegion->HostHighRespQue.Headers.ConsumerIndex = Headers++;
4215 +    *CommRegion->HostHighRespQue.Headers.ProducerIndex = HOST_HIGH_RESP_ENTRIES;
4216 +    *CommRegion->HostHighRespQue.Headers.ConsumerIndex = HOST_HIGH_RESP_ENTRIES;
4217 +
4218 +    CommRegion->HostHighRespQue.SavedIrql = 0;    
4219 +    CommRegion->HostHighRespQue.BaseAddress = Queues;
4220 +    CommRegion->HostHighRespQue.QueueEntries = HOST_HIGH_RESP_ENTRIES;
4221 +//     CommRegion->HostHighRespQue.QueueLock = (PKSPIN_LOCK) ExAllocatePool(NonPagedPool, sizeof(KSPIN_LOCK));
4222 +       CommRegion->HostHighRespQue.QueueLock = OsSpinLockAlloc();
4223 +       if (CommRegion->HostHighRespQue.QueueLock == NULL) {
4224 +               return (FALSE);
4225 +       }
4226 +    InitializeNTQueue(Adapter, &CommRegion->HostHighRespQue, HostHighRespQueue);
4227 +    
4228 +    Queues += HOST_HIGH_RESP_ENTRIES;
4229 +
4230 +    // host to adapter normal priority response queue
4231 +    
4232 +    CommRegion->AdapNormRespQue.Headers.ProducerIndex = Headers++;
4233 +    CommRegion->AdapNormRespQue.Headers.ConsumerIndex = Headers++;
4234 +    *CommRegion->AdapNormRespQue.Headers.ProducerIndex = ADAP_NORM_RESP_ENTRIES;
4235 +    *CommRegion->AdapNormRespQue.Headers.ConsumerIndex = ADAP_NORM_RESP_ENTRIES;
4236 +
4237 +    CommRegion->AdapNormRespQue.SavedIrql = 0;    
4238 +    CommRegion->AdapNormRespQue.BaseAddress = Queues;
4239 +    CommRegion->AdapNormRespQue.QueueEntries = ADAP_NORM_RESP_ENTRIES;
4240 +    InitializeNTQueue(Adapter, &CommRegion->AdapNormRespQue, AdapNormRespQueue);
4241 +    
4242 +    Queues += ADAP_NORM_RESP_ENTRIES;
4243 +
4244 +    // host to adapter high priority response queue
4245 +    
4246 +    CommRegion->AdapHighRespQue.Headers.ProducerIndex = Headers++;
4247 +    CommRegion->AdapHighRespQue.Headers.ConsumerIndex = Headers++;
4248 +    *CommRegion->AdapHighRespQue.Headers.ProducerIndex = ADAP_HIGH_RESP_ENTRIES;
4249 +    *CommRegion->AdapHighRespQue.Headers.ConsumerIndex = ADAP_HIGH_RESP_ENTRIES;
4250 +
4251 +    CommRegion->AdapHighRespQue.SavedIrql = 0;    
4252 +    CommRegion->AdapHighRespQue.BaseAddress = Queues;
4253 +    CommRegion->AdapHighRespQue.QueueEntries = ADAP_HIGH_RESP_ENTRIES;
4254 +    InitializeNTQueue(Adapter, &CommRegion->AdapHighRespQue, AdapHighRespQueue);
4255 +
4256 +       CommRegion->AdapNormCmdQue.QueueLock = CommRegion->HostNormRespQue.QueueLock;
4257 +       CommRegion->AdapHighCmdQue.QueueLock = CommRegion->HostHighRespQue.QueueLock;
4258 +       CommRegion->AdapNormRespQue.QueueLock = CommRegion->HostNormCmdQue.QueueLock;
4259 +       CommRegion->AdapHighRespQue.QueueLock = CommRegion->HostHighCmdQue.QueueLock;
4260 +
4261 +    return(TRUE);
4262 +}
4263 +
4264 +AAC_STATUS
4265 +AfaCommShutdown(
4266 +       PAFA_COMM_ADAPTER Adapter
4267 +       )
4268 +/*++
4269 +
4270 +Routine Description:
4271 +
4272 +       This routine will send a shutdown request to each adapter.
4273 +
4274 +Arguments:
4275 +
4276 +       Adapter - which adapter to send the shutdown to.
4277 +
4278 +Return Value:
4279 +
4280 +    NT Status success.
4281 +
4282 +--*/
4283 +
4284 +{
4285 +       PFIB_CONTEXT FibContext;
4286 +       PCLOSECOMMAND CloseCommand;
4287 +       AAC_STATUS Status;
4288 +
4289 +       FibContext = AllocateFib( Adapter );
4290 +
4291 +       InitializeFib( FibContext );
4292 +
4293 +       CloseCommand = (PCLOSECOMMAND) FsaGetFibData( FibContext );
4294 +
4295 +       CloseCommand->Command = VM_CloseAll;
4296 +       CloseCommand->ContainerId = 0xffffffff;
4297 +
4298 +       Status = SendFib( ContainerCommand, FibContext, sizeof(CLOSECOMMAND), FsaNormal, TRUE, NULL, TRUE, NULL, NULL );
4299 +
4300 +       if (Status != STATUS_SUCCESS) {
4301 +
4302 +               FreeFib( FibContext );
4303 +
4304 +               goto ret;
4305 +
4306 +       }
4307 +
4308 +       CompleteFib( FibContext );
4309 +
4310 +       FreeFib( FibContext );
4311 +
4312 +
4313 +       Status = STATUS_SUCCESS;
4314 +
4315 +ret:
4316 +
4317 +       return (Status);
4318 +
4319 +}
4320 +
4321 +VOID
4322 +AfaCommBugcheckHandler(
4323 +               IN PVOID Buffer,
4324 +               IN ULONG Length
4325 +               )
4326 +/*++
4327 +
4328 +Routine Description:
4329 +
4330 +       This routine will shutdown the adapter if there is a bugcheck and
4331 +       copy the shutdown data from the adapter response into the buffer
4332 +       so it will show up in the host dump file.
4333 +p
4334 +Arguments:
4335 +
4336 +       Buffer - This buffer will be written to the host dump by nt for us.
4337 +
4338 +       Length - The size of the buffer.
4339 +
4340 +Return Value:
4341 +
4342 +       N/A
4343 +
4344 +--*/
4345 +{
4346 +       PAFA_COMM_ADAPTER Adapter = FsaCommData.AdapterList;
4347 +
4348 +       while (Adapter) {
4349 +
4350 +               NotifyAdapter(Adapter, HostShutdown);
4351 +
4352 +               Adapter = Adapter->NextAdapter;
4353 +
4354 +       }
4355 +
4356 +}      
4357 +
4358 +VOID
4359 +FsaCommLogEvent(
4360 +       PFIB_CONTEXT FibContext, 
4361 +       PDEVICE_OBJECT DeviceObject,
4362 +       AAC_STATUS FsaStatus,
4363 +       AAC_STATUS AacStatus,
4364 +       ULONG LocationCode,
4365 +       USHORT Category,
4366 +       PUCHAR String,
4367 +       BOOLEAN DumpFib
4368 +)
4369 +{
4370 +}
4371 +
4372 +AfaCommProbeDisks(
4373 +       PAFA_COMM_ADAPTER       Adapter
4374 +       )
4375 +{
4376 +    PMNTINFO DiskInfo;
4377 +    PMNTINFORESPONSE DiskInfoResponse;
4378 +       AAC_STATUS Status;
4379 +       PCOMM_FIB_CONTEXT FibContext;
4380 +    
4381 +       FibContext = AllocateFib( Adapter );
4382 +
4383 +       InitializeFib( FibContext );
4384 +
4385 +       DiskInfo = (PMNTINFO) FibContext->Fib->data;
4386 +       DiskInfo->Command = VM_NameServe;
4387 +       DiskInfo->MntCount = 0;
4388 +       DiskInfo->MntType = FT_FILESYS;
4389 +
4390 +    Status = SendFib(ContainerCommand,
4391 +                            FibContext,
4392 +                        sizeof(MNTINFO),
4393 +                        FsaNormal,
4394 +                        TRUE,
4395 +                        NULL,
4396 +                        TRUE,
4397 +                        NULL,
4398 +                        NULL);
4399 +
4400 +       DiskInfoResponse = (PMNTINFORESPONSE) FibContext->Fib->data;
4401 +
4402 +       if (DiskInfoResponse->MntRespCount) {
4403 +
4404 +               cmn_err(CE_CONT, "container found on adapter, size = 0x%x blocks\n", 
4405 +                               DiskInfoResponse->MntTable[0].Capacity);
4406 +                               
4407 +       } else {
4408 +       
4409 +               cmn_err(CE_CONT, "no containers found on adapter\n");
4410 +               
4411 +       }
4412 +                                       
4413 +       CompleteFib( FibContext );
4414 +       
4415 +       FreeFib( FibContext );                           
4416 +}
4417 +
4418 +
4419 diff -burN linux-2.4.4/drivers/scsi/aacraid/commsup.c linux/drivers/scsi/aacraid/commsup.c
4420 --- linux-2.4.4/drivers/scsi/aacraid/commsup.c  Wed Dec 31 18:00:00 1969
4421 +++ linux/drivers/scsi/aacraid/commsup.c        Mon Apr 30 09:43:34 2001
4422 @@ -0,0 +1,2180 @@
4423 +/*++
4424 + * Adaptec aacraid device driver for Linux.
4425 + *
4426 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
4427 + *
4428 + * This program is free software; you can redistribute it and/or modify
4429 + * it under the terms of the GNU General Public License as published by
4430 + * the Free Software Foundation; either version 2, or (at your option)
4431 + * any later version.
4432 + *
4433 + * This program is distributed in the hope that it will be useful,
4434 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
4435 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
4436 + * GNU General Public License for more details.
4437 + *
4438 + * You should have received a copy of the GNU General Public License
4439 + * along with this program; see the file COPYING.  If not, write to
4440 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
4441 + *
4442 + * Module Name:
4443 + *  commsup.c
4444 + *
4445 + * Abstract: Contain all routines that are required for FSA host/adapter
4446 + *    commuication.
4447 + *
4448 + *
4449 + --*/
4450 +
4451 +static char *ident_commsup = "aacraid_ident commsup.c 1.0.7 2000/10/11 Adaptec, Inc.";
4452 +
4453 +#include "comprocs.h"
4454 +
4455 +#define BugCheckFileId                   (FSAFS_BUG_CHECK_COMMSUP)
4456 +
4457 +int CommPrinting;
4458 +
4459 +void
4460 +ThrottleExceptionHandler(
4461 +       IN PCOMM_REGION CommRegion,
4462 +       AAC_STATUS              Status
4463 +       );
4464 +
4465 +void ThrottlePeriodEndDpcRtn(
4466 +    IN PKDPC Dpc,
4467 +    IN PVOID DeferredContext,
4468 +    IN PVOID SystemArgument1,
4469 +    IN PVOID SystemArgument2
4470 +    );
4471 +
4472 +
4473 +/*++
4474 +
4475 +Routine Description:
4476 +
4477 +       This routine will free all resources used by a given FibContextSegment.
4478 +
4479 +Arguments:
4480 +
4481 +       Adapter - The adapter that this COMM_FIB_CONTEXT will communicate with.
4482 +       ZoneSegment - The segment to release resources from.
4483 +
4484 +Return Value:
4485 +
4486 +       TRUE - All resources were properly freed.
4487 +       FALSE - An Error occured while freeing resources.
4488 +
4489 +--*/
4490 +BOOLEAN
4491 +FsaFreeFibContextSegment (PAFA_COMM_ADAPTER Adapter,
4492 +                                                 PFIB_CONTEXT_ZONE_SEGMENT     ZoneSegment)
4493 +{
4494 +       PCOMM_FIB_CONTEXT FibContext;
4495 +       int i;
4496 +       
4497 +       // Account for the ZONE_SEGMENT_HEADER before the first actual FibContext.
4498 +
4499 +       for (i = 0, FibContext = (PCOMM_FIB_CONTEXT)((PUCHAR)ZoneSegment->FibContextSegment + sizeof(ZONE_SEGMENT_HEADER));
4500 +                i < ZoneSegment->ExtendSize; i++, FibContext++) {
4501 +
4502 +               OsCvLockDestroy( FibContext->FsaEventMutex );
4503 +               OsCv_destroy( &FibContext->FsaEvent );
4504 +
4505 +       }
4506 +
4507 +       UnmapAndFreeFibSpace( Adapter, &ZoneSegment->MapFibContext );
4508 +
4509 +       OsFreeMemory( ZoneSegment->FibContextSegment, ZoneSegment->FibContextSegmentSize );
4510 +
4511 +       OsFreeMemory( ZoneSegment, sizeof( FIB_CONTEXT_ZONE_SEGMENT ) );
4512 +
4513 +       return (TRUE);
4514 +}
4515 +
4516 +BOOLEAN
4517 +FsaFreeFibContextZone(
4518 +       PAFA_COMM_ADAPTER Adapter
4519 +       )
4520 +/*++
4521 +
4522 +Routine Description:
4523 +
4524 +       This routine will walk through the FibContextSegmentList and free up all
4525 +       resources used by the FibContextZone.
4526 +
4527 +Arguments:
4528 +
4529 +       Adapter - The adapter that this COMM_FIB_CONTEXT will communicate with.
4530 +
4531 +Return Value:
4532 +
4533 +       TRUE - All resources were properly freed.
4534 +       FALSE - An Error occured while freeing resources.
4535 +
4536 +--*/
4537 +
4538 +{
4539 +       PFIB_CONTEXT_ZONE_SEGMENT ZoneSegment, NextZoneSegment;
4540 +
4541 +       ZoneSegment = Adapter->FibContextSegmentList;
4542 +
4543 +       while (ZoneSegment) {
4544 +
4545 +               NextZoneSegment = ZoneSegment->Next;
4546 +
4547 +               FsaFreeFibContextSegment( Adapter, ZoneSegment );
4548 +
4549 +               ZoneSegment = NextZoneSegment;
4550 +       }
4551 +
4552 +       return (TRUE);
4553 +}
4554 +
4555 +       
4556 +
4557 +BOOLEAN
4558 +FsaExtendFibContextZone (IN PAFA_COMM_ADAPTER Adapter)
4559 +{
4560 +    int ExtendSize;
4561 +    KIRQL SavedIrql;
4562 +       ULONG ZoneSegmentAllocSize, FibAllocSize;
4563 +       PVOID FibContextSegment;
4564 +       PCOMM_FIB_CONTEXT FibContext;
4565 +       PFIB Fib;
4566 +       PVOID FibPhysicalAddress;
4567 +       int i;
4568 +       PFIB_CONTEXT_ZONE_SEGMENT ZoneSegment;
4569 +       
4570 +       //
4571 +       // Allocate space to describe this zone segment.
4572 +       //
4573 +
4574 +       cmn_err (CE_DEBUG, "Entered FsaExtendFibConextZone");
4575 +       ZoneSegment = OsAllocMemory( sizeof( FIB_CONTEXT_ZONE_SEGMENT ), OS_ALLOC_MEM_SLEEP );
4576 +
4577 +       ExtendSize = Adapter->FibContextZoneExtendSize;
4578 +       ZoneSegmentAllocSize = (ExtendSize * sizeof(COMM_FIB_CONTEXT)) + sizeof(ZONE_SEGMENT_HEADER);
4579 +
4580 +       FibContextSegment = OsAllocMemory( ZoneSegmentAllocSize, OS_ALLOC_MEM_SLEEP );
4581 +
4582 +       if (FibContextSegment == NULL) {
4583 +               return (FALSE);
4584 +       }       
4585 +
4586 +       RtlZeroMemory( FibContextSegment, ZoneSegmentAllocSize );
4587 +
4588 +       ZoneSegment->FibContextSegment = FibContextSegment;
4589 +       ZoneSegment->FibContextSegmentSize = ZoneSegmentAllocSize;
4590 +       ZoneSegment->ExtendSize = ExtendSize;
4591 +
4592 +       FibAllocSize = ExtendSize * sizeof(FIB);
4593 +
4594 +
4595 +       ZoneSegment->MapFibContext.Size = FibAllocSize;
4596 +
4597 +       AllocateAndMapFibSpace( Adapter, &ZoneSegment->MapFibContext );
4598 +
4599 +       Fib = ZoneSegment->MapFibContext.FibVirtualAddress;
4600 +       FibPhysicalAddress = ZoneSegment->MapFibContext.FibPhysicalAddress;
4601 +
4602 +       RtlZeroMemory( Fib, FibAllocSize );
4603 +
4604 +       // Account for the ZONE_SEGMENT_HEADER before the first actual FibContext.
4605 +
4606 +       for (i = 0, FibContext = (PCOMM_FIB_CONTEXT)((PUCHAR)FibContextSegment + sizeof(ZONE_SEGMENT_HEADER));
4607 +                i < ExtendSize; i++, FibContext++) {
4608 +
4609 +               FibContext->Adapter = Adapter;
4610 +
4611 +               FibContext->Fib = Fib;
4612 +               FibContext->FibData = (PVOID) FibContext->Fib->data;
4613 +
4614 +               OsCv_init( &FibContext->FsaEvent);
4615 +               FibContext->FsaEventMutex = OsCvLockAlloc();
4616 +               OsCvLockInit( FibContext->FsaEventMutex, Adapter->SpinLockCookie );
4617 +
4618 +               Fib->Header.XferState = 0xffffffff;
4619 +               Fib->Header.SenderSize = sizeof(FIB);
4620 +
4621 +               FibContext->LogicalFibAddress.LowPart = (ULONG) FibPhysicalAddress;
4622 +
4623 +               Fib = (PFIB)((PUCHAR)Fib + sizeof(FIB));
4624 +               FibPhysicalAddress = (PVOID)((PUCHAR)FibPhysicalAddress + sizeof(FIB));
4625 +       }
4626 +
4627 +       //
4628 +       // If FibContextZone.TotalSegmentSize is non-zero, then a zone has already been
4629 +       // initialized, we just need to extend it.
4630 +       //
4631 +
4632 +       if (Adapter->FibContextZone.TotalSegmentSize) {
4633 +
4634 +               OsSpinLockAcquire( Adapter->FibContextZoneSpinLock );
4635 +
4636 +               ExExtendZone( &Adapter->FibContextZone,
4637 +                                         FibContextSegment,
4638 +                                         ZoneSegmentAllocSize );
4639 +
4640 +               OsSpinLockRelease( Adapter->FibContextZoneSpinLock );
4641 +
4642 +       } else {
4643 +
4644 +           if (ExInitializeZone( &Adapter->FibContextZone,
4645 +                                                         sizeof(COMM_FIB_CONTEXT),
4646 +                             FibContextSegment,
4647 +                                 ZoneSegmentAllocSize ) != STATUS_SUCCESS)
4648 +                       FsaBugCheck(0,0,0);
4649 +
4650 +       }
4651 +
4652 +       //
4653 +       // Add this segment to the adapter's list of segments
4654 +       //
4655 +
4656 +       ZoneSegment->Next = Adapter->FibContextSegmentList;
4657 +       Adapter->FibContextSegmentList = ZoneSegment;
4658 +
4659 +       return (TRUE);
4660 +}
4661 +
4662 +
4663 +
4664 +/*++
4665 +
4666 +Routine Description:
4667 +
4668 +    This routine creates a new COMM_FIB_CONTEXT record
4669 +
4670 +Arguments:
4671 +
4672 +       Adapter - The adapter that this COMM_FIB_CONTEXT will communicate with.
4673 +
4674 +Return Value:
4675 +
4676 +    PCOMM_FIB_CONTEXT - returns a pointer to the newly allocate COMM_FIB_CONTEXT Record
4677 +
4678 +--*/
4679 +PFIB_CONTEXT
4680 +AllocateFib (IN PVOID AdapterArg)
4681 +{
4682 +       PAFA_COMM_ADAPTER Adapter = (PAFA_COMM_ADAPTER) AdapterArg;
4683 +    KIRQL SavedIrql;
4684 +    PCOMM_FIB_CONTEXT FibContext;
4685 +       int FullZoneLoopCounter = 0;
4686 +        
4687 +
4688 +        //
4689 +       // Acquire the zone spin lock, and check to see if the zone is full.
4690 +       // If it is, then release the spin lock and allocate more fibs for the 
4691 +       // zone.  The ExtendFibZone routine will re-acquire the spin lock to add
4692 +       // the new fibs onto the zone.
4693 +        //
4694 +
4695 +    OsSpinLockAcquire( Adapter->FibContextZoneSpinLock );
4696 +
4697 +    while (ExIsFullZone( &Adapter->FibContextZone )) {
4698 +
4699 +               if (++FullZoneLoopCounter >  10)
4700 +                       FsaBugCheck(0,0,0);
4701 +
4702 +               OsSpinLockRelease( Adapter->FibContextZoneSpinLock );
4703 +
4704 +                // bmb debug
4705 +                cmn_err (CE_DEBUG, "Extending FibContextZone");
4706 +               if (FsaExtendFibContextZone(Adapter) == FALSE) {
4707 +                       return (NULL);
4708 +               }
4709 +
4710 +                OsSpinLockAcquire( Adapter->FibContextZoneSpinLock );
4711 +
4712 +       }
4713 +
4714 +    //
4715 +       //  At this point we now know that the zone has at least one more
4716 +    //  IRP context record available.  So allocate from the zone and
4717 +    //  then release the mutex.
4718 +    //
4719 +
4720 +    FibContext = (PCOMM_FIB_CONTEXT) ExAllocateFromZone( &Adapter->FibContextZone );
4721 +
4722 +       OsSpinLockRelease( Adapter->FibContextZoneSpinLock );
4723 +
4724 +    //
4725 +    //  Set the proper node type code and node byte size
4726 +    //
4727 +
4728 +    FibContext->NodeTypeCode = FSAFS_NTC_FIB_CONTEXT;
4729 +    FibContext->NodeByteSize = sizeof( COMM_FIB_CONTEXT );
4730 +
4731 +       // 
4732 +       // Null out fields that depend on being zero at the start of each I/O
4733 +       //
4734 +
4735 +       FibContext->Fib->Header.XferState = 0;
4736 +       FibContext->FibCallback = NULL;
4737 +       FibContext->FibCallbackContext = NULL;
4738 +
4739 +
4740 +    //
4741 +    //  return and tell the caller
4742 +    //
4743 +
4744 +    return ((PFIB_CONTEXT) FibContext);
4745 +}
4746 +
4747 +
4748 +/*++
4749 +
4750 +Routine Description:
4751 +
4752 +    This routine deallocates and removes the specified COMM_FIB_CONTEXT record
4753 +    from the Fsafs in memory data structures.  It should only be called
4754 +    by FsaCompleteRequest.
4755 +
4756 +Arguments:
4757 +
4758 +       FibContext - Supplies the COMM_FIB_CONTEXT to remove
4759 +
4760 +Return Value:
4761 +
4762 +    None
4763 +
4764 +--*/
4765 +VOID
4766 +FreeFib (IN PFIB_CONTEXT Context)
4767 +{
4768 +    KIRQL SavedIrql;
4769 +       PCOMM_FIB_CONTEXT FibContext = Context;
4770 +
4771 +    ASSERT(FibContext->NodeTypeCode == FSAFS_NTC_FIB_CONTEXT);
4772 +
4773 +    OsSpinLockAcquire( FibContext->Adapter->FibContextZoneSpinLock );
4774 +
4775 +       if (FibContext->Flags & FIB_CONTEXT_FLAG_TIMED_OUT) {
4776 +
4777 +               FsaCommData.TimedOutFibs++;
4778 +
4779 +               FibContext->Next = FibContext->Adapter->FibContextTimedOutList;
4780 +               FibContext->Adapter->FibContextTimedOutList = FibContext;
4781 +
4782 +       } else {
4783 +
4784 +           ASSERT(FibContext->Fib->Header.XferState == 0);
4785 +
4786 +               if (FibContext->Fib->Header.XferState != 0) {
4787 +                               cmn_err(CE_WARN, "FreeFib, XferState != 0, FibContext = 0x%x, XferState = 0x%x\n", 
4788 +                                        FibContext, FibContext->Fib->Header.XferState);
4789 +               }
4790 +
4791 +           ExFreeToZone( &FibContext->Adapter->FibContextZone, FibContext );
4792 +
4793 +       }       
4794 +
4795 +       OsSpinLockRelease( FibContext->Adapter->FibContextZoneSpinLock );
4796 +
4797 +    //
4798 +    //  return and tell the caller
4799 +    //
4800 +
4801 +    return;
4802 +}
4803 +
4804 +
4805 +/*++
4806 +
4807 +Routine Description:
4808 +
4809 +    This routine deallocates and removes the specified COMM_FIB_CONTEXT record
4810 +    from the Fsafs in memory data structures.  It should only be called
4811 +    from the dpc routines to from dpc to free an FibContext from an async or
4812 +       no response io
4813 +
4814 +Arguments:
4815 +
4816 +    FibContext - Supplies the COMM_FIB_CONTEXT to remove
4817 +
4818 +Return Value:
4819 +
4820 +    None
4821 +
4822 +--*/
4823 +VOID
4824 +FreeFibFromDpc (IN PFIB_CONTEXT Context)
4825 +{
4826 +    PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
4827 +
4828 +    ASSERT(FibContext->NodeTypeCode == FSAFS_NTC_FIB_CONTEXT);
4829 +
4830 +    OsSpinLockAcquire(FibContext->Adapter->FibContextZoneSpinLock);
4831 +
4832 +       if (FibContext->Flags & FIB_CONTEXT_FLAG_TIMED_OUT) {
4833 +
4834 +               FsaCommData.TimedOutFibs++;
4835 +
4836 +               FibContext->Next = FibContext->Adapter->FibContextTimedOutList;
4837 +               FibContext->Adapter->FibContextTimedOutList = FibContext;
4838 +
4839 +       } else {
4840 +
4841 +           ASSERT(FibContext->Fib->Header.XferState == 0);
4842 +
4843 +               if (FibContext->Fib->Header.XferState != 0) {
4844 +                               cmn_err(CE_WARN, "FreeFibFromDpc, XferState != 0, FibContext = 0x%x, XferState = 0x%x\n", 
4845 +                                        FibContext, FibContext->Fib->Header.XferState);
4846 +               }
4847 +
4848 +
4849 +           ExFreeToZone( &FibContext->Adapter->FibContextZone, FibContext );
4850 +
4851 +       }
4852 +               
4853 +       OsSpinLockRelease(FibContext->Adapter->FibContextZoneSpinLock);
4854 +
4855 +    //
4856 +    //  return and tell the caller
4857 +    //
4858 +
4859 +    return;
4860 +}
4861 +
4862 +
4863 +/*++
4864 +
4865 +Routine Description:
4866 +
4867 +    Will initialize a FIB of the requested size.
4868 +    
4869 +Arguments:
4870 +
4871 +    Fib is a pointer to a location which will receive the address of the allocated
4872 +        FIB.
4873 +
4874 +    Size is the size of the Fib to allocate.
4875 +
4876 +Return Value:
4877 +
4878 +    NT_SUCCESS if a Fib was returned to the caller.
4879 +    NT_ERROR if event was an invalid event. 
4880 +
4881 +--*/
4882 +AAC_STATUS
4883 +InitializeFib (IN PFIB_CONTEXT Context)
4884 +{
4885 +    PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
4886 +       PFIB Fib = FibContext->Fib;
4887 +
4888 +    Fib->Header.StructType = TFib;
4889 +    Fib->Header.Size = sizeof(FIB);
4890 +//    if (Fib->Header.XferState & AllocatedFromPool)
4891 +//        Fib->Header.XferState = HostOwned | FibInitialized | FibEmpty | AllocatedFromPool;
4892 +//    else
4893 +        Fib->Header.XferState = HostOwned | FibInitialized | FibEmpty | FastResponseCapable;
4894 +    Fib->Header.SenderFibAddress = 0;
4895 +    Fib->Header.ReceiverFibAddress = 0;
4896 +    Fib->Header.SenderSize = sizeof(FIB);
4897 +
4898 +    return(STATUS_SUCCESS);
4899 +}
4900 +    
4901 +
4902 +/*++
4903 +
4904 +Routine Description:
4905 +
4906 +    Will allocate and initialize a FIB of the requested size and return a
4907 +    pointer to the structure. The size allocated may be larger than the size
4908 +    requested due to allocation performace optimizations.
4909 +    
4910 +Arguments:
4911 +
4912 +    Fib is a pointer to a location which will receive the address of the allocated
4913 +        FIB.
4914 +
4915 +    Size is the size of the Fib to allocate.
4916 +
4917 +    JustInitialize is a boolean which indicates a Fib has been allocated most likly in an
4918 +        imbedded structure the FS always allocates. So just initiaize it and return.
4919 +    
4920 +Return Value:
4921 +
4922 +    NT_SUCCESS if a Fib was returned to the caller.
4923 +    NT_ERROR if event was an invalid event. 
4924 +
4925 +--*/
4926 +AAC_STATUS
4927 +AllocatePoolFib (OUT PFIB *Fib, IN USHORT Size)
4928 +{}
4929 +    
4930 +
4931 +/*++
4932 +
4933 +Routine Description:
4934 +
4935 +    Will deallocate and return to the free pool the FIB pointed to by the
4936 +    caller. Upon return accessing locations pointed to by the FIB parameter
4937 +    could cause system access faults.
4938 +
4939 +Arguments:
4940 +
4941 +    Fib is a pointer to the FIB that caller wishes to deallocate.
4942 +    
4943 +Return Value:
4944 +
4945 +    NT_SUCCESS if a Fib was returned to the caller.
4946 +    NT_ERROR if event was an invalid event. 
4947 +
4948 +--*/
4949 +AAC_STATUS
4950 +DeallocateFib (PFIB_CONTEXT Context)
4951 +{
4952 +    PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
4953 +       PFIB Fib = FibContext->Fib;
4954 +
4955 +    if ( Fib->Header.StructType != TFib ) {
4956 +        FsaCommPrint("Error CompleteFib called with a non Fib structure.\n");
4957 +        return(STATUS_UNSUCCESSFUL);
4958 +    }
4959 +
4960 +
4961 +    Fib->Header.XferState = 0;        
4962 +        
4963 +    return(STATUS_SUCCESS);
4964 +
4965 +}
4966 +
4967 +
4968 +AAC_STATUS
4969 +GetResponse(
4970 +    IN PCOMM_QUE ResponseQueue,
4971 +    OUT PFIB Fib
4972 +    )
4973 +/*++
4974 +
4975 +Routine Description:
4976 +
4977 +    Gets a QE off the requested response queue and gets the response FIB into
4978 +    host memory. The FIB may already be in host memory depending on the bus
4979 +    interface, or may require the host to DMA it over from the adapter. The routine
4980 +    will return the FIB to the caller.
4981 +
4982 +Arguments:
4983 +
4984 +    ResponseQueue - Is the queue the caller wishes to have the response gotten from.
4985 +    Fib - Is the Fib which was the response from the adapter
4986 +
4987 +Return Value:
4988 +
4989 +    NT_SUCCESS if a Fib was returned to the caller.
4990 +    NT_ERROR if there was no Fib to return to the caller.
4991 +    bkpfix - add in all the other possible errors ect
4992 +
4993 +--*/
4994 +{
4995 +return(STATUS_UNSUCCESSFUL);
4996 +}
4997 +
4998 +//
4999 +// Commuication primitives define and support the queuing method we use to
5000 +// support host to adapter commuication. All queue accesses happen through
5001 +// these routines and are the only routines which have a knowledge of the
5002 +// how these queues are implemented.
5003 +//
5004 +
5005 +
5006 +/*++
5007 +
5008 +Routine Description:
5009 +
5010 +    With a priority the routine returns a queue entry if the queue has free entries. If the queue
5011 +    is full(no free entries) than no entry is returned and the function returns FALSE otherwise TRUE is
5012 +    returned.
5013 +
5014 +Arguments:
5015 +
5016 +    Priority is an enumerated type which determines which priority level
5017 +        command queue the QE is going to be queued on.
5018 +
5019 +    Entry is a pointer to the address of where to return the address of
5020 +        the queue entry from the requested command queue.
5021 +
5022 +    Index is a pointer to the address of where to store the index of the new
5023 +        queue entry returned.
5024 +
5025 +       DontInterrupt - We set this true if the queue state is such that we don't
5026 +               need to interrupt the adapter for this queue entry.
5027 +
5028 +Return Value:
5029 +
5030 +    TRUE - If a queue entry is returned
5031 +    FALSE - If there are no free queue entries on the requested command queue.
5032 +
5033 +--*/
5034 +BOOLEAN
5035 +GetEntry (IN PAFA_COMM_ADAPTER Adapter, IN QUEUE_TYPES WhichQueue,
5036 +                 OUT PQUEUE_ENTRY *Entry, OUT PQUEUE_INDEX Index,
5037 +                 OUT ULONG *DontInterrupt)
5038 +{
5039 +    ULONG QueueOffset;
5040 +       BOOLEAN status;
5041 +       PCOMM_REGION CommRegion;
5042 +
5043 +       CommRegion = Adapter->CommRegion;
5044 +
5045 +    //
5046 +    // All of the queues wrap when they reach the end, so we check to see if they
5047 +    // have reached the end and if they have we just set the index back to zero.
5048 +    // This is a wrap. You could or off the high bits in all updates but this is
5049 +    // a bit faster I think.
5050 +    //
5051 +
5052 +    if (WhichQueue == AdapHighCmdQueue) {
5053 +        *Index = *(CommRegion->AdapHighCmdQue.Headers.ProducerIndex);
5054 +
5055 +               if (*Index - 2 == *(CommRegion->AdapHighCmdQue.Headers.ConsumerIndex))
5056 +                       *DontInterrupt = TRUE; 
5057 +
5058 +        if (*Index >= ADAP_HIGH_CMD_ENTRIES)
5059 +            *Index = 0;
5060 +
5061 +        if (*Index + 1 == *(CommRegion->AdapHighCmdQue.Headers.ConsumerIndex)) { // Queue is full
5062 +                       status = FALSE;
5063 +                       cmn_err(CE_WARN, "Adapter High Command Queue full, %d outstanding",
5064 +                                       CommRegion->AdapHighCmdQue.NumOutstandingIos);
5065 +               } else {
5066 +               QueueOffset = sizeof(QUEUE_ENTRY) * (*Index);
5067 +               *Entry = QueueOffset + CommRegion->AdapHighCmdQue.BaseAddress;
5068 +
5069 +                       status = TRUE;
5070 +               }
5071 +    } else if (WhichQueue == AdapNormCmdQueue) {
5072 +
5073 +        *Index = *(CommRegion->AdapNormCmdQue.Headers.ProducerIndex);
5074 +
5075 +               if (*Index - 2 == *(CommRegion->AdapNormCmdQue.Headers.ConsumerIndex))
5076 +                       *DontInterrupt = TRUE; 
5077 +
5078 +               //
5079 +               // If we are at the end of the QUEUE then wrap back to 
5080 +               // the beginning.
5081 +        //
5082 +
5083 +        if (*Index >= ADAP_NORM_CMD_ENTRIES) 
5084 +            *Index = 0; // Wrap to front of the Producer Queue.
5085 +
5086 +               //
5087 +        // The IEEE spec says that it the producer is one behind the consumer then
5088 +        // the queue is full.
5089 +        //       
5090 +
5091 +               ASSERT(*(CommRegion->AdapNormCmdQue.Headers.ConsumerIndex) != 0);
5092 +
5093 +        if (*Index + 1 == *(CommRegion->AdapNormCmdQue.Headers.ConsumerIndex)) { // Queue is full
5094 +                       cmn_err(CE_WARN, "Adapter Norm Command Queue full, %d outstanding",
5095 +                                       CommRegion->AdapNormCmdQue.NumOutstandingIos);
5096 +                       status = FALSE;
5097 +               } else {        
5098 +               //
5099 +                       // The success case just falls through and returns the a valid queue entry.
5100 +                       //
5101 +
5102 +#ifdef commdebug
5103 +               FsaCommPrint("queue entry = %x.\n",CommRegion->AdapNormCmdQue.BaseAddress + *Index);
5104 +               FsaCommPrint("GetEntry: Index = %d, QueueOffset = %x, Entry = %x, *Entry = %x.\n",
5105 +                            *Index, QueueOffset, Entry, *Entry);
5106 +#endif
5107 +               *Entry = CommRegion->AdapNormCmdQue.BaseAddress + *Index;
5108 +
5109 +                       status = TRUE;
5110 +               }
5111 +    } else if (WhichQueue == AdapHighRespQueue) {
5112 +
5113 +        *Index = *(CommRegion->AdapHighRespQue.Headers.ProducerIndex);
5114 +
5115 +               if (*Index - 2 == *(CommRegion->AdapHighRespQue.Headers.ConsumerIndex))
5116 +                       *DontInterrupt = TRUE; 
5117 +
5118 +        if (*Index >= ADAP_HIGH_RESP_ENTRIES)
5119 +            *Index = 0;
5120 +
5121 +        if (*Index + 1 == *(CommRegion->AdapHighRespQue.Headers.ConsumerIndex)) { // Queue is full
5122 +                       status = FALSE;
5123 +                       cmn_err(CE_WARN, "Adapter High Resp Queue full, %d outstanding",
5124 +                                       CommRegion->AdapHighRespQue.NumOutstandingIos);
5125 +               } else {                                                        
5126 +               *Entry = CommRegion->AdapHighRespQue.BaseAddress + *Index;
5127 +               status = TRUE;
5128 +               } 
5129 +    } else if (WhichQueue == AdapNormRespQueue) {
5130 +
5131 +        *Index = *(CommRegion->AdapNormRespQue.Headers.ProducerIndex);
5132 +
5133 +               if (*Index - 2 == *(CommRegion->AdapNormRespQue.Headers.ConsumerIndex))
5134 +                       *DontInterrupt = TRUE; 
5135 +
5136 +               //
5137 +               // If we are at the end of the QUEUE then wrap back to 
5138 +               // the beginning.
5139 +        //
5140 +
5141 +        if (*Index >= ADAP_NORM_RESP_ENTRIES) 
5142 +            *Index = 0; // Wrap to front of the Producer Queue.
5143 +
5144 +               //
5145 +        // The IEEE spec says that it the producer is one behind the consumer then
5146 +        // the queue is full.
5147 +        //       
5148 +
5149 +        if (*Index + 1 == *(CommRegion->AdapNormRespQue.Headers.ConsumerIndex)) { // Queue is full
5150 +                       status = FALSE; 
5151 +                       cmn_err(CE_WARN, "Adapter Norm Resp Queue full, %d outstanding",
5152 +                                       CommRegion->AdapNormRespQue.NumOutstandingIos);
5153 +               } else {        
5154 +               //
5155 +                       // The success case just falls through and returns the a valid queue entry.
5156 +                       //
5157 +
5158 +               *Entry = CommRegion->AdapNormRespQue.BaseAddress + *Index;
5159 +
5160 +#ifdef commdebug
5161 +               FsaCommPrint("queue entry = %x.\n",CommRegion->AdapNormRespQue.BaseAddress + *Index);
5162 +               FsaCommPrint("GetEntry: Index = %d, Entry = %x, *Entry = %x.\n",*Index, Entry, *Entry);
5163 +#endif
5164 +                       status = TRUE;
5165 +               }     
5166 +    } else {
5167 +               cmn_err(CE_PANIC, "GetEntry: invalid queue %d", WhichQueue);
5168 +       }
5169 +
5170 +
5171 +       return (status);
5172 +}
5173 +   
5174 +
5175 +
5176 +#ifdef API_THROTTLE
5177 +
5178 +void ThrottleCheck(
5179 +       IN PAFA_COMM_ADAPTER Adapter,
5180 +       IN PFIB Fib
5181 +       )
5182 +/*++
5183 +
5184 +Routine Description:
5185 +
5186 +    This routine implements data I/O throttling. Throttling occurs when
5187 +       a CLI FIB is detected. To ensure the CLI responds quickly (the user
5188 +       is waiting for the response), this mechanism restricts the queue
5189 +       depth of data IOs at the adapter for a period of time (called the
5190 +       Throttle Period, default 5 seconds).
5191 +
5192 +    The mechanism uses a counted semaphore to place threads into a wait
5193 +       state should there be too many data I/Os outstanding.
5194 +
5195 +       At the start of a throttle period (indicated by the first CLI FIB)
5196 +       a timer is started. When the timer expires, new requests can go to
5197 +       the adapter freely. Throttled requests gradually drain to the
5198 +       adapter as each outstanding throttle I/O completes.
5199 +
5200 +    To avoid hurting regular I/O performance, we use a flag in the FIB
5201 +       header to mark FIBs involved in throttling. This means we only need
5202 +       take the extra spinlock in the response DPC routine for FIBs who
5203 +       were subject to throttling. If no throttling is occurring, the cost
5204 +       to the regular code paths is a handful of instructions.
5205 +
5206 +Arguments:
5207 +
5208 +       Adapter - Pointer to per-adapter context. This is used to locate the
5209 +                         throttle information for this adapter.
5210 +       
5211 +       Fib             - Pointer to the header for the fib being sent.
5212 +
5213 +Return Value:
5214 +
5215 +       None.
5216 +
5217 +--*/
5218 +{
5219 +       PCOMM_REGION CommRegion = Adapter->CommRegion;
5220 +       AAC_STATUS       Status;
5221 +
5222 +       //
5223 +       // This routine is called under protection of the queue spinlock.
5224 +       // As such we are allowed to check and change the counts for the
5225 +       // throttle.
5226 +       // Check the FIB. If its not a data operation, send it on without
5227 +       // throttle check. If it is a data operation, check for throttle.
5228 +       //
5229 +
5230 +       CommRegion->TotalFibs++;                                                        // Keep statistics
5231 +
5232 +       if ((Fib->Header.XferState & ApiFib) != 0) {
5233 +
5234 +               CommRegion->ApiFibs++;                                                  // Keep statistics
5235 +
5236 +               //
5237 +               // Its an API fib. If the throttle is not already active,
5238 +               // make it so. This will prevent new data Fibs being sent
5239 +               // if they exceed the throttle check.
5240 +               //
5241 +
5242 +               if (!CommRegion->ThrottleActive) {
5243 +                       BOOLEAN          InQue;
5244 +
5245 +                       CommRegion->ThrottleActive = TRUE;                      // This causes new data I/Os to be throttled
5246 +
5247 +                       //
5248 +                       // Schedule a timer for the throttle active period. When
5249 +                       // it expires, we'll be called back at routine ThrottleDpcRoutine
5250 +                       // above. This will signify the throttle active period ended
5251 +                       // and any waiting threads will be signalled to restart.
5252 +                       //
5253 +
5254 +                       FsaCommPrint("Throttle Period Start - CommRegion: %x\n", CommRegion);
5255 +                       CommRegion->ThrottleTimerSets++;
5256 +                       InQue = KeSetTimer( &CommRegion->ThrottleTimer,
5257 +                                                               CommRegion->ThrottleTimeout,
5258 +                                                               &CommRegion->ThrottleDpc);
5259 +                       ASSERT(InQue == FALSE);
5260 +               }
5261 +
5262 +               return;
5263 +       }
5264 +
5265 +       //
5266 +       // Its a non-API fib, so subject to throttle checks.
5267 +       // The following are exempt from throttling:
5268 +       //              o FIBs marked as "throttle exempt" by upper layers.
5269 +       //              o I/Os issued from a raised IRQL. We can't suspend
5270 +       //                a thread when at raised IRQL so throttling is exempt.
5271 +       //
5272 +
5273 +       if (CommRegion->AdapNormCmdQue.SavedIrql != PASSIVE_LEVEL) {
5274 +
5275 +               CommRegion->NonPassiveFibs++;
5276 +               FsaCommPrint("ThrottleCheck: Non-Passive level FIB bypasses throttle: %x\n", Fib);
5277 +               return;
5278 +
5279 +       }
5280 +
5281 +       if (CommRegion->ThrottleActive) {
5282 +
5283 +               //
5284 +               // Throttle is active.
5285 +               // Check if the FIB is a read or write. If so, and its to the
5286 +               // file system information area, let it through without throttling.
5287 +               //
5288 +
5289 +               if (Fib->Header.Command == ContainerCommand) {
5290 +                       PBLOCKREAD BlockDisk = (PBLOCKREAD) &Fib->data;
5291 +
5292 +                       //
5293 +                       // *** Note *** We are using read and write command formats
5294 +                       // interchangably here. This is ok for this purpose as the
5295 +                       // command is in the same place for both. Read and write command
5296 +                       // formats are different at higher offsets though.
5297 +                       //
5298 +
5299 +                       if ( ((BlockDisk->Command == VM_CtBlockRead) ||
5300 +                                 (BlockDisk->Command == VM_CtBlockWrite)) &&
5301 +                                 (BlockDisk->BlockNumber <= FILESYSTEM_INFO_MAX_BLKNO)) {
5302 +
5303 +                               CommRegion->FSInfoFibs++;                                                       // Keep statistics
5304 +                               return;
5305 +
5306 +                       }
5307 +
5308 +               }
5309 +
5310 +               //
5311 +               // Throttle the FIB.
5312 +               // Mark it as throttle active so that it can signal a waiter
5313 +               // when it completes.
5314 +
5315 +               CommRegion->ThrottledFibs++;
5316 +               Fib->Header.Flags |= ThrottledFib;
5317 +               
5318 +               //
5319 +               // Release the spinlock so we can wait the thread if necessary.
5320 +               // Since we specify a timeout, check the caller is at passive level.
5321 +               //
5322 +
5323 +               OsSpinLockRelease((CommRegion->AdapNormCmdQue.QueueLock), CommRegion->AdapNormCmdQue.SavedIrql);
5324 +
5325 +               FsaCommPrint("ThrottleCheck - Thread Suspension - FIB: %x\n", Fib);
5326 +
5327 +               Status = KeWaitForSingleObject(&CommRegion->ThrottleReleaseSema,
5328 +                                                                               Executive,                                                      // Don't allow user APCs to wake us
5329 +                                                                               KernelMode,                                                     // Wait in kernel mode
5330 +                                                                               FALSE,                                                          // Not alertable
5331 +                                                                               &CommRegion->ThrottleWaitTimeout);      // Timeout after this time
5332 +
5333 +               //
5334 +               // Check the signal status. If we've timed out, clear the throttle
5335 +               // flag on the FIB to avoid us signalling the semaphore on completion.
5336 +               // We never acquired the semaphore.
5337 +               //
5338 +               if (Status == STATUS_TIMEOUT) {
5339 +
5340 +                       CommRegion->ThrottleTimedoutFibs++;
5341 +                       FsaCommPrint("ThrottledFib Timed Out - FIB: %x\n", Fib);
5342 +                       Fib->Header.Flags &= ~ThrottledFib;                                             // Clear the throttledfib flag
5343 +
5344 +               } else {
5345 +
5346 +                       ASSERT(Status == STATUS_SUCCESS);                                               // No other return is possible
5347 +
5348 +               }
5349 +
5350 +               //
5351 +               // We've been woken up and can now send the FIB to the adapter.
5352 +               // Acquire the spinlock again so we can get a queue entry. This
5353 +               // returns to GetQueueEntry.
5354 +               //
5355 +
5356 +               FsaCommPrint("ThrottleCheck - Thread Resume - FIB: %x\n", Fib);
5357 +               KeAcquireSpinLock((CommRegion->AdapNormCmdQue.QueueLock), &(CommRegion->AdapNormCmdQue.SavedIrql));
5358 +               CommRegion->ThrottleOutstandingFibs++;          // There's another throttle controlled FIB going.
5359 +               return;
5360 +
5361 +       }
5362 +}
5363 +
5364 +#endif //#ifdef API_THROTTLE
5365 +
5366 +int GetQueueEntryTimeouts = 0;
5367 +
5368 +
5369 +/*++
5370 +
5371 +Routine Description:
5372 +
5373 +    Gets the next free QE off the requested priorty adapter command queue and
5374 +    associates the Fib with the QE. The QE represented by index is ready to
5375 +     insert on the queue when this routine returns success.
5376 +
5377 +Arguments:
5378 +
5379 +    Index is the returned value which represents the QE which is ready to
5380 +        insert on the adapter's command queue.
5381 +
5382 +    Priority is an enumerated type which determines which priority level
5383 +        command queue the QE is going to be queued on.
5384 +
5385 +    Fib is a pointer to the FIB the caller wishes to have associated with the
5386 +        QE.
5387 +
5388 +    Wait is a boolean which determines if the routine will wait if there are
5389 +        no free QEs on the requested priority command queue.
5390 +
5391 +    FibContext is where the driver stores all system resources required to execute the
5392 +        command requested from the calling thread. This includes mapping resources for
5393 +        the FIB and the 'users' buffer.
5394 +
5395 +       DontInterrupt - We set this true if the queue state is such that we don't
5396 +               need to interrupt the adapter for this queue entry.
5397 +
5398 +Return Value:
5399 +
5400 +    NT_SUCCESS if a Fib was returned to the caller.
5401 +    NT_ERROR if event was an invalid event. 
5402 +
5403 +--*/
5404 +AAC_STATUS
5405 +GetQueueEntry (IN PAFA_COMM_ADAPTER Adapter, OUT PQUEUE_INDEX Index,
5406 +                          IN QUEUE_TYPES WhichQueue, IN PFIB Fib, IN BOOLEAN Wait,
5407 +                          IN PCOMM_FIB_CONTEXT FibContext, OUT ULONG *DontInterrupt)
5408 +{
5409 +    PQUEUE_ENTRY QueueEntry = NULL;
5410 +    BOOLEAN MapAddress = FALSE;
5411 +       int timeouts = 0;
5412 +       AAC_STATUS Status;
5413 +       PCOMM_REGION CommRegion;
5414 +
5415 +       CommRegion = Adapter->CommRegion;
5416 +
5417 +    //
5418 +    // Get the spinlock for the queue we are putting a command on
5419 +    //
5420 +
5421 +    if (WhichQueue == AdapHighCmdQueue) 
5422 +        OsSpinLockAcquire(CommRegion->AdapHighCmdQue.QueueLock);
5423 +    else if (WhichQueue == AdapNormCmdQueue)
5424 +        OsSpinLockAcquire(CommRegion->AdapNormCmdQue.QueueLock);
5425 +    else if (WhichQueue == AdapHighRespQueue)
5426 +        OsSpinLockAcquire(CommRegion->AdapHighRespQue.QueueLock);
5427 +    else if (WhichQueue == AdapNormRespQueue)
5428 +        OsSpinLockAcquire(CommRegion->AdapNormRespQue.QueueLock);
5429 +    else {
5430 +        FsaCommPrint("Invalid queue priority passed to GetQueueEntry.\n");
5431 +        return(FSA_INVALID_QUEUE);
5432 +    }
5433 +    
5434 +    //
5435 +    // Get the pointers to a queue entry on the queue the caller wishes to queue
5436 +    // a command request on. If there are no entries then wait if that is what the
5437 +    // caller requested. 
5438 +    //
5439 +
5440 +    if (WhichQueue == AdapHighCmdQueue) {
5441 +         // if no entries wait for some if caller wants to
5442 +        while ( !GetEntry(Adapter, AdapHighCmdQueue, &QueueEntry, Index, DontInterrupt) ) { 
5443 +                       cmn_err(CE_PANIC, "GetEntries failed (1)\n");
5444 +               }
5445 +
5446 +        //
5447 +        // Setup queue entry with a command, status and Fib mapped
5448 +        //
5449 +
5450 +        QueueEntry->Size = Fib->Header.Size;
5451 +        MapAddress = TRUE;
5452 +       
5453 +    } else if (WhichQueue == AdapNormCmdQueue) {
5454 +         // if no entries wait for some if caller wants to
5455 +        while ( !GetEntry(Adapter, AdapNormCmdQueue, &QueueEntry, Index, DontInterrupt) ) { 
5456 +                       cmn_err(CE_PANIC, "GetEntries failed (2)\n");
5457 +               }
5458
5459 +        //
5460 +        // Setup queue entry with command, status and Fib mapped
5461 +        //
5462 +
5463 +        QueueEntry->Size = Fib->Header.Size;
5464 +        MapAddress = TRUE;
5465 +        
5466 +     } else if (WhichQueue == AdapHighRespQueue) {
5467 +
5468 +        while ( !GetEntry(Adapter, AdapHighRespQueue, &QueueEntry, Index, DontInterrupt) ) { // if no entries wait for some if caller wants to
5469 +               }
5470 +
5471 +        //
5472 +        // Setup queue entry with command, status and Fib mapped
5473 +        //
5474 +
5475 +        QueueEntry->Size = Fib->Header.Size;
5476 +        QueueEntry->FibAddress = Fib->Header.SenderFibAddress;                         // Restore adapters pointer to the FIB
5477 +               Fib->Header.ReceiverFibAddress = Fib->Header.SenderFibAddress;          // Let the adapter now where to find its data
5478 +        MapAddress = FALSE;
5479 +        
5480 +     } else if (WhichQueue == AdapNormRespQueue) {
5481 +        while ( !GetEntry(Adapter, AdapNormRespQueue, &QueueEntry, Index, DontInterrupt) ) { // if no entries wait for some if caller wants to
5482 +               }
5483 +
5484 +               //
5485 +               // Setup queue entry with command, status, adapter's pointer to the Fib it sent
5486 +               //
5487 +       
5488 +        QueueEntry->Size = Fib->Header.Size;
5489 +        QueueEntry->FibAddress = Fib->Header.SenderFibAddress;                         // Restore adapters pointer to the FIB
5490 +               Fib->Header.ReceiverFibAddress = Fib->Header.SenderFibAddress;          // Let the adapter now where to find its data
5491 +        MapAddress = FALSE;
5492 +     }
5493 +                
5494 +    //
5495 +    // If MapFib is true than we need to map the Fib and put pointers in the queue entry.
5496 +    //
5497 +
5498 +    if (MapAddress) {
5499 +               QueueEntry->FibAddress = (ULONG)(FibContext->LogicalFibAddress.LowPart);
5500 +    }
5501 +    
5502 +    //
5503 +    // Return
5504 +    //
5505 +#ifdef commdebug    
5506 +    FsaCommPrint("Queue Entry contents:.\n");
5507 +    FsaCommPrint("  Command =               %d.\n", QueueEntry->Command);
5508 +    FsaCommPrint("  Status  =               %x.\n", QueueEntry->Status);
5509 +    FsaCommPrint("  Rec Fib address low =   %x.\n", QueueEntry->FibAddressLow);        
5510 +    FsaCommPrint("  Fib size in bytes =     %d.\n", QueueEntry->Size);
5511 +#endif
5512 +
5513 +    return(FSA_SUCCESS);
5514 +}
5515 +
5516 +
5517 +/*++
5518 +
5519 +Routine Description:
5520 +
5521 +    Gets the next free QE off the requested priorty adapter command queue and
5522 +      associates the Fib with the QE. The QE represented by index is ready to
5523 +    insert on the queue when this routine returns success.
5524 +
5525 +Arguments:
5526 +
5527 +    Index is the returned value which represents the QE which is ready to
5528 +        insert on the adapter's command queue.
5529 +
5530 +    WhichQueue tells us which queue the caller wishes to have the entry put.
5531 +        
5532 +Return Value:
5533 +
5534 +    NT_SUCCESS if a Fib was returned to the caller.
5535 +    NT_ERROR if event was an invalid event. 
5536 +
5537 +--*/
5538 +AAC_STATUS
5539 +InsertQueueEntry(
5540 +                 IN PAFA_COMM_ADAPTER Adapter,
5541 +                 IN QUEUE_INDEX Index,
5542 +                 IN QUEUE_TYPES WhichQueue,
5543 +                 IN ULONG DontInterrupt
5544 +                 )
5545 +{
5546 +       PCOMM_REGION CommRegion;
5547 +    
5548 +       CommRegion = Adapter->CommRegion;
5549 +
5550 +    //
5551 +    // We have already verified the queue in getentry, but we still have to make
5552 +    // sure we don't wrap here too.
5553 +    //
5554 +
5555 +    if (WhichQueue == AdapHighCmdQueue) {
5556 +
5557 +        *(CommRegion->AdapHighCmdQue.Headers.ProducerIndex) = Index + 1;
5558 +            
5559 +        OsSpinLockRelease(CommRegion->AdapHighCmdQue.QueueLock);
5560 +
5561 +               if (!DontInterrupt)
5562 +               NotifyAdapter(Adapter, AdapHighCmdQue);
5563 +        
5564 +    } else if (WhichQueue == AdapNormCmdQueue) {
5565 +
5566 +#ifdef commdebug
5567 +        FsaCommPrint("InsertQueueEntry: Inerting with an index of %d.\n",Index);
5568 +#endif
5569 +        *(CommRegion->AdapNormCmdQue.Headers.ProducerIndex) = Index + 1;
5570 +       
5571 +        OsSpinLockRelease(CommRegion->AdapNormCmdQue.QueueLock);
5572 +
5573 +               if (!DontInterrupt)
5574 +               NotifyAdapter(Adapter, AdapNormCmdQue);
5575 +
5576 +    } else if (WhichQueue == AdapHighRespQueue) {
5577 +
5578 +        *(CommRegion->AdapHighRespQue.Headers.ProducerIndex) = Index + 1;
5579 +
5580 +        OsSpinLockRelease(CommRegion->AdapHighRespQue.QueueLock);
5581 +
5582 +               if (!DontInterrupt)
5583 +               NotifyAdapter(Adapter, AdapHighRespQue);
5584 +
5585 +    } else if (WhichQueue == AdapNormRespQueue) {
5586 +
5587 +           *(CommRegion->AdapNormRespQue.Headers.ProducerIndex) = Index + 1;
5588 +           
5589 +           OsSpinLockRelease(CommRegion->AdapNormRespQue.QueueLock);
5590 +
5591 +           if (!DontInterrupt)
5592 +                   NotifyAdapter(Adapter, AdapNormRespQue);
5593 +
5594 +    } else {        
5595 +        FsaCommPrint("Invalid queue priority passed to InsertQueueEntry.\n");
5596 +        return(FSA_INVALID_QUEUE_PRIORITY);
5597 +    }
5598 +
5599 +    return(FSA_SUCCESS);                
5600 +}
5601 +
5602 +extern int GatherFibTimes;
5603 +
5604 +BOOLEAN
5605 +SendSynchFib(
5606 +       PVOID                   Arg,
5607 +       FIB_COMMAND     Command,
5608 +       PVOID                   Data,
5609 +       USHORT                  Size,
5610 +       PVOID                   Response,
5611 +       USHORT                  *ResponseSize
5612 +       )
5613 +/*++
5614 +
5615 +Routine Description:
5616 +
5617 +       This routine will send a synchronous FIB to the adapter and wait for its
5618 +       completion.
5619 +
5620 +Arguments:
5621 +
5622 +       DeviceExtension - Pointer to adapter extension structure.
5623 +
5624 +
5625 +Return Value:
5626 +
5627 +       BOOLEAN
5628 +
5629 +--*/
5630 +{
5631 +       PAFA_COMM_ADAPTER Adapter = Arg;
5632 +       FIB *Fib;
5633 +       ULONG returnStatus;
5634 +
5635 +       Fib = Adapter->SyncFib;
5636 +
5637 +    Fib->Header.StructType = TFib;
5638 +    Fib->Header.Size = sizeof(FIB);
5639 +    Fib->Header.XferState = HostOwned | FibInitialized | FibEmpty;
5640 +    Fib->Header.ReceiverFibAddress = 0;
5641 +    Fib->Header.SenderSize = sizeof(FIB);
5642 +    Fib->Header.SenderFibAddress = (ULONG)Fib;
5643 +    Fib->Header.Command = Command;
5644 +
5645 +       //
5646 +       // Copy the Data portion into the Fib.
5647 +       //
5648 +
5649 +       RtlCopyMemory( Fib->data, Data, Size );
5650 +
5651 +
5652 +    Fib->Header.XferState |= (SentFromHost | NormalPriority);
5653 +    
5654 +       //
5655 +    // Set the size of the Fib we want to send to the adapter
5656 +       //
5657 +
5658 +    Fib->Header.Size = sizeof(FIB_HEADER) + Size;
5659 +
5660 +       if (!Adapter->AdapterFuncs->SendSynchFib( Adapter->AdapterExtension,
5661 +                                                                                         Adapter->SyncFibPhysicalAddress )) {
5662 +
5663 +                       return (FALSE);
5664 +
5665 +       }
5666 +
5667 +       //
5668 +       // Copy the response back to the caller's buffer.
5669 +       //
5670 +
5671 +       RtlCopyMemory( Response, Fib->data, Fib->Header.Size - sizeof(FIB_HEADER) );
5672 +
5673 +       *ResponseSize = Fib->Header.Size - sizeof(FIB_HEADER);
5674 +
5675 +       //
5676 +       // Indicate success
5677 +       //
5678 +
5679 +       return (TRUE);
5680 +}
5681 +
5682 +//
5683 +// Define the highest level of host to adapter communication routines. These
5684 +// routines will support host to adapter FS commuication. These routines have
5685 +// no knowledge of the commuication method used. This level sends and receives
5686 +// FIBs. This level has no knowledge of how these FIBs get passed back and forth.
5687 +//
5688 +
5689 +
5690 +
5691 +/*++
5692 +
5693 +Routine Description:
5694 +
5695 +    Sends the requested FIB to the adapter and optionally will wait for a
5696 +     response FIB. If the caller does not wish to wait for a response than
5697 +    an event to wait on must be supplied. This event will be set when a
5698 +    response FIB is received from the adapter.
5699 +
5700 +Arguments:
5701 +
5702 +    Fib is a pointer to the FIB the caller wishes to send to the adapter.
5703 +    
5704 +    Size - Size of the data portion of the Fib.
5705 +    
5706 +    Priority is an enumerated type which determines which priority level
5707 +        the caller wishes to send this command at. 
5708 +
5709 +    Wait is a boolean which determines if the routine will wait for the
5710 +        completion Fib to be returned(TRUE), or return when the Fib has been
5711 +        successfully received by the adapter(FALSE).
5712 +
5713 +    WaitOn is only vaild when Wait is FALSE. The Event will be set when the response
5714 +        FIB has been returned by the adapter.
5715 +
5716 +    ReturnFib is an optional pointer to a FIB that if present the response FIB will
5717 +        copied to.     
5718 +        
5719 +Return Value:
5720 +
5721 +    NT_SUCCESS if a Fib was returned to the caller.
5722 +    NT_ERROR if event was an invalid event. 
5723 +
5724 +       --*/
5725 +AAC_STATUS
5726 +SendFib (IN FIB_COMMAND Command,
5727 +         IN PFIB_CONTEXT Context,
5728 +         IN ULONG Size, 
5729 +         IN COMM_PRIORITIES Priority,
5730 +         IN BOOLEAN Wait,
5731 +         IN PVOID WaitOn,
5732 +         IN BOOLEAN ResponseExpected,
5733 +         IN PFIB_CALLBACK FibCallback,
5734 +         IN PVOID FibCallbackContext)
5735 +{
5736 +               PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
5737 +               QUEUE_INDEX Index;
5738 +               QUEUE_TYPES WhichQueue;
5739 +               LARGE_INTEGER Timeout;
5740 +               AAC_STATUS Status;
5741 +               PAFA_COMM_ADAPTER Adapter = FibContext->Adapter;
5742 +               ULONG DontInterrupt = FALSE;
5743 +               PFIB Fib = FibContext->Fib;
5744 +               IN PCOMM_QUE OurQueue;
5745 +
5746 +               Timeout = FsaCommData.AdapterTimeout;
5747 +
5748 +               if (!(Fib->Header.XferState & HostOwned)) {
5749 +                               FsaCommPrint("SendFib was called with a xfer state not set to HostOwned!\n");
5750 +                               FsaCommLogEvent(FibContext,
5751 +                                                               FsaCommData.DeviceObject, 
5752 +                                                               FSAFS_FIB_INVALID, 
5753 +                                                               STATUS_UNSUCCESSFUL, 
5754 +                                                               BugCheckFileId | __LINE__,
5755 +                                                               FACILITY_FSAFS_ERROR_CODE,
5756 +                                                               NULL,
5757 +                                                               TRUE);                  
5758 +
5759 +                               return(STATUS_UNSUCCESSFUL);
5760 +
5761 +               }
5762 +    
5763 +               //
5764 +               // There are 5 cases with the wait and reponse requested flags. The only invalid cases
5765 +               // are if the caller requests to wait and  does not request a response and if the
5766 +               // caller does not want a response and the Fib is not allocated from pool. If a response
5767 +               // is not requesed the Fib will just be deallocaed by the DPC routine when the response
5768 +               // comes back from the adapter. No further processing will be done besides deleting the
5769 +               // Fib. We will have a debug mode where the adapter can notify the host it had a problem
5770 +               // and the host can log that fact.
5771 +
5772 +               if (Wait && !ResponseExpected) {
5773 +
5774 +                               FsaCommLogEvent(FibContext,
5775 +                                                FsaCommData.DeviceObject, 
5776 +                                                FSAFS_FIB_INVALID, 
5777 +                                                STATUS_UNSUCCESSFUL, 
5778 +                                                BugCheckFileId | __LINE__,
5779 +                                                FACILITY_FSAFS_ERROR_CODE,
5780 +                                                NULL,
5781 +                                                TRUE);                 
5782 +
5783 +                               return(STATUS_UNSUCCESSFUL);
5784 +
5785 +               } else if (!Wait && ResponseExpected) {
5786 +                               Fib->Header.XferState |= (Async | ResponseExpected);
5787 +                               FIB_COUNTER_INCREMENT(FsaCommData.AsyncSent);
5788 +               } else if (!Wait && !ResponseExpected) {
5789 +                               Fib->Header.XferState |= NoResponseExpected;
5790 +                               FIB_COUNTER_INCREMENT(FsaCommData.NoResponseSent);
5791 +               } else if (Wait && ResponseExpected) {
5792 +                  Fib->Header.XferState |= ResponseExpected;
5793 +                  FIB_COUNTER_INCREMENT(FsaCommData.NormalSent);
5794 +               } 
5795 +
5796 +               Fib->Header.SenderData = (ULONG)FibContext; // so we can complete the io in the dpc routine
5797 +
5798 +               //
5799 +               // Set FIB state to indicate where it came from and if we want a response from the
5800 +               // adapter. Also load the command from the caller.
5801 +               //
5802 +
5803 +               Fib->Header.SenderFibAddress = (ULONG)Fib;
5804 +               Fib->Header.Command = Command;
5805 +               Fib->Header.XferState |= SentFromHost;
5806 +               FibContext->Fib->Header.Flags = 0;                              // Zero the flags field - its internal only...
5807 +    
5808 +               //
5809 +               // Set the size of the Fib we want to send to the adapter
5810 +               //
5811 +
5812 +               Fib->Header.Size = sizeof(FIB_HEADER) + Size;
5813 +               if (Fib->Header.Size > Fib->Header.SenderSize) {
5814 +                               return(STATUS_BUFFER_OVERFLOW);
5815 +               }                
5816 +
5817 +               //
5818 +               // Get a queue entry connect the FIB to it and send an notify the adapter a command is ready.
5819 +               //
5820 +            
5821 +               if (Priority == FsaHigh) {
5822 +                               Fib->Header.XferState |= HighPriority;
5823 +                               WhichQueue = AdapHighCmdQueue;
5824 +                               OurQueue = &Adapter->CommRegion->AdapHighCmdQue;
5825 +               } else {
5826 +                               Fib->Header.XferState |= NormalPriority;
5827 +                               WhichQueue = AdapNormCmdQueue;
5828 +                               OurQueue = &Adapter->CommRegion->AdapNormCmdQue;
5829 +               }
5830 +
5831 +               if (Wait) {
5832 +                               OsCvLockAcquire( FibContext->FsaEventMutex );
5833 +               }
5834 +
5835 +               if ( GetQueueEntry( Adapter, &Index, WhichQueue, Fib, TRUE, FibContext, &DontInterrupt) != FSA_SUCCESS )
5836 +                               return(STATUS_UNSUCCESSFUL);
5837 +
5838 +               // bmb debug
5839 +
5840 +               cmn_err (CE_DEBUG,"SendFib: inserting a queue entry at index %d.\n",Index);
5841 +               cmn_err (CE_DEBUG,"Fib contents:.\n");
5842 +               cmn_err (CE_DEBUG,"  Command =               %d.\n", Fib->Header.Command);
5843 +               cmn_err (CE_DEBUG,"  XferState  =            %x.\n", Fib->Header.XferState );
5844 +
5845 +               //
5846 +               // Fill in the Callback and CallbackContext if we are not going to wait.
5847 +               //
5848 +
5849 +               if (!Wait) {
5850 +
5851 +                               FibContext->FibCallback = FibCallback;
5852 +                               FibContext->FibCallbackContext = FibCallbackContext;
5853 +
5854 +               }
5855 +
5856 +               FIB_COUNTER_INCREMENT(FsaCommData.FibsSent);
5857 +
5858 +               InsertTailList( &OurQueue->OutstandingIoQueue, &FibContext->QueueEntry );
5859 +               OurQueue->NumOutstandingIos++;
5860 +
5861 +               FibContext->FibComplete = 0;
5862 +
5863 +
5864 +
5865 +               if ( InsertQueueEntry( Adapter, Index, WhichQueue, (DontInterrupt & FsaCommData.EnableInterruptModeration)) != FSA_SUCCESS )
5866 +                        return(STATUS_UNSUCCESSFUL);
5867 +
5868 +               //
5869 +               // If the caller wanted us to wait for response wait now. 
5870 +               // If Timeouts are enabled than set the timeout otherwise wait forever.
5871 +               //
5872 +    
5873 +               if (Wait) {
5874 +                        while (FibContext->FibComplete == 0) {
5875 +                                OsCv_wait( &FibContext->FsaEvent, FibContext->FsaEventMutex );
5876 +                        }      
5877 +                        
5878 +                        OsCvLockRelease( FibContext->FsaEventMutex );
5879 +                                       
5880 +                        if ( (FibContext->Flags & FIB_CONTEXT_FLAG_TIMED_OUT) ) {
5881 +                                return(STATUS_IO_TIMEOUT);
5882 +                        } else {
5883 +                                return(STATUS_SUCCESS);
5884 +                        }
5885 +               }
5886 +
5887 +               //
5888 +               // If the user does not want a response than return success otherwise return pending
5889 +               // 
5890 +
5891 +               ASSERT( FibCallback );
5892 +
5893 +               if (ResponseExpected)
5894 +                               return(STATUS_PENDING);
5895 +               else
5896 +                               return(STATUS_SUCCESS);
5897 +}
5898 +
5899 +BOOLEAN
5900 +GetConsumerEntry(
5901 +       IN PAFA_COMM_ADAPTER Adapter,
5902 +    PCOMM_QUE OurQueue,
5903 +    OUT PQUEUE_ENTRY *Entry
5904 +    )
5905 +/*++
5906 +
5907 +Routine Description:
5908 +
5909 +    Will return a pointer to the entry on the top of the queue requested that we are a consumer
5910 +    of, and return the address of the queue entry. It does not change the state of the queue. 
5911 +
5912 +Arguments:
5913 +
5914 +    OurQueue - is the queue the queue entry should be removed from.
5915 +
5916 +    Entry - is a pointer where the address  of the queue entry should be returned.    
5917 +    
5918 +Return Value:
5919 +
5920 +    TRUE if there was a queue entry on the response queue for the host to consume.
5921 +    FALSE if there were no queue entries to consume.
5922 +    
5923 +--*/
5924 +
5925 +{
5926 +    QUEUE_INDEX Index;
5927 +       BOOLEAN status;
5928 +
5929 +    if (*OurQueue->Headers.ProducerIndex == *OurQueue->Headers.ConsumerIndex) {
5930 +               status = FALSE;
5931 +       } else {
5932 +
5933 +           //
5934 +           // The consumer index must be wrapped if we have reached the end of
5935 +           // the queue. 
5936 +           // Else we just use the entry pointed to by the header index
5937 +           //
5938 +           
5939 +           if (*OurQueue->Headers.ConsumerIndex >= OurQueue->QueueEntries) 
5940 +                       Index = 0;              
5941 +           else
5942 +               Index = *OurQueue->Headers.ConsumerIndex;
5943 +           
5944 +           *Entry = OurQueue->BaseAddress + Index;
5945 +
5946 +#ifdef commdebug
5947 +           FsaCommPrint("Got a QE at Index %d, QE Addrss of %x.\n",Index,*Entry);
5948 +#endif
5949 +               status = TRUE;
5950 +       }
5951 +
5952 +    return(status);
5953 +}
5954 +
5955 +BOOLEAN
5956 +ConsumerEntryAvailable(
5957 +       IN PAFA_COMM_ADAPTER Adapter,
5958 +    PCOMM_QUE OurQueue
5959 +       )
5960 +{
5961 +    return (*OurQueue->Headers.ProducerIndex != *OurQueue->Headers.ConsumerIndex);
5962 +}
5963 +
5964 +VOID
5965 +FreeConsumerEntry(
5966 +       IN PAFA_COMM_ADAPTER Adapter,
5967 +    PCOMM_QUE OurQueue,
5968 +    QUEUE_TYPES WhichQueue
5969 +    )
5970 +/*++
5971 +
5972 +Routine Description:
5973 +
5974 +    Frees up the current top of the queue we are a consumer of. If the queue was full
5975 +    notify the producer that the queue is no longer full.
5976 +
5977 +Arguments:
5978 +
5979 +    OurQueue - is the queue we will free the current consumer entry on.
5980 +
5981 +Return Value:
5982 +
5983 +    TRUE if there was a queue entry on the response queue for the host to consume.
5984 +    FALSE if there were no queue entries to consume.
5985 +    
5986 +--*/
5987 +
5988 +{
5989 +    BOOLEAN WasFull = FALSE;
5990 +    HOST_2_ADAP_EVENT Notify;
5991 +
5992 +    if (*OurQueue->Headers.ProducerIndex+1 == *OurQueue->Headers.ConsumerIndex)
5993 +        WasFull = TRUE;
5994 +        
5995 +    if (*OurQueue->Headers.ConsumerIndex >= OurQueue->QueueEntries)
5996 +        *OurQueue->Headers.ConsumerIndex = 1;
5997 +    else
5998 +        *OurQueue->Headers.ConsumerIndex += 1;
5999 +        
6000 +    if (WasFull) {
6001 +        switch (WhichQueue) {
6002 +
6003 +            case HostNormCmdQueue:
6004 +                Notify = HostNormCmdNotFull;
6005 +                break;
6006 +            case HostHighCmdQueue:
6007 +                Notify = HostHighCmdNotFull;
6008 +                break;
6009 +
6010 +            case HostNormRespQueue:
6011 +                Notify = HostNormRespNotFull;
6012 +                break;
6013 +
6014 +            case HostHighRespQueue:
6015 +                Notify = HostHighRespNotFull;
6016 +                break;
6017 +
6018 +        }
6019 +        NotifyAdapter(Adapter, Notify);
6020 +    }
6021 +
6022 +}        
6023 +
6024 +AAC_STATUS
6025 +CompleteAdapterFib(
6026 +       IN PFIB_CONTEXT Context,
6027 +    IN USHORT Size
6028 +    )
6029 +/*++
6030 +
6031 +Routine Description:
6032 +
6033 +    Will do all necessary work to complete a FIB that was sent from the adapter.
6034 +
6035 +Arguments:
6036 +
6037 +    Fib is a pointer to the FIB that caller wishes to complete processing on. 
6038 +
6039 +    Size - Size of the completion Packet(Opitional). If not present than the current
6040 +           largest size in the Fib will be used
6041 +    
6042 +       Adapter - Pointer to which adapter sent this FIB
6043 +
6044 +Return Value:
6045 +
6046 +    NT_SUCCESS if a Fib was returned to the caller.
6047 +    NT_ERROR if event was an invalid event. 
6048 +
6049 +--*/
6050 +{
6051 +       PCOMM_FIB_CONTEXT FibContext = Context;
6052 +    PFIB Fib = FibContext->Fib;
6053 +       PAFA_COMM_ADAPTER Adapter = FibContext->Adapter;
6054 +    ULONG DontInterrupt = FALSE;
6055 +
6056 +    if (Fib->Header.XferState == 0)
6057 +        return(STATUS_SUCCESS);
6058 +
6059 +    //
6060 +    // If we plan to do anything check the structure type first.
6061 +    // 
6062 +
6063 +    if ( Fib->Header.StructType != TFib ) {
6064 +        FsaCommPrint("Error CompleteFib called with a non Fib structure.\n");
6065 +        return(STATUS_UNSUCCESSFUL);
6066 +    }
6067 +
6068 +    //
6069 +    // This block handles the case where the adapter had sent us a command and we
6070 +    // have finished processing the command. We call completeFib when we are done
6071 +    // processing the command and want to send a response back to the adapter. This
6072 +    // will send the completed cdb to the adapter.
6073 +    //
6074 +
6075 +    if (Fib->Header.XferState & SentFromAdapter) {
6076 +        Fib->Header.XferState |= HostProcessed;
6077 +        if (Fib->Header.XferState & HighPriority) {
6078 +            QUEUE_INDEX Index;
6079 +            
6080 +            if (Size) {
6081 +                Size += sizeof(FIB_HEADER);
6082 +                if (Size > Fib->Header.SenderSize) 
6083 +                    return(STATUS_BUFFER_OVERFLOW);
6084 +                Fib->Header.Size = Size;
6085 +            }
6086 +
6087 +            if (GetQueueEntry(Adapter, &Index, AdapHighRespQueue, Fib, TRUE, NULL, &DontInterrupt) != STATUS_SUCCESS) {
6088 +                FsaCommPrint("CompleteFib got an error geting a queue entry for a response.\n");
6089 +                return(FSA_FATAL);
6090 +            }
6091 +            if (InsertQueueEntry(Adapter, 
6092 +                                               Index, 
6093 +                                               AdapHighRespQueue, 
6094 +                                               (DontInterrupt & (BOOLEAN)FsaCommData.EnableInterruptModeration)) != STATUS_SUCCESS) {
6095 +                FsaCommPrint("CompleteFib failed while inserting entry on the queue.\n");
6096 +            }
6097 +        } else if (Fib->Header.XferState & NormalPriority) {
6098 +            QUEUE_INDEX Index;
6099 +
6100 +            if (Size) {
6101 +                Size += sizeof(FIB_HEADER);
6102 +                if (Size > Fib->Header.SenderSize) 
6103 +                    return(STATUS_BUFFER_OVERFLOW);
6104 +                Fib->Header.Size = Size;
6105 +            }
6106 +            
6107 +            if (GetQueueEntry(Adapter, &Index, AdapNormRespQueue, Fib, TRUE, NULL, &DontInterrupt) != STATUS_SUCCESS) {
6108 +                FsaCommPrint("CompleteFib got an error geting a queue entry for a response.\n");
6109 +                return(FSA_FATAL);
6110 +            }
6111 +            if (InsertQueueEntry(Adapter, 
6112 +                                               Index, 
6113 +                                               AdapNormRespQueue, 
6114 +                                               (DontInterrupt & (BOOLEAN)FsaCommData.EnableInterruptModeration)) != STATUS_SUCCESS) {
6115 +                FsaCommPrint("CompleteFib failed while inserting entry on the queue.\n");
6116 +            }
6117 +               }
6118 +    } else {
6119 +        cmn_err(CE_WARN, "CompleteFib: Unknown xferstate detected.\n");
6120 +               FsaBugCheck(0,0,0);
6121 +    }   
6122 +    return(STATUS_SUCCESS);
6123 +}
6124 +
6125 +AAC_STATUS
6126 +CompleteFib(
6127 +       IN PFIB_CONTEXT Context
6128 +    )
6129 +/*++
6130 +
6131 +Routine Description:
6132 +
6133 +    Will do all necessary work to complete a FIB. If the caller wishes to
6134 +    reuse the FIB after post processing has been completed Reinitialize
6135 +    should be called set to TRUE, otherwise the FIB will be returned to the
6136 +    free FIB pool. If Reinitialize is set to TRUE then the FIB header is
6137 +    reinitialzied and is ready for reuse on return from this routine.
6138 +
6139 +Arguments:
6140 +
6141 +    Fib is a pointer to the FIB that caller wishes to complete processing on. 
6142 +
6143 +    Size - Size of the completion Packet(Opitional). If not present than the current
6144 +           largest size in the Fib will be used
6145 +    
6146 +    Reinitialize is a boolean which determines if the routine will ready the
6147 +        completed FIB for reuse(TRUE) or not(FALSE).
6148 +
6149 +Return Value:
6150 +
6151 +    NT_SUCCESS if a Fib was returned to the caller.
6152 +    NT_ERROR if event was an invalid event. 
6153 +
6154 +--*/
6155 +{
6156 +    PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
6157 +       PAFA_COMM_ADAPTER Adapter = FibContext->Adapter;
6158 +       PFIB Fib = FibContext->Fib;
6159 +
6160 +    //
6161 +    // Check for a fib which has already been completed
6162 +    //
6163 +
6164 +//     ASSERT(Fib->Header.XferState & AdapterProcessed);
6165 +    if (Fib->Header.XferState == 0)
6166 +        return(STATUS_SUCCESS);
6167 +
6168 +    //
6169 +    // If we plan to do anything check the structure type first.
6170 +    // 
6171 +
6172 +    if ( Fib->Header.StructType != TFib ) {
6173 +        FsaCommPrint("Error CompleteFib called with a non Fib structure.\n");
6174 +        return(STATUS_UNSUCCESSFUL);
6175 +    }
6176 +
6177 +#if 0
6178 +//#if FSA_ADAPTER_METER
6179 +       //
6180 +       // Meter the completion
6181 +       //
6182 +       fsaMeterEnd(                                            // meter the end of an operation
6183 +               &(Adapter->FibMeter),                   // .. the meter
6184 +               IrpContext->FibMeterType,               // .. type of operation
6185 +               &(IrpContext->FibStartTime),    // .. ptr to operation start timestamp
6186 +               FibGetMeterSize(Fib,                    // .. number of bytes in operation
6187 +                               IrpContext->FibMeterType, 
6188 +                               IrpContext->FibSubCommand));
6189 +#endif // FSA_ADAPTER_METER
6190 +       
6191 +    //
6192 +    // This block completes a cdb which orginated on the host and we just need
6193 +    // to deallocate the cdb or reinit it. At this point the command is complete
6194 +    // that we had sent to the adapter and this cdb could be reused.
6195 +    //
6196 +       
6197 +    if ( (Fib->Header.XferState & SentFromHost) &&
6198 +         (Fib->Header.XferState & AdapterProcessed)) {
6199 +        
6200 +        ASSERT(FibContext->LogicalFibAddress.LowPart != 0);
6201 +
6202 +        return( DeallocateFib(FibContext) ); 
6203 +       
6204 +    //
6205 +    // This handles the case when the host has aborted the I/O to the
6206 +    // adapter because the adapter is not responding
6207 +    //
6208 +
6209 +    } else if (Fib->Header.XferState & SentFromHost) {
6210 +
6211 +        ASSERT(FibContext->LogicalFibAddress.LowPart != 0);
6212 +
6213 +
6214 +        return( DeallocateFib(FibContext) ); 
6215 +
6216 +    } else if (Fib->Header.XferState & HostOwned) {
6217 +
6218 +        return(DeallocateFib(FibContext));
6219 +
6220 +    } else {
6221 +        cmn_err(CE_WARN, "CompleteFib: Unknown xferstate detected.\n");
6222 +               FsaBugCheck(0,0,0);
6223 +    }   
6224 +    return(STATUS_SUCCESS);
6225 +}
6226 +
6227 +VOID
6228 +HandleDriverAif(
6229 +    IN PAFA_COMM_ADAPTER Adapter,
6230 +       IN PCOMM_FIB_CONTEXT FibContext
6231 +    )
6232 +/*++
6233 +
6234 +Routine Description:
6235 +
6236 +       This routine handles a driver notify fib from the adapter and dispatches it to 
6237 +       the appropriate routine for handling.
6238 +
6239 +Arguments:
6240 +
6241 +       Adapter - Which adapter this fib is from
6242 +       FibContext - Pointer to FibContext from adapter.
6243 +    
6244 +Return Value:
6245 +
6246 +    Nothing.
6247 +    
6248 +--*/
6249 +{
6250 +       PFIB Fib = FibContext->Fib;
6251 +       PAFA_CLASS_DRIVER ClassDriver;
6252 +       BOOLEAN Handled = FALSE;
6253 +
6254 +
6255 +       //
6256 +       // First loop through all of the class drivers to give them a chance to handle
6257 +       // the Fib.
6258 +       //
6259 +
6260 +       ClassDriver = Adapter->ClassDriverList;
6261 +
6262 +       while (ClassDriver) {
6263 +
6264 +               if (ClassDriver->HandleAif) {
6265 +
6266 +                       if (ClassDriver->HandleAif( ClassDriver->ClassDriverExtension, FibContext ) ) {
6267 +
6268 +                               Handled = TRUE;
6269 +                               break;
6270 +
6271 +                       }
6272 +               }
6273 +
6274 +               ClassDriver = ClassDriver->Next;
6275 +       }
6276 +
6277 +       if (!Handled) {
6278 +
6279 +               //
6280 +               // Set the status of this FIB to be Invalid parameter.
6281 +               //
6282 +
6283 +//             *(FSASTATUS *)Fib->data = ST_INVAL;
6284 +               *(FSASTATUS *)Fib->data = ST_OK;
6285 +
6286 +
6287 +               CompleteAdapterFib(FibContext, sizeof(FSASTATUS));
6288 +
6289 +       }
6290 +}
6291 +
6292 +int
6293 +NormCommandThread(
6294 +    IN PAFA_COMM_ADAPTER Adapter
6295 +    )
6296 +/*++
6297 +
6298 +Routine Description:
6299 +
6300 +    Waits on the commandready event in it's queue. When the event gets set it will
6301 +    pull FIBs off it's queue. It will continue to pull FIBs off till the queue is empty.
6302 +    When the queue is empty it will wait for more FIBs.
6303 +
6304 +Arguments:
6305 +
6306 +    Context is used. All data os global
6307 +    
6308 +Return Value:
6309 +    Nothing.
6310 +    
6311 +--*/
6312 +{
6313 +    PFIB Fib, NewFib;
6314 +       COMM_FIB_CONTEXT FibContext; // for error logging
6315 +    KIRQL SavedIrql;
6316 +       PCOMM_REGION CommRegion = Adapter->CommRegion;
6317 +       PLIST_ENTRY Entry;
6318 +       PGET_ADAPTER_FIB_CONTEXT AdapterFibContext;
6319 +
6320 +       //
6321 +       // We can only have one thread per adapter for AIF's.
6322 +       //
6323 +
6324 +       if (Adapter->AifThreadStarted) {
6325 +               return (EINVAL);
6326 +       }
6327 +
6328 +// cmn_err(CE_DEBUG, "AIF thread started");
6329 +
6330 +       //
6331 +       // Let the DPC know it has a place to send the AIF's to.
6332 +       //
6333 +
6334 +       Adapter->AifThreadStarted = TRUE;
6335 +
6336 +       RtlZeroMemory(&FibContext, sizeof(COMM_FIB_CONTEXT));
6337 +
6338 +       OsSpinLockAcquire(CommRegion->HostNormCmdQue.QueueLock);
6339 +
6340 +    while (TRUE) {
6341 +
6342 +               //
6343 +               // NOTE : the QueueLock is held at the top of each loop.
6344 +               //
6345 +
6346 +               ASSERT(OsSpinLockOwned(CommRegion->HostNormCmdQue.QueueLock));
6347 +
6348 +               while (!IsListEmpty(&(CommRegion->HostNormCmdQue.CommandQueue))) {
6349 +                       PLIST_ENTRY Entry;
6350 +                       PAIFCOMMANDTOHOST AifCommandToHost;
6351 +
6352 +                       Entry = RemoveHeadList(&(CommRegion->HostNormCmdQue.CommandQueue));
6353 +
6354 +                       OsSpinLockRelease(CommRegion->HostNormCmdQue.QueueLock);
6355 +
6356 +                       Fib = CONTAINING_RECORD( Entry, FIB, Header.FibLinks );
6357 +                                               
6358 +                       //
6359 +                       // We will process the FIB here or pass it to a worker thread that is TBD. We Really
6360 +                       // can't do anything at this point since we don't have anything defined for this thread to
6361 +                       // do.
6362 +                       //
6363 +                       
6364 +                       // cmn_err(CE_DEBUG, "Got Fib from the adapter with a NORMAL priority, command 0x%x.\n", Fib->Header.Command);
6365 +
6366 +                       RtlZeroMemory( &FibContext, sizeof(COMM_FIB_CONTEXT) );
6367 +
6368 +
6369 +                   FibContext.NodeTypeCode = FSAFS_NTC_FIB_CONTEXT;
6370 +                   FibContext.NodeByteSize = sizeof( COMM_FIB_CONTEXT );
6371 +                       FibContext.Fib = Fib;
6372 +                       FibContext.FibData = Fib->data;
6373 +                       FibContext.Adapter = Adapter;
6374 +
6375 +                       
6376 +                       //
6377 +                       // We only handle AifRequest fibs from the adapter.
6378 +                       //
6379 +
6380 +                       ASSERT(Fib->Header.Command == AifRequest);
6381 +
6382 +
6383 +                       AifCommandToHost = (PAIFCOMMANDTOHOST) Fib->data;
6384 +
6385 +                       if (AifCommandToHost->command == AifCmdDriverNotify) {
6386 +
6387 +
6388 +
6389 +                               HandleDriverAif( Adapter, &FibContext );
6390 +
6391 +                       } else {
6392 +                                       AAC_UINT32 time_now, time_last;
6393 +                                       time_now = (AAC_UINT32)OsGetSeconds();
6394 +                       
6395 +
6396 +                               OsCvLockAcquire(Adapter->AdapterFibMutex);
6397 +
6398 +                               Entry = Adapter->AdapterFibContextList.Flink;
6399 +
6400 +                               //
6401 +                               // For each Context that is on the AdapterFibContextList, make a copy of the
6402 +                               // fib, and then set the event to wake up the thread that is waiting for it.
6403 +                               //
6404 +
6405 +                               while (Entry != &Adapter->AdapterFibContextList) {
6406 +
6407 +                                       //
6408 +                                       // Extract the AdapterFibContext
6409 +                                       //
6410 +
6411 +                                       AdapterFibContext = CONTAINING_RECORD( Entry, GET_ADAPTER_FIB_CONTEXT, NextContext );
6412 +
6413 +                                       //
6414 +                                       // Check if the queue is getting backlogged
6415 +                                       //
6416 +                                       if ( AdapterFibContext->FibCount > 20 ) {
6417 +                                               time_last = (AAC_UINT32)(AdapterFibContext->FileObject);
6418 +
6419 +                                               //
6420 +                                               // has it been > 2 minutes since the last read off the queue?
6421 +                                               //
6422 +                                               if ((time_now - time_last) > 120) {
6423 +                                                       Entry = Entry->Flink;
6424 +                                                       // cmn_err (CE_WARN, "aifd: Flushing orphaned AdapterFibContext: idle %d seconds, %d fibs",
6425 +                                                       //               time_now - time_last,
6426 +                                                       //               AdapterFibContext->FibCount);
6427 +                                                       FsaCloseAdapterFibContext ( Adapter, AdapterFibContext );
6428 +                                                       continue;
6429 +                                               }
6430 +                                       }
6431 +                                                                       
6432 +//  Warning: sleep possible while holding spinlock
6433 +                                       NewFib = OsAllocMemory(sizeof(FIB), OS_ALLOC_MEM_SLEEP);
6434 +
6435 +                                       if (NewFib) {
6436 +
6437 +                                               //
6438 +                                               // Make the copy of the FIB
6439 +                                               //
6440 +
6441 +                                               RtlCopyMemory(NewFib, Fib, sizeof(FIB));
6442 +
6443 +                                               //
6444 +                                               // Put the FIB onto the AdapterFibContext's FibList
6445 +                                               //
6446 +
6447 +                                               InsertTailList(&AdapterFibContext->FibList, &NewFib->Header.FibLinks);
6448 +                                               AdapterFibContext->FibCount++;
6449 +
6450 +                                               // 
6451 +                                               // Set the event to wake up the thread that will waiting.
6452 +                                               //
6453 +
6454 +                                               OsCv_signal(&AdapterFibContext->UserEvent);
6455 +
6456 +                                       } else {
6457 +
6458 +
6459 +                                       }
6460 +
6461 +                                       Entry = Entry->Flink;
6462 +                               }
6463 +
6464 +                               //
6465 +                               // Set the status of this FIB
6466 +                               //
6467 +
6468 +                               *(FSASTATUS *)Fib->data = ST_OK;
6469 +                               
6470 +                               CompleteAdapterFib( &FibContext, sizeof(FSASTATUS) );
6471 +
6472 +                               OsCvLockRelease(Adapter->AdapterFibMutex);
6473 +
6474 +                       }
6475 +
6476 +                       OsSpinLockAcquire(CommRegion->HostNormCmdQue.QueueLock);
6477 +
6478 +               }
6479 +
6480 +               //
6481 +               // There are no more AIF's,  call cv_wait_sig to wait for more
6482 +               // to process.
6483 +               //
6484 +
6485 +               // cmn_err(CE_DEBUG, "no more AIF's going to sleep\n");
6486 +
6487 +               if (OsCv_wait_sig( &(CommRegion->HostNormCmdQue.CommandReady), 
6488 +                                                CommRegion->HostNormCmdQue.QueueLock ) == 0) {
6489 +
6490 +                       OsSpinLockRelease(CommRegion->HostNormCmdQue.QueueLock);
6491 +
6492 +                       Adapter->AifThreadStarted = FALSE;
6493 +
6494 +                       // cmn_err(CE_DEBUG, "AifThread awoken by a signal\n");
6495 +                       
6496 +                       return (EINTR);
6497 +                       
6498 +               }                                
6499 +
6500 +               // cmn_err(CE_DEBUG, "Aif thread awake, going to look for more AIF's\n");
6501 +
6502 +       }
6503 +}
6504 +    
6505 +
6506 +PVOID
6507 +FsaGetFibData(
6508 +       IN PFIB_CONTEXT Context
6509 +       )
6510 +{
6511 +    PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
6512 +
6513 +       return ((PVOID)FibContext->Fib->data);
6514 +}          
6515 +                              
6516 +
6517 +#ifdef API_THROTTLE
6518 +
6519 +void ThrottlePeriodEndDpcRtn(
6520 +    IN PKDPC Dpc,
6521 +    IN PVOID DeferredContext,
6522 +    IN PVOID SystemArgument1,
6523 +    IN PVOID SystemArgument2
6524 +    )
6525 +/*++
6526 +
6527 +Routine Description:
6528 +
6529 +    This routine is called as a DPC when a throttle period expires. It
6530 +       restarts all threads suspended due to the throttling flow control.
6531 +       
6532 +       The throttling counted semaphore is signalled for all waiting threads
6533 +       and the indicator of throttling active is cleared.
6534 +
6535 +Arguments:
6536 +
6537 +    Dpc                                - Pointer to Dpc structure. Not used.
6538 +       DefferedContext - Pointer to per-adapter context. This is used to locate the
6539 +                                         throttle information for this adapter.
6540 +    SystemArgument1    - Not used
6541 +       SystemArgument2 - Not used
6542 +       
6543 +Return Value:
6544 +
6545 +       None.
6546 +
6547 +--*/
6548 +{
6549 +       PCOMM_REGION CommRegion;
6550 +       PAFA_COMM_ADAPTER Adapter = (PAFA_COMM_ADAPTER) DeferredContext;
6551 +
6552 +       CommRegion = Adapter->CommRegion;
6553 +
6554 +       //
6555 +       // Acquire the spinlock protecting the throttle status.
6556 +       //
6557 +       OsSpinLockAcquire(CommRegion->AdapNormCmdQue.QueueLock);
6558 +
6559 +       FsaCommPrint("ThrottlePeriodEndDpc\n");
6560 +
6561 +       //
6562 +       // Check that the timer has fired as many times as it was set !
6563 +       //
6564 +
6565 +       CommRegion->ThrottleTimerFires++;
6566 +       ASSERT(CommRegion->ThrottleTimerFires == CommRegion->ThrottleTimerSets);
6567 +
6568 +       //
6569 +       // The throttle period is now over. Restart all threads waiting
6570 +       // on the throttle being released.
6571 +       // Clear the throttle active indicator. This will allow new FIBs
6572 +       // to be sent to the adapter once we release the spinlock on exiting
6573 +       // the DPC. This means all restarted threads will be runnable
6574 +       // threads by then.
6575 +       //
6576 +
6577 +       ASSERT(CommRegion->ThrottleActive == TRUE);             // The throttle had better be on !
6578 +       CommRegion->ThrottleActive = FALSE;                             // This allows new data FIBs to go to the adapter on dpc exit
6579 +
6580 +       OsSpinLockRelease(CommRegion->AdapNormCmdQue.QueueLock);
6581 +}
6582 +
6583 +#endif // #ifdef API_THROTTLE
6584 +
6585 +/*
6586 + * Overrides for Emacs so that we almost follow Linus's tabbing style.
6587 + * Emacs will notice this stuff at the end of the file and automatically
6588 + * adjust the settings for this buffer only.  This must remain at the end
6589 + * of the file.
6590 + * ---------------------------------------------------------------------------
6591 + * Local variables:
6592 + * c-indent-level: 4
6593 + * c-brace-imaginary-offset: 0
6594 + * c-brace-offset: -4
6595 + * c-argdecl-indent: 4
6596 + * c-label-offset: -4
6597 + * c-continued-statement-offset: 4
6598 + * c-continued-brace-offset: 0
6599 + * indent-tabs-mode: nil
6600 + * tab-width: 8
6601 + * End:
6602 + */
6603 diff -burN linux-2.4.4/drivers/scsi/aacraid/dpcsup.c linux/drivers/scsi/aacraid/dpcsup.c
6604 --- linux-2.4.4/drivers/scsi/aacraid/dpcsup.c   Wed Dec 31 18:00:00 1969
6605 +++ linux/drivers/scsi/aacraid/dpcsup.c Mon Apr 30 09:43:34 2001
6606 @@ -0,0 +1,443 @@
6607 +/*++
6608 + * Adaptec aacraid device driver for Linux.
6609 + *
6610 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
6611 + *
6612 + * This program is free software; you can redistribute it and/or modify
6613 + * it under the terms of the GNU General Public License as published by
6614 + * the Free Software Foundation; either version 2, or (at your option)
6615 + * any later version.
6616 + *
6617 + * This program is distributed in the hope that it will be useful,
6618 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
6619 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
6620 + * GNU General Public License for more details.
6621 + *
6622 + * You should have received a copy of the GNU General Public License
6623 + * along with this program; see the file COPYING.  If not, write to
6624 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
6625 + *
6626 + * Module Name:
6627 + *  dpcsup.c
6628 + *
6629 + * Abstract: All DPC processing routines for the cyclone board occur here.
6630 + *
6631 + *
6632 + --*/
6633 +
6634 +static char *ident_dpcsup = "aacraid_ident dpcsup.c 1.0.6 2000/10/09 Adaptec, Inc.";
6635 +
6636 +#include "comprocs.h"
6637 +
6638 +
6639 +//
6640 +//  The Bug check file id for this module
6641 +//
6642 +
6643 +#define BugCheckFileId                   (FSAFS_BUG_CHECK_DPCSUP)
6644 +
6645 +#define Dbg                              (DEBUG_TRACE_DPCSUP)
6646 +
6647 +u_int
6648 +CommonNotFullDpc(
6649 +       IN PCOMM_REGION CommRegion
6650 +    )
6651 +/*++
6652 +
6653 +Routine Description:
6654 +
6655 +    This DPC routine will be queued when the adapter interrupts us to let us know the queue is
6656 +    no longer full. The Isr will pass the queue that we will set the not full event.
6657 +
6658 +Arguments:
6659 +
6660 +    Dpc - Pointer to this routine.
6661 +
6662 +    Dummy - is a pointer to the comm region which is global so we don't need it anyway
6663 +
6664 +    Queue is a pointer to the queue structure we will operate on.
6665 +
6666 +    MoreData2 are DPC parameters we don't need for this function. Maybe we can add some accounting
6667 +        stuff in here.
6668 +
6669 +Return Value:
6670 +    Nothing.
6671 +
6672 +--*/
6673 +{
6674 +
6675 +#ifdef unix_queue_full
6676 +    KeSetEvent(&Queue->QueueFull, 0, FALSE);
6677 +#endif
6678 +
6679 +}
6680 +
6681 +int GatherFibTimes = 0;
6682 +
6683 +// XXX - hack this in until I figure out which header file should contain it. <smb>
6684 +extern ULONG
6685 +FibGetMeterSize(
6686 +    PFIB pFib,
6687 +       ULONG MeterType,
6688 +       char SubCommand
6689 +       );
6690 +
6691 +
6692 +/*++
6693 +
6694 +Routine Description:
6695 +
6696 +    This DPC routine will be queued when the adapter interrupts us to let us know there
6697 +    is a response on our normal priority queue. We will pull off all QE there are and wake
6698 +    up all the waiters before exiting. We will take a spinlock out on the queue before operating
6699 +    on it.
6700 +
6701 +Arguments:
6702 +
6703 +    Dpc - Pointer to this routine.
6704 +
6705 +    OurQueue is a pointer to the queue structure we will operate on.
6706 +
6707 +    MoreData1&2 are DPC parameters we don't need for this function. Maybe we can add some accounting
6708 +        stuff in here.
6709 +
6710 +Return Value:
6711 +    Nothing.
6712 +
6713 +--*/
6714 +u_int
6715 +HostResponseNormalDpc (IN PCOMM_QUE OurQueue)
6716 +{
6717 +    PAFA_COMM_ADAPTER Adapter = OurQueue->Adapter;
6718 +    PQUEUE_ENTRY QueueEntry;
6719 +    PFIB Fib;
6720 +       PCOMM_FIB_CONTEXT FibContext;
6721 +    int Consumed = 0;
6722 +       KIRQL OldIrql;
6723 +
6724 +       LARGE_INTEGER ResponseAllocSize;
6725 +
6726 +#ifdef commdebug
6727 +    FsaCommPrint("entering the host normal reponse dpc routine.\n");
6728 +#endif
6729 +
6730 +       OsSpinLockAcquire( OurQueue->QueueLock );       
6731 +
6732 +    //
6733 +    // Keep pulling response QEs off the response queue and waking
6734 +    // up the waiters until there are no more QEs. We then return
6735 +    // back to the system. If no response was requesed we just
6736 +    // deallocate the Fib here and continue.
6737 +    //
6738 +
6739 + loop:
6740 +    while ( GetConsumerEntry( Adapter, OurQueue, &QueueEntry) ) {
6741 +
6742 +               int IsFastResponse;
6743 +
6744 +               IsFastResponse = (int) (QueueEntry->FibAddress & 0x01);
6745 +               Fib = (PFIB) (QueueEntry->FibAddress & ~0x01);
6746 +
6747 +               FreeConsumerEntry(Adapter, OurQueue, HostNormRespQueue);
6748 +
6749 +               FibContext = (PCOMM_FIB_CONTEXT)Fib->Header.SenderData;
6750 +
6751 +               ASSERT(FibContext->Fib == Fib);
6752 +
6753 +               //
6754 +               // Remove this FibContext from the Outstanding I/O queue.
6755 +               // But only if it has not already been timed out.
6756 +               //
6757 +               // If the fib has been timed out already, then just continue.
6758 +               // The caller has already been notified that the fib timed out.
6759 +               //
6760 +
6761 +               if (!(FibContext->Flags & FIB_CONTEXT_FLAG_TIMED_OUT)) {
6762 +
6763 +                       RemoveEntryList( &FibContext->QueueEntry );
6764 +                       Adapter->CommRegion->AdapNormCmdQue.NumOutstandingIos--;
6765 +
6766 +               } else {
6767 +
6768 +                       FsaCommLogEvent(FibContext,
6769 +                                                       FsaCommData.DeviceObject, 
6770 +                                                       FSAFS_TIMED_OUT_FIB_COMPLETED,
6771 +                                                       STATUS_UNSUCCESSFUL, 
6772 +                                                       BugCheckFileId | __LINE__,
6773 +                                                       FACILITY_FSAFS_ERROR_CODE,
6774 +                                                       NULL,
6775 +                                                       TRUE);                  
6776 +
6777 +                       continue;
6778 +
6779 +               }
6780 +
6781 +               OsSpinLockRelease( OurQueue->QueueLock );
6782 +
6783 +               if (IsFastResponse) {
6784 +
6785 +                       //
6786 +                       // doctor the fib
6787 +                       //
6788 +
6789 +                       *(FSASTATUS *)Fib->data = ST_OK;
6790 +
6791 +                       Fib->Header.XferState |= AdapterProcessed;
6792 +
6793 +               }
6794 +
6795 +               ASSERT((Fib->Header.XferState & (AdapterProcessed | HostOwned | SentFromHost)) == (AdapterProcessed | HostOwned | SentFromHost));
6796 +
6797 +               FIB_COUNTER_INCREMENT(FsaCommData.FibRecved);
6798 +
6799 +               ASSERT(FsaCommData.FibsSent >= FsaCommData.FibRecved);
6800 +
6801 +
6802 +               if (Fib->Header.Command == NuFileSystem) {
6803 +
6804 +                       FSASTATUS *pStatus = (FSASTATUS *)Fib->data;
6805 +
6806 +                       if (*pStatus & 0xffff0000) {
6807 +
6808 +                               ULONG Hint = *pStatus;
6809 +
6810 +                               *pStatus = ST_OK;
6811 +
6812 +/*
6813 +                               DbgPrint("Replacing hint in fid (drive = %d, f1 = 0x%x, f2 = 0x%x, hint = 0x%x, new_hint = 0x%x)\n", 
6814 +                                                IrpContext->NonPaged->FileId.fid_driveno,
6815 +                                                IrpContext->NonPaged->FileId.fid_f1,
6816 +                                                IrpContext->NonPaged->FileId.fid_f2,
6817 +                                                IrpContext->NonPaged->FileId.fid_hint,
6818 +                                                Hint);
6819 +*/
6820 +
6821 +                       }
6822 +
6823 +               }
6824 +
6825 +               if (Fib->Header.XferState & (NoResponseExpected | Async) ) {
6826 +
6827 +                       ASSERT(FibContext->FibCallback);
6828 +
6829 +               if (Fib->Header.XferState & NoResponseExpected)
6830 +                               FIB_COUNTER_INCREMENT(FsaCommData.NoResponseRecved);
6831 +                       else 
6832 +                               FIB_COUNTER_INCREMENT(FsaCommData.AsyncRecved);
6833 +
6834 +                       //
6835 +                       // NOTE:  we can not touch the FibContext after this call, because it may have been
6836 +                       // deallocated.
6837 +                       //
6838 +
6839 +                       FibContext->FibCallback(FibContext->FibCallbackContext, FibContext, STATUS_SUCCESS);
6840 +
6841 +               } else {
6842 +
6843 +                       OsCvLockAcquire( FibContext->FsaEventMutex);
6844 +
6845 +                       FibContext->FibComplete = 1;
6846 +
6847 +                       OsCv_signal( &FibContext->FsaEvent );
6848 +
6849 +                       OsCvLockRelease( FibContext->FsaEventMutex );
6850 +
6851 +                       FIB_COUNTER_INCREMENT(FsaCommData.NormalRecved);
6852 +                       
6853 +               }
6854 +
6855 +
6856 +               Consumed++;
6857 +
6858 +               OsSpinLockAcquire( OurQueue->QueueLock );
6859 +               
6860 +    }
6861 +
6862 +       if (Consumed > FsaCommData.PeakFibsConsumed)
6863 +               FsaCommData.PeakFibsConsumed = Consumed;
6864 +
6865 +       if (Consumed == 0) 
6866 +               FsaCommData.ZeroFibsConsumed++;
6867 +
6868 +       if (FsaCommData.HardInterruptModeration) {
6869 +
6870 +               //
6871 +               // Re-Enable the interrupt from the adapter, then recheck to see if anything has 
6872 +               // been put on the queue.  This removes the race condition that exists between the
6873 +               // last time we checked the queue, and when we re-enabled the interrupt.
6874 +               //
6875 +               // If there is something on the queue, then go handle it.
6876 +               //
6877 +
6878 +               EnableInterrupt( Adapter, HostNormRespQue, FALSE );
6879 +
6880 +               if (ConsumerEntryAvailable( Adapter, OurQueue ) ) {
6881 +
6882 +                       DisableInterrupt( Adapter, HostNormRespQue, FALSE );
6883 +
6884 +                       goto loop;
6885 +
6886 +               }
6887 +       }
6888 +
6889 +#ifdef commdebug
6890 +    FsaCommPrint("Exiting host normal reponse dpc routine after consuming %d QE(s).\n",Consumed);
6891 +#endif
6892 +
6893 +       OsSpinLockRelease( OurQueue->QueueLock );
6894 +
6895 +}
6896 +
6897 +/*++
6898 +
6899 +Routine Description:
6900 +
6901 +    This DPC routine wiol be queued when the adapter interrupts us to let us know there
6902 +    is a response on our high priority queue. We will pull off all QE there are and wake
6903 +    up all the waiters before exiting. We will take a spinlock out on the queue before operating
6904 +    on it.
6905 +
6906 +Arguments:
6907 +
6908 +    Dpc - Pointer to this routine.
6909 +
6910 +    OurQueue is a pointer to the queue structure we will operate on.
6911 +
6912 +    MoreData1&2 are DPC parameters we don't need for this function. Maybe we can add some accounting
6913 +        stuff in here.
6914 +
6915 +Return Value:
6916 +    Nothing.
6917 +
6918 +--*/
6919 +u_int
6920 +HostResponseHighDpc (IN PCOMM_QUE OurQueue)
6921 +{}
6922 +
6923 +
6924 +/*++
6925 +
6926 +Routine Description:
6927 +
6928 +    This DPC routine will be queued when the adapter interrupts us to let us know there
6929 +    is a command on our high priority queue. We will pull off all QE there are and wake
6930 +    up all the waiters before exiting. We will take a spinlock out on the queue before operating
6931 +    on it.
6932 +
6933 +Arguments:
6934 +
6935 +    Dpc - Pointer to this routine.
6936 +
6937 +    OurQueue is a pointer to the queue structure we will operate on.
6938 +
6939 +    MoreData1&2 are DPC parameters we don't need for this function. Maybe we can add some accounting
6940 +        stuff in here.
6941 +
6942 +Return Value:
6943 +    Nothing.
6944 +
6945 +--*/
6946 +u_int
6947 +HostCommandHighDpc (IN PCOMM_QUE OurQueue)
6948 +{}
6949 +
6950 +
6951 +/*++
6952 +
6953 +Routine Description:
6954 +
6955 +    This DPC routine will be queued when the adapter interrupts us to let us know there
6956 +    is a command on our normal priority queue. We will pull off all QE there are and wake
6957 +    up all the waiters before exiting. We will take a spinlock out on the queue before operating
6958 +    on it.
6959 +
6960 +Arguments:
6961 +
6962 +    Dpc - Pointer to this routine.
6963 +
6964 +    OurQueue is a pointer to the queue structure we will operate on.
6965 +
6966 +    MoreData1&2 are DPC parameters we don't need for this function. Maybe we can add some accounting
6967 +        stuff in here.
6968 +
6969 +Return Value:
6970 +    Nothing.
6971 +
6972 +--*/
6973 +u_int
6974 +HostCommandNormDpc (IN PCOMM_QUE OurQueue)
6975 +{
6976 +    PAFA_COMM_ADAPTER Adapter = OurQueue->Adapter;
6977 +    PQUEUE_ENTRY QueueEntry;
6978 +
6979 +       OsSpinLockAcquire( OurQueue->QueueLock );
6980 +
6981 +    //
6982 +    // Keep pulling response QEs off the response queue and waking
6983 +    // up the waiters until there are no more QEs. We then return
6984 +    // back to the system.
6985 +    //
6986 +
6987 +    while ( GetConsumerEntry( Adapter, OurQueue, &QueueEntry) ) {
6988 +
6989 +               PFIB Fib;
6990 +
6991 +               Fib = (PFIB)QueueEntry->FibAddress;
6992 +
6993 +
6994 +               if (Adapter->AifThreadStarted) {
6995 +
6996 +
6997 +//                     cmn_err(CE_CONT, "^Received AIF, putting onto command queue\n");
6998 +
6999 +
7000 +               InsertTailList(&OurQueue->CommandQueue, &Fib->Header.FibLinks);
7001 +               FreeConsumerEntry(Adapter, OurQueue, HostNormCmdQueue);
7002 +               OsCv_signal(&OurQueue->CommandReady);
7003 +
7004 +
7005 +
7006 +               } else {
7007 +
7008 +
7009 +
7010 +                       COMM_FIB_CONTEXT FibContext;
7011 +
7012 +               
7013 +
7014 +               FreeConsumerEntry(Adapter, OurQueue, HostNormCmdQueue);
7015 +
7016 +
7017 +
7018 +                       OsSpinLockRelease( OurQueue->QueueLock );
7019 +
7020 +
7021 +
7022 +//                     cmn_err(CE_CONT, "^Received AIF, thread not started\n");
7023 +
7024 +
7025 +                       RtlZeroMemory( &FibContext, sizeof(COMM_FIB_CONTEXT) );
7026 +
7027 +                   FibContext.NodeTypeCode = FSAFS_NTC_FIB_CONTEXT;
7028 +                   FibContext.NodeByteSize = sizeof( COMM_FIB_CONTEXT );
7029 +                       FibContext.Fib = Fib;
7030 +                       FibContext.FibData = Fib->data;
7031 +                       FibContext.Adapter = Adapter;
7032 +
7033 +                       //
7034 +                       // Set the status of this FIB
7035 +                       //
7036 +
7037 +                       *(FSASTATUS *)Fib->data = ST_OK;
7038 +                               
7039 +                       CompleteAdapterFib( &FibContext, sizeof(FSASTATUS) );
7040 +
7041 +
7042 +
7043 +                       OsSpinLockAcquire( OurQueue->QueueLock );
7044 +               }               
7045 +    }
7046 +
7047 +       OsSpinLockRelease( OurQueue->QueueLock );
7048 +
7049 +}
7050 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/AacGenericTypes.h linux/drivers/scsi/aacraid/include/AacGenericTypes.h
7051 --- linux-2.4.4/drivers/scsi/aacraid/include/AacGenericTypes.h  Wed Dec 31 18:00:00 1969
7052 +++ linux/drivers/scsi/aacraid/include/AacGenericTypes.h        Mon Apr 30 09:43:34 2001
7053 @@ -0,0 +1,57 @@
7054 +/*++
7055 + * Adaptec aacraid device driver for Linux.
7056 + *
7057 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
7058 + *
7059 + * This program is free software; you can redistribute it and/or modify
7060 + * it under the terms of the GNU General Public License as published by
7061 + * the Free Software Foundation; either version 2, or (at your option)
7062 + * any later version.
7063 + *
7064 + * This program is distributed in the hope that it will be useful,
7065 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7066 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
7067 + * GNU General Public License for more details.
7068 + *
7069 + * You should have received a copy of the GNU General Public License
7070 + * along with this program; see the file COPYING.  If not, write to
7071 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
7072 + *
7073 + * Module Name:
7074 + *
7075 + *  AacGenericTypes.h
7076 + *
7077 + * Abstract:
7078 + *
7079 + *     The module defines the generic data types that all of the other header files
7080 + *     depend upon.
7081 + --*/
7082 +
7083 +#ifndef _AAC_GENERIC_TYPES
7084 +#define _AAC_GENERIC_TYPES
7085 +
7086 +static char *ident_AacGeneric = "aacraid_ident AacGenericTypes.h 1.0.6 2000/10/09 Adaptec, Inc.";
7087 +
7088 +typedef        char                    AAC_INT8, *PAAC_INT8;
7089 +typedef short                  AAC_INT16, *PAAC_INT16;
7090 +typedef int                    AAC_INT32, *PAAC_INT32;
7091 +typedef long long              AAC_INT64, *PAAC_INT64;
7092 +
7093 +typedef unsigned char  AAC_UINT8, *PAAC_UINT8;
7094 +typedef unsigned short AAC_UINT16, *PAAC_UINT16;
7095 +typedef unsigned int   AAC_UINT32, *PAAC_UINT32;
7096 +typedef unsigned long long     AAC_UINT64, *PAAC_UINT64;
7097 +
7098 +typedef void                   AAC_VOID, *PAAC_VOID;
7099 +
7100 +//
7101 +// this compiler uses 32 bit enum data types
7102 +//
7103 +
7104 +#define        AAC_32BIT_ENUMS 1
7105 +#define FAILURE 1
7106 +#define INTR_UNCLAIMED 1
7107 +#define INTR_CLAIMED 0
7108 +
7109 +#endif // _AAC_GENERIC_TYPES
7110 +
7111 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/aac_unix_defs.h linux/drivers/scsi/aacraid/include/aac_unix_defs.h
7112 --- linux-2.4.4/drivers/scsi/aacraid/include/aac_unix_defs.h    Wed Dec 31 18:00:00 1969
7113 +++ linux/drivers/scsi/aacraid/include/aac_unix_defs.h  Mon Apr 30 09:43:34 2001
7114 @@ -0,0 +1,300 @@
7115 +/*++
7116 + * Adaptec aacraid device driver for Linux.
7117 + *
7118 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
7119 + *
7120 + * This program is free software; you can redistribute it and/or modify
7121 + * it under the terms of the GNU General Public License as published by
7122 + * the Free Software Foundation; either version 2, or (at your option)
7123 + * any later version.
7124 + *
7125 + * This program is distributed in the hope that it will be useful,
7126 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7127 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
7128 + * GNU General Public License for more details.
7129 + *
7130 + * You should have received a copy of the GNU General Public License
7131 + * along with this program; see the file COPYING.  If not, write to
7132 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
7133 + *
7134 + * Module Name:
7135 + *
7136 + *  aac_unix_defs.h
7137 + *
7138 + * Abstract:
7139 + *
7140 + *     Macro definition and typedefs
7141 + *
7142 + --*/
7143 +
7144 +#ifndef _AAC_UNIX_DEFS
7145 +#define _AAC_UNIX_DEFS
7146 +
7147 +static char *ident_aac_unix = "aacraid_ident aac_unix_defs.h 1.0.6 2000/10/09 Adaptec, Inc.";
7148 +
7149 +#define        AAC_MAX_ADAPTERS        64
7150 +
7151 +#ifndef        TRUE
7152 +#define TRUE   1
7153 +#define FALSE  0
7154 +#endif
7155 +
7156 +#define PAGE_SIZE      4096
7157 +
7158 +typedef        void    VOID;
7159 +typedef VOID   *PVOID;
7160 +
7161 +typedef char           CHAR, *PCHAR;
7162 +typedef unsigned char  UCHAR, *PUCHAR;
7163 +typedef short          SHORT, *PSHORT;
7164 +typedef short          CSHORT, *PCSHORT;
7165 +typedef unsigned short         USHORT, *PUSHORT;
7166 +typedef unsigned long  ULONG, *PULONG;
7167 +typedef long           LONG, *PLONG;
7168 +
7169 +typedef unsigned long  BOOLEAN;
7170 +
7171 +typedef unsigned long  AAC_STATUS, *PNT_STATUS;
7172 +
7173 +typedef struct {
7174 +       unsigned long   LowPart;
7175 +       unsigned long   HighPart;
7176 +} LARGE_INTEGER;
7177 +
7178 +typedef LARGE_INTEGER  PHYSICAL_ADDRESS;
7179 +
7180 +
7181 +typedef struct _AFA_IOCTL_CMD {
7182 +       int             cmd;
7183 +       intptr_t        arg;
7184 +       int             flag;
7185 +       cred_t          *cred_p;
7186 +       int             *rval_p;
7187 +} AFA_IOCTL_CMD, *PAFA_IOCTL_CMD;
7188 +
7189 +
7190 +//
7191 +//  Singly linked list structure. Can be used as either a list head, or
7192 +//  as link words.
7193 +//
7194 +
7195 +typedef struct _SINGLE_LIST_ENTRY {
7196 +    struct _SINGLE_LIST_ENTRY *Next;
7197 +} SINGLE_LIST_ENTRY, *PSINGLE_LIST_ENTRY;
7198 +
7199 +
7200 +//
7201 +// Calculate the address of the base of the structure given its type, and an
7202 +// address of a field within the structure.
7203 +//
7204 +
7205 +#define CONTAINING_RECORD(address, type, field) ((type *)( \
7206 +                                                  (PCHAR)(address) - \
7207 +                                                  (PCHAR)(&((type *)0)->field)))
7208 +
7209 +typedef        PVOID   PMDL;
7210 +typedef PVOID  PDEVICE_OBJECT;
7211 +typedef PVOID  PADAPTER_OBJECT;
7212 +typedef ULONG  KIRQL;
7213 +typedef PVOID  HANDLE;
7214 +typedef PVOID  KDPC, *PKDPC;
7215 +typedef PVOID  PFILE_OBJECT;
7216 +typedef PVOID  PIRP;
7217 +typedef PVOID  PDRIVER_OBJECT;
7218 +typedef ULONG  KTIMER;
7219 +
7220 +
7221 +#define        STATUS_SUCCESS          0x00000000
7222 +#define STATUS_PENDING         0x40000001
7223 +#define STATUS_IO_TIMEOUT                      0xc0000001
7224 +#define STATUS_UNSUCCESSFUL                    0xc0000002
7225 +#define STATUS_INSUFFICIENT_RESOURCES  0xc0000005
7226 +#define STATUS_BUFFER_OVERFLOW         0xc0000003
7227 +
7228 +
7229 +#define OUT
7230 +
7231 +
7232 +
7233 +typedef u_int
7234 +(*PUNIX_INTR_HANDLER)(caddr_t Arg);
7235 +
7236 +//
7237 +// Zone Allocation
7238 +//
7239 +
7240 +typedef struct _ZONE_SEGMENT_HEADER {
7241 +    SINGLE_LIST_ENTRY SegmentList;
7242 +    PVOID Reserved;
7243 +} ZONE_SEGMENT_HEADER, *PZONE_SEGMENT_HEADER;
7244 +
7245 +typedef struct _ZONE_HEADER {
7246 +    SINGLE_LIST_ENTRY FreeList;
7247 +    SINGLE_LIST_ENTRY SegmentList;
7248 +    ULONG BlockSize;
7249 +    ULONG TotalSegmentSize;
7250 +} ZONE_HEADER, *PZONE_HEADER;
7251 +
7252 +
7253 +//++
7254 +//
7255 +// PVOID
7256 +// ExAllocateFromZone(
7257 +//     IN PZONE_HEADER Zone
7258 +//     )
7259 +//
7260 +// Routine Description:
7261 +//
7262 +//     This routine removes an entry from the zone and returns a pointer to it.
7263 +//
7264 +// Arguments:
7265 +//
7266 +//     Zone - Pointer to the zone header controlling the storage from which the
7267 +//         entry is to be allocated.
7268 +//
7269 +// Return Value:
7270 +//
7271 +//     The function value is a pointer to the storage allocated from the zone.
7272 +//
7273 +//--
7274 +
7275 +#define ExAllocateFromZone(Zone) \
7276 +    (PVOID)((Zone)->FreeList.Next); \
7277 +    if ( (Zone)->FreeList.Next ) (Zone)->FreeList.Next = (Zone)->FreeList.Next->Next
7278 +
7279 +//++
7280 +//
7281 +// PVOID
7282 +// ExFreeToZone(
7283 +//     IN PZONE_HEADER Zone,
7284 +//     IN PVOID Block
7285 +//     )
7286 +//
7287 +// Routine Description:
7288 +//
7289 +//     This routine places the specified block of storage back onto the free
7290 +//     list in the specified zone.
7291 +//
7292 +// Arguments:
7293 +//
7294 +//     Zone - Pointer to the zone header controlling the storage to which the
7295 +//         entry is to be inserted.
7296 +//
7297 +//     Block - Pointer to the block of storage to be freed back to the zone.
7298 +//
7299 +// Return Value:
7300 +//
7301 +//     Pointer to previous block of storage that was at the head of the free
7302 +//         list.  NULL implies the zone went from no available free blocks to
7303 +//         at least one free block.
7304 +//
7305 +//--
7306 +
7307 +#define ExFreeToZone(Zone,Block)                                    \
7308 +    ( ((PSINGLE_LIST_ENTRY)(Block))->Next = (Zone)->FreeList.Next,  \
7309 +      (Zone)->FreeList.Next = ((PSINGLE_LIST_ENTRY)(Block)),        \
7310 +      ((PSINGLE_LIST_ENTRY)(Block))->Next                           \
7311 +    )
7312 +
7313 +//++
7314 +//
7315 +// BOOLEAN
7316 +// ExIsFullZone(
7317 +//     IN PZONE_HEADER Zone
7318 +//     )
7319 +//
7320 +// Routine Description:
7321 +//
7322 +//     This routine determines if the specified zone is full or not.  A zone
7323 +//     is considered full if the free list is empty.
7324 +//
7325 +// Arguments:
7326 +//
7327 +//     Zone - Pointer to the zone header to be tested.
7328 +//
7329 +// Return Value:
7330 +//
7331 +//     TRUE if the zone is full and FALSE otherwise.
7332 +//
7333 +//--
7334 +
7335 +#define ExIsFullZone(Zone) \
7336 +    ( (Zone)->FreeList.Next == (PSINGLE_LIST_ENTRY)NULL )
7337 +
7338 +
7339 +#define RtlCopyMemory( Destination, Source, Size )     bcopy( (Source), (Destination), (Size) )
7340 +#define RtlZeroMemory( Destination, Size )                     bzero( (Destination), (Size) )
7341 +
7342 +//
7343 +//  Doubly-linked list manipulation routines.  Implemented as macros
7344 +//  but logically these are procedures.
7345 +//
7346 +
7347 +//
7348 +//  VOID
7349 +//  InitializeListHead(
7350 +//      PLIST_ENTRY ListHead
7351 +//      );
7352 +//
7353 +
7354 +#define InitializeListHead(ListHead) (\
7355 +    (ListHead)->Flink = (ListHead)->Blink = (ListHead))
7356 +
7357 +//
7358 +//  BOOLEAN
7359 +//  IsListEmpty(
7360 +//      PLIST_ENTRY ListHead
7361 +//      );
7362 +//
7363 +
7364 +#define IsListEmpty(ListHead) \
7365 +    ((ListHead)->Flink == (ListHead))
7366 +
7367 +//
7368 +//  PLIST_ENTRY
7369 +//  RemoveHeadList(
7370 +//      PLIST_ENTRY ListHead
7371 +//      );
7372 +//
7373 +
7374 +#define RemoveHeadList(ListHead) \
7375 +    (ListHead)->Flink;\
7376 +    {RemoveEntryList((ListHead)->Flink)}
7377 +
7378 +
7379 +//
7380 +//  VOID
7381 +//  RemoveEntryList(
7382 +//      PLIST_ENTRY Entry
7383 +//      );
7384 +//
7385 +
7386 +#define RemoveEntryList(Entry) {\
7387 +    PLIST_ENTRY _EX_Blink;\
7388 +    PLIST_ENTRY _EX_Flink;\
7389 +    _EX_Flink = (Entry)->Flink;\
7390 +    _EX_Blink = (Entry)->Blink;\
7391 +    _EX_Blink->Flink = _EX_Flink;\
7392 +    _EX_Flink->Blink = _EX_Blink;\
7393 +    }
7394 +
7395 +//
7396 +//  VOID
7397 +//  InsertTailList(
7398 +//      PLIST_ENTRY ListHead,
7399 +//      PLIST_ENTRY Entry
7400 +//      );
7401 +//
7402 +
7403 +#define InsertTailList(ListHead,Entry) {\
7404 +    PLIST_ENTRY _EX_Blink;\
7405 +    PLIST_ENTRY _EX_ListHead;\
7406 +    _EX_ListHead = (ListHead);\
7407 +    _EX_Blink = _EX_ListHead->Blink;\
7408 +    (Entry)->Flink = _EX_ListHead;\
7409 +    (Entry)->Blink = _EX_Blink;\
7410 +    _EX_Blink->Flink = (Entry);\
7411 +    _EX_ListHead->Blink = (Entry);\
7412 +    }
7413 +
7414 +#endif /* AAC_UNIX_DEFS */
7415 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/adapter.h linux/drivers/scsi/aacraid/include/adapter.h
7416 --- linux-2.4.4/drivers/scsi/aacraid/include/adapter.h  Wed Dec 31 18:00:00 1969
7417 +++ linux/drivers/scsi/aacraid/include/adapter.h        Mon Apr 30 09:43:34 2001
7418 @@ -0,0 +1,164 @@
7419 +/*++
7420 + * Adaptec aacraid device driver for Linux.
7421 + *
7422 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
7423 + *
7424 + * This program is free software; you can redistribute it and/or modify
7425 + * it under the terms of the GNU General Public License as published by
7426 + * the Free Software Foundation; either version 2, or (at your option)
7427 + * any later version.
7428 + *
7429 + * This program is distributed in the hope that it will be useful,
7430 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7431 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
7432 + * GNU General Public License for more details.
7433 + *
7434 + * You should have received a copy of the GNU General Public License
7435 + * along with this program; see the file COPYING.  If not, write to
7436 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
7437 + *
7438 + * Module Name:
7439 + *
7440 + *   Adapter.h
7441 + *
7442 + * Abstract:
7443 + *   The module contains the definitions for a comm layer view of the adapter.
7444 + *
7445 + *
7446 + *
7447 + --*/
7448 +
7449 +#ifndef _ADAPTER_
7450 +#define _ADAPTER_
7451 +
7452 +static char *ident_adapter = "aacraid_ident adapter.h 1.0.6 2000/10/09 Adaptec, Inc.";
7453 +
7454 +typedef struct _GET_ADAPTER_FIB_CONTEXT {
7455 +
7456 +       NODE_TYPE_CODE          NodeTypeCode;   // used for verification of structure   
7457 +       NODE_BYTE_SIZE          NodeByteSize;
7458 +       PFILE_OBJECT            FileObject;     // used for cleanup
7459 +       LIST_ENTRY              NextContext;    // used to link context's into a linked list
7460 +       OS_CV_T                 UserEvent;      // this is used to wait for the next fib to arrive.
7461 +       BOOLEAN                 WaitingForFib;  // Set to true when thread is in WaitForSingleObject
7462 +       ULONG                   FibCount;       // total number of FIBs on FibList
7463 +       LIST_ENTRY              FibList;
7464 +} GET_ADAPTER_FIB_CONTEXT;
7465 +typedef GET_ADAPTER_FIB_CONTEXT *PGET_ADAPTER_FIB_CONTEXT;
7466 +
7467 +
7468 +typedef struct _FIB_CONTEXT_ZONE_SEGMENT {
7469 +
7470 +       struct _FIB_CONTEXT_ZONE_SEGMENT        *Next;
7471 +       ULONG                                   FibContextSegmentSize;
7472 +       PVOID                                   FibContextSegment;
7473 +       ULONG                                   ExtendSize;
7474 +       MAPFIB_CONTEXT                          MapFibContext;
7475 +
7476 +} FIB_CONTEXT_ZONE_SEGMENT;
7477 +typedef FIB_CONTEXT_ZONE_SEGMENT *PFIB_CONTEXT_ZONE_SEGMENT;
7478 +
7479 +typedef struct _AFA_COMM_ADAPTER {
7480 +
7481 +       struct _AFA_COMM_ADAPTER        *NextAdapter;
7482 +
7483 +    //
7484 +    //  The following fields are used to allocate FIB context structures
7485 +    //  using the zone allocator, and other fixed sized structures from a
7486 +    //  small cache.  The mutex protects access to the zone/lists
7487 +    //
7488 +
7489 +    ZONE_HEADER                FibContextZone;
7490 +       OS_SPINLOCK                     *FibContextZoneSpinLock;
7491 +       int                             FibContextZoneExtendSize;
7492 +
7493 +       PFIB_CONTEXT_ZONE_SEGMENT       FibContextSegmentList;
7494 +
7495 +       PVOID                           FibContextTimedOutList;
7496 +
7497 +       PFIB                            SyncFib;
7498 +       ULONG                           SyncFibPhysicalAddress;
7499 +
7500 +       PCOMM_REGION            CommRegion;
7501 +
7502 +       OS_SPINLOCK_COOKIE      SpinLockCookie;
7503 +
7504 +       //
7505 +       // The user API will use an IOCTL to register itself to receive FIBs
7506 +       // from the adapter.  The following list is used to keep track of all
7507 +       // the threads that have requested these FIBs.  The mutex is used to 
7508 +       // synchronize access to all data associated with the adapter fibs.
7509 +       //
7510 +       LIST_ENTRY                      AdapterFibContextList;
7511 +       OS_CVLOCK                       *AdapterFibMutex;
7512 +
7513 +       //
7514 +       // The following holds which FileObject is allow to send configuration
7515 +       // commands to the adapter that would modify the configuration.
7516 +       //
7517 +       // This is controlled by the FSACTL_OPEN_ADAPTER_CONFIG and FSACTL_CLOSE_ADAPTER_CONFIG
7518 +       // ioctls.
7519 +       //
7520 +       PFILE_OBJECT            AdapterConfigFileObject;
7521 +
7522 +       //
7523 +       // The following is really here because of the simulator
7524 +       //
7525 +       BOOLEAN                         InterruptsBelowDpc;
7526 +
7527 +       //
7528 +       // The following is the device specific extension.
7529 +       //
7530 +       PVOID                   AdapterExtension;       
7531 +       PFSAPORT_FUNCS          AdapterFuncs;
7532 +       void                    *Dip;
7533 +
7534 +       //
7535 +       // The following are user variables that are specific to the mini port.
7536 +       //
7537 +       PFSA_USER_VAR           AdapterUserVars;
7538 +       ULONG                   AdapterUserVarsSize;
7539 +
7540 +       //
7541 +       // The following is the number of the individual adapter..i.e. \Device\Afa0
7542 +       //
7543 +       LONG                    AdapterNumber;
7544 +
7545 +       AFACOMM_FUNCS           CommFuncs;
7546 +
7547 +       PAFA_CLASS_DRIVER       ClassDriverList;
7548 +
7549 +       BOOLEAN                 AifThreadStarted;
7550 +
7551 +} AFA_COMM_ADAPTER;
7552 +
7553 +typedef AFA_COMM_ADAPTER *PAFA_COMM_ADAPTER;
7554 +
7555 +
7556 +#define FsaAllocateAdapterCommArea(Adapter, BaseAddress, Size, Alignment) \
7557 +       Adapter->AdapterFuncs->AllocateAdapterCommArea(Adapter->AdapterExtension, BaseAddress, Size, Alignment)
7558 +
7559 +#define FsaFreeAdapterCommArea(Adapter) \
7560 +       Adapter->AdapterFuncs->FreeAdapterCommArea(Adapter->AdapterExtension)
7561 +
7562 +
7563 +#define AllocateAndMapFibSpace(Adapter, MapFibContext) \
7564 +       Adapter->AdapterFuncs->AllocateAndMapFibSpace(Adapter->AdapterExtension, MapFibContext)
7565 +
7566 +#define UnmapAndFreeFibSpace(Adapter, MapFibContext) \
7567 +       Adapter->AdapterFuncs->UnmapAndFreeFibSpace(Adapter->AdapterExtension, MapFibContext)
7568 +
7569 +#define InterruptAdapter(Adapter) \
7570 +       Adapter->AdapterFuncs->InterruptAdapter(Adapter->AdapterExtension)
7571 +
7572 +#define NotifyAdapter(Adapter, AdapterEvent) \
7573 +       Adapter->AdapterFuncs->NotifyAdapter(Adapter->AdapterExtension, AdapterEvent)
7574 +
7575 +#define EnableInterrupt(Adapter, AdapterEvent, AtDeviceIrq) \
7576 +       Adapter->AdapterFuncs->EnableInterrupt(Adapter->AdapterExtension, AdapterEvent, AtDeviceIrq)
7577 +
7578 +#define DisableInterrupt(Adapter, AdapterEvent, AtDeviceIrq) \
7579 +       Adapter->AdapterFuncs->DisableInterrupt(Adapter->AdapterExtension, AdapterEvent, AtDeviceIrq)
7580 +
7581 +
7582 +#endif // _ADAPTER_
7583 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/afacomm.h linux/drivers/scsi/aacraid/include/afacomm.h
7584 --- linux-2.4.4/drivers/scsi/aacraid/include/afacomm.h  Wed Dec 31 18:00:00 1969
7585 +++ linux/drivers/scsi/aacraid/include/afacomm.h        Mon Apr 30 09:43:34 2001
7586 @@ -0,0 +1,191 @@
7587 +/*++
7588 + * Adaptec aacraid device driver for Linux.
7589 + *
7590 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
7591 + *
7592 + * This program is free software; you can redistribute it and/or modify
7593 + * it under the terms of the GNU General Public License as published by
7594 + * the Free Software Foundation; either version 2, or (at your option)
7595 + * any later version.
7596 + *
7597 + * This program is distributed in the hope that it will be useful,
7598 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7599 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
7600 + * GNU General Public License for more details.
7601 + *
7602 + * You should have received a copy of the GNU General Public License
7603 + * along with this program; see the file COPYING.  If not, write to
7604 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
7605 + *
7606 + * Module Name:
7607 + *   AfaComm.h
7608 + *
7609 + * Abstract:
7610 + *   This module defines all of the external interfaces to the AFA comm layer.
7611 + *
7612 + *
7613 + *
7614 + --*/
7615 +#ifndef _AFACOMM_
7616 +#define _AFACOMM_
7617 +
7618 +static char *ident_afacomm = "aacraid_ident afacomm.h 1.0.6 2000/10/09 Adaptec, Inc.";
7619 +
7620 +#include "fsaport.h"
7621 +
7622 +typedef void   *PFIB_CONTEXT;
7623 +
7624 +typedef VOID
7625 +(*PFIB_CALLBACK)(
7626 +       PVOID           FibCallbackContext,
7627 +       PFIB_CONTEXT    FibContext,
7628 +       AAC_STATUS      Status
7629 +       );
7630 +
7631 +
7632 +typedef PFIB_CONTEXT
7633 +(*PAFA_COMM_ALLOCATE_FIB) (
7634 +       IN PVOID AdapterExtension
7635 +    );
7636 +
7637 +typedef VOID
7638 +(*PAFA_COMM_FREE_FIB) (
7639 +    IN PFIB_CONTEXT FibContext
7640 +    );
7641 +
7642 +
7643 +typedef AAC_STATUS
7644 +(*PAFA_COMM_DEALLOCATE_FIB) (
7645 +    IN PFIB_CONTEXT FibContext
7646 +    );
7647 +
7648 +
7649 +typedef VOID
7650 +(*PAFA_COMM_FREE_FIB_FROM_DPC) (
7651 +    IN PFIB_CONTEXT FibContext
7652 +    );
7653 +
7654 +typedef AAC_STATUS
7655 +(*PAFA_COMM_INITIALIZE_FIB) (
7656 +       IN PFIB_CONTEXT FibContext
7657 +    );
7658 +
7659 +typedef PVOID
7660 +(*PAFA_COMM_GET_FIB_DATA) (
7661 +       IN PFIB_CONTEXT FibContext
7662 +       );
7663 +
7664 +typedef AAC_STATUS
7665 +(*PAFA_COMM_SEND_FIB) (
7666 +    IN FIB_COMMAND Command, 
7667 +       IN PFIB_CONTEXT FibContext,
7668 +    IN ULONG Size,
7669 +    IN COMM_PRIORITIES Priority,
7670 +    IN BOOLEAN Wait,
7671 +    IN PVOID WaitOn,
7672 +    IN BOOLEAN ResponseExpected,
7673 +       IN PFIB_CALLBACK FibCallback,
7674 +       IN PVOID FibCallbackContext
7675 +    );
7676 +
7677 +typedef AAC_STATUS
7678 +(*PAFA_COMM_COMPLETE_FIB) (
7679 +       IN PFIB_CONTEXT FibContext
7680 +    );
7681 +
7682 +typedef AAC_STATUS
7683 +(*PAFA_COMM_COMPLETE_ADAPTER_FIB) (
7684 +       IN PFIB_CONTEXT FibContext,
7685 +       IN USHORT Size
7686 +    );
7687 +
7688 +typedef BOOLEAN
7689 +(*PAFA_COMM_SEND_SYNCH_FIB) (
7690 +       PVOID                   AdapterExtension,
7691 +       FIB_COMMAND     Command,
7692 +       PVOID                   Data,
7693 +       USHORT                  Size,
7694 +       PVOID                   Response,
7695 +       USHORT                  *ResponseSize
7696 +       );
7697 +
7698 +
7699 +typedef struct _AFACOMM_FUNCS {
7700 +       ULONG                                   SizeOfAfaCommFuncs;
7701 +       PAFA_COMM_ALLOCATE_FIB                  AllocateFib;
7702 +       PAFA_COMM_FREE_FIB                      FreeFib;
7703 +       PAFA_COMM_FREE_FIB_FROM_DPC             FreeFibFromDpc;
7704 +       PAFA_COMM_DEALLOCATE_FIB                DeallocateFib;
7705 +       PAFA_COMM_INITIALIZE_FIB                InitializeFib;
7706 +       PAFA_COMM_GET_FIB_DATA                  GetFibData;
7707 +       PAFA_COMM_SEND_FIB                      SendFib;
7708 +       PAFA_COMM_COMPLETE_FIB                  CompleteFib;
7709 +       PAFA_COMM_COMPLETE_ADAPTER_FIB          CompleteAdapterFib;
7710 +       PAFA_COMM_SEND_SYNCH_FIB                SendSynchFib;
7711 +       PFSA_FREE_DMA_RESOURCES                 FreeDmaResources;
7712 +       PFSA_BUILD_SGMAP                        BuildSgMap;
7713 +       PFSA_ADAPTER_ADDR_TO_SYSTEM_ADDR        AdapterAddressToSystemAddress;
7714 +} AFACOMM_FUNCS;
7715 +typedef AFACOMM_FUNCS *PAFACOMM_FUNCS;
7716 +
7717 +
7718 +typedef AAC_STATUS
7719 +(*PAFA_CLASS_OPEN_ADAPTER) (
7720 +       IN PVOID Adapter
7721 +       );
7722 +
7723 +
7724 +typedef AAC_STATUS
7725 +(*PAFA_CLASS_CLOSE_ADAPTER) (
7726 +       IN PVOID Adapter
7727 +       );
7728 +
7729 +
7730 +typedef BOOLEAN
7731 +(*PAFA_CLASS_DEV_CONTROL) (
7732 +       IN PVOID Adapter,
7733 +       IN PAFA_IOCTL_CMD       IoctlCmdPtr,
7734 +       OUT int * Status
7735 +       );
7736 +
7737 +typedef BOOLEAN
7738 +(*PAFA_CLASS_HANDLE_AIF) (
7739 +       IN PVOID Adapter,
7740 +       IN PFIB_CONTEXT FibContext
7741 +       );
7742 +
7743 +
7744 +typedef struct _AFA_NEW_CLASS_DRIVER {
7745 +       PVOID                           ClassDriverExtension;
7746 +       PAFA_CLASS_OPEN_ADAPTER         OpenAdapter;
7747 +        PAFA_CLASS_CLOSE_ADAPTER       CloseAdapter;
7748 +        PAFA_CLASS_DEV_CONTROL                 DeviceControl;
7749 +       PAFA_CLASS_HANDLE_AIF           HandleAif;
7750 +       PFSA_USER_VAR                   UserVars;
7751 +       ULONG                           NumUserVars;
7752 +} AFA_NEW_CLASS_DRIVER;
7753 +typedef AFA_NEW_CLASS_DRIVER *PAFA_NEW_CLASS_DRIVER;
7754 +
7755 +
7756 +typedef struct _AFA_NEW_CLASS_DRIVER_RESPONSE {
7757 +       PAFACOMM_FUNCS          CommFuncs;
7758 +       PVOID                   CommPortExtension;
7759 +       PVOID                   MiniPortExtension;
7760 +       OS_SPINLOCK_COOKIE      SpinLockCookie;
7761 +       void                    *Dip;
7762 +} AFA_NEW_CLASS_DRIVER_RESPONSE;
7763 +typedef AFA_NEW_CLASS_DRIVER_RESPONSE *PAFA_NEW_CLASS_DRIVER_RESPONSE;
7764 +
7765 +
7766 +typedef struct _AFA_CLASS_DRIVER {
7767 +       struct _AFA_CLASS_DRIVER        *Next;
7768 +       PVOID                           ClassDriverExtension;
7769 +       PAFA_CLASS_OPEN_ADAPTER         OpenAdapter;
7770 +       PAFA_CLASS_CLOSE_ADAPTER        CloseAdapter;
7771 +       PAFA_CLASS_DEV_CONTROL          DeviceControl;
7772 +       PAFA_CLASS_HANDLE_AIF           HandleAif;
7773 +} AFA_CLASS_DRIVER;
7774 +typedef AFA_CLASS_DRIVER *PAFA_CLASS_DRIVER;
7775 +
7776 +
7777 +#endif // _AFACOMM_
7778 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/aifstruc.h linux/drivers/scsi/aacraid/include/aifstruc.h
7779 --- linux-2.4.4/drivers/scsi/aacraid/include/aifstruc.h Wed Dec 31 18:00:00 1969
7780 +++ linux/drivers/scsi/aacraid/include/aifstruc.h       Mon Apr 30 09:43:34 2001
7781 @@ -0,0 +1,319 @@
7782 +/*++
7783 + * Adaptec aacraid device driver for Linux.
7784 + *
7785 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
7786 + *
7787 + * This program is free software; you can redistribute it and/or modify
7788 + * it under the terms of the GNU General Public License as published by
7789 + * the Free Software Foundation; either version 2, or (at your option)
7790 + * any later version.
7791 + *
7792 + * This program is distributed in the hope that it will be useful,
7793 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7794 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
7795 + * GNU General Public License for more details.
7796 + *
7797 + * You should have received a copy of the GNU General Public License
7798 + * along with this program; see the file COPYING.  If not, write to
7799 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
7800 + *
7801 + * Module Name:
7802 + *   Aifstruc.h
7803 + *
7804 + * Abstract:
7805 + *   Define all shared data types relating to
7806 + *   the set of features utilizing Adapter
7807 + *   Initiated Fibs.
7808 + *
7809 + *
7810 + *
7811 + --*/
7812 +#ifndef _AIFSTRUC_H
7813 +#define _AIFSTRUC_H
7814 +
7815 +static char *ident_aifstruc = "aacraid_ident aifstruc.h 1.0.6 2000/10/09 Adaptec, Inc.";
7816 +
7817 +#include <protocol.h>
7818 +
7819 +//
7820 +//     Progress report structure definitions
7821 +//
7822 +typedef enum {
7823 +       AifJobStsSuccess = 1,
7824 +       AifJobStsFinished,
7825 +       AifJobStsAborted,
7826 +       AifJobStsFailed,
7827 +       AifJobStsLastReportMarker = 100, // All before mean last report
7828 +       AifJobStsSuspended,
7829 +       AifJobStsRunning
7830 +} _E_AifJobStatus;
7831 +
7832 +#ifdef AAC_32BIT_ENUMS
7833 +typedef        _E_AifJobStatus AifJobStatus;
7834 +#else
7835 +typedef        AAC_UINT32              AifJobStatus;
7836 +#endif
7837 +
7838 +
7839 +typedef enum {
7840 +       AifJobScsiMin = 1,              // Minimum value for Scsi operation
7841 +       AifJobScsiZero,                 // SCSI device clear operation
7842 +       AifJobScsiVerify,               // SCSI device Verify operation NO REPAIR
7843 +       AifJobScsiExercise,             // SCSI device Exercise operation
7844 +       AifJobScsiVerifyRepair, // SCSI device Verify operation WITH repair
7845 +       // Add new SCSI task types above this line
7846 +       AifJobScsiMax = 99,             // Max Scsi value
7847 +       AifJobCtrMin,                   // Min Ctr op value
7848 +       AifJobCtrZero,                  // Container clear operation
7849 +       AifJobCtrCopy,                  // Container copy operation
7850 +       AifJobCtrCreateMirror,  // Container Create Mirror operation
7851 +       AifJobCtrMergeMirror,   // Container Merge Mirror operation
7852 +       AifJobCtrScrubMirror,   // Container Scrub Mirror operation
7853 +       AifJobCtrRebuildRaid5,  // Container Rebuild Raid5 operation
7854 +       AifJobCtrScrubRaid5,    // Container Scrub Raid5 operation
7855 +       AifJobCtrMorph,                 // Container morph operation
7856 +       AifJobCtrPartCopy,              // Container Partition copy operation
7857 +       AifJobCtrRebuildMirror, // Container Rebuild Mirror operation
7858 +       AifJobCtrCrazyCache,            // crazy cache
7859 +       // Add new container task types above this line
7860 +       AifJobCtrMax = 199,             // Max Ctr type operation
7861 +       AifJobFsMin,                    // Min Fs type operation
7862 +       AifJobFsCreate,                 // File System Create operation
7863 +       AifJobFsVerify,                 // File System Verify operation
7864 +       AifJobFsExtend,                 // File System Extend operation
7865 +       // Add new file system task types above this line
7866 +       AifJobFsMax = 299,              // Max Fs type operation
7867 +       // Add new API task types here
7868 +       AifJobApiFormatNTFS,    // Format a drive to NTFS
7869 +       AifJobApiFormatFAT,             // Format a drive to FAT
7870 +       AifJobApiUpdateSnapshot, // update the read/write half of a snapshot
7871 +       AifJobApiFormatFAT32,   // Format a drive to FAT32
7872 +       AifJobApiMax = 399,             // Max API type operation
7873 +       AifJobCtlContinuousCtrVerify,   // Controller operation
7874 +       AifJobCtlMax = 499              // Max Controller type operation
7875 +
7876 +} _E_AifJobType;
7877 +
7878 +#ifdef AAC_32BIT_ENUMS
7879 +typedef        _E_AifJobType   AifJobType;
7880 +#else
7881 +typedef        AAC_UINT32              AifJobType;
7882 +#endif
7883 +
7884 +union SrcContainer {
7885 +       AAC_UINT32 from;
7886 +       AAC_UINT32 master;
7887 +       AAC_UINT32 container;
7888 +};
7889 +
7890 +union DstContainer {
7891 +       AAC_UINT32 to;
7892 +       AAC_UINT32 slave;
7893 +       AAC_UINT32 container;
7894 +};
7895 +
7896 +
7897 +struct AifContainers {
7898 +       union SrcContainer src;
7899 +       union DstContainer dst;
7900 +};
7901 +
7902 +union AifJobClient {
7903 +       
7904 +       struct AifContainers container; // For Container nd file system progress ops;
7905 +       AAC_INT32 scsi_dh;                      // For SCSI progress ops
7906 +};
7907 +
7908 +struct AifJobDesc {
7909 +       AAC_UINT32 jobID;                       // DO NOT FILL IN! Will be filled in by AIF
7910 +       AifJobType type;                // Operation that is being performed
7911 +       union AifJobClient client; // Details
7912 +};
7913 +
7914 +struct AifJobProgressReport {
7915 +       struct AifJobDesc jd;
7916 +       AifJobStatus status;
7917 +       AAC_UINT32 finalTick;
7918 +       AAC_UINT32 currentTick;
7919 +       AAC_UINT32 jobSpecificData1;
7920 +       AAC_UINT32 jobSpecificData2;
7921 +};
7922 +
7923 +//
7924 +//     Notification of events structure definition starts here
7925 +//
7926 +typedef enum {
7927 +       // General application notifies start here
7928 +       AifEnGeneric = 1,                       // Generic notification
7929 +       AifEnTaskComplete,                      // Task has completed
7930 +       AifEnConfigChange,                      // Adapter configuration change occurred
7931 +       AifEnContainerChange,           // Adapter specific container configuration change
7932 +       AifEnDeviceFailure,                     // SCSI device failed
7933 +       AifEnMirrorFailover,            // Mirror failover started
7934 +       AifEnContainerEvent,            // Significant container event
7935 +       AifEnFileSystemChange,          // File system changed
7936 +       AifEnConfigPause,                       // Container pause event
7937 +       AifEnConfigResume,                      // Container resume event
7938 +       AifEnFailoverChange,            // Failover space assignment changed
7939 +       AifEnRAID5RebuildDone,          // RAID5 rebuild finished
7940 +       AifEnEnclosureManagement,       // Enclosure management event
7941 +       AifEnBatteryEvent,                      // Significant NV battery event
7942 +       AifEnAddContainer,                      // A new container was created.
7943 +       AifEnDeleteContainer,           // A container was deleted.
7944 +       AifEnSMARTEvent,            // SMART Event
7945 +       AifEnBatteryNeedsRecond,        // The battery needs reconditioning
7946 +       AifEnClusterEvent,                      // Some cluster event
7947 +       AifEnDiskSetEvent,                      // A disk set event occured.
7948 +       // Add general application notifies above this comment
7949 +       AifDriverNotifyStart=199,       // Notifies for host driver go here
7950 +       // Host driver notifications start here
7951 +       AifDenMorphComplete,            // A morph operation completed
7952 +       AifDenVolumeExtendComplete      // A volume expand operation completed
7953 +       // Add host driver notifications above this comment
7954 +} _E_AifEventNotifyType;
7955 +
7956 +#ifdef AAC_32BIT_ENUMS
7957 +typedef _E_AifEventNotifyType  AifEventNotifyType;
7958 +#else
7959 +typedef        AAC_UINT32                              AifEventNotifyType;
7960 +#endif
7961 +
7962 +struct AifEnsGeneric {
7963 +       AAC_INT8 text[132];                             // Generic text
7964 +};
7965 +
7966 +struct AifEnsDeviceFailure {
7967 +       AAC_INT32 deviceHandle; // SCSI device handle
7968 +};
7969 +
7970 +struct AifEnsMirrorFailover {
7971 +       AAC_UINT32 container;           // Container with failed element
7972 +       AAC_UINT32 failedSlice;         // Old slice which failed
7973 +       AAC_UINT32 creatingSlice;       // New slice used for auto-create
7974 +};
7975 +
7976 +struct AifEnsContainerChange {
7977 +       AAC_UINT32 container[2];                // container that changed, -1 if no container
7978 +};
7979 +
7980 +struct AifEnsContainerEvent {
7981 +       AAC_UINT32 container;           // container number 
7982 +       AAC_UINT32 eventType;           // event type
7983 +};
7984 +
7985 +struct AifEnsEnclosureEvent {
7986 +       AAC_UINT32 empID;                               // enclosure management processor number 
7987 +       AAC_UINT32 unitID;                      // unitId, fan id, power supply id, slot id, tempsensor id. 
7988 +       AAC_UINT32 eventType;           // event type
7989 +};
7990 +
7991 +
7992 +struct AifEnsBatteryEvent {
7993 +       NVBATT_TRANSITION transition_type;      // e.g. from low to ok
7994 +       NVBATTSTATUS current_state;                     // current battery state
7995 +       NVBATTSTATUS prior_state;                       // previous battery state
7996 +};
7997 +
7998 +struct AifEnsDiskSetEvent {
7999 +       AAC_UINT32      eventType;
8000 +       AAC_UINT32      DsNum[2];
8001 +       AAC_UINT32      CreatorId[2];
8002 +};
8003 +
8004 +
8005 +
8006 +typedef enum _CLUSTER_AIF_EVENT {
8007 +       CLUSTER_NULL_EVENT = 0,
8008 +       CLUSTER_PARTNER_NAME_EVENT,             // change in partner hostname or adaptername from NULL to non-NULL
8009 +                                                                       // (partner's agent may be up)
8010 +       CLUSTER_PARTNER_NULL_NAME_EVENT // change in partner hostname or adaptername from non-null to NULL
8011 +                                                                       // (partner has rebooted)
8012 +} _E_CLUSTER_AIF_EVENT;
8013 +
8014 +#ifdef AAC_32BIT_ENUMS
8015 +typedef        _E_CLUSTER_AIF_EVENT    CLUSTER_AIF_EVENT;
8016 +#else
8017 +typedef        AAC_UINT32                              CLUSTER_AIF_EVENT;
8018 +#endif
8019 +
8020 +struct AifEnsClusterEvent {
8021 +       CLUSTER_AIF_EVENT   eventType;
8022 +};
8023 +
8024 +struct AifEventNotify {
8025 +       AifEventNotifyType      type;
8026 +       union {
8027 +               struct AifEnsGeneric            EG;
8028 +               struct AifEnsDeviceFailure      EDF;
8029 +               struct AifEnsMirrorFailover EMF;
8030 +               struct AifEnsContainerChange ECC;
8031 +               struct AifEnsContainerEvent ECE;
8032 +               struct AifEnsEnclosureEvent EEE;
8033 +               struct AifEnsBatteryEvent       EBE;
8034 +               struct AifEnsDiskSetEvent       EDS;
8035 +#ifdef BRIDGE
8036 +               struct AifEnsSMARTEvent ES;
8037 +#endif
8038 +               struct AifEnsClusterEvent ECLE;
8039 +       } data;
8040 +};
8041 +
8042 +//
8043 +//     Generic API structure
8044 +//
8045 +#define AIF_API_REPORT_MAX_SIZE 64
8046 +typedef AAC_INT8 AifApiReport[AIF_API_REPORT_MAX_SIZE];
8047 +
8048 +
8049 +
8050 +//
8051 +//     For FIB communication, we need all of the following things
8052 +//     to send back to the user.
8053 +//
8054 +typedef enum {
8055 +       AifCmdEventNotify = 1,  // Notify of event
8056 +       AifCmdJobProgress,              // Progress report
8057 +       AifCmdAPIReport,                // Report from other user of API
8058 +       AifCmdDriverNotify,             // Notify host driver of event
8059 +       AifReqJobList = 100,    // Gets back complete job list
8060 +       AifReqJobsForCtr,               // Gets back jobs for specific container
8061 +       AifReqJobsForScsi,              // Gets back jobs for specific SCSI device
8062 +       AifReqJobReport,                // Gets back a specific job report or list of them
8063 +       AifReqTerminateJob,             // Terminates job
8064 +       AifReqSuspendJob,               // Suspends a job
8065 +       AifReqResumeJob,                // Resumes a job
8066 +       AifReqSendAPIReport,    // API generic report requests
8067 +       AifReqAPIJobStart,              // Start a job from the API
8068 +       AifReqAPIJobUpdate,             // Update a job report from the API
8069 +       AifReqAPIJobFinish              // Finish a job from the API
8070 +} _E_AIFCOMMAND;
8071 +
8072 +#ifdef AAC_32BIT_ENUMS
8073 +typedef _E_AIFCOMMAND  AIFCOMMAND;
8074 +#else
8075 +typedef        AAC_UINT32              AIFCOMMAND;
8076 +#endif
8077 +
8078 +
8079 +
8080 +//
8081 +//     Adapter Initiated FIB command structures. Start with the adapter
8082 +//     initiated FIBs that really come from the adapter, and get responded
8083 +//     to by the host.
8084 +//
8085 +typedef struct _AIFCOMMANDTOHOST {
8086 +       AIFCOMMAND command;                     // Tell host what type of notify this is
8087 +       AAC_UINT32 seqNumber;   // To allow ordering of reports (if necessary)
8088 +       union {
8089 +               // First define data going to the adapter
8090 +               struct AifEventNotify EN;       // Event notify structure
8091 +               struct AifJobProgressReport PR[1]; // Progress report
8092 +               AifApiReport AR;
8093 +       } data;
8094 +} AIFCOMMANDTOHOST, *PAIFCOMMANDTOHOST;
8095 +
8096 +
8097 +#endif // _AIFSTRUC_H
8098 +
8099 +
8100 +
8101 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/build_number.h linux/drivers/scsi/aacraid/include/build_number.h
8102 --- linux-2.4.4/drivers/scsi/aacraid/include/build_number.h     Wed Dec 31 18:00:00 1969
8103 +++ linux/drivers/scsi/aacraid/include/build_number.h   Mon Apr 30 09:43:34 2001
8104 @@ -0,0 +1,39 @@
8105 +/*++
8106 + * Adaptec aacraid device driver for Linux.
8107 + *
8108 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8109 + *
8110 + * This program is free software; you can redistribute it and/or modify
8111 + * it under the terms of the GNU General Public License as published by
8112 + * the Free Software Foundation; either version 2, or (at your option)
8113 + * any later version.
8114 + *
8115 + * This program is distributed in the hope that it will be useful,
8116 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8117 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
8118 + * GNU General Public License for more details.
8119 + *
8120 + * You should have received a copy of the GNU General Public License
8121 + * along with this program; see the file COPYING.  If not, write to
8122 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8123 + *
8124 + * Module Name:
8125 + *   build_number.h
8126 + *
8127 + * Abstract:
8128 + *   DThis module contains the single location where the build number
8129 + *   is kept.
8130 + *
8131 + *
8132 + *
8133 + --*/
8134 +#ifndef _BUILD_NUMBER_H 
8135 +#define _BUILD_NUMBER_H 
8136 +
8137 +static char *ident_build_num = "aacraid_ident build_number.h 1.0.6 2000/10/09 Adaptec, Inc.";
8138 +
8139 +#define REV_BUILD_NUMBER 3911 
8140 +
8141 +
8142 +#endif  // _BUILD_NUMBER_H 
8143 +
8144 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/commdata.h linux/drivers/scsi/aacraid/include/commdata.h
8145 --- linux-2.4.4/drivers/scsi/aacraid/include/commdata.h Wed Dec 31 18:00:00 1969
8146 +++ linux/drivers/scsi/aacraid/include/commdata.h       Mon Apr 30 09:43:34 2001
8147 @@ -0,0 +1,112 @@
8148 +/*++
8149 + * Adaptec aacraid device driver for Linux.
8150 + *
8151 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8152 + *
8153 + * This program is free software; you can redistribute it and/or modify
8154 + * it under the terms of the GNU General Public License as published by
8155 + * the Free Software Foundation; either version 2, or (at your option)
8156 + * any later version.
8157 + *
8158 + * This program is distributed in the hope that it will be useful,
8159 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8160 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
8161 + * GNU General Public License for more details.
8162 + *
8163 + * You should have received a copy of the GNU General Public License
8164 + * along with this program; see the file COPYING.  If not, write to
8165 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8166 + *
8167 + * Module Name:
8168 + *   commdata.h
8169 + *
8170 + * Abstract: Define the communication layer of the adapter
8171 + *
8172 + *
8173 + *
8174 + --*/
8175 +#ifndef _COMMDATA_
8176 +#define _COMMDATA_
8177 +
8178 +static char *ident_commdata = "aacraid_ident commdata.h 1.0.6 2000/10/09 Adaptec, Inc.";
8179 +
8180 +typedef struct _FSA_COMM_DATA {
8181 +  
8182 +  //
8183 +  //  A pointer to the Driver and Device object we were initialized with
8184 +  //
8185 +  
8186 +  PDRIVER_OBJECT DriverObject;
8187 +  PDEVICE_OBJECT DeviceObject;
8188 +  
8189 +  //
8190 +  // A list of all adapters we have configured.
8191 +  // 
8192 +  
8193 +  PAFA_COMM_ADAPTER AdapterList;
8194 +  ULONG                  TotalAdapters;
8195 +  
8196 +  //
8197 +  // Adapter timeout support. This is the default timeout to wait for the
8198 +  // adapter to respond(setup in initfs.c), and a boolean to indicate if
8199 +  // we should timeout requests to the adapter or not.
8200 +  //
8201 +
8202 +  LARGE_INTEGER QueueFreeTimeout;
8203 +  LARGE_INTEGER AdapterTimeout;
8204 +  BOOLEAN EnableAdapterTimeouts;
8205 +
8206 +  ULONG        FibTimeoutIncrement;
8207 +  
8208 +  ULONG FibsSent;
8209 +  ULONG FibRecved;
8210 +  ULONG NoResponseSent;
8211 +  ULONG NoResponseRecved;
8212 +  ULONG AsyncSent;
8213 +  ULONG AsyncRecved;
8214 +  ULONG NormalSent;
8215 +  ULONG NormalRecved;
8216 +  
8217 +  ULONG TimedOutFibs;
8218 +  
8219 +  KDPC         TimeoutDPC;
8220 +  KTIMER       TimeoutTimer;
8221 +  
8222 +  // 
8223 +  // If this value is set to 1 then interrupt moderation will occur 
8224 +  // in the base commuication support.
8225 +  //
8226 +
8227 +  ULONG EnableInterruptModeration;
8228 +
8229 +  int HardInterruptModeration;
8230 +  int HardInterruptModeration1;
8231 +  int PeakFibsConsumed;
8232 +  int ZeroFibsConsumed;
8233 +  int EnableFibTimeoutBreak;
8234 +  ULONG FibTimeoutSeconds;
8235 +  
8236 +  //
8237 +  // The following holds all of the available user settable variables.
8238 +  // This includes all for the comm layer as well as any from the class
8239 +  // drivers as well.
8240 +  //
8241 +  
8242 +  FSA_USER_VAR *UserVars;
8243 +  ULONG                        NumUserVars;
8244 +  
8245 +  
8246 +  ULONG           MeterFlag;
8247 +  
8248 +#ifdef FIB_CHECKSUMS
8249 +  int do_fib_checksums;
8250 +#endif
8251 +  
8252 +} FSA_COMM_DATA;
8253 +typedef FSA_COMM_DATA *PFSA_COMM_DATA;
8254 +
8255 +extern FSA_COMM_DATA FsaCommData;
8256 +
8257 +
8258 +#endif // _COMMDATA_
8259 +
8260 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/commerr.h linux/drivers/scsi/aacraid/include/commerr.h
8261 --- linux-2.4.4/drivers/scsi/aacraid/include/commerr.h  Wed Dec 31 18:00:00 1969
8262 +++ linux/drivers/scsi/aacraid/include/commerr.h        Mon Apr 30 09:43:34 2001
8263 @@ -0,0 +1,125 @@
8264 +/*++
8265 + * Adaptec aacraid device driver for Linux.
8266 + *
8267 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8268 + *
8269 + * This program is free software; you can redistribute it and/or modify
8270 + * it under the terms of the GNU General Public License as published by
8271 + * the Free Software Foundation; either version 2, or (at your option)
8272 + * any later version.
8273 + *
8274 + * This program is distributed in the hope that it will be useful,
8275 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8276 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
8277 + * GNU General Public License for more details.
8278 + *
8279 + * You should have received a copy of the GNU General Public License
8280 + * along with this program; see the file COPYING.  If not, write to
8281 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8282 + *
8283 + * Module Name:
8284 + *   commerr.h
8285 + *
8286 + * Abstract: This file defines all errors that are unique to the Adaptec Fsa Filesystem
8287 + *
8288 + *
8289 + *
8290 + --*/
8291 +
8292 +#ifndef _FSAERR_
8293 +#define _FSAERR_
8294 +
8295 +static char *ident_commerr = "aacraid_ident commerr.h 1.0.6 2000/10/09 Adaptec, Inc.";
8296 +
8297 +//
8298 +//  Note: comments in the .mc file must use both ";" and "//".
8299 +//
8300 +//  Status values are 32 bit values layed out as follows:
8301 +//
8302 +//   3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
8303 +//   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
8304 +//  +---+-+-------------------------+-------------------------------+
8305 +//  |Sev|C|       Facility          |               Code            |
8306 +//  +---+-+-------------------------+-------------------------------+
8307 +//
8308 +//  where
8309 +//
8310 +//      Sev - is the severity code
8311 +//
8312 +//          00 - Success
8313 +//          01 - Informational
8314 +//          10 - Warning
8315 +//          11 - Error
8316 +//
8317 +//      C - is the Customer code flag
8318 +//
8319 +//      Facility - is the facility code
8320 +//
8321 +//      Code - is the facility's status code
8322 +//
8323 +
8324 +
8325 +//
8326 +// %1 is reserved by the IO Manager. If IoAllocateErrorLogEntry is
8327 +// called with a device, the name of the device will be inserted into
8328 +// the message at %1. Otherwise, the place of %1 will be left empty.
8329 +// In either case, the insertion strings from the driver's error log
8330 +// entry starts at %2. In other words, the first insertion string goes
8331 +// to %2, the second to %3 and so on.
8332 +//
8333 +
8334 +//
8335 +//  Values are 32 bit values layed out as follows:
8336 +//
8337 +//   3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
8338 +//   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
8339 +//  +---+-+-+-----------------------+-------------------------------+
8340 +//  |Sev|C|R|     Facility          |               Code            |
8341 +//  +---+-+-+-----------------------+-------------------------------+
8342 +//
8343 +//  where
8344 +//
8345 +//      Sev - is the severity code
8346 +//
8347 +//          00 - Success
8348 +//          01 - Informational
8349 +//          10 - Warning
8350 +//          11 - Error
8351 +//
8352 +//      C - is the Customer code flag
8353 +//
8354 +//      R - is a reserved bit
8355 +//
8356 +//      Facility - is the facility code
8357 +//
8358 +//      Code - is the facility's status code
8359 +//
8360 +//
8361 +// Define the facility codes
8362 +//
8363 +
8364 +
8365 +#define FACILITY_FSAFS_ERROR_CODE        0x7
8366 +
8367 +
8368 +
8369 +//
8370 +// MessageId: FSAFS_FIB_INVALID
8371 +//
8372 +// MessageText:
8373 +//
8374 +//  A communication packet was detected to be formatted poorly. Please Contact Adaptec support.
8375 +//
8376 +#define FSAFS_FIB_INVALID                ((AAC_STATUS)0xE0070009L)
8377 +
8378 +
8379 +//
8380 +// MessageId: FSAFS_TIMED_OUT_FIB_COMPLETED
8381 +//
8382 +// MessageText:
8383 +//
8384 +//  A Fib previously timed out by host has been completed by the adapter. (\\.\Afa%2)
8385 +//
8386 +#define FSAFS_TIMED_OUT_FIB_COMPLETED    ((AAC_STATUS)0xA007000EL)
8387 +
8388 +#endif _FSAERR_
8389 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/commfibcontext.h linux/drivers/scsi/aacraid/include/commfibcontext.h
8390 --- linux-2.4.4/drivers/scsi/aacraid/include/commfibcontext.h   Wed Dec 31 18:00:00 1969
8391 +++ linux/drivers/scsi/aacraid/include/commfibcontext.h Mon Apr 30 09:43:34 2001
8392 @@ -0,0 +1,98 @@
8393 +/*++
8394 + * Adaptec aacraid device driver for Linux.
8395 + *
8396 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8397 + *
8398 + * This program is free software; you can redistribute it and/or modify
8399 + * it under the terms of the GNU General Public License as published by
8400 + * the Free Software Foundation; either version 2, or (at your option)
8401 + * any later version.
8402 + *
8403 + * This program is distributed in the hope that it will be useful,
8404 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8405 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
8406 + * GNU General Public License for more details.
8407 + *
8408 + * You should have received a copy of the GNU General Public License
8409 + * along with this program; see the file COPYING.  If not, write to
8410 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8411 + *
8412 + * Module Name:
8413 + *   commfibcontext.h
8414 + *
8415 + * Abstract: defines the _COMM_FIB_CONTEXT strcuture
8416 + *
8417 + *
8418 + *
8419 + --*/
8420 +#ifndef _COMM_FIB_CONTEXT_
8421 +#define _COMM_FIB_CONTEXT_
8422 +
8423 +static char *ident_commfib = "aacraid_ident commfibcontext.h 1.0.6 2000/10/09 Adaptec, Inc.";
8424 +
8425 +typedef struct _COMM_FIB_CONTEXT {
8426 +
8427 +       PVOID           Next;   // this is used by the zone allocation
8428 +
8429 +    //
8430 +    //  Type and size of this record (must be FSA_NTC_FIB_CONTEXT)
8431 +    //
8432 +    //  NOTE:  THIS STRUCTURE MUST REMAIN 64-bit ALIGNED IN SIZE, SINCE
8433 +    //         IT IS ZONE ALLOCATED, AND REPINNED_BCBS_ARRAY_SIZE AFFECTS
8434 +    //         ITS SIZE.
8435 +    //
8436 +
8437 +    NODE_TYPE_CODE NodeTypeCode;
8438 +    NODE_BYTE_SIZE NodeByteSize;
8439 +
8440 +       //
8441 +       //      The Adapter that this I/O is destined for.
8442 +       //
8443 +
8444 +       PAFA_COMM_ADAPTER Adapter;
8445 +
8446 +    PHYSICAL_ADDRESS LogicalFibAddress;
8447 +
8448 +    //
8449 +    // This is the event the sendfib routine will wait on if the
8450 +    // caller did not pass one and this is synch io.
8451 +    //
8452 +
8453 +  OS_CV_T      FsaEvent;
8454 +       OS_CVLOCK       *FsaEventMutex;
8455 +
8456 +       ULONG   FibComplete;    // gets set to 1 when fib is complete
8457 +    
8458 +       PFIB_CALLBACK FibCallback;
8459 +       PVOID FibCallbackContext;
8460 +
8461 +       ULONG   Flags;
8462 +
8463 +
8464 +#ifdef GATHER_FIB_TIMES
8465 +       LARGE_INTEGER   FibTimeStamp;
8466 +       PFIB_TIMES              FibTimesPtr;
8467 +#endif
8468 +
8469 +       //
8470 +       // The following is used to put this fib context onto the Outstanding I/O queue.
8471 +       //
8472 +               
8473 +       LIST_ENTRY      QueueEntry;     
8474 +
8475 +       //
8476 +       // The following is used to timeout a fib to the adapter.
8477 +       //
8478 +
8479 +       LARGE_INTEGER   TimeoutValue;
8480 +
8481 +       PVOID   FibData;
8482 +
8483 +    PFIB Fib;
8484 +
8485 +} COMM_FIB_CONTEXT;
8486 +typedef COMM_FIB_CONTEXT *PCOMM_FIB_CONTEXT;
8487 +
8488 +#define FIB_CONTEXT_FLAG_TIMED_OUT             (0x00000001)
8489 +
8490 +#endif /* _COMM_FIB_CONTEXT_ */
8491 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/comprocs.h linux/drivers/scsi/aacraid/include/comprocs.h
8492 --- linux-2.4.4/drivers/scsi/aacraid/include/comprocs.h Wed Dec 31 18:00:00 1969
8493 +++ linux/drivers/scsi/aacraid/include/comprocs.h       Mon Apr 30 09:43:34 2001
8494 @@ -0,0 +1,93 @@
8495 +/*++
8496 + * Adaptec aacraid device driver for Linux.
8497 + *
8498 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8499 + *
8500 + * This program is free software; you can redistribute it and/or modify
8501 + * it under the terms of the GNU General Public License as published by
8502 + * the Free Software Foundation; either version 2, or (at your option)
8503 + * any later version.
8504 + *
8505 + * This program is distributed in the hope that it will be useful,
8506 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8507 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
8508 + * GNU General Public License for more details.
8509 + *
8510 + * You should have received a copy of the GNU General Public License
8511 + * along with this program; see the file COPYING.  If not, write to
8512 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8513 + *
8514 + * Module Name:
8515 + *   comprocs.h
8516 + *
8517 + * Abstract: This module defines all of the globally used procedures in the Afa comm layer
8518 + *
8519 + *
8520 + *
8521 + --*/
8522 +#ifndef _COMPROCS_
8523 +#define _COMPROCS_
8524 +
8525 +static char *ident_comproc = "aacraid_ident comprocs.h 1.0.6 2000/10/09 Adaptec, Inc.";
8526 +
8527 +#include "osheaders.h"
8528 +
8529 +#include "AacGenericTypes.h"
8530 +
8531 +#include "aac_unix_defs.h"
8532 +
8533 +#include "nodetype.h"
8534 +
8535 +// #define GATHER_FIB_TIMES
8536 +
8537 +#include "fsatypes.h"
8538 +
8539 +#include "perfpack.h"
8540 +
8541 +#include "comstruc.h"
8542 +
8543 +//#include "unix_protocol.h"
8544 +
8545 +#include "fsact.h"
8546 +
8547 +#include "protocol.h"
8548 +
8549 +#include "fsaioctl.h"
8550 +
8551 +#undef GATHER_FIB_TIMES
8552 +
8553 +#include "aifstruc.h"
8554 +
8555 +#include "fsaport.h"
8556 +#include "comsup.h"
8557 +#include "afacomm.h"
8558 +#include "adapter.h"
8559 +
8560 +#include "commfibcontext.h"
8561 +#include "comproto.h"
8562 +#include "commdata.h"
8563 +#include "commerr.h"
8564 +
8565 +
8566 +
8567 +
8568 +//
8569 +// The following macro is used when sending and receiving FIBs.  It is only used for
8570 +// debugging.
8571 +
8572 +#if DBG
8573 +#define        FIB_COUNTER_INCREMENT(Counter)          InterlockedIncrement(&(Counter))
8574 +#else
8575 +#define        FIB_COUNTER_INCREMENT(Counter)          
8576 +#endif
8577 +
8578 +
8579 +
8580 +int
8581 +AfaCommAdapterDeviceControl (
8582 +       IN PVOID AdapterArg,
8583 +       IN PAFA_IOCTL_CMD       IoctlCmdPtr
8584 +       );
8585 +
8586 +
8587 +#endif // _COMPROCS_
8588 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/comproto.h linux/drivers/scsi/aacraid/include/comproto.h
8589 --- linux-2.4.4/drivers/scsi/aacraid/include/comproto.h Wed Dec 31 18:00:00 1969
8590 +++ linux/drivers/scsi/aacraid/include/comproto.h       Mon Apr 30 09:43:34 2001
8591 @@ -0,0 +1,170 @@
8592 +/*++
8593 + * Adaptec aacraid device driver for Linux.
8594 + *
8595 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8596 + *
8597 + * This program is free software; you can redistribute it and/or modify
8598 + * it under the terms of the GNU General Public License as published by
8599 + * the Free Software Foundation; either version 2, or (at your option)
8600 + * any later version.
8601 + *
8602 + * This program is distributed in the hope that it will be useful,
8603 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8604 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
8605 + * GNU General Public License for more details.
8606 + *
8607 + * You should have received a copy of the GNU General Public License
8608 + * along with this program; see the file COPYING.  If not, write to
8609 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8610 + *
8611 + * Module Name:
8612 + *   comproto.h
8613 + *
8614 + * Abstract: Global routines for the commuication interface that are device
8615 + *           independant.
8616 + *
8617 + *
8618 + *
8619 + --*/
8620 +#ifndef _COMM_PROTO
8621 +#define _COMM_PROTO
8622 +
8623 +static char *ident_comproto = "aacraid_ident comproto.h 1.0.6 2000/10/09 Adaptec, Inc.";
8624 +
8625 +//
8626 +// define the routines we need so we can commuicate with the
8627 +// fsa adapter
8628 +//
8629 +
8630 +//
8631 +// The following 4 dpc routines will support commuication from the adapter to the
8632 +// host. There is one DPC routine to deal with each type of queue that supports
8633 +// commuication from the adapter. (adapter to host resposes, adapter to host commands)
8634 +// These routines will simply pull off the QE and set an event. In the case of a
8635 +// adapter to host command they will also put the FIB on a queue to be processed by
8636 +// a FS thread running at passive level.
8637 +//
8638 +
8639 +// Handle queue not full notification to the file system thread waiting for a queue entry
8640 +
8641 +u_int
8642 +CommonNotFullDpc(
8643 +       IN PCOMM_REGION CommRegion
8644 +    );
8645 +
8646 +// Adapter to host normal priority responses
8647 +
8648 +u_int
8649 +HostResponseNormalDpc(
8650 +    IN PCOMM_QUE OurQueue
8651 +    );
8652 +
8653 +// Adapter to host high priority responses
8654 +u_int
8655 +HostResponseHighDpc(
8656 +    IN PCOMM_QUE OurQueue
8657 +    );
8658 +
8659 +// Adapter to host high priority commands
8660 +u_int
8661 +HostCommandHighDpc(
8662 +    IN PCOMM_QUE OurQueue
8663 +    );
8664 +    
8665 +
8666 +// Adapter to host normal priority commands
8667 +u_int
8668 +HostCommandNormDpc(
8669 +    IN PCOMM_QUE OurQueue
8670 +    );
8671 +
8672 +
8673 +
8674 +BOOLEAN
8675 +SendSynchFib(
8676 +       PVOID                   Arg,
8677 +       FIB_COMMAND     Command,
8678 +       PVOID                   Data,
8679 +       USHORT                  Size,
8680 +       PVOID                   Response,
8681 +       USHORT                  *ResponseSize
8682 +       );
8683 +
8684 +PFIB_CONTEXT
8685 +AllocateFib (
8686 +       IN PVOID Adapter
8687 +    );
8688 +
8689 +VOID
8690 +FreeFib (
8691 +    IN PFIB_CONTEXT FibContext
8692 +    );
8693 +
8694 +VOID
8695 +FreeFibFromDpc(
8696 +    IN PFIB_CONTEXT FibContext
8697 +    );
8698 +
8699 +AAC_STATUS
8700 +DeallocateFib(
8701 +    IN PFIB_CONTEXT FibContext
8702 +    );
8703 +
8704 +
8705 +
8706 +AAC_STATUS
8707 +SendFib(
8708 +    IN FIB_COMMAND Command, 
8709 +       IN PFIB_CONTEXT FibContext,
8710 +    IN ULONG Size,
8711 +    IN COMM_PRIORITIES Priority,
8712 +    IN BOOLEAN Wait,
8713 +    IN PVOID WaitOn,
8714 +    IN BOOLEAN ResponseExpected,
8715 +       IN PFIB_CALLBACK FibCallback,
8716 +       IN PVOID FibCallbackContext
8717 +    );
8718 +
8719 +AAC_STATUS
8720 +CompleteFib(
8721 +       IN PFIB_CONTEXT FibContext
8722 +    );
8723 +
8724 +AAC_STATUS
8725 +CompleteAdapterFib(
8726 +       IN PFIB_CONTEXT FibContext,
8727 +    IN USHORT Size
8728 +    );
8729 +
8730 +AAC_STATUS
8731 +InitializeFib(
8732 +       IN PFIB_CONTEXT FibContext
8733 +    );
8734 +
8735 +
8736 +PVOID
8737 +FsaGetFibData(
8738 +       IN PFIB_CONTEXT FibContext
8739 +       );
8740 +
8741 +
8742 +
8743 +AAC_STATUS
8744 +AfaCommOpenAdapter (
8745 +       IN PVOID AdapterArg
8746 +       );
8747 +
8748 +AAC_STATUS
8749 +AfaCommCloseAdapter (
8750 +       IN PVOID AdapterArg
8751 +       );
8752 +
8753 +
8754 +VOID
8755 +AfaCommInterruptHost(
8756 +       PVOID   Adapter,
8757 +       ADAPTER_EVENT   AdapterEvent
8758 +       );
8759 +
8760 +
8761 +#endif // _COMM_PROTO
8762 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/comstruc.h linux/drivers/scsi/aacraid/include/comstruc.h
8763 --- linux-2.4.4/drivers/scsi/aacraid/include/comstruc.h Wed Dec 31 18:00:00 1969
8764 +++ linux/drivers/scsi/aacraid/include/comstruc.h       Mon Apr 30 09:43:34 2001
8765 @@ -0,0 +1,435 @@
8766 +/*++
8767 + * Adaptec aacraid device driver for Linux.
8768 + *
8769 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8770 + *
8771 + * This program is free software; you can redistribute it and/or modify
8772 + * it under the terms of the GNU General Public License as published by
8773 + * the Free Software Foundation; either version 2, or (at your option)
8774 + * any later version.
8775 + *
8776 + * This program is distributed in the hope that it will be useful,
8777 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8778 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
8779 + * GNU General Public License for more details.
8780 + *
8781 + * You should have received a copy of the GNU General Public License
8782 + * along with this program; see the file COPYING.  If not, write to
8783 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8784 + *
8785 + * Module Name:
8786 + *   comstruc.h
8787 + *
8788 + * Abstract: This module defines the data structures that make up the communication
8789 + *           region for the FSA filesystem. This region is how the host based code
8790 + *           communicates both control and data to the adapter based code.
8791 + *
8792 + *
8793 + *
8794 + --*/
8795 +#ifndef _COMM_STRUCT
8796 +#define _COMM_STRUCT
8797 +
8798 +static char *ident_comstruc = "aacraid_ident comstruc.h 1.0.7 2000/10/11 Adaptec, Inc.";
8799 +
8800 +//
8801 +// Define all the constants needed for the communication interface
8802 +//
8803 +
8804 +// Define how many queue entries each queue will have and the total number of
8805 +// entries for the entire communication interface. Also define how many queues
8806 +// we support.
8807 +
8808 +#define NUMBER_OF_COMM_QUEUES  8   // 4 command; 4 response
8809 +#define HOST_HIGH_CMD_ENTRIES  4
8810 +#define HOST_NORM_CMD_ENTRIES  8
8811 +#define ADAP_HIGH_CMD_ENTRIES  4
8812 +#define ADAP_NORM_CMD_ENTRIES  512
8813 +#define HOST_HIGH_RESP_ENTRIES 4
8814 +#define HOST_NORM_RESP_ENTRIES 512
8815 +#define ADAP_HIGH_RESP_ENTRIES 4
8816 +#define ADAP_NORM_RESP_ENTRIES 8
8817 +
8818 +#define TOTAL_QUEUE_ENTRIES  \
8819 +    (HOST_NORM_CMD_ENTRIES + HOST_HIGH_CMD_ENTRIES + ADAP_NORM_CMD_ENTRIES + ADAP_HIGH_CMD_ENTRIES + \
8820 +           HOST_NORM_RESP_ENTRIES + HOST_HIGH_RESP_ENTRIES + ADAP_NORM_RESP_ENTRIES + ADAP_HIGH_RESP_ENTRIES)
8821 +
8822 +
8823 +
8824 +
8825 +// Set the queues on a 16 byte alignment
8826 +#define QUEUE_ALIGNMENT                16
8827 +
8828 +
8829 +//
8830 +// The queue headers define the Communication Region queues. These
8831 +// are physically contiguous and accessible by both the adapter and the
8832 +// host. Even though all queue headers are in the same contiguous block they will be
8833 +// represented as individual units in the data structures.
8834 +//
8835 +
8836 +typedef AAC_UINT32 QUEUE_INDEX;
8837 +
8838 +typedef QUEUE_INDEX *PQUEUE_INDEX;
8839 +
8840 +typedef struct _QUEUE_ENTRY {
8841 +
8842 +    AAC_UINT32 Size;                     // Size in bytes of the Fib which this QE points to
8843 +    AAC_UINT32 FibAddress;             // Receiver addressable address of the FIB (low 32 address bits)
8844 +
8845 +} QUEUE_ENTRY;
8846 +
8847 +typedef QUEUE_ENTRY *PQUEUE_ENTRY;
8848 +
8849 +
8850 +
8851 +// The adapter assumes the ProducerIndex and ConsumerIndex are grouped
8852 +// adjacently and in that order.
8853 +//
8854 +typedef struct _QUEUE_HEADERS {
8855 +
8856 +    PHYSICAL_ADDRESS LogicalHeaderAddress;  // Address to hand the adapter to access to this queue head
8857 +    PQUEUE_INDEX ProducerIndex;              // The producer index for this queue (host address)
8858 +    PQUEUE_INDEX ConsumerIndex;              // The consumer index for this queue (host address)
8859 +
8860 +} QUEUE_HEADERS;
8861 +typedef QUEUE_HEADERS *PQUEUE_HEADERS;
8862 +
8863 +//
8864 +// Define all the events which the adapter would like to notify
8865 +// the host of.
8866 +//
8867 +typedef enum _ADAPTER_EVENT {
8868 +    HostNormCmdQue = 1,         // Change in host normal priority command queue
8869 +    HostHighCmdQue,             // Change in host high priority command queue
8870 +    HostNormRespQue,            // Change in host normal priority response queue
8871 +    HostHighRespQue,            // Change in host high priority response queue
8872 +    AdapNormRespNotFull,
8873 +    AdapHighRespNotFull,
8874 +    AdapNormCmdNotFull,
8875 +    AdapHighCmdNotFull,
8876 +       SynchCommandComplete,
8877 +    AdapInternalError = 0xfe    // The adapter detected an internal error shutting down
8878 +
8879 +} _E_ADAPTER_EVENT;
8880 +
8881 +#ifdef AAC_32BIT_ENUMS
8882 +typedef _E_ADAPTER_EVENT       ADAPTER_EVENT;
8883 +#else
8884 +typedef AAC_UINT32                     ADAPTER_EVENT;
8885 +#endif
8886 +
8887 +//
8888 +// Define all the events the host wishes to notify the
8889 +// adapter of.
8890 +//
8891 +typedef enum _HOST_2_ADAP_EVENT {
8892 +    AdapNormCmdQue = 1,
8893 +    AdapHighCmdQue,
8894 +    AdapNormRespQue,
8895 +    AdapHighRespQue,
8896 +    HostShutdown,
8897 +    HostPowerFail,
8898 +    FatalCommError,
8899 +    HostNormRespNotFull,
8900 +    HostHighRespNotFull,
8901 +    HostNormCmdNotFull,
8902 +    HostHighCmdNotFull,
8903 +       FastIo,
8904 +       AdapPrintfDone
8905 +} _E_HOST_2_ADAP_EVENT;
8906 +
8907 +#ifdef AAC_32BIT_ENUMS
8908 +typedef _E_HOST_2_ADAP_EVENT   HOST_2_ADAP_EVENT;
8909 +#else
8910 +typedef        AAC_UINT32                              HOST_2_ADAP_EVENT;
8911 +#endif
8912 +
8913 +//
8914 +// Define all the queues that the adapter and host use to communicate
8915 +//
8916 +
8917 +typedef enum _QUEUE_TYPES {
8918 +        HostNormCmdQueue = 1,       // Adapter to host normal priority command traffic
8919 +        HostHighCmdQueue,           // Adapter to host high priority command traffic
8920 +        AdapNormRespQueue,          // Host to adapter normal priority response traffic
8921 +        AdapHighRespQueue,          // Host to adapter high priority response traffic
8922 +        AdapNormCmdQueue,           // Host to adapter normal priority command traffic
8923 +        AdapHighCmdQueue,           // Host to adapter high priority command traffic
8924 +        HostNormRespQueue,          // Adapter to host normal priority response traffic
8925 +        HostHighRespQueue           // Adapter to host high priority response traffic
8926 +} _E_QUEUE_TYPES;
8927 +
8928 +#ifdef AAC_32BIT_ENUMS
8929 +typedef _E_QUEUE_TYPES         QUEUE_TYPES;
8930 +#else
8931 +typedef        AAC_UINT32                      QUEUE_TYPES;
8932 +#endif
8933 +
8934 +
8935 +//
8936 +// Assign type values to the FSA communication data structures
8937 +//
8938 +
8939 +typedef enum _STRUCT_TYPES {
8940 +    TFib = 1,
8941 +    TQe,
8942 +       TCtPerf
8943 +} _E_STRUCT_TYPES;
8944 +
8945 +#ifdef AAC_32BIT_ENUMS
8946 +typedef        _E_STRUCT_TYPES STRUCT_TYPES;
8947 +#else
8948 +typedef        AAC_UINT32              STRUCT_TYPES;
8949 +#endif
8950 +
8951 +//
8952 +// Define the priority levels the FSA communication routines support.
8953 +//
8954 +
8955 +typedef enum _COMM_PRIORITIES {
8956 +    FsaNormal = 1,
8957 +    FsaHigh
8958 +} _E_COMM_PRIORITIES;
8959 +
8960 +#ifdef AAC_32BIT_ENUMS
8961 +typedef _E_COMM_PRIORITIES     COMM_PRIORITIES;
8962 +#else
8963 +typedef        AAC_UINT32                      COMM_PRIORITIES;
8964 +#endif
8965 +
8966 +
8967 +
8968 +//
8969 +// Define the LIST_ENTRY structure.  This structure is used on the NT side to link
8970 +// the FIBs together in a linked list.  Since this structure gets compiled on the adapter
8971 +// as well, we need to define this structure for the adapter's use.  If '_NT_DEF_'
8972 +// is defined, then this header is being included from the NT side, and therefore LIST_ENTRY
8973 +// is already defined.
8974 +#if !defined(_NTDEF_) && !defined(_WINNT_)
8975 +typedef struct _LIST_ENTRY {
8976 +   struct _LIST_ENTRY *Flink;
8977 +   struct _LIST_ENTRY *Blink;
8978 +} LIST_ENTRY;
8979 +typedef LIST_ENTRY *PLIST_ENTRY;
8980 +#endif
8981 +
8982 +
8983 +//
8984 +// Define the FIB. The FIB is the where all the requested data and
8985 +// command information are put to the application on the FSA adapter.
8986 +//
8987 +
8988 +typedef struct _FIB_HEADER {
8989 +    AAC_UINT32 XferState;                    // Current transfer state for this CCB
8990 +    AAC_UINT16 Command;                     // Routing information for the destination
8991 +    AAC_UINT8 StructType;                   // Type FIB
8992 +       AAC_UINT8 Flags;                                                  // Flags for FIB
8993 +    AAC_UINT16 Size;                        // Size of this FIB in bytes
8994 +    AAC_UINT16 SenderSize;                  // Size of the FIB in the sender (for response sizing)
8995 +    AAC_UINT32 SenderFibAddress;               // Host defined data in the FIB
8996 +    AAC_UINT32 ReceiverFibAddress;             // Logical address of this FIB for the adapter
8997 +    AAC_UINT32 SenderData;                     // Place holder for the sender to store data
8998 +#ifndef __midl
8999 +       union {
9000 +               struct {
9001 +                   AAC_UINT32 _ReceiverTimeStart;      // Timestamp for receipt of fib
9002 +                   AAC_UINT32 _ReceiverTimeDone;       // Timestamp for completion of fib
9003 +               } _s;
9004 +               LIST_ENTRY _FibLinks;                   // Used to link Adapter Initiated Fibs on the host
9005 +       } _u;
9006 +#else                          // The MIDL compiler does not support unions without a discriminant.
9007 +       struct {                // Since nothing during the midl compile actually looks into this
9008 +               struct {        // structure, this shoudl be ok.
9009 +                       AAC_UINT32 _ReceiverTimeStart;  // Timestamp for receipt of fib
9010 +                   AAC_UINT32 _ReceiverTimeDone;       // Timestamp for completion of fib
9011 +               } _s;
9012 +       } _u;
9013 +#endif
9014 +} FIB_HEADER;
9015 +
9016 +
9017 +#define FibLinks                       _u._FibLinks
9018 +
9019 +
9020 +#define FIB_DATA_SIZE_IN_BYTES (512 - sizeof(FIB_HEADER))
9021 +
9022 +
9023 +typedef struct _FIB {
9024 +
9025 +#ifdef BRIDGE //rma
9026 +       DLQUE link;
9027 +#endif
9028 +    FIB_HEADER Header;
9029 +
9030 +    AAC_UINT8 data[FIB_DATA_SIZE_IN_BYTES];            // Command specific data
9031 +
9032 +} FIB;
9033 +typedef FIB *PFIB;
9034 +
9035 +
9036 +
9037 +//
9038 +// FIB commands
9039 +//
9040 +
9041 +typedef enum _FIB_COMMANDS {
9042 +    TestCommandResponse =                      1,
9043 +    TestAdapterCommand =                       2,
9044 +
9045 +       // Lowlevel and comm commands
9046 +
9047 +    LastTestCommand =                          100,
9048 +    ReinitHostNormCommandQueue =       101,
9049 +    ReinitHostHighCommandQueue =       102,
9050 +    ReinitHostHighRespQueue =          103,
9051 +    ReinitHostNormRespQueue =          104,
9052 +    ReinitAdapNormCommandQueue =       105,
9053 +    ReinitAdapHighCommandQueue =       107,
9054 +    ReinitAdapHighRespQueue =          108,
9055 +    ReinitAdapNormRespQueue =          109,
9056 +    InterfaceShutdown =                        110,
9057 +    DmaCommandFib =                            120,
9058 +    StartProfile =                                     121,
9059 +    TermProfile =                                      122,
9060 +    SpeedTest =                                        123,
9061 +    TakeABreakPt =                                     124,
9062 +    RequestPerfData =                          125,
9063 +    SetInterruptDefTimer=           126,
9064 +    SetInterruptDefCount=           127,
9065 +    GetInterruptDefStatus=          128,
9066 +    LastCommCommand =                          129,
9067 +
9068 +       // Filesystem commands
9069 +
9070 +    NuFileSystem =                                     300,
9071 +    UFS =                                                      301,
9072 +    HostFileSystem =                           302,
9073 +    LastFileSystemCommand =            303,
9074 +
9075 +       // Container Commands
9076 +
9077 +    ContainerCommand =                                 500,
9078 +       ContainerCommand64 =                    501,
9079 +
9080 +       // Cluster Commands
9081 +
9082 +    ClusterCommand =                           550,
9083 +
9084 +       // Scsi Port commands (scsi passthrough)
9085 +
9086 +    ScsiPortCommand =                          600,
9087 +
9088 +       // misc house keeping and generic adapter initiated commands
9089 +
9090 +    AifRequest =                                       700,
9091 +    CheckRevision =                                    701,
9092 +    FsaHostShutdown =                          702,
9093 +    RequestAdapterInfo =                       703,
9094 +    IsAdapterPaused =                          704,
9095 +    SendHostTime =                                     705,
9096 +    LastMiscCommand =                          706
9097 +
9098 +} _E_FIB_COMMANDS;
9099 +
9100 +
9101 +
9102 +typedef AAC_UINT16 FIB_COMMAND;
9103 +
9104 +//
9105 +// Commands that will target the failover level on the FSA adapter
9106 +//
9107 +
9108 +typedef enum _FIB_XFER_STATE {
9109 +    HostOwned                          = (1<<0),
9110 +    AdapterOwned                       = (1<<1),
9111 +    FibInitialized                     = (1<<2),
9112 +    FibEmpty                           = (1<<3),
9113 +    AllocatedFromPool          = (1<<4),
9114 +    SentFromHost                       = (1<<5),
9115 +    SentFromAdapter            = (1<<6),
9116 +    ResponseExpected           = (1<<7),
9117 +    NoResponseExpected                 = (1<<8),
9118 +    AdapterProcessed           = (1<<9),
9119 +    HostProcessed                      = (1<<10),
9120 +    HighPriority                       = (1<<11),
9121 +    NormalPriority                     = (1<<12),
9122 +    Async                                      = (1<<13),
9123 +    AsyncIo                                    = (1<<13),      // rpbfix: remove with new regime
9124 +    PageFileIo                         = (1<<14),      // rpbfix: remove with new regime
9125 +    ShutdownRequest                    = (1<<15),
9126 +    LazyWrite                          = (1<<16),      // rpbfix: remove with new regime
9127 +    AdapterMicroFib                    = (1<<17),
9128 +    BIOSFibPath                                = (1<<18),
9129 +    FastResponseCapable                = (1<<19),
9130 +       ApiFib                                  = (1<<20)       // Its an API Fib.
9131 +
9132 +} _E_FIB_XFER_STATE;
9133 +
9134 +
9135 +typedef enum _FSA_ERRORS {
9136 +    FSA_NORMAL                  = 0,
9137 +    FSA_SUCCESS                 = 0,
9138 +    FSA_PENDING                 = 0x01,
9139 +    FSA_FATAL                   = 0x02,
9140 +    FSA_INVALID_QUEUE           = 0x03,
9141 +    FSA_NOENTRIES               = 0x04,
9142 +    FSA_SENDFAILED              = 0x05,
9143 +    FSA_INVALID_QUEUE_PRIORITY  = 0x06,
9144 +    FSA_FIB_ALLOCATION_FAILED   = 0x07,
9145 +    FSA_FIB_DEALLOCATION_FAILED = 0x08
9146 +
9147 +} _E_FSA_ERRORS;
9148 +
9149 +
9150 +//
9151 +// The following defines needs to be updated any time there is an incompatible change made
9152 +// to the ADAPTER_INIT_STRUCT structure.
9153 +//
9154 +#define ADAPTER_INIT_STRUCT_REVISION           3
9155 +
9156 +typedef struct _ADAPTER_INIT_STRUCT {
9157 +       AAC_UINT32              InitStructRevision;
9158 +       AAC_UINT32              MiniPortRevision;
9159 +       AAC_UINT32              FilesystemRevision;
9160 +       PAAC_VOID               CommHeaderAddress;
9161 +       PAAC_VOID               FastIoCommAreaAddress;
9162 +       PAAC_VOID               AdapterFibsPhysicalAddress;
9163 +       PAAC_VOID               AdapterFibsVirtualAddress;
9164 +       AAC_UINT32              AdapterFibsSize;
9165 +       AAC_UINT32              AdapterFibAlign;
9166 +       PAAC_VOID               PrintfBufferAddress;
9167 +       AAC_UINT32              PrintfBufferSize;
9168 +       AAC_UINT32              HostPhysMemPages;               // number of 4k pages of host physical memory
9169 +       AAC_UINT32              HostElapsedSeconds;             // number of seconds since 1970.
9170 +} ADAPTER_INIT_STRUCT;
9171 +typedef ADAPTER_INIT_STRUCT *PADAPTER_INIT_STRUCT;
9172 +
9173 +#ifdef AAC_32BIT_ENUMS
9174 +typedef _E_FSA_ERRORS  FSA_ERRORS;
9175 +#else
9176 +typedef        AAC_UINT32              FSA_ERRORS;
9177 +#endif
9178 +
9179 +typedef enum _LOG_LEVEL {
9180 +       LOG_INIT                                = 10,
9181 +       LOG_INFORMATIONAL               = 20,
9182 +       LOG_WARNING                             = 30,
9183 +       LOG_LOW_ERROR                   = 40,
9184 +       LOG_MEDIUM_ERROR                = 50,
9185 +       LOG_HIGH_ERROR                  = 60,
9186 +       LOG_PANIC                               = 70,
9187 +       LOG_DEBUG                               = 80,
9188 +       LOG_WINDBG_PRINT                = 90
9189 +} _E_LOG_LEVEL;
9190 +
9191 +#ifdef AAC_32BIT_ENUMS
9192 +typedef _E_LOG_LEVEL   LOG_LEVEL;
9193 +#else
9194 +typedef        AAC_UINT32              LOG_LEVEL;
9195 +#endif
9196 +
9197 +
9198 +#endif //_COMM_STRUCT
9199 +
9200 +
9201 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/comsup.h linux/drivers/scsi/aacraid/include/comsup.h
9202 --- linux-2.4.4/drivers/scsi/aacraid/include/comsup.h   Wed Dec 31 18:00:00 1969
9203 +++ linux/drivers/scsi/aacraid/include/comsup.h Mon Apr 30 09:43:34 2001
9204 @@ -0,0 +1,132 @@
9205 +/*++
9206 + * Adaptec aacraid device driver for Linux.
9207 + *
9208 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9209 + *
9210 + * This program is free software; you can redistribute it and/or modify
9211 + * it under the terms of the GNU General Public License as published by
9212 + * the Free Software Foundation; either version 2, or (at your option)
9213 + * any later version.
9214 + *
9215 + * This program is distributed in the hope that it will be useful,
9216 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9217 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9218 + * GNU General Public License for more details.
9219 + *
9220 + * You should have received a copy of the GNU General Public License
9221 + * along with this program; see the file COPYING.  If not, write to
9222 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9223 + *
9224 + * Module Name:
9225 + *   comsup.h
9226 + *
9227 + * Abstract: This module defines the data structures that make up the 
9228 + *           commuication region for the FSA filesystem. This region is
9229 + *           how the host based code commuicates both control and data
9230 + *           to the adapter based code. 
9231 + *
9232 + *
9233 + *
9234 + --*/
9235 +#ifndef _COMM_SUP_DEF
9236 +#define _COMM_SUP_DEF
9237 +
9238 +static char *ident_comsup = "aacraid_ident comsup.h 1.0.6 2000/10/09 Adaptec, Inc.";
9239 +
9240 +//
9241 +// The adapter interface specs all queues to be located in the same physically
9242 +// contigous block. The host structure that defines the commuication queues will
9243 +// assume they are each a seperate physically contigous memory region that will
9244 +// support them all being one big contigous block.
9245 +// There is a command and response queue for each level and direction of
9246 +// commuication. These regions are accessed by both the host and adapter.
9247 +//
9248 +typedef struct _COMM_QUE {
9249 +
9250 +    PHYSICAL_ADDRESS LogicalAddress;    // This is the address we give the adapter
9251 +    
9252 +    PQUEUE_ENTRY       BaseAddress;        // This is the system virtual address 
9253 +    QUEUE_HEADERS      Headers;            // A pointer to the producer and consumer queue headers for this queue
9254 +    ULONG                      QueueEntries;       // Number of queue entries on this queue
9255 +    OS_CV_T                    QueueFull;          // Event to wait on if the queue is full
9256 +    OS_CV_T                    CommandReady;       // Indicates there is a Command ready from the adapter on this queue.
9257 +                                        // This is only valid for adapter to host command queues.                                        
9258 +    OS_SPINLOCK                *QueueLock;         // Spinlock for this queue must take this lock before accessing the lock
9259 +    KIRQL                      SavedIrql;          // Previous IRQL when the spin lock is taken
9260 +    ddi_softintr_t     ConsumerRoutine;    // The DPC routine which will consume entries off this queue
9261 +                                        // Only queues which the host will be the consumer will this field be valid
9262 +    LIST_ENTRY                 CommandQueue;       // A queue of FIBs which need to be prcessed by the FS thread. This is
9263 +                                        // only valid for command queues which receive entries from the adapter.
9264 +       LIST_ENTRY              OutstandingIoQueue;     // A queue of outstanding fib's to the adapter.
9265 +       ULONG                   NumOutstandingIos;      // Number of entries on outstanding queue.
9266 +
9267 +       PVOID                   Adapter;                        // Back pointer to adapter structure
9268 +
9269 +} COMM_QUE;
9270 +typedef COMM_QUE *PCOMM_QUE;
9271 +
9272 +
9273 +typedef struct _COMM_REGION {
9274 +
9275 +    COMM_QUE HostNormCmdQue;           // Command queue for normal priority commands from the host
9276 +    COMM_QUE HostNormRespQue;           // A response for normal priority adapter responses
9277 +    
9278 +    COMM_QUE HostHighCmdQue;            // Command queue for high priority commands from the host
9279 +    COMM_QUE HostHighRespQue;           // A response for normal priority adapter responses
9280 +    
9281 +    COMM_QUE AdapNormCmdQue;            // Command queue for normal priority command from the adapter
9282 +    COMM_QUE AdapNormRespQue;           // A response for normal priority host responses
9283 +
9284 +    COMM_QUE AdapHighCmdQue;            // Command queue for high priority command from the adapter
9285 +    COMM_QUE AdapHighRespQue;           // A response for high priority host responses
9286 +
9287 +    //
9288 +    // The 2 threads below are the threads which handle command traffic from the
9289 +    // the adapter. There is one for normal priority and one for high priority queues.
9290 +    // These threads will wait on the commandready event for it's queue.
9291 +    //
9292 +
9293 +    HANDLE NormCommandThread;
9294 +    HANDLE HighCommandThread;
9295 +
9296 +    //
9297 +    // This dpc routine will handle the setting the of not full event when the adapter
9298 +    // lets us know the queue is not longer full via interrupt
9299 +    //
9300 +
9301 +    KDPC QueueNotFullDpc;
9302 +
9303 +#ifdef API_THROTTLE
9304 +       //
9305 +       // Support for data I/O throttling to improve CLI performance
9306 +       // while the system is under load.
9307 +       // This is the throttling mechanism built into the COMM layer.
9308 +       // Look in commsup.c, dpcsup.c and comminit.c for use.
9309 +       //
9310 +
9311 +       int                             ThrottleLimit;                          // Max queue depth of data ops allowed during throttle
9312 +       int                             ThrottleOutstandingFibs;        // Number of data FIBs outstanding to adapter
9313 +       LARGE_INTEGER   ThrottleTimeout;                        // Duration of a a throttle period
9314 +       LARGE_INTEGER   ThrottleWaitTimeout;            // Timeout for a suspended threads to wait
9315 +       BOOLEAN                 ThrottleActive;                         // Is there a current throttle active period ?
9316 +       KTIMER                  ThrottleTimer;                          // Throttle timer to end a throttle period.
9317 +       KDPC                    ThrottleDpc;                            // Throttle timer timeout DPC routine.
9318 +       KSEMAPHORE              ThrottleReleaseSema;            // Semaphore callers of SendFib wait on during a throttle.
9319 +
9320 +       unsigned int    ThrottleExceptionsCount;        // Number of times throttle exception handler executed (0!)
9321 +       unsigned int    ThrottleTimerFires;                     // Debug info - #times throttle timer Dpc has fired
9322 +       unsigned int    ThrottleTimerSets;                      // Debug info - #times throttle timer was set
9323 +
9324 +       unsigned int    ThrottledFibs;
9325 +       unsigned int    ThrottleTimedoutFibs;
9326 +       unsigned int    ApiFibs;
9327 +       unsigned int    NonPassiveFibs;
9328 +       unsigned int    TotalFibs;
9329 +       unsigned int    FSInfoFibs;
9330 +
9331 +#endif // #ifdef API_THROTTLE
9332 +
9333 +} COMM_REGION;
9334 +typedef COMM_REGION *PCOMM_REGION;
9335 +
9336 +#endif // _COMM_SUP
9337 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/fsact.h linux/drivers/scsi/aacraid/include/fsact.h
9338 --- linux-2.4.4/drivers/scsi/aacraid/include/fsact.h    Wed Dec 31 18:00:00 1969
9339 +++ linux/drivers/scsi/aacraid/include/fsact.h  Mon Apr 30 09:43:34 2001
9340 @@ -0,0 +1,165 @@
9341 +/*++
9342 + * Adaptec aacraid device driver for Linux.
9343 + *
9344 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9345 + *
9346 + * This program is free software; you can redistribute it and/or modify
9347 + * it under the terms of the GNU General Public License as published by
9348 + * the Free Software Foundation; either version 2, or (at your option)
9349 + * any later version.
9350 + *
9351 + * This program is distributed in the hope that it will be useful,
9352 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9353 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9354 + * GNU General Public License for more details.
9355 + *
9356 + * You should have received a copy of the GNU General Public License
9357 + * along with this program; see the file COPYING.  If not, write to
9358 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9359 + *
9360 + * Module Name:
9361 + *   fsact.h
9362 + *
9363 + * Abstract:  Common container structures that are required to be
9364 + *            known on both the host and adapter.
9365 + *
9366 + *
9367 + --*/
9368 +#ifndef _FSACT_H_
9369 +#define        _FSACT_H_
9370 +
9371 +static char *ident_fsact = "aacraid_ident fsact.h 1.0.6 2000/10/09 Adaptec, Inc.";
9372 +
9373 +//#include <comstruc.h>
9374 +//#include <fsatypes.h>
9375 +#include <protocol.h> // definitions for FSASTATUS
9376 +
9377 +
9378 +/*
9379 + * Object-Server / Volume-Manager Dispatch Classes
9380 + */
9381 +typedef enum _VM_COMMANDS {
9382 +   VM_Null = 0,
9383 +   VM_NameServe,
9384 +   VM_ContainerConfig,
9385 +   VM_Ioctl,
9386 +   VM_FilesystemIoctl,
9387 +   VM_CloseAll,
9388 +   VM_CtBlockRead,             // see protocol.h for BlockRead command layout
9389 +   VM_CtBlockWrite,            // see protocol.h for BlockWrite command layout
9390 +   VM_SliceBlockRead,  // raw access to configured "storage objects"
9391 +   VM_SliceBlockWrite,
9392 +   VM_DriveBlockRead,  // raw access to physical devices
9393 +   VM_DriveBlockWrite,
9394 +   VM_EnclosureMgt,            // enclosure management
9395 +   VM_Unused,                  // used to be diskset management
9396 +   VM_CtBlockVerify,   // see protocol.h for BlockVerify command layout
9397 +   VM_CtPerf,                  // performance test
9398 +   VM_CtBlockRead64,   // see protocol.h for BlockRead64 command layout
9399 +   VM_CtBlockWrite64,  // see protocol.h for BlockWrite64 command layout
9400 +   VM_CtBlockVerify64, // see protocol.h for BlockVerify64 command layout   
9401 +   MAX_VMCOMMAND_NUM   // used for sizing stats array - leave last
9402 +} _E_VMCOMMAND;
9403 +
9404 +#ifdef AAC_32BIT_ENUMS
9405 +typedef _E_VMCOMMAND   VMCOMMAND;
9406 +#else
9407 +typedef        AAC_UINT32              VMCOMMAND;
9408 +#endif
9409 +
9410 +
9411 +
9412 +//
9413 +// Descriptive information (eg, vital stats)
9414 +// that a content manager might report.  The
9415 +// FileArray filesystem component is one example
9416 +// of a content manager.  Raw mode might be
9417 +// another.
9418 +//
9419 +
9420 +struct FileSysInfo {
9421 +/*
9422 +       a) DOS usage - THINK ABOUT WHERE THIS MIGHT GO -- THXXX
9423 +       b) FSA usage (implemented by ObjType and ContentState fields)
9424 +       c) Block size
9425 +       d) Frag size
9426 +       e) Max file system extension size - (fsMaxExtendSize * fsSpaceUnits)
9427 +       f) I-node density - (computed from other fields)
9428 +*/
9429 +       AAC_UINT32  fsTotalSize;        // consumed by fs, incl. metadata
9430 +       AAC_UINT32  fsBlockSize;
9431 +       AAC_UINT32  fsFragSize;
9432 +       AAC_UINT32  fsMaxExtendSize;
9433 +       AAC_UINT32  fsSpaceUnits;
9434 +       AAC_UINT32  fsMaxNumFiles;
9435 +       AAC_UINT32  fsNumFreeFiles;
9436 +       AAC_UINT32  fsInodeDensity;
9437 +};     // valid iff ObjType == FT_FILESYS && !(ContentState & FSCS_NOTCLEAN)
9438 +
9439 +union ContentManagerInfo {
9440 +       struct FileSysInfo FileSys;     // valid iff ObjType == FT_FILESYS && !(ContentState & FSCS_NOTCLEAN)
9441 +};
9442 +
9443 +//
9444 +// Query for "mountable" objects, ie, objects that are typically
9445 +// associated with a drive letter on the client (host) side.
9446 +//
9447 +
9448 +typedef struct _MNTOBJ {
9449 +
9450 +   AAC_UINT32    ObjectId;
9451 +   FSASTRING  FileSystemName;   // if applicable
9452 +   ContainerCreationInfo   CreateInfo; // if applicable
9453 +   AAC_UINT32    Capacity;
9454 +   FSAVOLTYPE VolType;          // substrate structure
9455 +   FTYPE      ObjType;          // FT_FILESYS, FT_DATABASE, etc.
9456 +   AAC_UINT32     ContentState;     // unready for mounting, readonly, etc.
9457 +
9458 +   union ContentManagerInfo
9459 +              ObjExtension;     // Info specific to content manager (eg, filesystem)
9460 +
9461 +   AAC_UINT32    AlterEgoId;       // != ObjectId <==> snapshot or broken mirror exists
9462 +
9463 +} MNTOBJ;
9464 +
9465 +
9466 +#define FSCS_READONLY  0x0002  // possible result of broken mirror
9467 +
9468 +
9469 +
9470 +typedef struct _MNTINFO {
9471 +
9472 +   VMCOMMAND  Command;
9473 +   FTYPE      MntType;
9474 +   AAC_UINT32     MntCount;
9475 +
9476 +} MNTINFO;
9477 +typedef MNTINFO *PMNTINFO;
9478 +
9479 +typedef struct _MNTINFORESPONSE {
9480 +
9481 +   FSASTATUS Status;
9482 +   FTYPE     MntType;           // should be same as that requested
9483 +   AAC_UINT32    MntRespCount;
9484 +   MNTOBJ    MntTable[1];
9485 +
9486 +} MNTINFORESPONSE;
9487 +typedef MNTINFORESPONSE *PMNTINFORESPONSE;
9488 +
9489 +
9490 +//
9491 +// The following command is sent to shut down each container.
9492 +//
9493 +
9494 +typedef struct _CLOSECOMMAND {
9495 +
9496 +   VMCOMMAND  Command;
9497 +   AAC_UINT32    ContainerId;
9498 +
9499 +} CLOSECOMMAND;
9500 +typedef CLOSECOMMAND *PCLOSECOMMAND;
9501 +
9502 +
9503 +#endif /* _FSACT_H_ */
9504 +
9505 +
9506 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/fsafs.h linux/drivers/scsi/aacraid/include/fsafs.h
9507 --- linux-2.4.4/drivers/scsi/aacraid/include/fsafs.h    Wed Dec 31 18:00:00 1969
9508 +++ linux/drivers/scsi/aacraid/include/fsafs.h  Mon Apr 30 09:43:34 2001
9509 @@ -0,0 +1,78 @@
9510 +/*++
9511 + * Adaptec aacraid device driver for Linux.
9512 + *
9513 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9514 + *
9515 + * This program is free software; you can redistribute it and/or modify
9516 + * it under the terms of the GNU General Public License as published by
9517 + * the Free Software Foundation; either version 2, or (at your option)
9518 + * any later version.
9519 + *
9520 + * This program is distributed in the hope that it will be useful,
9521 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9522 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9523 + * GNU General Public License for more details.
9524 + *
9525 + * You should have received a copy of the GNU General Public License
9526 + * along with this program; see the file COPYING.  If not, write to
9527 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9528 + *
9529 + * Module Name:
9530 + *   fsafs.h
9531 + *
9532 + * Abstract: Common file system structures that are required to be
9533 + *           known on both the host and adapter
9534 + *
9535 + *
9536 + *
9537 + --*/
9538 +
9539 +#ifndef _FSAFS_H_
9540 +#define        _FSAFS_H_ 1
9541 +
9542 +static char *ident_fsafs = "aacraid_ident fsafs.h 1.0.6 2000/10/09 Adaptec, Inc.";
9543 +
9544 +#include <fsatypes.h>   // core types, shared by client and server, eg, u_long
9545 +
9546 +/*
9547 + *  Maximum number of filesystems.
9548 + */
9549 +#define NFILESYS   24
9550 +
9551 +/*
9552 + * File identifier.
9553 + * These are unique and self validating within a filesystem
9554 + * on a single machine and can persist across reboots.
9555 + * The hint field may be volatile and is not guaranteed to persist
9556 + * across reboots but is used to speed up the FID to file object translation
9557 + * if possible. The opaque f1 and f2 fields are guaranteed to uniquely identify
9558 + * the file object (assuming a filesystem context, i.e. driveno).
9559 + */
9560 +typedef struct {
9561 +                               AAC_UINT32  hint; // last used hint for fast reclaim
9562 +                               AAC_UINT32  f1;   // opaque
9563 +                               AAC_UINT32  f2;   // opaque
9564 +                       } fileid_t;             /* intra-filesystem file ID type */
9565 +
9566 +       
9567 +/*
9568 + * Generic file handle
9569 + */
9570 +struct fhandle {
9571 +       fsid_t   fh_fsid;       /* File system id of mount point */
9572 +       fileid_t fh_fid;        /* File sys specific file id */
9573 +};
9574 +typedef struct fhandle fhandle_t;
9575 +
9576 +#define        FIDSIZE         sizeof(fhandle_t)
9577 +
9578 +typedef struct {
9579 +       union {
9580 +               AAC_INT8        fid_data[FIDSIZE];
9581 +               struct  fhandle fsafid;
9582 +       } fidu;
9583 +} FSAFID;                                      /* FSA File ID type */
9584 +
9585 +                                                               
9586 +#endif /* _FSAFS_H_ */
9587 +
9588 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/fsaioctl.h linux/drivers/scsi/aacraid/include/fsaioctl.h
9589 --- linux-2.4.4/drivers/scsi/aacraid/include/fsaioctl.h Wed Dec 31 18:00:00 1969
9590 +++ linux/drivers/scsi/aacraid/include/fsaioctl.h       Mon Apr 30 09:43:34 2001
9591 @@ -0,0 +1,159 @@
9592 +/*++
9593 + * Adaptec aacraid device driver for Linux.
9594 + *
9595 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9596 + *
9597 + * This program is free software; you can redistribute it and/or modify
9598 + * it under the terms of the GNU General Public License as published by
9599 + * the Free Software Foundation; either version 2, or (at your option)
9600 + * any later version.
9601 + *
9602 + * This program is distributed in the hope that it will be useful,
9603 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9604 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9605 + * GNU General Public License for more details.
9606 + *
9607 + * You should have received a copy of the GNU General Public License
9608 + * along with this program; see the file COPYING.  If not, write to
9609 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9610 + *
9611 + * Module Name:
9612 + *   fsaioctl.h
9613 + *
9614 + * Abstract: Defines the interface structures between user mode applications
9615 + *           and the fsa driver.  This structures are used in 
9616 + *           DeviceIoControl() calls.
9617 + *
9618 + *
9619 + *
9620 + --*/
9621 +#ifndef _FSAIOCTL_H_
9622 +#define _FSAIOCTL_H_
9623 +
9624 +static char *ident_fsaioctl = "aacraid_ident fsaioctl.h 1.0.6 2000/10/09 Adaptec, Inc.";
9625 +
9626 +#ifndef IOTRACEUSER
9627 +
9628 +#ifndef CTL_CODE
9629 +
9630 +
9631 +#define FILE_DEVICE_CONTROLLER          0x00000004
9632 +
9633 +//
9634 +// Macro definition for defining IOCTL and FSCTL function control codes.  Note
9635 +// that function codes 0-2047 are reserved for Microsoft Corporation, and
9636 +// 2048-4095 are reserved for customers.
9637 +//
9638 +
9639 +#define CTL_CODE( DeviceType, Function, Method, Access ) (                 \
9640 +    ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
9641 +)
9642 +
9643 +//
9644 +// Define the method codes for how buffers are passed for I/O and FS controls
9645 +//
9646 +
9647 +#define METHOD_BUFFERED                 0
9648 +
9649 +
9650 +#define METHOD_NEITHER                  3
9651 +
9652 +//
9653 +// Define the access check value for any access
9654 +//
9655 +//
9656 +// The FILE_READ_ACCESS and FILE_WRITE_ACCESS constants are also defined in
9657 +// ntioapi.h as FILE_READ_DATA and FILE_WRITE_DATA. The values for these
9658 +// constants *MUST* always be in sync.
9659 +//
9660 +#define FILE_ANY_ACCESS                 0
9661 +
9662 +
9663 +
9664 +#endif
9665 +
9666 +
9667 +
9668 +typedef struct _UNIX_QUERY_DISK {
9669 +       AAC_INT32       ContainerNumber;
9670 +       AAC_INT32       Bus;
9671 +       AAC_INT32       Target;
9672 +       AAC_INT32       Lun;
9673 +       AAC_BOOLEAN     Valid;
9674 +       AAC_BOOLEAN     Locked;
9675 +       AAC_BOOLEAN     Deleted;
9676 +       AAC_INT32       Instance;
9677 +       AAC_INT8        diskDeviceName[10];
9678 +       AAC_BOOLEAN UnMapped;
9679 +} UNIX_QUERY_DISK;
9680 +typedef UNIX_QUERY_DISK *PUNIX_QUERY_DISK;
9681 +
9682 +
9683 +typedef struct _DELETE_DISK {
9684 +       AAC_UINT32      NtDiskNumber;
9685 +       AAC_UINT32      ContainerNumber;
9686 +} DELETE_DISK;
9687 +typedef DELETE_DISK *PDELETE_DISK;
9688 +
9689 +
9690 +#endif /*IOTRACEUSER*/
9691 +
9692 +#define FSACTL_NULL_IO_TEST             0x43    // CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 2048, METHOD_NEITHER, FILE_ANY_ACCESS)
9693 +#define FSACTL_SIM_IO_TEST              0x53    // CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 2049, METHOD_NEITHER, FILE_ANY_ACCESS)
9694 +
9695 +
9696 +#define FSACTL_SENDFIB                  CTL_CODE(FILE_DEVICE_CONTROLLER, 2050, METHOD_BUFFERED, FILE_ANY_ACCESS)
9697 +
9698 +
9699 +#define FSACTL_GET_VAR                                 0x93
9700 +#define FSACTL_SET_VAR                                 0xa3
9701 +#define FSACTL_GET_FIBTIMES                            0xb3
9702 +#define FSACTL_ZERO_FIBTIMES                   0xc3
9703 +
9704 +
9705 +#define FSACTL_DELETE_DISK                             0x163
9706 +#define FSACTL_QUERY_DISK                              0x173
9707 +
9708 +
9709 +// AfaComm perfmon ioctls
9710 +#define FSACTL_GET_COMM_PERF_DATA              CTL_CODE(FILE_DEVICE_CONTROLLER, 2084, METHOD_BUFFERED, FILE_ANY_ACCESS)
9711 +
9712 +
9713 +#define FSACTL_OPENCLS_COMM_PERF_DATA  CTL_CODE(FILE_DEVICE_CONTROLLER, 2085, METHOD_BUFFERED, FILE_ANY_ACCESS)
9714 +
9715 +
9716 +typedef struct _GET_ADAPTER_FIB_IOCTL {
9717 +       char    *AdapterFibContext;
9718 +       int             Wait;
9719 +       char    *AifFib;
9720 +} GET_ADAPTER_FIB_IOCTL, *PGET_ADAPTER_FIB_IOCTL;
9721 +
9722 +//
9723 +// filesystem ioctls
9724 +//
9725 +#define FSACTL_OPEN_GET_ADAPTER_FIB            CTL_CODE(FILE_DEVICE_CONTROLLER, 2100, METHOD_BUFFERED, FILE_ANY_ACCESS)
9726 +
9727 +#define FSACTL_GET_NEXT_ADAPTER_FIB            CTL_CODE(FILE_DEVICE_CONTROLLER, 2101, METHOD_BUFFERED, FILE_ANY_ACCESS)
9728 +
9729 +#define FSACTL_CLOSE_GET_ADAPTER_FIB   CTL_CODE(FILE_DEVICE_CONTROLLER, 2102, METHOD_BUFFERED, FILE_ANY_ACCESS)
9730 +
9731 +#define FSACTL_OPEN_ADAPTER_CONFIG             CTL_CODE(FILE_DEVICE_CONTROLLER, 2103, METHOD_NEITHER, FILE_ANY_ACCESS)
9732 +
9733 +#define FSACTL_CLOSE_ADAPTER_CONFIG            CTL_CODE(FILE_DEVICE_CONTROLLER, 2104, METHOD_NEITHER, FILE_ANY_ACCESS)
9734 +
9735 +
9736 +#define FSACTL_MINIPORT_REV_CHECK              CTL_CODE(FILE_DEVICE_CONTROLLER, 2107, METHOD_BUFFERED, FILE_ANY_ACCESS)
9737 +
9738 +
9739 +#define FSACTL_QUERY_ADAPTER_CONFIG            CTL_CODE(FILE_DEVICE_CONTROLLER, 2113, METHOD_BUFFERED, FILE_ANY_ACCESS)
9740 +
9741 +
9742 +#define FSACTL_FORCE_DELETE_DISK               CTL_CODE(FILE_DEVICE_CONTROLLER, 2120, METHOD_NEITHER, FILE_ANY_ACCESS)
9743 +
9744 +
9745 +#define FSACTL_AIF_THREAD                              CTL_CODE(FILE_DEVICE_CONTROLLER, 2127, METHOD_NEITHER, FILE_ANY_ACCESS)
9746 +
9747 +
9748 +#endif // _FSAIOCTL_H_
9749 +
9750 +
9751 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/fsaport.h linux/drivers/scsi/aacraid/include/fsaport.h
9752 --- linux-2.4.4/drivers/scsi/aacraid/include/fsaport.h  Wed Dec 31 18:00:00 1969
9753 +++ linux/drivers/scsi/aacraid/include/fsaport.h        Mon Apr 30 09:43:34 2001
9754 @@ -0,0 +1,223 @@
9755 +/*++
9756 + * Adaptec aacraid device driver for Linux.
9757 + *
9758 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9759 + *
9760 + * This program is free software; you can redistribute it and/or modify
9761 + * it under the terms of the GNU General Public License as published by
9762 + * the Free Software Foundation; either version 2, or (at your option)
9763 + * any later version.
9764 + *
9765 + * This program is distributed in the hope that it will be useful,
9766 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9767 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9768 + * GNU General Public License for more details.
9769 + *
9770 + * You should have received a copy of the GNU General Public License
9771 + * along with this program; see the file COPYING.  If not, write to
9772 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9773 + *
9774 + * Module Name:
9775 + *   fsaport.h
9776 + *
9777 + * Abstract: This module defines all of the globally used procedures in the FSA
9778 + *           file system.
9779 + *
9780 + *
9781 + *
9782 + --*/
9783 +#ifndef _FSAPORT_
9784 +#define _FSAPORT_
9785 +
9786 +static char *ident_fsaport = "aacraid_ident fsaport.h 1.0.6 2000/10/09 Adaptec, Inc.";
9787 +
9788 +//
9789 +// The scatter/gather map context is the information we 
9790 +// we need to keep the map and transfer data to and from the
9791 +// adapter.
9792 +//
9793 +
9794 +typedef struct _SGMAP_CONTEXT {
9795 +       
9796 +       caddr_t         BaseAddress;
9797 +    PVOID              MapRegBase;
9798 +    ULONG              NumberMapRegs;
9799 +       PSGMAP          SgMapPtr;
9800 +       ULONG           ByteCount;              // Used to check the Mdl length.
9801 +       BOOLEAN         WriteToDevice;
9802 +
9803 +       struct buf      *bp;
9804 +
9805 +
9806 +} SGMAP_CONTEXT;
9807 +typedef SGMAP_CONTEXT *PSGMAP_CONTEXT;
9808 +
9809 +typedef struct _MAPFIB_CONTEXT {
9810 +       PMDL            Mdl;    
9811 +    PVOID              MapRegBase;
9812 +    ULONG              NumberMapRegs;
9813 +       PVOID           FibVirtualAddress;
9814 +       ULONG           Size;
9815 +       PVOID       FibPhysicalAddress;
9816 +
9817 +
9818 +} MAPFIB_CONTEXT;
9819 +typedef MAPFIB_CONTEXT *PMAPFIB_CONTEXT;
9820 +
9821 +typedef BOOLEAN
9822 +(*PFSA_ALLOCATE_ADAPTER_COMM_AREA)(
9823 +       PVOID AdapterExtension,
9824 +       IN OUT PVOID    *BaseAddress,
9825 +       IN ULONG                Size,
9826 +       IN ULONG                Alignment
9827 +       );
9828 +
9829 +typedef BOOLEAN
9830 +(*PFSA_FREE_ADAPTER_COMM_AREA)(
9831 +       PVOID   AdapterExtension
9832 +       );
9833 +
9834 +typedef VOID
9835 +(*PFSA_FREE_DMA_RESOURCES)(     
9836 +       IN PVOID AdapterExtension,
9837 +    IN PSGMAP_CONTEXT SgMapContext
9838 +    );
9839 +
9840 +typedef BOOLEAN
9841 +(*PFSA_ALLOCATE_AND_MAP_FIB_SPACE)(
9842 +       IN PVOID AdapterExtension, 
9843 +       IN PMAPFIB_CONTEXT MapFibContext
9844 +    );
9845 +
9846 +typedef BOOLEAN
9847 +(*PFSA_UNMAP_AND_FREE_FIB_SPACE)(
9848 +       IN PVOID AdapterExtension, 
9849 +       IN PMAPFIB_CONTEXT MapFibContext
9850 +    );
9851 +
9852 +typedef VOID
9853 +(*PFSA_INTERRUPT_ADAPTER)(
9854 +       IN PVOID AdapterExtension
9855 +       );
9856 +
9857 +typedef VOID
9858 +(*PFSA_NOTIFY_ADAPTER)(
9859 +       IN PVOID AdapterExtension,
9860 +    IN HOST_2_ADAP_EVENT AdapterEvent
9861 +    );
9862 +
9863 +typedef VOID
9864 +(*PFSA_RESET_DEVICE)(
9865 +       PVOID AdapterExtension
9866 +       );
9867 +
9868 +typedef AAC_STATUS
9869 +(*PFSA_BUILD_SGMAP)(  
9870 +       IN PVOID AdapterExtension,
9871 +       IN PSGMAP_CONTEXT SgMapContext
9872 +       );
9873 +
9874 +typedef PVOID
9875 +(*PFSA_ADAPTER_ADDR_TO_SYSTEM_ADDR)(  
9876 +       IN PVOID AdapterExtension,
9877 +       IN PVOID AdapterAddress
9878 +       );
9879 +
9880 +typedef VOID
9881 +(*PFSA_INTERRUPT_HOST)(
9882 +       PVOID                   Adapter,
9883 +       ADAPTER_EVENT   AdapterEvent
9884 +       );
9885 +
9886 +typedef VOID
9887 +(*PFSA_ENABLE_INTERRUPT)(
9888 +       PVOID                   Adapter,
9889 +       ADAPTER_EVENT   AdapterEvent,
9890 +       BOOLEAN                 AtDeviceIrq
9891 +       );
9892 +
9893 +
9894 +typedef VOID
9895 +(*PFSA_DISABLE_INTERRUPT)(
9896 +       PVOID                   Adapter,
9897 +       ADAPTER_EVENT   AdapterEvent,
9898 +       BOOLEAN                 AtDeviceIrq
9899 +       );
9900 +
9901 +typedef AAC_STATUS
9902 +(*PFSA_OPEN_ADAPTER) (
9903 +       IN PVOID Adapter
9904 +       );
9905 +
9906 +typedef int
9907 +(*PFSA_DEVICE_CONTROL) (
9908 +       IN PVOID Adapter,
9909 +       IN PAFA_IOCTL_CMD IoctlCmdPtr
9910 +       );
9911 +
9912 +typedef AAC_STATUS
9913 +(*PFSA_CLOSE_ADAPTER) (
9914 +       IN PVOID Adapter
9915 +       );
9916 +
9917 +typedef BOOLEAN
9918 +(*PFSA_SEND_SYNCH_FIB) (
9919 +       IN PVOID Adapter,
9920 +       IN ULONG FibPhysicalAddress
9921 +       );
9922 +
9923 +typedef struct _FSAPORT_FUNCS {
9924 +       ULONG                                                           SizeOfFsaPortFuncs;
9925 +
9926 +       PFSA_ALLOCATE_ADAPTER_COMM_AREA         AllocateAdapterCommArea;
9927 +       PFSA_FREE_ADAPTER_COMM_AREA                     FreeAdapterCommArea;
9928 +       PFSA_FREE_DMA_RESOURCES                         FreeDmaResources;
9929 +       PFSA_ALLOCATE_AND_MAP_FIB_SPACE         AllocateAndMapFibSpace;
9930 +       PFSA_UNMAP_AND_FREE_FIB_SPACE           UnmapAndFreeFibSpace;
9931 +       PFSA_INTERRUPT_ADAPTER                          InterruptAdapter;
9932 +       PFSA_NOTIFY_ADAPTER                                     NotifyAdapter;
9933 +       PFSA_ENABLE_INTERRUPT                           EnableInterrupt;
9934 +       PFSA_DISABLE_INTERRUPT                          DisableInterrupt;
9935 +       PFSA_RESET_DEVICE                                       ResetDevice;
9936 +       PFSA_BUILD_SGMAP                                        BuildSgMap;
9937 +       PFSA_ADAPTER_ADDR_TO_SYSTEM_ADDR        AdapterAddressToSystemAddress;
9938 +
9939 +       PFSA_INTERRUPT_HOST                                     InterruptHost;
9940 +       PFSA_OPEN_ADAPTER                                       OpenAdapter;
9941 +       PFSA_DEVICE_CONTROL                                     DeviceControl;
9942 +       PFSA_CLOSE_ADAPTER                                      CloseAdapter;
9943 +
9944 +       PFSA_SEND_SYNCH_FIB                                     SendSynchFib;
9945 +
9946 +} FSAPORT_FUNCS;
9947 +typedef FSAPORT_FUNCS *PFSAPORT_FUNCS;
9948 +
9949 +typedef AAC_STATUS
9950 +(*PFSA_SETVAR_CALLBACK) (
9951 +       IN PVOID Adapter,
9952 +       IN ULONG NewValue
9953 +       );
9954 +
9955 +typedef struct _FSA_USER_VAR {
9956 +       char                                    Name[32];
9957 +       ULONG                                   *Address;
9958 +       PFSA_SETVAR_CALLBACK    SetVarCallback;
9959 +} FSA_USER_VAR;
9960 +
9961 +typedef FSA_USER_VAR *PFSA_USER_VAR;
9962 +
9963 +typedef struct _FSA_NEW_ADAPTER {
9964 +       PVOID                           AdapterExtension;
9965 +       PFSAPORT_FUNCS          AdapterFuncs;
9966 +       PVOID                           Adapter;
9967 +       BOOLEAN                         AdapterInterruptsBelowDpc;
9968 +       PFSA_USER_VAR           AdapterUserVars;
9969 +       ULONG                           AdapterUserVarsSize;
9970 +       void                            *Dip;
9971 +} FSA_NEW_ADAPTER;
9972 +typedef FSA_NEW_ADAPTER *PFSA_NEW_ADAPTER;
9973 +
9974 +#define        FSAFS_GET_NEXT_ADAPTER                  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 2048, METHOD_NEITHER, FILE_ANY_ACCESS)
9975 +#define        FSAFS_INIT_NEW_ADAPTER                  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 2049, METHOD_NEITHER, FILE_ANY_ACCESS)
9976 +
9977 +#endif
9978 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/fsatypes.h linux/drivers/scsi/aacraid/include/fsatypes.h
9979 --- linux-2.4.4/drivers/scsi/aacraid/include/fsatypes.h Wed Dec 31 18:00:00 1969
9980 +++ linux/drivers/scsi/aacraid/include/fsatypes.h       Mon Apr 30 09:43:34 2001
9981 @@ -0,0 +1,214 @@
9982 +/*++
9983 + * Adaptec aacraid device driver for Linux.
9984 + *
9985 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9986 + *
9987 + * This program is free software; you can redistribute it and/or modify
9988 + * it under the terms of the GNU General Public License as published by
9989 + * the Free Software Foundation; either version 2, or (at your option)
9990 + * any later version.
9991 + *
9992 + * This program is distributed in the hope that it will be useful,
9993 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9994 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9995 + * GNU General Public License for more details.
9996 + *
9997 + * You should have received a copy of the GNU General Public License
9998 + * along with this program; see the file COPYING.  If not, write to
9999 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10000 + *
10001 + * Module Name:
10002 + *   fsatypes.h
10003 + *
10004 + * Abstract: Define all shared data types here, ie, those
10005 + *           types shared among several components, such
10006 + *           as host (driver + apps), adapter, and BIOS.
10007 + *
10008 + *
10009 + --*/
10010 +#ifndef _FSATYPES_H
10011 +#define _FSATYPES_H
10012 +
10013 +static char *ident_fsatype = "aacraid_ident fsatypes.h 1.0.6 2000/10/09 Adaptec, Inc.";
10014 +
10015 +typedef        AAC_UINT32              AAC_BOOLEAN;
10016 +
10017 +//
10018 +// Define a 64-bit address structure for use on
10019 +// a 32-bit processor architecture.
10020 +//
10021 +typedef struct {
10022 +       AAC_UINT32              lo32;
10023 +       AAC_UINT32              hi32;
10024 +} AAC_UINT64S, *PAAC_UINT64S;
10025 +
10026 +
10027 +
10028 +//
10029 +// Container Types
10030 +//
10031 +typedef struct {
10032 +   AAC_UINT32 data[2];  // RMA FIX, make this a real serial number when we
10033 +                           // know what it looks like.  Note, BIOS sees this
10034 +                           // definition and it must be coded in such a way
10035 +                           // that it appears to be 64 bits.  ints are 16 bits
10036 +                           // in BIOS land; fortunately, longs are 32 bits.
10037 +} SerialNumberT;
10038 +
10039 +
10040 +
10041 +//
10042 +//     ***********************
10043 +//     DON'T CHANGE THE ORDER, ctdevsw use this order to map the drivers
10044 +//     ***********************
10045 +//     drivers for CT_NONE to CT_PASSTHRU
10046 +//
10047 +typedef enum _FSAVOLTYPE {
10048 +       CT_NONE = 0,                            
10049 +       CT_VOLUME,                                      
10050 +       CT_MIRROR,
10051 +       CT_STRIPE,
10052 +       CT_RAID5,
10053 +       CT_SSRW,
10054 +       CT_SSRO,
10055 +       CT_MORPH,
10056 +       CT_PASSTHRU,
10057 +       CT_RAID4,
10058 +       CT_RAID10,                                      // stripe of mirror
10059 +       CT_RAID00,                                      // stripe of stripe
10060 +       CT_VOLUME_OF_MIRRORS,           // volume of mirror
10061 +       CT_PSEUDO_RAID3,                        // really raid4
10062 +
10063 +       CT_LAST_VOLUME_TYPE
10064 +
10065 +} _E_FSAVOLTYPE;
10066 +
10067 +#ifdef AAC_32BIT_ENUMS
10068 +typedef        _E_FSAVOLTYPE   FSAVOLTYPE;
10069 +#else
10070 +typedef        AAC_UINT32              FSAVOLTYPE;
10071 +#endif
10072 +
10073 +
10074 +//
10075 +// Types of objects addressable in some fashion by the client.
10076 +// This is a superset of those objects handled just by the filesystem
10077 +// and includes "raw" objects that an administrator would use to
10078 +// configure containers and filesystems.
10079 +//
10080 +typedef enum _FTYPE {
10081 +    FT_REG = 1,     // regular file
10082 +    FT_DIR,         // directory
10083 +    FT_BLK,         // "block" device - reserved
10084 +    FT_CHR,         // "character special" device - reserved
10085 +    FT_LNK,         // symbolic link
10086 +    FT_SOCK,        // socket
10087 +    FT_FIFO,        // fifo
10088 +    FT_FILESYS,     // ADAPTEC's "FSA"(tm) filesystem
10089 +    FT_DRIVE,       // physical disk - addressable in scsi by bus/target/lun
10090 +    FT_SLICE,       // virtual disk - raw volume - slice
10091 +    FT_PARTITION,   // FSA partition - carved out of a slice - building block for containers
10092 +    FT_VOLUME,      // Container - Volume Set
10093 +    FT_STRIPE,      // Container - Stripe Set
10094 +    FT_MIRROR,      // Container - Mirror Set
10095 +    FT_RAID5,       // Container - Raid 5 Set
10096 +    FT_DATABASE     // Storage object with "foreign" content manager
10097 +} _E_FTYPE;
10098 +
10099 +#ifdef AAC_32BIT_ENUMS
10100 +typedef        _E_FTYPE        FTYPE;
10101 +#else
10102 +typedef        AAC_UINT32      FTYPE;
10103 +#endif
10104 +
10105 +
10106 +
10107 +//
10108 +// Host side memory scatter gather list
10109 +// Used by the adapter for read, write, and readdirplus operations
10110 +//
10111 +typedef  PAAC_UINT8 HOSTADDRESS;
10112 +
10113 +typedef struct _SGENTRY {
10114 +       HOSTADDRESS             SgAddress;              /* 32-bit Base address. */
10115 +       AAC_UINT32                      SgByteCount;    /* Length. */
10116 +} SGENTRY;
10117 +typedef SGENTRY *PSGENTRY;
10118 +
10119 +
10120 +
10121 +//
10122 +// SGMAP
10123 +//
10124 +// This is the SGMAP structure for all commands that use
10125 +// 32-bit addressing.
10126 +//
10127 +// Note that the upper 16 bits of SgCount are used as flags.
10128 +// Only the lower 16 bits of SgCount are actually used as the
10129 +// SG element count.
10130 +//
10131 +typedef struct _SGMAP {
10132 +       AAC_UINT32              SgCount;
10133 +       SGENTRY                 SgEntry[1];
10134 +} SGMAP;
10135 +typedef SGMAP *PSGMAP;
10136 +
10137 +
10138 +
10139 +//
10140 +// SGMAP64
10141 +//
10142 +// This is the SGMAP structure for 64-bit container commands.
10143 +//
10144 +typedef struct _SGMAP64 {
10145 +       AAC_UINT8       SgCount;
10146 +       AAC_UINT8       SgSectorsPerPage;
10147 +       AAC_UINT16      SgByteOffset; // For the first page 
10148 +       AAC_UINT64S     SgEntry[1];     // Must be last entry
10149 +} SGMAP64;
10150 +typedef SGMAP64 *PSGMAP64;
10151 +
10152 +
10153 +
10154 +
10155 +//
10156 +// attempt at common time structure across host and adapter
10157 +//
10158 +typedef struct __TIME_T {
10159 +
10160 +       AAC_UINT32      tv_sec;         /* seconds (maybe, depends upon host) */
10161 +       AAC_UINT32      tv_usec;        /* and nanoseconds (maybe, depends upon host)*/
10162 +
10163 +} TIME_T;
10164 +typedef TIME_T *PTIME_T;
10165 +
10166 +#ifndef _TIME_T
10167 +#define timespec __TIME_T
10168 +#define ts_sec tv_sec
10169 +#define ts_nsec        tv_usec
10170 +#endif
10171 +
10172 +
10173 +
10174 +
10175 +typedef struct _ContainerCreationInfo
10176 +{
10177 +
10178 +       AAC_UINT8               ViaBuildNumber;         // e.g., 588
10179 +       AAC_UINT8               MicroSecond;            // e.g., 588
10180 +       AAC_UINT8               Via;                            // e.g.,        1 = FSU,
10181 +                                                                               //                      2 = API,
10182 +       AAC_UINT8               YearsSince1900;         // e.g., 1997 = 97
10183 +       AAC_UINT32              Date;                   //
10184 +                                                                               // unsigned     Month           :4;             // 1 - 12
10185 +                                                                               // unsigned     Day                     :6;             // 1 - 32
10186 +                                                                               // unsigned     Hour            :6;             // 0 - 23
10187 +                                                                               // unsigned     Minute          :6;             // 0 - 60
10188 +                                                                               // unsigned     Second          :6;             // 0 - 60
10189 +       SerialNumberT   ViaAdapterSerialNumber; // e.g., 0x1DEADB0BFAFAF001
10190 +} ContainerCreationInfo;
10191 +
10192 +
10193 +#endif // _FSATYPES_H
10194 +
10195 +
10196 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/linit.h linux/drivers/scsi/aacraid/include/linit.h
10197 --- linux-2.4.4/drivers/scsi/aacraid/include/linit.h    Wed Dec 31 18:00:00 1969
10198 +++ linux/drivers/scsi/aacraid/include/linit.h  Mon Apr 30 09:43:34 2001
10199 @@ -0,0 +1,107 @@
10200 +/*++
10201 + * Adaptec aacraid device driver for Linux.
10202 + *
10203 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10204 + *
10205 + * This program is free software; you can redistribute it and/or modify
10206 + * it under the terms of the GNU General Public License as published by
10207 + * the Free Software Foundation; either version 2, or (at your option)
10208 + * any later version.
10209 + *
10210 + * This program is distributed in the hope that it will be useful,
10211 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10212 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10213 + * GNU General Public License for more details.
10214 + *
10215 + * You should have received a copy of the GNU General Public License
10216 + * along with this program; see the file COPYING.  If not, write to
10217 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10218 + *
10219 + * Module Name:
10220 + *   linit.h
10221 + *
10222 + * Abstract: Header file for Linux Driver for Adaptec RAID Array Controller
10223 + *
10224 + --*/
10225 +/*------------------------------------------------------------------------------
10226 + *              I N C L U D E S
10227 + *----------------------------------------------------------------------------*/
10228 +
10229 +#ifndef _LINIT_H_
10230 +#define _LINIT_H_
10231 +
10232 +static char *ident_linith = "aacraid_ident linit.h 1.0.6 2000/10/09 Adaptec, Inc.";
10233 +
10234 +#include <linux/config.h>
10235 +
10236 +/*------------------------------------------------------------------------------
10237 + *              D E F I N E S
10238 + *----------------------------------------------------------------------------*/
10239 +/* Define the AAC SCSI Host Template structure. */
10240 +#define AAC_HOST_TEMPLATE_ENTRY        \
10241 +  { name:           "AAC",                   /* Driver Name            */ \
10242 +    proc_info:      AAC_ProcDirectoryInfo,   /* ProcFS Info Func       */ \
10243 +    detect:         AAC_DetectHostAdapter,   /* Detect Host Adapter    */ \
10244 +    release:        AAC_ReleaseHostAdapter,  /* Release Host Adapter   */ \
10245 +    info:           AAC_DriverInfo,          /* Driver Info Function   */ \
10246 +    ioctl:          AAC_Ioctl,               /* ioctl Interface        */ \
10247 +    command:        AAC_Command,             /* unqueued command       */ \
10248 +    queuecommand:   AAC_QueueCommand,        /* Queue Command Function */ \
10249 +    abort:          AAC_AbortCommand,        /* Abort Command Function */ \
10250 +    reset:          AAC_ResetCommand,        /* Reset Command Function */ \
10251 +    bios_param:     AAC_BIOSDiskParameters,  /* BIOS Disk Parameters   */ \
10252 +    can_queue:      1,                       /* Default initial value  */ \
10253 +    this_id:        0,                       /* Default initial value  */ \
10254 +    sg_tablesize:   0,                       /* Default initial value  */ \
10255 +    max_sectors:    128,                     /* max xfer size of 64k   */ \
10256 +    cmd_per_lun:    0,                       /* Default initial value  */ \
10257 +    present:        0,                       /* Default initial value  */ \
10258 +    unchecked_isa_dma: 0,                    /* Default Initial Value  */ \
10259 +    use_new_eh_code:         0,                  /* Default initial value      */ \
10260 +    eh_abort_handler:        AAC_AbortCommand,   /* New Abort Command func     */ \
10261 +    eh_strategy_handler:     NULL,               /* New Strategy Error Handler */ \
10262 +    eh_device_reset_handler: NULL,               /* New Device Reset Handler   */ \
10263 +    eh_bus_reset_handler:    NULL,               /* New Bus Reset Handler      */ \
10264 +    eh_host_reset_handler:   NULL,               /* New Host reset Handler     */ \
10265 +    use_clustering: ENABLE_CLUSTERING        /* Disable Clustering      */ \
10266 +  }
10267 +
10268 +
10269 +/*------------------------------------------------------------------------------
10270 + *              T Y P E D E F S / S T R U C T S
10271 + *----------------------------------------------------------------------------*/
10272 +typedef struct AAC_BIOS_DiskParameters
10273 +{
10274 +       int heads;
10275 +       int sectors;
10276 +       int cylinders;
10277 +} AAC_BIOS_DiskParameters_T;
10278 +
10279 +
10280 +/*------------------------------------------------------------------------------
10281 + *              P R O G R A M   G L O B A L S
10282 + *----------------------------------------------------------------------------*/
10283 +
10284 +const char *AAC_DriverInfo( struct Scsi_Host * );
10285 +
10286 +
10287 +/*------------------------------------------------------------------------------
10288 + *              F U N C T I O N   P R O T O T Y P E S
10289 + *----------------------------------------------------------------------------*/
10290 +/* Define prototypes for the AAC Driver Interface Functions. */
10291 +int AAC_DetectHostAdapter( Scsi_Host_Template * );
10292 +int AAC_ReleaseHostAdapter( struct Scsi_Host * );
10293 +int AAC_QueueCommand( Scsi_Cmnd *, void ( *CompletionRoutine )( Scsi_Cmnd * ) );
10294 +int AAC_Command( Scsi_Cmnd * );
10295 +int AAC_ResetCommand( Scsi_Cmnd *, unsigned int );
10296 +int AAC_BIOSDiskParameters( Disk *, kdev_t, int * );
10297 +int AAC_ProcDirectoryInfo( char *, char **, off_t, int, int, int );
10298 +int AAC_Ioctl( Scsi_Device *, int, void * );
10299 +
10300 +
10301 +void AAC_SelectQueueDepths(    struct Scsi_Host *, Scsi_Device * );
10302 +
10303 +
10304 +int AAC_AbortCommand( Scsi_Cmnd *scsi_cmnd_ptr );
10305 +
10306 +#endif /* _LINIT_H_ */
10307 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/monkerapi.h linux/drivers/scsi/aacraid/include/monkerapi.h
10308 --- linux-2.4.4/drivers/scsi/aacraid/include/monkerapi.h        Wed Dec 31 18:00:00 1969
10309 +++ linux/drivers/scsi/aacraid/include/monkerapi.h      Mon Apr 30 09:43:34 2001
10310 @@ -0,0 +1,98 @@
10311 +/*++
10312 + * Adaptec aacraid device driver for Linux.
10313 + *
10314 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10315 + *
10316 + * This program is free software; you can redistribute it and/or modify
10317 + * it under the terms of the GNU General Public License as published by
10318 + * the Free Software Foundation; either version 2, or (at your option)
10319 + * any later version.
10320 + *
10321 + * This program is distributed in the hope that it will be useful,
10322 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10323 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10324 + * GNU General Public License for more details.
10325 + *
10326 + * You should have received a copy of the GNU General Public License
10327 + * along with this program; see the file COPYING.  If not, write to
10328 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10329 + *
10330 + * Module Name:
10331 + *   monkerapi.h
10332 + *
10333 + * Abstract: This module contains the definitions used by the Host Adapter
10334 + *      Communications interface.
10335 + *      This is the interface used for by host programs and the Adapter 
10336 + *      to communicate via synchronous commands via a shared set of registers
10337 + *      on a platform (typically doorbells and mailboxes).
10338 + *
10339 + --*/
10340 +//**********************************************************************
10341 +//
10342 +//     Monitor / Kernel API
10343 +//
10344 +//     03/24/1998 Bob Peret    Initial creation
10345 +//
10346 +//**********************************************************************
10347 +
10348 +#ifndef MONKER_H
10349 +#define MONKER_H
10350 +
10351 +static char *ident_monk = "aacraid_ident monkerapi.h 1.0.6 2000/10/09 Adaptec, Inc.";
10352 +
10353 +#define        BREAKPOINT_REQUEST                                      0x00000004
10354 +#define        INIT_STRUCT_BASE_ADDRESS                        0x00000005
10355 +
10356 +
10357 +#define        SEND_SYNCHRONOUS_FIB                            0x0000000c
10358 +
10359 +
10360 +
10361 +//
10362 +//     Adapter Status Register
10363 +//
10364 +//  Phase Staus mailbox is 32bits:
10365 +//     <31:16> = Phase Status
10366 +//     <15:0>  = Phase
10367 +//
10368 +//  The adapter reports is present state through the phase.  Only
10369 +//  a single phase should be ever be set.  Each phase can have multiple
10370 +//     phase status bits to provide more detailed information about the 
10371 +//     state of the board.  Care should be taken to ensure that any phase status 
10372 +//  bits that are set when changing the phase are also valid for the new phase
10373 +//  or be cleared out.  Adapter software (monitor, iflash, kernel) is responsible
10374 +//  for properly maintining the phase status mailbox when it is running.
10375 +
10376 +//                                                                                     
10377 +// MONKER_API Phases                                                   
10378 +//
10379 +// Phases are bit oriented.  It is NOT valid 
10380 +// to have multiple bits set                                           
10381 +//                                     
10382 +
10383 +
10384 +#define        SELF_TEST_FAILED                                        0x00000004
10385 +
10386 +
10387 +#define        KERNEL_UP_AND_RUNNING                           0x00000080
10388 +#define        KERNEL_PANIC                                            0x00000100
10389 +
10390 +
10391 +
10392 +//
10393 +// Doorbell bit defines
10394 +//
10395 +
10396 +
10397 +#define DoorBellPrintfDone                             (1<<5)  // Host -> Adapter
10398 +
10399 +
10400 +#define DoorBellAdapterNormCmdReady            (1<<1)  // Adapter -> Host
10401 +#define DoorBellAdapterNormRespReady   (1<<2)  // Adapter -> Host
10402 +#define DoorBellAdapterNormCmdNotFull  (1<<3)  // Adapter -> Host
10403 +#define DoorBellAdapterNormRespNotFull (1<<4)  // Adapter -> Host
10404 +#define DoorBellPrintfReady                            (1<<5)  // Adapter -> Host
10405 +
10406 +
10407 +#endif // MONKER_H
10408 +
10409 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/nodetype.h linux/drivers/scsi/aacraid/include/nodetype.h
10410 --- linux-2.4.4/drivers/scsi/aacraid/include/nodetype.h Wed Dec 31 18:00:00 1969
10411 +++ linux/drivers/scsi/aacraid/include/nodetype.h       Mon Apr 30 09:43:34 2001
10412 @@ -0,0 +1,67 @@
10413 +/*++
10414 + * Adaptec aacraid device driver for Linux.
10415 + *
10416 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10417 + *
10418 + * This program is free software; you can redistribute it and/or modify
10419 + * it under the terms of the GNU General Public License as published by
10420 + * the Free Software Foundation; either version 2, or (at your option)
10421 + * any later version.
10422 + *
10423 + * This program is distributed in the hope that it will be useful,
10424 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10425 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10426 + * GNU General Public License for more details.
10427 + *
10428 + * You should have received a copy of the GNU General Public License
10429 + * along with this program; see the file COPYING.  If not, write to
10430 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10431 + *
10432 + * Module Name:
10433 + *   nodetype.h
10434 + *
10435 + * Abstract:     This module defines all of the node type codes used in this development
10436 + *  shell.  Every major data structure in the file system is assigned a node
10437 + *  type code that is.  This code is the first CSHORT in the structure and is
10438 + *  followed by a CSHORT containing the size, in bytes, of the structure.
10439 + *
10440 + --*/
10441 +#ifndef _NODETYPE_
10442 +#define _NODETYPE_
10443 +
10444 +static char *ident_node = "aacraid_ident nodetype.h 1.0.6 2000/10/09 Adaptec, Inc.";
10445 +
10446 +typedef CSHORT NODE_TYPE_CODE;
10447 +
10448 +
10449 +#define FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT ((NODE_TYPE_CODE)0x030b)
10450 +#define FSAFS_NTC_FIB_CONTEXT            ((NODE_TYPE_CODE)0x030c)
10451 +
10452 +
10453 +typedef CSHORT NODE_BYTE_SIZE;
10454 +
10455 +
10456 +//
10457 +//  The following definitions are used to generate meaningful blue bugcheck
10458 +//  screens.  On a bugcheck the file system can output 4 ulongs of useful
10459 +//  information.  The first ulong will have encoded in it a source file id
10460 +//  (in the high word) and the line number of the bugcheck (in the low word).
10461 +//  The other values can be whatever the caller of the bugcheck routine deems
10462 +//  necessary.
10463 +//
10464 +//  Each individual file that calls bugcheck needs to have defined at the
10465 +//  start of the file a constant called BugCheckFileId with one of the
10466 +//  FSAFS_BUG_CHECK_ values defined below and then use FsaBugCheck to bugcheck
10467 +//  the system.
10468 +//
10469 +
10470 +
10471 +#define FSAFS_BUG_CHECK_COMMSUP           (0X001e0000)
10472 +#define FSAFS_BUG_CHECK_DPCSUP            (0X001f0000)
10473 +
10474 +
10475 +#define FsaBugCheck(A,B,C) { cmn_err( CE_PANIC, "aacdisk: module %x, line %x, 0x%x, 0x%x, 0x%x ", BugCheckFileId, __LINE__, A, B, C); }
10476 +
10477 +
10478 +#endif // _NODETYPE_
10479 +
10480 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/nvramioctl.h linux/drivers/scsi/aacraid/include/nvramioctl.h
10481 --- linux-2.4.4/drivers/scsi/aacraid/include/nvramioctl.h       Wed Dec 31 18:00:00 1969
10482 +++ linux/drivers/scsi/aacraid/include/nvramioctl.h     Mon Apr 30 09:43:34 2001
10483 @@ -0,0 +1,112 @@
10484 +/*++
10485 + * Adaptec aacraid device driver for Linux.
10486 + *
10487 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10488 + *
10489 + * This program is free software; you can redistribute it and/or modify
10490 + * it under the terms of the GNU General Public License as published by
10491 + * the Free Software Foundation; either version 2, or (at your option)
10492 + * any later version.
10493 + *
10494 + * This program is distributed in the hope that it will be useful,
10495 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10496 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10497 + * GNU General Public License for more details.
10498 + *
10499 + * You should have received a copy of the GNU General Public License
10500 + * along with this program; see the file COPYING.  If not, write to
10501 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10502 + *
10503 + * Module Name:
10504 + *   nvramioctl.h
10505 + *
10506 + * Abstract: This file defines the data structures related to querying
10507 + *    and controlling the FSA NVRAM/WriteCache subsystem via the NVRAMIOCTL FIB.
10508 + *
10509 + --*/
10510 +#ifndef _NVRAMIOCTL_H_
10511 +#define _NVRAMIOCTL_H_ 1
10512 +
10513 +static char *ident_nvram = "aacraid_ident nvramioctl.h 1.0.6 2000/10/09 Adaptec, Inc.";
10514 +
10515 +/*
10516 + * NVRAM/Write Cache subsystem states
10517 + */
10518 +typedef enum _NVSTATUS {
10519 +       NVSTATUS_DISABLED = 0,  // present, clean, not being used
10520 +       NVSTATUS_ENABLED,               // present, possibly dirty, ready for use
10521 +       NVSTATUS_ERROR,                 // present, dirty, contains dirty data
10522 +                                                       // for bad/missing device
10523 +       NVSTATUS_BATTERY,               // present, bad or low battery, may contain dirty data
10524 +                                                       // for bad/missing device
10525 +       NVSTATUS_UNKNOWN                // present?????
10526 +} _E_NVSTATUS;
10527 +
10528 +#ifdef AAC_32BIT_ENUMS
10529 +typedef _E_NVSTATUS    NVSTATUS;
10530 +#else
10531 +typedef AAC_UINT32     NVSTATUS;
10532 +#endif
10533 +
10534 +/*
10535 + * NVRAM/Write Cache subsystem battery component states
10536 + *
10537 + */
10538 +//NB: this enum should be identical to battery_status in nvram.h
10539 +//       or else collapsed into one enum someday
10540 +typedef enum _NVBATTSTATUS {
10541 +       NVBATTSTATUS_NONE = 0,  // battery has no power or is not present
10542 +       NVBATTSTATUS_LOW,               // battery is low on power
10543 +       NVBATTSTATUS_OK,                        // battery is okay - normal operation possible only in this state
10544 +       NVBATTSTATUS_RECONDITIONING     // no battery present - reconditioning in process
10545 +} _E_NVBATTSTATUS;
10546 +
10547 +#ifdef AAC_32BIT_ENUMS
10548 +typedef        _E_NVBATTSTATUS NVBATTSTATUS;
10549 +#else
10550 +typedef AAC_UINT32             NVBATTSTATUS;
10551 +#endif
10552 +
10553 +/*
10554 + * battery transition type
10555 + */
10556 +typedef enum _NVBATT_TRANSITION {
10557 +       NVBATT_TRANSITION_NONE = 0,     // battery now has no power or is not present
10558 +       NVBATT_TRANSITION_LOW,          // battery is now low on power
10559 +       NVBATT_TRANSITION_OK            // battery is now okay - normal operation possible only in this state
10560 +} _E_NVBATT_TRANSITION;
10561 +
10562 +#ifdef AAC_32BIT_ENUMS
10563 +typedef _E_NVBATT_TRANSITION   NVBATT_TRANSITION;
10564 +#else
10565 +typedef        AAC_UINT32                              NVBATT_TRANSITION;
10566 +#endif
10567 +
10568 +/*
10569 + * NVRAM Info structure returned for NVRAM_GetInfo call
10570 + */
10571 +typedef struct _NVRAMDEVINFO {
10572 +       AAC_UINT32              NV_Enabled;             /* write caching enabled */
10573 +       AAC_UINT32              NV_Error;               /* device in error state */
10574 +       AAC_UINT32              NV_NDirty;              /* count of dirty NVRAM buffers */
10575 +       AAC_UINT32              NV_NActive;             /* count of NVRAM buffers being written */
10576 +} NVRAMDEVINFO, *PNVRAMDEVINFO;
10577 +
10578 +typedef struct _NVRAMINFO {
10579 +       NVSTATUS                NV_Status;                              /* nvram subsystem status */
10580 +       NVBATTSTATUS    NV_BattStatus;                  /* battery status */
10581 +       AAC_UINT32              NV_Size;                                /* size of WriteCache NVRAM in bytes */
10582 +       AAC_UINT32              NV_BufSize;                             /* size of NVRAM buffers in bytes */
10583 +       AAC_UINT32              NV_NBufs;                               /* number of NVRAM buffers */
10584 +       AAC_UINT32              NV_NDirty;                              /* count of dirty NVRAM buffers */
10585 +       AAC_UINT32              NV_NClean;                              /* count of clean NVRAM buffers */
10586 +       AAC_UINT32              NV_NActive;                             /* count of NVRAM buffers being written */
10587 +       AAC_UINT32              NV_NBrokered;                   /* count of brokered NVRAM buffers */
10588 +       NVRAMDEVINFO    NV_DevInfo[NFILESYS];   /* per device info */
10589 +       AAC_UINT32              NV_BattNeedsReconditioning;     /* boolean */
10590 +       AAC_UINT32              NV_TotalSize;                   /* total size of all non-volatile memories in bytes */
10591 +} NVRAMINFO, *PNVRAMINFO;
10592 +
10593 +#endif /* !_NVRAMIOCTL_H_ */
10594 +
10595 +
10596 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/osheaders.h linux/drivers/scsi/aacraid/include/osheaders.h
10597 --- linux-2.4.4/drivers/scsi/aacraid/include/osheaders.h        Wed Dec 31 18:00:00 1969
10598 +++ linux/drivers/scsi/aacraid/include/osheaders.h      Mon Apr 30 09:43:34 2001
10599 @@ -0,0 +1,150 @@
10600 +/*++
10601 + * Adaptec aacraid device driver for Linux.
10602 + *
10603 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10604 + *
10605 + * This program is free software; you can redistribute it and/or modify
10606 + * it under the terms of the GNU General Public License as published by
10607 + * the Free Software Foundation; either version 2, or (at your option)
10608 + * any later version.
10609 + *
10610 + * This program is distributed in the hope that it will be useful,
10611 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10612 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10613 + * GNU General Public License for more details.
10614 + *
10615 + * You should have received a copy of the GNU General Public License
10616 + * along with this program; see the file COPYING.  If not, write to
10617 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10618 + *
10619 + * Module Name:
10620 + *   osheaders.h
10621 + *
10622 + * Abstract: Holds all of the header file includes for a particular O/S flavor.
10623 + *
10624 + --*/
10625 +#ifndef _OSHEADERS_H_
10626 +#define _OSHEADERS_H_
10627 +
10628 +static char *ident_oshead = "aacraid_ident osheaders.h 1.0.6 2000/10/09 Adaptec, Inc.";
10629 +
10630 +#include <linux/autoconf.h>    // retrieve the kernel configuration info
10631 +#if defined( CONFIG_MODVERSIONS ) && !defined( MODVERSIONS )
10632 +#define MODVERSIONS    // force it on
10633 +#endif
10634 +
10635 +#include <linux/version.h>
10636 +
10637 +#if defined( MODVERSIONS ) && defined( MODULE )
10638 +#if DRIVER_KERNEL_CODE >= KERNEL_VERSION(2,2,12)
10639 +#ifdef __SMP__
10640 +#include <linux/modversions-smp.h>
10641 +#elif defined( BOOT_DRIVER ) 
10642 +#include <linux/modversions-BOOT.h>
10643 +#else 
10644 +#include <linux/modversions-up.h>
10645 +#endif // ifdef __SMP__
10646 +#else
10647 +#include <linux/modversions.h>
10648 +#endif
10649 +#endif
10650 +
10651 +
10652 +#include <linux/kernel.h>
10653 +#include <linux/config.h>
10654 +#include <linux/init.h>
10655 +#include <linux/types.h>
10656 +#include <linux/blk.h>
10657 +#include <linux/blkdev.h>
10658 +#include <linux/delay.h>
10659 +#include <linux/ioport.h>
10660 +#include <linux/mm.h>
10661 +#include <linux/sched.h>
10662 +#include <linux/stat.h>
10663 +#include <linux/pci.h>
10664 +#include <linux/interrupt.h>
10665 +#include <asm/dma.h>
10666 +#include <asm/io.h>
10667 +#include <linux/spinlock.h>
10668 +#include <asm/system.h>
10669 +#include <asm/bitops.h>
10670 +#include <asm/uaccess.h>
10671 +#include <linux/wait.h>
10672 +#include <linux/malloc.h>
10673 +#include <linux/tqueue.h>
10674 +/* bmb fix
10675 +#include <linux/tasks.h>
10676 +*/
10677 +#include <ostypes.h>
10678 +#include "scsi.h"
10679 +#include "hosts.h"
10680 +
10681 +#ifndef intptr_t
10682 +#define intptr_t void *
10683 +#endif
10684 +
10685 +#ifndef cred_t
10686 +#define cred_t void
10687 +#endif
10688 +
10689 +#ifndef paddr32_t
10690 +#define paddr32_t unsigned
10691 +#endif
10692 +
10693 +#ifndef bzero 
10694 +#define bzero(b,len) memset(b,0,len)
10695 +#endif
10696 +
10697 +#ifndef bcopy
10698 +#define bcopy(src,dst,len) memcpy(dst,src,len )
10699 +#endif
10700 +
10701 +#ifndef DEVICE_NR
10702 +#define DEVICE_NR(device) ( ( ( MAJOR( device ) & 7 ) << 4 ) + ( MINOR( device ) >> 4 ) )
10703 +#endif
10704 +
10705 +typedef unsigned uint_t;
10706 +
10707 +typedef enum
10708 +{
10709 +       CE_PANIC = 0,
10710 +       CE_WARN,
10711 +       CE_NOTE, 
10712 +       CE_CONT, 
10713 +       CE_DEBUG,
10714 +       CE_DEBUG2,
10715 +       CE_TAIL
10716 +} CE_ENUM_T;
10717 +
10718 +#define CMN_ERR_LEVEL CE_NOTE
10719 +
10720 +#ifndef IN
10721 +#define IN
10722 +#endif
10723 +
10724 +// usage of READ & WRITE as a typedefs in protocol.h
10725 +// conflicts with <linux/fs.h> definition.
10726 +#ifdef READ
10727 +#undef READ
10728 +#endif
10729 +
10730 +#ifdef WRITE
10731 +#undef WRITE
10732 +#endif
10733 +
10734 +typedef struct aac_options
10735 +{
10736 +       int message_level;
10737 +       int reverse_scan; 
10738 +} aac_options_t;
10739 +
10740 +#endif // _OSHEADERS_H_
10741 +
10742 +
10743 +
10744 +
10745 +
10746 +
10747 +
10748 +
10749 +
10750 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/ostypes.h linux/drivers/scsi/aacraid/include/ostypes.h
10751 --- linux-2.4.4/drivers/scsi/aacraid/include/ostypes.h  Wed Dec 31 18:00:00 1969
10752 +++ linux/drivers/scsi/aacraid/include/ostypes.h        Mon Apr 30 09:43:34 2001
10753 @@ -0,0 +1,149 @@
10754 +/*++
10755 + * Adaptec aacraid device driver for Linux.
10756 + *
10757 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10758 + *
10759 + * This program is free software; you can redistribute it and/or modify
10760 + * it under the terms of the GNU General Public License as published by
10761 + * the Free Software Foundation; either version 2, or (at your option)
10762 + * any later version.
10763 + *
10764 + * This program is distributed in the hope that it will be useful,
10765 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10766 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10767 + * GNU General Public License for more details.
10768 + *
10769 + * You should have received a copy of the GNU General Public License
10770 + * along with this program; see the file COPYING.  If not, write to
10771 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10772 + *
10773 + * Module Name:
10774 + *   ostypes.h
10775 + *
10776 + * Abstract: Holds all of the O/S specific types.
10777 + *
10778 + --*/
10779 +/*------------------------------------------------------------------------------
10780 + *              D E F I N E S
10781 + *----------------------------------------------------------------------------*/
10782 +#ifndef _OSTYPES_H_
10783 +#define _OSTYPES_H_
10784 +
10785 +static char *ident_ostypes = "aacraid_ident ostypes.h 1.0.7 2000/10/11 Adaptec, Inc.";
10786 +
10787 +#include <linux/types.h>
10788 +
10789 +#define MAXIMUM_NUM_CONTAINERS 64              // 4 Luns * 16 Targets
10790 +#define MAXIMUM_NUM_ADAPTERS   8
10791 +
10792 +#define OS_ALLOC_MEM_SLEEP             GFP_KERNEL
10793 +
10794 +#define Os_remove_softintr OsSoftInterruptRemove
10795 +#define OsPrintf printk
10796 +#define FsaCommPrint
10797 +
10798 +// the return values for copy_from_user & copy_to_user is the 
10799 +// number of bytes not transferred. Thus if an internal error 
10800 +// occurs, the return value is greater than zero.
10801 +#define COPYIN(SRC,DST,COUNT,FLAGS)  copy_from_user(DST,SRC,COUNT)
10802 +#define COPYOUT(SRC,DST,COUNT,FLAGS) copy_to_user(DST,SRC,COUNT)
10803 +
10804 +#define copyin(SRC,DST,COUNT) copy_from_user(DST,SRC,COUNT)
10805 +#define copyout(SRC,DST,COUNT) copy_to_user(DST,SRC,COUNT)
10806 +
10807 +/*------------------------------------------------------------------------------
10808 + *              S T R U C T S / T Y P E D E F S
10809 + *----------------------------------------------------------------------------*/
10810 +typedef struct OS_MUTEX
10811 +{
10812 +       unsigned long lock_var;
10813 +       wait_queue_head_t wq;
10814 +       unsigned owner;
10815 +} OS_MUTEX;
10816 +
10817 +typedef        struct OS_SPINLOCK
10818 +{
10819 +       spinlock_t      spin_lock;
10820 +       unsigned cpu_lock_count[NR_CPUS];
10821 +       long cpu_flag;
10822 +       long lockout_count;
10823 +} OS_SPINLOCK;
10824 +
10825 +#ifdef CVLOCK_USE_SPINLOCK
10826 +       typedef OS_SPINLOCK OS_CVLOCK;
10827 +#else
10828 +       typedef OS_MUTEX OS_CVLOCK;
10829 +#endif
10830 +
10831 +typedef size_t         OS_SIZE_T;
10832 +
10833 +typedef        struct OS_CV_T
10834 +{
10835 +       unsigned long lock_var;
10836 +       unsigned long type;
10837 +       wait_queue_head_t wq;   
10838 +} OS_CV_T;
10839 +
10840 +struct fsa_scsi_hba {
10841 +       void                            *CommonExtension;
10842 +       unsigned long           ContainerSize[MAXIMUM_NUM_CONTAINERS];
10843 +       unsigned long           ContainerType[MAXIMUM_NUM_CONTAINERS];
10844 +       unsigned char           ContainerValid[MAXIMUM_NUM_CONTAINERS];
10845 +       unsigned char           ContainerReadOnly[MAXIMUM_NUM_CONTAINERS];
10846 +       unsigned char           ContainerLocked[MAXIMUM_NUM_CONTAINERS];
10847 +       unsigned char           ContainerDeleted[MAXIMUM_NUM_CONTAINERS];
10848 +       long                            ContainerDevNo[MAXIMUM_NUM_CONTAINERS];
10849 +};
10850 +
10851 +typedef struct fsa_scsi_hba fsadev_t;
10852 +
10853 +typedef struct OsKI
10854 +{
10855 +       struct Scsi_Host *scsi_host_ptr;
10856 +       void * dip;     // #REVISIT#
10857 +       fsadev_t fsa_dev;
10858 +       int thread_pid;
10859 +  int    MiniPortIndex;
10860 +} OsKI_t;
10861 +
10862 +#define dev_info_t     fsadev_t
10863 +
10864 +typedef int    OS_SPINLOCK_COOKIE;
10865 +
10866 +typedef unsigned int   OS_STATUS;
10867 +
10868 +typedef struct tq_struct OS_SOFTINTR;
10869 +
10870 +typedef        OS_SOFTINTR     *ddi_softintr_t;
10871 +
10872 +
10873 +
10874 +//-----------------------------------------------------------------------------
10875 +// Conditional variable functions
10876 +
10877 +void OsCv_init ( 
10878 +       OS_CV_T *cv_ptr );
10879 +
10880 +
10881 +//-----------------------------------------------------------------------------
10882 +// Printing functions
10883 +void printk_err(int flag, char *fmt, ...);
10884 +
10885 +#define cmn_err printk_err
10886 +
10887 +
10888 +//
10889 +// just ignore these solaris ddi functions in the code
10890 +//
10891 +#define DDI_SUCCESS                                            0
10892 +
10893 +#define ddi_add_softintr(A,B,C,D,E,F,G)                OsSoftInterruptAdd(C,F,G)
10894 +
10895 +//#REVIEW#
10896 +#define ddi_remove_softintr(A)                         0
10897 +#define ddi_get_soft_iblock_cookie(A, B, C)    0
10898 +
10899 +#define ASSERT(expr) ((void) 0)
10900 +#define drv_usecwait udelay
10901 +
10902 +#endif // _OSTYPES_H_
10903 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/pcisup.h linux/drivers/scsi/aacraid/include/pcisup.h
10904 --- linux-2.4.4/drivers/scsi/aacraid/include/pcisup.h   Wed Dec 31 18:00:00 1969
10905 +++ linux/drivers/scsi/aacraid/include/pcisup.h Mon Apr 30 09:43:34 2001
10906 @@ -0,0 +1,97 @@
10907 +/*++
10908 + * Adaptec aacraid device driver for Linux.
10909 + *
10910 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10911 + *
10912 + * This program is free software; you can redistribute it and/or modify
10913 + * it under the terms of the GNU General Public License as published by
10914 + * the Free Software Foundation; either version 2, or (at your option)
10915 + * any later version.
10916 + *
10917 + * This program is distributed in the hope that it will be useful,
10918 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10919 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10920 + * GNU General Public License for more details.
10921 + *
10922 + * You should have received a copy of the GNU General Public License
10923 + * along with this program; see the file COPYING.  If not, write to
10924 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10925 + *
10926 + * Module Name:
10927 + *   pcisup.h
10928 + *
10929 + * Abstract: This module defines functions that are defined in PciSup.c
10930 + *
10931 + --*/
10932 +#ifndef _PCISUP_
10933 +#define _PCISUP_
10934 +
10935 +static char *ident_pcisup = "aacraid_ident pcisup.h 1.0.6 2000/10/09 Adaptec, Inc.";
10936 +
10937 +       
10938 +/*
10939 + * define which interrupt handler needs to be installed
10940 + */
10941 +
10942 +#define SaISR  1
10943 +#define RxISR  2
10944 +
10945 +typedef struct _PCI_MINIPORT_COMMON_EXTENSION {
10946 +       ULONG                                   AdapterNumber;                  // Which FSA# this miniport is
10947 +       
10948 +       ULONG                                   PciBusNumber;                   // Which PCI bus we are located on
10949 +       ULONG                                   PciSlotNumber;                  // Whiat PCI slot we are in
10950 +       
10951 +       PVOID                                   Adapter;                                // Back pointer to Fsa adapter object
10952 +       ULONG                                   AdapterIndex;                   // Index into PlxAdapterTypes array
10953 +       PDEVICE_OBJECT                  DeviceObject;                   // Pointer to our device object
10954 +       
10955 +       FSAPORT_FUNCS                   AdapterFuncs;
10956 +       ULONG                                   FilesystemRevision;     // Main driver's revision number
10957 +       
10958 +       
10959 +       PADAPTER_INIT_STRUCT    InitStruct;                             // Holds initialization info to communicate with adapter
10960 +       PVOID                                   PhysicalInitStruct;     // Holds physical address of the init struct
10961 +       
10962 +       
10963 +       PVOID                                   PrintfBufferAddress;    // pointer to buffer used for printf's from the adapter
10964 +       
10965 +       BOOLEAN                                 AdapterPrintfsToScreen;                 
10966 +       BOOLEAN                                 AdapterConfigured;              // set to true when we know adapter can take FIBs
10967 +       
10968 +       void *                                  MiniPort;
10969 +       
10970 +       caddr_t                                 CommAddress;    // Base address of Comm area
10971 +       paddr32_t                               CommPhysAddr;   // Physical Address of Comm area
10972 +       size_t                                  CommSize;
10973 +
10974 +       OsKI_t                                  OsDep;                  // OS dependent kernel interfaces
10975 +
10976 +       
10977 +} PCI_MINIPORT_COMMON_EXTENSION;
10978 +
10979 +typedef PCI_MINIPORT_COMMON_EXTENSION *PPCI_MINIPORT_COMMON_EXTENSION;
10980 +
10981 +typedef int
10982 +(*PFSA_MINIPORT_INIT) (
10983 +       IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
10984 +       IN ULONG AdapterNumber,
10985 +       IN ULONG PciBus,
10986 +       IN ULONG PciSlot
10987 +       );
10988 +
10989 +typedef struct _FSA_MINIPORT {
10990 +       USHORT                          VendorId;
10991 +       USHORT                          DeviceId;
10992 +       USHORT                          SubVendorId;
10993 +       USHORT                          SubSystemId;
10994 +       PCHAR                           DevicePrefix;
10995 +  PFSA_MINIPORT_INIT   InitRoutine;
10996 +  PCHAR               DeviceName;
10997 +  PCHAR               Vendor;
10998 +  PCHAR               Model;
10999 +} FSA_MINIPORT;
11000 +typedef FSA_MINIPORT *PFSA_MINIPORT;
11001 +
11002 +
11003 +#endif // _PCISUP_
11004 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/perfpack.h linux/drivers/scsi/aacraid/include/perfpack.h
11005 --- linux-2.4.4/drivers/scsi/aacraid/include/perfpack.h Wed Dec 31 18:00:00 1969
11006 +++ linux/drivers/scsi/aacraid/include/perfpack.h       Mon Apr 30 09:43:34 2001
11007 @@ -0,0 +1,110 @@
11008 +/*++
11009 + * Adaptec aacraid device driver for Linux.
11010 + *
11011 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11012 + *
11013 + * This program is free software; you can redistribute it and/or modify
11014 + * it under the terms of the GNU General Public License as published by
11015 + * the Free Software Foundation; either version 2, or (at your option)
11016 + * any later version.
11017 + *
11018 + * This program is distributed in the hope that it will be useful,
11019 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11020 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11021 + * GNU General Public License for more details.
11022 + *
11023 + * You should have received a copy of the GNU General Public License
11024 + * along with this program; see the file COPYING.  If not, write to
11025 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11026 + *
11027 + * Module Name:
11028 + *   perfpack.h
11029 + *
11030 + * Abstract: This file defines the layout of the performance data that is passed
11031 + *           back from the FSA filesystem driver.
11032 + *
11033 + *     
11034 + --*/
11035 +
11036 +#ifndef _FSA_PERFPACK_H_
11037 +#define _FSA_PERFPACK_H_       1
11038 +
11039 +static char *ident_perf = "aacraid_ident perfpack.h 1.0.6 2000/10/09 Adaptec, Inc.";
11040 +
11041 +//#define FSA_DO_PERF          1               /* enable the engineering counters */
11042 +
11043 +#ifdef FSA_DO_PERF
11044 +//
11045 +// engineering counters
11046 +//
11047 +typedef struct _FSA_PERF_DATA {
11048 +                       ULONG FibsSent;
11049 +                       ULONG ReadDirs;
11050 +                       ULONG GetAttrs;
11051 +                       ULONG SetAttrs;
11052 +                       ULONG Lookups;
11053 +                       ULONG ReadFibs;
11054 +                       ULONG WriteFibs;
11055 +                       ULONG CreateFibs;
11056 +                       ULONG MakeDirs;
11057 +                       ULONG RemoveFibs;
11058 +                       ULONG RemoveDirs;
11059 +                       ULONG RenameFibs;
11060 +                       ULONG ReadDirPlus;
11061 +                       ULONG FsStat;
11062 +                       ULONG WriteBytes;
11063 +                       ULONG ReadBytes;
11064 +// NT FSA entry points
11065 +                       ULONG FsaFsdCreateCount;
11066 +                       ULONG FsaFsdCloseCount;
11067 +                       ULONG FsaFsdReadCount;
11068 +                       ULONG FsaFsdWriteCount;
11069 +                       ULONG FsaFsdQueryInformationCount;
11070 +
11071 +                       struct _FsaFsdSetInfomation{
11072 +                               ULONG FsaSetAllocationInfoCount;
11073 +                               ULONG FsaSetBasicInfoCount;
11074 +                               ULONG FsaSetDispositionInfoCount;
11075 +                               ULONG FsaSetEndOfFileInfoCount;
11076 +                               ULONG FsaSetPositionInfoCount;
11077 +                               ULONG FsaSetRenameInfoCount;
11078 +                               ULONG FsaClearArchiveBitCount;
11079 +                       };
11080 +
11081 +                       ULONG FsaFsdFlushBuffersCount;
11082 +                       ULONG FsaFsdQueryVolumeInfoCount;
11083 +                       ULONG FsaFsdSetVolumeInfoCount;
11084 +                       ULONG FsaFsdCleanupCount;
11085 +                       ULONG FsaFsdDirectoryControlCount;
11086 +                       ULONG FsaFsdFileSystemControlCount;
11087 +                       ULONG FsaFsdLockControlCount;
11088 +                       ULONG FsaFsdDeviceControlCount;
11089 +                       ULONG FsaFsdShutdownCount;
11090 +                       ULONG FsaFsdQuerySecurityInfo;
11091 +                       ULONG FsaFsdSetSecurityInfo;
11092 +                       ULONG FastIoCheckIfPossibleCount;
11093 +                       ULONG FastIoReadCount;
11094 +                       ULONG FastIoWriteCount;
11095 +                       ULONG FastIoQueryBasicInfoCount;
11096 +                       ULONG FastIoQueryStandardInfoCount;
11097 +                       ULONG FastIoLockCount;
11098 +                       ULONG FastIoUnlockSingleCount;
11099 +                       ULONG FastIoUnlockAllCount;
11100 +                       ULONG FastIoUnlockAllByKeyCount;
11101 +                       ULONG FastIoDeviceControlCount;
11102 + } FSA_PERF_DATA;
11103 +
11104 +typedef FSA_PERF_DATA *PFSA_PERF_DATA;
11105 +
11106 +
11107 +#else /* FSA_DO_PERF */
11108 +
11109 +//
11110 +// engineering performance counters are disabled
11111 +//
11112 +#define FSA_DO_PERF_INC(Counter)               /* */
11113 +#define FSA_DO_FSP_PERF_INC(Counter)   /* */
11114 +
11115 +#endif /* FSA_DO_PERF */
11116 +
11117 +#endif // _FSA_PERFPACK_H_
11118 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/port.h linux/drivers/scsi/aacraid/include/port.h
11119 --- linux-2.4.4/drivers/scsi/aacraid/include/port.h     Wed Dec 31 18:00:00 1969
11120 +++ linux/drivers/scsi/aacraid/include/port.h   Mon Apr 30 09:43:34 2001
11121 @@ -0,0 +1,87 @@
11122 +/*++
11123 + * Adaptec aacraid device driver for Linux.
11124 + *
11125 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11126 + *
11127 + * This program is free software; you can redistribute it and/or modify
11128 + * it under the terms of the GNU General Public License as published by
11129 + * the Free Software Foundation; either version 2, or (at your option)
11130 + * any later version.
11131 + *
11132 + * This program is distributed in the hope that it will be useful,
11133 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11134 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11135 + * GNU General Public License for more details.
11136 + *
11137 + * You should have received a copy of the GNU General Public License
11138 + * along with this program; see the file COPYING.  If not, write to
11139 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11140 + *
11141 + * Module Name:
11142 + *   port.h
11143 + *
11144 + * Abstract: This module defines functions and structures that are in common among all miniports
11145 + *
11146 + *     
11147 + --*/
11148 +
11149 +#ifndef _PORT_
11150 +#define _PORT_
11151 +
11152 +static char *ident_porth = "aacraid_ident port.h 1.0.6 2000/10/09 Adaptec, Inc.";
11153 +
11154 +#ifdef DBG
11155 +#define AfaPortPrint if (AfaPortPrinting) DbgPrint
11156 +extern int AfaPortPrinting;
11157 +#else
11158 +#define AfaPortPrint 
11159 +#endif DBG
11160 +
11161 +extern int AfaPortPrinting;
11162 +
11163 +
11164 +BOOLEAN
11165 +AfaPortAllocateAdapterCommArea(
11166 +       IN PVOID                Arg1,
11167 +       IN OUT PVOID    *CommHeaderAddress,
11168 +       IN ULONG                CommAreaSize,
11169 +       IN ULONG                CommAreaAlignment
11170 +       );
11171 +
11172 +
11173 +BOOLEAN
11174 +AfaPortFreeAdapterCommArea(
11175 +       IN PVOID                Arg1
11176 +       );
11177 +
11178 +
11179 +AAC_STATUS
11180 +AfaPortBuildSgMap(
11181 +       PVOID Arg1,
11182 +       IN PSGMAP_CONTEXT SgMapContext
11183 +       );
11184 +
11185 +
11186 +VOID
11187 +AfaPortFreeDmaResources(
11188 +       PVOID Arg1,
11189 +    IN PSGMAP_CONTEXT SgMapContext
11190 +    );
11191 +
11192 +
11193 +BOOLEAN
11194 +AfaPortAllocateAndMapFibSpace(
11195 +       PVOID Arg1,
11196 +    IN PMAPFIB_CONTEXT MapFibContext
11197 +    );
11198 +
11199 +
11200 +BOOLEAN
11201 +AfaPortUnmapAndFreeFibSpace(
11202 +       PVOID Arg1,
11203 +    IN PMAPFIB_CONTEXT MapFibContext
11204 +    );
11205 +
11206 +
11207 +#endif // _PORT_
11208 +
11209 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/protocol.h linux/drivers/scsi/aacraid/include/protocol.h
11210 --- linux-2.4.4/drivers/scsi/aacraid/include/protocol.h Wed Dec 31 18:00:00 1969
11211 +++ linux/drivers/scsi/aacraid/include/protocol.h       Mon Apr 30 09:43:34 2001
11212 @@ -0,0 +1,249 @@
11213 +/*++
11214 + * Adaptec aacraid device driver for Linux.
11215 + *
11216 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11217 + *
11218 + * This program is free software; you can redistribute it and/or modify
11219 + * it under the terms of the GNU General Public License as published by
11220 + * the Free Software Foundation; either version 2, or (at your option)
11221 + * any later version.
11222 + *
11223 + * This program is distributed in the hope that it will be useful,
11224 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11225 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11226 + * GNU General Public License for more details.
11227 + *
11228 + * You should have received a copy of the GNU General Public License
11229 + * along with this program; see the file COPYING.  If not, write to
11230 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11231 + *
11232 + * Module Name:
11233 + *   protocol.h
11234 + *
11235 + * Abstract: Defines the commands and command data which enables the nt
11236 + *    filesystem driver to be the client of the fsa adapter
11237 + *    filesystem. This protocol is largely modeled after the NFS
11238 + *    V3 protocol with modifications allowed due to the unique
11239 + *    client/server model FSA works under.
11240 + *
11241 + *
11242 + *     
11243 + --*/
11244 +
11245 +#ifndef _PROTOCOL_H_
11246 +#define _PROTOCOL_H_
11247 +
11248 +static char *ident_protocol = "aacraid_ident protocol.h 1.0.6 2000/10/09 Adaptec, Inc.";
11249 +
11250 +#include <fsafs.h>      // definition of FSAFID; includes fsatypes.h
11251 +#include <nvramioctl.h> // for NVRAMINFO definition
11252 +
11253 +// #define MDL_READ_WRITE
11254 +
11255 +//
11256 +// Define the command values
11257 +//
11258 +typedef enum _FSA_COMMANDS {
11259 +        Null = 0,
11260 +        GetAttributes,
11261 +        SetAttributes,
11262 +        Lookup,
11263 +        ReadLink,
11264 +        Read,
11265 +        Write,
11266 +        Create,
11267 +        MakeDirectory,
11268 +        SymbolicLink,
11269 +        MakeNode,
11270 +        Removex,
11271 +        RemoveDirectoryx, // bkpfix added x to this because already defined in nt
11272 +        Rename,
11273 +        Link,
11274 +        ReadDirectory,
11275 +        ReadDirectoryPlus,
11276 +        FileSystemStatus,
11277 +        FileSystemInfo,
11278 +        PathConfigure,
11279 +        Commit,
11280 +        Mount,
11281 +        UnMount,
11282 +        Newfs,
11283 +        FsCheck,
11284 +        FsSync,
11285 +               SimReadWrite,
11286 +               SetFileSystemStatus,
11287 +               BlockRead,
11288 +               BlockWrite,
11289 +               NvramIoctl,
11290 +               FsSyncWait,
11291 +               ClearArchiveBit,
11292 +#ifdef MDL_READ_WRITE
11293 +               MdlReadComplete,
11294 +               MdlWriteComplete,
11295 +               MdlRead,                        // these are used solely for stats, Mdl really controlled by 
11296 +               MdlWrite,                       // flags field in Fib.
11297 +#endif
11298 +               SetAcl,
11299 +               GetAcl,
11300 +               AssignAcl,
11301 +               FaultInsertion,         // Fault Insertion Command
11302 +               CrazyCache,                     // crazycache
11303 +               MAX_FSACOMMAND_NUM      //CJ: used for sizing stats array - leave last
11304 +} _E_FSACOMMAND;
11305 +
11306 +#ifdef AAC_32BIT_ENUMS
11307 +typedef        _E_FSACOMMAND   FSACOMMAND;
11308 +#else
11309 +typedef AAC_UINT32             FSACOMMAND;
11310 +#endif
11311 +
11312 +
11313 +
11314 +//
11315 +// Define the status returns
11316 +//
11317 +// See include\comm\errno.h for adapter kernel errno's
11318 +typedef enum _FSASTATUS {
11319 +       ST_OK = 0,
11320 +       ST_PERM = 1,
11321 +       ST_NOENT = 2,
11322 +       ST_IO = 5,
11323 +       ST_NXIO = 6,
11324 +       ST_E2BIG = 7,
11325 +       ST_ACCES = 13,
11326 +       ST_EXIST = 17,
11327 +       ST_XDEV = 18,
11328 +       ST_NODEV = 19,
11329 +       ST_NOTDIR = 20,
11330 +       ST_ISDIR = 21,
11331 +       ST_INVAL = 22,
11332 +       ST_FBIG = 27,
11333 +       ST_NOSPC = 28,
11334 +       ST_ROFS = 30,
11335 +       ST_MLINK = 31,
11336 +       ST_WOULDBLOCK = 35,
11337 +       ST_NAMETOOLONG = 63,
11338 +       ST_NOTEMPTY = 66,
11339 +       ST_DQUOT = 69,
11340 +       ST_STALE = 70,
11341 +       ST_REMOTE = 71,
11342 +       ST_BADHANDLE = 10001,
11343 +       ST_NOT_SYNC = 10002,
11344 +       ST_BAD_COOKIE = 10003,
11345 +       ST_NOTSUPP = 10004,
11346 +       ST_TOOSMALL = 10005,
11347 +       ST_SERVERFAULT = 10006,
11348 +       ST_BADTYPE = 10007,
11349 +       ST_JUKEBOX = 10008,
11350 +       ST_NOTMOUNTED = 10009,
11351 +       ST_MAINTMODE = 10010,
11352 +       ST_STALEACL = 10011
11353 +} _E_FSASTATUS;
11354 +
11355 +#ifdef AAC_32BIT_ENUMS
11356 +typedef _E_FSASTATUS   FSASTATUS;
11357 +#else
11358 +typedef        AAC_UINT32              FSASTATUS;
11359 +#endif
11360 +
11361 +//
11362 +// On writes how does the client want the data written.
11363 +//
11364 +
11365 +typedef enum _CACHELEVEL {
11366 +       CSTABLE = 1,
11367 +    CUNSTABLE
11368 +} _E_CACHELEVEL;
11369 +
11370 +#ifdef AAC_32BIT_ENUMS
11371 +typedef _E_CACHELEVEL  CACHELEVEL;
11372 +#else
11373 +typedef        AAC_UINT32              CACHELEVEL;
11374 +#endif
11375 +
11376 +//
11377 +// Lets the client know at which level the data was commited on a write request
11378 +//
11379 +
11380 +typedef enum _COMMITLEVEL {
11381 +    CMFILE_SYNCH_NVRAM = 1,
11382 +    CMDATA_SYNCH_NVRAM,
11383 +    CMFILE_SYNCH,
11384 +    CMDATA_SYNCH,
11385 +    CMUNSTABLE
11386 +} _E_COMMITLEVEL;
11387 +
11388 +#ifdef AAC_32BIT_ENUMS
11389 +typedef _E_COMMITLEVEL COMMITLEVEL;
11390 +#else
11391 +typedef AAC_UINT32             COMMITLEVEL;
11392 +#endif
11393 +
11394 +
11395 +
11396 +//
11397 +// The following are all the different commands or FIBs which can be sent to the
11398 +// FSA filesystem. We will define a required subset which cannot return STATUS_NOT_IMPLEMENTED,
11399 +// but others outside that subset are allowed to return not implemented. The client is then
11400 +// responsible for dealing with the fact it is not implemented.
11401 +//
11402 +typedef AAC_INT8 FSASTRING[16];
11403 +
11404 +
11405 +typedef AAC_UINT32     BYTECOUNT;      // only 32 bit-ism
11406 +
11407 +
11408 +
11409 +//
11410 +// BlockRead
11411 +//
11412 +
11413 +typedef struct _BLOCKREAD { // variable size struct
11414 +
11415 +    FSACOMMAND                 Command;
11416 +    AAC_UINT32                 ContainerId;
11417 +    BYTECOUNT          BlockNumber;
11418 +    BYTECOUNT          ByteCount;
11419 +       SGMAP                   SgMap;  // Must be last in struct because it is variable
11420 +
11421 +} BLOCKREAD;
11422 +typedef BLOCKREAD *PBLOCKREAD;
11423 +
11424 +typedef struct _BLOCKREADRESPONSE {
11425 +
11426 +    FSASTATUS          Status;
11427 +    BYTECOUNT          ByteCount;
11428 +
11429 +} BLOCKREADRESPONSE;
11430 +typedef BLOCKREADRESPONSE *PBLOCKREADRESPONSE;
11431 +
11432 +//
11433 +// BlockWrite
11434 +//
11435 +
11436 +typedef struct _BLOCKWRITE {   // variable size struct
11437 +
11438 +    FSACOMMAND                 Command;
11439 +    AAC_UINT32                 ContainerId;
11440 +    BYTECOUNT          BlockNumber;
11441 +    BYTECOUNT          ByteCount;
11442 +    CACHELEVEL                 Stable;
11443 +       SGMAP                   SgMap;  // Must be last in struct because it is variable
11444 +
11445 +} BLOCKWRITE;
11446 +typedef BLOCKWRITE *PBLOCKWRITE;
11447 +
11448 +
11449 +typedef struct _BLOCKWRITERESPONSE {
11450 +
11451 +    FSASTATUS          Status;
11452 +    BYTECOUNT          ByteCount;
11453 +    COMMITLEVEL        Committed;
11454 +
11455 +} BLOCKWRITERESPONSE;
11456 +typedef BLOCKWRITERESPONSE *PBLOCKWRITERESPONSE;
11457 +
11458 +
11459 +
11460 +#endif // _PROTOCOL_H_
11461 +
11462 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/revision.h linux/drivers/scsi/aacraid/include/revision.h
11463 --- linux-2.4.4/drivers/scsi/aacraid/include/revision.h Wed Dec 31 18:00:00 1969
11464 +++ linux/drivers/scsi/aacraid/include/revision.h       Mon Apr 30 09:43:34 2001
11465 @@ -0,0 +1,350 @@
11466 +/*++
11467 + * Adaptec aacraid device driver for Linux.
11468 + *
11469 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11470 + *
11471 + * This program is free software; you can redistribute it and/or modify
11472 + * it under the terms of the GNU General Public License as published by
11473 + * the Free Software Foundation; either version 2, or (at your option)
11474 + * any later version.
11475 + *
11476 + * This program is distributed in the hope that it will be useful,
11477 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11478 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11479 + * GNU General Public License for more details.
11480 + *
11481 + * You should have received a copy of the GNU General Public License
11482 + * along with this program; see the file COPYING.  If not, write to
11483 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11484 + *
11485 + * Module Name:
11486 + *   revision.h
11487 + *
11488 + * Abstract: This module contains all of the revision information for
11489 + *     the FSA product, as well as the support routines for
11490 + *     checking module compatibility.
11491 + *
11492 + *     Before editing anything in this module, make sure that
11493 + *     you read the comments. Some lines are changed automatically
11494 + *     as part of the build, and should never be changed by hand.
11495 + *
11496 + * Routines (all inlines):
11497 + *
11498 + *     RevGetBuildNumber - Retrieve current build number
11499 + *     RevGetExternalRev - Retrieve revision for external use
11500 + *     RevGetFullRevision - Retrieve full revision structure
11501 + *
11502 + *     RevCheckCompatibility - Checks compatibility base on internal table
11503 + *
11504 + *     RevCheckCompatibilityFullInfo - Check for static component
11505 + *     RevGetCompInfoTableSize - Get size for static component table
11506 + *     RevGetCompInfoTable - Get actual table to place on static component
11507 + *     RevGetBuildNumberFromInfo - Get build number for static component.
11508 + *
11509 + *
11510 + *     
11511 + --*/
11512 +
11513 +#ifndef _REVISION_H
11514 +#define _REVISION_H
11515 +
11516 +static char *ident_revision = "aacraid_ident revision.h 1.0.6 2000/10/09 Adaptec, Inc.";
11517 +
11518 +#include "version.h" // revision numbers kept separate so they can be used by resource compiler as well
11519 +
11520 +typedef int REV_BOOL;
11521 +
11522 +#define REV_TRUE 1
11523 +#define REV_FALSE 0
11524 +
11525 +//
11526 +//     Define Revision Levels for this product
11527 +//
11528 +//  IMPORTANT: Do NOT modify BUILD_NUMBER define, this is modified
11529 +//                        automatically by the build.
11530 +//
11531 +//  Version is VMAJOR.MINOR-DASH TYPE (Build BUILD_NUMBER)
11532 +//
11533 +//     IMPORTANT: Don't access these revisions directly. They can be
11534 +//                        accessed via, the RevGetXxxxx rouines.
11535 +//
11536 +
11537 +
11538 +#define REV_AS_LONGWORD \
11539 +       ((REV_MAJOR << 24) | (REV_MINOR << 16) | (REV_TYPE << 8) | (REV_DASH))
11540 +
11541 +
11542 +
11543 +#ifndef BIOS
11544 +
11545 +//
11546 +//     Enumerate the types of product levels we can have
11547 +//
11548 +enum {
11549 +       RevType_Devo=1,         // Development mode, testing all of latest
11550 +       RevType_Alpha,          // Alpha - Internal field test
11551 +       RevType_Beta,           // Beta - External field test
11552 +       RevType_Release         // Release - Retail version
11553 +};
11554 +
11555 +//
11556 +//     Define the basic structure for all revision information. Note
11557 +//     that the ordering of the components is such that they should
11558 +//     always increase. dash will be updated the most, then the version
11559 +//     type, then minor and major.
11560 +//
11561 +typedef struct {
11562 +       union {
11563 +               struct {
11564 +                       unsigned char dash;     // Dash version number
11565 +                       unsigned char type;     // Type, 1=Devo, 2=Alpha, 3=Beta, 4=Release
11566 +                       unsigned char minor;// Minor version minor
11567 +                       unsigned char major;// Major version number
11568 +               } comp;                         // Components to external viewed rev number
11569 +               unsigned long ul;       // External revision as single 32-bit value
11570 +       } external;                     // External revision number (union)
11571 +       unsigned long buildNumber; // Automatically generated build number
11572 +} FsaRevision;
11573 +
11574 +
11575 +//
11576 +//     Define simple routines to get basic revision information. The
11577 +//     definitions should never be accessed directly. These routines
11578 +//     are meant to be used to access all relevant information no matter
11579 +//     how simple.
11580 +//
11581 +static inline unsigned long RevGetBuildNumber() {return REV_BUILD_NUMBER;}
11582 +
11583 +static inline unsigned long RevGetExternalRev() {return REV_AS_LONGWORD;}
11584 +
11585 +
11586 +//
11587 +//     Enumerate different components that may have to check
11588 +//     compatibility. This list of components can be changed
11589 +//     at any time.
11590 +//
11591 +//     IMPORTANT: ONLY add to the END of this enum structure. Otherwise,
11592 +//                        incompatibilities between component rev checking will
11593 +//                        cause wrong checking results.
11594 +//
11595 +typedef enum {
11596 +       RevApplication = 1,     // Any user End application
11597 +       RevDkiCli,                      // ADAPTEC proprietary interface (knows FIBs)
11598 +       RevNetService,          // Network Service Revision (under API)
11599 +       RevApi,                         // ADAPTEC User mode API
11600 +       RevFileSysDriver,       // FSA File System Driver
11601 +       RevMiniportDriver,      // FSA File System Miniport Driver
11602 +       RevAdapterSW,           // Adapter Software (or NT Simulator)
11603 +       RevMonitor,                     // Monitor for adapter hardware (MON960 for now)
11604 +       RevRemoteApi            // The remote API.
11605 +       // ALWAYS ADD NEW COMPONENTS HERE - AT END
11606 +} RevComponent;
11607 +
11608 +//
11609 +//     Define a structure so that we can create a compatibility table.
11610 +//
11611 +typedef struct {
11612 +       RevComponent A,B;
11613 +       unsigned long BuildNumOfB_RequiredByA;
11614 +       unsigned long BuildNumOfA_RequiredByB;
11615 +} RevCompareElement;
11616 +
11617 +//
11618 +//     Now, define the table. This table should only be included once,
11619 +//     in one program. If it is linked from 2 modules, there will likely
11620 +//     be a multiply defined symbol error from the linker.
11621 +//
11622 +//     To fix this problem, REV_REFERENCE_ONLY can be defined. This will
11623 +//     allow access to the revision information table without a redefinition
11624 +//     of the tables.
11625 +//
11626 +extern const int                          RevCompareTableLength;
11627 +
11628 +extern const RevCompareElement RevCompareTable[];
11629 +
11630 +/********************************************************************\
11631 +* Routine: RevCheckCompatibility(callerComp,compB,compB_BuildNumber)
11632 +*
11633 +*      The following routine is used to check compatibility between
11634 +*      the calling component and a component that has some dependencies
11635 +*      on it. If this routine returns REV_FALSE, it is expected that the caller
11636 +*      will send an appropriate incompatibility message and stop.
11637 +*
11638 +*      This routine is only meant to check for compatibility in the
11639 +*      absolute sense. If code wishes to execute a different path based
11640 +*      on the CompB_BuildNumber, then this routine is not useful. The
11641 +*      routine RevGetBuildNumber can be used to get the calling module's
11642 +*      current build number for a comparison check.
11643 +*
11644 +*      The return value is REV_TRUE, if compatibility is possible, and REV_FALSE
11645 +*      if the components are definitely not compatible, or there is an
11646 +*      error when trying to figure it out. To be more specific:
11647 +*
11648 +*              1) REV_TRUE if component B is newer than calling component. (In this
11649 +*                 case, the revision check done by component B with respect to
11650 +*                 this component will give the real compatibility information.
11651 +*                 It is the only one with the knowledge, since this component
11652 +*                 could not look into the future.)
11653 +*              2) REV_TRUE if calling component is more recent and table shows okay
11654 +*              3) REV_FALSE if calling component more recent and table show not okay
11655 +*              4) REV_FALSE if calling component is more recent and table entry to
11656 +*                 check does not exist.
11657 +*
11658 +*      Note that the CompB_BuildNumber must be attained by the calling
11659 +*      routine through some mechanism done by the caller.
11660 +*
11661 +* Input:
11662 +*
11663 +*      callerComp - Name of component making this call
11664 +*      compB - Name of component to check compatibility with
11665 +*      compB_BuildNumber - Build number to component B
11666 +*
11667 +* Output:
11668 +*
11669 +*      None
11670 +*
11671 +* Return Value:
11672 +*
11673 +*      REV_TRUE - Component compatibility is possible, continue as usual. compB
11674 +*                 must give true compatibility information.
11675 +*      REV_FALSE - Incompatible components, notify and end
11676 +*
11677 +\********************************************************************/
11678 +static inline REV_BOOL RevCheckCompatibility(
11679 +               RevComponent callerComp,
11680 +               RevComponent compB,
11681 +               unsigned long compB_BuildNumber)
11682 +{
11683 +       int i;
11684 +       unsigned long RevForB;
11685 +
11686 +       //
11687 +       //      Compatibility check is possible, so we should continue. When
11688 +       //      compB makes this call in its own component, it will get the
11689 +       //      true compatibility information, since only it can know.
11690 +       //
11691 +       if (RevGetBuildNumber() < compB_BuildNumber) return REV_TRUE;
11692 +
11693 +       //
11694 +       //      Go through rev table. When the components are found in the
11695 +       //      same table entry, return the approprate number.
11696 +       //
11697 +       for (i=0; i<RevCompareTableLength; i++) {
11698 +               if (RevCompareTable[i].A == callerComp) {
11699 +                       if (RevCompareTable[i].B == compB) {
11700 +                               RevForB = RevCompareTable[i].BuildNumOfB_RequiredByA;
11701 +                               return (compB_BuildNumber >= RevForB);
11702 +                       }
11703 +               } else if (RevCompareTable[i].B == callerComp) {
11704 +                       if (RevCompareTable[i].A == compB) {
11705 +                               RevForB = RevCompareTable[i].BuildNumOfA_RequiredByB;
11706 +                               return (compB_BuildNumber >= RevForB);
11707 +                       }
11708 +               }
11709 +       }
11710 +
11711 +       //
11712 +       //      Uh oh! No relevant table entry was found (this should never
11713 +       //      happen).
11714 +       //
11715 +       return REV_FALSE;
11716 +}
11717 +
11718 +
11719 +//
11720 +//     Now create a structure that can be used by a FIB to check
11721 +//     compatibility.
11722 +//
11723 +typedef struct _RevCheck {
11724 +       RevComponent callingComponent;
11725 +       FsaRevision callingRevision;
11726 +} RevCheck;
11727 +
11728 +typedef struct _RevCheckResp {
11729 +       REV_BOOL possiblyCompatible;
11730 +       FsaRevision adapterSWRevision;
11731 +} RevCheckResp;
11732 +
11733 +#endif /* bios */
11734 +#endif /* _REVISION_H */
11735 +
11736 +//
11737 +//     The following allows for inclusion of revision.h in other h
11738 +//     files. when you include this file in another h file, simply
11739 +//     define REV_REFERENCE_ONLY. This will be undefined later, so that
11740 +//     the single C file inclusion in the module will be used to
11741 +//     implement the global structures.
11742 +//
11743 +#ifndef REV_REFERENCE_ONLY
11744 +#ifndef _REVISION_H_GLOBAL
11745 +#define _REVISION_H_GLOBAL
11746 +
11747 +
11748 +
11749 +//
11750 +//     The following array is the table of compatibility. This table
11751 +//     can be modified in two ways:
11752 +//
11753 +//             1) A component which has an incompatible change done to
11754 +//                it, can get a new build number.
11755 +//
11756 +//             2) A new component can be added, requiring more entries
11757 +//                to be place into this table.
11758 +//
11759 +//
11760 +//     In case (1), you must change the revision number in the appropriate
11761 +//     column, based on which component absolutely requires an upgrade.
11762 +//
11763 +//     Example: A new FIB used by the API, in build number 105
11764 +//             {RevApi,        RevAdapterSW,           100,  100}
11765 +//                     ---> would be changed to <---
11766 +//             {RevApi,        RevAdapterSW,           105,  100}
11767 +//
11768 +//     Example: A structure is changed for a FIB that only the API uses
11769 +//             {RevApi,        RevAdapterSW,           100,  100}
11770 +//                     ---> would be changed to <---
11771 +//             {RevApi,        RevAdapterSW,           105,  105}
11772 +//
11773 +//
11774 +//     In case (2), the less common case, the enumerated list of
11775 +//     components must be changed to include the new component. Then
11776 +//     entries need to be placed into this table.
11777 +//
11778 +//     Since the revisions must be communicated between the two
11779 +//     components, it is likely that you would need to put in the
11780 +//     current build number for both columns. That is the recommended
11781 +//     way to start revision test.
11782 +//
11783 +const RevCompareElement RevCompareTable[] = {
11784 +       // Component A          Component B                     MinBForA        MinAForB
11785 +       // -----------          -----------                     --------        --------
11786 +       {RevApplication,        RevApi,                         2120,           2120    },
11787 +       {RevDkiCli,             RevApi,                         2120,           2120    },
11788 +       {RevDkiCli,             RevFileSysDriver,               257,            257     },
11789 +       {RevDkiCli,             RevMiniportDriver,              257,            257     },
11790 +       {RevDkiCli,             RevAdapterSW,                   257,            257     },
11791 +       {RevApi,                RevFileSysDriver,               2120,           2120    },
11792 +       {RevApi,                RevMiniportDriver,              2120,           2120    },
11793 +       {RevApi,                RevAdapterSW,                   2120,           2120    },
11794 +       {RevApi,                RevNetService,                  2120,           2120    },
11795 +       {RevFileSysDriver,      RevMiniportDriver,              100,            100     },
11796 +       {RevFileSysDriver,      RevAdapterSW,                   257,            257     },
11797 +       {RevMiniportDriver,     RevAdapterSW,                   257,            257     },
11798 +       {RevMiniportDriver,     RevMonitor,                     100,            100     },
11799 +       {RevApi,                RevNetService,                  2120,           2120    },
11800 +       {RevApi,                RevRemoteApi,                   2120,           2120    },
11801 +       {RevNetService,         RevRemoteApi,                   2120,           2120    }
11802 +};
11803 +
11804 +const int RevCompareTableLength = sizeof(RevCompareTable)/sizeof(RevCompareElement);
11805 +
11806 +#endif /* _REVISION_H_GLOBAL */
11807 +#endif /* REV_REFERENCE_ONLY */
11808 +#undef REV_REFERENCE_ONLY
11809 +
11810 +
11811 +
11812 +
11813 +
11814 +
11815 +
11816 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/rx.h linux/drivers/scsi/aacraid/include/rx.h
11817 --- linux-2.4.4/drivers/scsi/aacraid/include/rx.h       Wed Dec 31 18:00:00 1969
11818 +++ linux/drivers/scsi/aacraid/include/rx.h     Mon Apr 30 09:43:34 2001
11819 @@ -0,0 +1,81 @@
11820 +/*++
11821 + * Adaptec aacraid device driver for Linux.
11822 + *
11823 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11824 + *
11825 + * This program is free software; you can redistribute it and/or modify
11826 + * it under the terms of the GNU General Public License as published by
11827 + * the Free Software Foundation; either version 2, or (at your option)
11828 + * any later version.
11829 + *
11830 + * This program is distributed in the hope that it will be useful,
11831 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11832 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11833 + * GNU General Public License for more details.
11834 + *
11835 + * You should have received a copy of the GNU General Public License
11836 + * along with this program; see the file COPYING.  If not, write to
11837 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11838 + *
11839 + * Module Name:
11840 + *   rx.h
11841 + *
11842 + * Abstract: Prototypes and data structures unique to the Rx based controller board.
11843 + *
11844 + *     
11845 + --*/
11846 +
11847 +static char *ident_rxh = "aacraid_ident rx.h 1.0.6 2000/10/09 Adaptec, Inc.";
11848 +
11849 +typedef struct _Rx_ADAPTER_EXTENSION {
11850 +
11851 +       //
11852 +       // The following must be first.
11853 +       //
11854 +       PPCI_MINIPORT_COMMON_EXTENSION  Common;
11855 +       struct _Rx_ADAPTER_EXTENSION    *Next;                          // Next adapter miniport structure
11856 +    USHORT                                                     LocalMaskInterruptControl;
11857 +       PRx_DEVICE_REGISTERS                    Device;
11858 +
11859 +} Rx_ADAPTER_EXTENSION;
11860 +
11861 +    
11862 +typedef Rx_ADAPTER_EXTENSION *PRx_ADAPTER_EXTENSION;
11863 +
11864 +
11865 +
11866 +#ifdef LINUX
11867 +/*
11868 + * 
11869 + */
11870 +
11871 +#define Rx_READ_UCHAR(AEP,  CSR)                       *(volatile unsigned char *)  &((AEP)->Device->CSR)
11872 +    
11873 +
11874 +
11875 +#define Rx_READ_ULONG(AEP,  CSR)                       *(volatile unsigned int *)   &((AEP)->Device->CSR)
11876 +#define Rx_WRITE_UCHAR(AEP,  CSR, Value)       *(volatile unsigned char *)  &((AEP)->Device->CSR) = (Value)
11877 +
11878 +
11879 +#define Rx_WRITE_ULONG(AEP, CSR, Value)                *(volatile unsigned int *)   &((AEP)->Device->CSR) = (Value)
11880 +
11881 +#endif /* LINUX */
11882 +
11883 +
11884 +VOID
11885 +RxInterruptAdapter(
11886 +       PVOID Arg1
11887 +       );
11888 +
11889 +VOID
11890 +RxNotifyAdapter(
11891 +       PVOID Arg1,
11892 +    IN HOST_2_ADAP_EVENT AdapterEvent
11893 +    );
11894 +
11895 +VOID
11896 +RxResetDevice(
11897 +       PVOID Arg1
11898 +       );
11899 +
11900 +
11901 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/rxcommon.h linux/drivers/scsi/aacraid/include/rxcommon.h
11902 --- linux-2.4.4/drivers/scsi/aacraid/include/rxcommon.h Wed Dec 31 18:00:00 1969
11903 +++ linux/drivers/scsi/aacraid/include/rxcommon.h       Mon Apr 30 09:43:34 2001
11904 @@ -0,0 +1,105 @@
11905 +/*++
11906 + * Adaptec aacraid device driver for Linux.
11907 + *
11908 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11909 + *
11910 + * This program is free software; you can redistribute it and/or modify
11911 + * it under the terms of the GNU General Public License as published by
11912 + * the Free Software Foundation; either version 2, or (at your option)
11913 + * any later version.
11914 + *
11915 + * This program is distributed in the hope that it will be useful,
11916 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11917 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11918 + * GNU General Public License for more details.
11919 + *
11920 + * You should have received a copy of the GNU General Public License
11921 + * along with this program; see the file COPYING.  If not, write to
11922 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11923 + *
11924 + * Module Name:
11925 + *   rxcommon.h
11926 + *
11927 + * Abstract: Structures and defines for the i960 Rx chip.
11928 + *
11929 + *     
11930 + --*/
11931 +
11932 +#ifndef _Rx_COMMON_H_
11933 +#define _Rx_COMMON_H_
11934 +
11935 +static char *ident_rxcommon = "aacraid_ident rxcommon.h 1.0.6 2000/10/09 Adaptec, Inc.";
11936 +
11937 +//
11938 +// Rx Message Unit Registers
11939 +//
11940 +
11941 +typedef volatile struct _StructRxMURegisters {
11942 +                                                                               //       Local  |   PCI*        |       Name
11943 +                                                                               //                      |               |
11944 +       unsigned        ARSR;                                   //      1300h   |       00h     |       APIC Register Select Register
11945 +       unsigned        reserved0;                              //      1304h   |       04h     |       Reserved
11946 +       unsigned        AWR;                                    //      1308h   |       08h     |       APIC Window Register
11947 +       unsigned        reserved1;                              //      130Ch   |       0Ch     |       Reserved
11948 +       unsigned        IMRx[2];                                //      1310h   |       10h     |       Inbound Message Registers
11949 +       unsigned        OMRx[2];                                //      1318h   |       18h     |       Outbound Message Registers
11950 +       unsigned        IDR;                                    //      1320h   |       20h     |       Inbound Doorbell Register
11951 +       unsigned        IISR;                                   //      1324h   |       24h     |       Inbound Interrupt Status Register
11952 +       unsigned        IIMR;                                   //      1328h   |       28h     |       Inbound Interrupt Mask Register
11953 +       unsigned        ODR;                                    //      132Ch   |       2Ch     |       Outbound Doorbell Register
11954 +       unsigned        OISR;                                   //      1330h   |       30h     |       Outbound Interrupt Status Register
11955 +       unsigned        OIMR;                                   //      1334h   |       34h     |       Outbound Interrupt Mask Register
11956 +                                                                               // * Must access trhough ATU Inbound Translation Window
11957 +
11958 +}Rx_MU_CONFIG;
11959 +typedef Rx_MU_CONFIG *PRx_MU_CONFIG;
11960 +
11961 +typedef volatile struct _Rx_Inbound {
11962 +
11963 +       unsigned        Mailbox[8];
11964 +
11965 +}Rx_Inbound;
11966 +
11967 +typedef Rx_Inbound *PRx_Inbound;
11968 +
11969 +#define        InboundMailbox0         IndexRegs.Mailbox[0]
11970 +#define        InboundMailbox1         IndexRegs.Mailbox[1]
11971 +#define        InboundMailbox2         IndexRegs.Mailbox[2]
11972 +#define        InboundMailbox3         IndexRegs.Mailbox[3]
11973 +#define        InboundMailbox4         IndexRegs.Mailbox[4]
11974 +
11975 +
11976 +
11977 +#define        INBOUNDDOORBELL_0       0x00000001
11978 +#define INBOUNDDOORBELL_1      0x00000002
11979 +#define INBOUNDDOORBELL_2      0x00000004
11980 +#define INBOUNDDOORBELL_3      0x00000008
11981 +#define INBOUNDDOORBELL_4      0x00000010
11982 +#define INBOUNDDOORBELL_5      0x00000020
11983 +#define INBOUNDDOORBELL_6      0x00000040
11984 +
11985 +
11986 +#define        OUTBOUNDDOORBELL_0      0x00000001
11987 +#define OUTBOUNDDOORBELL_1     0x00000002
11988 +#define OUTBOUNDDOORBELL_2     0x00000004
11989 +#define OUTBOUNDDOORBELL_3     0x00000008
11990 +#define OUTBOUNDDOORBELL_4     0x00000010
11991 +
11992 +
11993 +#define InboundDoorbellReg     MUnit.IDR
11994 +
11995 +#define OutboundDoorbellReg    MUnit.ODR
11996 +
11997 +
11998 +typedef struct _Rx_DEVICE_REGISTERS {
11999 +       Rx_MU_CONFIG                    MUnit;                  // 1300h - 1334h
12000 +       unsigned                                reserved1[6];   // 1338h - 134ch
12001 +       Rx_Inbound                              IndexRegs;
12002 +} Rx_DEVICE_REGISTERS;
12003 +
12004 +typedef Rx_DEVICE_REGISTERS *PRx_DEVICE_REGISTERS;
12005 +
12006 +
12007 +#endif // _Rx_COMMON_H_
12008 +
12009 +
12010 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/sap1.h linux/drivers/scsi/aacraid/include/sap1.h
12011 --- linux-2.4.4/drivers/scsi/aacraid/include/sap1.h     Wed Dec 31 18:00:00 1969
12012 +++ linux/drivers/scsi/aacraid/include/sap1.h   Mon Apr 30 09:43:34 2001
12013 @@ -0,0 +1,85 @@
12014 +/*++
12015 + * Adaptec aacraid device driver for Linux.
12016 + *
12017 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
12018 + *
12019 + * This program is free software; you can redistribute it and/or modify
12020 + * it under the terms of the GNU General Public License as published by
12021 + * the Free Software Foundation; either version 2, or (at your option)
12022 + * any later version.
12023 + *
12024 + * This program is distributed in the hope that it will be useful,
12025 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
12026 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12027 + * GNU General Public License for more details.
12028 + *
12029 + * You should have received a copy of the GNU General Public License
12030 + * along with this program; see the file COPYING.  If not, write to
12031 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
12032 + *
12033 + * Module Name:
12034 + *   sap1.h
12035 + *
12036 + * Abstract: Prototypes and data structures unique to the Strong Arm based controller board.
12037 + *
12038 + *     
12039 + --*/
12040 +#ifndef _SAP1_H_
12041 +#define _SAP1_H_
12042 +
12043 +static char *ident_sap1h = "aacraid_ident sap1.h 1.0.6 2000/10/09 Adaptec, Inc.";
12044 +
12045 +#define Sa_MINIPORT_REVISION                   1
12046 +
12047 +typedef struct _Sa_ADAPTER_EXTENSION {
12048 +
12049 +       //
12050 +       // The following must be first.
12051 +       //
12052 +       PPCI_MINIPORT_COMMON_EXTENSION  Common;
12053 +       struct _Sa_ADAPTER_EXTENSION    *Next;                  // Next adapter miniport structure
12054 +       USHORT                                                  LocalMaskInterruptControl;
12055 +       PSa_DEVICE_REGISTERS                    Device;
12056 +
12057 +} Sa_ADAPTER_EXTENSION;
12058 +
12059 +typedef Sa_ADAPTER_EXTENSION *PSa_ADAPTER_EXTENSION;
12060 +
12061
12062 +
12063 +#ifdef LINUX
12064 +/*
12065 + * 
12066 + */
12067 +
12068
12069 +#define Sa_READ_USHORT(AEP, CSR)                       *(volatile unsigned short *) &((AEP)->Device->CSR)
12070 +#define Sa_READ_ULONG(AEP,  CSR)                       *(volatile unsigned int *)   &((AEP)->Device->CSR)
12071 +
12072
12073 +#define Sa_WRITE_USHORT(AEP, CSR, Value)       *(volatile unsigned short *) &((AEP)->Device->CSR) = (Value)
12074 +#define Sa_WRITE_ULONG(AEP, CSR, Value)                *(volatile unsigned int *)   &((AEP)->Device->CSR) = (Value)
12075 +
12076 +#endif /* LINUX */
12077 +
12078
12079 +VOID
12080 +SaInterruptAdapter(
12081 +       PVOID Arg1
12082 +       );
12083 +
12084 +VOID
12085 +SaNotifyAdapter(
12086 +       PVOID Arg1,
12087 +    IN HOST_2_ADAP_EVENT AdapterEvent
12088 +    );
12089 +
12090 +VOID
12091 +SaResetDevice(
12092 +       PVOID Arg1
12093 +       );
12094 +
12095
12096 +#endif /* _SAP1_H_ */
12097 +
12098 +
12099 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/sap1common.h linux/drivers/scsi/aacraid/include/sap1common.h
12100 --- linux-2.4.4/drivers/scsi/aacraid/include/sap1common.h       Wed Dec 31 18:00:00 1969
12101 +++ linux/drivers/scsi/aacraid/include/sap1common.h     Mon Apr 30 09:43:34 2001
12102 @@ -0,0 +1,111 @@
12103 +/*++
12104 + * Adaptec aacraid device driver for Linux.
12105 + *
12106 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
12107 + *
12108 + * This program is free software; you can redistribute it and/or modify
12109 + * it under the terms of the GNU General Public License as published by
12110 + * the Free Software Foundation; either version 2, or (at your option)
12111 + * any later version.
12112 + *
12113 + * This program is distributed in the hope that it will be useful,
12114 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
12115 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12116 + * GNU General Public License for more details.
12117 + *
12118 + * You should have received a copy of the GNU General Public License
12119 + * along with this program; see the file COPYING.  If not, write to
12120 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
12121 + *
12122 + * Module Name:
12123 + *   sap1common.h
12124 + *
12125 + * Abstract: Structures and defines for the Drawbridge and StrongArm110 chip.
12126 + *     
12127 + --*/
12128 +
12129 +#ifndef _Sa_COMMON_H_
12130 +#define _Sa_COMMON_H_
12131 +
12132 +static char *ident_sap1common = "aacraid_ident sap1common.h 1.0.6 2000/10/09 Adaptec, Inc.";
12133 +
12134 +//
12135 +// SaP1 Message Unit Registers
12136 +//
12137 +
12138 +typedef volatile struct _StructSaDrawbridge_CSR_RegisterMap {
12139 +                                                                                               //       Offset |       Name
12140 +       unsigned                        reserved[10];                   //      00h-27h |   Reserved
12141 +       unsigned char           LUT_Offset;                             //              28h     |       Looup Table Offset
12142 +       unsigned char           reserved1[3];                   //      29h-2bh |       Reserved
12143 +       unsigned                        LUT_Data;                               //              2ch     |       Looup Table Data        
12144 +       unsigned                        reserved2[26];                  //      30h-97h |       Reserved
12145 +       unsigned short          PRICLEARIRQ;                    //              98h     |       Primary Clear Irq
12146 +       unsigned short          SECCLEARIRQ;                    //              9ah     |       Secondary Clear Irq
12147 +       unsigned short          PRISETIRQ;                              //              9ch     |       Primary Set Irq
12148 +       unsigned short          SECSETIRQ;                              //              9eh     |       Secondary Set Irq
12149 +       unsigned short          PRICLEARIRQMASK;                //              a0h     |       Primary Clear Irq Mask
12150 +       unsigned short          SECCLEARIRQMASK;                //              a2h     |       Secondary Clear Irq Mask
12151 +       unsigned short          PRISETIRQMASK;                  //              a4h     |       Primary Set Irq Mask
12152 +       unsigned short          SECSETIRQMASK;                  //              a6h     |       Secondary Set Irq Mask
12153 +       unsigned                        MAILBOX0;                               //              a8h     |       Scratchpad 0
12154 +       unsigned                        MAILBOX1;                               //              ach     |       Scratchpad 1
12155 +       unsigned                        MAILBOX2;                               //              b0h     |       Scratchpad 2
12156 +       unsigned                        MAILBOX3;                               //              b4h     |       Scratchpad 3
12157 +       unsigned                        MAILBOX4;                               //              b8h     |       Scratchpad 4
12158 +       unsigned                        MAILBOX5;                               //              bch     |       Scratchpad 5
12159 +       unsigned                        MAILBOX6;                               //              c0h     |       Scratchpad 6
12160 +       unsigned                        MAILBOX7;                               //              c4h     |       Scratchpad 7
12161 +
12162 +       unsigned                        ROM_Setup_Data;                 //              c8h |   Rom Setup and Data
12163 +       unsigned                        ROM_Control_Addr;               //              cch |   Rom Control and Address
12164 +
12165 +       unsigned                        reserved3[12];                  //      d0h-ffh |       reserved
12166 +       unsigned                        LUT[64];                                // 100h-1ffh|   Lookup Table Entries
12167 +
12168 +       //
12169 +       //  TO DO
12170 +       //      need to add DMA, I2O, UART, etc registers form 80h to 364h
12171 +       //
12172 +
12173 +}Sa_Drawbridge_CSR;
12174 +
12175 +typedef Sa_Drawbridge_CSR *PSa_Drawbridge_CSR;
12176 +
12177 +
12178 +#define Mailbox0       SaDbCSR.MAILBOX0
12179 +#define Mailbox1       SaDbCSR.MAILBOX1
12180 +#define Mailbox2       SaDbCSR.MAILBOX2
12181 +#define Mailbox3       SaDbCSR.MAILBOX3
12182 +#define Mailbox4       SaDbCSR.MAILBOX4
12183 +
12184 +       
12185 +#define Mailbox7       SaDbCSR.MAILBOX7
12186 +       
12187 +#define DoorbellReg_p SaDbCSR.PRISETIRQ
12188 +#define DoorbellReg_s SaDbCSR.SECSETIRQ
12189 +#define DoorbellClrReg_p SaDbCSR.PRICLEARIRQ
12190 +
12191 +
12192 +#define        DOORBELL_0      0x00000001
12193 +#define DOORBELL_1     0x00000002
12194 +#define DOORBELL_2     0x00000004
12195 +#define DOORBELL_3     0x00000008
12196 +#define DOORBELL_4     0x00000010
12197 +#define DOORBELL_5     0x00000020
12198 +#define DOORBELL_6     0x00000040
12199 +
12200 +       
12201 +#define PrintfReady                    DOORBELL_5
12202 +#define PrintfDone                     DOORBELL_5
12203 +       
12204 +typedef struct _Sa_DEVICE_REGISTERS {
12205 +       Sa_Drawbridge_CSR       SaDbCSR;                        // 98h - c4h
12206 +} Sa_DEVICE_REGISTERS;
12207 +       
12208 +typedef Sa_DEVICE_REGISTERS *PSa_DEVICE_REGISTERS;
12209 +
12210 +       
12211 +#endif // _Sa_COMMON_H_
12212 +
12213 +
12214 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/version.h linux/drivers/scsi/aacraid/include/version.h
12215 --- linux-2.4.4/drivers/scsi/aacraid/include/version.h  Wed Dec 31 18:00:00 1969
12216 +++ linux/drivers/scsi/aacraid/include/version.h        Mon Apr 30 09:43:34 2001
12217 @@ -0,0 +1,40 @@
12218 +/*++
12219 + * Adaptec aacraid device driver for Linux.
12220 + *
12221 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
12222 + *
12223 + * This program is free software; you can redistribute it and/or modify
12224 + * it under the terms of the GNU General Public License as published by
12225 + * the Free Software Foundation; either version 2, or (at your option)
12226 + * any later version.
12227 + *
12228 + * This program is distributed in the hope that it will be useful,
12229 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
12230 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12231 + * GNU General Public License for more details.
12232 + *
12233 + * You should have received a copy of the GNU General Public License
12234 + * along with this program; see the file COPYING.  If not, write to
12235 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
12236 + *
12237 + * Module Name:
12238 + *   version.h
12239 + *
12240 + * Abstract: Keeps track of build number for development purposes.
12241 + *     
12242 + --*/
12243 +#ifndef _VERSION_H_
12244 +#define _VERSION_H_
12245 +
12246 +static char *ident_version = "aacraid_ident version.h 1.0.6 2000/10/09 Adaptec, Inc.";
12247 +
12248 +#include "build_number.h"
12249 +
12250 +#define REV_MAJOR 2
12251 +#define REV_MINOR 1
12252 +#define REV_TYPE RevType_Release
12253 +#define REV_DASH 5
12254 +
12255 +#define FSA_VERSION_STRING "2.1.5.3857\0"
12256 +
12257 +#endif /* _VERSION_H_ */
12258 diff -burN linux-2.4.4/drivers/scsi/aacraid/linit.c linux/drivers/scsi/aacraid/linit.c
12259 --- linux-2.4.4/drivers/scsi/aacraid/linit.c    Wed Dec 31 18:00:00 1969
12260 +++ linux/drivers/scsi/aacraid/linit.c  Mon Apr 30 09:47:34 2001
12261 @@ -0,0 +1,1062 @@
12262 +/*++
12263 + * Adaptec aacraid device driver for Linux.
12264 + *
12265 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
12266 + *
12267 + * This program is free software; you can redistribute it and/or modify
12268 + * it under the terms of the GNU General Public License as published by
12269 + * the Free Software Foundation; either version 2, or (at your option)
12270 + * any later version.
12271 + *
12272 + * This program is distributed in the hope that it will be useful,
12273 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
12274 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12275 + * GNU General Public License for more details.
12276 + *
12277 + * You should have received a copy of the GNU General Public License
12278 + * along with this program; see the file COPYING.  If not, write to
12279 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
12280 + *
12281 + * Module Name:
12282 + *   linit.c
12283 + *
12284 + * Abstract: Linux Driver entry module for Adaptec RAID Array Controller
12285 + *                             
12286 + *     Provides the following driver entry points:
12287 + *             AAC_DetectHostAdapter()
12288 + *             AAC_ReleaseHostAdapter()
12289 + *             AAC_QueueCommand()
12290 + *             AAC_ResetCommand()
12291 + *             AAC_BIOSDiskParameters()
12292 + *     
12293 + --*/
12294 +
12295 +static char *ident_linit = "aacraid_ident linit.c 1.0.6 2000/10/09 Adaptec, Inc.";
12296 +
12297 +/*------------------------------------------------------------------------------
12298 + *              D E F I N E S
12299 + *----------------------------------------------------------------------------*/
12300 +#define AAC_DRIVER_VERSION                             "0.1.1"
12301 +#define AAC_DRIVER_BUILD_DATE                  __DATE__
12302 +#define MAX_DRIVER_QUEUE_DEPTH                 500
12303 +
12304 +/*------------------------------------------------------------------------------
12305 + *              I N C L U D E S
12306 + *----------------------------------------------------------------------------*/
12307 +#include "osheaders.h"
12308 +
12309 +#include "AacGenericTypes.h"
12310 +
12311 +#ifdef MODULE
12312 +#include <linux/module.h>
12313 +#endif
12314 +#include "sd.h"
12315 +#include "linit.h"
12316 +#include "aac_unix_defs.h"
12317 +#include "fsatypes.h"
12318 +#include "comstruc.h"
12319 +#include "fsaport.h"
12320 +#include "pcisup.h"
12321 +#include "port.h"
12322 +#include "afacomm.h"
12323 +#include "nodetype.h"
12324 +#include "comsup.h"
12325 +#include "adapter.h"
12326 +
12327 +/*------------------------------------------------------------------------------
12328 + *              G L O B A L S
12329 + *----------------------------------------------------------------------------*/
12330 +extern FSA_MINIPORT MiniPorts[];
12331 +extern int CommPrinting;
12332 +extern char DescriptionString[];
12333 +extern char devicestr[];
12334 +
12335 +/*------------------------------------------------------------------------------
12336 + *              M O D U L E   G L O B A L S
12337 + *----------------------------------------------------------------------------*/
12338 +aac_options_t g_options = { CMN_ERR_LEVEL, 0 };        // default message_level
12339 +
12340 +char g_DriverName[] = { "aacraid" };
12341 +#define module_options aacraid_options
12342 +static char * aacraid_options = NULL;
12343 +
12344 +PCI_MINIPORT_COMMON_EXTENSION *g_CommonExtensionPtrArray[ MAXIMUM_NUM_ADAPTERS ];
12345 +unsigned g_HostAdapterCount = 0;
12346 +unsigned g_chardev_major = 0;
12347 +
12348 +int g_single_command_done = FALSE;
12349 +
12350 +/*------------------------------------------------------------------------------
12351 + *              F U N C T I O N   P R O T O T Y P E S
12352 + *----------------------------------------------------------------------------*/
12353 +int AacHba_Ioctl(
12354 +       PCI_MINIPORT_COMMON_EXTENSION *CommonExtension,
12355 +       int cmd,
12356 +       void * arg );
12357 +
12358 +int AacHba_ProbeContainers( 
12359 +       PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr );
12360 +
12361 +int AacHba_DoScsiCmd(
12362 +       Scsi_Cmnd *scsi_cmnd_ptr,
12363 +       int wait );
12364 +
12365 +void AacHba_DetachAdapter(
12366 +       IN PVOID AdapterArg );
12367 +
12368 +int AacHba_ClassDriverInit(
12369 +       PCI_MINIPORT_COMMON_EXTENSION * CommonExtensionPtr);
12370 +
12371 +void AacHba_AbortScsiCommand(
12372 +       Scsi_Cmnd *scsi_cmnd_ptr );
12373 +
12374 +
12375 +/*------------------------------------------------------------------------------
12376 + *              L O C A L   F U N C T I O N   P R O T O T Y P E S
12377 + *----------------------------------------------------------------------------*/
12378 +static int parse_keyword(
12379 +       char ** str_ptr, 
12380 +       char * keyword );
12381 +
12382 +static void AAC_ParseDriverOptions( 
12383 +       char * cmnd_line_options_str );
12384 +
12385 +static void AAC_AnnounceDriver( void );
12386 +
12387 +int AAC_ChardevIoctl(
12388 +       struct inode * inode_ptr, 
12389 +       struct file * file_ptr,
12390 +       unsigned int cmd,
12391 +       unsigned long arg );
12392 +
12393 +int AAC_ChardevOpen(
12394 +       struct inode * inode_ptr,
12395 +       struct file * file_ptr );
12396 +
12397 +int AAC_ChardevRelease(
12398 +       struct inode * inode_ptr,
12399 +       struct file * file_ptr );
12400 +
12401 +struct file_operations AAC_fops = {
12402 +       NULL,               // module name
12403 +       NULL,                           // lseek
12404 +       NULL,                           // read
12405 +       NULL,                           // write
12406 +       NULL,                           // readdir
12407 +       NULL,                           // poll
12408 +       AAC_ChardevIoctl,       // ioctl
12409 +       NULL,                           // mmap
12410 +       AAC_ChardevOpen,        // open
12411 +       NULL,                           // flush
12412 +       AAC_ChardevRelease,     // release
12413 +       NULL,                           // fsync
12414 +       NULL,                           // fasync
12415 +       NULL,                           // check media change
12416 +       NULL,                           // revalidate
12417 +       NULL                            // lock
12418 +};
12419 +
12420 +/*------------------------------------------------------------------------------
12421 + *              F U N C T I O N S
12422 + *----------------------------------------------------------------------------*/
12423 +/*------------------------------------------------------------------------------
12424 +       AAC_AnnounceDriver()
12425 +
12426 +               Announce the driver name, version and date.
12427 + *----------------------------------------------------------------------------*/
12428 +static void AAC_AnnounceDriver( void ){
12429 +  printk("<1>%s, %s\n", 
12430 +                "aacraid raid driver version", AAC_DRIVER_BUILD_DATE );   
12431 +  schedule();
12432 +}
12433 +
12434 +
12435 +/*------------------------------------------------------------------------------
12436 +       AAC_DetectHostAdapter()
12437 +
12438 +               Probe for AAC Host Adapters initialize, register, and report the 
12439 +               configuration of each AAC Host Adapter found.
12440 +
12441 +       Preconditions:
12442 +       Postconditions:
12443 +               - Returns the number of adapters successfully initialized and 
12444 +               registered.
12445 +               - Initialize all data necessary for this particular SCSI driver.
12446 +       Notes:
12447 +               The detect routine must not call any of the mid level functions 
12448 +               to queue commands because things are not guaranteed to be set 
12449 +               up yet. The detect routine can send commands to the host adapter 
12450 +               as long as the program control will not be passed to scsi.c in 
12451 +               the processing of the command. Note especially that 
12452 +               scsi_malloc/scsi_free must not be called.
12453 + *----------------------------------------------------------------------------*/
12454 +int AAC_DetectHostAdapter (Scsi_Host_Template *HostTemplate)
12455 +{
12456 +               int index;
12457 +               int ContainerId;
12458 +               uint16_t vendor_id, device_id, sub_vendor_id, sub_system_id;
12459 +               struct Scsi_Host *host_ptr;
12460 +               PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
12461 +               struct pci_dev *dev = NULL;
12462 +               extern int NumMiniPorts;
12463 +               fsadev_t *fsa_dev_ptr;
12464 +               char *DeviceName;
12465 +
12466 +               struct pci_dev *devp;
12467 +
12468 +               int     first_index, last_index, increment;
12469 +
12470 +               CommPrinting = TRUE;
12471 +
12472 +#ifdef MODULE
12473 +               EXPORT_NO_SYMBOLS;
12474 +#endif
12475 +
12476 +               AAC_AnnounceDriver();
12477 +
12478 +               /* setting up the proc directory structure */
12479 +               HostTemplate->proc_name = "aacraid";
12480 +
12481 +               if( module_options != NULL ) AAC_ParseDriverOptions( module_options );
12482 +
12483 +               // NumMiniPorts & MiniPorts[] defined in aacid.c
12484 +               if (g_options.reverse_scan == 0) {
12485 +                               first_index = 0;
12486 +                               last_index  = NumMiniPorts;
12487 +                               increment   = 1;
12488 +               } else {
12489 +                               first_index = NumMiniPorts -1;
12490 +                               last_index  = -1;
12491 +                               increment   = -1;
12492 +               }
12493 +
12494 +               for( index = first_index; index != last_index; index += increment )
12495 +               {
12496 +                               device_id = MiniPorts[index].DeviceId;
12497 +                               vendor_id = MiniPorts[index].VendorId;
12498 +                               DeviceName = MiniPorts[index].DeviceName;
12499 +                               cmn_err(CE_DEBUG, "Checking %s %x/%x/%x/%x", 
12500 +                                               DeviceName,     vendor_id, device_id,
12501 +                                               MiniPorts[index].SubVendorId,
12502 +                                               MiniPorts[index].SubSystemId);
12503 +
12504 +
12505 +                               // pci_find_device traverses the pci_devices linked list for devices
12506 +                               // with matching vendor and device ids.
12507 +
12508 +                               dev = NULL;     // start from beginning of list
12509 +                               while( ( dev = pci_find_device( vendor_id, device_id, dev ) ) )
12510 +                               {
12511 +                                               if (pci_enable_device(dev)) continue;
12512 +                 
12513 +                                               if( pci_read_config_word( dev, PCI_SUBSYSTEM_VENDOR_ID, &sub_vendor_id ) ){
12514 +                                                               cmn_err(CE_WARN, "pci_read_config_word SUBSYS_VENDOR_ID failed");
12515 +                                                               break;
12516 +                                               }
12517 +                                               if( pci_read_config_word( dev, PCI_SUBSYSTEM_ID, &sub_system_id ) ){
12518 +                                                               cmn_err(CE_WARN, "pci_read_config_work SUBSYSTEM_ID failed");
12519 +                                                               break;
12520 +                                               }
12521 +
12522 +                                               cmn_err(CE_DEBUG, "     found: %x/%x/%x/%x", vendor_id, device_id, sub_vendor_id, sub_system_id);
12523 +                                               if( ( sub_vendor_id != MiniPorts[index].SubVendorId ) || 
12524 +                                                       ( sub_system_id != MiniPorts[index].SubSystemId ) ){
12525 +                                                               continue;
12526 +                                               }
12527 +                       
12528 +
12529 +                                               printk("<1>%s device detected\n", DeviceName );
12530 +                                               cmn_err(CE_DEBUG, "%x/%x/%x/%x", vendor_id, device_id, sub_vendor_id, sub_system_id);
12531 +
12532 +                                               // Increment the host adapter count
12533 +                                               g_HostAdapterCount++;
12534 +
12535 +                                               // scsi_register() allocates memory for a Scsi_Hosts structure and
12536 +                                               // links it into the linked list of host adapters. This linked list
12537 +                                               // contains the data for all possible <supported> scsi hosts.
12538 +                                               // This is similar to the Scsi_Host_Template, except that we have
12539 +                                               // one entry for each actual physical host adapter on the system,
12540 +                                               // stored as a linked list. If there are two AAC boards, then we
12541 +                                               // will need to make two Scsi_Host entries, but there will be only
12542 +                                               // one Scsi_Host_Template entry. The second argument to scsi_register()
12543 +                                               // specifies the size of the extra memory we want to hold any device 
12544 +                                               // specific information.
12545 +                                               host_ptr = scsi_register( HostTemplate, sizeof( PCI_MINIPORT_COMMON_EXTENSION ) );
12546 +
12547 +                                               // These three parameters can be used to allow for wide SCSI 
12548 +                                               // and for host adapters that support multiple buses.
12549 +                                               host_ptr->max_id = 17;
12550 +                                               host_ptr->max_lun = 8;
12551 +                                               host_ptr->max_channel = 1;
12552 +
12553 +
12554 +                                               host_ptr->irq = dev->irq;               // Adapter IRQ number
12555 +                                               /* host_ptr->base = ( char * )(dev->resource[0].start & ~0xff); */
12556 +                                               host_ptr->base = ( char * )(dev->resource[0].start);
12557 +                                               scsi_set_pci_device(host_ptr, dev);
12558 +
12559 +                                               cmn_err( CE_DEBUG, "Device base address = 0x%lx [0x%lx]", host_ptr->base, dev->resource[0].start );
12560 +                                               cmn_err( CE_DEBUG, "Device irq = 0x%lx", dev->irq );
12561 +
12562 +                                               // The unique_id field is a unique identifier that must be assigned
12563 +                                               // so that we have some way of identifying each host adapter properly
12564 +                                               // and uniquely. For hosts that do not support more than one card in the
12565 +                                               // system, this does not need to be set. It is initialized to zero in
12566 +                                               // scsi_register(). This is the value returned from OsGetDeviceInstance().
12567 +
12568 +                                               host_ptr->unique_id = g_HostAdapterCount - 1;
12569 +                                               host_ptr->this_id = 16;                 // SCSI Id for the adapter itself
12570 +
12571 +                                               // Set the maximum number of simultaneous commands supported by the driver.
12572 +                                               host_ptr->can_queue = MAX_DRIVER_QUEUE_DEPTH;
12573 +
12574 +                                               // Define the maximum number of scatter/gather elements supported by 
12575 +                                               // the driver. 
12576 +
12577 +                                               host_ptr->sg_tablesize = 16;
12578 +                                               host_ptr->max_sectors = 128;
12579 +                                               host_ptr->cmd_per_lun = 1;              // untagged queue depth
12580 +
12581 +                                               // This function is called after the device list has been built to find
12582 +                                               // tagged queueing depth supported for each device.
12583 +
12584 +                                               host_ptr->select_queue_depths = AAC_SelectQueueDepths;
12585 +                                               CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )host_ptr->hostdata;
12586 +                       
12587 +                                               // attach a pointer back to Scsi_Host
12588 +                                               CommonExtensionPtr->OsDep.scsi_host_ptr = host_ptr;     
12589 +                                               CommonExtensionPtr->OsDep.MiniPortIndex =  index;
12590 +
12591 +                                               // Initialize the ordinal number of the device to -1
12592 +                                               fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
12593 +                                               for( ContainerId = 0; ContainerId < MAXIMUM_NUM_CONTAINERS; ContainerId++ )
12594 +                                                               fsa_dev_ptr->ContainerDevNo[ContainerId] = -1;
12595 +
12596 +                                               // Call initialization routine
12597 +                                               cmn_err (CE_DEBUG, "Initializing Hardware...\n");
12598 +                                               if( ( *MiniPorts[index].InitRoutine )
12599 +                                                       ( CommonExtensionPtr, host_ptr->unique_id, dev->bus->number, 0 ) != 0 )
12600 +                                               {
12601 +                                                               // device initialization failed
12602 +                                                               cmn_err( CE_WARN, "%s:%d device initialization failed", DeviceName, host_ptr->unique_id );
12603 +                                                               scsi_unregister( host_ptr );
12604 +                                                               g_HostAdapterCount--;
12605 +                                               } /* end if */
12606 +                                               else
12607 +                                               {
12608 +                                                       cmn_err( CE_NOTE, "%s:%d device initialization successful", DeviceName, host_ptr->unique_id  );
12609 +                                                       AacHba_ClassDriverInit( CommonExtensionPtr );
12610 +                                                       cmn_err(CE_NOTE, "%s:%d AacHba_ClassDriverInit complete", DeviceName, host_ptr->unique_id);
12611 +                                                       AacHba_ProbeContainers( CommonExtensionPtr );
12612 +                                                       g_CommonExtensionPtrArray[ g_HostAdapterCount - 1 ] = CommonExtensionPtr;
12613 +
12614 +                                               } /* end else */
12615 +
12616 +                               } /* end while */
12617 +
12618 +               } /* end for */
12619 +
12620 +               if( g_HostAdapterCount ){
12621 +                       if( !( g_chardev_major = register_chrdev( 0, devicestr, &AAC_fops ) ) )
12622 +                               cmn_err( CE_WARN, "%s: unable to register %s device", DeviceName, devicestr);
12623 +               }
12624 +
12625 +               HostTemplate->present = g_HostAdapterCount; // # of cards of this type found
12626 +
12627 +               return( g_HostAdapterCount ); 
12628 +}
12629 +
12630 +
12631 +/*------------------------------------------------------------------------------
12632 +       AAC_ReleaseHostAdapter()
12633 +
12634 +               Release all resources previously acquired to support a specific Host 
12635 +               Adapter and unregister the AAC Host Adapter.
12636 + *----------------------------------------------------------------------------*/
12637 +int AAC_ReleaseHostAdapter( 
12638 +       struct Scsi_Host *host_ptr )
12639 +/*----------------------------------------------------------------------------*/
12640 +{
12641 +       PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
12642 +
12643 +       cmn_err( CE_DEBUG, "AAC_ReleaseHostAdapter" );
12644 +
12645 +       CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )host_ptr->hostdata;
12646 +
12647 +       // kill any threads we started
12648 +       kill_proc( CommonExtensionPtr->OsDep.thread_pid, SIGKILL, 0 );
12649 +
12650 +       // Call the comm layer to detach from this adapter
12651 +       AacHba_DetachAdapter( CommonExtensionPtr->Adapter );
12652 +
12653 +       // remove interrupt binding
12654 +       OsDetachInterrupt( CommonExtensionPtr->MiniPort );
12655 +
12656 +       SaDetachDevice( CommonExtensionPtr );
12657 +
12658 +       // unregister adapter
12659 +       scsi_unregister( host_ptr );
12660 +
12661 +       if( g_chardev_major )
12662 +       {
12663 +               unregister_chrdev( g_chardev_major, devicestr );
12664 +               g_chardev_major = 0;
12665 +       }
12666 +
12667 +       return( 0 ); // #REVISIT# return code
12668 +}
12669 +
12670 +
12671 +/*------------------------------------------------------------------------------
12672 +       AAC_QueueCommand()
12673 +
12674 +               Queues a command for execution by the associated Host Adapter.
12675 + *----------------------------------------------------------------------------*/
12676 +int AAC_QueueCommand(
12677 +       Scsi_Cmnd *scsi_cmnd_ptr,
12678 +       void ( *CompletionRoutine )( Scsi_Cmnd * ) )
12679 +/*----------------------------------------------------------------------------*/
12680 +{
12681 +       scsi_cmnd_ptr->scsi_done = CompletionRoutine;
12682 +
12683 +       // AacHba_DoScsiCmd() handles command processing, setting the 
12684 +       // result code and calling completion routine. 
12685 +       #ifdef SYNC_FIB
12686 +       if( AacHba_DoScsiCmd( scsi_cmnd_ptr, 1 ) )      // called with wait = TRUE
12687 +       #else
12688 +       if( AacHba_DoScsiCmd( scsi_cmnd_ptr, 0 ) )      // called with wait = FALSE
12689 +       #endif
12690 +               cmn_err( CE_DEBUG, "AacHba_DoScsiCmd failed" );
12691 +       return 0;
12692 +} 
12693 +
12694 +
12695 +/*------------------------------------------------------------------------------
12696 +       AAC_Done()
12697 +
12698 +               Callback function for a non-queued command.
12699 +
12700 +       Postconditions
12701 +               Sets g_single_command done to TRUE
12702 + *----------------------------------------------------------------------------*/
12703 +void AAC_Done( 
12704 +       Scsi_Cmnd * scsi_cmnd_ptr ) 
12705 +/*----------------------------------------------------------------------------*/
12706 +{
12707 +       g_single_command_done = TRUE;
12708 +}
12709 +
12710 +
12711 +/*------------------------------------------------------------------------------
12712 +       AAC_Command()
12713 +       
12714 +               Accepts a single command for execution by the associated Host Adapter.
12715 +
12716 +       Postconditions
12717 +               Returns an int where:
12718 +               Byte 0 = SCSI status code
12719 +               Byte 1 = SCSI 1 byte message
12720 +               Byte 2 = host error return
12721 +               Byte 3 = mid level error return
12722 + *----------------------------------------------------------------------------*/
12723 +int AAC_Command(
12724 +       Scsi_Cmnd *scsi_cmnd_ptr )
12725 +/*----------------------------------------------------------------------------*/
12726 +{
12727 +       scsi_cmnd_ptr->scsi_done = AAC_Done;
12728 +
12729 +       cmn_err( CE_DEBUG, "AAC_Command" );
12730 +
12731 +       // AacHba_DoScsiCmd() handles command processing, setting the 
12732 +       // result code and calling completion routine.
12733 +       g_single_command_done = FALSE;
12734 +       
12735 +       AacHba_DoScsiCmd( scsi_cmnd_ptr, 0 );
12736 +       while( !g_single_command_done );
12737 +       return( scsi_cmnd_ptr->result );
12738 +} 
12739 +
12740 +
12741 +/*------------------------------------------------------------------------------
12742 +       AAC_AbortCommand()
12743 +
12744 +               Abort command if possible.
12745 + *----------------------------------------------------------------------------*/
12746 +int AAC_AbortCommand( 
12747 +       Scsi_Cmnd *scsi_cmnd_ptr )
12748 +/*----------------------------------------------------------------------------*/
12749 +{
12750 +       int target = scsi_cmnd_ptr->target;
12751 +       int hba = scsi_cmnd_ptr->host->unique_id;
12752 +       int result = 0;
12753 +       u_short interrupt_status;
12754 +       PCI_MINIPORT_COMMON_EXTENSION *cep;
12755 +       char   *DeviceName;
12756 +
12757 +       cmn_err( CE_WARN, "%s:%d ABORT", g_DriverName, hba, target );
12758 +       AacHba_AbortScsiCommand( scsi_cmnd_ptr );
12759 +
12760 +       cep = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
12761 +       DeviceName = MiniPorts[cep->OsDep.MiniPortIndex].DeviceName; 
12762 +
12763 +               /*
12764 +               cmn_err( CE_WARN, "%s:%d Unable to abort command to target %d - "
12765 +                 "command already completed", DeviceName, hba, target);
12766 +               result = SCSI_ABORT_NOT_RUNNING;
12767 +
12768 +               cmn_err(CE_WARN, "%s:%d Unable to abort command to target %d - "
12769 +                  "no command found\n", DeviceName, hba, target);
12770 +               result = SCSI_ABORT_NOT_RUNNING;
12771 +
12772 +               cmn_err(CE_WARN, "%s:%d Unable to abort command to target %d - "
12773 +                  "command reset\n", DeviceName, hba, target);
12774 +               result = SCSI_ABORT_PENDING;
12775 +
12776 +               cmn_err(CE_WARN, "%s:%d Unable to abort command to target %d - "
12777 +                  "abort tag not supported\n", DeviceName, hba, target);
12778 +               result = SCSI_ABORT_SNOOZE;
12779 +
12780 +               cmn_err(CE_WARN, "%s:%d Aborting command to target %d - pending",
12781 +                  DeviceName, hba, target);
12782 +               result = SCSI_ABORT_PENDING;
12783 +
12784 +               cmn_err(CE_WARN, "%s:%d Unable to abort command to target %d",
12785 +                  DeviceName, hba, target);
12786 +               result = SCSI_ABORT_BUSY;
12787 +
12788 +               cmn_err(CE_WARN, "%s:%d Aborted command to target %d\n",
12789 +                  DeviceName, hba, target);
12790 +               result = SCSI_ABORT_SUCCESS;
12791 +               */
12792 +
12793 +       // Abort not supported yet
12794 +       result = SCSI_ABORT_BUSY;
12795 +       return result;
12796 +}
12797 +
12798 +
12799 +/*------------------------------------------------------------------------------
12800 +       AAC_ResetCommand()
12801 +
12802 +               Reset command handling.
12803 + *----------------------------------------------------------------------------*/
12804 +int AAC_ResetCommand( 
12805 +       struct scsi_cmnd *scsi_cmnd_ptr, 
12806 +       unsigned int reset_flags )
12807 +/*----------------------------------------------------------------------------*/
12808 +{
12809 +       int target = scsi_cmnd_ptr->target;
12810 +       int hba = scsi_cmnd_ptr->host->unique_id;
12811 +       PCI_MINIPORT_COMMON_EXTENSION *cep;
12812 +       char    *DeviceName;
12813 +
12814 +       cep = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
12815 +       DeviceName = MiniPorts[cep->OsDep.MiniPortIndex].DeviceName;
12816 +
12817 +       cmn_err( CE_WARN, "%s:%d RESET", DeviceName, hba, target );
12818 +
12819 +       return SCSI_RESET_PUNT;
12820 +}
12821 +
12822 +
12823 +/*------------------------------------------------------------------------------
12824 +       AAC_DriverInfo()
12825 +
12826 +               Returns the host adapter name
12827 + *----------------------------------------------------------------------------*/
12828 +const char *AAC_DriverInfo( 
12829 +       struct Scsi_Host *host_ptr )
12830 +/*----------------------------------------------------------------------------*/
12831 +{
12832 +  PCI_MINIPORT_COMMON_EXTENSION *cep;
12833 +  char *DeviceName;
12834 +
12835 +  cep = ( PCI_MINIPORT_COMMON_EXTENSION * )( host_ptr->hostdata );
12836 +  DeviceName = MiniPorts[cep->OsDep.MiniPortIndex].DeviceName;
12837 +
12838 +  cmn_err( CE_DEBUG, "AAC_DriverInfo" );
12839 +  return (DeviceName);
12840 +}
12841 +
12842 +
12843 +/*------------------------------------------------------------------------------
12844 +       AAC_BIOSDiskParameters()
12845 +
12846 +               Return the Heads/Sectors/Cylinders BIOS Disk Parameters for Disk.  
12847 +               The default disk geometry is 64 heads, 32 sectors, and the appropriate 
12848 +               number of cylinders so as not to exceed drive capacity.  In order for 
12849 +               disks equal to or larger than 1 GB to be addressable by the BIOS
12850 +               without exceeding the BIOS limitation of 1024 cylinders, Extended 
12851 +               Translation should be enabled.   With Extended Translation enabled, 
12852 +               drives between 1 GB inclusive and 2 GB exclusive are given a disk 
12853 +               geometry of 128 heads and 32 sectors, and drives above 2 GB inclusive 
12854 +               are given a disk geometry of 255 heads and 63 sectors.  However, if 
12855 +               the BIOS detects that the Extended Translation setting does not match 
12856 +               the geometry in the partition table, then the translation inferred 
12857 +               from the partition table will be used by the BIOS, and a warning may 
12858 +               be displayed.
12859 + *----------------------------------------------------------------------------*/
12860 +int AAC_BIOSDiskParameters(
12861 +       Scsi_Disk *scsi_disk_ptr, 
12862 +       kdev_t device,
12863 +       int *parameter_ptr )
12864 +/*----------------------------------------------------------------------------*/
12865 +{
12866 +       AAC_BIOS_DiskParameters_T *disk_parameters = 
12867 +               ( AAC_BIOS_DiskParameters_T *)parameter_ptr;
12868 +       struct buffer_head * buffer_head_ptr;
12869 +
12870 +       cmn_err( CE_DEBUG, "AAC_BIOSDiskParameters" );
12871 +
12872 +       // Assuming extended translation is enabled - #REVISIT#
12873 +       if( scsi_disk_ptr->capacity >= 2 * 1024 * 1024 ) // 1 GB in 512 byte sectors
12874 +       {
12875 +               if( scsi_disk_ptr->capacity >= 4 * 1024 * 1024 ) // 2 GB in 512 byte sectors
12876 +               {
12877 +                       disk_parameters->heads = 255;
12878 +                       disk_parameters->sectors = 63;
12879 +               }
12880 +               else
12881 +               {
12882 +                       disk_parameters->heads = 128;
12883 +                       disk_parameters->sectors = 32;
12884 +               }
12885 +       }
12886 +       else
12887 +       {
12888 +               disk_parameters->heads = 64;
12889 +               disk_parameters->sectors = 32;
12890 +       }
12891 +
12892 +       disk_parameters->cylinders = scsi_disk_ptr->capacity
12893 +               /( disk_parameters->heads * disk_parameters->sectors );
12894 +
12895 +       // Read the first 1024 bytes from the disk device
12896 +       buffer_head_ptr = bread( 
12897 +                                               MKDEV( MAJOR( device ), 
12898 +                                               MINOR( device ) & ~0x0F ), 
12899 +                                               0, 1024 );
12900 +
12901 +       if( buffer_head_ptr == NULL )
12902 +               return( 0 );
12903 +       /* 
12904 +               If the boot sector partition table is valid, search for a partition 
12905 +               table entry whose end_head matches one of the standard geometry 
12906 +               translations ( 64/32, 128/32, 255/63 ).
12907 +       */
12908 +       if( *( unsigned short * )( buffer_head_ptr->b_data + 0x1fe ) == 0xaa55 )
12909 +       {
12910 +               struct partition *first_partition_entry =
12911 +                       ( struct partition * )( buffer_head_ptr->b_data + 0x1be );
12912 +               struct partition *partition_entry = first_partition_entry;
12913 +               int saved_cylinders = disk_parameters->cylinders;
12914 +               int partition_number;
12915 +               unsigned char partition_entry_end_head, partition_entry_end_sector;
12916 +
12917 +               for( partition_number = 0; partition_number < 4; partition_number++ )
12918 +               {
12919 +                       partition_entry_end_head   = partition_entry->end_head;
12920 +                       partition_entry_end_sector = partition_entry->end_sector & 0x3f;
12921 +
12922 +                       if( partition_entry_end_head == ( 64 - 1 ) )
12923 +                       {
12924 +                               disk_parameters->heads = 64;
12925 +                               disk_parameters->sectors = 32;
12926 +                               break;
12927 +                       }
12928 +                       else if( partition_entry_end_head == ( 128 - 1 ) )
12929 +                       {
12930 +                               disk_parameters->heads = 128;
12931 +                               disk_parameters->sectors = 32;
12932 +                               break;
12933 +                       }
12934 +                       else if( partition_entry_end_head == ( 255 - 1 ) ) 
12935 +                       {
12936 +                               disk_parameters->heads = 255;
12937 +                               disk_parameters->sectors = 63;
12938 +                               break;
12939 +                       }
12940 +                       partition_entry++;
12941 +               }
12942 +
12943 +               if( partition_number == 4 )
12944 +               {
12945 +                       partition_entry_end_head   = first_partition_entry->end_head;
12946 +                       partition_entry_end_sector = first_partition_entry->end_sector & 0x3f;
12947 +               }
12948 +
12949 +               disk_parameters->cylinders = scsi_disk_ptr->capacity
12950 +                       /( disk_parameters->heads * disk_parameters->sectors );
12951 +
12952 +               if( ( partition_number < 4 )  && ( partition_entry_end_sector == disk_parameters->sectors ) )
12953 +               {
12954 +                       if( disk_parameters->cylinders != saved_cylinders )
12955 +                               cmn_err( CE_DEBUG, "Adopting geometry: heads=%d, sectors=%d from partition table %d",
12956 +                                       disk_parameters->heads, disk_parameters->sectors, partition_number );
12957 +               }
12958 +               else if( ( partition_entry_end_head > 0 ) || ( partition_entry_end_sector > 0 ) )
12959 +               {
12960 +                       cmn_err( CE_DEBUG, "Strange geometry: heads=%d, sectors=%d in partition table %d",
12961 +                               partition_entry_end_head + 1, partition_entry_end_sector, partition_number );
12962 +                       cmn_err( CE_DEBUG, "Using geometry: heads=%d, sectors=%d",
12963 +                                       disk_parameters->heads, disk_parameters->sectors );
12964 +               }
12965 +       }
12966 +       
12967 +       brelse( buffer_head_ptr );
12968 +
12969 +       return( 0 );
12970 +}
12971 +
12972 +
12973 +/*------------------------------------------------------------------------------
12974 +       AAC_SelectQueueDepths()
12975 +
12976 +               Selects queue depths for each target device based on the host adapter's
12977 +               total capacity and the queue depth supported by the target device.
12978 +               A queue depth of one automatically disables tagged queueing.
12979 + *----------------------------------------------------------------------------*/
12980 +void AAC_SelectQueueDepths(
12981 +       struct Scsi_Host * host_ptr,
12982 +       Scsi_Device * scsi_device_ptr )
12983 +/*----------------------------------------------------------------------------*/
12984 +{
12985 +       Scsi_Device * device_ptr;
12986 +
12987 +       cmn_err( CE_DEBUG, "AAC_SelectQueueDepths" );
12988 +       cmn_err( CE_DEBUG, "Device #   Q Depth   Online" );
12989 +       cmn_err( CE_DEBUG, "---------------------------" );
12990 +       for( device_ptr = scsi_device_ptr; device_ptr != NULL; device_ptr = device_ptr->next )
12991 +               if( device_ptr->host == host_ptr )
12992 +               {
12993 +                       device_ptr->queue_depth = 10;           
12994 +                       cmn_err( CE_DEBUG, "  %2d         %d        %d", 
12995 +                               device_ptr->id, device_ptr->queue_depth, device_ptr->online );
12996 +               }
12997 +}
12998 +
12999 +
13000 +/*------------------------------------------------------------------------------
13001 +       AAC_SearchBiosSignature()
13002 +
13003 +               Locate adapter signature in BIOS
13004 + *----------------------------------------------------------------------------*/
13005 +int AAC_SearchBiosSignature( void )
13006 +/*----------------------------------------------------------------------------*/
13007 +{
13008 +       unsigned base;
13009 +       unsigned namep;
13010 +       int index;
13011 +       int val;
13012 +       char name_buf[32];
13013 +       int result = FALSE;
13014 +
13015 +       for( base = 0xc8000; base < 0xdffff; base += 0x4000 )
13016 +       {
13017 +               val = readb( base );
13018 +               if( val != 0x55 ) 
13019 +                       continue;
13020 +
13021 +               result = TRUE;
13022 +               namep = base + 0x1e;
13023 +               memcpy_fromio( name_buf, namep, 32 );
13024 +               name_buf[31] = '\0';
13025 +       }
13026 +       return( result );
13027 +}
13028 +
13029 +
13030 +/*------------------------------------------------------------------------------
13031 +       AAC_Ioctl()
13032 +
13033 +               Handle SCSI ioctls
13034 + *----------------------------------------------------------------------------*/
13035 +int AAC_Ioctl(
13036 +       Scsi_Device * scsi_dev_ptr,
13037 +       int cmd,
13038 +       void * arg )
13039 +/*----------------------------------------------------------------------------*/
13040 +{
13041 +       PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
13042 +
13043 +       cmn_err( CE_DEBUG, "AAC_Ioctl" );
13044 +       CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )scsi_dev_ptr->host->hostdata;
13045 +       return( AacHba_Ioctl( CommonExtensionPtr, cmd, arg ) );
13046 +}
13047 +
13048 +
13049 +
13050 +/*------------------------------------------------------------------------------
13051 +       AAC_ChardevOpen()
13052 +       
13053 +               Handle character device open
13054 +       
13055 +       Preconditions:
13056 +       Postconditions:
13057 +               Returns 0 if successful, -ENODEV or -EINVAL otherwise
13058 + *----------------------------------------------------------------------------*/
13059 +int AAC_ChardevOpen(
13060 +       struct inode * inode_ptr,
13061 +       struct file * file_ptr )
13062 +/*----------------------------------------------------------------------------*/
13063 +{
13064 +       unsigned minor_number;
13065 +
13066 +       cmn_err( CE_DEBUG, "AAC_ChardevOpen" );
13067 +
13068 +       // check device permissions in file_ptr->f_mode ??
13069 +
13070 +       // extract & check the minor number
13071 +       minor_number = MINOR( inode_ptr->i_rdev );
13072 +       if( minor_number > ( g_HostAdapterCount - 1 ) )
13073 +       {
13074 +               cmn_err( CE_WARN, "AAC_ChardevOpen: Minor number %d not supported", minor_number );
13075 +               return( -ENODEV );
13076 +       }
13077 +
13078 +#ifdef MODULE
13079 +       MOD_INC_USE_COUNT;
13080 +#endif
13081 +
13082 +       return( 0 );
13083 +}
13084 +
13085 +
13086 +/*------------------------------------------------------------------------------
13087 +       AAC_ChardevRelease()
13088 +       
13089 +               Handle character device release.
13090 +       
13091 +       Preconditions:
13092 +       Postconditions:
13093 +               Returns 0 if successful, -ENODEV or -EINVAL otherwise
13094 + *----------------------------------------------------------------------------*/
13095 +int AAC_ChardevRelease(
13096 +       struct inode * inode_ptr,
13097 +       struct file * file_ptr )
13098 +/*----------------------------------------------------------------------------*/
13099 +{
13100 +       cmn_err( CE_DEBUG, "AAC_ChardevRelease" );
13101 +
13102 +#ifdef MODULE
13103 +       MOD_DEC_USE_COUNT;
13104 +#endif
13105 +
13106 +       return( 0 );
13107 +}
13108 +
13109 +
13110 +/*------------------------------------------------------------------------------
13111 +       AAC_ChardevIoctl()
13112 +       
13113 +               Handle character device interface ioctls
13114 +       
13115 +       Preconditions:
13116 +       Postconditions:
13117 +               Returns 0 if successful, -ENODEV or -EINVAL otherwise
13118 + *----------------------------------------------------------------------------*/
13119 +int AAC_ChardevIoctl(
13120 +       struct inode * inode_ptr, 
13121 +       struct file * file_ptr,
13122 +       unsigned int cmd,
13123 +       unsigned long arg )
13124 +{
13125 +       unsigned minor_number;
13126 +       PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
13127 +
13128 +       cmn_err( CE_DEBUG, "AAC_ChardevIoctl" );
13129 +
13130 +       // check device permissions in file_ptr->f_mode ??
13131 +
13132 +       // extract & check the minor number
13133 +       minor_number = MINOR( inode_ptr->i_rdev );
13134 +       if( minor_number > ( g_HostAdapterCount - 1 ) )
13135 +       {
13136 +               cmn_err( CE_WARN, "AAC_ChardevIoctl: Minor number %d not supported", minor_number );
13137 +               return( -ENODEV );
13138 +       }
13139 +
13140 +       // get device pointer
13141 +       CommonExtensionPtr = g_CommonExtensionPtrArray[ minor_number ];
13142 +
13143 +       // dispatch ioctl - AacHba_Ioctl() returns zero on success
13144 +       if( AacHba_Ioctl( CommonExtensionPtr, cmd, ( void * )arg ) )
13145 +               return( -EINVAL );
13146 +
13147 +       return( 0 );
13148 +}
13149 +
13150 +
13151 +/*------------------------------------------------------------------------------
13152 +       parse_keyword()
13153 +
13154 +               Look for the keyword in str_ptr
13155 +
13156 +       Preconditions:
13157 +       Postconditions:
13158 +               If keyword found
13159 +                       - return true and update the pointer str_ptr.
13160 +               otherwise
13161 +                       - return false
13162 + *----------------------------------------------------------------------------*/
13163 +static int parse_keyword(
13164 +       char ** str_ptr, 
13165 +       char * keyword )
13166 +/*----------------------------------------------------------------------------*/
13167 +{
13168 +       char * ptr = *str_ptr;
13169 +       
13170 +       while( *keyword != '\0' )
13171 +       {
13172 +               char string_char = *ptr++;
13173 +               char keyword_char = *keyword++;
13174 +
13175 +               if ( ( string_char >= 'A' ) && ( string_char <= 'Z' ) )
13176 +                       string_char += 'a' - 'Z';
13177 +               if( ( keyword_char >= 'A' ) && ( keyword_char <= 'Z' ) ) 
13178 +                       keyword_char += 'a' - 'Z';
13179 +               if( string_char != keyword_char )
13180 +                       return FALSE;
13181 +       }
13182 +       *str_ptr = ptr;
13183 +       return TRUE;
13184 +}
13185 +
13186 +
13187 +/*------------------------------------------------------------------------------
13188 +       AAC_ParseDriverOptions()
13189 +
13190 +       For modules the usage is:
13191 +               insmod -f aacraid.o 'aacraid_options="<option_name:argument>"'
13192 + *----------------------------------------------------------------------------*/
13193 +static void AAC_ParseDriverOptions( 
13194 +       char * cmnd_line_options_str )
13195 +/*----------------------------------------------------------------------------*/
13196 +{
13197 +       int message_level;
13198 +       int reverse_scan;
13199 +       char *cp;
13200 +       char *endp;
13201 +
13202 +       cp = cmnd_line_options_str;
13203 +
13204 +       cmn_err(CE_DEBUG, "AAC_ParseDriverOptions: <%s>", cp);
13205 +
13206 +       while( *cp ) {
13207 +               if( parse_keyword( &cp, "message_level:" ) ) {
13208 +                       message_level = simple_strtoul( cp, 0, 0 );
13209 +                       if( ( message_level < CE_TAIL ) && ( message_level >= 0 ) ) {
13210 +                               g_options.message_level = message_level;
13211 +                               cmn_err( CE_WARN, "%s: new message level = %d", g_DriverName, g_options.message_level );
13212 +                       }
13213 +                       else {
13214 +                               cmn_err( CE_WARN, "%s: invalid message level = %d", g_DriverName, message_level );
13215 +                       }
13216 +               } else if (parse_keyword( &cp, "reverse_scan:" ) ) {
13217 +                       reverse_scan = simple_strtoul( cp, 0, 0 );
13218 +                       if (reverse_scan) {
13219 +                               g_options.reverse_scan = 1;
13220 +                               cmn_err( CE_WARN, "%s: reversing device discovery order", g_DriverName, g_options.message_level );
13221 +                       }
13222 +               }
13223 +               else {
13224 +                       cmn_err( CE_WARN, "%s: unknown command line option <%s>", g_DriverName, cp );
13225 +               }
13226 +
13227 +               /*
13228 +                * skip to next option,  accept " ", ";", and "," as delimiters
13229 +                */
13230 +               while ( *cp && (*cp != ' ')  && (*cp != ';')  && (*cp != ','))
13231 +                       cp++;
13232 +
13233 +               if (*cp)                                 /* skip over the delimiter */
13234 +                       cp++;
13235 +       }
13236 +
13237 +}
13238 +
13239 +
13240 +/*------------------------------------------------------------------------------
13241 +       Include Module support if requested.
13242 +
13243 +       To use the low level SCSI driver support using the linux kernel loadable 
13244 +       module interface we should initialize the global variable driver_interface  
13245 +       (datatype Scsi_Host_Template) and then include the file scsi_module.c.
13246 +       This should also be wrapped in a #ifdef MODULE/#endif
13247 + *----------------------------------------------------------------------------*/
13248 +#ifdef MODULE
13249 +
13250 +/*
13251 +       The Loadable Kernel Module Installation Facility may pass us
13252 +       a pointer to a driver specific options string to be parsed, 
13253 +       we assign this to options string. 
13254 +*/
13255 +MODULE_PARM( module_options, "s" );
13256 +
13257 +Scsi_Host_Template driver_template = AAC_HOST_TEMPLATE_ENTRY;
13258 +
13259 +#include "scsi_module.c"
13260 +
13261 +#else
13262 +Scsi_Host_Template driver_template = AAC_HOST_TEMPLATE_ENTRY;
13263 +
13264 +#include "scsi_module.c"
13265 +#endif
13266 +
13267 +/*********************************************************************
13268 +       AAC_ProcDirectoryInfo()
13269 +
13270 +               Implement /proc/scsi/<drivername>/<n>.
13271 +               Used to export driver statistics and other infos to the world outside 
13272 +               the kernel using the proc file system. Also provides an interface to
13273 +               feed the driver with information.
13274 +
13275 +       Postconditions
13276 +               For reads
13277 +                       - if offset > 0 return 0
13278 +                       - if offset == 0 write data to proc_buffer and set the start_ptr to
13279 +                       beginning of proc_buffer, return the number of characters written.
13280 +               For writes
13281 +                       - writes currently not supported, return 0
13282 +************************************************************/
13283 +int AAC_ProcDirectoryInfo(
13284 +       char *proc_buffer,              // read/write buffer
13285 +       char **start_ptr,               // start of valid data in the buffer
13286 +       off_t offset,                   // offset from the beginning of the imaginary file 
13287 +       int bytes_available,    // bytes available
13288 +       int host_no,                    // SCSI host number 
13289 +       int write )                             // direction of dataflow: TRUE for writes, FALSE for reads      
13290 +{
13291 +       int length = 0;
13292 +       cmn_err( CE_WARN, "AAC_ProcDirectoryInfo" );
13293 +
13294 +       if( ( write ) || ( offset > 0 ) )
13295 +               return( 0 );
13296 +
13297 +       *start_ptr = proc_buffer;
13298 +
13299 +       return( sprintf(&proc_buffer[length], "%s  %d\n", "Raid Controller, scsi hba number", host_no ) );
13300 +}
13301 +
13302 +void aac_allocate_SyncFibs (PCI_MINIPORT_COMMON_EXTENSION *CommonExtension)
13303 +{
13304 +  void         *BaseAddress;
13305 +  ULONG                PhysAddress;
13306 +  int          size;
13307 +  int          npages;
13308 +  int          i;
13309 +
13310 +  AFA_COMM_ADAPTER             *Adapter;
13311 +  Adapter = CommonExtension->Adapter;
13312 +
13313 +
13314 +  // Allocate 1 fib for synch fibs
13315 +  // Allocate 1 page.
13316 +  BaseAddress = OsAllocMemory ( PAGE_SIZE, OS_ALLOC_MEM_SLEEP);
13317 +  bzero(BaseAddress, PAGE_SIZE);
13318 +  PhysAddress = virt_to_phys (BaseAddress);
13319 +  Adapter->SyncFib = BaseAddress;
13320 +  Adapter->SyncFibPhysicalAddress = PhysAddress;
13321 +  cmn_err(CE_DEBUG,"aac_allocate_SyncFibs: syncFib: vaddr: 0x%x paddr: 0x%x ", BaseAddress, PhysAddress);
13322 +
13323 +}
13324 diff -burN linux-2.4.4/drivers/scsi/aacraid/osddi.c linux/drivers/scsi/aacraid/osddi.c
13325 --- linux-2.4.4/drivers/scsi/aacraid/osddi.c    Wed Dec 31 18:00:00 1969
13326 +++ linux/drivers/scsi/aacraid/osddi.c  Mon Apr 30 09:43:34 2001
13327 @@ -0,0 +1,512 @@
13328 +/*++
13329 + * Adaptec aacraid device driver for Linux.
13330 + *
13331 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
13332 + *
13333 + * This program is free software; you can redistribute it and/or modify
13334 + * it under the terms of the GNU General Public License as published by
13335 + * the Free Software Foundation; either version 2, or (at your option)
13336 + * any later version.
13337 + *
13338 + * This program is distributed in the hope that it will be useful,
13339 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
13340 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13341 + * GNU General Public License for more details.
13342 + *
13343 + * You should have received a copy of the GNU General Public License
13344 + * along with this program; see the file COPYING.  If not, write to
13345 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
13346 + *
13347 + * Module Name:
13348 + *   osddi.c
13349 + *
13350 + * Abstract: This file contains all the proceedures which use LINUX specific Device 
13351 + *             Driver Interfaces.
13352 + *     
13353 + --*/
13354 +
13355 +static char *ident_osddi = "aacraid_ident osddi.c 1.0.6 2000/10/09 Adaptec, Inc.";
13356 +
13357 +#include "osheaders.h"
13358 +
13359 +#include <linux/smp_lock.h>
13360 +
13361 +#ifdef fsid_t
13362 +#undef fsid_t
13363 +#endif
13364 +#include "AacGenericTypes.h"
13365 +#include "aac_unix_defs.h"
13366 +#include "comstruc.h"
13367 +#include "monkerapi.h"
13368 +#include "protocol.h"
13369 +#include "fsafs.h"
13370 +
13371 +#include "sap1common.h"
13372 +#include "fsaport.h"
13373 +#include "pcisup.h"
13374 +#include "sap1.h"
13375 +#include "nodetype.h"
13376 +#include "comsup.h"
13377 +#include "afacomm.h"
13378 +#include "adapter.h"
13379 +
13380 +
13381 +void AacSaPciIsr( 
13382 +       int irq,
13383 +       void * irq_data,
13384 +       struct pt_regs *regs);
13385 +
13386 +void AacRxPciIsr( 
13387 +       int irq,
13388 +       void * irq_data,
13389 +       struct pt_regs *regs);
13390 +
13391 +unsigned SaPciIsr (
13392 +    IN PSa_ADAPTER_EXTENSION AdapterExtension );
13393 +
13394 +unsigned RxPciIsr (
13395 +    IN PSa_ADAPTER_EXTENSION AdapterExtension );
13396 +
13397 +
13398 +/*----------------------------------------------------------------------------*/
13399 +VOID AfaCommInterruptHost(
13400 +       PVOID                   AdapterArg,
13401 +       ADAPTER_EVENT   AdapterEvent )
13402 +/*----------------------------------------------------------------------------*/
13403 +{
13404 +       PAFA_COMM_ADAPTER       Adapter = ( PAFA_COMM_ADAPTER ) AdapterArg;
13405 +       PCOMM_REGION CommRegion = Adapter->CommRegion;
13406 +
13407 +       switch (AdapterEvent) {
13408 +
13409 +         case HostNormRespQue:
13410 +               OsSoftInterruptTrigger( CommRegion->HostNormRespQue.ConsumerRoutine );
13411 +       
13412 +       // #REVIEW# - what do we do with this
13413 +       // if (FsaCommData.HardInterruptModeration)
13414 +       //                      DisableInterrupt( Adapter, HostNormRespQue, TRUE );
13415 +
13416 +                       break;
13417 +
13418 +      case AdapNormCmdNotFull:
13419 +               OsSoftInterruptTrigger( CommRegion->QueueNotFullDpc );
13420 +                       break;
13421 +
13422 +         case HostNormCmdQue:
13423 +               OsSoftInterruptTrigger( CommRegion->HostNormCmdQue.ConsumerRoutine );
13424 +                       break;
13425 +
13426 +      case AdapNormRespNotFull:
13427 +               OsSoftInterruptTrigger( CommRegion->QueueNotFullDpc );
13428 +                       break;
13429 +
13430 +       // #REVIEW# - what do we do with these
13431 +         case HostHighCmdQue:
13432 +         case HostHighRespQue:
13433 +         case AdapHighCmdNotFull:
13434 +         case AdapHighRespNotFull:
13435 +         case SynchCommandComplete:
13436 +         case AdapInternalError:
13437 +                 break;
13438 +       }
13439 +}
13440 +
13441 +
13442 +// get the device name associated with this instance of the device
13443 +/*----------------------------------------------------------------------------*/
13444 +char *OsGetDeviceName( 
13445 +       void *AdapterExtension )
13446 +/*----------------------------------------------------------------------------*/
13447 +{
13448 +       return( ( ( Sa_ADAPTER_EXTENSION * )AdapterExtension )->Common->
13449 +               OsDep.scsi_host_ptr->hostt->name );
13450 +}
13451 +
13452 +
13453 +/*----------------------------------------------------------------------------*/
13454 +int OsGetDeviceInstance( 
13455 +       void *AdapterExtension )
13456 +/*----------------------------------------------------------------------------*/
13457 +{
13458 +       return( ( int )( ( Sa_ADAPTER_EXTENSION * )AdapterExtension )->Common->
13459 +               OsDep.scsi_host_ptr->unique_id );
13460 +}
13461 +
13462 +
13463 +/*------------------------------------------------------------------------------
13464 +       OsMapDeviceRegisters()
13465 +
13466 +       Postconditions:
13467 +               Return zero on success non-zero otherwise.
13468 + *----------------------------------------------------------------------------*/
13469 +int OsMapDeviceRegisters( 
13470 +       Sa_ADAPTER_EXTENSION *AdapterExtension )
13471 +/*----------------------------------------------------------------------------*/
13472 +{
13473 +       PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
13474 +
13475 +       CommonExtension = AdapterExtension->Common;
13476 +
13477 +       if( AdapterExtension->Device = ( Sa_DEVICE_REGISTERS * )
13478 +                       ioremap( ( unsigned long )CommonExtension->OsDep.scsi_host_ptr->base, 8192 ) )
13479 +       {
13480 +               cmn_err( CE_WARN, "Device mapped to virtual address 0x%x", AdapterExtension->Device ); 
13481 +               return( 0 );
13482 +       }
13483 +       else
13484 +       {       
13485 +               cmn_err( CE_WARN, "OsMapDeviceRegisters: ioremap() failed" );
13486 +               return( 1 );
13487 +       }
13488 +}
13489 +
13490 +
13491 +/*------------------------------------------------------------------------------
13492 +       OsUnMapDeviceRegisters()
13493 +
13494 +       Postconditions:
13495 + *----------------------------------------------------------------------------*/
13496 +void OsUnMapDeviceRegisters( 
13497 +       Sa_ADAPTER_EXTENSION *AdapterExtension )
13498 +/*----------------------------------------------------------------------------*/
13499 +{
13500 +       iounmap( ( void * )AdapterExtension->Device );
13501 +}
13502 +
13503 +
13504 +/*----------------------------------------------------------------------------*/
13505 +int OsAttachInterrupt( 
13506 +       Sa_ADAPTER_EXTENSION *AdapterExtension ,
13507 +       int     WhichIsr )
13508 +/*----------------------------------------------------------------------------*/
13509 +{
13510 +       PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
13511 +       void *irq_data;
13512 +       void (*Isr)();
13513 +
13514 +       CommonExtension = AdapterExtension->Common;
13515 +       irq_data = ( void * )AdapterExtension;
13516 +
13517 +       switch (WhichIsr) {
13518 +               case SaISR:
13519 +                       Isr = AacSaPciIsr;
13520 +                       break;
13521 +               case RxISR:
13522 +                       Isr = AacRxPciIsr;
13523 +                       break;
13524 +               default:
13525 +                       cmn_err(CE_WARN, "OsAttachInterrupt: invalid ISR case: 0x%x", WhichIsr);
13526 +                       return( FAILURE );
13527 +                       break;
13528 +       }
13529 +
13530 +       
13531 +       if      ( OsRegisterInterrupt (
13532 +                               CommonExtension->OsDep.scsi_host_ptr->irq,      // interrupt number
13533 +                               Isr,                                                                            // handler function
13534 +                               irq_data )
13535 +               ) 
13536 +       {
13537 +               cmn_err( CE_WARN, "OsAttachInterrupt: Failed for IRQ: 0x%x", 
13538 +                       CommonExtension->OsDep.scsi_host_ptr->irq );
13539 +               return( FAILURE );
13540 +       }
13541 +
13542 +       return ( 0 );
13543 +}
13544 +
13545 +
13546 +/*----------------------------------------------------------------------------*/
13547 +void AacSaPciIsr( 
13548 +       int irq,
13549 +       void * irq_data,
13550 +       struct pt_regs *regs)
13551 +/*----------------------------------------------------------------------------*/
13552 +{
13553 +       // call the actual interrupt handler
13554 +       SaPciIsr( ( Sa_ADAPTER_EXTENSION * )irq_data );
13555 +}
13556 +
13557 +/*----------------------------------------------------------------------------*/
13558 +void AacRxPciIsr( 
13559 +       int irq,
13560 +       void * irq_data,
13561 +       struct pt_regs *regs)
13562 +/*----------------------------------------------------------------------------*/
13563 +{
13564 +       // call the actual interrupt handler
13565 +       RxPciIsr( ( Sa_ADAPTER_EXTENSION * )irq_data );
13566 +}
13567 +
13568 +
13569 +/*----------------------------------------------------------------------------*/
13570 +void OsDetachInterrupt( 
13571 +       Sa_ADAPTER_EXTENSION *AdapterExtension )
13572 +/*----------------------------------------------------------------------------*/
13573 +{
13574 +       PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
13575 +       void *irq_data;
13576 +
13577 +       CommonExtension = AdapterExtension->Common;
13578 +       irq_data = ( void * )AdapterExtension;
13579 +
13580 +       OsUnregisterInterrupt (
13581 +               CommonExtension->OsDep.scsi_host_ptr->irq,      // interrupt number
13582 +               irq_data );
13583 +}
13584 +
13585 +
13586 +/*----------------------------------------------------------------------------*/
13587 +int OsAttachDMA( 
13588 +       Sa_ADAPTER_EXTENSION *AdapterExtension )
13589 +/*----------------------------------------------------------------------------*/
13590 +{
13591 +       return( 0 );
13592 +}
13593 +
13594 +/*----------------------------------------------------------------------------*/
13595 +int OsAttachHBA( 
13596 +       Sa_ADAPTER_EXTENSION *AdapterExtension )
13597 +/*----------------------------------------------------------------------------*/
13598 +{
13599 +       return( 0 );
13600 +}
13601 +
13602 +/*----------------------------------------------------------------------------*/
13603 +void OsDetachDevice( 
13604 +       Sa_ADAPTER_EXTENSION *AdapterExtension )
13605 +/*----------------------------------------------------------------------------*/
13606 +{
13607 +       OsUnMapDeviceRegisters( AdapterExtension );
13608 +       return( 0 );
13609 +}
13610 +
13611 +/*----------------------------------------------------------------------------*/
13612 +ULONG *OsAllocCommPhysMem(
13613 +       Sa_ADAPTER_EXTENSION    *AdapterExtension, 
13614 +       ULONG                                   size,
13615 +       ULONG                                   **virt_addr_pptr,
13616 +       ULONG                                   *phys_addr_ptr )
13617 +/*----------------------------------------------------------------------------*/
13618 +{
13619 +       if( ( *virt_addr_pptr = ( ULONG * )OsAllocMemory( size, GFP_KERNEL ) ) )
13620 +       {
13621 +               *phys_addr_ptr = OsVirtToPhys( ( volatile void * )*virt_addr_pptr );
13622 +               if( !*phys_addr_ptr )
13623 +               {
13624 +                       cmn_err( CE_WARN, "OsAllocCommPhysMem: OsVirtToPhys failed" );
13625 +               }
13626 +                               
13627 +               return( *virt_addr_pptr );
13628 +       }
13629 +       else
13630 +               return( NULL );
13631 +}
13632 +
13633 +OsAifKernelThread(
13634 +       Sa_ADAPTER_EXTENSION    *AdapterExtension )
13635 +{
13636 +
13637 +       struct fs_struct *fs;
13638 +       int i;
13639 +       struct task_struct *tsk;
13640 +
13641 +       tsk = current;
13642 +
13643 +
13644 +       /*
13645 +        * set up the name that will appear in 'ps'
13646 +        * stored in  task_struct.comm[16].
13647 +        */
13648 +
13649 +       sprintf(tsk->comm, "AIFd");
13650 +
13651 +
13652 +       // use_init_fs_context();  only exists in 2.2.13 onward.
13653 +
13654 +#ifdef __SMP__
13655 +       lock_kernel();
13656 +#endif
13657 +
13658 +       /*
13659 +        * we were started as a result of loading the  module.
13660 +        * free all of user space pages
13661 +        */
13662 +
13663 +       exit_mm(tsk);
13664 +
13665 +       exit_files(tsk);
13666 +
13667 +       exit_fs(tsk);
13668 +
13669 +       fs = init_task.fs;
13670 +       tsk->fs = fs;
13671 +
13672 +       tsk->session = 1;
13673 +       tsk->pgrp = 1;
13674 +
13675 +       if (fs)
13676 +               atomic_inc(&fs->count);
13677 +
13678 +#ifdef __SMP__
13679 +       unlock_kernel();
13680 +#endif
13681 +
13682 +
13683 +
13684 +
13685 +       NormCommandThread(AdapterExtension);
13686 +       /* NOT REACHED */
13687 +}
13688 +
13689 +/*----------------------------------------------------------------------------*/
13690 +void OsStartKernelThreads(
13691 +       Sa_ADAPTER_EXTENSION    *AdapterExtension )
13692 +/*----------------------------------------------------------------------------*/
13693 +{
13694 +       PCI_MINIPORT_COMMON_EXTENSION   *CommonExtension;
13695 +       AFA_COMM_ADAPTER                                *Adapter;
13696 +       extern void                                     NormCommandThread(void *Adapter);
13697 +
13698 +       CommonExtension = AdapterExtension->Common;
13699 +       Adapter = (AFA_COMM_ADAPTER *)CommonExtension->Adapter;
13700 +
13701 +       // 
13702 +       // Start thread which will handle interrupts for this adapter
13703 +       //
13704 +       //kthread_spawn(FsaCommIntrHandler, AdapterExtension, "fsaintr",0);
13705 +
13706 +       //
13707 +       // Start thread which will handle AdapterInititatedFibs from this adapter
13708 +       //
13709 +       CommonExtension->OsDep.thread_pid = 
13710 +               kernel_thread( ( int ( * )( void * ) )OsAifKernelThread, Adapter, 0 );
13711 +//             kernel_thread( ( int ( * )( void * ) )NormCommandThread, Adapter, 0 );
13712 +}
13713 +
13714 +/*----------------------------------------------------------------------------*/
13715 +BOOLEAN AfaPortAllocateAndMapFibSpace(
13716 +       PVOID Arg1,
13717 +    IN PMAPFIB_CONTEXT MapFibContext )
13718 +/*----------------------------------------------------------------------------*/
13719 +{
13720 +       PVOID           BaseAddress;
13721 +       ULONG           PhysAddress;
13722 +
13723 +       if( !( BaseAddress = (ULONG *)OsAllocMemory( MapFibContext->Size, GFP_KERNEL ) ) )
13724 +       {
13725 +               cmn_err( CE_WARN, "AfaPortAllocateAndMapFibSpace: OsAllocMemory failed" );
13726 +               return( FALSE );
13727 +       }
13728 +
13729 +       PhysAddress = OsVirtToPhys( BaseAddress );
13730 +       
13731 +       MapFibContext->FibVirtualAddress = BaseAddress;
13732 +       MapFibContext->FibPhysicalAddress = (PVOID) PhysAddress;
13733 +
13734 +       return (TRUE);
13735 +}
13736 +
13737 +/*----------------------------------------------------------------------------*/
13738 +BOOLEAN AfaPortUnmapAndFreeFibSpace(
13739 +       PVOID Arg1,
13740 +    IN PMAPFIB_CONTEXT MapFibContext )
13741 +/*----------------------------------------------------------------------------*/
13742 +{
13743 +       PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
13744 +
13745 +       OsFreeMemory( MapFibContext->FibVirtualAddress, 0 );
13746 +
13747 +       return (TRUE);
13748 +}
13749 +
13750 +/*----------------------------------------------------------------------------*/
13751 +BOOLEAN AfaPortFreeAdapterCommArea(
13752 +       IN PVOID Arg1 )
13753 +/*----------------------------------------------------------------------------*/
13754 +{
13755 +       PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
13756 +
13757 +       OsFreeMemory( CommonExtension->CommAddress, 0 );
13758 +
13759 +       return (TRUE);
13760 +}
13761 +
13762 +
13763 +/* ================================================================================ */
13764 +/*
13765 + * Not sure if the functions below here ever get called in the current code
13766 + * These probably should be a different file.
13767 + */
13768 +/*
13769 +ddi_dma_attr_t AfaPortDmaAttributes = {
13770 +       //rpbfix : we may want something different for I/O
13771 +       DMA_ATTR_V0,
13772 +       0,
13773 +       0xffffffff,
13774 +       0x0000ffff,
13775 +       1,
13776 +       1,
13777 +       1,
13778 +       0x0000ffff,
13779 +       0x0000ffff,
13780 +       17,
13781 +       512,
13782 +       0
13783 +};
13784 +*/
13785 +
13786 +AAC_STATUS
13787 +AfaPortBuildSgMap(
13788 +       PVOID Arg1,
13789 +       IN PSGMAP_CONTEXT SgMapContext
13790 +       )
13791 +
13792 +/*++
13793 +
13794 +Routine Description:
13795 +
13796 +       This routine build a scatter gather map using the information
13797 +       in the SgMapContext.
13798 +
13799 +Arguments:
13800 +
13801 +       AdapterExtension - Pointer to adapter extension structure.
13802 +    SgMapContext - Pointer to the SgMapContext for the request.
13803 +
13804 +
13805 +Return Value:
13806 +
13807 +       AAC_STATUS      
13808 +--*/
13809 +{
13810 +       printk( "<1>AfaPortBuildSgMap: unimplemented function called" );
13811 +       return (STATUS_UNSUCCESSFUL);
13812 +}
13813 +
13814 +VOID
13815 +AfaPortFreeDmaResources(
13816 +       PVOID Arg1,
13817 +    IN PSGMAP_CONTEXT SgMapContext
13818 +    )
13819 +
13820 +/*++
13821 +
13822 +Routine Description:
13823 +
13824 +    Given a pointer to the IRP context will free all reserved DMA resources allocated for
13825 +    the completed IO operation.
13826 +
13827 +Arguments:
13828 +
13829 +    Fib - Pointer to the Fib the caller wishes to have transfered over to the adapter.
13830 +    Context - Pointer to the Irp Context we use to store the dma mapping information
13831 +        we need to do and complete the IO.
13832 +
13833 +Return Value:
13834 +
13835 +    Nothing
13836 +
13837 +--*/
13838 +{
13839 +}
13840 diff -burN linux-2.4.4/drivers/scsi/aacraid/osfuncs.c linux/drivers/scsi/aacraid/osfuncs.c
13841 --- linux-2.4.4/drivers/scsi/aacraid/osfuncs.c  Wed Dec 31 18:00:00 1969
13842 +++ linux/drivers/scsi/aacraid/osfuncs.c        Mon Apr 30 09:43:34 2001
13843 @@ -0,0 +1,596 @@
13844 +/*++
13845 + * Adaptec aacraid device driver for Linux.
13846 + *
13847 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
13848 + *
13849 + * This program is free software; you can redistribute it and/or modify
13850 + * it under the terms of the GNU General Public License as published by
13851 + * the Free Software Foundation; either version 2, or (at your option)
13852 + * any later version.
13853 + *
13854 + * This program is distributed in the hope that it will be useful,
13855 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
13856 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13857 + * GNU General Public License for more details.
13858 + *
13859 + * You should have received a copy of the GNU General Public License
13860 + * along with this program; see the file COPYING.  If not, write to
13861 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
13862 + *
13863 + * Module Name:
13864 + *  osfuncs.c
13865 + *
13866 + * Abstract: Holds all of the O/S specific interface functions.
13867 + *     
13868 + --*/
13869 +
13870 +static char *ident_osfuncs = "aacraid_ident osfuncs.c 1.0.6 2000/10/09 Adaptec, Inc.";
13871 +
13872 +#include "osheaders.h"
13873 +
13874 +//static LKINFO_DECL(fsa_locks, "fsa_locks",0);
13875 +
13876 +extern aac_options_t g_options;
13877 +
13878 +OS_SOFTINTR g_idle_task = { 0, 0, 0, 0 };
13879 +wait_queue_t * g_wait_queue_ptr = NULL;
13880 +wait_queue_t g_wait;
13881 +
13882 +void OsTimeoutHandler( 
13883 +       struct semaphore * sem );
13884 +
13885 +int * OsIdleTask( void * data );
13886 +
13887 +//-----------------------------------------------------------------------------
13888 +// Memory Allocation functions
13889 +
13890 +/*----------------------------------------------------------------------------*/
13891 +void * OsAllocMemory(
13892 +       OS_SIZE_T Size,
13893 +       unsigned int Flags )
13894 +/*----------------------------------------------------------------------------*/
13895 +{
13896 +       void *mem_ptr;
13897 +
13898 +       if( !( mem_ptr = kmalloc( Size, GFP_KERNEL ) ) )
13899 +               cmn_err( CE_WARN, "OsAllocMemory: FAILED\n" );
13900 +       return( mem_ptr );
13901 +}
13902 +
13903 +
13904 +/*----------------------------------------------------------------------------*/
13905 +void OsFreeMemory(
13906 +       void * Buffer,
13907 +       OS_SIZE_T Size )
13908 +/*----------------------------------------------------------------------------*/
13909 +{
13910 +       kfree( Buffer );
13911 +}
13912 +
13913 +
13914 +/*----------------------------------------------------------------------------*/
13915 +int OsRegisterInterrupt(
13916 +       unsigned int irq,               // interrupt number
13917 +       void ( *handler )( int, void*, struct pt_regs * ),      // handler function
13918 +       void *irq_data )                // argument to handler function
13919 +/*----------------------------------------------------------------------------*/
13920 +{
13921 +  return( request_irq (irq, handler, SA_INTERRUPT | SA_SHIRQ,  "aacraid", irq_data ) );
13922 +}
13923 +
13924 +
13925 +/*----------------------------------------------------------------------------*/
13926 +void OsUnregisterInterrupt(
13927 +       unsigned int irq,               // interrupt number
13928 +       void *irq_data)
13929 +/*----------------------------------------------------------------------------*/
13930 +{
13931 +       free_irq (
13932 +               irq,                                                                            // interrupt number
13933 +               irq_data );
13934 +}
13935 +
13936 +
13937 +/*----------------------------------------------------------------------------*/
13938 +unsigned long OsVirtToPhys( 
13939 +       void * virtual_address )
13940 +/*----------------------------------------------------------------------------*/
13941 +{
13942 +       return( virt_to_phys( virtual_address ) );
13943 +}
13944 +
13945 +
13946 +//-----------------------------------------------------------------------------
13947 +// MUTEX functions
13948 +
13949 +/*----------------------------------------------------------------------------*/
13950 +OS_STATUS OsMutexInit( 
13951 +       OS_MUTEX *Mutex,
13952 +       OS_SPINLOCK_COOKIE Cookie )
13953 +/*----------------------------------------------------------------------------*/
13954 +{
13955 +       Mutex->lock_var = 0;
13956 +       //      bzero (&Mutex->wq, sizeof (Mutex->wq));
13957 +       init_waitqueue_head (&Mutex->wq);
13958 +       return ( 0 );
13959 +}
13960 +
13961 +
13962 +/*----------------------------------------------------------------------------*/
13963 +void OsMutexDestroy( 
13964 +       OS_MUTEX *Mutex )
13965 +/*----------------------------------------------------------------------------*/
13966 +{
13967 +}
13968 +
13969 +
13970 +/*----------------------------------------------------------------------------*/
13971 +void OsMutexAcquire( 
13972 +       OS_MUTEX *Mutex )
13973 +/*----------------------------------------------------------------------------*/
13974 +{
13975 +  //   wait_queue_t wait = { current, NULL };
13976 +       unsigned long time_stamp;
13977 +
13978 +       DECLARE_WAITQUEUE (wait, current);
13979 +
13980 +       time_stamp = jiffies;
13981 +
13982 +       if( test_and_set_bit( 0, &( Mutex->lock_var ) ) != 0 )
13983 +       {
13984 +               if( in_interrupt() )
13985 +                       panic( "OsMutexAcquire going to sleep at interrupt time\n" );
13986 +               current->state = TASK_INTERRUPTIBLE;
13987 +               add_wait_queue( &( Mutex->wq ), &wait );
13988 +               while( test_and_set_bit( 0, &( Mutex->lock_var ) ) != 0 )
13989 +                       schedule();
13990 +               remove_wait_queue( &( Mutex->wq ), &wait );
13991 +       }
13992 +
13993 +       if( ( jiffies - 1 ) > time_stamp )
13994 +               cmn_err( CE_WARN, "Mutex %ld locked out for %ld ticks", 
13995 +                       Mutex, jiffies - time_stamp );
13996 +}
13997 +
13998 +
13999 +/*----------------------------------------------------------------------------*/
14000 +void OsMutexRelease( 
14001 +       OS_MUTEX *Mutex )
14002 +/*----------------------------------------------------------------------------*/
14003 +{
14004 +       if( test_and_clear_bit( 0, &( Mutex->lock_var ) ) == 0 )
14005 +               cmn_err( CE_WARN, "OsMutexRelease: mutex not locked" );
14006 +       wake_up_interruptible( &( Mutex->wq ) );
14007 +}
14008 +
14009 +// see man hierarchy(D5)
14010 +#define FSA_LOCK 1
14011 +
14012 +//-----------------------------------------------------------------------------
14013 +// Spinlock functions
14014 +
14015 +/*----------------------------------------------------------------------------*/
14016 +OS_SPINLOCK * OsSpinLockAlloc( void ) 
14017 +/*----------------------------------------------------------------------------*/
14018 +{
14019 +       OS_SPINLOCK *SpinLock;
14020 +       int i;
14021 +
14022 +
14023 +       SpinLock = ( OS_SPINLOCK * )kmalloc( sizeof( OS_SPINLOCK ), GFP_KERNEL );
14024 +
14025 +       if (SpinLock == NULL)
14026 +               cmn_err (CE_WARN, "WARNING: OsSpinLockAlloc Failed!!!");
14027 +       
14028 +       SpinLock->spin_lock = SPIN_LOCK_UNLOCKED;
14029 +       for( i = 0; i < NR_CPUS; i++ )
14030 +               SpinLock->cpu_lock_count[ i ] = 0;
14031 +       return( SpinLock );
14032 +}
14033 +
14034 +
14035 +/*----------------------------------------------------------------------------*/
14036 +OS_STATUS OsSpinLockInit( 
14037 +       OS_SPINLOCK *SpinLock,
14038 +       OS_SPINLOCK_COOKIE Cookie )
14039 +/*----------------------------------------------------------------------------*/
14040 +{
14041 +       return( 0 );
14042 +}
14043 +
14044 +
14045 +/*----------------------------------------------------------------------------*/
14046 +void OsSpinLockDestroy( 
14047 +       OS_SPINLOCK *SpinLock )
14048 +/*----------------------------------------------------------------------------*/
14049 +{
14050 +       kfree( SpinLock );
14051 +       SpinLock = NULL;
14052 +}
14053 +
14054 +
14055 +/*----------------------------------------------------------------------------*/
14056 +void OsSpinLockAcquire( 
14057 +       OS_SPINLOCK *SpinLock )
14058 +/*----------------------------------------------------------------------------*/
14059 +{
14060 +       unsigned cpu_id, i;
14061 +
14062 +
14063 +       if( SpinLock )
14064 +       {
14065 +               cpu_id = smp_processor_id();
14066 +               if( SpinLock->cpu_lock_count[ cpu_id ] ){
14067 +                       cmn_err (CE_PANIC, "CPU %d trying to acquire lock again: lock count = %d\n",
14068 +                                cpu_id, SpinLock->cpu_lock_count[ cpu_id ]);
14069 +               }                 
14070 +               
14071 +               spin_lock_irqsave( &( SpinLock->spin_lock ), SpinLock->cpu_flag );
14072 +               SpinLock->cpu_lock_count[ cpu_id ]++;
14073 +          
14074 +       } else {
14075 +               cmn_err( CE_WARN, "OsSpinLockAcquire: lock does not exist" );
14076 +       }
14077 +}
14078 +
14079 +
14080 +/*----------------------------------------------------------------------------*/
14081 +void OsSpinLockRelease( 
14082 +       OS_SPINLOCK *SpinLock )
14083 +/*----------------------------------------------------------------------------*/
14084 +{
14085 +       if( SpinLock )
14086 +       {
14087 +               SpinLock->cpu_lock_count[ smp_processor_id() ]--;
14088 +               spin_unlock_irqrestore( &( SpinLock->spin_lock ), SpinLock->cpu_flag );
14089 +       }
14090 +       else
14091 +               cmn_err( CE_WARN, "OsSpinLockRelease: lock does not exist" );
14092 +}
14093 +
14094 +
14095 +/*----------------------------------------------------------------------------*/
14096 +int OsSpinLockOwned(
14097 +       OS_SPINLOCK *SpinLock )
14098 +/*----------------------------------------------------------------------------*/
14099 +{
14100 +#ifdef __SMP__
14101 +       if( SpinLock->spin_lock.lock != 0 )
14102 +               return( 1 );
14103 +       else
14104 +#endif
14105 +               return( 0 );
14106 +}
14107 +
14108 +
14109 +//-----------------------------------------------------------------------------
14110 +// CvLock functions
14111 +
14112 +/*----------------------------------------------------------------------------*/
14113 +OS_CVLOCK *OsCvLockAlloc( void ) 
14114 +{
14115 +       OS_CVLOCK *cv_lock;
14116 +
14117 +
14118 +#ifdef CVLOCK_USE_SPINLOCK
14119 +       cv_lock = OsSpinLockAlloc(); 
14120 +#else
14121 +       cv_lock = ( OS_CVLOCK * )kmalloc( sizeof( OS_CVLOCK ), GFP_KERNEL );
14122 +       cv_lock->wq = NULL;
14123 +       cv_lock->lock_var = 0;
14124 +#endif
14125 +
14126 +       return( cv_lock );
14127 +}
14128 +
14129 +
14130 +/*----------------------------------------------------------------------------*/
14131 +OS_STATUS OsCvLockInit( 
14132 +       OS_CVLOCK *cv_lock,
14133 +       OS_SPINLOCK_COOKIE Cookie )
14134 +/*----------------------------------------------------------------------------*/
14135 +{
14136 +       return ( 0 );
14137 +}
14138 +
14139 +
14140 +/*----------------------------------------------------------------------------*/
14141 +void OsCvLockDestroy( 
14142 +       OS_CVLOCK *cv_lock )
14143 +/*----------------------------------------------------------------------------*/
14144 +{
14145 +       if( cv_lock )
14146 +               kfree( cv_lock );
14147 +       cv_lock = NULL;
14148 +}
14149 +
14150 +
14151 +/*----------------------------------------------------------------------------*/
14152 +void OsCvLockAcquire (OS_CVLOCK *cv_lock)
14153 +{
14154 +#ifdef CVLOCK_USE_SPINLOCK
14155 +               OsSpinLockAcquire( cv_lock );
14156 +#else
14157 +               OsMutexAcquire( cv_lock );
14158 +#endif
14159 +}
14160 +
14161 +
14162 +/*----------------------------------------------------------------------------*/
14163 +void OsCvLockRelease( 
14164 +       OS_CVLOCK *cv_lock )
14165 +/*----------------------------------------------------------------------------*/
14166 +{
14167 +#ifdef CVLOCK_USE_SPINLOCK
14168 +               OsSpinLockRelease( cv_lock );
14169 +#else
14170 +               OsMutexRelease( cv_lock );
14171 +#endif
14172 +}
14173 +
14174 +
14175 +/*----------------------------------------------------------------------------*/
14176 +int OsCvLockOwned(
14177 +       OS_CVLOCK *cv_lock )
14178 +/*----------------------------------------------------------------------------*/
14179 +{
14180 +       return( 1 );
14181 +}
14182 +
14183 +
14184 +//-----------------------------------------------------------------------------
14185 +// Conditional variable functions
14186 +
14187 +/*----------------------------------------------------------------------------*/
14188 +void OsCv_init ( 
14189 +       OS_CV_T *cv_ptr )
14190 +/*----------------------------------------------------------------------------*/
14191 +{
14192 +       cv_ptr->lock_var = 1;
14193 +       init_waitqueue_head (&cv_ptr->wq);
14194 +}
14195 +
14196 +
14197 +/*----------------------------------------------------------------------------*/
14198 +void OsCv_destroy( 
14199 +       OS_CV_T  *cv_ptr )
14200 +/*----------------------------------------------------------------------------*/
14201 +{
14202 +}
14203 +
14204 +
14205 +/*______________________________________________________________________________
14206 + -
14207 + -
14208 + -----------------------------------------------------------------------------*/
14209 +OsCv_wait (OS_CV_T *cv_ptr, OS_CVLOCK *cv_lock_ptr)
14210 +{
14211 +       unsigned long flags;
14212 +
14213 +       DECLARE_WAITQUEUE (wait, current);
14214 +       
14215 +       if( in_interrupt() )
14216 +               panic( "OsCv_wait going to sleep at interrupt time\n" );
14217 +
14218 +       cv_ptr->type = TASK_UNINTERRUPTIBLE;
14219 +       current->state = TASK_UNINTERRUPTIBLE;
14220 +
14221 +       add_wait_queue( &cv_ptr->wq, &wait );
14222 +
14223 +       OsCvLockRelease( cv_lock_ptr );
14224 +       schedule();
14225 +
14226 +       while( test_and_set_bit( 0, &( cv_ptr->lock_var ) ) != 0 )
14227 +       {
14228 +               if( in_interrupt() )
14229 +                       panic( "OsCv_wait going to sleep at interrupt time\n" );
14230 +               schedule();
14231 +       }
14232 +
14233 +       remove_wait_queue( &( cv_ptr->wq ), &wait );
14234 +
14235 +       OsCvLockAcquire( cv_lock_ptr );
14236 +}
14237 +
14238 +
14239 +/*----------------------------------------------------------------------------*/
14240 +int OsCv_wait_sig( 
14241 +       OS_CV_T *cv_ptr,
14242 +       OS_CVLOCK *cv_lock_ptr ) 
14243 +/*----------------------------------------------------------------------------*/
14244 +{
14245 +       unsigned long flags;
14246 +       int signal_state = 1;
14247 +
14248 +       DECLARE_WAITQUEUE (wait, current);
14249 +       
14250 +       if( in_interrupt() )
14251 +               panic( "OsCv_wait_sig going to sleep at interrupt time\n" );
14252 +
14253 +       cv_ptr->type = TASK_INTERRUPTIBLE;
14254 +       current->state = TASK_INTERRUPTIBLE;
14255 +
14256 +       add_wait_queue( &( cv_ptr->wq ), &wait );
14257 +
14258 +       OsCvLockRelease( cv_lock_ptr );
14259 +       schedule();
14260 +
14261 +       while( ( test_and_set_bit( 0, &( cv_ptr->lock_var ) ) != 0 ) && 
14262 +                       ( !signal_pending( current ) ) )
14263 +       {
14264 +               if( in_interrupt() )
14265 +                       panic( "OsCv_wait_sig going to sleep at interrupt time\n" );
14266 +               schedule();
14267 +       }
14268 +
14269 +       if( signal_pending( current ) )
14270 +               signal_state = 0;
14271 +       
14272 +       remove_wait_queue( &( cv_ptr->wq ), &wait );
14273 +       
14274 +       OsCvLockAcquire( cv_lock_ptr );
14275 +       return( signal_state );
14276 +}
14277 +
14278 +
14279 +/*----------------------------------------------------------------------------*/
14280 +void OsCv_signal( 
14281 +       OS_CV_T *cv_ptr )
14282 +/*----------------------------------------------------------------------------*/
14283 +{
14284 +
14285 +       clear_bit( 0, &( cv_ptr->lock_var ) );
14286 +       if( cv_ptr->type == TASK_INTERRUPTIBLE )
14287 +                       wake_up_interruptible( &( cv_ptr->wq ) );
14288 +       else{
14289 +                       wake_up( &( cv_ptr->wq ) );
14290 +       }
14291 +}
14292 +
14293 +
14294 +// return time in seconds
14295 +/*----------------------------------------------------------------------------*/
14296 +unsigned long OsGetSeconds( void )
14297 +/*----------------------------------------------------------------------------*/
14298 +{
14299 +       return( jiffies/HZ );
14300 +}
14301 +
14302 +
14303 +//-----------------------------------------------------------------------------
14304 +// Deferred procedure call functions
14305 +
14306 +// create a soft interrupt object
14307 +/*----------------------------------------------------------------------------*/
14308 +int OsSoftInterruptAdd( 
14309 +       OS_SOFTINTR **ptr,
14310 +       void * handler,
14311 +       void * data )
14312 +/*----------------------------------------------------------------------------*/
14313 +{
14314 +       OS_SOFTINTR *tmp_ptr;
14315 +
14316 +       if( !( tmp_ptr = ( OS_SOFTINTR * )kmalloc( sizeof( OS_SOFTINTR ), GFP_KERNEL ) ) )
14317 +               return( -1 );
14318 +       tmp_ptr->routine = handler;
14319 +       tmp_ptr->data = data;
14320 +       tmp_ptr->sync = 0;
14321 +
14322 +       *ptr = tmp_ptr; 
14323 +
14324 +       return( 0 );
14325 +}
14326 +
14327 +/*
14328 +       Use kernel_thread( ( int ( * )( void * ) )OsIdleTask, NULL, 0 ); to start
14329 +*/
14330 +/*----------------------------------------------------------------------------*/
14331 +int * OsIdleTask( void * data )
14332 +/*----------------------------------------------------------------------------*/
14333 +{
14334 +       DECLARE_WAITQUEUE (wait, current);
14335 +
14336 +       while( 1 )
14337 +       {
14338 +               current->state = TASK_INTERRUPTIBLE;
14339 +               add_wait_queue( &g_wait_queue_ptr, &wait );
14340 +               schedule();
14341 +               remove_wait_queue( &g_wait_queue_ptr, &wait );
14342 +               wait.task =  current;
14343 +               wait.task_list.next = NULL;
14344 +       }
14345 +       return( NULL );
14346 +}
14347 +
14348 +
14349 +// dispatch a soft interrupt 
14350 +/*----------------------------------------------------------------------------*/
14351 +void OsSoftInterruptTrigger( 
14352 +       OS_SOFTINTR *soft_intr_ptr )
14353 +/*----------------------------------------------------------------------------*/
14354 +{
14355 +       // call the completion routine directly
14356 +       soft_intr_ptr->routine( soft_intr_ptr->data );
14357 +}
14358 +
14359 +
14360 +// delete a soft interrupt object
14361 +/*----------------------------------------------------------------------------*/
14362 +void OsSoftInterruptRemove( 
14363 +       OS_SOFTINTR *arg )
14364 +/*----------------------------------------------------------------------------*/
14365 +{
14366 +       if( arg )
14367 +               kfree( arg );
14368 +       arg = NULL;
14369 +}
14370 +
14371 +
14372 +/*----------------------------------------------------------------------------*/
14373 +void OsSleep( 
14374 +       unsigned time )         // in seconds
14375 +/*----------------------------------------------------------------------------*/
14376 +{
14377 +       struct semaphore sem;
14378 +       struct timer_list timer_var;
14379 +       
14380 +       init_MUTEX_LOCKED (&sem);
14381 +
14382 +       //      if( in_interrupt() )
14383 +       //              panic( "OsSleep going to sleep at interrupt time\n" );
14384 +
14385 +       init_timer( &timer_var );
14386 +       timer_var.function = ( void ( * )( unsigned long ) )OsTimeoutHandler;
14387 +       timer_var.data = ( unsigned long )&sem;
14388 +       timer_var.expires = jiffies + time * HZ;
14389 +
14390 +       add_timer( &timer_var );
14391 +       down( &sem );
14392 +
14393 +       del_timer( &timer_var );
14394 +}
14395 +
14396 +
14397 +/*----------------------------------------------------------------------------*/
14398 +void OsTimeoutHandler( 
14399 +       struct semaphore * sem )
14400 +/*----------------------------------------------------------------------------*/
14401 +{
14402 +       if( sem != NULL )
14403 +               up( sem );
14404 +}
14405 +
14406 +
14407 +/*----------------------------------------------------------------------------*/
14408 +void printk_err(
14409 +       int flag, 
14410 +       char *fmt, 
14411 +       ...)
14412 +/*----------------------------------------------------------------------------*/
14413 +{
14414 +       char    buf[256];
14415 +       va_list ap;
14416 +
14417 +       va_start(ap, fmt);
14418 +       (void) vsprintf(buf, fmt, ap);
14419 +       va_end(ap);
14420 +       
14421 +       if( flag <= g_options.message_level )
14422 +               printk("<1>%s\n", buf);
14423 +}
14424 +
14425 +/*  void aac_show_tasks (struct list_head *our_tasks){ */
14426
14427 +/*             cmn_err (CE_DEBUG, "Entering aac_show_tasks"); */
14428 +
14429 +/*             if (our_tasks->next == NULL || our_tasks->next == 0) */
14430 +/*                             cmn_err (CE_DEBUG, "list_head->next is NULL or 0"); */
14431 +/*             else */
14432 +/*                             cmn_err (CE_DEBUG, "list_head->next: 0x%x", our_tasks->next); */
14433 +
14434 +/*             if (our_tasks->prev == NULL || our_tasks->prev == 0) */
14435 +/*                             cmn_err (CE_DEBUG, "list_head->prev is NULL or 0"); */
14436 +/*             else */
14437 +/*                             cmn_err (CE_DEBUG, "list_head->prev: 0x%x", our_tasks->prev); */
14438 +
14439 +/*  } */
14440 diff -burN linux-2.4.4/drivers/scsi/aacraid/ossup.c linux/drivers/scsi/aacraid/ossup.c
14441 --- linux-2.4.4/drivers/scsi/aacraid/ossup.c    Wed Dec 31 18:00:00 1969
14442 +++ linux/drivers/scsi/aacraid/ossup.c  Mon Apr 30 09:43:34 2001
14443 @@ -0,0 +1,199 @@
14444 +/*++
14445 + * Adaptec aacraid device driver for Linux.
14446 + *
14447 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
14448 + *
14449 + * This program is free software; you can redistribute it and/or modify
14450 + * it under the terms of the GNU General Public License as published by
14451 + * the Free Software Foundation; either version 2, or (at your option)
14452 + * any later version.
14453 + *
14454 + * This program is distributed in the hope that it will be useful,
14455 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
14456 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14457 + * GNU General Public License for more details.
14458 + *
14459 + * You should have received a copy of the GNU General Public License
14460 + * along with this program; see the file COPYING.  If not, write to
14461 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
14462 + *
14463 + * Module Name:
14464 + *  ossup.c
14465 + *
14466 + * 
14467 + *
14468 + --*/
14469 +
14470 +static char *ident_ossup = "aacraid_ident ossup.c 1.0.6 2000/10/09 Adaptec, Inc.";
14471 +
14472 +#include "osheaders.h"
14473 +
14474 +#include "aac_unix_defs.h"
14475 +
14476 +
14477 +AAC_STATUS
14478 +ExInitializeZone(
14479 +    IN PZONE_HEADER Zone,
14480 +    IN ULONG BlockSize,
14481 +    IN PVOID InitialSegment,
14482 +    IN ULONG InitialSegmentSize
14483 +    )
14484 +
14485 +/*++
14486 +
14487 +Routine Description:
14488 +
14489 +    This function initializes a zone header.  Once successfully
14490 +    initialized, blocks can be allocated and freed from the zone, and
14491 +    the zone can be extended.
14492 +
14493 +Arguments:
14494 +
14495 +    Zone - Supplies the address of a zone header to be initialized.
14496 +
14497 +    BlockSize - Supplies the block size of the allocatable unit within
14498 +                the zone.  The size must be larger that the size of the
14499 +                initial segment, and must be 64-bit aligned.
14500 +
14501 +    InitialSegment - Supplies the address of a segment of storage.  The
14502 +                     first ZONE_SEGMENT_HEADER-sized portion of the segment
14503 +                     is used by the zone allocator.  The remainder of
14504 +                     the segment is carved up into fixed size
14505 +                     (BlockSize) blocks and is made available for
14506 +                     allocation and deallocation from the zone.  The
14507 +                     address of the segment must be aligned on a 64-bit
14508 +                     boundary.
14509 +
14510 +    InitialSegmentSize - Supplies the size in bytes of the InitialSegment.
14511 +
14512 +Return Value:
14513 +
14514 +    STATUS_UNSUCCESSFUL - BlockSize or InitialSegment was not aligned on
14515 +                          64-bit boundaries, or BlockSize was larger than
14516 +                          the initial segment size.
14517 +
14518 +    STATUS_SUCCESS - The zone was successfully initialized.
14519 +
14520 +--*/
14521 +
14522 +{
14523 +    ULONG i;
14524 +    PCHAR p;
14525 +
14526 +
14527 +    Zone->BlockSize = BlockSize;
14528 +
14529 +    Zone->SegmentList.Next = &((PZONE_SEGMENT_HEADER) InitialSegment)->SegmentList;
14530 +    ((PZONE_SEGMENT_HEADER) InitialSegment)->SegmentList.Next = NULL;
14531 +    ((PZONE_SEGMENT_HEADER) InitialSegment)->Reserved = NULL;
14532 +
14533 +    Zone->FreeList.Next = NULL;
14534 +
14535 +    p = (PCHAR)InitialSegment + sizeof(ZONE_SEGMENT_HEADER);
14536 +
14537 +    for (i = sizeof(ZONE_SEGMENT_HEADER);
14538 +         i <= InitialSegmentSize - BlockSize;
14539 +         i += BlockSize
14540 +        ) {
14541 +        ((PSINGLE_LIST_ENTRY)p)->Next = Zone->FreeList.Next;
14542 +        Zone->FreeList.Next = (PSINGLE_LIST_ENTRY)p;
14543 +        p += BlockSize;
14544 +    }
14545 +    Zone->TotalSegmentSize = i;
14546 +
14547 +#if 0
14548 +    DbgPrint( "EX: ExInitializeZone( %lx, %lx, %lu, %lu, %lx )\n",
14549 +              Zone, InitialSegment, InitialSegmentSize,
14550 +              BlockSize, p
14551 +            );
14552 +#endif
14553 +
14554 +    return STATUS_SUCCESS;
14555 +}
14556 +
14557 +AAC_STATUS
14558 +ExExtendZone(
14559 +    IN PZONE_HEADER Zone,
14560 +    IN PVOID Segment,
14561 +    IN ULONG SegmentSize
14562 +    )
14563 +
14564 +/*++
14565 +
14566 +Routine Description:
14567 +
14568 +    This function extends a zone by adding another segment's worth of
14569 +    blocks to the zone.
14570 +
14571 +Arguments:
14572 +
14573 +    Zone - Supplies the address of a zone header to be extended.
14574 +
14575 +    Segment - Supplies the address of a segment of storage.  The first
14576 +              ZONE_SEGMENT_HEADER-sized portion of the segment is used by the
14577 +              zone allocator.  The remainder of the segment is carved up
14578 +              into fixed-size (BlockSize) blocks and is added to the
14579 +              zone.  The address of the segment must be aligned on a 64-
14580 +              bit boundary.
14581 +
14582 +    SegmentSize - Supplies the size in bytes of Segment.
14583 +
14584 +Return Value:
14585 +
14586 +    STATUS_UNSUCCESSFUL - BlockSize or Segment was not aligned on
14587 +                          64-bit boundaries, or BlockSize was larger than
14588 +                          the segment size.
14589 +
14590 +    STATUS_SUCCESS - The zone was successfully extended.
14591 +
14592 +--*/
14593 +
14594 +{
14595 +    ULONG i;
14596 +    PCHAR p;
14597 +
14598 +
14599 +    ((PZONE_SEGMENT_HEADER) Segment)->SegmentList.Next = Zone->SegmentList.Next;
14600 +    Zone->SegmentList.Next = &((PZONE_SEGMENT_HEADER) Segment)->SegmentList;
14601 +
14602 +    p = (PCHAR)Segment + sizeof(ZONE_SEGMENT_HEADER);
14603 +
14604 +    for (i = sizeof(ZONE_SEGMENT_HEADER);
14605 +         i <= SegmentSize - Zone->BlockSize;
14606 +         i += Zone->BlockSize
14607 +        ) {
14608 +
14609 +        ((PSINGLE_LIST_ENTRY)p)->Next = Zone->FreeList.Next;
14610 +        Zone->FreeList.Next = (PSINGLE_LIST_ENTRY)p;
14611 +        p += Zone->BlockSize;
14612 +    }
14613 +    Zone->TotalSegmentSize += i;
14614 +
14615 +#if 0
14616 +    DbgPrint( "EX: ExExtendZone( %lx, %lx, %lu, %lu, %lx )\n",
14617 +              Zone, Segment, SegmentSize, Zone->BlockSize, p
14618 +            );
14619 +#endif
14620 +
14621 +    return STATUS_SUCCESS;
14622 +}
14623 +
14624 +DbgPrint()
14625 +{
14626 +}
14627 +
14628 +/* Function: InqStrCopy()
14629 + *
14630 + * Arguments: [2] pointer to char
14631 + *
14632 + * Purpose: Copy a String from one location to another
14633 + * without copying \0
14634 + */
14635 +void
14636 +InqStrCopy(char *a, char *b)
14637 +{
14638 +
14639 +       while(*a != (char)0) 
14640 +               *b++ = *a++;
14641 +}
14642 +
14643 diff -burN linux-2.4.4/drivers/scsi/aacraid/port.c linux/drivers/scsi/aacraid/port.c
14644 --- linux-2.4.4/drivers/scsi/aacraid/port.c     Wed Dec 31 18:00:00 1969
14645 +++ linux/drivers/scsi/aacraid/port.c   Mon Apr 30 09:43:34 2001
14646 @@ -0,0 +1,287 @@
14647 +/*++
14648 + * Adaptec aacraid device driver for Linux.
14649 + *
14650 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
14651 + *
14652 + * This program is free software; you can redistribute it and/or modify
14653 + * it under the terms of the GNU General Public License as published by
14654 + * the Free Software Foundation; either version 2, or (at your option)
14655 + * any later version.
14656 + *
14657 + * This program is distributed in the hope that it will be useful,
14658 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
14659 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14660 + * GNU General Public License for more details.
14661 + *
14662 + * You should have received a copy of the GNU General Public License
14663 + * along with this program; see the file COPYING.  If not, write to
14664 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
14665 + *
14666 + * Module Name:
14667 + *  port.c
14668 + *
14669 + * Abstract: All support routines for FSA communication which are miniport specific.
14670 + *
14671 + --*/
14672 +
14673 +static char *ident_port = "aacraid_ident port.c 1.0.7 2000/10/11 Adaptec, Inc.";
14674 +
14675 +#include "osheaders.h"
14676 +
14677 +
14678 +#include "AacGenericTypes.h"
14679 +
14680 +#include "aac_unix_defs.h"
14681 +
14682 +#include "fsatypes.h"
14683 +#include "comstruc.h"
14684 +#include "protocol.h"
14685 +
14686 +#include "fsaport.h"
14687 +#include "fsaioctl.h"
14688 +
14689 +#include "pcisup.h"
14690 +#include "port.h"
14691 +
14692 +int AfaPortPrinting = 1;
14693 +
14694 +extern AAC_STATUS AfaPort_Err_Adapter_Printf;
14695 +extern AAC_STATUS AfaPort_Warn_Adapter_Printf;
14696 +extern AAC_STATUS AfaPort_Info_Adapter_Printf;
14697 +extern AAC_STATUS AfaPort_Err_FastAfa_Load_Driver;
14698 +
14699 +
14700 +
14701 +VOID
14702 +AfaPortLogError(
14703 +       IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
14704 +       IN AAC_STATUS ErrorCode,
14705 +       IN PUCHAR StringBuffer,
14706 +       IN ULONG StringLength
14707 +       )
14708 +/*++
14709 +
14710 +Routine Description:
14711 +
14712 +       Does all of the work to log an error log entry
14713 +Arguments:
14714 +
14715 +       CommonExtension - Pointer to the adapter that caused the error.
14716 +
14717 +       ErrorCode - Which error is being logged.
14718 +
14719 +       StringBuffer - Pointer to optional String for error log entry.
14720 +
14721 +       StringLength - Length of StringBuffer.
14722 +
14723 +Return Value:
14724 +
14725 +    Nothing
14726 +
14727 +--*/
14728 +
14729 +{
14730 +
14731 +}
14732 +
14733 +BOOLEAN
14734 +AfaPortGetNextAdapterNumber(
14735 +    IN  PDRIVER_OBJECT  DriverObject,
14736 +       OUT PDEVICE_OBJECT      *FsaDeviceObject,
14737 +       OUT PFILE_OBJECT        *FileObject,
14738 +       OUT PULONG                      AdapterNumber
14739 +       )
14740 +{
14741 +}
14742 +BOOLEAN
14743 +AfaPortAllocateAdapterCommArea(
14744 +       IN PVOID                Arg1,
14745 +       IN OUT PVOID    *CommHeaderAddress,
14746 +       IN ULONG                CommAreaSize,
14747 +       IN ULONG                CommAreaAlignment
14748 +       )
14749 +{
14750 +       PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
14751 +       PVOID BaseAddress;
14752 +       PHYSICAL_ADDRESS PhysicalBaseAddress;
14753 +       ULONG TotalSize, BytesToAlign;
14754 +       size_t          RealLength;
14755 +       uint_t          Count;
14756 +//     ULONG SizeOfFastIoComm = sizeof(FASTIO_STRUCT);
14757 +//     ULONG AdapterFibsSize = PAGE_SIZE;
14758 +       ULONG AdapterFibsSize = 4096;
14759 +       ULONG PrintfBufferSize = 256;
14760 +       PADAPTER_INIT_STRUCT InitStruct;
14761 +       extern int MiniPortRevision;
14762 +       ULONG   PhysAddress;
14763 +
14764 +//     TotalSize = AdapterFibsSize + sizeof(ADAPTER_INIT_STRUCT) + CommAreaSize + CommAreaAlignment +
14765 +//              SizeOfFastIoComm + PrintfBufferSize;
14766 +       TotalSize = AdapterFibsSize + sizeof(ADAPTER_INIT_STRUCT) + CommAreaSize + CommAreaAlignment +
14767 +                PrintfBufferSize;
14768 +
14769 +
14770 +       OsAllocCommPhysMem(CommonExtension->MiniPort, TotalSize, &BaseAddress, &PhysAddress);
14771 +
14772 +       CommonExtension->CommAddress  = BaseAddress;
14773 +       CommonExtension->CommPhysAddr = PhysAddress;
14774 +       CommonExtension->CommSize         = TotalSize;
14775 +
14776 +       PhysicalBaseAddress.HighPart = 0;
14777 +       PhysicalBaseAddress.LowPart = PhysAddress;
14778 +
14779 +       CommonExtension->InitStruct = (PADAPTER_INIT_STRUCT)((PUCHAR)(BaseAddress) + AdapterFibsSize);
14780 +       CommonExtension->PhysicalInitStruct = (PADAPTER_INIT_STRUCT)((PUCHAR)(PhysicalBaseAddress.LowPart) + AdapterFibsSize);
14781 +
14782 +       InitStruct = CommonExtension->InitStruct;
14783 +
14784 +       InitStruct->InitStructRevision = ADAPTER_INIT_STRUCT_REVISION;
14785 +       InitStruct->MiniPortRevision = MiniPortRevision;
14786 +       InitStruct->FilesystemRevision = CommonExtension->FilesystemRevision;
14787 +
14788 +       //
14789 +       // Adapter Fibs are the first thing allocated so that they start page aligned
14790 +       //
14791 +       InitStruct->AdapterFibsVirtualAddress = BaseAddress;
14792 +       InitStruct->AdapterFibsPhysicalAddress = (PVOID) PhysicalBaseAddress.LowPart;
14793 +       InitStruct->AdapterFibsSize = AdapterFibsSize;
14794 +       InitStruct->AdapterFibAlign = sizeof(FIB);
14795 +
14796 +       //
14797 +       // Increment the base address by the amount already used
14798 +       //
14799 +       BaseAddress = (PVOID)((PUCHAR)(BaseAddress) + AdapterFibsSize + sizeof(ADAPTER_INIT_STRUCT));
14800 +       PhysicalBaseAddress.LowPart = (ULONG)((PUCHAR)(PhysicalBaseAddress.LowPart) + AdapterFibsSize + sizeof(ADAPTER_INIT_STRUCT));
14801 +
14802 +       //
14803 +       // Align the beginning of Headers to CommAreaAlignment
14804 +       //
14805 +       BytesToAlign = (CommAreaAlignment - ((ULONG)(BaseAddress) & (CommAreaAlignment - 1)));
14806 +       BaseAddress = (PVOID)((PUCHAR)(BaseAddress) + BytesToAlign);
14807 +       PhysicalBaseAddress.LowPart = (ULONG)((PUCHAR)(PhysicalBaseAddress.LowPart) + BytesToAlign);
14808 +
14809 +       //
14810 +       // Fill in addresses of the Comm Area Headers and Queues
14811 +       //
14812 +       *CommHeaderAddress = BaseAddress;
14813 +       InitStruct->CommHeaderAddress = (PVOID)PhysicalBaseAddress.LowPart;
14814 +
14815 +       //
14816 +       //      Increment the base address by the size of the CommArea
14817 +       //
14818 +       BaseAddress = (PVOID)((PUCHAR)(BaseAddress) + CommAreaSize);
14819 +       PhysicalBaseAddress.LowPart = (ULONG)((PUCHAR)(PhysicalBaseAddress.LowPart) + CommAreaSize);
14820 +
14821 +
14822 +       //
14823 +       // Place the Printf buffer area after the Fast I/O comm area.
14824 +       //
14825 +       CommonExtension->PrintfBufferAddress = (PVOID)(BaseAddress);
14826 +       InitStruct->PrintfBufferAddress = (PVOID)PhysicalBaseAddress.LowPart;
14827 +       InitStruct->PrintfBufferSize = PrintfBufferSize;
14828 +       bzero (BaseAddress, PrintfBufferSize);
14829 +
14830 +       AfaPortPrint("FsaAllocateAdapterCommArea: allocated a common buffer of 0x%x bytes from address 0x%x to address 0x%x\n",
14831 +                        TotalSize, InitStruct->AdapterFibsVirtualAddress,
14832 +                        (PUCHAR)(InitStruct->AdapterFibsVirtualAddress) + TotalSize);
14833 +
14834 +       AfaPortPrint("Mapped on to PCI address 0x%x\n", InitStruct->AdapterFibsPhysicalAddress);
14835 +
14836 +       return (TRUE);
14837 +}
14838 +
14839 +AAC_STATUS
14840 +AfaPortCreate (
14841 +    IN PDEVICE_OBJECT DeviceObject,
14842 +    IN PIRP Irp
14843 +    )
14844 +/*++
14845 +
14846 +Routine Description:
14847 +
14848 +       The routine will get called each time a user issues a CreateFile on the DeviceObject
14849 +       for the adapter.
14850 +
14851 +       The main purpose of this routine is to set up any data structures that may be needed
14852 +       to handle any requests made on this DeviceObject.
14853 +
14854 +Arguments:
14855 +
14856 +       DeviceObject - Pointer to device object representing adapter
14857 +
14858 +       Irp - Pointer to Irp that caused this open
14859 +
14860 +
14861 +Return Value:
14862 +
14863 +       Status value returned from File system driver AdapterOpen
14864 +
14865 +--*/
14866 +
14867 +{
14868 +}
14869 +
14870 +AAC_STATUS
14871 +AfaPortClose (
14872 +    IN PDEVICE_OBJECT DeviceObject,
14873 +    IN PIRP Irp
14874 +    )
14875 +/*++
14876 +
14877 +Routine Description:
14878 +
14879 +       This routine will get called each time a user issues a CloseHandle on the DeviceObject
14880 +       for the adapter.
14881 +
14882 +       The main purpose of this routine is to cleanup any data structures that have been set up
14883 +       while this FileObject has been opened.
14884 +
14885 +Arguments:
14886 +
14887 +       DeviceObject - Pointer to device object representing adapter
14888 +
14889 +       Irp - Pointer to Irp that caused this close
14890 +
14891 +Return Value:
14892 +
14893 +       Status value returned from File system driver AdapterClose
14894 +
14895 +--*/
14896 +
14897 +{
14898 +
14899 +}
14900 +
14901 +AAC_STATUS
14902 +AfaPortDeviceControl (
14903 +    IN PDEVICE_OBJECT DeviceObject,
14904 +    IN PIRP Irp
14905 +    )
14906 +{
14907 +
14908 +}
14909 +
14910 +ULONG
14911 +AfaPortGetMaxPhysicalPage(
14912 +       IN PPCI_MINIPORT_COMMON_EXTENSION       CommonExtension
14913 +       )
14914 +/*++
14915 +
14916 +Routine Description:
14917 +
14918 +       This routine determines the max physical page in host memory.
14919 +
14920 +Arguments:
14921 +
14922 +       AdapterExtension
14923 +
14924 +Return Value:
14925 +
14926 +       Max physical page in host memory.
14927 +
14928 +--*/
14929 +{
14930 +
14931 +}
14932 +
14933 +
14934 diff -burN linux-2.4.4/drivers/scsi/aacraid/rx.c linux/drivers/scsi/aacraid/rx.c
14935 --- linux-2.4.4/drivers/scsi/aacraid/rx.c       Wed Dec 31 18:00:00 1969
14936 +++ linux/drivers/scsi/aacraid/rx.c     Mon Apr 30 09:43:34 2001
14937 @@ -0,0 +1,917 @@
14938 +/*++
14939 + * Adaptec aacraid device driver for Linux.
14940 + *
14941 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
14942 + *
14943 + * This program is free software; you can redistribute it and/or modify
14944 + * it under the terms of the GNU General Public License as published by
14945 + * the Free Software Foundation; either version 2, or (at your option)
14946 + * any later version.
14947 + *
14948 + * This program is distributed in the hope that it will be useful,
14949 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
14950 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14951 + * GNU General Public License for more details.
14952 + *
14953 + * You should have received a copy of the GNU General Public License
14954 + * along with this program; see the file COPYING.  If not, write to
14955 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
14956 + *
14957 + * Module Name:
14958 + *  rx.c
14959 + *
14960 + * Abstract: Hardware miniport for Drawbridge specific hardware functions.
14961 + *
14962 + --*/
14963 +
14964 +static char *ident_rx = "aacraid_ident rx.c 1.0.7 2000/10/11 Adaptec, Inc.";
14965 +
14966 +#include "osheaders.h"
14967 +
14968 +
14969 +#include "AacGenericTypes.h"
14970 +
14971 +#include "aac_unix_defs.h"
14972 +
14973 +#include "fsatypes.h"
14974 +#include "comstruc.h"
14975 +#include "fsact.h"
14976 +#include "protocol.h"
14977 +
14978 +#define DEFINE_PCI_IDS
14979 +#include "rxcommon.h"
14980 +#include "monkerapi.h"
14981 +
14982 +#include "fsaport.h"
14983 +#include "fsaioctl.h"
14984 +
14985 +#include "pcisup.h"
14986 +#include "rx.h"
14987 +
14988 +#include "port.h"
14989 +
14990 +#define BugCheckFileId                   (FSAFS_BUG_CHECK_CYCLONESUP)
14991 +
14992 +// #define RxBugCheck(A,B,C) { KeBugCheckEx(0x00000AFA, __LINE__, (ULONG)A, (ULONG)B,(ULONG)C ); }
14993 +
14994 +#define RxBugCheck(A, B, C) {  cmn_err(CE_PANIC, "aacdisk : line %s, 0x%x, 0x%x, 0x%x ", __LINE__, A, B, C);  }
14995 +
14996 +#define NUM_TICKS_PER_SECOND (1000 * 1000 * 10) /* time is in 100 nanoseconds */
14997 +
14998 +
14999 +//
15000 +// The list of all the Rx adapter structures
15001 +//
15002 +
15003 +PRx_ADAPTER_EXTENSION  RxAdapterList;
15004 +
15005 +int
15006 +RxInitDevice(
15007 +       IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
15008 +       IN ULONG AdapterNumber,
15009 +       IN ULONG PciBus,
15010 +       IN ULONG PciSlot
15011 +);
15012 +
15013 +BOOLEAN
15014 +RxSendSynchFib(
15015 +       PVOID Arg1,
15016 +       ULONG FibPhysicalAddress
15017 +       );
15018 +
15019 +FSA_USER_VAR   RxUserVars[] = {
15020 +       { "AfaPortPrinting", (PULONG)&AfaPortPrinting, NULL },
15021 +};
15022 +
15023 +
15024 +//
15025 +// Declare private use routines for this modual
15026 +//
15027 +
15028 +u_int
15029 +RxPciIsr (
15030 +    IN PRx_ADAPTER_EXTENSION AdapterExtension
15031 +    )
15032 +
15033 +/*++
15034 +
15035 +Routine Description:
15036 +
15037 +    The Isr routine for fsa Rx based adapter boards.
15038 +
15039 +Arguments:
15040 +
15041 +
15042 +Return Value:
15043 +
15044 +       TRUE - if the interrupt was handled by this isr
15045 +       FALSE - if the interrupt was not handled by this isr
15046 +
15047 +--*/
15048 +
15049 +{
15050 +       ULONG   DoorbellBits;
15051 +       UCHAR   InterruptStatus, Mask;
15052 +       u_int OurInterrupt = INTR_UNCLAIMED;
15053 +
15054 +       //cmn_err(CE_WARN, "RxPciIsr entered\n");
15055 +
15056 +       InterruptStatus = Rx_READ_UCHAR(AdapterExtension, MUnit.OISR);
15057 +
15058 +       //
15059 +       // Read mask and invert because drawbridge is reversed.
15060 +       //
15061 +       // This allows us to only service interrupts that have been enabled.
15062 +       //
15063 +
15064 +       Mask = ~(Rx_READ_UCHAR(AdapterExtension, MUnit.OIMR));
15065 +
15066 +       // Check to see if this is our interrupt.  If it isn't just return FALSE.
15067 +
15068 +
15069 +       if (InterruptStatus & Mask) {
15070 +
15071 +               DoorbellBits = Rx_READ_ULONG(AdapterExtension, OutboundDoorbellReg);
15072 +
15073 +               OurInterrupt = INTR_CLAIMED;
15074 +
15075 +               if (DoorbellBits & DoorBellPrintfReady) {
15076 +
15077 +                       ULONG Length, Level;
15078 +                       unsigned char *cp;
15079 +
15080 +                       cp = AdapterExtension->Common->PrintfBufferAddress;
15081 +
15082 +                       //
15083 +                       // The size of the Printfbuffer is set in port.c
15084 +                       // There is no variable or define for it
15085 +                       //
15086 +                       if (Length > 255)
15087 +                               Length = 255;
15088 +
15089 +                       if (cp[Length] != 0) {
15090 +                               // cmn_err (CE_NOTE, "byte %d is 0x%x, should be 0", Length, cp[Length]);
15091 +                               cp[Length] = 0;
15092 +                       }
15093 +
15094 +                       if (Level == LOG_HIGH_ERROR)
15095 +                               cmn_err (CE_WARN, "%s:%s", OsGetDeviceName(AdapterExtension), AdapterExtension->Common->PrintfBufferAddress);
15096 +                       else
15097 +                               cmn_err (CE_NOTE, "%s:%s", OsGetDeviceName(AdapterExtension), AdapterExtension->Common->PrintfBufferAddress);
15098 +
15099 +                       bzero (AdapterExtension->Common->PrintfBufferAddress, 256);
15100 +
15101 +                       Rx_WRITE_ULONG(AdapterExtension, MUnit.ODR,DoorBellPrintfReady); //clear PrintfReady
15102 +
15103 +                       Rx_WRITE_ULONG(AdapterExtension, InboundDoorbellReg,DoorBellPrintfDone);
15104 +
15105 +
15106 +               } else if (DoorbellBits & DoorBellAdapterNormCmdReady) {        // Adapter -> Host Normal Command Ready
15107 +
15108 +                       AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, HostNormCmdQue);
15109 +                       Rx_WRITE_ULONG(AdapterExtension, MUnit.ODR, DoorBellAdapterNormCmdReady);
15110 +
15111 +               } else if (DoorbellBits & DoorBellAdapterNormRespReady) {       // Adapter -> Host Normal Response Ready
15112 +
15113 +                       AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, HostNormRespQue);
15114 +                       Rx_WRITE_ULONG(AdapterExtension, MUnit.ODR,DoorBellAdapterNormRespReady);
15115 +
15116 +               } else if (DoorbellBits & DoorBellAdapterNormCmdNotFull) {      // Adapter -> Host Normal Command Not Full
15117 +
15118 +                       AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, AdapNormCmdNotFull);
15119 +                       Rx_WRITE_ULONG(AdapterExtension, MUnit.ODR, DoorBellAdapterNormCmdNotFull);
15120 +
15121 +               } else if (DoorbellBits & DoorBellAdapterNormRespNotFull) {     // Adapter -> Host Normal Response Not Full
15122 +
15123 +                       AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, AdapNormRespNotFull);
15124 +                       Rx_WRITE_ULONG(AdapterExtension, MUnit.ODR, DoorBellAdapterNormRespNotFull);
15125 +
15126 +               }
15127 +
15128 +       }
15129 +       return(OurInterrupt);
15130 +}
15131 +
15132 +VOID
15133 +RxEnableInterrupt(
15134 +       PVOID                                           Arg1,
15135 +       ADAPTER_EVENT                           AdapterEvent,
15136 +       BOOLEAN                                         AtDeviceIrq
15137 +       )
15138 +/*++
15139 +
15140 +Routine Description:
15141 +
15142 +       This routine will enable the corresponding adapter event to cause an interrupt on 
15143 +       the host.
15144 +
15145 +Arguments:
15146 +
15147 +       AdapterExtension - Which adapter to enable.
15148 +
15149 +       AdapterEvent - Which adapter event.
15150 +
15151 +       AtDeviceIrq - Whether the system is in DEVICE irql
15152 +
15153 +Return Value:
15154 +
15155 +    Nothing.
15156 +
15157 +--*/
15158 +{
15159 +       PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
15160 +       PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) CommonExtension->MiniPort;
15161 +
15162 +       //cmn_err(CE_WARN, "RxEnableInterrupt");
15163 +       switch (AdapterEvent) {
15164 +
15165 +         case HostNormCmdQue:
15166 +
15167 +               AdapterExtension->LocalMaskInterruptControl &= ~(OUTBOUNDDOORBELL_1);
15168 +
15169 +               break;
15170 +
15171 +         case HostNormRespQue:
15172 +
15173 +               AdapterExtension->LocalMaskInterruptControl &= ~(OUTBOUNDDOORBELL_2);
15174 +
15175 +               break;
15176 +
15177 +      case AdapNormCmdNotFull:
15178 +
15179 +               AdapterExtension->LocalMaskInterruptControl &= ~(OUTBOUNDDOORBELL_3);
15180 +
15181 +               break;
15182 +
15183 +      case AdapNormRespNotFull:
15184 +
15185 +               AdapterExtension->LocalMaskInterruptControl &= ~(OUTBOUNDDOORBELL_4);
15186 +
15187 +               break;
15188 +
15189 +       }
15190 +
15191 +}
15192 +
15193 +VOID
15194 +RxDisableInterrupt(
15195 +       PVOID                                           Arg1,
15196 +       ADAPTER_EVENT                           AdapterEvent,
15197 +       BOOLEAN                                         AtDeviceIrq
15198 +       )
15199 +/*++
15200 +
15201 +Routine Description:
15202 +
15203 +       This routine will disable the corresponding adapter event to cause an interrupt on 
15204 +       the host.
15205 +
15206 +Arguments:
15207 +
15208 +       AdapterExtension - Which adapter to enable.
15209 +
15210 +       AdapterEvent - Which adapter event.
15211 +
15212 +       AtDeviceIrq - Whether the system is in DEVICE irql
15213 +
15214 +Return Value:
15215 +
15216 +    Nothing.
15217 +
15218 +--*/
15219 +{
15220 +       PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
15221 +       PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) CommonExtension->MiniPort;
15222 +
15223 +       //cmn_err(CE_WARN, "RxEnableInterrupt");
15224 +
15225 +       switch (AdapterEvent) {
15226 +
15227 +
15228 +         case HostNormCmdQue:
15229 +
15230 +               AdapterExtension->LocalMaskInterruptControl |= (OUTBOUNDDOORBELL_1);
15231 +
15232 +               break;
15233 +
15234 +         case HostNormRespQue:
15235 +
15236 +               AdapterExtension->LocalMaskInterruptControl |= (OUTBOUNDDOORBELL_2);
15237 +
15238 +               break;
15239 +
15240 +      case AdapNormCmdNotFull:
15241 +
15242 +               AdapterExtension->LocalMaskInterruptControl |= (OUTBOUNDDOORBELL_3);
15243 +
15244 +               break;
15245 +
15246 +
15247 +      case AdapNormRespNotFull:
15248 +
15249 +               AdapterExtension->LocalMaskInterruptControl |= (OUTBOUNDDOORBELL_4);
15250 +
15251 +               break;
15252 +
15253 +       }
15254 +
15255 +}
15256 +
15257 +
15258 +
15259 +RxDetachDevice(
15260 +       IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension
15261 +       )
15262 +{
15263 +       PRx_ADAPTER_EXTENSION AdapterExtension = CommonExtension->MiniPort;
15264 +
15265 +       //
15266 +       // Free the register mapping.
15267 +       //
15268 +
15269 +       OsDetachDevice( AdapterExtension);
15270 +
15271 +       OsFreeMemory( AdapterExtension, sizeof(Rx_ADAPTER_EXTENSION) );
15272 +
15273 +}
15274 +
15275 +int
15276 +RxInitDevice(
15277 +       IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
15278 +       IN ULONG AdapterNumber,
15279 +       IN ULONG PciBus,
15280 +       IN ULONG PciSlot
15281 +)
15282 +
15283 +/*++
15284 +
15285 +Routine Description:
15286 +
15287 +       Scans the PCI bus looking for the Rx card. When found all resources for the
15288 +       device will be allocated and the interrupt vectors and csrs will be allocated and
15289 +       mapped.
15290 +
15291 +       The device_interface in the commregion will be allocated and linked to the comm region.
15292 +
15293 +Arguments:
15294 +
15295 +
15296 +Return Value:
15297 +
15298 +    TRUE - if the device was setup with not problems
15299 +    FALSE - if the device could not be mapped and init successfully
15300 +
15301 +--*/
15302 +
15303 +{
15304 +       AAC_STATUS Status;
15305 +       PRx_ADAPTER_EXTENSION AdapterExtension = NULL;
15306 +       FSA_NEW_ADAPTER NewAdapter;
15307 +       ULONG StartTime, EndTime, WaitTime;
15308 +       ULONG InitStatus;
15309 +       int instance;
15310 +       int nIntrs;
15311 +       char * name;
15312 +
15313 +    AfaPortPrint("In init device.\n");
15314 +
15315 +       //cmn_err(CE_WARN, "In RxInitDevice");
15316 +
15317 +//     AdapterExtension->Common->AdapterIndex = AdapterIndex;
15318 +       CommonExtension->AdapterNumber = AdapterNumber;
15319 +
15320 +
15321 +       CommonExtension->PciBusNumber = PciBus;
15322 +       CommonExtension->PciSlotNumber = PciSlot;
15323 +
15324 +
15325 +       AdapterExtension = OsAllocMemory( sizeof(Rx_ADAPTER_EXTENSION), OS_ALLOC_MEM_SLEEP );
15326 +       AdapterExtension->Common = CommonExtension;
15327 +       CommonExtension->MiniPort = AdapterExtension;
15328 +
15329 +       instance = OsGetDeviceInstance(AdapterExtension);
15330 +       name     = OsGetDeviceName(AdapterExtension);
15331 +       //
15332 +       // Map in the registers from the adapter, register space 0 is config space,
15333 +       // register space 1 is the memery space.
15334 +       //
15335 +
15336 +       if (OsMapDeviceRegisters(AdapterExtension)) {
15337 +
15338 +               cmn_err(CE_CONT, "%s%d: can't map device registers\n",
15339 +                               OsGetDeviceName(AdapterExtension), instance);
15340 +               return(FAILURE);
15341 +       }
15342 +
15343 +       //
15344 +       // Check to see if the board failed any self tests.
15345 +       //
15346 +
15347 +       if (Rx_READ_ULONG( AdapterExtension, IndexRegs.Mailbox[7]) & SELF_TEST_FAILED) {
15348 +
15349 +               cmn_err(CE_CONT, "%s%d: adapter self-test failed\n",
15350 +                               OsGetDeviceName(AdapterExtension), instance);
15351 +               return(FAILURE);
15352 +
15353 +       }
15354 +       //cmn_err(CE_WARN, "RxInitDevice: %s%d: adapter passwd self-test\n",
15355 +       //                      OsGetDeviceName(AdapterExtension), instance);
15356 +
15357 +       //
15358 +       // Check to see if the board panic'd while booting.
15359 +       //
15360 +
15361 +       if (Rx_READ_ULONG( AdapterExtension, IndexRegs.Mailbox[7]) & KERNEL_PANIC) {
15362 +
15363 +               cmn_err(CE_CONT, "%s%d: adapter kernel panic'd\n",
15364 +                               OsGetDeviceName(AdapterExtension), instance);
15365 +               return(FAILURE);
15366 +
15367 +       }
15368 +
15369 +       StartTime = OsGetSeconds();
15370 +       WaitTime = 0;
15371 +
15372 +
15373 +       //
15374 +       //  Wait for the adapter to be up and running. Wait up until 3 minutes.
15375 +       //
15376 +
15377 +       while (!(Rx_READ_ULONG( AdapterExtension, IndexRegs.Mailbox[7]) & KERNEL_UP_AND_RUNNING)) {
15378 +       
15379 +               EndTime = OsGetSeconds();
15380 +
15381 +               WaitTime = EndTime - StartTime;
15382 +
15383 +               if ( WaitTime > (3 * 10) ) {
15384 +
15385 +                       InitStatus = Rx_READ_ULONG( AdapterExtension, IndexRegs.Mailbox[7]) >> 16;
15386 +
15387 +                       cmn_err(CE_CONT, "%s%d: adapter kernel failed to start, init status = %d\n",
15388 +                                       OsGetDeviceName(AdapterExtension), instance, InitStatus);
15389 +                       return(FAILURE);
15390 +
15391 +               }
15392 +       }
15393 +
15394 +       if (OsAttachInterrupt(AdapterExtension,RxISR)) {
15395 +               cmn_err(CE_WARN, "%s%d RxInitDevice: failed OsAttachIntterupt", name, instance);
15396 +               return(FAILURE);
15397 +       }
15398 +
15399 +
15400 +       if (OsAttachDMA(AdapterExtension)) {
15401 +               cmn_err(CE_WARN, "%s%d SaInitDevice: failed OsAttachDMA", name, instance);
15402 +               return(FAILURE);
15403 +       }
15404 +
15405 +       //
15406 +       // Fill in the function dispatch table.
15407 +       //
15408 +
15409 +       AdapterExtension->Common->AdapterFuncs.SizeOfFsaPortFuncs = sizeof(FSAPORT_FUNCS);
15410 +       AdapterExtension->Common->AdapterFuncs.AllocateAdapterCommArea = AfaPortAllocateAdapterCommArea;
15411 +       AdapterExtension->Common->AdapterFuncs.FreeAdapterCommArea = AfaPortFreeAdapterCommArea;
15412 +       AdapterExtension->Common->AdapterFuncs.BuildSgMap = AfaPortBuildSgMap;
15413 +       AdapterExtension->Common->AdapterFuncs.FreeDmaResources = AfaPortFreeDmaResources;
15414 +       AdapterExtension->Common->AdapterFuncs.AllocateAndMapFibSpace = AfaPortAllocateAndMapFibSpace;
15415 +       AdapterExtension->Common->AdapterFuncs.UnmapAndFreeFibSpace = AfaPortUnmapAndFreeFibSpace;
15416 +       AdapterExtension->Common->AdapterFuncs.InterruptAdapter = RxInterruptAdapter;
15417 +       AdapterExtension->Common->AdapterFuncs.EnableInterrupt = RxEnableInterrupt;
15418 +       AdapterExtension->Common->AdapterFuncs.DisableInterrupt = RxDisableInterrupt;
15419 +       AdapterExtension->Common->AdapterFuncs.NotifyAdapter = RxNotifyAdapter;
15420 +       AdapterExtension->Common->AdapterFuncs.ResetDevice = RxResetDevice;
15421 +       AdapterExtension->Common->AdapterFuncs.InterruptHost = NULL;
15422 +
15423 +       AdapterExtension->Common->AdapterFuncs.SendSynchFib = RxSendSynchFib;
15424 +
15425 +       NewAdapter.AdapterExtension = CommonExtension;
15426 +       NewAdapter.AdapterFuncs = &AdapterExtension->Common->AdapterFuncs;
15427 +       NewAdapter.AdapterInterruptsBelowDpc = FALSE;
15428 +       NewAdapter.AdapterUserVars = RxUserVars;
15429 +       NewAdapter.AdapterUserVarsSize = sizeof(RxUserVars) / sizeof(FSA_USER_VAR);
15430 +
15431 +       NewAdapter.Dip = CommonExtension->OsDep.dip;
15432 +
15433 +       
15434 +       if (AfaCommInitNewAdapter( &NewAdapter ) == NULL) {
15435 +               
15436 +               cmn_err(CE_WARN, "AfaCommInitNewAdapter failed\n");
15437 +               return (FAILURE);
15438 +       }
15439 +
15440 +
15441 +       AdapterExtension->Common->Adapter = NewAdapter.Adapter;
15442 +
15443 +       if (AdapterExtension->Common->Adapter == NULL) {
15444 +
15445 +               AfaPortLogError(AdapterExtension->Common, FAILURE, NULL, 0);
15446 +               cmn_err(CE_WARN, "%s%d RxInitDevice: No Adapter pointer", name, instance);
15447 +
15448 +
15449 +               return (FAILURE);
15450 +       }
15451 +
15452 +
15453 +       //
15454 +       // Start any kernel threads needed
15455 +       //
15456 +       OsStartKernelThreads(AdapterExtension);
15457 +
15458 +       //
15459 +       // Tell the adapter that all is configure, and it can start accepting requests
15460 +       //
15461 +
15462 +       RxStartAdapter(AdapterExtension);
15463 +
15464 +
15465 +#ifdef AACDISK
15466 +#endif
15467 +
15468 +
15469 +       //
15470 +       // Put this adapter into the list of Rx adapters
15471 +       //
15472 +
15473 +       AdapterExtension->Next = RxAdapterList;
15474 +       RxAdapterList = AdapterExtension;
15475 +
15476 +       AdapterExtension->Common->AdapterConfigured = TRUE;
15477 +
15478 +
15479 +#ifdef AACDISK
15480 +       //
15481 +       // Call the disk layer to initialize itself.
15482 +       //
15483 +
15484 +       AfaDiskInitNewAdapter( AdapterExtension->Common->AdapterNumber, AdapterExtension->Common->Adapter );
15485 +#endif
15486 +
15487 +
15488 +init_done:
15489 +
15490 +       AdapterExtension->Common->AdapterPrintfsToScreen = FALSE;
15491 +
15492 +
15493 +
15494 +       OsAttachHBA(AdapterExtension);
15495 +
15496 +    return(0);
15497 +}
15498 +
15499 +VOID
15500 +RxStartAdapter(
15501 +       PRx_ADAPTER_EXTENSION AdapterExtension
15502 +       )
15503 +{
15504 +       ULONG ReturnStatus;
15505 +       LARGE_INTEGER HostTime;
15506 +       ULONG ElapsedSeconds;
15507 +       PADAPTER_INIT_STRUCT InitStruct;
15508 +
15509 +       //cmn_err(CE_WARN, "RxStartAdapter");
15510 +       //
15511 +       // Fill in the remaining pieces of the InitStruct.
15512 +       //
15513 +
15514 +       InitStruct = AdapterExtension->Common->InitStruct;
15515 +
15516 +       InitStruct->HostPhysMemPages = AfaPortGetMaxPhysicalPage(AdapterExtension->Common);
15517 +
15518 +       ElapsedSeconds = OsGetSeconds();
15519 +
15520 +       InitStruct->HostElapsedSeconds = ElapsedSeconds;
15521 +
15522 +       //
15523 +       // Tell the adapter we are back and up and running so it will scan its command
15524 +       // queues and enable our interrupts
15525 +       //
15526 +
15527 +       AdapterExtension->LocalMaskInterruptControl =
15528 +               (DoorBellPrintfReady | OUTBOUNDDOORBELL_1 | OUTBOUNDDOORBELL_2 | OUTBOUNDDOORBELL_3 | OUTBOUNDDOORBELL_4);
15529 +
15530 +       //
15531 +       // First clear out all interrupts.  Then enable the one's that we can handle.
15532 +       //
15533 +
15534 +       Rx_WRITE_UCHAR( AdapterExtension, MUnit.OIMR, 0xff);
15535 +       Rx_WRITE_ULONG( AdapterExtension, MUnit.ODR, 0xffffffff);
15536 +//     Rx_WRITE_UCHAR(AdapterExtension, MUnit.OIMR, ~(UCHAR)OUTBOUND_DOORBELL_INTERRUPT_MASK);
15537 +       Rx_WRITE_UCHAR( AdapterExtension, MUnit.OIMR, 0xfb);
15538 +
15539 +       RxSendSynchCommand(AdapterExtension, 
15540 +                                        INIT_STRUCT_BASE_ADDRESS, 
15541 +                                        (ULONG) AdapterExtension->Common->PhysicalInitStruct,
15542 +                                        0,
15543 +                                        0,
15544 +                                        0,
15545 +                                        &ReturnStatus);
15546 +
15547 +}
15548 +
15549 +
15550 +VOID
15551 +RxResetDevice(
15552 +       PVOID Arg1
15553 +    )
15554 +
15555 +{
15556 +}
15557 +
15558 +VOID
15559 +RxInterruptAdapter(
15560 +       PVOID Arg1
15561 +       )
15562 +/*++
15563 +
15564 +Routine Description:
15565 +
15566 +       The will cause the adapter to take a break point.
15567 +
15568 +Arguments:
15569 +
15570 +       None
15571 +
15572 +Return Value:
15573 +
15574 +    Nothing
15575 +
15576 +--*/
15577 +{
15578 +       PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
15579 +       PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) CommonExtension->MiniPort;
15580 +
15581 +       ULONG ReturnStatus;
15582 +
15583 +       RxSendSynchCommand(AdapterExtension, 
15584 +                                          BREAKPOINT_REQUEST,
15585 +                                          0,
15586 +                                          0,
15587 +                                          0,
15588 +                                          0,
15589 +                                          &ReturnStatus);
15590 +
15591 +}
15592 +
15593 +VOID
15594 +RxNotifyAdapter(
15595 +       PVOID Arg1,
15596 +    IN HOST_2_ADAP_EVENT AdapterEvent
15597 +    )
15598 +/*++
15599 +
15600 +Routine Description:
15601 +
15602 +    Will read the adapter CSRs to find the reason the adapter has
15603 +    interrupted us.
15604 +
15605 +Arguments:
15606 +
15607 +    AdapterEvent - Enumerated type the returns the reason why we were interrutped.
15608 +
15609 +Return Value:
15610 +
15611 +    Nothing
15612 +
15613 +--*/
15614 +{
15615 +       PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
15616 +       PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) CommonExtension->MiniPort;
15617 +       ULONG ReturnStatus;
15618 +
15619 +       //cmn_err(CE_WARN, "RxNotifyAdapter %d", AdapterEvent);
15620 +
15621 +    switch (AdapterEvent) {
15622 +        case AdapNormCmdQue:
15623 +
15624 +                       Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_1);
15625 +            break;
15626 +
15627 +        case HostNormRespNotFull:
15628 +
15629 +                       Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_4);
15630 +            break;
15631 +
15632 +        case AdapNormRespQue:
15633 +
15634 +                       Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_2);
15635 +            break;
15636 +
15637 +        case HostNormCmdNotFull:
15638 +
15639 +                       Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_3);
15640 +            break;
15641 +
15642 +        case HostShutdown:
15643 +
15644 +//                     RxSendSynchCommand(AdapterExtension, HOST_CRASHING, 0, 0, 0, 0, &ReturnStatus);
15645 +
15646 +            break;
15647 +
15648 +               case FastIo:
15649 +                       Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_6);
15650 +                       break;
15651 +
15652 +               case AdapPrintfDone:
15653 +                       Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_5);
15654 +                       break;
15655 +
15656 +        default:
15657 +
15658 +                       RxBugCheck(0,0,0);
15659 +            AfaPortPrint("Notify requested with an invalid request 0x%x.\n",AdapterEvent);
15660 +            break;
15661 +    }
15662 +}
15663 +
15664 +AAC_STATUS
15665 +RxSendSynchCommand(
15666 +       PVOID Arg1,
15667 +       ULONG Command,
15668 +       ULONG Parameter1,
15669 +       ULONG Parameter2,
15670 +       ULONG Parameter3,
15671 +       ULONG Parameter4,
15672 +       PULONG  ReturnStatus
15673 +       )
15674 +/*++
15675 +
15676 +Routine Description:
15677 +
15678 +       This routine will send a synchronous comamnd to the adapter and wait for its
15679 +       completion.
15680 +
15681 +Arguments:
15682 +
15683 +       AdapterExtension - Pointer to adapter extension structure.
15684 +       Command - Which command to send
15685 +       Parameter1 - 4  - Parameters for command
15686 +       ReturnStatus - return status from adapter after completion of command
15687 +
15688 +
15689 +Return Value:
15690 +
15691 +       AAC_STATUS
15692 +
15693 +--*/
15694 +{
15695 +       PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) Arg1;
15696 +       ULONG StartTime,EndTime,WaitTime;
15697 +       BOOLEAN CommandSucceeded;
15698 +
15699 +       //cmn_err(CE_WARN, "RxSendSyncCommand");
15700 +       //
15701 +       // Write the Command into Mailbox 0
15702 +       //
15703 +
15704 +       Rx_WRITE_ULONG( AdapterExtension, InboundMailbox0, Command);
15705 +
15706 +       //
15707 +       // Write the parameters into Mailboxes 1 - 4
15708 +       //
15709 +
15710 +       Rx_WRITE_ULONG( AdapterExtension, InboundMailbox1, Parameter1);
15711 +       Rx_WRITE_ULONG( AdapterExtension, InboundMailbox2, Parameter2);
15712 +       Rx_WRITE_ULONG( AdapterExtension, InboundMailbox3, Parameter3);
15713 +       Rx_WRITE_ULONG( AdapterExtension, InboundMailbox4, Parameter4);
15714 +
15715 +       //
15716 +       // Clear the synch command doorbell to start on a clean slate.
15717 +       //
15718 +               
15719 +       Rx_WRITE_ULONG( AdapterExtension, OutboundDoorbellReg, OUTBOUNDDOORBELL_0);
15720 +
15721 +       //
15722 +       // disable doorbell interrupts
15723 +       //
15724 +
15725 +       Rx_WRITE_UCHAR( AdapterExtension, MUnit.OIMR, 
15726 +                                       Rx_READ_UCHAR(AdapterExtension, MUnit.OIMR) | 0x04);
15727 +
15728 +       //
15729 +       // force the completion of the mask register write before issuing the interrupt.
15730 +       //
15731 +
15732 +       Rx_READ_UCHAR ( AdapterExtension, MUnit.OIMR);
15733 +
15734 +       //
15735 +       // Signal that there is a new synch command
15736 +       //
15737 +
15738 +       Rx_WRITE_ULONG( AdapterExtension, InboundDoorbellReg, INBOUNDDOORBELL_0);
15739 +
15740 +       CommandSucceeded = FALSE;
15741 +
15742 +       StartTime = OsGetSeconds();
15743 +       WaitTime = 0;
15744 +
15745 +       while (WaitTime < 30) { // wait up to 30 seconds
15746 +
15747 +               drv_usecwait(5);                                // delay 5 microseconds to let Mon960 get info.
15748 +
15749 +               //
15750 +               // Mon110 will set doorbell0 bit when it has completed the command.
15751 +               //
15752 +
15753 +               if (Rx_READ_ULONG(AdapterExtension, OutboundDoorbellReg) & OUTBOUNDDOORBELL_0) {
15754 +
15755 +                       //
15756 +                       // clear the doorbell.
15757 +                       //
15758 +
15759 +                       Rx_WRITE_ULONG(AdapterExtension, OutboundDoorbellReg, OUTBOUNDDOORBELL_0);
15760 +
15761 +                       CommandSucceeded = TRUE;
15762 +                       break;
15763 +               }
15764 +
15765 +               EndTime = OsGetSeconds();
15766 +               WaitTime = EndTime - StartTime;
15767 +
15768 +       }
15769 +
15770 +       if (CommandSucceeded != TRUE) {
15771 +
15772 +               //
15773 +               // restore interrupt mask even though we timed out
15774 +               //
15775 +
15776 +               Rx_WRITE_UCHAR(AdapterExtension, MUnit.OIMR, 
15777 +                                          Rx_READ_ULONG(AdapterExtension, MUnit.OIMR) & 0xfb);
15778 +
15779 +               return (STATUS_IO_TIMEOUT);
15780 +
15781 +       }
15782 +
15783 +       //
15784 +       // Pull the synch status from Mailbox 0.
15785 +       //
15786 +
15787 +       *ReturnStatus = Rx_READ_ULONG(AdapterExtension, IndexRegs.Mailbox[0]);
15788 +
15789 +       //
15790 +       // Clear the synch command doorbell.
15791 +       //
15792 +               
15793 +       Rx_WRITE_ULONG(AdapterExtension, OutboundDoorbellReg, OUTBOUNDDOORBELL_0);
15794 +
15795 +       //
15796 +       // restore interrupt mask
15797 +       //
15798 +
15799 +       Rx_WRITE_UCHAR(AdapterExtension, MUnit.OIMR, 
15800 +                                  Rx_READ_ULONG(AdapterExtension, MUnit.OIMR) & 0xfb);
15801 +
15802 +       //
15803 +       // Return SUCCESS
15804 +       //
15805 +
15806 +       return (STATUS_SUCCESS);
15807 +
15808 +}
15809 +
15810 +BOOLEAN
15811 +RxSendSynchFib(
15812 +       PVOID Arg1,
15813 +       ULONG FibPhysicalAddress
15814 +       )
15815 +/*++
15816 +
15817 +Routine Description:
15818 +
15819 +       This routine will send a synchronous fib to the adapter and wait for its
15820 +       completion.
15821 +
15822 +Arguments:
15823 +
15824 +       AdapterExtension - Pointer to adapter extension structure.
15825 +       FibPhysicalAddress - Physical address of fib to send.
15826 +
15827 +
15828 +Return Value:
15829 +
15830 +       BOOLEAN
15831 +
15832 +--*/
15833 +{
15834 +       PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
15835 +       PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) CommonExtension->MiniPort;
15836 +       ULONG returnStatus;
15837 +
15838 +       if (RxSendSynchCommand( AdapterExtension,
15839 +                                                   SEND_SYNCHRONOUS_FIB,
15840 +                                                   FibPhysicalAddress,
15841 +                                                   0,
15842 +                                                   0,
15843 +                                                   0,
15844 +                                                   &returnStatus ) != STATUS_SUCCESS ) {
15845 +
15846 +               return (FALSE);
15847 +               
15848 +       }
15849 +       
15850 +       return (TRUE);
15851 +                                                                               
15852 +}
15853 +
15854 +
15855 diff -burN linux-2.4.4/drivers/scsi/aacraid/sap1sup.c linux/drivers/scsi/aacraid/sap1sup.c
15856 --- linux-2.4.4/drivers/scsi/aacraid/sap1sup.c  Wed Dec 31 18:00:00 1969
15857 +++ linux/drivers/scsi/aacraid/sap1sup.c        Mon Apr 30 09:43:34 2001
15858 @@ -0,0 +1,859 @@
15859 +/*++
15860 + * Adaptec aacraid device driver for Linux.
15861 + *
15862 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
15863 + *
15864 + * This program is free software; you can redistribute it and/or modify
15865 + * it under the terms of the GNU General Public License as published by
15866 + * the Free Software Foundation; either version 2, or (at your option)
15867 + * any later version.
15868 + *
15869 + * This program is distributed in the hope that it will be useful,
15870 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
15871 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15872 + * GNU General Public License for more details.
15873 + *
15874 + * You should have received a copy of the GNU General Public License
15875 + * along with this program; see the file COPYING.  If not, write to
15876 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
15877 + *
15878 + * Module Name:
15879 + *  sap1sup.c
15880 + *
15881 + * Abstract: Drawbridge specific support functions
15882 + *
15883 + --*/
15884 +
15885 +static char *ident_sap1 = "aacraid_ident sap1sup.c 1.0.7 2000/10/11 Adaptec, Inc.";
15886 +
15887 +#include "osheaders.h"
15888 +
15889 +
15890 +#include "AacGenericTypes.h"
15891 +
15892 +#include "aac_unix_defs.h"
15893 +
15894 +#include "fsatypes.h"
15895 +#include "comstruc.h"
15896 +#include "fsact.h"
15897 +#include "protocol.h"
15898 +
15899 +#define DEFINE_PCI_IDS
15900 +#include "sap1common.h"
15901 +#include "monkerapi.h"
15902 +
15903 +#include "fsaport.h"
15904 +#include "fsaioctl.h"
15905 +
15906 +
15907 +#include "pcisup.h"
15908 +#include "sap1.h"
15909 +
15910 +#include "port.h"
15911 +
15912 +#include "nodetype.h"
15913 +#include "comsup.h"
15914 +#include "afacomm.h"
15915 +#include "adapter.h"
15916 +
15917 +#define BugCheckFileId                   (FSAFS_BUG_CHECK_CYCLONESUP)
15918 +
15919 +// #define SaBugCheck(A,B,C) { KeBugCheckEx(0x00000AFA, __LINE__, (ULONG)A, (ULONG)B,(ULONG)C ); }
15920 +
15921 +#define SaBugCheck(A, B, C) {  cmn_err(CE_PANIC, "aacdisk : line %s, 0x%x, 0x%x, 0x%x ", __LINE__, A, B, C);  }
15922 +
15923 +#define NUM_TICKS_PER_SECOND (1000 * 1000 * 10) /* time is in 100 nanoseconds */
15924 +
15925 +int MiniPortRevision = Sa_MINIPORT_REVISION;
15926 +
15927 +
15928 +//
15929 +// The list of all the Sa adapter structures
15930 +//
15931 +
15932 +PSa_ADAPTER_EXTENSION  SaAdapterList;
15933 +
15934 +int
15935 +SaInitDevice(
15936 +       IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
15937 +       IN ULONG AdapterNumber,
15938 +       IN ULONG PciBus,
15939 +       IN ULONG PciSlot
15940 +);
15941 +
15942 +BOOLEAN
15943 +SaSendSynchFib(
15944 +       PVOID Arg1,
15945 +       ULONG FibPhysicalAddress
15946 +       );
15947 +
15948 +FSA_USER_VAR   SaUserVars[] = {
15949 +       { "AfaPortPrinting", (PULONG)&AfaPortPrinting, NULL },
15950 +};
15951 +
15952 +
15953 +//
15954 +// Declare private use routines for this modual
15955 +//
15956 +
15957 +
15958 +/*++
15959 +
15960 +Routine Description:
15961 +
15962 +    The Isr routine for fsa Sa based adapter boards.
15963 +
15964 +Arguments:
15965 +
15966 +
15967 +Return Value:
15968 +
15969 +       TRUE - if the interrupt was handled by this isr
15970 +       FALSE - if the interrupt was not handled by this isr
15971 +
15972 +--*/
15973 +u_int
15974 +SaPciIsr (IN PSa_ADAPTER_EXTENSION AdapterExtension)
15975 +{
15976 +               USHORT InterruptStatus, Mask;
15977 +               u_int OurInterrupt = INTR_UNCLAIMED;
15978 +
15979 +       InterruptStatus = Sa_READ_USHORT( AdapterExtension, DoorbellReg_p);
15980 +
15981 +       //
15982 +       // Read mask and invert because drawbridge is reversed.
15983 +       //
15984 +       // This allows us to only service interrupts that have been enabled.
15985 +       //
15986 +
15987 +       Mask = ~(Sa_READ_USHORT( AdapterExtension, SaDbCSR.PRISETIRQMASK));
15988 +
15989 +       // Check to see if this is our interrupt.  If it isn't just return FALSE.
15990 +
15991 +
15992 +       if (InterruptStatus & Mask) {
15993 +
15994 +               OurInterrupt = INTR_CLAIMED;
15995 +
15996 +               if (InterruptStatus & PrintfReady) {
15997 +
15998 +                       ULONG Length, Level;
15999 +                       unsigned char *cp;
16000 +
16001 +                       cp = AdapterExtension->Common->PrintfBufferAddress;
16002 +
16003 +                       //
16004 +                       // The size of the Printbuffer is set in port.c
16005 +                       // There is no variable or define for it
16006 +                       //
16007 +                       if (Length > 255)
16008 +                               Length = 255;
16009 +
16010 +                       if (cp[Length] != 0) {
16011 +                               // cmn_err (CE_NOTE, "byte %d is 0x%x, should be 0", Length, cp[Length]);
16012 +                               cp[Length] = 0;
16013 +                       }
16014 +
16015 +                       if (Level == LOG_HIGH_ERROR)
16016 +                               cmn_err (CE_WARN, "%s:%s", OsGetDeviceName(AdapterExtension), AdapterExtension->Common->PrintfBufferAddress);
16017 +                       else
16018 +                               cmn_err (CE_NOTE, "%s:%s", OsGetDeviceName(AdapterExtension), AdapterExtension->Common->PrintfBufferAddress);
16019 +
16020 +                       bzero (AdapterExtension->Common->PrintfBufferAddress, 256);
16021 +
16022 +                       Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p,PrintfReady); //clear PrintfReady
16023 +
16024 +                       Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,PrintfDone);
16025 +
16026 +               } else if (InterruptStatus & DOORBELL_1) {      // Adapter -> Host Normal Command Ready
16027 +
16028 +                       AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, HostNormCmdQue);
16029 +                       Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p, DOORBELL_1);
16030 +
16031 +               } else if (InterruptStatus & DOORBELL_2) {      // Adapter -> Host Normal Response Ready
16032 +
16033 +                               AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, HostNormRespQue);
16034 +                               Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p,DOORBELL_2);
16035 +
16036 +               } else if (InterruptStatus & DOORBELL_3) {      // Adapter -> Host Normal Command Not Full
16037 +
16038 +                       AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, AdapNormCmdNotFull);
16039 +                       Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p, DOORBELL_3);
16040 +
16041 +               } else if (InterruptStatus & DOORBELL_4) {      // Adapter -> Host Normal Response Not Full
16042 +
16043 +                       AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, AdapNormRespNotFull);
16044 +                       Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p, DOORBELL_4);
16045 +
16046 +               }
16047 +
16048 +       }
16049 +       return(OurInterrupt);
16050 +}
16051 +
16052 +
16053 +/*++
16054 +
16055 +Routine Description:
16056 +
16057 +       This routine will enable the corresponding adapter event to cause an interrupt on 
16058 +       the host.
16059 +
16060 +Arguments:
16061 +
16062 +       AdapterExtension - Which adapter to enable.
16063 +
16064 +       AdapterEvent - Which adapter event.
16065 +
16066 +       AtDeviceIrq - Whether the system is in DEVICE irql
16067 +
16068 +Return Value:
16069 +
16070 +    Nothing.
16071 +
16072 +--*/
16073 +VOID
16074 +SaEnableInterrupt (PVOID Arg1, ADAPTER_EVENT AdapterEvent, BOOLEAN AtDeviceIrq)
16075 +{
16076 +       PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
16077 +       PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) CommonExtension->MiniPort;
16078 +
16079 +       switch (AdapterEvent) {
16080 +
16081 +         case HostNormCmdQue:
16082 +
16083 +               Sa_WRITE_USHORT( AdapterExtension,  SaDbCSR.PRICLEARIRQMASK, DOORBELL_1 );
16084 +
16085 +               break;
16086 +
16087 +         case HostNormRespQue:
16088 +
16089 +               Sa_WRITE_USHORT( AdapterExtension,  SaDbCSR.PRICLEARIRQMASK, DOORBELL_2 );
16090 +
16091 +               break;
16092 +
16093 +      case AdapNormCmdNotFull:
16094 +
16095 +               Sa_WRITE_USHORT( AdapterExtension,  SaDbCSR.PRICLEARIRQMASK, DOORBELL_3 );
16096 +
16097 +               break;
16098 +
16099 +      case AdapNormRespNotFull:
16100 +
16101 +               Sa_WRITE_USHORT( AdapterExtension,  SaDbCSR.PRICLEARIRQMASK, DOORBELL_4 );
16102 +
16103 +               break;
16104 +
16105 +       }
16106 +
16107 +}
16108 +
16109 +
16110 +
16111 +/*++
16112 +
16113 +Routine Description:
16114 +
16115 +       This routine will disable the corresponding adapter event to cause an interrupt on 
16116 +       the host.
16117 +
16118 +Arguments:
16119 +
16120 +       AdapterExtension - Which adapter to enable.
16121 +
16122 +       AdapterEvent - Which adapter event.
16123 +
16124 +       AtDeviceIrq - Whether the system is in DEVICE irql
16125 +
16126 +Return Value:
16127 +
16128 +    Nothing.
16129 +
16130 +--*/
16131 +VOID
16132 +SaDisableInterrupt (PVOID Arg1,        ADAPTER_EVENT AdapterEvent, BOOLEAN AtDeviceIrq)
16133 +{
16134 +       PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
16135 +       PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) CommonExtension->MiniPort;
16136 +
16137 +       switch (AdapterEvent) {
16138 +
16139 +
16140 +         case HostNormCmdQue:
16141 +
16142 +               Sa_WRITE_USHORT( AdapterExtension,  SaDbCSR.PRISETIRQMASK, DOORBELL_1 );
16143 +
16144 +               break;
16145 +
16146 +         case HostNormRespQue:
16147 +
16148 +               Sa_WRITE_USHORT( AdapterExtension,  SaDbCSR.PRISETIRQMASK, DOORBELL_2 );
16149 +
16150 +               break;
16151 +
16152 +      case AdapNormCmdNotFull:
16153 +
16154 +               Sa_WRITE_USHORT( AdapterExtension,  SaDbCSR.PRISETIRQMASK, DOORBELL_3 );
16155 +
16156 +               break;
16157 +
16158 +
16159 +      case AdapNormRespNotFull:
16160 +
16161 +               Sa_WRITE_USHORT( AdapterExtension,  SaDbCSR.PRISETIRQMASK, DOORBELL_4 );
16162 +
16163 +               break;
16164 +
16165 +       }
16166 +
16167 +}
16168 +
16169 +
16170 +SaDetachDevice (IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension)
16171 +{
16172 +       PSa_ADAPTER_EXTENSION AdapterExtension = CommonExtension->MiniPort;
16173 +
16174 +       //
16175 +       // Free the register mapping.
16176 +       //
16177 +
16178 +       OsDetachDevice(AdapterExtension);
16179 +
16180 +       OsFreeMemory( AdapterExtension, sizeof(Sa_ADAPTER_EXTENSION) );
16181 +
16182 +}
16183 +
16184 +
16185 +/*++
16186 +
16187 +Routine Description:
16188 +
16189 +       Scans the PCI bus looking for the Sa card. When found all resources for the
16190 +       device will be allocated and the interrupt vectors and csrs will be allocated and
16191 +       mapped.
16192 +
16193 +       The device_interface in the commregion will be allocated and linked to the comm region.
16194 +
16195 +Arguments:
16196 +
16197 +
16198 +Return Value:
16199 +
16200 +    TRUE - if the device was setup with not problems
16201 +    FALSE - if the device could not be mapped and init successfully
16202 +
16203 +--*/
16204 +int
16205 +SaInitDevice (IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
16206 +                         IN ULONG AdapterNumber, IN ULONG PciBus,
16207 +                         IN ULONG PciSlot)
16208 +{
16209 +       AAC_STATUS Status;
16210 +       PSa_ADAPTER_EXTENSION AdapterExtension = NULL;
16211 +       FSA_NEW_ADAPTER NewAdapter;
16212 +       ULONG StartTime, EndTime, WaitTime;
16213 +       ULONG InitStatus;
16214 +       int instance;
16215 +       char *name;
16216 +
16217 +    AfaPortPrint("In init device.\n");
16218 +
16219 +       CommonExtension->AdapterNumber = AdapterNumber;
16220 +
16221 +       CommonExtension->PciBusNumber = PciBus;
16222 +       CommonExtension->PciSlotNumber = PciSlot;
16223 +
16224 +       AdapterExtension = OsAllocMemory( sizeof(Sa_ADAPTER_EXTENSION), OS_ALLOC_MEM_SLEEP );
16225 +       AdapterExtension->Common = CommonExtension;
16226 +       CommonExtension->MiniPort = AdapterExtension;
16227 +
16228 +       instance = OsGetDeviceInstance(AdapterExtension);
16229 +       name     = OsGetDeviceName(AdapterExtension);
16230 +
16231 +       //
16232 +       // Map in the registers from the adapter, register space 0 is config space,
16233 +       // register space 1 is the memery space.
16234 +       //
16235 +
16236 +       if (OsMapDeviceRegisters(AdapterExtension)){
16237 +               cmn_err(CE_WARN, "%s%d SaInitDevice: failed OsMapDeviceRegisters", name, instance);
16238 +               return(FAILURE);
16239 +       }
16240 +
16241 +
16242 +       //
16243 +       // Check to see if the board failed any self tests.
16244 +       //
16245 +
16246 +       if (Sa_READ_ULONG( AdapterExtension, Mailbox7) & SELF_TEST_FAILED) {
16247 +
16248 +               cmn_err(CE_WARN, "%s%d: adapter self-test failed\n",
16249 +                               name, instance);
16250 +               return(FAILURE);
16251 +       }
16252 +
16253 +       //
16254 +       // Check to see if the board panic'd while booting.
16255 +       //
16256 +
16257 +       if (Sa_READ_ULONG( AdapterExtension, Mailbox7) & KERNEL_PANIC) {
16258 +
16259 +               cmn_err(CE_WARN, "%s%d: adapter kernel panic'd\n",
16260 +                               name, instance);
16261 +               return(FAILURE);
16262 +       }
16263 +
16264 +
16265 +       StartTime = OsGetSeconds();
16266 +       WaitTime = 0;
16267 +
16268 +
16269 +       //
16270 +       //  Wait for the adapter to be up and running. Wait up until 3 minutes.
16271 +       //
16272 +
16273 +       while (!(Sa_READ_ULONG( AdapterExtension, Mailbox7) & KERNEL_UP_AND_RUNNING)) {
16274 +       
16275 +               EndTime = OsGetSeconds();
16276 +
16277 +               WaitTime = EndTime - StartTime;
16278 +
16279 +               if ( WaitTime > (3 * 60) ) {
16280 +
16281 +                       InitStatus = Sa_READ_ULONG( AdapterExtension, Mailbox7) >> 16;
16282 +
16283 +                       cmn_err(CE_WARN, "%s%d: adapter kernel failed to start, init status = %d\n",
16284 +                                       name, instance, InitStatus);
16285 +                       return(FAILURE);
16286 +
16287 +               }
16288 +       }
16289 +
16290 +       if (OsAttachInterrupt(AdapterExtension, SaISR)) {
16291 +               cmn_err(CE_WARN, "%s%d SaInitDevice: failed OsAttachIntterupt", name, instance);
16292 +               return(FAILURE);
16293 +       }
16294 +
16295 +       if (OsAttachDMA(AdapterExtension)) {
16296 +               cmn_err(CE_WARN, "%s%d SaInitDevice: failed OsAttachDMA", name, instance);
16297 +               return(FAILURE);
16298 +       }
16299 +
16300 +
16301 +       //
16302 +       // Fill in the function dispatch table.
16303 +       //
16304 +
16305 +       AdapterExtension->Common->AdapterFuncs.SizeOfFsaPortFuncs = sizeof(FSAPORT_FUNCS);
16306 +       AdapterExtension->Common->AdapterFuncs.AllocateAdapterCommArea = AfaPortAllocateAdapterCommArea;
16307 +       AdapterExtension->Common->AdapterFuncs.FreeAdapterCommArea = AfaPortFreeAdapterCommArea;
16308 +       AdapterExtension->Common->AdapterFuncs.BuildSgMap = AfaPortBuildSgMap;
16309 +       AdapterExtension->Common->AdapterFuncs.FreeDmaResources = AfaPortFreeDmaResources;
16310 +       AdapterExtension->Common->AdapterFuncs.AllocateAndMapFibSpace = AfaPortAllocateAndMapFibSpace;
16311 +       AdapterExtension->Common->AdapterFuncs.UnmapAndFreeFibSpace = AfaPortUnmapAndFreeFibSpace;
16312 +       AdapterExtension->Common->AdapterFuncs.InterruptAdapter = SaInterruptAdapter;
16313 +       AdapterExtension->Common->AdapterFuncs.EnableInterrupt = SaEnableInterrupt;
16314 +       AdapterExtension->Common->AdapterFuncs.DisableInterrupt = SaDisableInterrupt;
16315 +       AdapterExtension->Common->AdapterFuncs.NotifyAdapter = SaNotifyAdapter;
16316 +       AdapterExtension->Common->AdapterFuncs.ResetDevice = SaResetDevice;
16317 +       AdapterExtension->Common->AdapterFuncs.InterruptHost = NULL;
16318 +
16319 +       AdapterExtension->Common->AdapterFuncs.SendSynchFib = SaSendSynchFib;
16320 +
16321 +       NewAdapter.AdapterExtension = CommonExtension;
16322 +       NewAdapter.AdapterFuncs = &AdapterExtension->Common->AdapterFuncs;
16323 +       NewAdapter.AdapterInterruptsBelowDpc = FALSE;
16324 +       NewAdapter.AdapterUserVars = SaUserVars;
16325 +       NewAdapter.AdapterUserVarsSize = sizeof(SaUserVars) / sizeof(FSA_USER_VAR);
16326 +
16327 +       NewAdapter.Dip = CommonExtension->OsDep.dip;
16328 +
16329 +       
16330 +       if ( AfaCommInitNewAdapter( &NewAdapter ) == NULL) {
16331 +                       cmn_err(CE_WARN, "SaInitDevice: AfaCommInitNewAdapter failed\n");
16332 +                       return (FAILURE);
16333 +       };
16334 +
16335 +
16336 +       AdapterExtension->Common->Adapter = NewAdapter.Adapter;
16337 +
16338 +       if (AdapterExtension->Common->Adapter == NULL) {
16339 +
16340 +               AfaPortLogError(AdapterExtension->Common, FAILURE, NULL, 0);
16341 +               cmn_err(CE_WARN, "%s%d SaInitDevice: No Adapter pointer", name, instance);
16342 +
16343 +               return (FAILURE); 
16344 +       }
16345 +
16346 +
16347 +    //
16348 +       // Start any kernel threads needed
16349 +       OsStartKernelThreads(AdapterExtension);
16350 +
16351 +       //
16352 +       // Tell the adapter that all is configure, and it can start accepting requests
16353 +       //
16354 +
16355 +       SaStartAdapter(AdapterExtension);
16356 +
16357 +
16358 +
16359 +       //
16360 +       // Put this adapter into the list of Sa adapters
16361 +       //
16362 +
16363 +       AdapterExtension->Next = SaAdapterList;
16364 +       SaAdapterList = AdapterExtension;
16365 +
16366 +       AdapterExtension->Common->AdapterConfigured = TRUE;
16367 +
16368 +
16369 +#ifdef AACDISK
16370 +       //
16371 +       // Call the disk layer to initialize itself.
16372 +       //
16373 +
16374 +       AfaDiskInitNewAdapter( AdapterExtension->Common->AdapterNumber, AdapterExtension->Common->Adapter );
16375 +#endif
16376 +
16377 +
16378 +init_done:
16379 +
16380 +       AdapterExtension->Common->AdapterPrintfsToScreen = FALSE;
16381 +
16382 +       OsAttachHBA(AdapterExtension);
16383 +
16384 +       return (0);
16385 +
16386 +init_error:
16387 +
16388 +       return (FAILURE);
16389 +}
16390 +
16391 +
16392 +
16393 +VOID
16394 +SaStartAdapter (PSa_ADAPTER_EXTENSION AdapterExtension)
16395 +{
16396 +       ULONG ReturnStatus;
16397 +       LARGE_INTEGER HostTime;
16398 +       ULONG ElapsedSeconds;
16399 +       PADAPTER_INIT_STRUCT InitStruct;
16400 +
16401 +       //
16402 +       // Fill in the remaining pieces of the InitStruct.
16403 +       //
16404 +
16405 +       InitStruct = AdapterExtension->Common->InitStruct;
16406 +
16407 +       InitStruct->HostPhysMemPages = AfaPortGetMaxPhysicalPage(AdapterExtension->Common);
16408 +
16409 +       ElapsedSeconds = OsGetSeconds();
16410 +
16411 +       InitStruct->HostElapsedSeconds = ElapsedSeconds;
16412 +
16413 +       //
16414 +       // Tell the adapter we are back and up and running so it will scan its command
16415 +       // queues and enable our interrupts
16416 +       //
16417 +
16418 +       AdapterExtension->LocalMaskInterruptControl =
16419 +               (PrintfReady | DOORBELL_1 | DOORBELL_2 | DOORBELL_3 | DOORBELL_4);
16420 +
16421 +
16422 +       //
16423 +       // First clear out all interrupts.  Then enable the one's that we can handle.
16424 +       //
16425 +
16426 +       Sa_WRITE_USHORT( AdapterExtension,  SaDbCSR.PRISETIRQMASK, (USHORT) 0xffff );
16427 +       Sa_WRITE_USHORT( AdapterExtension,  SaDbCSR.PRICLEARIRQMASK,
16428 +                                       (PrintfReady | DOORBELL_1 | DOORBELL_2 | DOORBELL_3 | DOORBELL_4) );
16429 +
16430 +       SaSendSynchCommand(AdapterExtension, 
16431 +                          INIT_STRUCT_BASE_ADDRESS, 
16432 +                          (ULONG) AdapterExtension->Common->PhysicalInitStruct,
16433 +                          0,
16434 +                          0,
16435 +                          0,
16436 +                          &ReturnStatus);
16437 +
16438 +}
16439 +
16440 +
16441 +VOID
16442 +SaResetDevice (PVOID Arg1){
16443 +
16444 +}
16445 +
16446 +
16447 +/*++
16448 +
16449 +Routine Description:
16450 +
16451 +       The will cause the adapter to take a break point.
16452 +
16453 +Arguments:
16454 +
16455 +       None
16456 +
16457 +Return Value:
16458 +
16459 +    Nothing
16460 +
16461 +--*/
16462 +VOID
16463 +SaInterruptAdapter (PVOID Arg1)
16464 +{
16465 +       PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
16466 +       PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) CommonExtension->MiniPort;
16467 +
16468 +       ULONG ReturnStatus;
16469 +
16470 +       SaSendSynchCommand(AdapterExtension, 
16471 +                          BREAKPOINT_REQUEST,
16472 +                          0,
16473 +                          0,
16474 +                          0,
16475 +                          0,
16476 +                          &ReturnStatus);
16477 +
16478 +}
16479 +
16480 +
16481 +/*++
16482 +
16483 +Routine Description:
16484 +
16485 +    Will read the adapter CSRs to find the reason the adapter has
16486 +    interrupted us.
16487 +
16488 +Arguments:
16489 +
16490 +    AdapterEvent - Enumerated type the returns the reason why we were interrutped.
16491 +
16492 +Return Value:
16493 +
16494 +    Nothing
16495 +
16496 +--*/
16497 +VOID
16498 +SaNotifyAdapter (PVOID Arg1, IN HOST_2_ADAP_EVENT AdapterEvent)
16499 +{
16500 +       PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
16501 +       PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) CommonExtension->MiniPort;
16502 +       ULONG ReturnStatus;
16503 +
16504 +    switch (AdapterEvent) {
16505 +        case AdapNormCmdQue:
16506 +
16507 +                       Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_1);
16508 +            break;
16509 +
16510 +        case HostNormRespNotFull:
16511 +
16512 +                       Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_4);
16513 +            break;
16514 +
16515 +        case AdapNormRespQue:
16516 +
16517 +                       Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_2);
16518 +            break;
16519 +
16520 +        case HostNormCmdNotFull:
16521 +
16522 +                       Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_3);
16523 +            break;
16524 +
16525 +        case HostShutdown:
16526 +
16527 +//                     SaSendSynchCommand(AdapterExtension, HOST_CRASHING, 0, 0, 0, 0, &ReturnStatus);
16528 +
16529 +            break;
16530 +
16531 +               case FastIo:
16532 +                       Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_6);
16533 +                       break;
16534 +
16535 +               case AdapPrintfDone:
16536 +                       Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_5);
16537 +                       break;
16538 +
16539 +        default:
16540 +
16541 +                       SaBugCheck(0,0,0);
16542 +            AfaPortPrint("Notify requested with an invalid request 0x%x.\n",AdapterEvent);
16543 +            break;
16544 +    }
16545 +}
16546 +
16547 +
16548 +/*++
16549 +
16550 +Routine Description:
16551 +
16552 +       This routine will send a synchronous comamnd to the adapter and wait for its
16553 +       completion.
16554 +
16555 +Arguments:
16556 +
16557 +       AdapterExtension - Pointer to adapter extension structure.
16558 +       Command - Which command to send
16559 +       Parameter1 - 4  - Parameters for command
16560 +       ReturnStatus - return status from adapter after completion of command
16561 +
16562 +
16563 +Return Value:
16564 +
16565 +       AAC_STATUS
16566 +
16567 +--*/
16568 +AAC_STATUS
16569 +SaSendSynchCommand(
16570 +                  PVOID Arg1,
16571 +                  ULONG Command,
16572 +                  ULONG Parameter1,
16573 +                  ULONG Parameter2,
16574 +                  ULONG Parameter3,
16575 +                  ULONG Parameter4,
16576 +                  PULONG       ReturnStatus
16577 +       )
16578 +{
16579 +       PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) Arg1;
16580 +       ULONG StartTime,EndTime,WaitTime;
16581 +       BOOLEAN CommandSucceeded;
16582 +
16583 +       //
16584 +       // Write the Command into Mailbox 0
16585 +       //
16586 +
16587 +       Sa_WRITE_ULONG( AdapterExtension, Mailbox0, Command);
16588 +
16589 +       //
16590 +       // Write the parameters into Mailboxes 1 - 4
16591 +       //
16592 +
16593 +       Sa_WRITE_ULONG( AdapterExtension, Mailbox1, Parameter1);
16594 +       Sa_WRITE_ULONG( AdapterExtension, Mailbox2, Parameter2);
16595 +       Sa_WRITE_ULONG( AdapterExtension, Mailbox3, Parameter3);
16596 +       Sa_WRITE_ULONG( AdapterExtension, Mailbox4, Parameter4);
16597 +
16598 +       //
16599 +       // Clear the synch command doorbell to start on a clean slate.
16600 +       //
16601 +               
16602 +       Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p, DOORBELL_0);
16603 +
16604 +       //
16605 +       // Signal that there is a new synch command
16606 +       //
16607 +
16608 +       Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s, DOORBELL_0);
16609 +
16610 +       CommandSucceeded = FALSE;
16611 +
16612 +       StartTime = OsGetSeconds();
16613 +       WaitTime = 0;
16614 +
16615 +       while (WaitTime < 30) { // wait up to 30 seconds
16616 +
16617 +               drv_usecwait(5);                                // delay 5 microseconds to let Mon960 get info.
16618 +
16619 +               //
16620 +               // Mon110 will set doorbell0 bit when it has completed the command.
16621 +               //
16622 +
16623 +               if( Sa_READ_USHORT( AdapterExtension, DoorbellReg_p) & DOORBELL_0 )  {
16624 +
16625 +                       CommandSucceeded = TRUE;
16626 +                       break;
16627 +               }
16628 +
16629 +               EndTime = OsGetSeconds();
16630 +               WaitTime = EndTime - StartTime;
16631 +
16632 +       }
16633 +
16634 +       if (CommandSucceeded != TRUE) {
16635 +
16636 +               return (STATUS_IO_TIMEOUT);
16637 +
16638 +       }
16639 +
16640 +       //
16641 +       // Clear the synch command doorbell.
16642 +       //
16643 +               
16644 +       Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p, DOORBELL_0);
16645 +
16646 +       //
16647 +       // Pull the synch status from Mailbox 0.
16648 +       //
16649 +
16650 +       *ReturnStatus = Sa_READ_ULONG( AdapterExtension, Mailbox0);
16651 +
16652 +       //
16653 +       // Return SUCCESS
16654 +       //
16655 +
16656 +       return (STATUS_SUCCESS);
16657 +
16658 +}
16659 +
16660 +
16661 +/*++
16662 +
16663 +Routine Description:
16664 +
16665 +       This routine will send a synchronous fib to the adapter and wait for its
16666 +       completion.
16667 +
16668 +Arguments:
16669 +
16670 +       AdapterExtension - Pointer to adapter extension structure.
16671 +       FibPhysicalAddress - Physical address of fib to send.
16672 +
16673 +
16674 +Return Value:
16675 +
16676 +       BOOLEAN
16677 +
16678 +--*/
16679 +BOOLEAN
16680 +SaSendSynchFib (PVOID Arg1, ULONG FibPhysicalAddress)
16681 +{
16682 +       PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
16683 +       PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) CommonExtension->MiniPort;
16684 +       ULONG returnStatus;
16685 +
16686 +       if (SaSendSynchCommand( AdapterExtension,
16687 +                                                   SEND_SYNCHRONOUS_FIB,
16688 +                                                   FibPhysicalAddress,
16689 +                                                   0,
16690 +                                                   0,
16691 +                                                   0,
16692 +                                                   &returnStatus ) != STATUS_SUCCESS ) {
16693 +
16694 +               return (FALSE);
16695 +               
16696 +       }
16697 +       
16698 +       return (TRUE);
16699 +                                                                               
16700 +}
16701 +
16702 +BOOLEAN
16703 +WriteFlash(
16704 +       PVOID AdapterExtension,
16705 +       ULONG *MappedBuffer)
16706 +{
16707 +       return (FALSE);
16708 +}
16709 +
16710 +BOOLEAN
16711 +ReadFlash(
16712 +       PVOID AdapterExtension,
16713 +       ULONG *MappedBuffer)
16714 +{
16715 +       return (FALSE);
16716 +}
16717 +
This page took 1.378158 seconds and 3 git commands to generate.