]> git.pld-linux.org Git - packages/kernel.git/blob - linux-2.4.7-aacraid-20010721.patch
- added CONFIG_PDC202XXX_FORCE, for new ide drivers
[packages/kernel.git] / linux-2.4.7-aacraid-20010721.patch
1 diff -burN linux-2.4.7/MAINTAINERS linux/MAINTAINERS
2 --- linux-2.4.7/MAINTAINERS     Sun Jul 15 18:15:44 2001
3 +++ linux/MAINTAINERS   Sat Jul 21 17:55:13 2001
4 @@ -119,6 +119,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@dell.com
11 +L:     linux-aacraid-devel@dell.com
12 +L:     linux-aacraid-announce@dell.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.7/arch/i386/defconfig linux/arch/i386/defconfig
20 --- linux-2.4.7/arch/i386/defconfig     Mon Jul 16 12:45:15 2001
21 +++ linux/arch/i386/defconfig   Sat Jul 21 17:55:13 2001
22 @@ -284,6 +284,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.7/drivers/scsi/Config.in linux/drivers/scsi/Config.in
31 --- linux-2.4.7/drivers/scsi/Config.in  Thu Jul  5 13:28:16 2001
32 +++ linux/drivers/scsi/Config.in        Sat Jul 21 17:55:13 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.7/drivers/scsi/Makefile linux/drivers/scsi/Makefile
42 --- linux-2.4.7/drivers/scsi/Makefile   Fri May  4 17:16:28 2001
43 +++ linux/drivers/scsi/Makefile Sat Jul 21 17:55:13 2001
44 @@ -70,6 +70,7 @@
45  obj-$(CONFIG_SCSI_AHA152X)     += aha152x.o
46  obj-$(CONFIG_SCSI_AHA1542)     += aha1542.o
47  obj-$(CONFIG_SCSI_AHA1740)     += aha1740.o
48 +obj-$(CONFIG_SCSI_AACRAID)     += aacraid.o
49  ifeq ($(CONFIG_SCSI_AIC7XXX),y)
50  obj-$(CONFIG_SCSI_AIC7XXX)     += aic7xxx/aic7xxx_drv.o
51  endif
52 @@ -193,3 +194,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.7/drivers/scsi/aacraid/ChangeLog linux/drivers/scsi/aacraid/ChangeLog
61 --- linux-2.4.7/drivers/scsi/aacraid/ChangeLog  Wed Dec 31 18:00:00 1969
62 +++ linux/drivers/scsi/aacraid/ChangeLog        Sat Jul 21 17:55:51 2001
63 @@ -0,0 +1,17 @@
64 +2001-07-21  Matt Domsch <Matt_Domsch@dell.com>
65 +* changed __SMP__ to CONFIG_SMP everywhere (really this time)
66 +* Applied read capacity patch
67 +* released patch against 2.4.6
68 +* released patch against 2.4.7
69 +       
70 +2001-07-04  Matt Domsch <Matt_Domsch@dell.com>
71 +* Started with linux-2.4.5-aacraid-043001.patch
72 +* Applied Chris Pascoe's SMP fix patch
73 +* Released patch against 2.4.6
74 +
75 +
76 +2001-04-30  Matt Domsch <Matt_Domsch@dell.com>
77 +* Started with linux-2.4.3-aacraid-030101.patch
78 +* Applied against 2.4.4.
79 +* Added scsi_set_pci_device() call in linit.c
80 +       
81 diff -burN linux-2.4.7/drivers/scsi/aacraid/Makefile linux/drivers/scsi/aacraid/Makefile
82 --- linux-2.4.7/drivers/scsi/aacraid/Makefile   Wed Dec 31 18:00:00 1969
83 +++ linux/drivers/scsi/aacraid/Makefile Sat Jul 21 17:55:13 2001
84 @@ -0,0 +1,169 @@
85 +#
86 +# Makefile aacraid Raid Controller
87 +#
88 +
89 +###############################################################################
90 +### SOURCE FILES DEFINES
91 +###############################################################################
92 +
93 +CFILES_DRIVER=\
94 +       ./aachba.c \
95 +       ./aacid.c \
96 +       ./commctrl.c \
97 +       ./comminit.c \
98 +       ./commsup.c \
99 +       ./dpcsup.c \
100 +       ./linit.c \
101 +       ./osddi.c \
102 +       ./osfuncs.c \
103 +       ./ossup.c \
104 +       ./port.c \
105 +       ./rx.c \
106 +       ./sap1sup.c
107 +
108 +IFILES_DRIVER=\
109 +       ./include/AacGenericTypes.h \
110 +       ./include/aac_unix_defs.h \
111 +       ./include/adapter.h \
112 +       ./include/afacomm.h \
113 +       ./include/aifstruc.h \
114 +       ./include/build_number.h \
115 +       ./include/commdata.h \
116 +       ./include/commerr.h \
117 +       ./include/commfibcontext.h \
118 +       ./include/comprocs.h \
119 +       ./include/comproto.h \
120 +       ./include/comstruc.h \
121 +       ./include/comsup.h \
122 +       ./include/fsact.h \
123 +       ./include/fsafs.h  \
124 +       ./include/fsaioctl.h \
125 +       ./include/fsaport.h \
126 +       ./include/fsatypes.h \
127 +       ./include/linit.h \
128 +       ./include/monkerapi.h \
129 +       ./include/nodetype.h \
130 +       ./include/nvramioctl.h \
131 +       ./include/osheaders.h \
132 +       ./include/ostypes.h \
133 +       ./include/pcisup.h \
134 +       ./include/perfpack.h \
135 +       ./include/port.h \
136 +       ./include/protocol.h \
137 +       ./include/revision.h \
138 +       ./include/rxcommon.h \
139 +       ./include/rx.h \
140 +       ./include/sap1common.h \
141 +       ./include/sap1.h \
142 +       ./include/version.h
143 +
144 +ALL_SOURCE=\
145 +       ${CFILES_DRIVER} \
146 +       ${IFILES_DRIVER} 
147 +
148 +###############################################################################
149 +### OBJECT FILES DEFINES
150 +###############################################################################
151 +
152 +
153 +OFILES_DRIVER=\
154 +       linit.o \
155 +       osfuncs.o \
156 +       osddi.o \
157 +       aachba.o \
158 +       commctrl.o \
159 +       comminit.o \
160 +       commsup.o \
161 +       dpcsup.o \
162 +       ossup.o \
163 +       port.o \
164 +       rx.o \
165 +       sap1sup.o
166 +
167 +TARGET_OFILES= ${OFILES_DRIVER} aacid.o
168 +
169 +###############################################################################
170 +### GENERAL DEFINES
171 +###############################################################################
172 +
173 +#  Remember that we're doing a chdir one level lower, so we need an extra ../
174 +INCS= \
175 +       -I./include \
176 +       -I../../../include -I..
177 +
178 +WARNINGS= -w -Wall -Wno-unused -Wno-switch -Wno-missing-prototypes -Wno-implicit
179 +
180 +
181 +COMMON_FLAGS=\
182 +       -D__KERNEL__=1 -DUNIX -DCVLOCK_USE_SPINLOCK -DLINUX \
183 +       ${INCS} \
184 +       ${WARNINGS}
185 +
186 +AACFLAGS=${CFLAGS} ${COMMON_FLAGS} ${EXTRA_FLAGS}
187 +
188 +###############################################################################
189 +### DO GENERAL STUFF
190 +###############################################################################
191 +
192 +.SUFFIXES:
193 +.SUFFIXES: .c .o .h .a
194 +
195 +all: source ${TARGET_OFILES} aacraid.o
196 +
197 +source: ${ALL_SOURCE}
198 +
199 +clean:
200 +       rm *.o
201 +
202 +###############################################################################
203 +### DRIVER LINKS
204 +###############################################################################
205 +
206 +aacraid.o: source ${TARGET_OFILES}
207 +       ld -r -o $@ $(TARGET_OFILES)
208 +       cp -r aacraid.o ../
209 +
210 +###############################################################################
211 +### SIMPLE COMPILES
212 +###############################################################################
213 +
214 +linit.o: ./linit.c
215 +       $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o linit.o ./linit.c
216 +
217 +aachba.o: ./aachba.c
218 +       $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o aachba.o ./aachba.c
219 +
220 +osddi.o: ./osddi.c
221 +       $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o osddi.o ./osddi.c
222 +
223 +osfuncs.o: ./osfuncs.c
224 +       $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o osfuncs.o ./osfuncs.c
225 +
226 +commctrl.o:  ./commctrl.c
227 +       $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o commctrl.o ./commctrl.c
228 +
229 +comminit.o:  ./comminit.c
230 +       $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o comminit.o ./comminit.c
231 +
232 +commsup.o:  ./commsup.c
233 +       $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o commsup.o ./commsup.c
234 +
235 +dpcsup.o:  ./dpcsup.c
236 +       $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o dpcsup.o ./dpcsup.c
237 +
238 +aacid.o:  ./aacid.c
239 +       $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o aacid.o ./aacid.c
240 +
241 +port.o:  ./port.c
242 +       $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o port.o ./port.c
243 +
244 +ossup.o:  ./ossup.c
245 +       $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o ossup.o ./ossup.c
246 +
247 +rx.o:  ./rx.c
248 +       $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o rx.o ./rx.c
249 +
250 +sap1sup.o: ./sap1sup.c
251 +       $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o sap1sup.o ./sap1sup.c
252 +
253 +
254 diff -burN linux-2.4.7/drivers/scsi/aacraid/README linux/drivers/scsi/aacraid/README
255 --- linux-2.4.7/drivers/scsi/aacraid/README     Wed Dec 31 18:00:00 1969
256 +++ linux/drivers/scsi/aacraid/README   Sat Jul 21 17:55:13 2001
257 @@ -0,0 +1,46 @@
258 +                               AACRAID Driver for Linux
259 +
260 +Introduction
261 +-------------------------
262 +The aacraid driver adds support for Adaptec (http://www.adaptec.com)
263 +OEM based RAID controllers.
264 +
265 +It is important to note the amount of test time the 2.4.x driver
266 +received. Though not a great deal has changed between 2.2 and 2.4
267 +for this version, it has not recevied a great deal of test time.
268 +
269 +A new driver version is in the works and that version will be
270 +submitted to the standard distribution kernel. The previous
271 +2.2 version was submitted but rejected due to the large
272 +amount of code reduncdancy and NTisms. This driver was
273 +initially ported from NT to Solaris and then to Linux.
274 +
275 +The new version is being written on Unix for Unix and
276 +should be much easier to read and a great deal cleaner.
277 +
278 +Supported Cards/Chipsets
279 +-------------------------
280 +       Dell Computer Corporation PERC 2 Quad Channel
281 +       Dell Computer Corporation PERC 2/Si
282 +       Dell Computer Corporation PERC 3/Si
283 +       Dell Computer Corporation PERC 3/Di
284 +       HP NetRAID-4M
285 +
286 +Not Supported Devices
287 +-------------------------
288 +       Any and All Adaptec branded raid controllers.
289 +
290 +People
291 +-------------------------
292 +       Adaptec Unix OEM Product Group
293 +
294 +Mailing List
295 +-------------------------
296 +please see http://domsch.com/linux for information
297 +on mailing lists. There is both a development and
298 +an announcment list. Due to the overwhelming amount
299 +of mail I receive about this driver, I can not
300 +answer questions individually and requests should
301 +be directed to the list server. Thanks.
302 +
303 +Modified by Brian Boerner February 2001
304 diff -burN linux-2.4.7/drivers/scsi/aacraid/aachba.c linux/drivers/scsi/aacraid/aachba.c
305 --- linux-2.4.7/drivers/scsi/aacraid/aachba.c   Wed Dec 31 18:00:00 1969
306 +++ linux/drivers/scsi/aacraid/aachba.c Sat Jul 21 17:55:13 2001
307 @@ -0,0 +1,1897 @@
308 +/*++
309 + * Adaptec aacraid device driver for Linux.
310 + *
311 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
312 + *
313 + * This program is free software; you can redistribute it and/or modify
314 + * it under the terms of the GNU General Public License as published by
315 + * the Free Software Foundation; either version 2, or (at your option)
316 + * any later version.
317 + *
318 + * This program is distributed in the hope that it will be useful,
319 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
320 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
321 + * GNU General Public License for more details.
322 + *
323 + * You should have received a copy of the GNU General Public License
324 + * along with this program; see the file COPYING.  If not, write to
325 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
326 + *
327 + * Module Name:
328 + *   aachba.c
329 + *
330 + * Abstract: driver...
331 + *
332 +--*/
333 +
334 +static char *ident_aachba = "aacraid_ident aachba.c 1.0.6 2000/10/09 Adaptec, Inc.";
335 +
336 +/*------------------------------------------------------------------------------
337 + *              I N C L U D E S
338 + *----------------------------------------------------------------------------*/
339 +#include "osheaders.h"
340 +#include "AacGenericTypes.h"
341 +#include "aac_unix_defs.h"
342 +#include "comstruc.h"
343 +#include "monkerapi.h"
344 +#include "protocol.h"
345 +#include "fsafs.h"
346 +#include "fsact.h"
347 +#include "fsaioctl.h"
348 +
349 +#include "sap1common.h"
350 +#include "fsaport.h"
351 +#include "pcisup.h"
352 +#include "sap1.h"
353 +#include "nodetype.h"
354 +#include "comsup.h"
355 +#include "afacomm.h"
356 +#include "adapter.h"
357 +
358 +/*------------------------------------------------------------------------------
359 + *              D E F I N E S
360 + *----------------------------------------------------------------------------*/
361 +/*     SCSI Commands */
362 +#define        SS_TEST                 0x00    /* Test unit ready */
363 +#define SS_REZERO              0x01    /* Rezero unit */
364 +#define        SS_REQSEN               0x03    /* Request Sense */
365 +#define SS_REASGN              0x07    /* Reassign blocks */
366 +#define        SS_READ                 0x08    /* Read 6   */
367 +#define        SS_WRITE                0x0A    /* Write 6  */
368 +#define        SS_INQUIR               0x12    /* inquiry */
369 +#define        SS_ST_SP                0x1B    /* Start/Stop unit */
370 +#define        SS_LOCK                 0x1E    /* prevent/allow medium removal */
371 +#define SS_RESERV              0x16    /* Reserve */
372 +#define SS_RELES               0x17    /* Release */
373 +#define SS_MODESEN             0x1A    /* Mode Sense 6 */
374 +#define        SS_RDCAP                0x25    /* Read Capacity */
375 +#define        SM_READ                 0x28    /* Read 10  */
376 +#define        SM_WRITE                0x2A    /* Write 10 */
377 +#define SS_SEEK                        0x2B    /* Seek */
378 +
379 +/* values for inqd_pdt: Peripheral device type in plain English */
380 +#define        INQD_PDT_DA     0x00    /* Direct-access (DISK) device */
381 +#define        INQD_PDT_PROC   0x03    /* Processor device */
382 +#define        INQD_PDT_CHNGR  0x08    /* Changer (jukebox, scsi2) */
383 +#define        INQD_PDT_COMM   0x09    /* Communication device (scsi2) */
384 +#define        INQD_PDT_NOLUN2 0x1f    /* Unknown Device (scsi2) */
385 +#define        INQD_PDT_NOLUN  0x7f    /* Logical Unit Not Present */
386 +
387 +#define        INQD_PDT_DMASK  0x1F    /* Peripheral Device Type Mask */
388 +#define        INQD_PDT_QMASK  0xE0    /* Peripheral Device Qualifer Mask */
389 +
390 +#define        TARGET_LUN_TO_CONTAINER(Target, Lun)    (((Lun) << 4) | Target)
391 +#define CONTAINER_TO_TARGET(Container)          ((Container) & 0xf)
392 +#define CONTAINER_TO_LUN(Container)             ((Container) >> 4)
393 +
394 +#define MAX_FIB_DATA (sizeof(FIB) - sizeof(FIB_HEADER))
395 +
396 +#define MAX_DRIVER_SG_SEGMENT_COUNT 17
397 +
398 +// ------------------------------------------------------
399 +// Sense keys
400 +//
401 +#define SENKEY_NO_SENSE      0x00 //
402 +#define SENKEY_UNDEFINED     0x01 //
403 +#define SENKEY_NOT_READY     0x02 //
404 +#define SENKEY_MEDIUM_ERR    0x03 //
405 +#define SENKEY_HW_ERR        0x04 //
406 +#define SENKEY_ILLEGAL       0x05 //
407 +#define SENKEY_ATTENTION     0x06 //
408 +#define SENKEY_PROTECTED     0x07 //
409 +#define SENKEY_BLANK         0x08 //
410 +#define SENKEY_V_UNIQUE      0x09 //
411 +#define SENKEY_CPY_ABORT     0x0A //
412 +#define SENKEY_ABORT         0x0B //
413 +#define SENKEY_EQUAL         0x0C //
414 +#define SENKEY_VOL_OVERFLOW  0x0D //
415 +#define SENKEY_MISCOMP       0x0E //
416 +#define SENKEY_RESERVED      0x0F //
417 +
418 +// ------------------------------------------------------
419 +// Sense codes
420 +//
421 +#define SENCODE_NO_SENSE                        0x00
422 +#define SENCODE_END_OF_DATA                     0x00
423 +#define SENCODE_BECOMING_READY                  0x04
424 +#define SENCODE_INIT_CMD_REQUIRED               0x04
425 +#define SENCODE_PARAM_LIST_LENGTH_ERROR         0x1A
426 +#define SENCODE_INVALID_COMMAND                 0x20
427 +#define SENCODE_LBA_OUT_OF_RANGE                0x21
428 +#define SENCODE_INVALID_CDB_FIELD               0x24
429 +#define SENCODE_LUN_NOT_SUPPORTED               0x25
430 +#define SENCODE_INVALID_PARAM_FIELD             0x26
431 +#define SENCODE_PARAM_NOT_SUPPORTED             0x26
432 +#define SENCODE_PARAM_VALUE_INVALID             0x26
433 +#define SENCODE_RESET_OCCURRED                  0x29
434 +#define SENCODE_LUN_NOT_SELF_CONFIGURED_YET     0x3E
435 +#define SENCODE_INQUIRY_DATA_CHANGED            0x3F
436 +#define SENCODE_SAVING_PARAMS_NOT_SUPPORTED     0x39
437 +#define SENCODE_DIAGNOSTIC_FAILURE              0x40
438 +#define SENCODE_INTERNAL_TARGET_FAILURE         0x44
439 +#define SENCODE_INVALID_MESSAGE_ERROR           0x49
440 +#define SENCODE_LUN_FAILED_SELF_CONFIG          0x4c
441 +#define SENCODE_OVERLAPPED_COMMAND              0x4E
442 +
443 +// ------------------------------------------------------
444 +// Additional sense codes
445 +//
446 +#define ASENCODE_NO_SENSE                       0x00
447 +#define ASENCODE_END_OF_DATA                    0x05
448 +#define ASENCODE_BECOMING_READY                 0x01
449 +#define ASENCODE_INIT_CMD_REQUIRED              0x02
450 +#define ASENCODE_PARAM_LIST_LENGTH_ERROR        0x00
451 +#define ASENCODE_INVALID_COMMAND                0x00
452 +#define ASENCODE_LBA_OUT_OF_RANGE               0x00
453 +#define ASENCODE_INVALID_CDB_FIELD              0x00
454 +#define ASENCODE_LUN_NOT_SUPPORTED              0x00
455 +#define ASENCODE_INVALID_PARAM_FIELD            0x00
456 +#define ASENCODE_PARAM_NOT_SUPPORTED            0x01
457 +#define ASENCODE_PARAM_VALUE_INVALID            0x02
458 +#define ASENCODE_RESET_OCCURRED                 0x00
459 +#define ASENCODE_LUN_NOT_SELF_CONFIGURED_YET    0x00
460 +#define ASENCODE_INQUIRY_DATA_CHANGED           0x03
461 +#define ASENCODE_SAVING_PARAMS_NOT_SUPPORTED    0x00
462 +#define ASENCODE_DIAGNOSTIC_FAILURE             0x80
463 +#define ASENCODE_INTERNAL_TARGET_FAILURE        0x00
464 +#define ASENCODE_INVALID_MESSAGE_ERROR          0x00
465 +#define ASENCODE_LUN_FAILED_SELF_CONFIG         0x00
466 +#define ASENCODE_OVERLAPPED_COMMAND             0x00
467 +
468 +#define BYTE0( x ) ( unsigned char )( x )
469 +#define BYTE1( x ) ( unsigned char )( x >> 8  )
470 +#define BYTE2( x ) ( unsigned char )( x >> 16 )
471 +#define BYTE3( x ) ( unsigned char )( x >> 24 )
472 +
473 +/*------------------------------------------------------------------------------
474 + *              S T R U C T S / T Y P E D E F S
475 + *----------------------------------------------------------------------------*/
476 +/* SCSI inquiry data */
477 +struct inquiry_data {
478 +       unchar inqd_pdt;     /* Peripheral qualifier | Peripheral Device Type  */
479 +       unchar inqd_dtq;     /* RMB | Device Type Qualifier  */
480 +       unchar inqd_ver;     /* ISO version | ECMA version | ANSI-approved version */
481 +       unchar inqd_rdf;     /* AENC | TrmIOP | Response data format */
482 +       unchar inqd_len;     /* Additional length (n-4) */
483 +       unchar inqd_pad1[2]; /* Reserved - must be zero */
484 +       unchar inqd_pad2;    /* RelAdr | WBus32 | WBus16 |  Sync  | Linked |Reserved| CmdQue | SftRe */
485 +       unchar inqd_vid[8];  /* Vendor ID */
486 +       unchar inqd_pid[16]; /* Product ID */
487 +       unchar inqd_prl[4];  /* Product Revision Level */
488 +};
489 +
490 +struct sense_data {
491 +       unchar error_code;              // 70h (current errors), 71h(deferred errors)
492 +       unchar valid:1;                 // A valid bit of one indicates that the information 
493 +                                       // field contains valid information as defined in the
494 +                                       // SCSI-2 Standard.
495 +       
496 +       unchar segment_number;  // Only used for COPY, COMPARE, or COPY AND VERIFY 
497 +                               // commands
498 +       
499 +       unchar sense_key:4;             // Sense Key
500 +       unchar reserved:1;
501 +       unchar ILI:1;                   // Incorrect Length Indicator
502 +       unchar EOM:1;                   // End Of Medium - reserved for random access devices
503 +       unchar filemark:1;              // Filemark - reserved for random access devices
504 +       
505 +       unchar information[4];  // for direct-access devices, contains the unsigned 
506 +                               // logical block address or residue associated with 
507 +                               // the sense key 
508 +       unchar add_sense_len;   // number of additional sense bytes to follow this field
509 +       unchar cmnd_info[4];    // not used
510 +       unchar ASC;             // Additional Sense Code
511 +       unchar ASCQ;            // Additional Sense Code Qualifier
512 +       unchar FRUC;            // Field Replaceable Unit Code - not used
513 +       
514 +       unchar bit_ptr:3;       // indicates which byte of the CDB or parameter data
515 +                               // was in error
516 +       unchar BPV:1;           // bit pointer valid (BPV): 1- indicates that 
517 +                               // the bit_ptr field has valid value
518 +       unchar reserved2:2;
519 +       unchar CD:1;            // command data bit: 1- illegal parameter in CDB.
520 +                               //                   0- illegal parameter in data.
521 +       unchar SKSV:1;
522 +       
523 +       unchar field_ptr[2];    // byte of the CDB or parameter data in error
524 +};
525 +
526 +/*------------------------------------------------------------------------------
527 + *              G L O B A L S
528 + *----------------------------------------------------------------------------*/
529 +/*------------------------------------------------------------------------------
530 + *              M O D U L E   G L O B A L S
531 + *----------------------------------------------------------------------------*/
532 +static fsadev_t *g_fsa_dev_array[8];   // SCSI Device Instance Pointers
533 +static struct sense_data g_sense_data[MAXIMUM_NUM_CONTAINERS];
534 +
535 +/*------------------------------------------------------------------------------
536 + *              F U N C T I O N   P R O T O T Y P E S
537 + *----------------------------------------------------------------------------*/
538 +AAC_STATUS AacHba_OpenAdapter( PVOID AdapterArg);
539 +AAC_STATUS AacHba_CloseAdapter( PVOID AdapterArg);
540 +BOOLEAN AacHba_HandleAif( PVOID AdapterArg, PFIB_CONTEXT FibContext);
541 +BOOLEAN AacHba_AdapterDeviceControl ( PVOID AdapterArg, 
542 +       PAFA_IOCTL_CMD IoctlCmdPtr, int * ReturnStatus);
543 +
544 +void AacHba_CompleteScsi( 
545 +       Scsi_Cmnd *scsi_cmnd_ptr );
546 +
547 +void AacHba_CompleteScsiNoLock( 
548 +       Scsi_Cmnd *scsi_cmnd_ptr );
549 +
550 +static void AacHba_ReadCallback( 
551 +       void *Context, 
552 +       PFIB_CONTEXT FibContext, 
553 +       int FibStatus );
554 +
555 +static void AacHba_WriteCallback( 
556 +       void *Context, 
557 +       PFIB_CONTEXT FibContext, 
558 +       int FibStatus );
559 +
560 +int AacHba_DoScsiRead(
561 +       Scsi_Cmnd *scsi_cmnd_ptr,
562 +       int ContainerId,
563 +       int wait );
564 +
565 +int AacHba_DoScsiWrite(
566 +       Scsi_Cmnd *scsi_cmnd_ptr,
567 +       int ContainerId,
568 +       int wait );
569 +
570 +int AacHba_QueryDisk(
571 +       PVOID AdapterArg,               // CommonExtensionPtr
572 +       IN PAFA_IOCTL_CMD IoctlCmdPtr );
573 +
574 +int AacHba_ForceDeleteDisk(
575 +       PVOID AdapterArg,               // CommonExtensionPtr
576 +       IN PAFA_IOCTL_CMD IoctlCmdPtr );
577 +
578 +int AacHba_DeleteDisk(
579 +       PVOID AdapterArg,
580 +       IN PAFA_IOCTL_CMD IoctlCmdPtr );
581 +
582 +void AacHba_DetachAdapter(
583 +       IN PVOID AdapterArg );
584 +
585 +BOOLEAN AacCommDetachAdapter(
586 +       IN PAFA_COMM_ADAPTER Adapter );
587 +
588 +void AacHba_SetSenseData(
589 +       char * sense_buf,
590 +       unchar sense_key,
591 +       unchar sense_code,
592 +       unchar a_sense_code,
593 +       unchar incorrect_length,
594 +       unchar bit_pointer,
595 +       unsigned field_pointer,
596 +       unsigned long residue );
597 +
598 +static void get_sd_devname(
599 +       long disknum, 
600 +       char * buffer);
601 +
602 +// Keep these here for the time being - #REVIEW#
603 +int
604 +AfaCommAdapterDeviceControl (
605 +       IN PVOID AdapterArg,
606 +       IN PAFA_IOCTL_CMD       IoctlCmdPtr
607 +       );
608 +
609 +AAC_STATUS
610 +AfaCommRegisterNewClassDriver(
611 +       IN PAFA_COMM_ADAPTER    Adapter,
612 +       IN PAFA_NEW_CLASS_DRIVER        NewClassDriver,
613 +       OUT PAFA_NEW_CLASS_DRIVER_RESPONSE NewClassDriverResponse
614 +       );
615 +
616 +void
617 +SetInqDataStr (int, void *, int);
618 +/*------------------------------------------------------------------------------
619 + *              F U N C T I O N S
620 + *----------------------------------------------------------------------------*/
621 +
622 +/*------------------------------------------------------------------------------
623 +       AacHba_ClassDriverInit()
624 +
625 +               Setup 'core' class driver to answer ioctl's
626 + *----------------------------------------------------------------------------*/
627 +int AacHba_ClassDriverInit(
628 +       PCI_MINIPORT_COMMON_EXTENSION * CommonExtensionPtr)
629 +/*----------------------------------------------------------------------------*/
630 +{
631 +    AFA_NEW_CLASS_DRIVER                               NewClassDriver;
632 +       AFA_NEW_CLASS_DRIVER_RESPONSE           NewClassDriverResponse;
633 +       PAFA_COMM_ADAPTER                                       Adapter;
634 +
635 +       Adapter = (AFA_COMM_ADAPTER *)CommonExtensionPtr->Adapter;
636 +
637 +       RtlZeroMemory( &NewClassDriver, sizeof( AFA_NEW_CLASS_DRIVER ) );
638 +       
639 +       // ClassDriverExtension is the first argument passed to class driver functions below
640 +       NewClassDriver.ClassDriverExtension = CommonExtensionPtr;
641 +       
642 +       NewClassDriver.OpenAdapter = AacHba_OpenAdapter;
643 +       NewClassDriver.CloseAdapter = AacHba_CloseAdapter;
644 +       NewClassDriver.DeviceControl = AacHba_AdapterDeviceControl;
645 +       NewClassDriver.HandleAif = AacHba_HandleAif;
646 +       AfaCommRegisterNewClassDriver( Adapter, &NewClassDriver, &NewClassDriverResponse );
647 +
648 +       return(0);
649 +}
650 +
651 +
652 +/*------------------------------------------------------------------------------
653 +       AacHba_ProbeContainers()
654 +
655 +               Make a list of all containers in the system.
656 +------------------------------------------------------------------------------*/
657 +int AacHba_ProbeContainers (PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr)
658 +{
659 +       fsadev_t                                                *fsa_dev_ptr;
660 +       int                                                             Index, Status;
661 +       PMNTINFO                                                DiskInfo;
662 +       PMNTINFORESPONSE                                DiskInfoResponse;
663 +       PFIB_CONTEXT                                    FibContext;
664 +       AFA_COMM_ADAPTER                                *Adapter;
665 +       unsigned                                                instance;
666 +       char                            *bufp;
667 +       int                             size;
668 +
669 +
670 +       Adapter = ( AFA_COMM_ADAPTER * )CommonExtensionPtr->Adapter;
671 +       fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
672 +       instance = CommonExtensionPtr->OsDep.scsi_host_ptr->unique_id;
673 +
674 +       if( !( FibContext = Adapter->CommFuncs.AllocateFib( Adapter ) ) )
675 +       {
676 +               cmn_err( CE_WARN, "AacHba_ProbeContainers: AllocateFib failed" );
677 +               return( STATUS_UNSUCCESSFUL );
678 +       }
679 +
680 +    for ( Index = 0; Index < MAXIMUM_NUM_CONTAINERS; Index++ ) 
681 +       {
682 +               Adapter->CommFuncs.InitializeFib( FibContext );
683 +
684 +               DiskInfo = ( PMNTINFO )Adapter->CommFuncs.GetFibData( FibContext );
685 +
686 +               DiskInfo->Command  = VM_NameServe;
687 +               DiskInfo->MntCount = Index;
688 +               DiskInfo->MntType  = FT_FILESYS;
689 +               
690 +               Status =  Adapter->CommFuncs.SendFib(   ContainerCommand,
691 +                                                       FibContext,
692 +                                                       sizeof(MNTINFO),
693 +                                                       FsaNormal,
694 +                                                       TRUE,
695 +                                                       NULL,
696 +                                                       TRUE,
697 +                                                       NULL,
698 +                                                       NULL );
699 +               if ( Status ) 
700 +               {
701 +                       cmn_err( CE_WARN, "ProbeContainers: SendFIb Failed" );
702 +                       break;
703 +               }
704 +
705 +               DiskInfoResponse = ( PMNTINFORESPONSE )Adapter->CommFuncs.GetFibData( FibContext );
706 +               
707 +
708 +               if ( ( DiskInfoResponse->Status == ST_OK ) &&
709 +                       ( DiskInfoResponse->MntTable[0].VolType != CT_NONE ) ) 
710 +               {
711 +
712 +
713 +                       fsa_dev_ptr->ContainerValid[Index] = TRUE;
714 +                       fsa_dev_ptr->ContainerType[Index]  = DiskInfoResponse->MntTable[0].VolType;
715 +                       fsa_dev_ptr->ContainerSize[Index]  = DiskInfoResponse->MntTable[0].Capacity;
716 +
717 +                       if (DiskInfoResponse->MntTable[0].ContentState & FSCS_READONLY)
718 +                               fsa_dev_ptr->ContainerReadOnly[Index] = TRUE;
719 +               }
720 +               
721 +               Adapter->CommFuncs.CompleteFib( FibContext );
722 +
723 +               // If there are no more containers, then stop asking.
724 +               if ((Index + 1) >= DiskInfoResponse->MntRespCount)
725 +                       break;
726 +    } // end for()
727 +
728 +       Adapter->CommFuncs.FreeFib( FibContext );
729 +
730 +       g_fsa_dev_array[instance] = fsa_dev_ptr;
731 +       return( Status );
732 +}
733 +
734 +
735 +/*------------------------------------------------------------------------------
736 +       AacHba_ProbeContainer()
737 +
738 +               Probe a single container.
739 + *----------------------------------------------------------------------------*/
740 +int AacHba_ProbeContainer( 
741 +       PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr,
742 +       int ContainerId )
743 +/*----------------------------------------------------------------------------*/
744 +{
745 +       fsadev_t                                                *fsa_dev_ptr;
746 +    int                                                                Status;
747 +    PMNTINFO                                           DiskInfo;
748 +    PMNTINFORESPONSE                           DiskInfoResponse;
749 +       PFIB_CONTEXT                                    FibContext;
750 +       AFA_COMM_ADAPTER                                *Adapter;
751 +       unsigned                                                instance;
752 +       
753 +       Adapter = ( AFA_COMM_ADAPTER * )CommonExtensionPtr->Adapter;
754 +       fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
755 +       instance = CommonExtensionPtr->OsDep.scsi_host_ptr->unique_id;
756 +
757 +       if( !( FibContext = Adapter->CommFuncs.AllocateFib( Adapter ) ) )
758 +       {
759 +               cmn_err( CE_WARN, "AacHba_ProbeContainers: AllocateFib failed" );
760 +               return( STATUS_UNSUCCESSFUL );
761 +       }
762 +
763 +       Adapter->CommFuncs.InitializeFib( FibContext );
764 +
765 +       DiskInfo = ( PMNTINFO )Adapter->CommFuncs.GetFibData( FibContext );
766 +
767 +       DiskInfo->Command  = VM_NameServe;
768 +       DiskInfo->MntCount = ContainerId;
769 +       DiskInfo->MntType  = FT_FILESYS;
770 +               
771 +       Status =  Adapter->CommFuncs.SendFib (ContainerCommand,
772 +                                             FibContext,
773 +                                             sizeof(MNTINFO),
774 +                                             FsaNormal,
775 +                                             TRUE,
776 +                                             NULL,
777 +                                             TRUE,
778 +                                             NULL,
779 +                                             NULL );
780 +       if ( Status ) 
781 +       {
782 +               cmn_err( CE_WARN, "ProbeContainers: SendFIb Failed" );
783 +               Adapter->CommFuncs.CompleteFib( FibContext );
784 +               Adapter->CommFuncs.FreeFib( FibContext );
785 +               return( Status );
786 +       }
787 +
788 +       DiskInfoResponse = ( PMNTINFORESPONSE )Adapter->CommFuncs.GetFibData( FibContext );
789 +               
790 +
791 +       if ( ( DiskInfoResponse->Status == ST_OK ) &&
792 +               ( DiskInfoResponse->MntTable[0].VolType != CT_NONE ) ) 
793 +       {
794 +
795 +               fsa_dev_ptr->ContainerValid[ContainerId] = TRUE;
796 +               fsa_dev_ptr->ContainerType[ContainerId]  = DiskInfoResponse->MntTable[0].VolType;
797 +               fsa_dev_ptr->ContainerSize[ContainerId]  = DiskInfoResponse->MntTable[0].Capacity;
798 +               if (DiskInfoResponse->MntTable[0].ContentState & FSCS_READONLY)
799 +                       fsa_dev_ptr->ContainerReadOnly[ContainerId] = TRUE;
800 +       }
801 +               
802 +       Adapter->CommFuncs.CompleteFib( FibContext );
803 +       Adapter->CommFuncs.FreeFib( FibContext );
804 +
805 +       return( Status );
806 +}
807 +
808 +
809 +/*------------------------------------------------------------------------------
810 +       AacHba_CompleteScsi()
811 +
812 +               Call SCSI completion routine after acquiring io_request_lock
813 +
814 +       Preconditions:
815 +       Postconditions:
816 + *----------------------------------------------------------------------------*/
817 +void AacHba_CompleteScsi( 
818 +       Scsi_Cmnd *scsi_cmnd_ptr )
819 +{
820 +       unsigned long cpu_flags;
821 +
822 +       spin_lock_irqsave( &io_request_lock, cpu_flags );
823 +       scsi_cmnd_ptr->scsi_done( scsi_cmnd_ptr );
824 +       spin_unlock_irqrestore( &io_request_lock, cpu_flags );
825 +}
826 +
827 +
828 +/*------------------------------------------------------------------------------
829 +       AacHba_CompleteScsiNoLock()
830 +
831 +               Call SCSI completion routine
832 +
833 +       Preconditions:
834 +       Postconditions:
835 + *----------------------------------------------------------------------------*/
836 +void AacHba_CompleteScsiNoLock( 
837 +       Scsi_Cmnd *scsi_cmnd_ptr )
838 +{
839 +       scsi_cmnd_ptr->scsi_done( scsi_cmnd_ptr );
840 +}
841 +
842 +/*------------------------------------------------------------------------------
843 +       AacHba_DoScsiCmd()
844 +
845 +               Process SCSI command
846 +
847 +       Preconditions:
848 +       Postconditions:
849 +               Returns 0 on success, -1 on failure
850 + *----------------------------------------------------------------------------*/
851 +int AacHba_DoScsiCmd(
852 +       Scsi_Cmnd *scsi_cmnd_ptr,
853 +       int wait )
854 +{
855 +       int                     ContainerId = 0;
856 +       fsadev_t        *fsa_dev_ptr;
857 +       PCI_MINIPORT_COMMON_EXTENSION   *CommonExtensionPtr;
858 +       int MiniPortIndex;
859 +
860 +       CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
861 +       MiniPortIndex = CommonExtensionPtr->OsDep.MiniPortIndex;
862 +
863 +       fsa_dev_ptr = g_fsa_dev_array[ scsi_cmnd_ptr->host->unique_id ];
864 +
865 +       // If the bus, target or lun is out of range, return fail
866 +       // Test does not apply to ID 16, the pseudo id for the controller itself.
867 +       if ( scsi_cmnd_ptr->target != scsi_cmnd_ptr->host->this_id ) 
868 +       {
869 +               if( ( scsi_cmnd_ptr->channel > 0 ) ||
870 +                       ( scsi_cmnd_ptr->target > 15 ) || 
871 +                       ( scsi_cmnd_ptr->lun > 7 ) )
872 +               {
873 +                       cmn_err( CE_DEBUG, "The bus, target or lun is out of range = %d, %d, %d",
874 +                               scsi_cmnd_ptr->channel,
875 +                               scsi_cmnd_ptr->target, 
876 +                               scsi_cmnd_ptr->lun );
877 +                       scsi_cmnd_ptr->result = DID_BAD_TARGET << 16;
878 +
879 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
880 +
881 +                       return ( -1 );
882 +               }
883 +
884 +               ContainerId = TARGET_LUN_TO_CONTAINER( scsi_cmnd_ptr->target, scsi_cmnd_ptr->lun );
885 +
886 +
887 +               // If the target container doesn't exist, it may have been newly created
888 +               if( fsa_dev_ptr->ContainerValid[ContainerId] == 0 )
889 +               {       
890 +                       switch( scsi_cmnd_ptr->cmnd[0] )
891 +                       {
892 +                               case SS_INQUIR:
893 +                               case SS_RDCAP:
894 +                               case SS_TEST:
895 +                                       spin_unlock_irq( &io_request_lock );
896 +                                       AacHba_ProbeContainer( CommonExtensionPtr, ContainerId );               
897 +                                       spin_lock_irq( &io_request_lock );
898 +                               default:
899 +                                       break;
900 +                       }
901 +               }
902 +
903 +               // If the target container still doesn't exist, return failure
904 +               if( fsa_dev_ptr->ContainerValid[ContainerId] == 0 )
905 +               {       
906 +
907 +                       scsi_cmnd_ptr->result = DID_BAD_TARGET << 16;
908 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
909 +
910 +                       return ( -1 );
911 +               }
912 +       }
913 +       else    // the command is for the controller itself
914 +               if( ( scsi_cmnd_ptr->cmnd[0] != SS_INQUIR )     && // only INQUIRY & TUR cmnd supported for controller 
915 +                       ( scsi_cmnd_ptr->cmnd[0] != SS_TEST ) )
916 +               {
917 +                       cmn_err( CE_WARN, "Only INQUIRY & TUR command supported for controller, rcvd = 0x%x", 
918 +                               scsi_cmnd_ptr->cmnd[0] );
919 +
920 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
921 +                       
922 +                       AacHba_SetSenseData( (char *)&g_sense_data[ ContainerId ],
923 +                               SENKEY_ILLEGAL, SENCODE_INVALID_COMMAND, ASENCODE_INVALID_COMMAND, 
924 +                               0, 0, 0, 0 );
925 +
926 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
927 +
928 +                       return ( -1 );
929 +               }
930 +
931 +       // Handle commands here that don't really require going out to the adapter
932 +       switch ( scsi_cmnd_ptr->cmnd[0] ) 
933 +       {
934 +               case SS_INQUIR:
935 +               {
936 +                       struct inquiry_data *inq_data_ptr;
937 +               
938 +                       cmn_err( CE_DEBUG, "INQUIRY command, ID: %d", scsi_cmnd_ptr->target );
939 +                       inq_data_ptr = ( struct inquiry_data * )scsi_cmnd_ptr->request_buffer;
940 +                       bzero( inq_data_ptr, sizeof( struct inquiry_data ) );
941 +
942 +                       inq_data_ptr->inqd_ver = 2;             // claim compliance to SCSI-2
943 +
944 +                       inq_data_ptr->inqd_dtq = 0x80;  // set RMB bit to one indicating 
945 +                                                                                       // that the medium is removable
946 +                       inq_data_ptr->inqd_rdf = 2;             // A response data format value of
947 +                                                                                       // two indicates that the data shall 
948 +                                                                                       // be in the format specified in SCSI-2
949 +                       inq_data_ptr->inqd_len = 31;
950 +
951 +                       // Set the Vendor, Product, and Revision Level see: <vendor>.c i.e. aac.c
952 +                       SetInqDataStr(  MiniPortIndex, 
953 +                                                       (void *)(inq_data_ptr->inqd_vid),
954 +                                                       fsa_dev_ptr->ContainerType[ContainerId]);
955 +
956 +                       if ( scsi_cmnd_ptr->target == scsi_cmnd_ptr->host->this_id )
957 +                               inq_data_ptr->inqd_pdt = INQD_PDT_PROC; // Processor device
958 +                       else
959 +                               inq_data_ptr->inqd_pdt = INQD_PDT_DA;   // Direct/random access device
960 +
961 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
962 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
963 +
964 +                       return ( 0 );
965 +               }
966 +
967 +               case SS_RDCAP:
968 +               {
969 +                       int capacity;
970 +                       char *cp;
971 +
972 +                       cmn_err( CE_DEBUG, "READ CAPACITY command" );
973 +                       capacity = fsa_dev_ptr->ContainerSize[ContainerId] - 1;
974 +                       cp = scsi_cmnd_ptr->request_buffer;
975 +                       cp[0] = ( capacity >> 24 ) & 0xff;
976 +                       cp[1] = ( capacity >> 16 ) & 0xff;
977 +                       cp[2] = ( capacity >>  8 ) & 0xff;
978 +                       cp[3] = ( capacity >>  0 ) & 0xff;
979 +                       cp[4] = 0;
980 +                       cp[5] = 0;
981 +                       cp[6] = 2;
982 +                       cp[7] = 0;
983 +       
984 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
985 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
986 +
987 +                       return ( 0 );
988 +               }
989 +
990 +               case SS_MODESEN:
991 +               {
992 +                       char *mode_buf;
993 +
994 +                       cmn_err( CE_DEBUG, "MODE SENSE command" );
995 +                       mode_buf = scsi_cmnd_ptr->request_buffer;
996 +                       mode_buf[0] = 0;        // Mode data length (MSB)
997 +                       mode_buf[1] = 6;        // Mode data length (LSB)
998 +                       mode_buf[2] = 0;        // Medium type - default
999 +                       mode_buf[3] = 0;        // Device-specific param, bit 8: 0/1 = write enabled/protected
1000 +                       mode_buf[4] = 0;        // reserved
1001 +                       mode_buf[5] = 0;        // reserved
1002 +                       mode_buf[6] = 0;        // Block descriptor length (MSB)
1003 +                       mode_buf[7] = 0;        // Block descriptor length (LSB)
1004 +       
1005 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1006 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1007 +
1008 +                       return ( 0 );
1009 +               }
1010 +
1011 +
1012 +               // These commands are all No-Ops
1013 +               case SS_TEST:
1014 +                       cmn_err( CE_DEBUG, "TEST UNIT READY command" );
1015 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1016 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1017 +                       return ( 0 );
1018 +
1019 +               case SS_REQSEN:
1020 +                       cmn_err( CE_DEBUG, "REQUEST SENSE command" );
1021 +
1022 +                       memcpy( scsi_cmnd_ptr->sense_buffer, &g_sense_data[ContainerId],
1023 +                               sizeof( struct sense_data ) );
1024 +                       bzero( &g_sense_data[ContainerId], sizeof( struct sense_data ) );
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_LOCK:
1031 +                       cmn_err(CE_DEBUG, "LOCK command");
1032 +
1033 +                       if( scsi_cmnd_ptr->cmnd[4] )
1034 +                               fsa_dev_ptr->ContainerLocked[ContainerId] = 1;
1035 +                       else
1036 +                               fsa_dev_ptr->ContainerLocked[ContainerId] = 0;
1037 +
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_RESERV:
1043 +                       cmn_err( CE_DEBUG, "RESERVE 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_RELES:
1049 +                       cmn_err( CE_DEBUG, "RELEASE 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_REZERO:
1055 +                       cmn_err( CE_DEBUG, "REZERO 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_REASGN:
1061 +                       cmn_err( CE_DEBUG, "REASSIGN command" );
1062 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1063 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1064 +                       return ( 0 );
1065 +
1066 +               case SS_SEEK:
1067 +                       cmn_err( CE_DEBUG, "SEEK command" );
1068 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1069 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1070 +                       return ( 0 );
1071 +
1072 +               case SS_ST_SP:
1073 +                       cmn_err( CE_DEBUG, "START/STOP command" );
1074 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1075 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1076 +                       return ( 0 );
1077 +       }
1078 +
1079 +       switch ( scsi_cmnd_ptr->cmnd[0] ) 
1080 +       {
1081 +               case SS_READ:
1082 +               case SM_READ:
1083 +                       // Hack to keep track of ordinal number of the device that corresponds
1084 +                       // to a container. Needed to convert containers to /dev/sd device names
1085 +                       fsa_dev_ptr->ContainerDevNo[ContainerId] = 
1086 +                               DEVICE_NR( scsi_cmnd_ptr->request.rq_dev );
1087 +
1088 +                       return( AacHba_DoScsiRead( scsi_cmnd_ptr, ContainerId,  wait ) );
1089 +                       break;
1090 +
1091 +               case SS_WRITE:
1092 +               case SM_WRITE:
1093 +
1094 +                       return( AacHba_DoScsiWrite( scsi_cmnd_ptr, ContainerId,  wait ) );
1095 +                       break;
1096 +       }
1097 +       //
1098 +       // Unhandled commands
1099 +       //
1100 +       cmn_err( CE_WARN, "Unhandled SCSI Command: 0x%x", scsi_cmnd_ptr->cmnd[0] );
1101 +       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1102 +
1103 +       AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1104 +               SENKEY_ILLEGAL, SENCODE_INVALID_COMMAND, ASENCODE_INVALID_COMMAND, 
1105 +               0, 0, 0, 0 );
1106 +
1107 +       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1108 +       return ( -1 );
1109 +}
1110 +
1111 +
1112 +/*------------------------------------------------------------------------------
1113 +       AacHba_DoScsiRead()
1114 +               
1115 +               Handles SCSI READ requests
1116 +
1117 +       Preconditions:
1118 +       Postconditions:
1119 +               Returns 0 on success, -1 on failure
1120 + *----------------------------------------------------------------------------*/
1121 +int AacHba_DoScsiRead(
1122 +       Scsi_Cmnd *scsi_cmnd_ptr,
1123 +       int ContainerId,
1124 +       int wait )
1125 +/*----------------------------------------------------------------------------*/
1126 +{
1127 +       u_long                          lba;
1128 +       u_long                          count;
1129 +       u_long                          byte_count;
1130 +       int                                     Status;
1131 +
1132 +       PBLOCKREAD                      BlockReadDisk;
1133 +       PBLOCKREADRESPONSE      BlockReadResponse;
1134 +       uint16_t                        FibSize;
1135 +       PCI_MINIPORT_COMMON_EXTENSION   *CommonExtension;
1136 +       AFA_COMM_ADAPTER                                *Adapter;
1137 +       PFIB_CONTEXT                                    cmd_fibcontext;
1138 +
1139 +       CommonExtension = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
1140 +       Adapter         = ( AFA_COMM_ADAPTER * )CommonExtension->Adapter;
1141 +
1142 +       // Get block address and transfer length
1143 +       if ( scsi_cmnd_ptr->cmnd[0] == SS_READ ) // 6 byte command
1144 +       {
1145 +               cmn_err( CE_DEBUG, "aachba: received a read(6) command on target %d", ContainerId );
1146 +
1147 +               lba = ( ( scsi_cmnd_ptr->cmnd[1] & 0x1F ) << 16 ) | 
1148 +                       ( scsi_cmnd_ptr->cmnd[2] << 8 ) |
1149 +                       scsi_cmnd_ptr->cmnd[3];
1150 +               count = scsi_cmnd_ptr->cmnd[4];
1151 +
1152 +               if ( count == 0 )
1153 +                       count = 256;
1154 +       } 
1155 +       else 
1156 +       {               
1157 +               cmn_err( CE_DEBUG, "aachba: received a read(10) command on target %d", ContainerId );
1158 +               
1159 +               lba = ( scsi_cmnd_ptr->cmnd[2] << 24 ) | ( scsi_cmnd_ptr->cmnd[3] << 16 ) | 
1160 +                       ( scsi_cmnd_ptr->cmnd[4] << 8 ) | scsi_cmnd_ptr->cmnd[5];
1161 +
1162 +               count = ( scsi_cmnd_ptr->cmnd[7] << 8 ) | scsi_cmnd_ptr->cmnd[8];
1163 +       }       
1164 +       cmn_err( CE_DEBUG, "AacHba_DoScsiRead[cpu %d]: lba = %lu, t = %ld", smp_processor_id(), lba, jiffies );
1165 +
1166 +       //-------------------------------------------------------------------------
1167 +       // Alocate and initialize a Fib
1168 +       //  Setup BlockRead command
1169 +       if( !( cmd_fibcontext = Adapter->CommFuncs.AllocateFib( Adapter ) ) )
1170 +       {
1171 +               cmn_err( CE_WARN, "AacHba_DoScsiRead: AllocateFib failed\n" );
1172 +               scsi_cmnd_ptr->result = DID_ERROR << 16;
1173 +               AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1174 +               return ( -1 );
1175 +       }
1176 +
1177 +    Adapter->CommFuncs.InitializeFib( cmd_fibcontext );
1178 +
1179 +       BlockReadDisk = ( PBLOCKREAD )Adapter->CommFuncs.GetFibData( cmd_fibcontext );
1180 +       BlockReadDisk->Command     = VM_CtBlockRead;
1181 +       BlockReadDisk->ContainerId = ContainerId;
1182 +       BlockReadDisk->BlockNumber = lba;
1183 +       BlockReadDisk->ByteCount   = count * 512;
1184 +       BlockReadDisk->SgMap.SgCount = 1;
1185 +
1186 +       if( BlockReadDisk->ByteCount > ( 64 * 1024 ) )
1187 +       {
1188 +               cmn_err( CE_WARN, "AacHba_DoScsiRead: READ request is larger than 64K" );
1189 +               scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1190 +
1191 +               AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1192 +                               SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD, 
1193 +                               0, 0, 7, 0 );
1194 +
1195 +               goto err_return;
1196 +       }
1197 +
1198 +       //-------------------------------------------------------------------------
1199 +       // Build Scatter/Gather list
1200 +       //
1201 +       if ( scsi_cmnd_ptr->use_sg )    // use scatter/gather list
1202 +       {
1203 +               struct scatterlist *scatterlist_ptr;
1204 +               int segment;
1205 +               
1206 +               scatterlist_ptr = ( struct scatterlist * )scsi_cmnd_ptr->request_buffer;
1207 +
1208 +               byte_count = 0;
1209 +               for( segment = 0; segment< scsi_cmnd_ptr->use_sg; segment++ ) 
1210 +               {
1211 +                       BlockReadDisk->SgMap.SgEntry[segment].SgAddress = 
1212 +                               ( void * )OsVirtToPhys( scatterlist_ptr[segment].address );
1213 +                       BlockReadDisk->SgMap.SgEntry[segment].SgByteCount = 
1214 +                               scatterlist_ptr[segment].length;
1215 +
1216 +#ifdef DEBUG_SGBUFFER
1217 +                       memset( scatterlist_ptr[segment].address, 0xa5, 
1218 +                               scatterlist_ptr[segment].length );
1219 +#endif
1220 +
1221 +                       byte_count += scatterlist_ptr[segment].length;
1222 +                       
1223 +                       if( BlockReadDisk->SgMap.SgEntry[segment].SgByteCount > ( 64 * 1024 ) )
1224 +                       {
1225 +                               cmn_err( CE_WARN, "AacHba_DoScsiRead: Segment byte count is larger than 64K" );
1226 +                               scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1227 +
1228 +                               AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1229 +                                       SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD, 
1230 +                                       0, 0, 7, 0 );
1231 +
1232 +                               goto err_return;
1233 +                       }
1234 +                       /*
1235 +                       cmn_err(CE_DEBUG, "SgEntry[%d].SgAddress = 0x%x, Byte count = 0x%x", 
1236 +                                       segment,
1237 +                                       BlockReadDisk->SgMap.SgEntry[segment].SgAddress,
1238 +                                       BlockReadDisk->SgMap.SgEntry[segment].SgByteCount);
1239 +                       */
1240 +               }
1241 +               BlockReadDisk->SgMap.SgCount = scsi_cmnd_ptr->use_sg;
1242 +
1243 +               if( BlockReadDisk->SgMap.SgCount > MAX_DRIVER_SG_SEGMENT_COUNT ) 
1244 +               {
1245 +                       cmn_err( CE_WARN, "AacHba_DoScsiRead: READ request with SgCount > %d", 
1246 +                               MAX_DRIVER_SG_SEGMENT_COUNT );
1247 +                       scsi_cmnd_ptr->result = DID_ERROR << 16;
1248 +                       goto err_return;
1249 +               }
1250 +       }       
1251 +       else            // one piece of contiguous phys mem
1252 +       {
1253 +               BlockReadDisk->SgMap.SgEntry[0].SgAddress = 
1254 +                       ( void * )OsVirtToPhys( scsi_cmnd_ptr->request_buffer );
1255 +               BlockReadDisk->SgMap.SgEntry[0].SgByteCount = scsi_cmnd_ptr->request_bufflen;
1256 +
1257 +               byte_count = scsi_cmnd_ptr->request_bufflen;
1258 +
1259 +               if( BlockReadDisk->SgMap.SgEntry[0].SgByteCount > ( 64 * 1024 ) )
1260 +               {
1261 +                       cmn_err( CE_WARN, "AacHba_DoScsiRead: Single segment byte count is larger than 64K" );
1262 +                       cmn_err( CE_WARN, "AacHba_DoScsiRead: ByteCount: %d", BlockReadDisk->ByteCount);
1263 +                       cmn_err( CE_WARN, "AacHba_DoScsiRead: SG ELEMENTS: %d", scsi_cmnd_ptr->use_sg);
1264 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1265 +
1266 +                       AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1267 +                               SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD, 
1268 +                               0, 0, 7, 0 );
1269 +
1270 +                       goto err_return;
1271 +               }
1272 +       }
1273 +
1274 +       if( byte_count != BlockReadDisk->ByteCount )
1275 +               cmn_err( CE_WARN, "AacHba_DoScsiRead: byte_count != BlockReadDisk->ByteCount" );
1276 +
1277 +       //-------------------------------------------------------------------------
1278 +       // Now send the Fib to the adapter
1279 +       //
1280 +       FibSize = sizeof( BLOCKREAD ) + ( ( BlockReadDisk->SgMap.SgCount - 1 ) * sizeof( SGENTRY ) );
1281 +
1282 +       if( wait ) 
1283 +       {
1284 +               // This path shouldn't ever get executed with the current driver
1285 +               Status = Adapter->CommFuncs.SendFib( ContainerCommand,
1286 +                                                                                        cmd_fibcontext,
1287 +                                                                                        FibSize,
1288 +                                                                                        FsaNormal,
1289 +                                                                                        TRUE,
1290 +                                                                                        NULL,
1291 +                                                                                        TRUE,
1292 +                                                                                        NULL,
1293 +                                                                                        NULL);
1294 +
1295 +               BlockReadResponse = ( PBLOCKREADRESPONSE )
1296 +                       Adapter->CommFuncs.GetFibData( cmd_fibcontext );        
1297 +
1298 +               Adapter->CommFuncs.CompleteFib( cmd_fibcontext );
1299 +               Adapter->CommFuncs.FreeFib( cmd_fibcontext );
1300 +               
1301 +               if( BlockReadResponse->Status != ST_OK )
1302 +               {
1303 +                       cmn_err( CE_WARN, "AacHba_DoScsiRead: BlockReadCommand failed with status: %d", 
1304 +                               BlockReadResponse->Status );
1305 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1306 +
1307 +                       AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1308 +                               SENKEY_HW_ERR, SENCODE_INTERNAL_TARGET_FAILURE, ASENCODE_INTERNAL_TARGET_FAILURE, 
1309 +                               0, 0, 0, 0 );
1310 +
1311 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1312 +                       return ( -1 );
1313 +               }
1314 +               else
1315 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1316 +
1317 +               AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1318 +               return ( 0 );
1319 +       } 
1320 +       else 
1321 +       {
1322 +               Status = Adapter->CommFuncs.SendFib( ContainerCommand,
1323 +                                                                                        cmd_fibcontext,
1324 +                                                                                        FibSize,
1325 +                                                                                        FsaNormal,
1326 +                                                                                        FALSE,
1327 +                                                                                        NULL,
1328 +                                                                                        TRUE,
1329 +                                                                                        ( PFIB_CALLBACK )AacHba_ReadCallback,
1330 +                                                                                        ( void *)scsi_cmnd_ptr );
1331 +
1332 +               // Check that the command queued to the controller
1333 +               if (Status != STATUS_PENDING) { 
1334 +                       cmn_err( CE_WARN, "AacHba_DoScsiRead: SendFib failed with status: %d\n", 
1335 +                                       Status);
1336 +
1337 +                       // For some reason, the Fib didn't queue, return QUEUE_FULL
1338 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | QUEUE_FULL ;
1339 +                       goto err_return;
1340 +               }
1341 +
1342 +               // don't call done func here
1343 +               return ( 0 );
1344 +       }
1345 +
1346 +err_return:
1347 +       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1348 +
1349 +       Adapter->CommFuncs.CompleteFib( cmd_fibcontext );
1350 +       Adapter->CommFuncs.FreeFib( cmd_fibcontext );
1351 +
1352 +       return ( -1 );
1353 +}
1354 +
1355 +
1356 +/*------------------------------------------------------------------------------
1357 +       AacHba_DoScsiWrite()
1358 +
1359 +               Handles SCSI WRITE requests
1360 +       
1361 +       Preconditions:
1362 +       Postconditions:
1363 +               Returns 0 on success, -1 on failure
1364 + *----------------------------------------------------------------------------*/
1365 +int AacHba_DoScsiWrite(
1366 +       Scsi_Cmnd *scsi_cmnd_ptr,
1367 +       int ContainerId,
1368 +       int wait )
1369 +/*----------------------------------------------------------------------------*/
1370 +{
1371 +       u_long                          lba;
1372 +       u_long                          count;
1373 +       u_long                          byte_count;
1374 +       int                                     Status;
1375 +
1376 +       PBLOCKWRITE                                             BlockWriteDisk;
1377 +       PBLOCKWRITERESPONSE                             BlockWriteResponse;
1378 +       uint16_t                                                FibSize;
1379 +       PCI_MINIPORT_COMMON_EXTENSION   *CommonExtension;
1380 +       AFA_COMM_ADAPTER                                *Adapter;
1381 +       PFIB_CONTEXT                                    cmd_fibcontext;
1382 +
1383 +       CommonExtension = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
1384 +       Adapter         = ( AFA_COMM_ADAPTER * )CommonExtension->Adapter;
1385 +
1386 +       // Get block address and transfer length
1387 +       if ( scsi_cmnd_ptr->cmnd[0] == SS_WRITE ) // 6 byte command
1388 +       {
1389 +               lba = ( ( scsi_cmnd_ptr->cmnd[1] & 0x1F ) << 16 ) | 
1390 +                       ( scsi_cmnd_ptr->cmnd[2] << 8 ) |
1391 +                       scsi_cmnd_ptr->cmnd[3];
1392 +               count = scsi_cmnd_ptr->cmnd[4];
1393 +
1394 +               if ( count == 0 )
1395 +                       count = 256;
1396 +       } 
1397 +       else 
1398 +       {               
1399 +               cmn_err( CE_DEBUG, "aachba: received a write(10) command on target %d", ContainerId );
1400 +               
1401 +               lba = ( scsi_cmnd_ptr->cmnd[2] << 24 ) | ( scsi_cmnd_ptr->cmnd[3] << 16 ) | 
1402 +                       ( scsi_cmnd_ptr->cmnd[4] << 8 ) | scsi_cmnd_ptr->cmnd[5];
1403 +
1404 +               count = ( scsi_cmnd_ptr->cmnd[7] << 8 ) | scsi_cmnd_ptr->cmnd[8];
1405 +
1406 +       }       
1407 +       cmn_err( CE_DEBUG, "AacHba_DoScsiWrite[cpu %d]: lba = %lu, t = %ld", smp_processor_id(), lba, jiffies );
1408 +
1409 +       //-------------------------------------------------------------------------
1410 +       // Alocate and initialize a Fib
1411 +       //  Setup BlockWrite command
1412 +       if( !( cmd_fibcontext = Adapter->CommFuncs.AllocateFib( Adapter ) ) ) 
1413 +       {
1414 +               cmn_err( CE_WARN, "AacHba_DoScsiWrite: AllocateFib failed\n" );
1415 +               scsi_cmnd_ptr->result = DID_ERROR << 16;
1416 +               AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1417 +               return ( -1 );
1418 +       }
1419 +
1420 +    Adapter->CommFuncs.InitializeFib( cmd_fibcontext );
1421 +
1422 +       BlockWriteDisk = (PBLOCKWRITE) Adapter->CommFuncs.GetFibData( cmd_fibcontext );
1423 +       BlockWriteDisk->Command     = VM_CtBlockWrite;
1424 +       BlockWriteDisk->ContainerId = ContainerId;
1425 +       BlockWriteDisk->BlockNumber = lba;
1426 +       BlockWriteDisk->ByteCount   = count * 512;
1427 +       BlockWriteDisk->SgMap.SgCount = 1;
1428 +
1429 +
1430 +       if ( BlockWriteDisk->ByteCount > ( 64 * 1024 ) )
1431 +         {
1432 +                 struct scatterlist *scatterlist_ptr;
1433 +                 int segment;
1434 +                 scatterlist_ptr = (struct scatterlist *)scsi_cmnd_ptr->request_buffer;
1435 +
1436 +                 cmn_err( CE_WARN, "\n");
1437 +                 cmn_err( CE_WARN, "AacHba_DoScsiWrite: WRITE request is larger than 64K");
1438 +                 cmn_err( CE_WARN, "AacHba_DoScsiWrite: ByteCount: %d", BlockWriteDisk->ByteCount);
1439 +/*               cmn_err( CE_WARN, "AacHba_DoScsiWrite: SG ELEMENTS: %d", scsi_cmnd_ptr->use_sg); */
1440 +/*               cmn_err( CE_WARN, "Dump SG Element Size..."); */
1441 +/*               for( segment = 0; segment < scsi_cmnd_ptr->use_sg; segment++ )  */
1442 +/*               { */
1443 +/*                       cmn_err (CE_WARN, "SG Segment %d: %d", segment, scatterlist_ptr[segment].length); */
1444 +/*               } */
1445 +/*               cmn_err (CE_WARN, "\n"); */
1446 +
1447 +               scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1448 +
1449 +               AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1450 +                               SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD, 
1451 +                               0, 0, 7, 0 );
1452 +
1453 +               goto err_return;
1454 +       }
1455 +
1456 +       //-------------------------------------------------------------------------
1457 +       // Build Scatter/Gather list
1458 +       //
1459 +       if ( scsi_cmnd_ptr->use_sg )    // use scatter/gather list
1460 +       {
1461 +               struct scatterlist *scatterlist_ptr;
1462 +               int segment;
1463 +               
1464 +               scatterlist_ptr = ( struct scatterlist * )scsi_cmnd_ptr->request_buffer;
1465 +
1466 +               byte_count = 0;
1467 +               for( segment = 0; segment< scsi_cmnd_ptr->use_sg; segment++ ) 
1468 +               {
1469 +                       BlockWriteDisk->SgMap.SgEntry[segment].SgAddress = 
1470 +                               ( HOSTADDRESS )OsVirtToPhys( scatterlist_ptr[segment].address );
1471 +                       BlockWriteDisk->SgMap.SgEntry[segment].SgByteCount = 
1472 +                               scatterlist_ptr[segment].length;
1473 +                       
1474 +                       byte_count += scatterlist_ptr[segment].length;
1475 +
1476 +                       if ( BlockWriteDisk->SgMap.SgEntry[segment].SgByteCount > ( 64 * 1024 ) )
1477 +                       {
1478 +                               cmn_err( CE_WARN, "AacHba_DoScsiWrite: Segment byte count is larger than 64K" );
1479 +                               scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1480 +
1481 +                               AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1482 +                                       SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD, 
1483 +                                       0, 0, 7, 0 );
1484 +
1485 +                               goto err_return;
1486 +                       }
1487 +
1488 +                       /*
1489 +                       cmn_err(CE_DEBUG, "SgEntry[%d].SgAddress = 0x%x, Byte count = 0x%x", 
1490 +                                       segment,
1491 +                                       BlockWriteDisk->SgMap.SgEntry[segment].SgAddress,
1492 +                                       BlockWriteDisk->SgMap.SgEntry[segment].SgByteCount); 
1493 +                       */
1494 +               }
1495 +               BlockWriteDisk->SgMap.SgCount = scsi_cmnd_ptr->use_sg;
1496 +
1497 +               if( BlockWriteDisk->SgMap.SgCount > MAX_DRIVER_SG_SEGMENT_COUNT ) 
1498 +               {
1499 +                       cmn_err( CE_WARN, "AacHba_DoScsiWrite: WRITE request with SgCount > %d", 
1500 +                               MAX_DRIVER_SG_SEGMENT_COUNT );
1501 +                       scsi_cmnd_ptr->result = DID_ERROR << 16;
1502 +                       goto err_return;
1503 +               }
1504 +       } 
1505 +       else            // one piece of contiguous phys mem
1506 +       {
1507 +               BlockWriteDisk->SgMap.SgEntry[0].SgAddress = 
1508 +                       ( HOSTADDRESS )OsVirtToPhys( scsi_cmnd_ptr->request_buffer );
1509 +               BlockWriteDisk->SgMap.SgEntry[0].SgByteCount = scsi_cmnd_ptr->request_bufflen;
1510 +
1511 +               byte_count = scsi_cmnd_ptr->request_bufflen;
1512 +
1513 +               if ( BlockWriteDisk->SgMap.SgEntry[0].SgByteCount > ( 64 * 1024 ) )
1514 +               {
1515 +                       cmn_err( CE_WARN, "AacHba_DoScsiWrite: Single segment byte count is larger than 64K" );
1516 +
1517 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1518 +                       AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1519 +                               SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD, 
1520 +                               0, 0, 7, 0 );
1521 +
1522 +                       goto err_return;
1523 +               }
1524 +       }
1525 +
1526 +       if( byte_count != BlockWriteDisk->ByteCount )
1527 +         cmn_err( CE_WARN, "AacHba_DoScsiWrite: byte_count != BlockReadDisk->ByteCount" );
1528 +
1529 +       //-------------------------------------------------------------------------
1530 +       // Now send the Fib to the adapter
1531 +       //
1532 +       FibSize = sizeof( BLOCKWRITE ) + ( ( BlockWriteDisk->SgMap.SgCount - 1 ) * sizeof( SGENTRY ) );
1533 +
1534 +       if( wait ) 
1535 +       {
1536 +               // This path shouldn't ever get executed with the current driver
1537 +               Status = Adapter->CommFuncs.SendFib( ContainerCommand,
1538 +                                                                                        cmd_fibcontext,
1539 +                                                                                        FibSize,
1540 +                                                                                        FsaNormal,
1541 +                                                                                        TRUE,
1542 +                                                                                        NULL,
1543 +                                                                                        TRUE,
1544 +                                                                                        NULL,
1545 +                                                                                        NULL );
1546 +
1547 +               BlockWriteResponse = ( PBLOCKWRITERESPONSE ) 
1548 +                       Adapter->CommFuncs.GetFibData( cmd_fibcontext );        
1549 +
1550 +               Adapter->CommFuncs.CompleteFib(  cmd_fibcontext );
1551 +               Adapter->CommFuncs.FreeFib(  cmd_fibcontext );
1552 +
1553 +               if( BlockWriteResponse->Status != ST_OK )
1554 +               {
1555 +                       cmn_err( CE_WARN, "AacHba_DoScsiWrite: BlockWriteCommand failed with status: %d\n", 
1556 +                               BlockWriteResponse->Status );
1557 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;;
1558 +                       AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1559 +                               SENKEY_HW_ERR, SENCODE_INTERNAL_TARGET_FAILURE, ASENCODE_INTERNAL_TARGET_FAILURE, 
1560 +                               0, 0, 0, 0 );
1561 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1562 +                       return ( -1 );
1563 +               }
1564 +               else
1565 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1566 +
1567 +               AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1568 +               return ( 0 );
1569 +       } 
1570 +       else 
1571 +       {
1572 +               Status = Adapter->CommFuncs.SendFib( ContainerCommand,
1573 +                                                                                        cmd_fibcontext,
1574 +                                                                                        FibSize,
1575 +                                                                                        FsaNormal,
1576 +                                                                                        FALSE,
1577 +                                                                                        NULL,
1578 +                                                                                        TRUE,
1579 +                                                                                        ( PFIB_CALLBACK )AacHba_WriteCallback,
1580 +                                                                                        ( void * )scsi_cmnd_ptr );
1581 +
1582 +               // Check that the command queued to the controller
1583 +               if (Status != STATUS_PENDING) { 
1584 +                       cmn_err( CE_WARN, "AacHba_DoScsiWrite: SendFib failed with status: %d\n", 
1585 +                                       Status);
1586 +
1587 +                       // For some reason, the Fib didn't queue, return QUEUE_FULL
1588 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | QUEUE_FULL ;
1589 +                       goto err_return;
1590 +               }
1591 +
1592 +               // don't call done func here - it should be called by the WriteCallback
1593 +               return ( 0 );
1594 +       }
1595 +
1596 +err_return:
1597 +       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1598 +
1599 +       Adapter->CommFuncs.CompleteFib( cmd_fibcontext );
1600 +       Adapter->CommFuncs.FreeFib( cmd_fibcontext );
1601 +
1602 +       return ( -1 );
1603 +}
1604 +
1605 +
1606 +/*------------------------------------------------------------------------------
1607 +       AacHba_ReadCallback()
1608 + *----------------------------------------------------------------------------*/
1609 +void AacHba_ReadCallback(  
1610 +       VOID                    *Context,
1611 +       PFIB_CONTEXT    FibContext,
1612 +       int                             FibStatus )
1613 +/*----------------------------------------------------------------------------*/
1614 +{
1615 +       PCI_MINIPORT_COMMON_EXTENSION   *CommonExtension;
1616 +       AFA_COMM_ADAPTER                                *Adapter;
1617 +       BLOCKREADRESPONSE                               *BlockReadResponse;
1618 +       Scsi_Cmnd * scsi_cmnd_ptr;
1619 +       u_long                                                  lba;
1620 +       int                     ContainerId;
1621 +
1622 +       scsi_cmnd_ptr = ( Scsi_Cmnd * )Context;
1623 +
1624 +       CommonExtension = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
1625 +       Adapter         = ( AFA_COMM_ADAPTER * )CommonExtension->Adapter;
1626 +
1627 +       ContainerId = TARGET_LUN_TO_CONTAINER( scsi_cmnd_ptr->target, scsi_cmnd_ptr->lun );
1628 +       
1629 +       lba = ( ( scsi_cmnd_ptr->cmnd[1] & 0x1F ) << 16 ) | 
1630 +                       ( scsi_cmnd_ptr->cmnd[2] << 8 ) |
1631 +                       scsi_cmnd_ptr->cmnd[3];
1632 +       cmn_err( CE_DEBUG, "AacHba_ReadCallback[cpu %d]: lba = %ld, t = %ld", smp_processor_id(), lba, jiffies );
1633 +
1634 +       if( FibContext == 0 ) 
1635 +       {
1636 +               cmn_err( CE_WARN, "AacHba_ReadCallback: no fib context" );
1637 +               scsi_cmnd_ptr->result = DID_ERROR << 16;
1638 +               AacHba_CompleteScsi( scsi_cmnd_ptr );
1639 +               return;
1640 +       }
1641 +
1642 +    BlockReadResponse = ( PBLOCKREADRESPONSE )Adapter->CommFuncs.GetFibData( FibContext );
1643 +
1644 +       if ( BlockReadResponse->Status == ST_OK ) 
1645 +               scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1646 +       else 
1647 +       {
1648 +               cmn_err( CE_WARN, "AacHba_ReadCallback: read failed, status = %d\n", 
1649 +                       BlockReadResponse->Status );
1650 +               scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1651 +               AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1652 +                       SENKEY_HW_ERR, SENCODE_INTERNAL_TARGET_FAILURE, ASENCODE_INTERNAL_TARGET_FAILURE, 
1653 +                       0, 0, 0, 0 );
1654 +       }
1655 +
1656 +#ifdef DEBUG_SGBUFFER
1657 +       if ( scsi_cmnd_ptr->use_sg )    // use scatter/gather list
1658 +       {
1659 +               struct scatterlist *scatterlist_ptr;
1660 +               int i, segment, count;
1661 +               char *ptr;
1662 +               
1663 +               scatterlist_ptr = ( struct scatterlist * )scsi_cmnd_ptr->request_buffer;
1664 +
1665 +               for( segment = 0; segment < scsi_cmnd_ptr->use_sg; segment++ ) 
1666 +               {
1667 +                       count = 0;
1668 +                       ptr = scatterlist_ptr[segment].address;
1669 +                       for( i = 0; i < scatterlist_ptr[segment].length; i++ )
1670 +                       {
1671 +                               if( *( ptr++ ) == 0xa5 )
1672 +                                       count++;
1673 +                       }
1674 +                       if( count == scatterlist_ptr[segment].length )
1675 +                               cmn_err( CE_WARN, "AacHba_ReadCallback: segment %d not filled", segment );
1676 +
1677 +               }
1678 +       }
1679 +#endif
1680 +
1681 +       Adapter->CommFuncs.CompleteFib( FibContext );
1682 +       Adapter->CommFuncs.FreeFib( FibContext );
1683 +
1684 +       AacHba_CompleteScsi( scsi_cmnd_ptr );
1685 +}
1686 +
1687 +/*------------------------------------------------------------------------------
1688 +       AacHba_WriteCallback()
1689 + *----------------------------------------------------------------------------*/
1690 +void AacHba_WriteCallback(  
1691 +       VOID                    *Context,
1692 +       PFIB_CONTEXT    FibContext,
1693 +       int                             FibStatus )
1694 +/*----------------------------------------------------------------------------*/
1695 +{
1696 +       PCI_MINIPORT_COMMON_EXTENSION   *CommonExtension;
1697 +       AFA_COMM_ADAPTER                                *Adapter;
1698 +       BLOCKWRITERESPONSE                              *BlockWriteResponse;
1699 +       Scsi_Cmnd                                               *scsi_cmnd_ptr;
1700 +       u_long                                                  lba;
1701 +       int                     ContainerId;
1702 +
1703 +       scsi_cmnd_ptr = ( Scsi_Cmnd * )Context;
1704 +
1705 +       CommonExtension = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
1706 +       Adapter         = ( AFA_COMM_ADAPTER * )CommonExtension->Adapter;
1707 +       
1708 +       ContainerId = TARGET_LUN_TO_CONTAINER( scsi_cmnd_ptr->target, scsi_cmnd_ptr->lun );
1709 +
1710 +       lba = ( ( scsi_cmnd_ptr->cmnd[1] & 0x1F ) << 16 ) | 
1711 +                       ( scsi_cmnd_ptr->cmnd[2] << 8 ) |
1712 +                       scsi_cmnd_ptr->cmnd[3];
1713 +       cmn_err( CE_DEBUG, "AacHba_WriteCallback[cpu %d]: lba = %ld, t = %ld", smp_processor_id(), lba, jiffies );
1714 +       if( FibContext == 0 ) 
1715 +       {
1716 +               cmn_err( CE_WARN, "AacHba_WriteCallback: no fib context" );
1717 +               scsi_cmnd_ptr->result = DID_ERROR << 16;
1718 +               AacHba_CompleteScsi( scsi_cmnd_ptr );
1719 +               return;
1720 +       }
1721 +
1722 +    BlockWriteResponse = (PBLOCKWRITERESPONSE) Adapter->CommFuncs.GetFibData( FibContext );
1723 +       if (BlockWriteResponse->Status == ST_OK) 
1724 +               scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1725 +       else 
1726 +       {
1727 +               cmn_err( CE_WARN, "AacHba_WriteCallback: write failed, status = %d\n", 
1728 +                       BlockWriteResponse->Status );
1729 +               scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1730 +               AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1731 +                       SENKEY_HW_ERR, SENCODE_INTERNAL_TARGET_FAILURE, ASENCODE_INTERNAL_TARGET_FAILURE, 
1732 +                       0, 0, 0, 0 );
1733 +       }
1734 +
1735 +       Adapter->CommFuncs.CompleteFib( FibContext );
1736 +       Adapter->CommFuncs.FreeFib( FibContext );
1737 +
1738 +       AacHba_CompleteScsi( scsi_cmnd_ptr );
1739 +}
1740 +
1741 +
1742 +/*------------------------------------------------------------------------------
1743 +       AacHba_Ioctl()
1744 +
1745 +               Handle IOCTL requests
1746 +
1747 +       Preconditions:
1748 +       Postconditions:
1749 + *----------------------------------------------------------------------------*/
1750 +int AacHba_Ioctl(
1751 +       PCI_MINIPORT_COMMON_EXTENSION *CommonExtension,
1752 +       int cmd,
1753 +       void * arg )
1754 +/*----------------------------------------------------------------------------*/
1755 +{
1756 +       Sa_ADAPTER_EXTENSION              *AdapterExtension;
1757 +       AFA_IOCTL_CMD IoctlCmd;
1758 +       int status;
1759 +       
1760 +       AdapterExtension = ( Sa_ADAPTER_EXTENSION * )CommonExtension->MiniPort;
1761 +
1762 +       cmn_err( CE_DEBUG, "AacHba_Ioctl, type = %d", cmd );
1763 +       switch( cmd )
1764 +       {
1765 +         case FSACTL_SENDFIB:
1766 +                 cmn_err( CE_DEBUG, "FSACTL_SENDFIB" );
1767 +               break;
1768 +
1769 +         case FSACTL_AIF_THREAD:
1770 +                 cmn_err( CE_DEBUG, "FSACTL_AIF_THREAD" );
1771 +               break;
1772 +
1773 +         case FSACTL_NULL_IO_TEST:
1774 +                 cmn_err( CE_DEBUG, "FSACTL_NULL_IO_TEST" );
1775 +               break;
1776 +
1777 +         case FSACTL_SIM_IO_TEST:
1778 +                 cmn_err( CE_DEBUG, "FSACTL_SIM_IO_TEST" );
1779 +               break;
1780 +
1781 +         case FSACTL_GET_FIBTIMES:
1782 +                 cmn_err( CE_DEBUG, "FSACTL_GET_FIBTIMES" );
1783 +               break;
1784 +
1785 +         case FSACTL_ZERO_FIBTIMES:
1786 +                 cmn_err( CE_DEBUG, "FSACTL_ZERO_FIBTIMES");
1787 +               break;
1788 +
1789 +         case FSACTL_GET_VAR:
1790 +                 cmn_err( CE_DEBUG, "FSACTL_GET_VAR" );
1791 +               break;
1792 +
1793 +         case FSACTL_SET_VAR:
1794 +                 cmn_err( CE_DEBUG, "FSACTL_SET_VAR" );
1795 +               break;
1796 +
1797 +         case FSACTL_OPEN_ADAPTER_CONFIG:
1798 +                 cmn_err( CE_DEBUG, "FSACTL_OPEN_ADAPTER_CONFIG" );
1799 +               break;  
1800 +
1801 +         case FSACTL_CLOSE_ADAPTER_CONFIG:
1802 +                 cmn_err( CE_DEBUG, "FSACTL_CLOSE_ADAPTER_CONFIG" );
1803 +               break;
1804 +
1805 +         case FSACTL_QUERY_ADAPTER_CONFIG:
1806 +                 cmn_err( CE_DEBUG, "FSACTL_QUERY_ADAPTER_CONFIG" );
1807 +               break;
1808 +
1809 +         case FSACTL_OPEN_GET_ADAPTER_FIB:
1810 +                 cmn_err( CE_DEBUG, "FSACTL_OPEN_GET_ADAPTER_FIB" );
1811 +               break;
1812 +
1813 +         case FSACTL_GET_NEXT_ADAPTER_FIB:
1814 +                 cmn_err( CE_DEBUG, "FSACTL_GET_NEXT_ADAPTER_FIB" );
1815 +               break;
1816 +
1817 +         case FSACTL_CLOSE_GET_ADAPTER_FIB:
1818 +                 cmn_err( CE_DEBUG, "FSACTL_CLOSE_GET_ADAPTER_FIB" );
1819 +               break;
1820 +
1821 +         case FSACTL_MINIPORT_REV_CHECK:
1822 +                 cmn_err( CE_DEBUG, "FSACTL_MINIPORT_REV_CHECK" );
1823 +               break;
1824 +
1825 +         case FSACTL_OPENCLS_COMM_PERF_DATA:
1826 +                 cmn_err( CE_DEBUG, "FSACTL_OPENCLS_COMM_PERF_DATA" );
1827 +               break;
1828 +       
1829 +         case FSACTL_GET_COMM_PERF_DATA:
1830 +                 cmn_err( CE_DEBUG, "FSACTL_GET_COMM_PERF_DATA" );
1831 +               break;
1832 +
1833 +         case FSACTL_QUERY_DISK:
1834 +                 cmn_err( CE_DEBUG, "FSACTL_QUERY_DISK" );
1835 +               break;
1836 +               
1837 +         case FSACTL_DELETE_DISK:
1838 +                 cmn_err( CE_DEBUG, "FSACTL_DELETE_DISK" );
1839 +               break;
1840 +
1841 +         default:
1842 +                 cmn_err( CE_DEBUG, "Unknown ioctl: 0x%x", cmd );
1843 +       }
1844 +
1845 +       IoctlCmd.cmd = cmd;
1846 +       IoctlCmd.arg = ( intptr_t )arg;
1847 +       IoctlCmd.flag = 0;
1848 +       IoctlCmd.cred_p = 0;
1849 +       IoctlCmd.rval_p = 0;
1850 +
1851 +       status = AfaCommAdapterDeviceControl( CommonExtension->Adapter, &IoctlCmd );
1852 +       cmn_err( CE_DEBUG, "AAC_Ioctl, completion status = %d", status );
1853 +       return( status );
1854 +}
1855 +
1856 +
1857 +/*------------------------------------------------------------------------------
1858 +       AacHba_AdapterDeviceControl()
1859 +
1860 +       Preconditions:
1861 +       Postconditions:
1862 +               Returns TRUE if ioctl handled, FALSE otherwise
1863 +               *ReturnStatus set to completion status
1864 + *----------------------------------------------------------------------------*/
1865 +BOOLEAN AacHba_AdapterDeviceControl (
1866 +       PVOID AdapterArg,               // CommonExtensionPtr
1867 +       IN PAFA_IOCTL_CMD IoctlCmdPtr,
1868 +       OUT int * ReturnStatus )
1869 +/*----------------------------------------------------------------------------*/
1870 +{
1871 +       BOOLEAN Handled = TRUE; // start out handling it.
1872 +       int Status = EFAULT;
1873 +
1874 +       switch( IoctlCmdPtr->cmd )
1875 +       {
1876 +               case FSACTL_QUERY_DISK:
1877 +                       Status = AacHba_QueryDisk( AdapterArg, IoctlCmdPtr );
1878 +                       break;
1879 +
1880 +               case FSACTL_DELETE_DISK:
1881 +                       Status = AacHba_DeleteDisk( AdapterArg, IoctlCmdPtr );
1882 +                       break;
1883 +
1884 +               case FSACTL_FORCE_DELETE_DISK:
1885 +                       Status = AacHba_ForceDeleteDisk( AdapterArg, IoctlCmdPtr );
1886 +                       break;
1887 +
1888 +               case 2131:
1889 +                       if( AacHba_ProbeContainers( ( PCI_MINIPORT_COMMON_EXTENSION * )AdapterArg ) )
1890 +                               Status = -EFAULT;
1891 +                       break;
1892 +
1893 +               default:
1894 +                       Handled = FALSE;
1895 +                       break;
1896 +       }
1897 +
1898 +       *ReturnStatus = Status;
1899 +
1900 +       return( Handled );
1901 +}
1902 +
1903 +
1904 +/*------------------------------------------------------------------------------
1905 +       AacHba_QueryDisk()
1906 +
1907 +       Postconditions:
1908 +               Return values
1909 +               0       = OK
1910 +               -EFAULT = Bad address
1911 +               -EINVAL = Bad container number
1912 + *----------------------------------------------------------------------------*/
1913 +int AacHba_QueryDisk(
1914 +       PVOID AdapterArg,               // CommonExtensionPtr
1915 +       IN PAFA_IOCTL_CMD IoctlCmdPtr )
1916 +/*----------------------------------------------------------------------------*/
1917 +{
1918 +       UNIX_QUERY_DISK QueryDisk;
1919 +       PCI_MINIPORT_COMMON_EXTENSION   *CommonExtensionPtr;
1920 +       fsadev_t                                                *fsa_dev_ptr;
1921 +
1922 +       CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )AdapterArg;
1923 +       fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
1924 +
1925 +       if( copyin( IoctlCmdPtr->arg, &QueryDisk, sizeof( UNIX_QUERY_DISK ) ) )
1926 +               return( -EFAULT );
1927 +
1928 +       if (QueryDisk.ContainerNumber == -1)
1929 +               QueryDisk.ContainerNumber = TARGET_LUN_TO_CONTAINER( QueryDisk.Target, QueryDisk.Lun );
1930 +       else 
1931 +               if( ( QueryDisk.Bus == -1 ) && ( QueryDisk.Target == -1 ) && ( QueryDisk.Lun == -1 ) )
1932 +               {
1933 +                       if( QueryDisk.ContainerNumber > MAXIMUM_NUM_CONTAINERS )
1934 +                               return( -EINVAL );
1935 +
1936 +                       QueryDisk.Instance = CommonExtensionPtr->OsDep.scsi_host_ptr->host_no;
1937 +                       QueryDisk.Bus = 0;
1938 +                       QueryDisk.Target = CONTAINER_TO_TARGET( QueryDisk.ContainerNumber );
1939 +                       QueryDisk.Lun = CONTAINER_TO_LUN( QueryDisk.ContainerNumber );
1940 +               }
1941 +               else 
1942 +                       return( -EINVAL );
1943 +
1944 +       QueryDisk.Valid = fsa_dev_ptr->ContainerValid[QueryDisk.ContainerNumber];
1945 +       QueryDisk.Locked = fsa_dev_ptr->ContainerLocked[QueryDisk.ContainerNumber];
1946 +       QueryDisk.Deleted = fsa_dev_ptr->ContainerDeleted[QueryDisk.ContainerNumber];
1947 +
1948 +       if( fsa_dev_ptr->ContainerDevNo[QueryDisk.ContainerNumber] == -1 )
1949 +               QueryDisk.UnMapped = TRUE;
1950 +       else
1951 +               QueryDisk.UnMapped = FALSE;
1952 +
1953 +       get_sd_devname( fsa_dev_ptr->ContainerDevNo[QueryDisk.ContainerNumber], 
1954 +               QueryDisk.diskDeviceName );
1955 +
1956 +       if( copyout( &QueryDisk, IoctlCmdPtr->arg, sizeof( UNIX_QUERY_DISK ) ) )
1957 +               return( -EFAULT );
1958 +
1959 +       return( 0 );
1960 +}
1961 +
1962 +
1963 +/*------------------------------------------------------------------------------
1964 +       get_sd_devname()
1965 + *----------------------------------------------------------------------------*/
1966 +static void get_sd_devname(
1967 +       long disknum, 
1968 +       char * buffer)
1969 +/*----------------------------------------------------------------------------*/
1970 +{
1971 +       if( disknum < 0 )
1972 +       {
1973 +        sprintf(buffer, "%s", "");
1974 +               return;
1975 +       }
1976 +
1977 +   if( disknum < 26 )
1978 +        sprintf(buffer, "sd%c", 'a' + disknum);
1979 +    else {
1980 +        unsigned int min1;
1981 +        unsigned int min2;
1982 +        /*
1983 +         * For larger numbers of disks, we need to go to a new
1984 +         * naming scheme.
1985 +         */
1986 +        min1 = disknum / 26;
1987 +        min2 = disknum % 26;
1988 +        sprintf(buffer, "sd%c%c", 'a' + min1 - 1, 'a' + min2);
1989 +    }
1990 +}
1991 +
1992 +
1993 +/*------------------------------------------------------------------------------
1994 +       AacHba_ForceDeleteDisk()
1995 +
1996 +       Postconditions:
1997 +               Return values
1998 +               0       = OK
1999 +               -EFAULT = Bad address
2000 +               -EINVAL = Bad container number
2001 + *----------------------------------------------------------------------------*/
2002 +int AacHba_ForceDeleteDisk(
2003 +       PVOID AdapterArg,               // CommonExtensionPtr
2004 +       IN PAFA_IOCTL_CMD IoctlCmdPtr )
2005 +/*----------------------------------------------------------------------------*/
2006 +{
2007 +       DELETE_DISK      DeleteDisk;
2008 +       PCI_MINIPORT_COMMON_EXTENSION   *CommonExtensionPtr;
2009 +       fsadev_t                                                *fsa_dev_ptr;
2010 +
2011 +       CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )AdapterArg;
2012 +       fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
2013 +
2014 +       if ( copyin( IoctlCmdPtr->arg,  &DeleteDisk, sizeof( DELETE_DISK ) ) )
2015 +               return( -EFAULT );
2016 +
2017 +       if ( DeleteDisk.ContainerNumber > MAXIMUM_NUM_CONTAINERS ) 
2018 +               return( -EINVAL );
2019 +       
2020 +       // Mark this container as being deleted.
2021 +       fsa_dev_ptr->ContainerDeleted[DeleteDisk.ContainerNumber] = TRUE;
2022 +
2023 +       // Mark the container as no longer valid
2024 +       fsa_dev_ptr->ContainerValid[DeleteDisk.ContainerNumber] = 0;
2025 +
2026 +       return( 0 );
2027 +}
2028 +
2029 +
2030 +/*------------------------------------------------------------------------------
2031 +       AacHba_DeleteDisk()
2032 +
2033 +       Postconditions:
2034 +               Return values
2035 +               0       = OK
2036 +               -EFAULT = Bad address
2037 +               -EINVAL = Bad container number
2038 +               -EBUSY  = Device locked
2039 + *----------------------------------------------------------------------------*/
2040 +int AacHba_DeleteDisk(
2041 +       PVOID AdapterArg,
2042 +       IN PAFA_IOCTL_CMD IoctlCmdPtr )
2043 +/*----------------------------------------------------------------------------*/
2044 +{
2045 +       DELETE_DISK DeleteDisk;
2046 +       PCI_MINIPORT_COMMON_EXTENSION   *CommonExtensionPtr;
2047 +       fsadev_t                                                *fsa_dev_ptr;
2048 +
2049 +       CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )AdapterArg;
2050 +       fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
2051 +
2052 +       if( copyin( IoctlCmdPtr->arg, &DeleteDisk, sizeof( DELETE_DISK ) ) ) 
2053 +               return( -EFAULT );
2054 +
2055 +       if( DeleteDisk.ContainerNumber > MAXIMUM_NUM_CONTAINERS )
2056 +               return( -EINVAL );
2057 +       
2058 +       // If the container is locked, it can not be deleted by the API.
2059 +       if( fsa_dev_ptr->ContainerLocked[DeleteDisk.ContainerNumber] )
2060 +               return( -EBUSY );
2061 +       else 
2062 +       {       
2063 +               // Mark the container as no longer being valid.
2064 +               fsa_dev_ptr->ContainerValid[DeleteDisk.ContainerNumber] = 0;
2065 +               fsa_dev_ptr->ContainerDevNo[DeleteDisk.ContainerNumber] = -1;
2066 +               return(0);
2067 +       }       
2068 +}
2069 +
2070 +
2071 +/*------------------------------------------------------------------------------
2072 +       AacHba_OpenAdapter()
2073 + *----------------------------------------------------------------------------*/
2074 +AAC_STATUS AacHba_OpenAdapter(
2075 +       IN PVOID AdapterArg )
2076 +/*----------------------------------------------------------------------------*/
2077 +{
2078 +       return( STATUS_SUCCESS );
2079 +}
2080 +
2081 +
2082 +/*------------------------------------------------------------------------------
2083 +       AacHba_CloseAdapter()
2084 + *----------------------------------------------------------------------------*/
2085 +AAC_STATUS AacHba_CloseAdapter(
2086 +       IN PVOID AdapterArg )
2087 +/*----------------------------------------------------------------------------*/
2088 +{
2089 +       return( STATUS_SUCCESS );
2090 +}
2091 +
2092 +
2093 +/*------------------------------------------------------------------------------
2094 +       AacHba_DetachAdapter()
2095 + *----------------------------------------------------------------------------*/
2096 +void AacHba_DetachAdapter(
2097 +       IN PVOID AdapterArg )
2098 +/*----------------------------------------------------------------------------*/
2099 +{
2100 +       AacCommDetachAdapter( AdapterArg );
2101 +}
2102 +
2103 +
2104 +/*------------------------------------------------------------------------------
2105 +       AacHba_AbortScsiCommand()
2106 + *----------------------------------------------------------------------------*/
2107 +void AacHba_AbortScsiCommand(
2108 +       Scsi_Cmnd *scsi_cmnd_ptr )
2109 +/*----------------------------------------------------------------------------*/
2110 +{
2111 +       u_short interrupt_status;
2112 +       PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
2113 +
2114 +       CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
2115 +       interrupt_status = Sa_READ_USHORT( ( PSa_ADAPTER_EXTENSION )( CommonExtensionPtr->MiniPort ),
2116 +               DoorbellReg_p );
2117 +       cmn_err( CE_WARN, "interrupt_status = %d", interrupt_status );
2118 +       
2119 +       if( interrupt_status & DOORBELL_1) {    // Adapter -> Host Normal Command Ready
2120 +               cmn_err( CE_WARN, "DOORBELL_1: Adapter -> Host Normal Command Ready" );
2121 +       } 
2122 +
2123 +       if( interrupt_status & DOORBELL_2) {    // Adapter -> Host Normal Response Ready
2124 +               cmn_err( CE_WARN, "DOORBELL_2: Adapter -> Host Normal Response Ready" );
2125 +       }
2126 +
2127 +       if ( interrupt_status & DOORBELL_3) {   // Adapter -> Host Normal Command Not Full
2128 +               cmn_err( CE_WARN, "DOORBELL_3: Adapter -> Host Normal Command Not Full" );
2129 +       }
2130 +
2131 +       if ( interrupt_status & DOORBELL_4) {   // Adapter -> Host Normal Response Not Full
2132 +               cmn_err( CE_WARN, "DOORBELL_4: Adapter -> Host Normal Response Not Full" );
2133 +       }
2134 +
2135 +}
2136 +
2137 +
2138 +/*------------------------------------------------------------------------------
2139 +       AacHba_HandleAif()
2140 + *----------------------------------------------------------------------------*/
2141 +BOOLEAN AacHba_HandleAif(
2142 +       IN PVOID AdapterArg,
2143 +       IN PFIB_CONTEXT FibContext )
2144 +/*----------------------------------------------------------------------------*/
2145 +{
2146 +       return( FALSE );
2147 +}
2148 +
2149 +
2150 +/*------------------------------------------------------------------------------
2151 +       AacHba_SetSenseData()
2152 +               Fill in the sense data.
2153 +       Preconditions:
2154 +       Postconditions:
2155 + *----------------------------------------------------------------------------*/
2156 +void AacHba_SetSenseData(
2157 +       char * sense_buf,
2158 +       unchar sense_key,
2159 +       unchar sense_code,
2160 +       unchar a_sense_code,
2161 +       unchar incorrect_length,
2162 +       unchar bit_pointer,
2163 +       unsigned field_pointer,
2164 +       unsigned long residue )
2165 +/*----------------------------------------------------------------------------*/
2166 +{
2167 +       sense_buf[0] = 0xF0;                    // Sense data valid, err code 70h (current error)
2168 +       sense_buf[1] = 0;                                                               // Segment number, always zero
2169 +
2170 +       if( incorrect_length )
2171 +       {
2172 +               sense_buf[2] = sense_key | 0x20;                // Set the ILI bit | sense key
2173 +               sense_buf[3] = BYTE3(residue);
2174 +               sense_buf[4] = BYTE2(residue);
2175 +               sense_buf[5] = BYTE1(residue);
2176 +               sense_buf[6] = BYTE0(residue);
2177 +       }
2178 +       else
2179 +               sense_buf[2] = sense_key;                               // Sense key
2180 +
2181 +       if( sense_key == SENKEY_ILLEGAL )
2182 +               sense_buf[7] = 10;                                              // Additional sense length
2183 +       else
2184 +               sense_buf[7] = 6;                                               // Additional sense length
2185 +
2186 +       sense_buf[12] = sense_code;                             // Additional sense code
2187 +       sense_buf[13] = a_sense_code;                           // Additional sense code qualifier
2188 +       if( sense_key == SENKEY_ILLEGAL )
2189 +       {
2190 +               sense_buf[15] = 0;
2191 +
2192 +               if( sense_code == SENCODE_INVALID_PARAM_FIELD )
2193 +                       sense_buf[15] = 0x80;                           // Std sense key specific field
2194 +                                                                                               // Illegal parameter is in the parameter block
2195 +
2196 +               if( sense_code == SENCODE_INVALID_CDB_FIELD )
2197 +                       sense_buf[15] = 0xc0;                           // Std sense key specific field
2198 +                                                                                               // Illegal parameter is in the CDB block
2199 +               sense_buf[15] |= bit_pointer;
2200 +               sense_buf[16] = field_pointer >> 8;     // MSB
2201 +               sense_buf[17] = field_pointer;          // LSB
2202 +       }
2203 +}
2204 +
2205 diff -burN linux-2.4.7/drivers/scsi/aacraid/aacid.c linux/drivers/scsi/aacraid/aacid.c
2206 --- linux-2.4.7/drivers/scsi/aacraid/aacid.c    Wed Dec 31 18:00:00 1969
2207 +++ linux/drivers/scsi/aacraid/aacid.c  Sat Jul 21 17:55:13 2001
2208 @@ -0,0 +1,153 @@
2209 +/*++
2210 + * Adaptec aacraid device driver for Linux.
2211 + *
2212 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
2213 + *
2214 + * This program is free software; you can redistribute it and/or modify
2215 + * it under the terms of the GNU General Public License as published by
2216 + * the Free Software Foundation; either version 2, or (at your option)
2217 + * any later version.
2218 + *
2219 + * This program is distributed in the hope that it will be useful,
2220 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2221 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
2222 + * GNU General Public License for more details.
2223 + *
2224 + * You should have received a copy of the GNU General Public License
2225 + * along with this program; see the file COPYING.  If not, write to
2226 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
2227 + *
2228 + * Module Name:
2229 + *  aac.c
2230 + *
2231 + * Abstract: Data structures for controller specific info.
2232 + *
2233 +--*/
2234 +
2235 +static char *ident_aacid = "aacraid_ident aacid.c 1.0.6 2000/10/09 Adaptec, Inc.";
2236 +
2237 +#include "osheaders.h"
2238 +
2239 +#include "AacGenericTypes.h"
2240 +
2241 +#include "aac_unix_defs.h"
2242 +
2243 +#include "fsatypes.h"
2244 +#include "comstruc.h"
2245 +#include "fsaport.h"
2246 +#include "pcisup.h"
2247 +
2248 +#include "version.h"
2249 +
2250 +
2251 +/* Function Prototypes */
2252 +void InqStrCopy(char *a, char *b); /* ossup.c */
2253 +
2254 +/* Device name used to register and unregister
2255 +   the device in linit.c */
2256 +char devicestr[]="aac";
2257 +
2258 +char *container_types[] = {
2259 +        "None",
2260 +        "Volume",
2261 +        "Mirror",
2262 +        "Stripe",
2263 +        "RAID5",
2264 +        "SSRW",
2265 +        "SSRO",
2266 +        "Morph",
2267 +        "Legacy",
2268 +        "RAID4",
2269 +        "RAID10",             
2270 +        "RAID00",             
2271 +        "V-MIRRORS",          
2272 +        "PSEUDO R4",          
2273 +       "RAID50",
2274 +        "Unknown"
2275 +};
2276 +
2277 +/* Local Structure to set SCSI inquiry data strings */
2278 +typedef struct _INQSTR {
2279 +  char vid[8];         /* Vendor ID */
2280 +  char pid[16];        /* Product ID */
2281 +  char prl[4];         /* Product Revision Level */
2282 +} INQSTR, *INQSTRP;
2283 +
2284 +FSA_MINIPORT MiniPorts[];
2285 +
2286 +/* Function: SetInqDataStr
2287 + *
2288 + * Arguments: [1] pointer to void [1] int
2289 + *
2290 + * Purpose: Sets SCSI inquiry data strings for vendor, product
2291 + * and revision level. Allows strings to be set in platform dependant
2292 + * files instead of in OS dependant driver source.
2293 + */
2294 +void
2295 +SetInqDataStr (
2296 +  int MiniPortIndex,
2297 +  void *dataPtr,
2298 +  int tindex)
2299 +{
2300 +  INQSTRP InqStrPtr;
2301 +   char *findit;
2302 +   FSA_MINIPORT   *mp;
2303 +
2304 +   mp = &MiniPorts[MiniPortIndex];
2305 +   
2306 +    InqStrPtr = (INQSTRP)(dataPtr); /* cast dataPtr to type INQSTRP */
2307 +
2308 +    InqStrCopy (mp->Vendor, InqStrPtr->vid); 
2309 +    InqStrCopy (mp->Model,  InqStrPtr->pid); /* last six chars reserved for vol type */
2310 +
2311 +    findit = InqStrPtr->pid;
2312 +
2313 +    for ( ; *findit != ' '; findit++); /* walk till we find a space then incr by 1 */
2314 +        findit++;
2315 +       
2316 +    if (tindex < (sizeof(container_types)/sizeof(char *))){
2317 +      InqStrCopy (container_types[tindex], findit);
2318 +    }
2319 +   InqStrCopy ("0001", InqStrPtr->prl);
2320 +}
2321 +
2322 +int
2323 +SaInitDevice(
2324 +       IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
2325 +       IN ULONG AdapterNumber,
2326 +       IN ULONG PciBus,
2327 +       IN ULONG PciSlot
2328 +);
2329 +
2330 +int
2331 +RxInitDevice(
2332 +       IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
2333 +       IN ULONG AdapterNumber,
2334 +       IN ULONG PciBus,
2335 +       IN ULONG PciSlot
2336 +);
2337 +
2338 +
2339 +/*
2340 + * Because of the way Linux names scsi devices, the order in this table has
2341 + * become important.  Check for on-board Raid first, add-in cards second.
2342 + */
2343 +
2344 +FSA_MINIPORT MiniPorts[] = {
2345 +       { 0x1028, 0x0001, 0x1028, 0x0001, "afa", RxInitDevice, "percraid", "DELL    ", "PERCRAID        " }, /* PERC 3/Si */
2346 +       { 0x1028, 0x0002, 0x1028, 0x0002, "afa", RxInitDevice, "percraid", "DELL    ", "PERCRAID        " }, /* PERC 3/Di */
2347 +       { 0x1028, 0x0003, 0x1028, 0x0003, "afa", RxInitDevice, "percraid", "DELL    ", "PERCRAID        " }, /* PERC 3/Si */
2348 +       { 0x1028, 0x0004, 0x1028, 0x00d0, "afa", RxInitDevice, "percraid", "DELL    ", "PERCRAID        " }, /* PERC 3/Si */
2349 +       { 0x1028, 0x0002, 0x1028, 0x00d1, "afa", RxInitDevice, "percraid", "DELL    ", "PERCRAID        " }, /* PERC 3/Di */
2350 +       { 0x1028, 0x0002, 0x1028, 0x00d9, "afa", RxInitDevice, "percraid", "DELL    ", "PERCRAID        " }, /* PERC 3/Di */
2351 +       { 0x1028, 0x000a, 0x1028, 0x0106, "afa", RxInitDevice, "percraid", "DELL    ", "PERCRAID        " }, /* PERC 3/Di */
2352 +       { 0x1011, 0x0046, 0x9005, 0x1364, "afa", SaInitDevice, "percraid", "DELL    ", "PERCRAID        " }, /* Dell PERC2 "Quad Channel */
2353 +       { 0x1011, 0x0046, 0x103c, 0x10c2, "hpn", SaInitDevice, "hpnraid",  "HP      ", "NetRAID-4M      " }  /* HP NetRAID-4M */
2354 +};
2355 +
2356 +
2357 +#define NUM_MINIPORTS  (sizeof(MiniPorts) / sizeof(FSA_MINIPORT))
2358 +
2359 +int NumMiniPorts = NUM_MINIPORTS;
2360 +
2361 +char DescriptionString[] =     "AACxxx Raid Controller" FSA_VERSION_STRING ;
2362 diff -burN linux-2.4.7/drivers/scsi/aacraid/commctrl.c linux/drivers/scsi/aacraid/commctrl.c
2363 --- linux-2.4.7/drivers/scsi/aacraid/commctrl.c Wed Dec 31 18:00:00 1969
2364 +++ linux/drivers/scsi/aacraid/commctrl.c       Sat Jul 21 17:55:13 2001
2365 @@ -0,0 +1,1098 @@
2366 +/*++
2367 + * Adaptec aacraid device driver for Linux.
2368 + *
2369 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
2370 + *
2371 + * This program is free software; you can redistribute it and/or modify
2372 + * it under the terms of the GNU General Public License as published by
2373 + * the Free Software Foundation; either version 2, or (at your option)
2374 + * any later version.
2375 + *
2376 + * This program is distributed in the hope that it will be useful,
2377 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2378 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
2379 + * GNU General Public License for more details.
2380 + *
2381 + * You should have received a copy of the GNU General Public License
2382 + * along with this program; see the file COPYING.  If not, write to
2383 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
2384 + *
2385 + * Module Name:
2386 + *  commctrl.c
2387 + *
2388 + * Abstract: Contains all routines for control of the AFA comm layer
2389 + *
2390 +--*/
2391 +
2392 +static char *ident_commctrl = "aacraid_ident commctrl.c 1.0.7 2000/10/11 Adaptec, Inc.";
2393 +
2394 +#include "comprocs.h"
2395 +#include "osheaders.h"
2396 +#include "ostypes.h"
2397 +
2398 +
2399 +
2400 +
2401 +
2402 +typedef BOOLEAN BOOL;
2403 +#define inline /* _inline */
2404 +
2405 +#include <revision.h>
2406 +AAC_STATUS
2407 +FsaCtlCheckRevision(
2408 +       IN PAFA_COMM_ADAPTER    Adapter,
2409 +       IN PAFA_IOCTL_CMD               IoctlCmdPtr
2410 +       )
2411 +/*++
2412 +
2413 +Routine Description:
2414 +
2415 +       This routine validates the revision of the caller with the current revision
2416 +       of the filesystem.
2417 +
2418 +Arguments:
2419 +
2420 +       Adapter - Supplies which adapter is being processed.
2421 +
2422 +    Irp - Supplies the Irp being processed.
2423 +
2424 +       IrpContext - Supplies the IrpContext.
2425 +
2426 +Return Value:
2427 +
2428 +       AAC_STATUS
2429 +
2430 +--*/
2431 +
2432 +{
2433 +       RevCheck APIRevCheck;
2434 +       RevCheckResp APIRevCheckResp;
2435 +       RevComponent APICallingComponent;
2436 +       ULONG APIBuildNumber;
2437 +
2438 +       if (COPYIN( (caddr_t) IoctlCmdPtr->arg, (caddr_t) &APIRevCheck, sizeof(RevCheck), IoctlCmdPtr->flag )) {
2439 +               return (EFAULT);
2440 +       }
2441 +
2442 +       APICallingComponent = APIRevCheck.callingComponent;
2443 +       APIBuildNumber = APIRevCheck.callingRevision.buildNumber;
2444 +
2445 +       APIRevCheckResp.possiblyCompatible = RevCheckCompatibility( RevMiniportDriver , APICallingComponent, APIBuildNumber );
2446 +
2447 +       APIRevCheckResp.adapterSWRevision.external.ul = RevGetExternalRev();
2448 +       APIRevCheckResp.adapterSWRevision.buildNumber = RevGetBuildNumber();
2449 +
2450 +       if (COPYOUT( (caddr_t) &APIRevCheckResp, (caddr_t) IoctlCmdPtr->arg, sizeof(RevCheckResp), IoctlCmdPtr->flag )) {
2451 +               return (EFAULT);
2452 +       }
2453 +
2454 +       return (0);
2455 +}
2456 +
2457 +
2458 +int
2459 +AfaCommAdapterDeviceControl(
2460 +       IN PVOID AdapterArg,
2461 +       IN PAFA_IOCTL_CMD IoctlCmdPtr
2462 +       )
2463 +{
2464 +       PAFA_COMM_ADAPTER Adapter = (PAFA_COMM_ADAPTER) AdapterArg;
2465 +    int Status = ENOTTY;
2466 +//    PIO_STACK_LOCATION IrpSp;
2467 +       PAFA_CLASS_DRIVER ClassDriver;
2468 +
2469 +       //
2470 +       // First loop through all of the class drivers to give them a chance to handle
2471 +       // the Device control first.
2472 +       //
2473 +
2474 +       ClassDriver = Adapter->ClassDriverList;
2475 +
2476 +       while (ClassDriver) {
2477 +
2478 +               if (ClassDriver->DeviceControl) {
2479 +
2480 +                       if (ClassDriver->DeviceControl( ClassDriver->ClassDriverExtension, IoctlCmdPtr, &Status ) ) {
2481 +
2482 +                               return (Status);
2483 +
2484 +                       }
2485 +               }
2486 +
2487 +               ClassDriver = ClassDriver->Next;
2488 +       }
2489 +
2490 +    switch (IoctlCmdPtr->cmd) {
2491 +
2492 +
2493 +         case FSACTL_SENDFIB:
2494 +
2495 +               Status = AfaCommCtlSendFib( Adapter, IoctlCmdPtr );
2496 +               break;
2497 +
2498 +         case FSACTL_AIF_THREAD:
2499 +
2500 +               Status = AfaCommCtlAifThread( Adapter, IoctlCmdPtr );   
2501 +               break;
2502 +
2503 +
2504 +         case FSACTL_OPEN_GET_ADAPTER_FIB:
2505 +
2506 +               Status = FsaCtlOpenGetAdapterFib( Adapter, IoctlCmdPtr );
2507 +               break;
2508 +
2509 +         case FSACTL_GET_NEXT_ADAPTER_FIB:
2510 +
2511 +               Status = FsaCtlGetNextAdapterFib( Adapter, IoctlCmdPtr );
2512 +               break;
2513 +
2514 +         case FSACTL_CLOSE_GET_ADAPTER_FIB:
2515 +
2516 +               Status = FsaCtlCloseGetAdapterFib( Adapter, IoctlCmdPtr );
2517 +               break;
2518 +
2519 +         case FSACTL_MINIPORT_REV_CHECK:
2520 +        
2521 +               Status = FsaCtlCheckRevision( Adapter , IoctlCmdPtr );
2522 +               break;
2523 +
2524 +
2525 +      default:
2526 +         
2527 +               Status = ENOTTY;
2528 +               break;  
2529 +
2530 +       }
2531 +
2532 +
2533 +       return (Status);
2534 +}
2535 +
2536 +AAC_STATUS
2537 +AfaCommRegisterNewClassDriver(
2538 +       IN PAFA_COMM_ADAPTER    Adapter,
2539 +       IN PAFA_NEW_CLASS_DRIVER        NewClassDriver,
2540 +       OUT PAFA_NEW_CLASS_DRIVER_RESPONSE NewClassDriverResponse
2541 +       )
2542 +/*++
2543 +
2544 +Routine Description:
2545 +
2546 +       This routine registers a new class driver for the comm layer.
2547 +
2548 +       It will return a pointer to the communication functions for the class driver
2549 +       to use.
2550 +
2551 +Arguments:
2552 +
2553 +       Adapter - Supplies which adapter is being processed.
2554 +
2555 +    Irp - Supplies the Irp being processed.
2556 +
2557 +Return Value:
2558 +
2559 +       STATUS_SUCCESS           - Everything OK.
2560 +
2561 +--*/
2562 +{
2563 +       AAC_STATUS Status;
2564 +       PAFA_CLASS_DRIVER ClassDriver;
2565 +
2566 +
2567 +       ClassDriver = (PAFA_CLASS_DRIVER) OsAllocMemory( sizeof(AFA_CLASS_DRIVER), OS_ALLOC_MEM_SLEEP );
2568 +
2569 +       if (ClassDriver == NULL) {
2570 +
2571 +               Status = STATUS_INSUFFICIENT_RESOURCES;
2572 +
2573 +               return Status;
2574 +       }
2575 +
2576 +       //
2577 +       // If the class driver has sent in user Vars, then copy them into the global
2578 +       // area.
2579 +       //
2580 +
2581 +       if (NewClassDriver->NumUserVars) {
2582 +
2583 +               PFSA_USER_VAR   NewUserVars;
2584 +
2585 +               NewUserVars = OsAllocMemory( (FsaCommData.NumUserVars +
2586 +                                                                  NewClassDriver->NumUserVars) * sizeof(FSA_USER_VAR), OS_ALLOC_MEM_SLEEP );
2587 +
2588 +               //
2589 +               // First copy the existing into the new area.
2590 +               //
2591 +
2592 +               RtlCopyMemory( NewUserVars, FsaCommData.UserVars, FsaCommData.NumUserVars * sizeof(FSA_USER_VAR) );
2593 +
2594 +               //
2595 +               // Next copy the new vars passed in from class driver.
2596 +               //
2597 +
2598 +               RtlCopyMemory( (NewUserVars + FsaCommData.NumUserVars),
2599 +                                          NewClassDriver->UserVars,
2600 +                                          NewClassDriver->NumUserVars * sizeof(FSA_USER_VAR) );
2601 +
2602 +               //
2603 +               // Free up the old user vars.
2604 +               //
2605 +
2606 +               OsFreeMemory( FsaCommData.UserVars, FsaCommData.NumUserVars * sizeof(FSA_USER_VAR) );
2607 +
2608 +               //
2609 +               // Point the global to the new area.
2610 +               //
2611 +
2612 +               FsaCommData.UserVars = NewUserVars;
2613 +
2614 +               //
2615 +               // Update the total count.
2616 +               //
2617 +
2618 +               FsaCommData.NumUserVars += NewClassDriver->NumUserVars;
2619 +
2620 +       }
2621 +
2622 +       ClassDriver->OpenAdapter = NewClassDriver->OpenAdapter;
2623 +       ClassDriver->CloseAdapter = NewClassDriver->CloseAdapter;
2624 +       ClassDriver->DeviceControl = NewClassDriver->DeviceControl;
2625 +       ClassDriver->HandleAif = NewClassDriver->HandleAif;
2626 +       ClassDriver->ClassDriverExtension = NewClassDriver->ClassDriverExtension;
2627 +
2628 +       ClassDriver->Next = Adapter->ClassDriverList;
2629 +       Adapter->ClassDriverList = ClassDriver;
2630 +
2631 +       //
2632 +       // Now return the information needed by the class driver to communicate to us.
2633 +       //
2634 +
2635 +       NewClassDriverResponse->CommFuncs = &Adapter->CommFuncs;
2636 +       NewClassDriverResponse->CommPortExtension = Adapter;
2637 +       NewClassDriverResponse->MiniPortExtension = Adapter->AdapterExtension;
2638 +       NewClassDriverResponse->SpinLockCookie = Adapter->SpinLockCookie;
2639 +       NewClassDriverResponse->Dip = Adapter->Dip;
2640 +
2641 +       return (STATUS_SUCCESS);
2642 +
2643 +
2644 +}
2645 +
2646 +int
2647 +AfaCommCtlSendFib(
2648 +       IN PAFA_COMM_ADAPTER    Adapter,
2649 +       IN PAFA_IOCTL_CMD               IoctlCmdPtr
2650 +)
2651 +/*++
2652 +
2653 +Routine Description:
2654 +
2655 +       This routine sends a fib to the adapter on behalf of a user level
2656 +       program.
2657 +
2658 +Arguments:
2659 +
2660 +       Adapter - Supplies which adapter is being processed.
2661 +
2662 +       IoctlCmdPtr - Pointer to the arguments to the IOCTL call
2663 +
2664 +Return Value:
2665 +
2666 +       STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2667 +
2668 +       STATUS_INSUFFICIENT_RESOURCES - If a memory allocation failed.
2669 +
2670 +       STATUS_SUCCESS           - Everything OK.
2671 +
2672 +--*/
2673 +{
2674 +    PFIB KFib;
2675 +//    PMDL DmaMdl = NULL;
2676 +       PCOMM_FIB_CONTEXT FibContext;
2677 +       PSGMAP_CONTEXT SgMapContext;
2678 +       SGMAP_CONTEXT _SgMapContext;
2679 +    QUEUE_TYPES WhichQueue;
2680 +    PVOID UsersAddress;
2681 +       AAC_STATUS Status;
2682 +
2683 +       FibContext = AllocateFib( Adapter );
2684 +
2685 +    KFib = FibContext->Fib;
2686 +
2687 +       //
2688 +       // First copy in the header so that we can check the size field.
2689 +       //
2690 +
2691 +       if (COPYIN( (caddr_t) IoctlCmdPtr->arg, (caddr_t) KFib, sizeof(FIB_HEADER), IoctlCmdPtr->flag )) {
2692 +               FreeFib( FibContext );
2693 +               Status = EFAULT;
2694 +               return (Status);
2695 +       }
2696 +
2697 +       //
2698 +       //      Since we copy based on the fib header size, make sure that we
2699 +       //      will not overrun the buffer when we copy the memory. Return
2700 +       //      an error if we would.
2701 +       //
2702 +
2703 +       if (KFib->Header.Size > sizeof(FIB) - sizeof(FIB_HEADER)) {
2704 +               FreeFib( FibContext );
2705 +               Status = EINVAL;
2706 +               return Status;
2707 +
2708 +       }
2709 +
2710 +       if (COPYIN( (caddr_t) IoctlCmdPtr->arg, (caddr_t) KFib, KFib->Header.Size + sizeof(FIB_HEADER), IoctlCmdPtr->flag )) {
2711 +               FreeFib( FibContext );
2712 +               Status = EFAULT;
2713 +               return (Status);
2714 +       }
2715 +
2716 +    WhichQueue = AdapNormCmdQueue;
2717 +
2718 +
2719 +       if (KFib->Header.Command == TakeABreakPt) {
2720 +
2721 +               InterruptAdapter(Adapter);
2722 +
2723 +               //
2724 +               // Since we didn't really send a fib, zero out the state to allow 
2725 +               // cleanup code not to assert.
2726 +               //
2727 +
2728 +               KFib->Header.XferState = 0;
2729 +
2730 +
2731 +       } else {
2732 +       
2733 +               if (SendFib(KFib->Header.Command, FibContext, KFib->Header.Size , FsaNormal,
2734 +                                       TRUE, NULL, TRUE, NULL, NULL) != FSA_SUCCESS) {
2735 +               FsaCommPrint("User SendFib failed!.\n");
2736 +
2737 +
2738 +                       FreeFib( FibContext );
2739 +                       return (ENXIO);
2740 +               }
2741 +
2742 +           if (CompleteFib(FibContext) != FSA_SUCCESS) {
2743 +               FsaCommPrint("User Complete FIB failed.\n");
2744 +
2745 +                       FreeFib( FibContext );
2746 +                       return (ENXIO);
2747 +               }
2748 +
2749 +
2750 +    }
2751 +
2752 +
2753 +       //
2754 +       //      Make sure that the size returned by the adapter (which includes
2755 +       //      the header) is less than or equal to the size of a fib, so we
2756 +       //      don't corrupt application data. Then copy that size to the user
2757 +       //      buffer. (Don't try to add the header information again, since it
2758 +       //      was already included by the adapter.)
2759 +       //
2760 +    ASSERT(KFib->Header.Size <= sizeof(FIB));
2761 +
2762 +       if (COPYOUT( (caddr_t) KFib, (caddr_t) IoctlCmdPtr->arg, KFib->Header.Size, IoctlCmdPtr->flag )) {
2763 +               FreeFib( FibContext );
2764 +               Status = EFAULT;
2765 +               return (Status);
2766 +       }
2767 +
2768 +       FreeFib( FibContext );
2769 +
2770 +    return (0);
2771 +
2772 +}
2773 +
2774 +int
2775 +AfaCommCtlAifThread(
2776 +       IN PAFA_COMM_ADAPTER    Adapter,
2777 +       IN PAFA_IOCTL_CMD               IoctlCmdPtr
2778 +)
2779 +/*++
2780 +
2781 +Routine Description:
2782 +
2783 +       This routine will act as the AIF thread for this adapter.
2784 +
2785 +Arguments:
2786 +
2787 +       Adapter - Supplies which adapter is being processed.
2788 +
2789 +       IoctlCmdPtr - Pointer to the arguments to the IOCTL call
2790 +
2791 +Return Value:
2792 +
2793 +       STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2794 +
2795 +       STATUS_INSUFFICIENT_RESOURCES - If a memory allocation failed.
2796 +
2797 +       STATUS_SUCCESS           - Everything OK.
2798 +
2799 +--*/
2800 +{
2801 +       return (NormCommandThread(Adapter));
2802 +}
2803 +
2804 +
2805 +
2806 +#ifdef GATHER_FIB_TIMES
2807 +AAC_STATUS
2808 +AfaCommGetFibTimes(
2809 +       IN PAFA_COMM_ADAPTER    Adapter,
2810 +       IN PIRP                                 Irp
2811 +       )
2812 +/*++
2813 +
2814 +Routine Description:
2815 +
2816 +       This routine returns the gathered fibtimes to the user.
2817 +
2818 +Arguments:
2819 +
2820 +       Adapter - Supplies which adapter is being processed.
2821 +
2822 +    Irp - Supplies the Irp being processed.
2823 +
2824 +Return Value:
2825 +
2826 +       STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2827 +
2828 +       STATUS_INSUFFICIENT_RESOURCES - If a memory allocation failed.
2829 +
2830 +       STATUS_SUCCESS           - Everything OK.
2831 +
2832 +--*/
2833 +{
2834 +       PALL_FIB_TIMES AllFibTimes;
2835 +       PLARGE_INTEGER FreqPtr;
2836 +    PIO_STACK_LOCATION IrpSp;
2837 +
2838 +    //
2839 +    //  Get a pointer to the current Irp stack location
2840 +    //
2841 +
2842 +    IrpSp = IoGetCurrentIrpStackLocation( Irp );
2843 +
2844 +       FreqPtr = (PLARGE_INTEGER)IrpSp->Parameters.FileSystemControl.Type3InputBuffer;
2845 +
2846 +       *FreqPtr = Adapter->FibTimesFrequency;
2847 +
2848 +       AllFibTimes = (PALL_FIB_TIMES)((PUCHAR)FreqPtr + sizeof(LARGE_INTEGER));
2849 +
2850 +       RtlCopyMemory(AllFibTimes, Adapter->FibTimes, sizeof(ALL_FIB_TIMES));
2851 +
2852 +       Irp->IoStatus.Information = 0;
2853 +
2854 +       return (STATUS_SUCCESS);
2855 +
2856 +}
2857 +
2858 +AAC_STATUS
2859 +AfaCommZeroFibTimes(
2860 +       IN PAFA_COMM_ADAPTER    Adapter,
2861 +       IN PIRP                                 Irp
2862 +       )
2863 +/*++
2864 +
2865 +Routine Description:
2866 +
2867 +       This routine zero's the FibTimes structure within the adapter structure.
2868 +
2869 +Arguments:
2870 +
2871 +       Adapter - Supplies which adapter is being processed.
2872 +
2873 +    Irp - Supplies the Irp being processed.
2874 +
2875 +Return Value:
2876 +
2877 +       STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2878 +
2879 +       STATUS_INSUFFICIENT_RESOURCES - If a memory allocation failed.
2880 +
2881 +       STATUS_SUCCESS           - Everything OK.
2882 +
2883 +--*/
2884 +{
2885 +       PFIB_TIMES FibTimesPtr;
2886 +       int i;
2887 +    PIO_STACK_LOCATION IrpSp;
2888 +
2889 +    //
2890 +    //  Get a pointer to the current Irp stack location
2891 +    //
2892 +
2893 +    IrpSp = IoGetCurrentIrpStackLocation( Irp );
2894 +
2895 +       //
2896 +       // Initialize the Fib timing data structures
2897 +       //
2898 +       RtlZeroMemory(Adapter->FibTimes, sizeof(ALL_FIB_TIMES));
2899 +
2900 +       for (i = 0; i < MAX_FSACOMMAND_NUM; i++) {
2901 +
2902 +               FibTimesPtr = &Adapter->FibTimes->FileSys[i];
2903 +
2904 +               FibTimesPtr->Minimum.LowPart = 0xffffffff;
2905 +               FibTimesPtr->Minimum.HighPart = 0x7fffffff;
2906 +               FibTimesPtr->AdapterMinimum.LowPart = 0xffffffff;
2907 +               FibTimesPtr->AdapterMinimum.HighPart = 0x7fffffff;
2908 +       }
2909 +       for (i = 0; i < MAX_RW_FIB_TIMES; i++) {
2910 +
2911 +               FibTimesPtr = &Adapter->FibTimes->Read[i];
2912 +
2913 +               FibTimesPtr->Minimum.LowPart = 0xffffffff;
2914 +               FibTimesPtr->Minimum.HighPart = 0x7fffffff;
2915 +               FibTimesPtr->AdapterMinimum.LowPart = 0xffffffff;
2916 +               FibTimesPtr->AdapterMinimum.HighPart = 0x7fffffff;
2917 +       }
2918 +       for (i = 0; i < MAX_RW_FIB_TIMES; i++) {
2919 +
2920 +               FibTimesPtr = &Adapter->FibTimes->Write[i];
2921 +
2922 +               FibTimesPtr->Minimum.LowPart = 0xffffffff;
2923 +               FibTimesPtr->Minimum.HighPart = 0x7fffffff;
2924 +               FibTimesPtr->AdapterMinimum.LowPart = 0xffffffff;
2925 +               FibTimesPtr->AdapterMinimum.HighPart = 0x7fffffff;
2926 +       }
2927 +
2928 +       FibTimesPtr = &Adapter->FibTimes->Other;
2929 +
2930 +       FibTimesPtr->Minimum.LowPart = 0xffffffff;
2931 +       FibTimesPtr->Minimum.HighPart = 0x7fffffff;
2932 +       FibTimesPtr->AdapterMinimum.LowPart = 0xffffffff;
2933 +       FibTimesPtr->AdapterMinimum.HighPart = 0x7fffffff;
2934 +
2935 +       Irp->IoStatus.Information = 0;
2936 +
2937 +       return (STATUS_SUCCESS);
2938 +
2939 +}
2940 +#endif // GATHER_FIB_TIMES
2941 +
2942 +#ifndef unix_aif
2943 +int
2944 +FsaCtlOpenGetAdapterFib(
2945 +       IN PAFA_COMM_ADAPTER    Adapter,
2946 +       IN PAFA_IOCTL_CMD               IoctlCmdPtr
2947 +       )
2948 +/*++
2949 +
2950 +Routine Description:
2951 +
2952 +    This routine will get the next Fib, if available, from the AdapterFibContext
2953 +       passed in from the user.
2954 +
2955 +Arguments:
2956 +
2957 +       Adapter - Supplies which adapter is being processed.
2958 +
2959 +    Irp - Supplies the Irp being processed.
2960 +
2961 +Return Value:
2962 +
2963 +       STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2964 +
2965 +       STATUS_INSUFFICIENT_RESOURCES - If a memory allocation failed.
2966 +
2967 +       STATUS_SUCCESS           - Everything OK.
2968 +
2969 +--*/
2970 +{
2971 +       PGET_ADAPTER_FIB_CONTEXT AdapterFibContext;
2972 +//     HANDLE Event;
2973 +//    PKEVENT eventObject = (PKEVENT) NULL;
2974 +       int Status;
2975 +
2976 +       //
2977 +       // The context must be allocated from NonPagedPool because we need to use MmIsAddressValid.
2978 +       //
2979 +
2980 +       AdapterFibContext = OsAllocMemory(sizeof(GET_ADAPTER_FIB_CONTEXT), OS_ALLOC_MEM_SLEEP);
2981 +
2982 +       if (AdapterFibContext == NULL) {
2983 +
2984 +               Status = ENOMEM;
2985 +
2986 +       } else {
2987 +
2988 +               AdapterFibContext->NodeTypeCode = FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT;
2989 +               AdapterFibContext->NodeByteSize = sizeof(GET_ADAPTER_FIB_CONTEXT);
2990 +
2991 +
2992 +               //
2993 +               // Initialize the conditional variable use to wait for the next AIF.
2994 +               //
2995 +
2996 +               OsCv_init( &AdapterFibContext->UserEvent);
2997 +
2998 +               //
2999 +               // Set WaitingForFib to FALSE to indicate we are not in a WaitForSingleObject
3000 +               //
3001 +
3002 +               AdapterFibContext->WaitingForFib = FALSE;
3003 +
3004 +               //
3005 +               // Initialize the FibList and set the count of fibs on the list to 0.
3006 +               //
3007 +
3008 +               AdapterFibContext->FibCount = 0;
3009 +               InitializeListHead(&AdapterFibContext->FibList);
3010 +
3011 +               //
3012 +               // Overload FileObject with a time stamp.
3013 +               //
3014 +               AdapterFibContext->FileObject = (void *)OsGetSeconds();
3015 +
3016 +               //
3017 +               // Now add this context onto the adapter's AdapterFibContext list.
3018 +               //
3019 +
3020 +               OsCvLockAcquire(Adapter->AdapterFibMutex);
3021 +
3022 +               InsertTailList(&Adapter->AdapterFibContextList, &AdapterFibContext->NextContext);
3023 +
3024 +               OsCvLockRelease(Adapter->AdapterFibMutex);
3025 +
3026 +               if (COPYOUT( &AdapterFibContext, (caddr_t) IoctlCmdPtr->arg, sizeof(PGET_ADAPTER_FIB_CONTEXT), 
3027 +                                                IoctlCmdPtr->flag )) {
3028 +
3029 +                       Status = EFAULT;
3030 +                       
3031 +               } else {
3032 +               
3033 +                       Status = 0;
3034 +
3035 +               }       
3036 +
3037 +       }
3038 +
3039 +       return (Status);
3040 +}
3041 +
3042 +int
3043 +FsaCtlGetNextAdapterFib(
3044 +       IN PAFA_COMM_ADAPTER    Adapter,
3045 +       IN PAFA_IOCTL_CMD               IoctlCmdPtr
3046 +       )
3047 +/*++
3048 +
3049 +Routine Description:
3050 +
3051 +    This routine will get the next Fib, if available, from the AdapterFibContext
3052 +       passed in from the user.
3053 +
3054 +Arguments:
3055 +
3056 +       Adapter - Supplies which adapter is being processed.
3057 +
3058 +    Irp - Supplies the Irp being processed.
3059 +
3060 +Return Value:
3061 +
3062 +       STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
3063 +
3064 +       STATUS_NO_MORE_ENTRIES - There are no more Fibs for this AdapterFibContext.
3065 +
3066 +       STATUS_SUCCESS           - Everything OK.
3067 +
3068 +--*/
3069 +{
3070 +       GET_ADAPTER_FIB_IOCTL AdapterFibIoctl;
3071 +       PGET_ADAPTER_FIB_CONTEXT AdapterFibContext, aifcp;
3072 +       PFIB Fib;
3073 +       int Status;
3074 +       PLIST_ENTRY Entry;
3075 +       int found;
3076 +
3077 +       if (COPYIN( (caddr_t) IoctlCmdPtr->arg, (caddr_t) &AdapterFibIoctl,
3078 +                                       sizeof(GET_ADAPTER_FIB_IOCTL), IoctlCmdPtr->flag )) {
3079 +               return (EFAULT);
3080 +       }
3081 +
3082 +       //
3083 +       // Extract the AdapterFibContext from the Input parameters.
3084 +       //
3085 +
3086 +       AdapterFibContext = (PGET_ADAPTER_FIB_CONTEXT) AdapterFibIoctl.AdapterFibContext;
3087 +
3088 +       //
3089 +       // Verify that the HANDLE passed in was a valid AdapterFibContext
3090 +       //
3091 +       // Search the list of AdapterFibContext addresses on the adapter to be sure
3092 +       // this is a valid address
3093 +
3094 +       found = 0;
3095 +       Entry = Adapter->AdapterFibContextList.Flink;
3096 +
3097 +       while ( Entry != &Adapter->AdapterFibContextList ) {
3098 +                       aifcp = CONTAINING_RECORD ( Entry, GET_ADAPTER_FIB_CONTEXT, NextContext );
3099 +                       if ( AdapterFibContext == aifcp ) {   // We found a winner
3100 +                                       found = 1;
3101 +                                       break;
3102 +                       }
3103 +                       Entry = Entry->Flink;
3104 +       }
3105 +
3106 +       if ( found == 0 ) {
3107 +                       return ( EINVAL );;
3108 +       }
3109 +
3110 +       if ( (AdapterFibContext->NodeTypeCode != FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT) ||
3111 +                (AdapterFibContext->NodeByteSize != sizeof(GET_ADAPTER_FIB_CONTEXT)) ) {
3112 +
3113 +               return ( EINVAL );
3114 +
3115 +       }
3116 +
3117 +       Status = STATUS_SUCCESS;
3118 +
3119 +       OsCvLockAcquire(Adapter->AdapterFibMutex);
3120 +
3121 +       //
3122 +       // If there are no fibs to send back, then either wait or return EAGAIN
3123 +       //
3124 +return_fib:
3125 +
3126 +       if (!IsListEmpty(&AdapterFibContext->FibList)) {
3127 +
3128 +               PLIST_ENTRY Entry;
3129 +
3130 +               //
3131 +               // Pull the next fib from the FibList
3132 +               //
3133 +               Entry = RemoveHeadList(&AdapterFibContext->FibList);
3134 +
3135 +               Fib = CONTAINING_RECORD( Entry, FIB, Header.FibLinks );
3136 +
3137 +               AdapterFibContext->FibCount--;
3138 +
3139 +               if (COPYOUT( Fib, AdapterFibIoctl.AifFib, sizeof(FIB), IoctlCmdPtr->flag )) {
3140 +
3141 +                       OsCvLockRelease( Adapter->AdapterFibMutex );
3142 +                       OsFreeMemory( Fib, sizeof(Fib) );
3143 +                       return (EFAULT);
3144 +
3145 +               }       
3146 +
3147 +               //
3148 +               // Free the space occupied by this copy of the fib.
3149 +               //
3150 +
3151 +               OsFreeMemory(Fib, sizeof(FIB));
3152 +
3153 +        Status = 0;
3154 +
3155 +               //
3156 +               // Overload FileObject with a time stamp
3157 +               // 
3158 +               AdapterFibContext->FileObject = ( void * )OsGetSeconds();
3159 +
3160 +       } else {
3161 +
3162 +               if (AdapterFibIoctl.Wait) {
3163 +                       
3164 +                       if (OsCv_wait_sig( &AdapterFibContext->UserEvent, Adapter->AdapterFibMutex ) == 0) {
3165 +
3166 +                               Status = EINTR;
3167 +
3168 +                       } else {
3169 +                       
3170 +                               goto return_fib;
3171 +                               
3172 +                       }
3173 +               } else {
3174 +                                       
3175 +                       Status = EAGAIN;
3176 +
3177 +               }       
3178 +
3179 +       }
3180 +       OsCvLockRelease( Adapter->AdapterFibMutex );
3181 +
3182 +       return (Status);
3183 +}
3184 +
3185 +int
3186 +FsaCtlCloseGetAdapterFib(
3187 +       IN PAFA_COMM_ADAPTER    Adapter,
3188 +       IN PAFA_IOCTL_CMD               IoctlCmdPtr
3189 +       )
3190 +/*++
3191 +
3192 +Routine Description:
3193 +
3194 +    This routine will close down the AdapterFibContext passed in from the user.
3195 +
3196 +Arguments:
3197 +
3198 +       Adapter - Supplies which adapter is being processed.
3199 +
3200 +    Irp - Supplies the Irp being processed.
3201 +
3202 +Return Value:
3203 +
3204 +       STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
3205 +
3206 +       STATUS_SUCCESS           - Everything OK.
3207 +
3208 +--*/
3209 +{
3210 +       PGET_ADAPTER_FIB_CONTEXT AdapterFibContext, aifcp;
3211 +       AAC_STATUS Status;
3212 +
3213 +       PLIST_ENTRY Entry;
3214 +       int found;
3215 +
3216 +       //
3217 +       // Extract the AdapterFibContext from the Input parameters
3218 +       //
3219 +
3220 +       AdapterFibContext = (PGET_ADAPTER_FIB_CONTEXT) IoctlCmdPtr->arg;
3221 +
3222 +       if (AdapterFibContext == 0) {
3223 +               cmn_err(CE_WARN, "FsaCtlCloseGetAdapterFib: AdapterFibContext is NULL");
3224 +               return(EINVAL);
3225 +       }
3226 +
3227 +       //
3228 +       // Verify that the HANDLE passed in was a valid AdapterFibContext
3229 +       //
3230 +       // Search the list of AdapterFibContext addresses on the adapter to be sure
3231 +       // this is a valid address
3232 +
3233 +       found = 0;
3234 +       Entry = Adapter->AdapterFibContextList.Flink;
3235 +
3236 +       while ( Entry != &Adapter->AdapterFibContextList ) {
3237 +                       aifcp = CONTAINING_RECORD ( Entry, GET_ADAPTER_FIB_CONTEXT, NextContext );
3238 +                       if ( AdapterFibContext == aifcp ) {   // We found a winner
3239 +                                       found = 1;
3240 +                                       break;
3241 +                       }
3242 +                       Entry = Entry->Flink;
3243 +       }
3244 +
3245 +       if ( found == 0 ) {
3246 +               return ( 0 ); // Already Gone
3247 +       }
3248 +
3249 +       if ( (AdapterFibContext->NodeTypeCode != FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT) ||
3250 +                (AdapterFibContext->NodeByteSize != sizeof(GET_ADAPTER_FIB_CONTEXT)) ) {
3251 +
3252 +               return (EINVAL);
3253 +
3254 +       }
3255 +
3256 +       OsCvLockAcquire(Adapter->AdapterFibMutex);
3257 +
3258 +       Status = FsaCloseAdapterFibContext(Adapter, AdapterFibContext);
3259 +
3260 +       OsCvLockRelease(Adapter->AdapterFibMutex);
3261 +
3262 +       return (Status);
3263 +}
3264 +
3265 +int
3266 +FsaCloseAdapterFibContext(
3267 +       IN PAFA_COMM_ADAPTER                    Adapter,
3268 +       IN PGET_ADAPTER_FIB_CONTEXT             AdapterFibContext
3269 +       )
3270 +{
3271 +       int Status;
3272 +       PFIB Fib;
3273 +
3274 +       //
3275 +       // First free any FIBs that have not been consumed yet.
3276 +       //
3277 +
3278 +       while (!IsListEmpty(&AdapterFibContext->FibList)) {
3279 +
3280 +               PLIST_ENTRY Entry;
3281 +
3282 +               //
3283 +               // Pull the next fib from the FibList
3284 +               //
3285 +
3286 +               Entry = RemoveHeadList(&AdapterFibContext->FibList);
3287 +
3288 +               Fib = CONTAINING_RECORD( Entry, FIB, Header.FibLinks );
3289 +
3290 +               AdapterFibContext->FibCount--;
3291 +
3292 +               //
3293 +               // Free the space occupied by this copy of the fib.
3294 +               //
3295 +
3296 +               OsFreeMemory(Fib, sizeof(FIB));
3297 +       }
3298 +
3299 +       //
3300 +       // Remove the Context from the AdapterFibContext List
3301 +       //
3302 +
3303 +       RemoveEntryList(&AdapterFibContext->NextContext);
3304 +
3305 +       OsCv_destroy( &AdapterFibContext->UserEvent );
3306 +
3307 +       //
3308 +       // Invalidate context
3309 +       //
3310 +
3311 +       AdapterFibContext->NodeTypeCode = 0;
3312 +
3313 +       //
3314 +       // Free the space occupied by the Context
3315 +       //
3316 +
3317 +       OsFreeMemory(AdapterFibContext, sizeof(GET_ADAPTER_FIB_CONTEXT));
3318 +
3319 +       Status = STATUS_SUCCESS;
3320 +
3321 +    return Status;
3322 +}
3323 +#endif 
3324 +
3325 +AAC_STATUS
3326 +AfaCommOpenAdapter(
3327 +       IN PVOID Arg
3328 +       )
3329 +/*++
3330 +
3331 +Routine Description:
3332 +
3333 +       The routine will get called by the miniport each time a user issues a CreateFile on the DeviceObject
3334 +       for the adapter.
3335 +
3336 +       The main purpose of this routine is to set up any data structures that may be needed
3337 +       to handle any requests made on this DeviceObject.
3338 +
3339 +Arguments:
3340 +
3341 +       Adapter - Pointer to which adapter miniport was opened.
3342 +
3343 +
3344 +Return Value:
3345 +
3346 +       STATUS_SUCCESS
3347 +
3348 +--*/
3349 +
3350 +{
3351 +       PAFA_COMM_ADAPTER       Adapter = (PAFA_COMM_ADAPTER) Arg;
3352 +       AAC_STATUS Status = STATUS_SUCCESS;
3353 +       PAFA_CLASS_DRIVER ClassDriver;
3354 +
3355 +       ClassDriver = Adapter->ClassDriverList;
3356 +
3357 +       while (ClassDriver) {
3358 +
3359 +               if (ClassDriver->OpenAdapter) {
3360 +
3361 +                       Status = ClassDriver->OpenAdapter( ClassDriver->ClassDriverExtension );
3362 +
3363 +                       if (Status != STATUS_SUCCESS)
3364 +                               break;
3365 +               }
3366 +
3367 +               ClassDriver = ClassDriver->Next;
3368 +       }
3369 +
3370 +       return ( Status );
3371 +}
3372 +
3373 +AAC_STATUS
3374 +AfaCommCloseAdapter(
3375 +       IN PVOID Arg
3376 +       )
3377 +/*++
3378 +
3379 +Routine Description:
3380 +
3381 +       This routine will get called by the miniport each time a user issues a CloseHandle on the DeviceObject
3382 +       for the adapter.
3383 +
3384 +       The main purpose of this routine is to cleanup any data structures that have been set up
3385 +       while this FileObject has been opened.
3386 +
3387 +       This routine loops through all of the AdapterFibContext structures to determine if any need
3388 +       to be deleted for this FileObject.
3389 +
3390 +Arguments:
3391 +
3392 +       Adapter - Pointer to adapter miniport
3393 +
3394 +       Irp - Pointer to Irp that caused this close
3395 +
3396 +Return Value:
3397 +
3398 +       Status value returned from File system driver AdapterClose
3399 +
3400 +--*/
3401 +{
3402 +       PAFA_COMM_ADAPTER       Adapter = (PAFA_COMM_ADAPTER) Arg;
3403 +       PLIST_ENTRY Entry, NextEntry;
3404 +       PGET_ADAPTER_FIB_CONTEXT AdapterFibContext;
3405 +       AAC_STATUS Status = STATUS_SUCCESS;
3406 +       PAFA_CLASS_DRIVER ClassDriver;
3407 +
3408 +       OsCvLockAcquire(Adapter->AdapterFibMutex);
3409 +
3410 +       Entry = Adapter->AdapterFibContextList.Flink;
3411 +
3412 +       //
3413 +       // Loop through all of the AdapterFibContext, looking for any that
3414 +       // were created with the FileObject that is being closed.
3415 +       //
3416 +       while (Entry != &Adapter->AdapterFibContextList) {
3417 +
3418 +               //
3419 +               // Extract the AdapterFibContext
3420 +               //
3421 +               AdapterFibContext = CONTAINING_RECORD( Entry, GET_ADAPTER_FIB_CONTEXT, NextContext );
3422 +
3423 +               // 
3424 +               // Save the next entry because CloseAdapterFibContext will delete the AdapterFibContext
3425 +               //
3426 +               NextEntry = Entry->Flink;
3427 +
3428 +               Entry = NextEntry;
3429 +
3430 +       }
3431 +
3432 +#ifdef unix_config_file
3433 +       //
3434 +       // If this FileObject had the adapter open for configuration, then release it.
3435 +       //
3436 +       if ( Adapter->AdapterConfigFileObject == IrpSp->FileObject ) {
3437 +
3438 +               Adapter->AdapterConfigFileObject = NULL;
3439 +
3440 +       }
3441 +#endif
3442 +
3443 +       OsCvLockRelease(Adapter->AdapterFibMutex);
3444 +
3445 +       ClassDriver = Adapter->ClassDriverList;
3446 +
3447 +       while (ClassDriver) {
3448 +
3449 +               if (ClassDriver->CloseAdapter) {
3450 +
3451 +                       Status = ClassDriver->CloseAdapter( ClassDriver->ClassDriverExtension );
3452 +
3453 +                       if (Status != STATUS_SUCCESS)
3454 +                               break;
3455 +               }
3456 +
3457 +               ClassDriver = ClassDriver->Next;
3458 +       }
3459 +
3460 +       return ( Status );
3461 +
3462 +}
3463 +
3464 diff -burN linux-2.4.7/drivers/scsi/aacraid/comminit.c linux/drivers/scsi/aacraid/comminit.c
3465 --- linux-2.4.7/drivers/scsi/aacraid/comminit.c Wed Dec 31 18:00:00 1969
3466 +++ linux/drivers/scsi/aacraid/comminit.c       Sat Jul 21 17:55:13 2001
3467 @@ -0,0 +1,986 @@
3468 +/*++
3469 + * Adaptec aacraid device driver for Linux.
3470 + *
3471 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
3472 + *
3473 + * This program is free software; you can redistribute it and/or modify
3474 + * it under the terms of the GNU General Public License as published by
3475 + * the Free Software Foundation; either version 2, or (at your option)
3476 + * any later version.
3477 + *
3478 + * This program is distributed in the hope that it will be useful,
3479 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
3480 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
3481 + * GNU General Public License for more details.
3482 + *
3483 + * You should have received a copy of the GNU General Public License
3484 + * along with this program; see the file COPYING.  If not, write to
3485 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
3486 + *
3487 + * Module Name:
3488 + *  comminit.c
3489 + *
3490 + * Abstract: This supports the initialization of the host adapter commuication interface.
3491 + *    This is a platform dependent module for the pci cyclone board.
3492 + *
3493 + --*/
3494 +
3495 +static char *ident_comminit = "aacraid_ident comminit.c 1.0.6 2000/10/09 Adaptec, Inc.";
3496 +
3497 +#include "comprocs.h"
3498 +
3499 +#define BugCheckFileId                   (FSAFS_BUG_CHECK_COMMINIT)
3500 +
3501 +VOID
3502 +AfaCommBugcheckHandler(
3503 +               IN PVOID Buffer,
3504 +               IN ULONG Length
3505 +               );
3506 +
3507 +VOID
3508 +ThrottlePeriodEndDpcRtn(
3509 +       IN PKDPC Dpc,
3510 +       IN PVOID DeferredContext,
3511 +       IN PVOID SystemArgument1,
3512 +       IN PVOID SystemArgument2);
3513 +
3514 +FSA_COMM_DATA FsaCommData;
3515 +
3516 +AAC_STATUS
3517 +HardInterruptModeration1Changed(
3518 +       IN PVOID AdapterContext,
3519 +       IN ULONG NewValue
3520 +       )
3521 +{
3522 +       PAFA_COMM_ADAPTER Adapter = AdapterContext;
3523 +
3524 +       //
3525 +       // If we are using interrupt moderation, then disable the interrupt
3526 +       // until we need to use it.
3527 +       //
3528 +       if (FsaCommData.HardInterruptModeration1)
3529 +               DisableInterrupt( Adapter, AdapNormCmdNotFull, FALSE );
3530 +       else
3531 +               EnableInterrupt( Adapter, AdapNormCmdNotFull, FALSE );
3532 +
3533 +       return (STATUS_SUCCESS);
3534 +}
3535 +
3536 +AAC_STATUS
3537 +FsaFibTimeoutChanged(
3538 +       IN PVOID AdapterContext,
3539 +       IN ULONG NewValue
3540 +       )
3541 +{
3542 +       //
3543 +       // scale the new timeout from seconds to 100 nsec units
3544 +       //
3545 +//     FsaCommData.AdapterTimeout = RtlConvertLongToLargeInteger(-10*1000*1000*NewValue);
3546 +
3547 +       return (STATUS_SUCCESS);
3548 +}
3549 +
3550 +#ifdef GATHER_FIB_TIMES
3551 +extern int GatherFibTimes;
3552 +#endif
3553 +
3554 +FSA_USER_VAR FsaCommUserVars[] = {
3555 +#ifdef FIB_CHECKSUMS
3556 +    { "do_fib_checksums", (PULONG)&FsaCommData.do_fib_checksums, NULL },
3557 +#endif
3558 +#ifdef GATHER_FIB_TIMES
3559 +       { "GatherFibTimes", (PULONG)&GatherFibTimes, NULL },
3560 +#endif
3561 +       { "EnableAdapterTimeouts", (PULONG)&FsaCommData.EnableAdapterTimeouts, NULL},
3562 +       { "EnableInterruptModeration", (PULONG)&FsaCommData.EnableInterruptModeration, NULL },
3563 +       { "FsaDataFibsSent", (PULONG) &FsaCommData.FibsSent, NULL },
3564 +       { "FsaDataFibRecved", (PULONG) &FsaCommData.FibRecved, NULL },
3565 +       { "HardInterruptModeration", (PULONG)&FsaCommData.HardInterruptModeration, NULL},
3566 +       { "HardInterruptModeration1", (PULONG)&FsaCommData.HardInterruptModeration1, HardInterruptModeration1Changed},
3567 +       { "EnableFibTimeoutBreak", (PULONG)&FsaCommData.EnableFibTimeoutBreak, NULL},
3568 +       { "PeakFibsConsumed", (PULONG)&FsaCommData.PeakFibsConsumed, NULL },
3569 +       { "ZeroFibsConsumed", (PULONG)&FsaCommData.ZeroFibsConsumed, NULL },
3570 +       { "FibTimeoutSeconds", (PULONG) &FsaCommData.FibTimeoutSeconds, FsaFibTimeoutChanged },
3571 +};
3572 +
3573 +#define NUM_COMM_USER_VARS     (sizeof(FsaCommUserVars) / sizeof(FSA_USER_VAR) )
3574 +
3575 +\f
3576 +AAC_STATUS
3577 +AacCommDriverEntry(
3578 +    )
3579 +
3580 +/*++
3581 +
3582 +Routine Description:
3583 +
3584 +    This is the initialization routine for the FileArray Comm layer device driver.
3585 +
3586 +Arguments:
3587 +
3588 +    DriverObject - Pointer to driver object created by the system.
3589 +
3590 +Return Value:
3591 +
3592 +    AAC_STATUS - The function value is the final status from the initialization
3593 +        operation.
3594 +
3595 +--*/
3596 +
3597 +{
3598 +    AAC_STATUS Status;
3599 +       PVOID BugCheckBuffer;
3600 +
3601 +       RtlZeroMemory( &FsaCommData, sizeof(FSA_COMM_DATA) );
3602 +
3603 +
3604 +    //
3605 +    // Load the global timeout value for the adapter timeout
3606 +    // Also init the global that enables or disables adapter timeouts
3607 +    //
3608 +
3609 +//     FsaCommData.AdapterTimeout = RtlConvertLongToLargeInteger(-10*1000*1000*180);
3610 +
3611 +       FsaCommData.FibTimeoutSeconds = 180;
3612 +
3613 +       FsaCommData.EnableAdapterTimeouts = TRUE; 
3614 +
3615 +//     FsaCommData.QueueFreeTimeout = RtlConvertLongToLargeInteger(QUEUE_ENTRY_FREE_TIMEOUT);
3616 +
3617 +#ifdef unix_fib_timeout
3618 +       FsaCommData.FibTimeoutIncrement = (180 * 1000 * 1000 * 10) / KeQueryTimeIncrement();
3619 +#endif
3620 +
3621 +       FsaCommData.EnableInterruptModeration = FALSE;
3622 +
3623 +       //
3624 +       // Preload UserVars with all variables from the comm layer.  The class layers will
3625 +       // include theirs when they register.
3626 +       //
3627 +
3628 +       FsaCommData.UserVars = OsAllocMemory(NUM_COMM_USER_VARS * sizeof(FSA_USER_VAR), OS_ALLOC_MEM_SLEEP );
3629 +       FsaCommData.NumUserVars = NUM_COMM_USER_VARS;
3630 +
3631 +       RtlCopyMemory( FsaCommData.UserVars, &FsaCommUserVars, NUM_COMM_USER_VARS * sizeof(FSA_USER_VAR) );
3632 +
3633 +
3634 +#ifdef AACDISK
3635 +       //
3636 +       // Call the disk driver to initialize itself.
3637 +       //
3638 +
3639 +       AacDiskDriverEntry();
3640 +
3641 +#endif
3642 +
3643 +
3644 +
3645 +       return (STATUS_SUCCESS);
3646 +}
3647 +
3648 +
3649 +VOID
3650 +DetachNTQueue(
3651 +       IN PAFA_COMM_ADAPTER Adapter,
3652 +    IN OUT PCOMM_QUE Queue,
3653 +    IN QUEUE_TYPES WhichQueue
3654 +    )
3655 +/*++
3656 +
3657 +Routine Description:
3658 +
3659 +       This routine will release all of the resources used by a given queue.
3660 +
3661 +Arguments:
3662 +
3663 +       Adapter - Which adapter the queue belongs to
3664 +       Queue - Pointer to the queue itself
3665 +       WhichQueue - Identifies which of the host queues this is.
3666 +
3667 +Return Value:
3668 +
3669 +       NONE.
3670 +
3671 +--*/
3672 +{
3673 +    switch (WhichQueue) {
3674 +
3675 +        case HostNormCmdQueue:
3676 +
3677 +                       Os_remove_softintr( Queue->ConsumerRoutine );
3678 +                       OsSpinLockDestroy( Queue->QueueLock );
3679 +                       OsCv_destroy( &Queue->CommandReady );
3680 +                               
3681 +            break;
3682 +
3683 +        case HostHighCmdQueue:
3684 +
3685 +                       Os_remove_softintr( Queue->ConsumerRoutine );
3686 +                       OsSpinLockDestroy( Queue->QueueLock );
3687 +                       OsCv_destroy( &Queue->CommandReady );
3688 +                               
3689 +            break;
3690 +
3691 +        case HostNormRespQueue:
3692 +
3693 +                       Os_remove_softintr( Queue->ConsumerRoutine );
3694 +                       OsSpinLockDestroy( Queue->QueueLock );
3695 +            break;
3696 +
3697 +        case HostHighRespQueue:
3698 +
3699 +                       Os_remove_softintr( Queue->ConsumerRoutine );
3700 +                       OsSpinLockDestroy( Queue->QueueLock );
3701 +            break;
3702 +
3703 +        case AdapNormCmdQueue:
3704 +        case AdapHighCmdQueue:
3705 +        case AdapNormRespQueue:
3706 +        case AdapHighRespQueue:
3707 +                       OsCv_destroy( &Queue->QueueFull );
3708 +            break;
3709 +    }
3710 +}
3711 +    
3712 +VOID
3713 +InitializeNTQueue(
3714 +       IN PAFA_COMM_ADAPTER Adapter,
3715 +    IN OUT PCOMM_QUE Queue,
3716 +    IN QUEUE_TYPES WhichQueue
3717 +    )
3718 +/*++
3719 +
3720 +Routine Description:
3721 +
3722 +    Will initialize all entries in the queue that is NT specific.
3723 +
3724 +Arguments:
3725 +
3726 +Return Value:
3727 +
3728 +    Nothing there is nothing to allocate so nothing should fail
3729 +
3730 +--*/
3731 +{
3732 +    
3733 +       Queue->NumOutstandingIos = 0;
3734 +
3735 +       //
3736 +       // Store a pointer to the adapter structure.
3737 +       //
3738 +
3739 +       Queue->Adapter = Adapter;
3740 +
3741 +       InitializeListHead( &Queue->OutstandingIoQueue );
3742 +           
3743 +    switch (WhichQueue) {
3744 +
3745 +        case HostNormCmdQueue:
3746 +
3747 +                       OsCv_init( &Queue->CommandReady);
3748 +                       OsSpinLockInit( Queue->QueueLock, Adapter->SpinLockCookie);
3749 +                       if (ddi_add_softintr( Adapter->Dip, DDI_SOFTINT_HIGH, &Queue->ConsumerRoutine, NULL,
3750 +                                                                 NULL, (PUNIX_INTR_HANDLER)HostCommandNormDpc,
3751 +                                                                 (caddr_t)Queue ) != DDI_SUCCESS) {
3752 +
3753 +                               cmn_err(CE_CONT, "OS_addr_intr failed\n");                                      
3754 +                       }                                       
3755 +
3756 +            InitializeListHead(&Queue->CommandQueue);
3757 +
3758 +            break;
3759 +
3760 +        case HostHighCmdQueue:
3761 +
3762 +                       OsCv_init( &Queue->CommandReady);
3763 +                       OsSpinLockInit( Queue->QueueLock, Adapter->SpinLockCookie);
3764 +                       if (ddi_add_softintr( Adapter->Dip, DDI_SOFTINT_HIGH, &Queue->ConsumerRoutine, NULL,
3765 +                                                                 NULL, (PUNIX_INTR_HANDLER)HostCommandHighDpc,
3766 +                                                                 (caddr_t) Queue ) != DDI_SUCCESS) {
3767 +
3768 +                               cmn_err(CE_CONT, "OS_addr_intr failed\n");                                      
3769 +                       }                                       
3770 +
3771 +            InitializeListHead(&Queue->CommandQueue);
3772 +            break;
3773 +
3774 +        case HostNormRespQueue:
3775 +
3776 +                       OsSpinLockInit( Queue->QueueLock, Adapter->SpinLockCookie);
3777 +                       if (ddi_add_softintr( Adapter->Dip, DDI_SOFTINT_HIGH, &Queue->ConsumerRoutine, NULL,
3778 +                                                                 NULL, (PUNIX_INTR_HANDLER)HostResponseNormalDpc, 
3779 +                                                                 (caddr_t) Queue ) != DDI_SUCCESS) {
3780 +
3781 +                               cmn_err(CE_CONT, "OS_addr_intr failed\n");                                      
3782 +                       }                                       
3783 +            break;
3784 +
3785 +        case HostHighRespQueue:
3786 +
3787 +
3788 +                       OsSpinLockInit( Queue->QueueLock, Adapter->SpinLockCookie);
3789 +                       if (ddi_add_softintr( Adapter->Dip, DDI_SOFTINT_HIGH, &Queue->ConsumerRoutine, NULL,
3790 +                                                                 NULL, (PUNIX_INTR_HANDLER)HostResponseHighDpc, 
3791 +                                                                 (caddr_t) Queue ) != DDI_SUCCESS) {
3792 +
3793 +                               cmn_err(CE_CONT, "OS_addr_intr failed\n");                                      
3794 +                       }                                       
3795 +            break;
3796 +
3797 +        case AdapNormCmdQueue:
3798 +        case AdapHighCmdQueue:
3799 +        case AdapNormRespQueue:
3800 +        case AdapHighRespQueue:
3801 +
3802 +                       OsCv_init( &Queue->QueueFull);
3803 +            break;
3804 +    }
3805 +}
3806 +
3807 +BOOLEAN
3808 +StartFsaCommandThreads(PAFA_COMM_ADAPTER Adapter)
3809 +/*++
3810 +
3811 +Routine Description:
3812 +
3813 +    Create and start the command receiver threads.
3814 +
3815 +Arguments:
3816 +
3817 +
3818 +Return Value:
3819 +
3820 +    Nothing
3821 +
3822 +--*/
3823 +
3824 +{
3825 +    return(TRUE);
3826 +}
3827 +
3828 +
3829 +
3830 +/*++
3831 +
3832 +Routine Description:
3833 +
3834 +       This routine gets called to detach all resources that have been allocated for 
3835 +       this adapter.
3836 +
3837 +Arguments:
3838 +
3839 +       Adapter - Pointer to the adapter structure to detach.
3840 +
3841 +Return Value:
3842 +
3843 +    TRUE - All resources have been properly released.
3844 +    FALSE - An error occured while trying to release resources.
3845 +--*/
3846 +BOOLEAN
3847 +AacCommDetachAdapter (IN PAFA_COMM_ADAPTER     Adapter)
3848 +{
3849 +       PAFA_CLASS_DRIVER ClassDriver;
3850 +       //
3851 +       // First remove this adapter from the list of adapters.
3852 +       //
3853 +
3854 +       if (FsaCommData.AdapterList == Adapter) {
3855 +               
3856 +               FsaCommData.AdapterList = Adapter->NextAdapter;
3857 +
3858 +       } else {
3859 +
3860 +               PAFA_COMM_ADAPTER CurrentAdapter, NextAdapter;
3861 +       
3862 +               CurrentAdapter = FsaCommData.AdapterList;
3863 +               NextAdapter = CurrentAdapter->NextAdapter;
3864 +
3865 +               while (NextAdapter) {
3866 +                               
3867 +                       if (NextAdapter == Adapter) {
3868 +
3869 +                               CurrentAdapter->NextAdapter = NextAdapter->NextAdapter;
3870 +                               break;
3871 +                        
3872 +                       }
3873 +                       
3874 +                       CurrentAdapter = NextAdapter;
3875 +                       NextAdapter = CurrentAdapter->NextAdapter;
3876 +               }
3877 +       }                       
3878 +               
3879 +       //
3880 +       // First send a shutdown to the adapter.
3881 +       //
3882 +
3883 +       AfaCommShutdown( Adapter );
3884 +
3885 +       //
3886 +       // Destroy the FibContextZone for this adapter.  This will free up all
3887 +       // of the fib space used by this adapter.
3888 +       //
3889 +       
3890 +       FsaFreeFibContextZone( Adapter );
3891 +
3892 +       //
3893 +       // Destroy the mutex used for synch'ing adapter fibs.
3894 +       //
3895 +
3896 +       OsCvLockDestroy( Adapter->AdapterFibMutex );
3897 +
3898 +       //
3899 +       // Detach all of the host queues.
3900 +       //
3901 +
3902 +    DetachNTQueue( Adapter, &Adapter->CommRegion->AdapHighRespQue, AdapHighRespQueue );
3903 +    DetachNTQueue( Adapter, &Adapter->CommRegion->AdapNormRespQue, AdapNormRespQueue );
3904 +    DetachNTQueue( Adapter, &Adapter->CommRegion->HostHighRespQue, HostHighRespQueue );
3905 +    DetachNTQueue( Adapter, &Adapter->CommRegion->HostNormRespQue, HostNormRespQueue );
3906 +    DetachNTQueue( Adapter, &Adapter->CommRegion->AdapHighCmdQue, AdapHighCmdQueue );
3907 +    DetachNTQueue( Adapter, &Adapter->CommRegion->AdapNormCmdQue, AdapNormCmdQueue );
3908 +    DetachNTQueue( Adapter, &Adapter->CommRegion->HostHighCmdQue, HostHighCmdQueue );
3909 +       DetachNTQueue( Adapter, &Adapter->CommRegion->HostNormCmdQue, HostNormCmdQueue );
3910 +
3911 +       //
3912 +       // Destroy the mutex used to protect the FibContextZone
3913 +       //
3914 +
3915 +       OsSpinLockDestroy( Adapter->FibContextZoneSpinLock );
3916 +
3917 +       //
3918 +       // Call the miniport to free the space allocated for the shared comm queues
3919 +       // between the host and the adapter.
3920 +       //
3921 +
3922 +       FsaFreeAdapterCommArea( Adapter );
3923 +
3924 +       //
3925 +       // Free the memory used by the comm region for this adapter
3926 +       //
3927 +
3928 +       OsFreeMemory( Adapter->CommRegion, sizeof(COMM_REGION) );
3929 +
3930 +       //
3931 +       // Free the memory used by the adapter structure.
3932 +       //
3933 +       ClassDriver = Adapter->ClassDriverList;
3934 +       Adapter->ClassDriverList = Adapter->ClassDriverList->Next;
3935 +       OsFreeMemory( ClassDriver, sizeof(AFA_CLASS_DRIVER) );
3936 +       
3937 +       OsFreeMemory( Adapter, sizeof(AFA_COMM_ADAPTER) );
3938 +
3939 +       return (TRUE);
3940 +}
3941 +
3942 +PVOID
3943 +AfaCommInitNewAdapter (IN PFSA_NEW_ADAPTER NewAdapter)
3944 +{
3945 +       PVOID BugCheckBuffer;
3946 +       PAFA_COMM_ADAPTER Adapter;
3947 +       MAPFIB_CONTEXT MapFibContext;
3948 +       LARGE_INTEGER Time;
3949 +       char ErrorBuffer[60];
3950 +
3951 +       Adapter = (PAFA_COMM_ADAPTER) OsAllocMemory( sizeof(AFA_COMM_ADAPTER) , OS_ALLOC_MEM_SLEEP );
3952 +
3953 +       if (Adapter == NULL)
3954 +               return (NULL);
3955 +
3956 +       RtlZeroMemory(Adapter, sizeof(AFA_COMM_ADAPTER));
3957 +
3958 +
3959 +       //
3960 +       // Save the current adapter number and increment the total number.
3961 +       //
3962 +
3963 +       Adapter->AdapterNumber = FsaCommData.TotalAdapters++;
3964 +
3965 +
3966 +       //
3967 +       // Fill in the pointer back to the device specific structures.
3968 +       // The device specific driver has also passed a pointer for us to 
3969 +       // fill in with the Adapter object that we have created.
3970 +       //
3971 +
3972 +       Adapter->AdapterExtension = NewAdapter->AdapterExtension;
3973 +       Adapter->AdapterFuncs = NewAdapter->AdapterFuncs;
3974 +       Adapter->InterruptsBelowDpc = NewAdapter->AdapterInterruptsBelowDpc;
3975 +       Adapter->AdapterUserVars = NewAdapter->AdapterUserVars;
3976 +       Adapter->AdapterUserVarsSize = NewAdapter->AdapterUserVarsSize;
3977 +
3978 +       Adapter->Dip = NewAdapter->Dip;
3979 +
3980 +       //
3981 +       // Fill in Our address into the function dispatch table
3982 +       //
3983 +
3984 +       NewAdapter->AdapterFuncs->InterruptHost = AfaCommInterruptHost;
3985 +       NewAdapter->AdapterFuncs->OpenAdapter = AfaCommOpenAdapter;
3986 +       NewAdapter->AdapterFuncs->CloseAdapter = AfaCommCloseAdapter;
3987 +       NewAdapter->AdapterFuncs->DeviceControl = AfaCommAdapterDeviceControl;
3988 +
3989 +       //
3990 +       // Ok now init the communication subsystem
3991 +       //
3992 +
3993 +       Adapter->CommRegion = (PCOMM_REGION) OsAllocMemory(sizeof(COMM_REGION), OS_ALLOC_MEM_SLEEP);
3994 +       if (Adapter->CommRegion == NULL) {
3995 +               cmn_err(CE_WARN, "Error could not allocate comm region.\n");
3996 +               return (NULL);
3997 +       }
3998 +       RtlZeroMemory(Adapter->CommRegion, sizeof(COMM_REGION));
3999 +
4000 +       //
4001 +       // Get a pointer to the iblock_cookie
4002 +       //
4003 +
4004 +       ddi_get_soft_iblock_cookie( Adapter->Dip, DDI_SOFTINT_HIGH, &Adapter->SpinLockCookie );
4005 +
4006 +       if (!CommInit(Adapter)) {
4007 +               FsaCommPrint("Failed to init the commuication subsystem.\n");
4008 +               return(NULL);
4009 +       }
4010 +
4011 +
4012 +       //
4013 +       // Initialize the list of AdapterFibContext's.
4014 +       //
4015 +
4016 +       InitializeListHead(&Adapter->AdapterFibContextList);
4017 +
4018 +       //
4019 +       // Initialize the fast mutex used for synchronization of the adapter fibs
4020 +       //
4021 +
4022 +       Adapter->AdapterFibMutex = OsCvLockAlloc();
4023 +       OsCvLockInit(Adapter->AdapterFibMutex, NULL);
4024 +
4025 +    //
4026 +    // Allocate and start the FSA command threads. These threads will handle
4027 +    // command requests from the adapter. They will wait on an event then pull
4028 +    // all CDBs off the thread's queue. Each CDB will be given to a worker thread
4029 +    // upto a defined limit. When that limit is reached wait a event will be waited
4030 +    // on till a worker thread is finished.
4031 +    //
4032 +
4033 +    if (!StartFsaCommandThreads(Adapter)) {
4034 +           FsaCommPrint("Fsainit could not initilize the command receiver threads.\n");
4035 +               return (NULL);
4036 +    }
4037 +
4038 +#ifdef unix_crash_dump
4039 +       //
4040 +       // Allocate and map a fib for use by the synch path, which is used for crash
4041 +       // dumps.
4042 +       //
4043 +       // Allocate an entire page so that alignment is correct.
4044 +       //
4045 +
4046 +       Adapter->SyncFib = OsAllocMemory( PAGE_SIZE, OS_ALLOC_MEM_SLEEP );
4047 +       MapFibContext.Fib = Adapter->SyncFib;
4048 +       MapFibContext.Size = sizeof(FIB);
4049 +       MapFib( Adapter, &MapFibContext );
4050 +       Adapter->SyncFibPhysicalAddress = MapFibContext.LogicalFibAddress.LowPart;
4051 +#endif
4052 +
4053 +       Adapter->CommFuncs.SizeOfAfaCommFuncs = sizeof(AFACOMM_FUNCS);
4054 +
4055 +       Adapter->CommFuncs.AllocateFib = AllocateFib;
4056 +
4057 +       Adapter->CommFuncs.FreeFib = FreeFib;
4058 +       Adapter->CommFuncs.FreeFibFromDpc = FreeFibFromDpc;
4059 +       Adapter->CommFuncs.DeallocateFib = DeallocateFib;
4060 +
4061 +       Adapter->CommFuncs.InitializeFib = InitializeFib;
4062 +       Adapter->CommFuncs.GetFibData = FsaGetFibData;
4063 +       Adapter->CommFuncs.SendFib = SendFib;
4064 +       Adapter->CommFuncs.CompleteFib = CompleteFib;
4065 +       Adapter->CommFuncs.CompleteAdapterFib = CompleteAdapterFib;
4066 +
4067 +       Adapter->CommFuncs.SendSynchFib = SendSynchFib;
4068 +
4069 +       Adapter->CommFuncs.FreeDmaResources = Adapter->AdapterFuncs->FreeDmaResources;
4070 +       Adapter->CommFuncs.BuildSgMap = Adapter->AdapterFuncs->BuildSgMap;
4071 +
4072 +       //
4073 +       // Add this adapter in to our Adapter List.
4074 +       //
4075 +
4076 +       Adapter->NextAdapter = FsaCommData.AdapterList;
4077 +       FsaCommData.AdapterList = Adapter;
4078 +
4079 +       NewAdapter->Adapter = Adapter;
4080 +
4081 +//     AfaDiskInitNewAdapter( Adapter->AdapterNumber, Adapter );
4082 +
4083 +       return (Adapter);
4084 +}
4085 +
4086 +AAC_STATUS
4087 +CommInitialize(
4088 +       PAFA_COMM_ADAPTER Adapter
4089 +       )
4090 +{
4091 +    //
4092 +    //  Now allocate and initialize the zone structures used as our pool
4093 +    //  of FIB context records.  The size of the zone is based on the
4094 +    //  system memory size.  We also initialize the mutex used to protect
4095 +    //  the zone.
4096 +    //
4097 +       Adapter->FibContextZoneSpinLock = OsSpinLockAlloc();
4098 +       OsSpinLockInit( Adapter->FibContextZoneSpinLock, Adapter->SpinLockCookie );
4099 +
4100 +       Adapter->FibContextZoneExtendSize = 64;
4101 +
4102 +       return (STATUS_SUCCESS);
4103 +}
4104 +
4105 +
4106 +    
4107 +/*++
4108 +
4109 +Routine Description:
4110 +
4111 +    Initializes the data structures that are required for the FSA commuication
4112 +    interface to operate.
4113 +
4114 +Arguments:
4115 +
4116 +    None - all global or allocated data.
4117 +
4118 +Return Value:
4119 +
4120 +    TRUE - if we were able to init the commuication interface.
4121 +    FALSE - If there were errors initing. This is a fatal error.
4122 +--*/
4123 +BOOLEAN
4124 +CommInit(PAFA_COMM_ADAPTER Adapter)
4125 +{
4126 +    
4127 +    ULONG SizeOfHeaders = (sizeof(QUEUE_INDEX) * NUMBER_OF_COMM_QUEUES) * 2;
4128 +    ULONG SizeOfQueues = sizeof(QUEUE_ENTRY) * TOTAL_QUEUE_ENTRIES;
4129 +    PQUEUE_INDEX Headers;
4130 +    PQUEUE_ENTRY Queues;
4131 +       ULONG TotalSize;
4132 +       PCOMM_REGION CommRegion = Adapter->CommRegion;
4133 +
4134 +        CommInitialize( Adapter );
4135 +
4136 +       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",
4137 +                         sizeof(QUEUE_ENTRY), sizeof(QUEUE_INDEX), TOTAL_QUEUE_ENTRIES, NUMBER_OF_COMM_QUEUES);
4138 +       //
4139 +       //
4140 +       // Allocate the physically contigous space for the commuication queue
4141 +       // headers. 
4142 +       //
4143 +
4144 +       TotalSize = SizeOfHeaders + SizeOfQueues;
4145 +
4146 +       if (!FsaAllocateAdapterCommArea(Adapter, (PVOID *)&Headers, TotalSize, QUEUE_ALIGNMENT))
4147 +               return (FALSE);
4148 +
4149 +       Queues = (PQUEUE_ENTRY)((PUCHAR)Headers + SizeOfHeaders);
4150 +
4151 +       if (ddi_add_softintr( Adapter->Dip, DDI_SOFTINT_HIGH, &CommRegion->QueueNotFullDpc, NULL,
4152 +                                                 NULL, (PUNIX_INTR_HANDLER)CommonNotFullDpc,
4153 +                                                 (caddr_t)CommRegion ) != DDI_SUCCESS) {
4154 +
4155 +         cmn_err(CE_CONT, "Os_addr_intr failed\n");                                    
4156 +       }                                       
4157 +
4158 +
4159 +    // Adapter to Host normal priority Command queue
4160 +
4161 +
4162 +    CommRegion->HostNormCmdQue.Headers.ProducerIndex = Headers++;
4163 +    CommRegion->HostNormCmdQue.Headers.ConsumerIndex = Headers++;
4164 +    *CommRegion->HostNormCmdQue.Headers.ProducerIndex = HOST_NORM_CMD_ENTRIES;
4165 +    *CommRegion->HostNormCmdQue.Headers.ConsumerIndex = HOST_NORM_CMD_ENTRIES;
4166 +
4167 +    CommRegion->HostNormCmdQue.SavedIrql = 0;
4168 +    CommRegion->HostNormCmdQue.BaseAddress = Queues;
4169 +    CommRegion->HostNormCmdQue.QueueEntries = HOST_NORM_CMD_ENTRIES;
4170 +
4171 +       CommRegion->HostNormCmdQue.QueueLock = OsSpinLockAlloc();
4172 +       if (CommRegion->HostNormCmdQue.QueueLock == NULL) {
4173 +               return (FALSE);
4174 +       }
4175 +    InitializeNTQueue(Adapter, &CommRegion->HostNormCmdQue, HostNormCmdQueue);
4176 +
4177 +    
4178 +    Queues += HOST_NORM_CMD_ENTRIES;
4179 +
4180 +    // Adapter to Host high priority command queue
4181 +    
4182 +    CommRegion->HostHighCmdQue.Headers.ProducerIndex = Headers++;
4183 +    CommRegion->HostHighCmdQue.Headers.ConsumerIndex = Headers++;
4184 +    *CommRegion->HostHighCmdQue.Headers.ProducerIndex = HOST_HIGH_CMD_ENTRIES;
4185 +    *CommRegion->HostHighCmdQue.Headers.ConsumerIndex = HOST_HIGH_CMD_ENTRIES;
4186 +
4187 +    CommRegion->HostHighCmdQue.SavedIrql = 0;
4188 +    CommRegion->HostHighCmdQue.BaseAddress = Queues;
4189 +    CommRegion->HostHighCmdQue.QueueEntries = HOST_HIGH_CMD_ENTRIES;
4190 +//     CommRegion->HostHighCmdQue.QueueLock = (PKSPIN_LOCK) ExAllocatePool(NonPagedPool, sizeof(KSPIN_LOCK));
4191 +       CommRegion->HostHighCmdQue.QueueLock = OsSpinLockAlloc();
4192 +       if (CommRegion->HostHighCmdQue.QueueLock == NULL) {
4193 +               return (FALSE);
4194 +       }
4195 +    InitializeNTQueue(Adapter, &CommRegion->HostHighCmdQue, HostHighCmdQueue);
4196 +    
4197 +    Queues += HOST_HIGH_CMD_ENTRIES;
4198 +
4199 +    // Host to adapter normal priority command queue
4200 +    
4201 +    CommRegion->AdapNormCmdQue.Headers.ProducerIndex = Headers++;
4202 +    CommRegion->AdapNormCmdQue.Headers.ConsumerIndex = Headers++;
4203 +    *CommRegion->AdapNormCmdQue.Headers.ProducerIndex = ADAP_NORM_CMD_ENTRIES;
4204 +    *CommRegion->AdapNormCmdQue.Headers.ConsumerIndex = ADAP_NORM_CMD_ENTRIES;
4205 +
4206 +    CommRegion->AdapNormCmdQue.SavedIrql = 0;    
4207 +    CommRegion->AdapNormCmdQue.BaseAddress = Queues;
4208 +    CommRegion->AdapNormCmdQue.QueueEntries = ADAP_NORM_CMD_ENTRIES;
4209 +    InitializeNTQueue(Adapter, &CommRegion->AdapNormCmdQue, AdapNormCmdQueue);
4210 +    
4211 +    Queues += ADAP_NORM_CMD_ENTRIES;
4212 +
4213 +    // host to adapter high priority command queue
4214 +    
4215 +    CommRegion->AdapHighCmdQue.Headers.ProducerIndex = Headers++;
4216 +    CommRegion->AdapHighCmdQue.Headers.ConsumerIndex = Headers++;
4217 +    *CommRegion->AdapHighCmdQue.Headers.ProducerIndex = ADAP_HIGH_CMD_ENTRIES;
4218 +    *CommRegion->AdapHighCmdQue.Headers.ConsumerIndex = ADAP_HIGH_CMD_ENTRIES;
4219 +
4220 +    CommRegion->AdapHighCmdQue.SavedIrql = 0;    
4221 +    CommRegion->AdapHighCmdQue.BaseAddress = Queues;
4222 +    CommRegion->AdapHighCmdQue.QueueEntries = ADAP_HIGH_CMD_ENTRIES;
4223 +    InitializeNTQueue(Adapter, &CommRegion->AdapHighCmdQue, AdapHighCmdQueue);
4224 +    
4225 +    Queues += ADAP_HIGH_CMD_ENTRIES;
4226 +
4227 +    // adapter to host normal priority response queue
4228 +    
4229 +    CommRegion->HostNormRespQue.Headers.ProducerIndex = Headers++;
4230 +    CommRegion->HostNormRespQue.Headers.ConsumerIndex = Headers++;
4231 +    *CommRegion->HostNormRespQue.Headers.ProducerIndex = HOST_NORM_RESP_ENTRIES;
4232 +    *CommRegion->HostNormRespQue.Headers.ConsumerIndex = HOST_NORM_RESP_ENTRIES;
4233 +
4234 +    CommRegion->HostNormRespQue.SavedIrql = 0;    
4235 +    CommRegion->HostNormRespQue.BaseAddress = Queues;
4236 +    CommRegion->HostNormRespQue.QueueEntries = HOST_NORM_RESP_ENTRIES;
4237 +//     CommRegion->HostNormRespQue.QueueLock = (PKSPIN_LOCK) ExAllocatePool(NonPagedPool, sizeof(KSPIN_LOCK));
4238 +       CommRegion->HostNormRespQue.QueueLock = OsSpinLockAlloc();
4239 +       if (CommRegion->HostNormRespQue.QueueLock == NULL) {
4240 +               return (FALSE);
4241 +       }
4242 +    InitializeNTQueue(Adapter, &CommRegion->HostNormRespQue, HostNormRespQueue);
4243 +    
4244 +    Queues += HOST_NORM_RESP_ENTRIES;
4245 +
4246 +    // adapter to host high priority response queue
4247 +    
4248 +    CommRegion->HostHighRespQue.Headers.ProducerIndex = Headers++;
4249 +    CommRegion->HostHighRespQue.Headers.ConsumerIndex = Headers++;
4250 +    *CommRegion->HostHighRespQue.Headers.ProducerIndex = HOST_HIGH_RESP_ENTRIES;
4251 +    *CommRegion->HostHighRespQue.Headers.ConsumerIndex = HOST_HIGH_RESP_ENTRIES;
4252 +
4253 +    CommRegion->HostHighRespQue.SavedIrql = 0;    
4254 +    CommRegion->HostHighRespQue.BaseAddress = Queues;
4255 +    CommRegion->HostHighRespQue.QueueEntries = HOST_HIGH_RESP_ENTRIES;
4256 +//     CommRegion->HostHighRespQue.QueueLock = (PKSPIN_LOCK) ExAllocatePool(NonPagedPool, sizeof(KSPIN_LOCK));
4257 +       CommRegion->HostHighRespQue.QueueLock = OsSpinLockAlloc();
4258 +       if (CommRegion->HostHighRespQue.QueueLock == NULL) {
4259 +               return (FALSE);
4260 +       }
4261 +    InitializeNTQueue(Adapter, &CommRegion->HostHighRespQue, HostHighRespQueue);
4262 +    
4263 +    Queues += HOST_HIGH_RESP_ENTRIES;
4264 +
4265 +    // host to adapter normal priority response queue
4266 +    
4267 +    CommRegion->AdapNormRespQue.Headers.ProducerIndex = Headers++;
4268 +    CommRegion->AdapNormRespQue.Headers.ConsumerIndex = Headers++;
4269 +    *CommRegion->AdapNormRespQue.Headers.ProducerIndex = ADAP_NORM_RESP_ENTRIES;
4270 +    *CommRegion->AdapNormRespQue.Headers.ConsumerIndex = ADAP_NORM_RESP_ENTRIES;
4271 +
4272 +    CommRegion->AdapNormRespQue.SavedIrql = 0;    
4273 +    CommRegion->AdapNormRespQue.BaseAddress = Queues;
4274 +    CommRegion->AdapNormRespQue.QueueEntries = ADAP_NORM_RESP_ENTRIES;
4275 +    InitializeNTQueue(Adapter, &CommRegion->AdapNormRespQue, AdapNormRespQueue);
4276 +    
4277 +    Queues += ADAP_NORM_RESP_ENTRIES;
4278 +
4279 +    // host to adapter high priority response queue
4280 +    
4281 +    CommRegion->AdapHighRespQue.Headers.ProducerIndex = Headers++;
4282 +    CommRegion->AdapHighRespQue.Headers.ConsumerIndex = Headers++;
4283 +    *CommRegion->AdapHighRespQue.Headers.ProducerIndex = ADAP_HIGH_RESP_ENTRIES;
4284 +    *CommRegion->AdapHighRespQue.Headers.ConsumerIndex = ADAP_HIGH_RESP_ENTRIES;
4285 +
4286 +    CommRegion->AdapHighRespQue.SavedIrql = 0;    
4287 +    CommRegion->AdapHighRespQue.BaseAddress = Queues;
4288 +    CommRegion->AdapHighRespQue.QueueEntries = ADAP_HIGH_RESP_ENTRIES;
4289 +    InitializeNTQueue(Adapter, &CommRegion->AdapHighRespQue, AdapHighRespQueue);
4290 +
4291 +       CommRegion->AdapNormCmdQue.QueueLock = CommRegion->HostNormRespQue.QueueLock;
4292 +       CommRegion->AdapHighCmdQue.QueueLock = CommRegion->HostHighRespQue.QueueLock;
4293 +       CommRegion->AdapNormRespQue.QueueLock = CommRegion->HostNormCmdQue.QueueLock;
4294 +       CommRegion->AdapHighRespQue.QueueLock = CommRegion->HostHighCmdQue.QueueLock;
4295 +
4296 +    return(TRUE);
4297 +}
4298 +
4299 +AAC_STATUS
4300 +AfaCommShutdown(
4301 +       PAFA_COMM_ADAPTER Adapter
4302 +       )
4303 +/*++
4304 +
4305 +Routine Description:
4306 +
4307 +       This routine will send a shutdown request to each adapter.
4308 +
4309 +Arguments:
4310 +
4311 +       Adapter - which adapter to send the shutdown to.
4312 +
4313 +Return Value:
4314 +
4315 +    NT Status success.
4316 +
4317 +--*/
4318 +
4319 +{
4320 +       PFIB_CONTEXT FibContext;
4321 +       PCLOSECOMMAND CloseCommand;
4322 +       AAC_STATUS Status;
4323 +
4324 +       FibContext = AllocateFib( Adapter );
4325 +
4326 +       InitializeFib( FibContext );
4327 +
4328 +       CloseCommand = (PCLOSECOMMAND) FsaGetFibData( FibContext );
4329 +
4330 +       CloseCommand->Command = VM_CloseAll;
4331 +       CloseCommand->ContainerId = 0xffffffff;
4332 +
4333 +       Status = SendFib( ContainerCommand, FibContext, sizeof(CLOSECOMMAND), FsaNormal, TRUE, NULL, TRUE, NULL, NULL );
4334 +
4335 +       if (Status != STATUS_SUCCESS) {
4336 +
4337 +               FreeFib( FibContext );
4338 +
4339 +               goto ret;
4340 +
4341 +       }
4342 +
4343 +       CompleteFib( FibContext );
4344 +
4345 +       FreeFib( FibContext );
4346 +
4347 +
4348 +       Status = STATUS_SUCCESS;
4349 +
4350 +ret:
4351 +
4352 +       return (Status);
4353 +
4354 +}
4355 +
4356 +VOID
4357 +AfaCommBugcheckHandler(
4358 +               IN PVOID Buffer,
4359 +               IN ULONG Length
4360 +               )
4361 +/*++
4362 +
4363 +Routine Description:
4364 +
4365 +       This routine will shutdown the adapter if there is a bugcheck and
4366 +       copy the shutdown data from the adapter response into the buffer
4367 +       so it will show up in the host dump file.
4368 +p
4369 +Arguments:
4370 +
4371 +       Buffer - This buffer will be written to the host dump by nt for us.
4372 +
4373 +       Length - The size of the buffer.
4374 +
4375 +Return Value:
4376 +
4377 +       N/A
4378 +
4379 +--*/
4380 +{
4381 +       PAFA_COMM_ADAPTER Adapter = FsaCommData.AdapterList;
4382 +
4383 +       while (Adapter) {
4384 +
4385 +               NotifyAdapter(Adapter, HostShutdown);
4386 +
4387 +               Adapter = Adapter->NextAdapter;
4388 +
4389 +       }
4390 +
4391 +}      
4392 +
4393 +VOID
4394 +FsaCommLogEvent(
4395 +       PFIB_CONTEXT FibContext, 
4396 +       PDEVICE_OBJECT DeviceObject,
4397 +       AAC_STATUS FsaStatus,
4398 +       AAC_STATUS AacStatus,
4399 +       ULONG LocationCode,
4400 +       USHORT Category,
4401 +       PUCHAR String,
4402 +       BOOLEAN DumpFib
4403 +)
4404 +{
4405 +}
4406 +
4407 +AfaCommProbeDisks(
4408 +       PAFA_COMM_ADAPTER       Adapter
4409 +       )
4410 +{
4411 +    PMNTINFO DiskInfo;
4412 +    PMNTINFORESPONSE DiskInfoResponse;
4413 +       AAC_STATUS Status;
4414 +       PCOMM_FIB_CONTEXT FibContext;
4415 +    
4416 +       FibContext = AllocateFib( Adapter );
4417 +
4418 +       InitializeFib( FibContext );
4419 +
4420 +       DiskInfo = (PMNTINFO) FibContext->Fib->data;
4421 +       DiskInfo->Command = VM_NameServe;
4422 +       DiskInfo->MntCount = 0;
4423 +       DiskInfo->MntType = FT_FILESYS;
4424 +
4425 +    Status = SendFib(ContainerCommand,
4426 +                            FibContext,
4427 +                        sizeof(MNTINFO),
4428 +                        FsaNormal,
4429 +                        TRUE,
4430 +                        NULL,
4431 +                        TRUE,
4432 +                        NULL,
4433 +                        NULL);
4434 +
4435 +       DiskInfoResponse = (PMNTINFORESPONSE) FibContext->Fib->data;
4436 +
4437 +       if (DiskInfoResponse->MntRespCount) {
4438 +
4439 +               cmn_err(CE_CONT, "container found on adapter, size = 0x%x blocks\n", 
4440 +                               DiskInfoResponse->MntTable[0].Capacity);
4441 +                               
4442 +       } else {
4443 +       
4444 +               cmn_err(CE_CONT, "no containers found on adapter\n");
4445 +               
4446 +       }
4447 +                                       
4448 +       CompleteFib( FibContext );
4449 +       
4450 +       FreeFib( FibContext );                           
4451 +}
4452 +
4453 +
4454 diff -burN linux-2.4.7/drivers/scsi/aacraid/commsup.c linux/drivers/scsi/aacraid/commsup.c
4455 --- linux-2.4.7/drivers/scsi/aacraid/commsup.c  Wed Dec 31 18:00:00 1969
4456 +++ linux/drivers/scsi/aacraid/commsup.c        Sat Jul 21 17:55:13 2001
4457 @@ -0,0 +1,2185 @@
4458 +/*++
4459 + * Adaptec aacraid device driver for Linux.
4460 + *
4461 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
4462 + *
4463 + * This program is free software; you can redistribute it and/or modify
4464 + * it under the terms of the GNU General Public License as published by
4465 + * the Free Software Foundation; either version 2, or (at your option)
4466 + * any later version.
4467 + *
4468 + * This program is distributed in the hope that it will be useful,
4469 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
4470 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
4471 + * GNU General Public License for more details.
4472 + *
4473 + * You should have received a copy of the GNU General Public License
4474 + * along with this program; see the file COPYING.  If not, write to
4475 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
4476 + *
4477 + * Module Name:
4478 + *  commsup.c
4479 + *
4480 + * Abstract: Contain all routines that are required for FSA host/adapter
4481 + *    commuication.
4482 + *
4483 + *
4484 + --*/
4485 +
4486 +static char *ident_commsup = "aacraid_ident commsup.c 1.0.7 2000/10/11 Adaptec, Inc.";
4487 +
4488 +#include "comprocs.h"
4489 +
4490 +#define BugCheckFileId                   (FSAFS_BUG_CHECK_COMMSUP)
4491 +
4492 +int CommPrinting;
4493 +
4494 +void
4495 +ThrottleExceptionHandler(
4496 +       IN PCOMM_REGION CommRegion,
4497 +       AAC_STATUS              Status
4498 +       );
4499 +
4500 +void ThrottlePeriodEndDpcRtn(
4501 +    IN PKDPC Dpc,
4502 +    IN PVOID DeferredContext,
4503 +    IN PVOID SystemArgument1,
4504 +    IN PVOID SystemArgument2
4505 +    );
4506 +
4507 +
4508 +/*++
4509 +
4510 +Routine Description:
4511 +
4512 +       This routine will free all resources used by a given FibContextSegment.
4513 +
4514 +Arguments:
4515 +
4516 +       Adapter - The adapter that this COMM_FIB_CONTEXT will communicate with.
4517 +       ZoneSegment - The segment to release resources from.
4518 +
4519 +Return Value:
4520 +
4521 +       TRUE - All resources were properly freed.
4522 +       FALSE - An Error occured while freeing resources.
4523 +
4524 +--*/
4525 +BOOLEAN
4526 +FsaFreeFibContextSegment (PAFA_COMM_ADAPTER Adapter,
4527 +                                                 PFIB_CONTEXT_ZONE_SEGMENT     ZoneSegment)
4528 +{
4529 +       PCOMM_FIB_CONTEXT FibContext;
4530 +       int i;
4531 +       
4532 +       // Account for the ZONE_SEGMENT_HEADER before the first actual FibContext.
4533 +
4534 +       for (i = 0, FibContext = (PCOMM_FIB_CONTEXT)((PUCHAR)ZoneSegment->FibContextSegment + sizeof(ZONE_SEGMENT_HEADER));
4535 +                i < ZoneSegment->ExtendSize; i++, FibContext++) {
4536 +
4537 +               OsCvLockDestroy( FibContext->FsaEventMutex );
4538 +               OsCv_destroy( &FibContext->FsaEvent );
4539 +
4540 +       }
4541 +
4542 +       UnmapAndFreeFibSpace( Adapter, &ZoneSegment->MapFibContext );
4543 +
4544 +       OsFreeMemory( ZoneSegment->FibContextSegment, ZoneSegment->FibContextSegmentSize );
4545 +
4546 +       OsFreeMemory( ZoneSegment, sizeof( FIB_CONTEXT_ZONE_SEGMENT ) );
4547 +
4548 +       return (TRUE);
4549 +}
4550 +
4551 +BOOLEAN
4552 +FsaFreeFibContextZone(
4553 +       PAFA_COMM_ADAPTER Adapter
4554 +       )
4555 +/*++
4556 +
4557 +Routine Description:
4558 +
4559 +       This routine will walk through the FibContextSegmentList and free up all
4560 +       resources used by the FibContextZone.
4561 +
4562 +Arguments:
4563 +
4564 +       Adapter - The adapter that this COMM_FIB_CONTEXT will communicate with.
4565 +
4566 +Return Value:
4567 +
4568 +       TRUE - All resources were properly freed.
4569 +       FALSE - An Error occured while freeing resources.
4570 +
4571 +--*/
4572 +
4573 +{
4574 +       PFIB_CONTEXT_ZONE_SEGMENT ZoneSegment, NextZoneSegment;
4575 +
4576 +       ZoneSegment = Adapter->FibContextSegmentList;
4577 +
4578 +       while (ZoneSegment) {
4579 +
4580 +               NextZoneSegment = ZoneSegment->Next;
4581 +
4582 +               FsaFreeFibContextSegment( Adapter, ZoneSegment );
4583 +
4584 +               ZoneSegment = NextZoneSegment;
4585 +       }
4586 +
4587 +       return (TRUE);
4588 +}
4589 +
4590 +       
4591 +
4592 +BOOLEAN
4593 +FsaExtendFibContextZone (IN PAFA_COMM_ADAPTER Adapter)
4594 +{
4595 +    int ExtendSize;
4596 +    KIRQL SavedIrql;
4597 +       ULONG ZoneSegmentAllocSize, FibAllocSize;
4598 +       PVOID FibContextSegment;
4599 +       PCOMM_FIB_CONTEXT FibContext;
4600 +       PFIB Fib;
4601 +       PVOID FibPhysicalAddress;
4602 +       int i;
4603 +       PFIB_CONTEXT_ZONE_SEGMENT ZoneSegment;
4604 +       
4605 +       //
4606 +       // Allocate space to describe this zone segment.
4607 +       //
4608 +
4609 +       cmn_err (CE_DEBUG, "Entered FsaExtendFibContextZone");
4610 +       ZoneSegment = OsAllocMemory( sizeof( FIB_CONTEXT_ZONE_SEGMENT ), OS_ALLOC_MEM_SLEEP );
4611 +       if (ZoneSegment == NULL) {
4612 +               return (FALSE);
4613 +       }
4614 +
4615 +       ExtendSize = Adapter->FibContextZoneExtendSize;
4616 +       ZoneSegmentAllocSize = (ExtendSize * sizeof(COMM_FIB_CONTEXT)) + sizeof(ZONE_SEGMENT_HEADER);
4617 +
4618 +       FibContextSegment = OsAllocMemory( ZoneSegmentAllocSize, OS_ALLOC_MEM_SLEEP );
4619 +
4620 +       if (FibContextSegment == NULL) {
4621 +               OsFreeMemory(ZoneSegment);
4622 +               return (FALSE);
4623 +       }       
4624 +
4625 +       RtlZeroMemory( FibContextSegment, ZoneSegmentAllocSize );
4626 +
4627 +       ZoneSegment->FibContextSegment = FibContextSegment;
4628 +       ZoneSegment->FibContextSegmentSize = ZoneSegmentAllocSize;
4629 +       ZoneSegment->ExtendSize = ExtendSize;
4630 +
4631 +       FibAllocSize = ExtendSize * sizeof(FIB);
4632 +
4633 +
4634 +       ZoneSegment->MapFibContext.Size = FibAllocSize;
4635 +
4636 +       AllocateAndMapFibSpace( Adapter, &ZoneSegment->MapFibContext );
4637 +
4638 +       Fib = ZoneSegment->MapFibContext.FibVirtualAddress;
4639 +       FibPhysicalAddress = ZoneSegment->MapFibContext.FibPhysicalAddress;
4640 +
4641 +       RtlZeroMemory( Fib, FibAllocSize );
4642 +
4643 +       // Account for the ZONE_SEGMENT_HEADER before the first actual FibContext.
4644 +
4645 +       for (i = 0, FibContext = (PCOMM_FIB_CONTEXT)((PUCHAR)FibContextSegment + sizeof(ZONE_SEGMENT_HEADER));
4646 +                i < ExtendSize; i++, FibContext++) {
4647 +
4648 +               FibContext->Adapter = Adapter;
4649 +
4650 +               FibContext->Fib = Fib;
4651 +               FibContext->FibData = (PVOID) FibContext->Fib->data;
4652 +
4653 +               OsCv_init( &FibContext->FsaEvent);
4654 +               FibContext->FsaEventMutex = OsCvLockAlloc();
4655 +               OsCvLockInit( FibContext->FsaEventMutex, Adapter->SpinLockCookie );
4656 +
4657 +               Fib->Header.XferState = 0xffffffff;
4658 +               Fib->Header.SenderSize = sizeof(FIB);
4659 +
4660 +               FibContext->LogicalFibAddress.LowPart = (ULONG) FibPhysicalAddress;
4661 +
4662 +               Fib = (PFIB)((PUCHAR)Fib + sizeof(FIB));
4663 +               FibPhysicalAddress = (PVOID)((PUCHAR)FibPhysicalAddress + sizeof(FIB));
4664 +       }
4665 +
4666 +       //
4667 +       // If FibContextZone.TotalSegmentSize is non-zero, then a zone has already been
4668 +       // initialized, we just need to extend it.
4669 +       //
4670 +
4671 +       if (Adapter->FibContextZone.TotalSegmentSize) {
4672 +
4673 +               OsSpinLockAcquire( Adapter->FibContextZoneSpinLock );
4674 +
4675 +               ExExtendZone( &Adapter->FibContextZone,
4676 +                                         FibContextSegment,
4677 +                                         ZoneSegmentAllocSize );
4678 +
4679 +               OsSpinLockRelease( Adapter->FibContextZoneSpinLock );
4680 +
4681 +       } else {
4682 +
4683 +           if (ExInitializeZone( &Adapter->FibContextZone,
4684 +                                                         sizeof(COMM_FIB_CONTEXT),
4685 +                             FibContextSegment,
4686 +                                 ZoneSegmentAllocSize ) != STATUS_SUCCESS)
4687 +                       FsaBugCheck(0,0,0);
4688 +
4689 +       }
4690 +
4691 +       //
4692 +       // Add this segment to the adapter's list of segments
4693 +       //
4694 +
4695 +       ZoneSegment->Next = Adapter->FibContextSegmentList;
4696 +       Adapter->FibContextSegmentList = ZoneSegment;
4697 +
4698 +       return (TRUE);
4699 +}
4700 +
4701 +
4702 +
4703 +/*++
4704 +
4705 +Routine Description:
4706 +
4707 +    This routine creates a new COMM_FIB_CONTEXT record
4708 +
4709 +Arguments:
4710 +
4711 +       Adapter - The adapter that this COMM_FIB_CONTEXT will communicate with.
4712 +
4713 +Return Value:
4714 +
4715 +    PCOMM_FIB_CONTEXT - returns a pointer to the newly allocate COMM_FIB_CONTEXT Record
4716 +
4717 +--*/
4718 +PFIB_CONTEXT
4719 +AllocateFib (IN PVOID AdapterArg)
4720 +{
4721 +       PAFA_COMM_ADAPTER Adapter = (PAFA_COMM_ADAPTER) AdapterArg;
4722 +    KIRQL SavedIrql;
4723 +    PCOMM_FIB_CONTEXT FibContext;
4724 +       int FullZoneLoopCounter = 0;
4725 +        
4726 +
4727 +        //
4728 +       // Acquire the zone spin lock, and check to see if the zone is full.
4729 +       // If it is, then release the spin lock and allocate more fibs for the 
4730 +       // zone.  The ExtendFibZone routine will re-acquire the spin lock to add
4731 +       // the new fibs onto the zone.
4732 +        //
4733 +
4734 +    OsSpinLockAcquire( Adapter->FibContextZoneSpinLock );
4735 +
4736 +    while (ExIsFullZone( &Adapter->FibContextZone )) {
4737 +
4738 +               if (++FullZoneLoopCounter >  10)
4739 +                       FsaBugCheck(0,0,0);
4740 +
4741 +               OsSpinLockRelease( Adapter->FibContextZoneSpinLock );
4742 +
4743 +                // bmb debug
4744 +                cmn_err (CE_DEBUG, "Extending FibContextZone");
4745 +               if (FsaExtendFibContextZone(Adapter) == FALSE) {
4746 +                       return (NULL);
4747 +               }
4748 +
4749 +                OsSpinLockAcquire( Adapter->FibContextZoneSpinLock );
4750 +
4751 +       }
4752 +
4753 +    //
4754 +       //  At this point we now know that the zone has at least one more
4755 +    //  IRP context record available.  So allocate from the zone and
4756 +    //  then release the mutex.
4757 +    //
4758 +
4759 +    FibContext = (PCOMM_FIB_CONTEXT) ExAllocateFromZone( &Adapter->FibContextZone );
4760 +
4761 +       OsSpinLockRelease( Adapter->FibContextZoneSpinLock );
4762 +
4763 +    //
4764 +    //  Set the proper node type code and node byte size
4765 +    //
4766 +
4767 +    FibContext->NodeTypeCode = FSAFS_NTC_FIB_CONTEXT;
4768 +    FibContext->NodeByteSize = sizeof( COMM_FIB_CONTEXT );
4769 +
4770 +       // 
4771 +       // Null out fields that depend on being zero at the start of each I/O
4772 +       //
4773 +
4774 +       FibContext->Fib->Header.XferState = 0;
4775 +       FibContext->FibCallback = NULL;
4776 +       FibContext->FibCallbackContext = NULL;
4777 +
4778 +
4779 +    //
4780 +    //  return and tell the caller
4781 +    //
4782 +
4783 +    return ((PFIB_CONTEXT) FibContext);
4784 +}
4785 +
4786 +
4787 +/*++
4788 +
4789 +Routine Description:
4790 +
4791 +    This routine deallocates and removes the specified COMM_FIB_CONTEXT record
4792 +    from the Fsafs in memory data structures.  It should only be called
4793 +    by FsaCompleteRequest.
4794 +
4795 +Arguments:
4796 +
4797 +       FibContext - Supplies the COMM_FIB_CONTEXT to remove
4798 +
4799 +Return Value:
4800 +
4801 +    None
4802 +
4803 +--*/
4804 +VOID
4805 +FreeFib (IN PFIB_CONTEXT Context)
4806 +{
4807 +    KIRQL SavedIrql;
4808 +       PCOMM_FIB_CONTEXT FibContext = Context;
4809 +
4810 +    ASSERT(FibContext->NodeTypeCode == FSAFS_NTC_FIB_CONTEXT);
4811 +
4812 +    OsSpinLockAcquire( FibContext->Adapter->FibContextZoneSpinLock );
4813 +
4814 +       if (FibContext->Flags & FIB_CONTEXT_FLAG_TIMED_OUT) {
4815 +
4816 +               FsaCommData.TimedOutFibs++;
4817 +
4818 +               FibContext->Next = FibContext->Adapter->FibContextTimedOutList;
4819 +               FibContext->Adapter->FibContextTimedOutList = FibContext;
4820 +
4821 +       } else {
4822 +
4823 +           ASSERT(FibContext->Fib->Header.XferState == 0);
4824 +
4825 +               if (FibContext->Fib->Header.XferState != 0) {
4826 +                               cmn_err(CE_WARN, "FreeFib, XferState != 0, FibContext = 0x%x, XferState = 0x%x\n", 
4827 +                                        FibContext, FibContext->Fib->Header.XferState);
4828 +               }
4829 +
4830 +           ExFreeToZone( &FibContext->Adapter->FibContextZone, FibContext );
4831 +
4832 +       }       
4833 +
4834 +       OsSpinLockRelease( FibContext->Adapter->FibContextZoneSpinLock );
4835 +
4836 +    //
4837 +    //  return and tell the caller
4838 +    //
4839 +
4840 +    return;
4841 +}
4842 +
4843 +
4844 +/*++
4845 +
4846 +Routine Description:
4847 +
4848 +    This routine deallocates and removes the specified COMM_FIB_CONTEXT record
4849 +    from the Fsafs in memory data structures.  It should only be called
4850 +    from the dpc routines to from dpc to free an FibContext from an async or
4851 +       no response io
4852 +
4853 +Arguments:
4854 +
4855 +    FibContext - Supplies the COMM_FIB_CONTEXT to remove
4856 +
4857 +Return Value:
4858 +
4859 +    None
4860 +
4861 +--*/
4862 +VOID
4863 +FreeFibFromDpc (IN PFIB_CONTEXT Context)
4864 +{
4865 +    PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
4866 +
4867 +    ASSERT(FibContext->NodeTypeCode == FSAFS_NTC_FIB_CONTEXT);
4868 +
4869 +    OsSpinLockAcquire(FibContext->Adapter->FibContextZoneSpinLock);
4870 +
4871 +       if (FibContext->Flags & FIB_CONTEXT_FLAG_TIMED_OUT) {
4872 +
4873 +               FsaCommData.TimedOutFibs++;
4874 +
4875 +               FibContext->Next = FibContext->Adapter->FibContextTimedOutList;
4876 +               FibContext->Adapter->FibContextTimedOutList = FibContext;
4877 +
4878 +       } else {
4879 +
4880 +           ASSERT(FibContext->Fib->Header.XferState == 0);
4881 +
4882 +               if (FibContext->Fib->Header.XferState != 0) {
4883 +                               cmn_err(CE_WARN, "FreeFibFromDpc, XferState != 0, FibContext = 0x%x, XferState = 0x%x\n", 
4884 +                                        FibContext, FibContext->Fib->Header.XferState);
4885 +               }
4886 +
4887 +
4888 +           ExFreeToZone( &FibContext->Adapter->FibContextZone, FibContext );
4889 +
4890 +       }
4891 +               
4892 +       OsSpinLockRelease(FibContext->Adapter->FibContextZoneSpinLock);
4893 +
4894 +    //
4895 +    //  return and tell the caller
4896 +    //
4897 +
4898 +    return;
4899 +}
4900 +
4901 +
4902 +/*++
4903 +
4904 +Routine Description:
4905 +
4906 +    Will initialize a FIB of the requested size.
4907 +    
4908 +Arguments:
4909 +
4910 +    Fib is a pointer to a location which will receive the address of the allocated
4911 +        FIB.
4912 +
4913 +    Size is the size of the Fib to allocate.
4914 +
4915 +Return Value:
4916 +
4917 +    NT_SUCCESS if a Fib was returned to the caller.
4918 +    NT_ERROR if event was an invalid event. 
4919 +
4920 +--*/
4921 +AAC_STATUS
4922 +InitializeFib (IN PFIB_CONTEXT Context)
4923 +{
4924 +    PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
4925 +       PFIB Fib = FibContext->Fib;
4926 +
4927 +    Fib->Header.StructType = TFib;
4928 +    Fib->Header.Size = sizeof(FIB);
4929 +//    if (Fib->Header.XferState & AllocatedFromPool)
4930 +//        Fib->Header.XferState = HostOwned | FibInitialized | FibEmpty | AllocatedFromPool;
4931 +//    else
4932 +        Fib->Header.XferState = HostOwned | FibInitialized | FibEmpty | FastResponseCapable;
4933 +    Fib->Header.SenderFibAddress = 0;
4934 +    Fib->Header.ReceiverFibAddress = 0;
4935 +    Fib->Header.SenderSize = sizeof(FIB);
4936 +
4937 +    return(STATUS_SUCCESS);
4938 +}
4939 +    
4940 +
4941 +/*++
4942 +
4943 +Routine Description:
4944 +
4945 +    Will allocate and initialize a FIB of the requested size and return a
4946 +    pointer to the structure. The size allocated may be larger than the size
4947 +    requested due to allocation performace optimizations.
4948 +    
4949 +Arguments:
4950 +
4951 +    Fib is a pointer to a location which will receive the address of the allocated
4952 +        FIB.
4953 +
4954 +    Size is the size of the Fib to allocate.
4955 +
4956 +    JustInitialize is a boolean which indicates a Fib has been allocated most likly in an
4957 +        imbedded structure the FS always allocates. So just initiaize it and return.
4958 +    
4959 +Return Value:
4960 +
4961 +    NT_SUCCESS if a Fib was returned to the caller.
4962 +    NT_ERROR if event was an invalid event. 
4963 +
4964 +--*/
4965 +AAC_STATUS
4966 +AllocatePoolFib (OUT PFIB *Fib, IN USHORT Size)
4967 +{}
4968 +    
4969 +
4970 +/*++
4971 +
4972 +Routine Description:
4973 +
4974 +    Will deallocate and return to the free pool the FIB pointed to by the
4975 +    caller. Upon return accessing locations pointed to by the FIB parameter
4976 +    could cause system access faults.
4977 +
4978 +Arguments:
4979 +
4980 +    Fib is a pointer to the FIB that caller wishes to deallocate.
4981 +    
4982 +Return Value:
4983 +
4984 +    NT_SUCCESS if a Fib was returned to the caller.
4985 +    NT_ERROR if event was an invalid event. 
4986 +
4987 +--*/
4988 +AAC_STATUS
4989 +DeallocateFib (PFIB_CONTEXT Context)
4990 +{
4991 +    PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
4992 +       PFIB Fib = FibContext->Fib;
4993 +
4994 +    if ( Fib->Header.StructType != TFib ) {
4995 +        FsaCommPrint("Error CompleteFib called with a non Fib structure.\n");
4996 +        return(STATUS_UNSUCCESSFUL);
4997 +    }
4998 +
4999 +
5000 +    Fib->Header.XferState = 0;        
5001 +        
5002 +    return(STATUS_SUCCESS);
5003 +
5004 +}
5005 +
5006 +
5007 +AAC_STATUS
5008 +GetResponse(
5009 +    IN PCOMM_QUE ResponseQueue,
5010 +    OUT PFIB Fib
5011 +    )
5012 +/*++
5013 +
5014 +Routine Description:
5015 +
5016 +    Gets a QE off the requested response queue and gets the response FIB into
5017 +    host memory. The FIB may already be in host memory depending on the bus
5018 +    interface, or may require the host to DMA it over from the adapter. The routine
5019 +    will return the FIB to the caller.
5020 +
5021 +Arguments:
5022 +
5023 +    ResponseQueue - Is the queue the caller wishes to have the response gotten from.
5024 +    Fib - Is the Fib which was the response from the adapter
5025 +
5026 +Return Value:
5027 +
5028 +    NT_SUCCESS if a Fib was returned to the caller.
5029 +    NT_ERROR if there was no Fib to return to the caller.
5030 +    bkpfix - add in all the other possible errors ect
5031 +
5032 +--*/
5033 +{
5034 +return(STATUS_UNSUCCESSFUL);
5035 +}
5036 +
5037 +//
5038 +// Commuication primitives define and support the queuing method we use to
5039 +// support host to adapter commuication. All queue accesses happen through
5040 +// these routines and are the only routines which have a knowledge of the
5041 +// how these queues are implemented.
5042 +//
5043 +
5044 +
5045 +/*++
5046 +
5047 +Routine Description:
5048 +
5049 +    With a priority the routine returns a queue entry if the queue has free entries. If the queue
5050 +    is full(no free entries) than no entry is returned and the function returns FALSE otherwise TRUE is
5051 +    returned.
5052 +
5053 +Arguments:
5054 +
5055 +    Priority is an enumerated type which determines which priority level
5056 +        command queue the QE is going to be queued on.
5057 +
5058 +    Entry is a pointer to the address of where to return the address of
5059 +        the queue entry from the requested command queue.
5060 +
5061 +    Index is a pointer to the address of where to store the index of the new
5062 +        queue entry returned.
5063 +
5064 +       DontInterrupt - We set this true if the queue state is such that we don't
5065 +               need to interrupt the adapter for this queue entry.
5066 +
5067 +Return Value:
5068 +
5069 +    TRUE - If a queue entry is returned
5070 +    FALSE - If there are no free queue entries on the requested command queue.
5071 +
5072 +--*/
5073 +BOOLEAN
5074 +GetEntry (IN PAFA_COMM_ADAPTER Adapter, IN QUEUE_TYPES WhichQueue,
5075 +                 OUT PQUEUE_ENTRY *Entry, OUT PQUEUE_INDEX Index,
5076 +                 OUT ULONG *DontInterrupt)
5077 +{
5078 +    ULONG QueueOffset;
5079 +       BOOLEAN status;
5080 +       PCOMM_REGION CommRegion;
5081 +
5082 +       CommRegion = Adapter->CommRegion;
5083 +
5084 +    //
5085 +    // All of the queues wrap when they reach the end, so we check to see if they
5086 +    // have reached the end and if they have we just set the index back to zero.
5087 +    // This is a wrap. You could or off the high bits in all updates but this is
5088 +    // a bit faster I think.
5089 +    //
5090 +
5091 +    if (WhichQueue == AdapHighCmdQueue) {
5092 +        *Index = *(CommRegion->AdapHighCmdQue.Headers.ProducerIndex);
5093 +
5094 +               if (*Index - 2 == *(CommRegion->AdapHighCmdQue.Headers.ConsumerIndex))
5095 +                       *DontInterrupt = TRUE; 
5096 +
5097 +        if (*Index >= ADAP_HIGH_CMD_ENTRIES)
5098 +            *Index = 0;
5099 +
5100 +        if (*Index + 1 == *(CommRegion->AdapHighCmdQue.Headers.ConsumerIndex)) { // Queue is full
5101 +                       status = FALSE;
5102 +                       cmn_err(CE_WARN, "Adapter High Command Queue full, %d outstanding",
5103 +                                       CommRegion->AdapHighCmdQue.NumOutstandingIos);
5104 +               } else {
5105 +               QueueOffset = sizeof(QUEUE_ENTRY) * (*Index);
5106 +               *Entry = QueueOffset + CommRegion->AdapHighCmdQue.BaseAddress;
5107 +
5108 +                       status = TRUE;
5109 +               }
5110 +    } else if (WhichQueue == AdapNormCmdQueue) {
5111 +
5112 +        *Index = *(CommRegion->AdapNormCmdQue.Headers.ProducerIndex);
5113 +
5114 +               if (*Index - 2 == *(CommRegion->AdapNormCmdQue.Headers.ConsumerIndex))
5115 +                       *DontInterrupt = TRUE; 
5116 +
5117 +               //
5118 +               // If we are at the end of the QUEUE then wrap back to 
5119 +               // the beginning.
5120 +        //
5121 +
5122 +        if (*Index >= ADAP_NORM_CMD_ENTRIES) 
5123 +            *Index = 0; // Wrap to front of the Producer Queue.
5124 +
5125 +               //
5126 +        // The IEEE spec says that it the producer is one behind the consumer then
5127 +        // the queue is full.
5128 +        //       
5129 +
5130 +               ASSERT(*(CommRegion->AdapNormCmdQue.Headers.ConsumerIndex) != 0);
5131 +
5132 +        if (*Index + 1 == *(CommRegion->AdapNormCmdQue.Headers.ConsumerIndex)) { // Queue is full
5133 +                       cmn_err(CE_WARN, "Adapter Norm Command Queue full, %d outstanding",
5134 +                                       CommRegion->AdapNormCmdQue.NumOutstandingIos);
5135 +                       status = FALSE;
5136 +               } else {        
5137 +               //
5138 +                       // The success case just falls through and returns the a valid queue entry.
5139 +                       //
5140 +
5141 +#ifdef commdebug
5142 +               FsaCommPrint("queue entry = %x.\n",CommRegion->AdapNormCmdQue.BaseAddress + *Index);
5143 +               FsaCommPrint("GetEntry: Index = %d, QueueOffset = %x, Entry = %x, *Entry = %x.\n",
5144 +                            *Index, QueueOffset, Entry, *Entry);
5145 +#endif
5146 +               *Entry = CommRegion->AdapNormCmdQue.BaseAddress + *Index;
5147 +
5148 +                       status = TRUE;
5149 +               }
5150 +    } else if (WhichQueue == AdapHighRespQueue) {
5151 +
5152 +        *Index = *(CommRegion->AdapHighRespQue.Headers.ProducerIndex);
5153 +
5154 +               if (*Index - 2 == *(CommRegion->AdapHighRespQue.Headers.ConsumerIndex))
5155 +                       *DontInterrupt = TRUE; 
5156 +
5157 +        if (*Index >= ADAP_HIGH_RESP_ENTRIES)
5158 +            *Index = 0;
5159 +
5160 +        if (*Index + 1 == *(CommRegion->AdapHighRespQue.Headers.ConsumerIndex)) { // Queue is full
5161 +                       status = FALSE;
5162 +                       cmn_err(CE_WARN, "Adapter High Resp Queue full, %d outstanding",
5163 +                                       CommRegion->AdapHighRespQue.NumOutstandingIos);
5164 +               } else {                                                        
5165 +               *Entry = CommRegion->AdapHighRespQue.BaseAddress + *Index;
5166 +               status = TRUE;
5167 +               } 
5168 +    } else if (WhichQueue == AdapNormRespQueue) {
5169 +
5170 +        *Index = *(CommRegion->AdapNormRespQue.Headers.ProducerIndex);
5171 +
5172 +               if (*Index - 2 == *(CommRegion->AdapNormRespQue.Headers.ConsumerIndex))
5173 +                       *DontInterrupt = TRUE; 
5174 +
5175 +               //
5176 +               // If we are at the end of the QUEUE then wrap back to 
5177 +               // the beginning.
5178 +        //
5179 +
5180 +        if (*Index >= ADAP_NORM_RESP_ENTRIES) 
5181 +            *Index = 0; // Wrap to front of the Producer Queue.
5182 +
5183 +               //
5184 +        // The IEEE spec says that it the producer is one behind the consumer then
5185 +        // the queue is full.
5186 +        //       
5187 +
5188 +        if (*Index + 1 == *(CommRegion->AdapNormRespQue.Headers.ConsumerIndex)) { // Queue is full
5189 +                       status = FALSE; 
5190 +                       cmn_err(CE_WARN, "Adapter Norm Resp Queue full, %d outstanding",
5191 +                                       CommRegion->AdapNormRespQue.NumOutstandingIos);
5192 +               } else {        
5193 +               //
5194 +                       // The success case just falls through and returns the a valid queue entry.
5195 +                       //
5196 +
5197 +               *Entry = CommRegion->AdapNormRespQue.BaseAddress + *Index;
5198 +
5199 +#ifdef commdebug
5200 +               FsaCommPrint("queue entry = %x.\n",CommRegion->AdapNormRespQue.BaseAddress + *Index);
5201 +               FsaCommPrint("GetEntry: Index = %d, Entry = %x, *Entry = %x.\n",*Index, Entry, *Entry);
5202 +#endif
5203 +                       status = TRUE;
5204 +               }     
5205 +    } else {
5206 +               cmn_err(CE_PANIC, "GetEntry: invalid queue %d", WhichQueue);
5207 +       }
5208 +
5209 +
5210 +       return (status);
5211 +}
5212 +   
5213 +
5214 +
5215 +#ifdef API_THROTTLE
5216 +
5217 +void ThrottleCheck(
5218 +       IN PAFA_COMM_ADAPTER Adapter,
5219 +       IN PFIB Fib
5220 +       )
5221 +/*++
5222 +
5223 +Routine Description:
5224 +
5225 +    This routine implements data I/O throttling. Throttling occurs when
5226 +       a CLI FIB is detected. To ensure the CLI responds quickly (the user
5227 +       is waiting for the response), this mechanism restricts the queue
5228 +       depth of data IOs at the adapter for a period of time (called the
5229 +       Throttle Period, default 5 seconds).
5230 +
5231 +    The mechanism uses a counted semaphore to place threads into a wait
5232 +       state should there be too many data I/Os outstanding.
5233 +
5234 +       At the start of a throttle period (indicated by the first CLI FIB)
5235 +       a timer is started. When the timer expires, new requests can go to
5236 +       the adapter freely. Throttled requests gradually drain to the
5237 +       adapter as each outstanding throttle I/O completes.
5238 +
5239 +    To avoid hurting regular I/O performance, we use a flag in the FIB
5240 +       header to mark FIBs involved in throttling. This means we only need
5241 +       take the extra spinlock in the response DPC routine for FIBs who
5242 +       were subject to throttling. If no throttling is occurring, the cost
5243 +       to the regular code paths is a handful of instructions.
5244 +
5245 +Arguments:
5246 +
5247 +       Adapter - Pointer to per-adapter context. This is used to locate the
5248 +                         throttle information for this adapter.
5249 +       
5250 +       Fib             - Pointer to the header for the fib being sent.
5251 +
5252 +Return Value:
5253 +
5254 +       None.
5255 +
5256 +--*/
5257 +{
5258 +       PCOMM_REGION CommRegion = Adapter->CommRegion;
5259 +       AAC_STATUS       Status;
5260 +
5261 +       //
5262 +       // This routine is called under protection of the queue spinlock.
5263 +       // As such we are allowed to check and change the counts for the
5264 +       // throttle.
5265 +       // Check the FIB. If its not a data operation, send it on without
5266 +       // throttle check. If it is a data operation, check for throttle.
5267 +       //
5268 +
5269 +       CommRegion->TotalFibs++;                                                        // Keep statistics
5270 +
5271 +       if ((Fib->Header.XferState & ApiFib) != 0) {
5272 +
5273 +               CommRegion->ApiFibs++;                                                  // Keep statistics
5274 +
5275 +               //
5276 +               // Its an API fib. If the throttle is not already active,
5277 +               // make it so. This will prevent new data Fibs being sent
5278 +               // if they exceed the throttle check.
5279 +               //
5280 +
5281 +               if (!CommRegion->ThrottleActive) {
5282 +                       BOOLEAN          InQue;
5283 +
5284 +                       CommRegion->ThrottleActive = TRUE;                      // This causes new data I/Os to be throttled
5285 +
5286 +                       //
5287 +                       // Schedule a timer for the throttle active period. When
5288 +                       // it expires, we'll be called back at routine ThrottleDpcRoutine
5289 +                       // above. This will signify the throttle active period ended
5290 +                       // and any waiting threads will be signalled to restart.
5291 +                       //
5292 +
5293 +                       FsaCommPrint("Throttle Period Start - CommRegion: %x\n", CommRegion);
5294 +                       CommRegion->ThrottleTimerSets++;
5295 +                       InQue = KeSetTimer( &CommRegion->ThrottleTimer,
5296 +                                                               CommRegion->ThrottleTimeout,
5297 +                                                               &CommRegion->ThrottleDpc);
5298 +                       ASSERT(InQue == FALSE);
5299 +               }
5300 +
5301 +               return;
5302 +       }
5303 +
5304 +       //
5305 +       // Its a non-API fib, so subject to throttle checks.
5306 +       // The following are exempt from throttling:
5307 +       //              o FIBs marked as "throttle exempt" by upper layers.
5308 +       //              o I/Os issued from a raised IRQL. We can't suspend
5309 +       //                a thread when at raised IRQL so throttling is exempt.
5310 +       //
5311 +
5312 +       if (CommRegion->AdapNormCmdQue.SavedIrql != PASSIVE_LEVEL) {
5313 +
5314 +               CommRegion->NonPassiveFibs++;
5315 +               FsaCommPrint("ThrottleCheck: Non-Passive level FIB bypasses throttle: %x\n", Fib);
5316 +               return;
5317 +
5318 +       }
5319 +
5320 +       if (CommRegion->ThrottleActive) {
5321 +
5322 +               //
5323 +               // Throttle is active.
5324 +               // Check if the FIB is a read or write. If so, and its to the
5325 +               // file system information area, let it through without throttling.
5326 +               //
5327 +
5328 +               if (Fib->Header.Command == ContainerCommand) {
5329 +                       PBLOCKREAD BlockDisk = (PBLOCKREAD) &Fib->data;
5330 +
5331 +                       //
5332 +                       // *** Note *** We are using read and write command formats
5333 +                       // interchangably here. This is ok for this purpose as the
5334 +                       // command is in the same place for both. Read and write command
5335 +                       // formats are different at higher offsets though.
5336 +                       //
5337 +
5338 +                       if ( ((BlockDisk->Command == VM_CtBlockRead) ||
5339 +                                 (BlockDisk->Command == VM_CtBlockWrite)) &&
5340 +                                 (BlockDisk->BlockNumber <= FILESYSTEM_INFO_MAX_BLKNO)) {
5341 +
5342 +                               CommRegion->FSInfoFibs++;                                                       // Keep statistics
5343 +                               return;
5344 +
5345 +                       }
5346 +
5347 +               }
5348 +
5349 +               //
5350 +               // Throttle the FIB.
5351 +               // Mark it as throttle active so that it can signal a waiter
5352 +               // when it completes.
5353 +
5354 +               CommRegion->ThrottledFibs++;
5355 +               Fib->Header.Flags |= ThrottledFib;
5356 +               
5357 +               //
5358 +               // Release the spinlock so we can wait the thread if necessary.
5359 +               // Since we specify a timeout, check the caller is at passive level.
5360 +               //
5361 +
5362 +               OsSpinLockRelease((CommRegion->AdapNormCmdQue.QueueLock), CommRegion->AdapNormCmdQue.SavedIrql);
5363 +
5364 +               FsaCommPrint("ThrottleCheck - Thread Suspension - FIB: %x\n", Fib);
5365 +
5366 +               Status = KeWaitForSingleObject(&CommRegion->ThrottleReleaseSema,
5367 +                                                                               Executive,                                                      // Don't allow user APCs to wake us
5368 +                                                                               KernelMode,                                                     // Wait in kernel mode
5369 +                                                                               FALSE,                                                          // Not alertable
5370 +                                                                               &CommRegion->ThrottleWaitTimeout);      // Timeout after this time
5371 +
5372 +               //
5373 +               // Check the signal status. If we've timed out, clear the throttle
5374 +               // flag on the FIB to avoid us signalling the semaphore on completion.
5375 +               // We never acquired the semaphore.
5376 +               //
5377 +               if (Status == STATUS_TIMEOUT) {
5378 +
5379 +                       CommRegion->ThrottleTimedoutFibs++;
5380 +                       FsaCommPrint("ThrottledFib Timed Out - FIB: %x\n", Fib);
5381 +                       Fib->Header.Flags &= ~ThrottledFib;                                             // Clear the throttledfib flag
5382 +
5383 +               } else {
5384 +
5385 +                       ASSERT(Status == STATUS_SUCCESS);                                               // No other return is possible
5386 +
5387 +               }
5388 +
5389 +               //
5390 +               // We've been woken up and can now send the FIB to the adapter.
5391 +               // Acquire the spinlock again so we can get a queue entry. This
5392 +               // returns to GetQueueEntry.
5393 +               //
5394 +
5395 +               FsaCommPrint("ThrottleCheck - Thread Resume - FIB: %x\n", Fib);
5396 +               KeAcquireSpinLock((CommRegion->AdapNormCmdQue.QueueLock), &(CommRegion->AdapNormCmdQue.SavedIrql));
5397 +               CommRegion->ThrottleOutstandingFibs++;          // There's another throttle controlled FIB going.
5398 +               return;
5399 +
5400 +       }
5401 +}
5402 +
5403 +#endif //#ifdef API_THROTTLE
5404 +
5405 +int GetQueueEntryTimeouts = 0;
5406 +
5407 +
5408 +/*++
5409 +
5410 +Routine Description:
5411 +
5412 +    Gets the next free QE off the requested priorty adapter command queue and
5413 +    associates the Fib with the QE. The QE represented by index is ready to
5414 +     insert on the queue when this routine returns success.
5415 +
5416 +Arguments:
5417 +
5418 +    Index is the returned value which represents the QE which is ready to
5419 +        insert on the adapter's command queue.
5420 +
5421 +    Priority is an enumerated type which determines which priority level
5422 +        command queue the QE is going to be queued on.
5423 +
5424 +    Fib is a pointer to the FIB the caller wishes to have associated with the
5425 +        QE.
5426 +
5427 +    Wait is a boolean which determines if the routine will wait if there are
5428 +        no free QEs on the requested priority command queue.
5429 +
5430 +    FibContext is where the driver stores all system resources required to execute the
5431 +        command requested from the calling thread. This includes mapping resources for
5432 +        the FIB and the 'users' buffer.
5433 +
5434 +       DontInterrupt - We set this true if the queue state is such that we don't
5435 +               need to interrupt the adapter for this queue entry.
5436 +
5437 +Return Value:
5438 +
5439 +    NT_SUCCESS if a Fib was returned to the caller.
5440 +    NT_ERROR if event was an invalid event. 
5441 +
5442 +--*/
5443 +AAC_STATUS
5444 +GetQueueEntry (IN PAFA_COMM_ADAPTER Adapter, OUT PQUEUE_INDEX Index,
5445 +                          IN QUEUE_TYPES WhichQueue, IN PFIB Fib, IN BOOLEAN Wait,
5446 +                          IN PCOMM_FIB_CONTEXT FibContext, OUT ULONG *DontInterrupt)
5447 +{
5448 +    PQUEUE_ENTRY QueueEntry = NULL;
5449 +    BOOLEAN MapAddress = FALSE;
5450 +       int timeouts = 0;
5451 +       AAC_STATUS Status;
5452 +       PCOMM_REGION CommRegion;
5453 +
5454 +       CommRegion = Adapter->CommRegion;
5455 +
5456 +    //
5457 +    // Get the spinlock for the queue we are putting a command on
5458 +    //
5459 +
5460 +    if (WhichQueue == AdapHighCmdQueue) 
5461 +        OsSpinLockAcquire(CommRegion->AdapHighCmdQue.QueueLock);
5462 +    else if (WhichQueue == AdapNormCmdQueue)
5463 +        OsSpinLockAcquire(CommRegion->AdapNormCmdQue.QueueLock);
5464 +    else if (WhichQueue == AdapHighRespQueue)
5465 +        OsSpinLockAcquire(CommRegion->AdapHighRespQue.QueueLock);
5466 +    else if (WhichQueue == AdapNormRespQueue)
5467 +        OsSpinLockAcquire(CommRegion->AdapNormRespQue.QueueLock);
5468 +    else {
5469 +        FsaCommPrint("Invalid queue priority passed to GetQueueEntry.\n");
5470 +        return(FSA_INVALID_QUEUE);
5471 +    }
5472 +    
5473 +    //
5474 +    // Get the pointers to a queue entry on the queue the caller wishes to queue
5475 +    // a command request on. If there are no entries then wait if that is what the
5476 +    // caller requested. 
5477 +    //
5478 +
5479 +    if (WhichQueue == AdapHighCmdQueue) {
5480 +         // if no entries wait for some if caller wants to
5481 +        while ( !GetEntry(Adapter, AdapHighCmdQueue, &QueueEntry, Index, DontInterrupt) ) { 
5482 +                       cmn_err(CE_PANIC, "GetEntries failed (1)\n");
5483 +               }
5484 +
5485 +        //
5486 +        // Setup queue entry with a command, status and Fib mapped
5487 +        //
5488 +
5489 +        QueueEntry->Size = Fib->Header.Size;
5490 +        MapAddress = TRUE;
5491 +       
5492 +    } else if (WhichQueue == AdapNormCmdQueue) {
5493 +         // if no entries wait for some if caller wants to
5494 +        while ( !GetEntry(Adapter, AdapNormCmdQueue, &QueueEntry, Index, DontInterrupt) ) { 
5495 +                       cmn_err(CE_PANIC, "GetEntries failed (2)\n");
5496 +               }
5497
5498 +        //
5499 +        // Setup queue entry with command, status and Fib mapped
5500 +        //
5501 +
5502 +        QueueEntry->Size = Fib->Header.Size;
5503 +        MapAddress = TRUE;
5504 +        
5505 +     } else if (WhichQueue == AdapHighRespQueue) {
5506 +
5507 +        while ( !GetEntry(Adapter, AdapHighRespQueue, &QueueEntry, Index, DontInterrupt) ) { // if no entries wait for some if caller wants to
5508 +               }
5509 +
5510 +        //
5511 +        // Setup queue entry with command, status and Fib mapped
5512 +        //
5513 +
5514 +        QueueEntry->Size = Fib->Header.Size;
5515 +        QueueEntry->FibAddress = Fib->Header.SenderFibAddress;                         // Restore adapters pointer to the FIB
5516 +               Fib->Header.ReceiverFibAddress = Fib->Header.SenderFibAddress;          // Let the adapter now where to find its data
5517 +        MapAddress = FALSE;
5518 +        
5519 +     } else if (WhichQueue == AdapNormRespQueue) {
5520 +        while ( !GetEntry(Adapter, AdapNormRespQueue, &QueueEntry, Index, DontInterrupt) ) { // if no entries wait for some if caller wants to
5521 +               }
5522 +
5523 +               //
5524 +               // Setup queue entry with command, status, adapter's pointer to the Fib it sent
5525 +               //
5526 +       
5527 +        QueueEntry->Size = Fib->Header.Size;
5528 +        QueueEntry->FibAddress = Fib->Header.SenderFibAddress;                         // Restore adapters pointer to the FIB
5529 +               Fib->Header.ReceiverFibAddress = Fib->Header.SenderFibAddress;          // Let the adapter now where to find its data
5530 +        MapAddress = FALSE;
5531 +     }
5532 +                
5533 +    //
5534 +    // If MapFib is true than we need to map the Fib and put pointers in the queue entry.
5535 +    //
5536 +
5537 +    if (MapAddress) {
5538 +               QueueEntry->FibAddress = (ULONG)(FibContext->LogicalFibAddress.LowPart);
5539 +    }
5540 +    
5541 +    //
5542 +    // Return
5543 +    //
5544 +#ifdef commdebug    
5545 +    FsaCommPrint("Queue Entry contents:.\n");
5546 +    FsaCommPrint("  Command =               %d.\n", QueueEntry->Command);
5547 +    FsaCommPrint("  Status  =               %x.\n", QueueEntry->Status);
5548 +    FsaCommPrint("  Rec Fib address low =   %x.\n", QueueEntry->FibAddressLow);        
5549 +    FsaCommPrint("  Fib size in bytes =     %d.\n", QueueEntry->Size);
5550 +#endif
5551 +
5552 +    return(FSA_SUCCESS);
5553 +}
5554 +
5555 +
5556 +/*++
5557 +
5558 +Routine Description:
5559 +
5560 +    Gets the next free QE off the requested priorty adapter command queue and
5561 +      associates the Fib with the QE. The QE represented by index is ready to
5562 +    insert on the queue when this routine returns success.
5563 +
5564 +Arguments:
5565 +
5566 +    Index is the returned value which represents the QE which is ready to
5567 +        insert on the adapter's command queue.
5568 +
5569 +    WhichQueue tells us which queue the caller wishes to have the entry put.
5570 +        
5571 +Return Value:
5572 +
5573 +    NT_SUCCESS if a Fib was returned to the caller.
5574 +    NT_ERROR if event was an invalid event. 
5575 +
5576 +--*/
5577 +AAC_STATUS
5578 +InsertQueueEntry(
5579 +                 IN PAFA_COMM_ADAPTER Adapter,
5580 +                 IN QUEUE_INDEX Index,
5581 +                 IN QUEUE_TYPES WhichQueue,
5582 +                 IN ULONG DontInterrupt
5583 +                 )
5584 +{
5585 +       PCOMM_REGION CommRegion;
5586 +    
5587 +       CommRegion = Adapter->CommRegion;
5588 +
5589 +    //
5590 +    // We have already verified the queue in getentry, but we still have to make
5591 +    // sure we don't wrap here too.
5592 +    //
5593 +
5594 +    if (WhichQueue == AdapHighCmdQueue) {
5595 +
5596 +        *(CommRegion->AdapHighCmdQue.Headers.ProducerIndex) = Index + 1;
5597 +            
5598 +        OsSpinLockRelease(CommRegion->AdapHighCmdQue.QueueLock);
5599 +
5600 +               if (!DontInterrupt)
5601 +               NotifyAdapter(Adapter, AdapHighCmdQue);
5602 +        
5603 +    } else if (WhichQueue == AdapNormCmdQueue) {
5604 +
5605 +#ifdef commdebug
5606 +        FsaCommPrint("InsertQueueEntry: Inerting with an index of %d.\n",Index);
5607 +#endif
5608 +        *(CommRegion->AdapNormCmdQue.Headers.ProducerIndex) = Index + 1;
5609 +       
5610 +        OsSpinLockRelease(CommRegion->AdapNormCmdQue.QueueLock);
5611 +
5612 +               if (!DontInterrupt)
5613 +               NotifyAdapter(Adapter, AdapNormCmdQue);
5614 +
5615 +    } else if (WhichQueue == AdapHighRespQueue) {
5616 +
5617 +        *(CommRegion->AdapHighRespQue.Headers.ProducerIndex) = Index + 1;
5618 +
5619 +        OsSpinLockRelease(CommRegion->AdapHighRespQue.QueueLock);
5620 +
5621 +               if (!DontInterrupt)
5622 +               NotifyAdapter(Adapter, AdapHighRespQue);
5623 +
5624 +    } else if (WhichQueue == AdapNormRespQueue) {
5625 +
5626 +           *(CommRegion->AdapNormRespQue.Headers.ProducerIndex) = Index + 1;
5627 +           
5628 +           OsSpinLockRelease(CommRegion->AdapNormRespQue.QueueLock);
5629 +
5630 +           if (!DontInterrupt)
5631 +                   NotifyAdapter(Adapter, AdapNormRespQue);
5632 +
5633 +    } else {        
5634 +        FsaCommPrint("Invalid queue priority passed to InsertQueueEntry.\n");
5635 +        return(FSA_INVALID_QUEUE_PRIORITY);
5636 +    }
5637 +
5638 +    return(FSA_SUCCESS);                
5639 +}
5640 +
5641 +extern int GatherFibTimes;
5642 +
5643 +BOOLEAN
5644 +SendSynchFib(
5645 +       PVOID                   Arg,
5646 +       FIB_COMMAND     Command,
5647 +       PVOID                   Data,
5648 +       USHORT                  Size,
5649 +       PVOID                   Response,
5650 +       USHORT                  *ResponseSize
5651 +       )
5652 +/*++
5653 +
5654 +Routine Description:
5655 +
5656 +       This routine will send a synchronous FIB to the adapter and wait for its
5657 +       completion.
5658 +
5659 +Arguments:
5660 +
5661 +       DeviceExtension - Pointer to adapter extension structure.
5662 +
5663 +
5664 +Return Value:
5665 +
5666 +       BOOLEAN
5667 +
5668 +--*/
5669 +{
5670 +       PAFA_COMM_ADAPTER Adapter = Arg;
5671 +       FIB *Fib;
5672 +       ULONG returnStatus;
5673 +
5674 +       Fib = Adapter->SyncFib;
5675 +
5676 +    Fib->Header.StructType = TFib;
5677 +    Fib->Header.Size = sizeof(FIB);
5678 +    Fib->Header.XferState = HostOwned | FibInitialized | FibEmpty;
5679 +    Fib->Header.ReceiverFibAddress = 0;
5680 +    Fib->Header.SenderSize = sizeof(FIB);
5681 +    Fib->Header.SenderFibAddress = (ULONG)Fib;
5682 +    Fib->Header.Command = Command;
5683 +
5684 +       //
5685 +       // Copy the Data portion into the Fib.
5686 +       //
5687 +
5688 +       RtlCopyMemory( Fib->data, Data, Size );
5689 +
5690 +
5691 +    Fib->Header.XferState |= (SentFromHost | NormalPriority);
5692 +    
5693 +       //
5694 +    // Set the size of the Fib we want to send to the adapter
5695 +       //
5696 +
5697 +    Fib->Header.Size = sizeof(FIB_HEADER) + Size;
5698 +
5699 +       if (!Adapter->AdapterFuncs->SendSynchFib( Adapter->AdapterExtension,
5700 +                                                                                         Adapter->SyncFibPhysicalAddress )) {
5701 +
5702 +                       return (FALSE);
5703 +
5704 +       }
5705 +
5706 +       //
5707 +       // Copy the response back to the caller's buffer.
5708 +       //
5709 +
5710 +       RtlCopyMemory( Response, Fib->data, Fib->Header.Size - sizeof(FIB_HEADER) );
5711 +
5712 +       *ResponseSize = Fib->Header.Size - sizeof(FIB_HEADER);
5713 +
5714 +       //
5715 +       // Indicate success
5716 +       //
5717 +
5718 +       return (TRUE);
5719 +}
5720 +
5721 +//
5722 +// Define the highest level of host to adapter communication routines. These
5723 +// routines will support host to adapter FS commuication. These routines have
5724 +// no knowledge of the commuication method used. This level sends and receives
5725 +// FIBs. This level has no knowledge of how these FIBs get passed back and forth.
5726 +//
5727 +
5728 +
5729 +
5730 +/*++
5731 +
5732 +Routine Description:
5733 +
5734 +    Sends the requested FIB to the adapter and optionally will wait for a
5735 +     response FIB. If the caller does not wish to wait for a response than
5736 +    an event to wait on must be supplied. This event will be set when a
5737 +    response FIB is received from the adapter.
5738 +
5739 +Arguments:
5740 +
5741 +    Fib is a pointer to the FIB the caller wishes to send to the adapter.
5742 +    
5743 +    Size - Size of the data portion of the Fib.
5744 +    
5745 +    Priority is an enumerated type which determines which priority level
5746 +        the caller wishes to send this command at. 
5747 +
5748 +    Wait is a boolean which determines if the routine will wait for the
5749 +        completion Fib to be returned(TRUE), or return when the Fib has been
5750 +        successfully received by the adapter(FALSE).
5751 +
5752 +    WaitOn is only vaild when Wait is FALSE. The Event will be set when the response
5753 +        FIB has been returned by the adapter.
5754 +
5755 +    ReturnFib is an optional pointer to a FIB that if present the response FIB will
5756 +        copied to.     
5757 +        
5758 +Return Value:
5759 +
5760 +    NT_SUCCESS if a Fib was returned to the caller.
5761 +    NT_ERROR if event was an invalid event. 
5762 +
5763 +       --*/
5764 +AAC_STATUS
5765 +SendFib (IN FIB_COMMAND Command,
5766 +         IN PFIB_CONTEXT Context,
5767 +         IN ULONG Size, 
5768 +         IN COMM_PRIORITIES Priority,
5769 +         IN BOOLEAN Wait,
5770 +         IN PVOID WaitOn,
5771 +         IN BOOLEAN ResponseExpected,
5772 +         IN PFIB_CALLBACK FibCallback,
5773 +         IN PVOID FibCallbackContext)
5774 +{
5775 +               PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
5776 +               QUEUE_INDEX Index;
5777 +               QUEUE_TYPES WhichQueue;
5778 +               LARGE_INTEGER Timeout;
5779 +               AAC_STATUS Status;
5780 +               PAFA_COMM_ADAPTER Adapter = FibContext->Adapter;
5781 +               ULONG DontInterrupt = FALSE;
5782 +               PFIB Fib = FibContext->Fib;
5783 +               IN PCOMM_QUE OurQueue;
5784 +
5785 +               Timeout = FsaCommData.AdapterTimeout;
5786 +
5787 +               if (!(Fib->Header.XferState & HostOwned)) {
5788 +                               FsaCommPrint("SendFib was called with a xfer state not set to HostOwned!\n");
5789 +                               FsaCommLogEvent(FibContext,
5790 +                                                               FsaCommData.DeviceObject, 
5791 +                                                               FSAFS_FIB_INVALID, 
5792 +                                                               STATUS_UNSUCCESSFUL, 
5793 +                                                               BugCheckFileId | __LINE__,
5794 +                                                               FACILITY_FSAFS_ERROR_CODE,
5795 +                                                               NULL,
5796 +                                                               TRUE);                  
5797 +
5798 +                               return(STATUS_UNSUCCESSFUL);
5799 +
5800 +               }
5801 +    
5802 +               //
5803 +               // There are 5 cases with the wait and reponse requested flags. The only invalid cases
5804 +               // are if the caller requests to wait and  does not request a response and if the
5805 +               // caller does not want a response and the Fib is not allocated from pool. If a response
5806 +               // is not requesed the Fib will just be deallocaed by the DPC routine when the response
5807 +               // comes back from the adapter. No further processing will be done besides deleting the
5808 +               // Fib. We will have a debug mode where the adapter can notify the host it had a problem
5809 +               // and the host can log that fact.
5810 +
5811 +               if (Wait && !ResponseExpected) {
5812 +
5813 +                               FsaCommLogEvent(FibContext,
5814 +                                                FsaCommData.DeviceObject, 
5815 +                                                FSAFS_FIB_INVALID, 
5816 +                                                STATUS_UNSUCCESSFUL, 
5817 +                                                BugCheckFileId | __LINE__,
5818 +                                                FACILITY_FSAFS_ERROR_CODE,
5819 +                                                NULL,
5820 +                                                TRUE);                 
5821 +
5822 +                               return(STATUS_UNSUCCESSFUL);
5823 +
5824 +               } else if (!Wait && ResponseExpected) {
5825 +                               Fib->Header.XferState |= (Async | ResponseExpected);
5826 +                               FIB_COUNTER_INCREMENT(FsaCommData.AsyncSent);
5827 +               } else if (!Wait && !ResponseExpected) {
5828 +                               Fib->Header.XferState |= NoResponseExpected;
5829 +                               FIB_COUNTER_INCREMENT(FsaCommData.NoResponseSent);
5830 +               } else if (Wait && ResponseExpected) {
5831 +                  Fib->Header.XferState |= ResponseExpected;
5832 +                  FIB_COUNTER_INCREMENT(FsaCommData.NormalSent);
5833 +               } 
5834 +
5835 +               Fib->Header.SenderData = (ULONG)FibContext; // so we can complete the io in the dpc routine
5836 +
5837 +               //
5838 +               // Set FIB state to indicate where it came from and if we want a response from the
5839 +               // adapter. Also load the command from the caller.
5840 +               //
5841 +
5842 +               Fib->Header.SenderFibAddress = (ULONG)Fib;
5843 +               Fib->Header.Command = Command;
5844 +               Fib->Header.XferState |= SentFromHost;
5845 +               FibContext->Fib->Header.Flags = 0;                              // Zero the flags field - its internal only...
5846 +    
5847 +               //
5848 +               // Set the size of the Fib we want to send to the adapter
5849 +               //
5850 +
5851 +               Fib->Header.Size = sizeof(FIB_HEADER) + Size;
5852 +               if (Fib->Header.Size > Fib->Header.SenderSize) {
5853 +                               return(STATUS_BUFFER_OVERFLOW);
5854 +               }                
5855 +
5856 +               //
5857 +               // Get a queue entry connect the FIB to it and send an notify the adapter a command is ready.
5858 +               //
5859 +            
5860 +               if (Priority == FsaHigh) {
5861 +                               Fib->Header.XferState |= HighPriority;
5862 +                               WhichQueue = AdapHighCmdQueue;
5863 +                               OurQueue = &Adapter->CommRegion->AdapHighCmdQue;
5864 +               } else {
5865 +                               Fib->Header.XferState |= NormalPriority;
5866 +                               WhichQueue = AdapNormCmdQueue;
5867 +                               OurQueue = &Adapter->CommRegion->AdapNormCmdQue;
5868 +               }
5869 +
5870 +               if (Wait) {
5871 +                               OsCvLockAcquire( FibContext->FsaEventMutex );
5872 +               }
5873 +
5874 +               if ( GetQueueEntry( Adapter, &Index, WhichQueue, Fib, TRUE, FibContext, &DontInterrupt) != FSA_SUCCESS )
5875 +                               return(STATUS_UNSUCCESSFUL);
5876 +
5877 +               // bmb debug
5878 +
5879 +               cmn_err (CE_DEBUG,"SendFib: inserting a queue entry at index %d.\n",Index);
5880 +               cmn_err (CE_DEBUG,"Fib contents:.\n");
5881 +               cmn_err (CE_DEBUG,"  Command =               %d.\n", Fib->Header.Command);
5882 +               cmn_err (CE_DEBUG,"  XferState  =            %x.\n", Fib->Header.XferState );
5883 +
5884 +               //
5885 +               // Fill in the Callback and CallbackContext if we are not going to wait.
5886 +               //
5887 +
5888 +               if (!Wait) {
5889 +
5890 +                               FibContext->FibCallback = FibCallback;
5891 +                               FibContext->FibCallbackContext = FibCallbackContext;
5892 +
5893 +               }
5894 +
5895 +               FIB_COUNTER_INCREMENT(FsaCommData.FibsSent);
5896 +
5897 +               InsertTailList( &OurQueue->OutstandingIoQueue, &FibContext->QueueEntry );
5898 +               OurQueue->NumOutstandingIos++;
5899 +
5900 +               FibContext->FibComplete = 0;
5901 +
5902 +
5903 +
5904 +               if ( InsertQueueEntry( Adapter, Index, WhichQueue, (DontInterrupt & FsaCommData.EnableInterruptModeration)) != FSA_SUCCESS )
5905 +                        return(STATUS_UNSUCCESSFUL);
5906 +
5907 +               //
5908 +               // If the caller wanted us to wait for response wait now. 
5909 +               // If Timeouts are enabled than set the timeout otherwise wait forever.
5910 +               //
5911 +    
5912 +               if (Wait) {
5913 +                        while (FibContext->FibComplete == 0) {
5914 +                                OsCv_wait( &FibContext->FsaEvent, FibContext->FsaEventMutex );
5915 +                        }      
5916 +                        
5917 +                        OsCvLockRelease( FibContext->FsaEventMutex );
5918 +                                       
5919 +                        if ( (FibContext->Flags & FIB_CONTEXT_FLAG_TIMED_OUT) ) {
5920 +                                return(STATUS_IO_TIMEOUT);
5921 +                        } else {
5922 +                                return(STATUS_SUCCESS);
5923 +                        }
5924 +               }
5925 +
5926 +               //
5927 +               // If the user does not want a response than return success otherwise return pending
5928 +               // 
5929 +
5930 +               ASSERT( FibCallback );
5931 +
5932 +               if (ResponseExpected)
5933 +                               return(STATUS_PENDING);
5934 +               else
5935 +                               return(STATUS_SUCCESS);
5936 +}
5937 +
5938 +BOOLEAN
5939 +GetConsumerEntry(
5940 +       IN PAFA_COMM_ADAPTER Adapter,
5941 +    PCOMM_QUE OurQueue,
5942 +    OUT PQUEUE_ENTRY *Entry
5943 +    )
5944 +/*++
5945 +
5946 +Routine Description:
5947 +
5948 +    Will return a pointer to the entry on the top of the queue requested that we are a consumer
5949 +    of, and return the address of the queue entry. It does not change the state of the queue. 
5950 +
5951 +Arguments:
5952 +
5953 +    OurQueue - is the queue the queue entry should be removed from.
5954 +
5955 +    Entry - is a pointer where the address  of the queue entry should be returned.    
5956 +    
5957 +Return Value:
5958 +
5959 +    TRUE if there was a queue entry on the response queue for the host to consume.
5960 +    FALSE if there were no queue entries to consume.
5961 +    
5962 +--*/
5963 +
5964 +{
5965 +    QUEUE_INDEX Index;
5966 +       BOOLEAN status;
5967 +
5968 +    if (*OurQueue->Headers.ProducerIndex == *OurQueue->Headers.ConsumerIndex) {
5969 +               status = FALSE;
5970 +       } else {
5971 +
5972 +           //
5973 +           // The consumer index must be wrapped if we have reached the end of
5974 +           // the queue. 
5975 +           // Else we just use the entry pointed to by the header index
5976 +           //
5977 +           
5978 +           if (*OurQueue->Headers.ConsumerIndex >= OurQueue->QueueEntries) 
5979 +                       Index = 0;              
5980 +           else
5981 +               Index = *OurQueue->Headers.ConsumerIndex;
5982 +           
5983 +           *Entry = OurQueue->BaseAddress + Index;
5984 +
5985 +#ifdef commdebug
5986 +           FsaCommPrint("Got a QE at Index %d, QE Addrss of %x.\n",Index,*Entry);
5987 +#endif
5988 +               status = TRUE;
5989 +       }
5990 +
5991 +    return(status);
5992 +}
5993 +
5994 +BOOLEAN
5995 +ConsumerEntryAvailable(
5996 +       IN PAFA_COMM_ADAPTER Adapter,
5997 +    PCOMM_QUE OurQueue
5998 +       )
5999 +{
6000 +    return (*OurQueue->Headers.ProducerIndex != *OurQueue->Headers.ConsumerIndex);
6001 +}
6002 +
6003 +VOID
6004 +FreeConsumerEntry(
6005 +       IN PAFA_COMM_ADAPTER Adapter,
6006 +    PCOMM_QUE OurQueue,
6007 +    QUEUE_TYPES WhichQueue
6008 +    )
6009 +/*++
6010 +
6011 +Routine Description:
6012 +
6013 +    Frees up the current top of the queue we are a consumer of. If the queue was full
6014 +    notify the producer that the queue is no longer full.
6015 +
6016 +Arguments:
6017 +
6018 +    OurQueue - is the queue we will free the current consumer entry on.
6019 +
6020 +Return Value:
6021 +
6022 +    TRUE if there was a queue entry on the response queue for the host to consume.
6023 +    FALSE if there were no queue entries to consume.
6024 +    
6025 +--*/
6026 +
6027 +{
6028 +    BOOLEAN WasFull = FALSE;
6029 +    HOST_2_ADAP_EVENT Notify;
6030 +
6031 +    if (*OurQueue->Headers.ProducerIndex+1 == *OurQueue->Headers.ConsumerIndex)
6032 +        WasFull = TRUE;
6033 +        
6034 +    if (*OurQueue->Headers.ConsumerIndex >= OurQueue->QueueEntries)
6035 +        *OurQueue->Headers.ConsumerIndex = 1;
6036 +    else
6037 +        *OurQueue->Headers.ConsumerIndex += 1;
6038 +        
6039 +    if (WasFull) {
6040 +        switch (WhichQueue) {
6041 +
6042 +            case HostNormCmdQueue:
6043 +                Notify = HostNormCmdNotFull;
6044 +                break;
6045 +            case HostHighCmdQueue:
6046 +                Notify = HostHighCmdNotFull;
6047 +                break;
6048 +
6049 +            case HostNormRespQueue:
6050 +                Notify = HostNormRespNotFull;
6051 +                break;
6052 +
6053 +            case HostHighRespQueue:
6054 +                Notify = HostHighRespNotFull;
6055 +                break;
6056 +
6057 +        }
6058 +        NotifyAdapter(Adapter, Notify);
6059 +    }
6060 +
6061 +}        
6062 +
6063 +AAC_STATUS
6064 +CompleteAdapterFib(
6065 +       IN PFIB_CONTEXT Context,
6066 +    IN USHORT Size
6067 +    )
6068 +/*++
6069 +
6070 +Routine Description:
6071 +
6072 +    Will do all necessary work to complete a FIB that was sent from the adapter.
6073 +
6074 +Arguments:
6075 +
6076 +    Fib is a pointer to the FIB that caller wishes to complete processing on. 
6077 +
6078 +    Size - Size of the completion Packet(Opitional). If not present than the current
6079 +           largest size in the Fib will be used
6080 +    
6081 +       Adapter - Pointer to which adapter sent this FIB
6082 +
6083 +Return Value:
6084 +
6085 +    NT_SUCCESS if a Fib was returned to the caller.
6086 +    NT_ERROR if event was an invalid event. 
6087 +
6088 +--*/
6089 +{
6090 +       PCOMM_FIB_CONTEXT FibContext = Context;
6091 +    PFIB Fib = FibContext->Fib;
6092 +       PAFA_COMM_ADAPTER Adapter = FibContext->Adapter;
6093 +    ULONG DontInterrupt = FALSE;
6094 +
6095 +    if (Fib->Header.XferState == 0)
6096 +        return(STATUS_SUCCESS);
6097 +
6098 +    //
6099 +    // If we plan to do anything check the structure type first.
6100 +    // 
6101 +
6102 +    if ( Fib->Header.StructType != TFib ) {
6103 +        FsaCommPrint("Error CompleteFib called with a non Fib structure.\n");
6104 +        return(STATUS_UNSUCCESSFUL);
6105 +    }
6106 +
6107 +    //
6108 +    // This block handles the case where the adapter had sent us a command and we
6109 +    // have finished processing the command. We call completeFib when we are done
6110 +    // processing the command and want to send a response back to the adapter. This
6111 +    // will send the completed cdb to the adapter.
6112 +    //
6113 +
6114 +    if (Fib->Header.XferState & SentFromAdapter) {
6115 +        Fib->Header.XferState |= HostProcessed;
6116 +        if (Fib->Header.XferState & HighPriority) {
6117 +            QUEUE_INDEX Index;
6118 +            
6119 +            if (Size) {
6120 +                Size += sizeof(FIB_HEADER);
6121 +                if (Size > Fib->Header.SenderSize) 
6122 +                    return(STATUS_BUFFER_OVERFLOW);
6123 +                Fib->Header.Size = Size;
6124 +            }
6125 +
6126 +            if (GetQueueEntry(Adapter, &Index, AdapHighRespQueue, Fib, TRUE, NULL, &DontInterrupt) != STATUS_SUCCESS) {
6127 +                FsaCommPrint("CompleteFib got an error geting a queue entry for a response.\n");
6128 +                return(FSA_FATAL);
6129 +            }
6130 +            if (InsertQueueEntry(Adapter, 
6131 +                                               Index, 
6132 +                                               AdapHighRespQueue, 
6133 +                                               (DontInterrupt & (BOOLEAN)FsaCommData.EnableInterruptModeration)) != STATUS_SUCCESS) {
6134 +                FsaCommPrint("CompleteFib failed while inserting entry on the queue.\n");
6135 +            }
6136 +        } else if (Fib->Header.XferState & NormalPriority) {
6137 +            QUEUE_INDEX Index;
6138 +
6139 +            if (Size) {
6140 +                Size += sizeof(FIB_HEADER);
6141 +                if (Size > Fib->Header.SenderSize) 
6142 +                    return(STATUS_BUFFER_OVERFLOW);
6143 +                Fib->Header.Size = Size;
6144 +            }
6145 +            
6146 +            if (GetQueueEntry(Adapter, &Index, AdapNormRespQueue, Fib, TRUE, NULL, &DontInterrupt) != STATUS_SUCCESS) {
6147 +                FsaCommPrint("CompleteFib got an error geting a queue entry for a response.\n");
6148 +                return(FSA_FATAL);
6149 +            }
6150 +            if (InsertQueueEntry(Adapter, 
6151 +                                               Index, 
6152 +                                               AdapNormRespQueue, 
6153 +                                               (DontInterrupt & (BOOLEAN)FsaCommData.EnableInterruptModeration)) != STATUS_SUCCESS) {
6154 +                FsaCommPrint("CompleteFib failed while inserting entry on the queue.\n");
6155 +            }
6156 +               }
6157 +    } else {
6158 +        cmn_err(CE_WARN, "CompleteFib: Unknown xferstate detected.\n");
6159 +               FsaBugCheck(0,0,0);
6160 +    }   
6161 +    return(STATUS_SUCCESS);
6162 +}
6163 +
6164 +AAC_STATUS
6165 +CompleteFib(
6166 +       IN PFIB_CONTEXT Context
6167 +    )
6168 +/*++
6169 +
6170 +Routine Description:
6171 +
6172 +    Will do all necessary work to complete a FIB. If the caller wishes to
6173 +    reuse the FIB after post processing has been completed Reinitialize
6174 +    should be called set to TRUE, otherwise the FIB will be returned to the
6175 +    free FIB pool. If Reinitialize is set to TRUE then the FIB header is
6176 +    reinitialzied and is ready for reuse on return from this routine.
6177 +
6178 +Arguments:
6179 +
6180 +    Fib is a pointer to the FIB that caller wishes to complete processing on. 
6181 +
6182 +    Size - Size of the completion Packet(Opitional). If not present than the current
6183 +           largest size in the Fib will be used
6184 +    
6185 +    Reinitialize is a boolean which determines if the routine will ready the
6186 +        completed FIB for reuse(TRUE) or not(FALSE).
6187 +
6188 +Return Value:
6189 +
6190 +    NT_SUCCESS if a Fib was returned to the caller.
6191 +    NT_ERROR if event was an invalid event. 
6192 +
6193 +--*/
6194 +{
6195 +    PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
6196 +       PAFA_COMM_ADAPTER Adapter = FibContext->Adapter;
6197 +       PFIB Fib = FibContext->Fib;
6198 +
6199 +    //
6200 +    // Check for a fib which has already been completed
6201 +    //
6202 +
6203 +//     ASSERT(Fib->Header.XferState & AdapterProcessed);
6204 +    if (Fib->Header.XferState == 0)
6205 +        return(STATUS_SUCCESS);
6206 +
6207 +    //
6208 +    // If we plan to do anything check the structure type first.
6209 +    // 
6210 +
6211 +    if ( Fib->Header.StructType != TFib ) {
6212 +        FsaCommPrint("Error CompleteFib called with a non Fib structure.\n");
6213 +        return(STATUS_UNSUCCESSFUL);
6214 +    }
6215 +
6216 +#if 0
6217 +//#if FSA_ADAPTER_METER
6218 +       //
6219 +       // Meter the completion
6220 +       //
6221 +       fsaMeterEnd(                                            // meter the end of an operation
6222 +               &(Adapter->FibMeter),                   // .. the meter
6223 +               IrpContext->FibMeterType,               // .. type of operation
6224 +               &(IrpContext->FibStartTime),    // .. ptr to operation start timestamp
6225 +               FibGetMeterSize(Fib,                    // .. number of bytes in operation
6226 +                               IrpContext->FibMeterType, 
6227 +                               IrpContext->FibSubCommand));
6228 +#endif // FSA_ADAPTER_METER
6229 +       
6230 +    //
6231 +    // This block completes a cdb which orginated on the host and we just need
6232 +    // to deallocate the cdb or reinit it. At this point the command is complete
6233 +    // that we had sent to the adapter and this cdb could be reused.
6234 +    //
6235 +       
6236 +    if ( (Fib->Header.XferState & SentFromHost) &&
6237 +         (Fib->Header.XferState & AdapterProcessed)) {
6238 +        
6239 +        ASSERT(FibContext->LogicalFibAddress.LowPart != 0);
6240 +
6241 +        return( DeallocateFib(FibContext) ); 
6242 +       
6243 +    //
6244 +    // This handles the case when the host has aborted the I/O to the
6245 +    // adapter because the adapter is not responding
6246 +    //
6247 +
6248 +    } else if (Fib->Header.XferState & SentFromHost) {
6249 +
6250 +        ASSERT(FibContext->LogicalFibAddress.LowPart != 0);
6251 +
6252 +
6253 +        return( DeallocateFib(FibContext) ); 
6254 +
6255 +    } else if (Fib->Header.XferState & HostOwned) {
6256 +
6257 +        return(DeallocateFib(FibContext));
6258 +
6259 +    } else {
6260 +        cmn_err(CE_WARN, "CompleteFib: Unknown xferstate detected.\n");
6261 +               FsaBugCheck(0,0,0);
6262 +    }   
6263 +    return(STATUS_SUCCESS);
6264 +}
6265 +
6266 +VOID
6267 +HandleDriverAif(
6268 +    IN PAFA_COMM_ADAPTER Adapter,
6269 +       IN PCOMM_FIB_CONTEXT FibContext
6270 +    )
6271 +/*++
6272 +
6273 +Routine Description:
6274 +
6275 +       This routine handles a driver notify fib from the adapter and dispatches it to 
6276 +       the appropriate routine for handling.
6277 +
6278 +Arguments:
6279 +
6280 +       Adapter - Which adapter this fib is from
6281 +       FibContext - Pointer to FibContext from adapter.
6282 +    
6283 +Return Value:
6284 +
6285 +    Nothing.
6286 +    
6287 +--*/
6288 +{
6289 +       PFIB Fib = FibContext->Fib;
6290 +       PAFA_CLASS_DRIVER ClassDriver;
6291 +       BOOLEAN Handled = FALSE;
6292 +
6293 +
6294 +       //
6295 +       // First loop through all of the class drivers to give them a chance to handle
6296 +       // the Fib.
6297 +       //
6298 +
6299 +       ClassDriver = Adapter->ClassDriverList;
6300 +
6301 +       while (ClassDriver) {
6302 +
6303 +               if (ClassDriver->HandleAif) {
6304 +
6305 +                       if (ClassDriver->HandleAif( ClassDriver->ClassDriverExtension, FibContext ) ) {
6306 +
6307 +                               Handled = TRUE;
6308 +                               break;
6309 +
6310 +                       }
6311 +               }
6312 +
6313 +               ClassDriver = ClassDriver->Next;
6314 +       }
6315 +
6316 +       if (!Handled) {
6317 +
6318 +               //
6319 +               // Set the status of this FIB to be Invalid parameter.
6320 +               //
6321 +
6322 +//             *(FSASTATUS *)Fib->data = ST_INVAL;
6323 +               *(FSASTATUS *)Fib->data = ST_OK;
6324 +
6325 +
6326 +               CompleteAdapterFib(FibContext, sizeof(FSASTATUS));
6327 +
6328 +       }
6329 +}
6330 +
6331 +int
6332 +NormCommandThread(
6333 +    IN PAFA_COMM_ADAPTER Adapter
6334 +    )
6335 +/*++
6336 +
6337 +Routine Description:
6338 +
6339 +    Waits on the commandready event in it's queue. When the event gets set it will
6340 +    pull FIBs off it's queue. It will continue to pull FIBs off till the queue is empty.
6341 +    When the queue is empty it will wait for more FIBs.
6342 +
6343 +Arguments:
6344 +
6345 +    Context is used. All data os global
6346 +    
6347 +Return Value:
6348 +    Nothing.
6349 +    
6350 +--*/
6351 +{
6352 +    PFIB Fib, NewFib;
6353 +       COMM_FIB_CONTEXT FibContext; // for error logging
6354 +    KIRQL SavedIrql;
6355 +       PCOMM_REGION CommRegion = Adapter->CommRegion;
6356 +       PLIST_ENTRY Entry;
6357 +       PGET_ADAPTER_FIB_CONTEXT AdapterFibContext;
6358 +
6359 +       //
6360 +       // We can only have one thread per adapter for AIF's.
6361 +       //
6362 +
6363 +       if (Adapter->AifThreadStarted) {
6364 +               return (EINVAL);
6365 +       }
6366 +
6367 +// cmn_err(CE_DEBUG, "AIF thread started");
6368 +
6369 +       //
6370 +       // Let the DPC know it has a place to send the AIF's to.
6371 +       //
6372 +
6373 +       Adapter->AifThreadStarted = TRUE;
6374 +
6375 +       RtlZeroMemory(&FibContext, sizeof(COMM_FIB_CONTEXT));
6376 +
6377 +       OsSpinLockAcquire(CommRegion->HostNormCmdQue.QueueLock);
6378 +
6379 +    while (TRUE) {
6380 +
6381 +               //
6382 +               // NOTE : the QueueLock is held at the top of each loop.
6383 +               //
6384 +
6385 +               ASSERT(OsSpinLockOwned(CommRegion->HostNormCmdQue.QueueLock));
6386 +
6387 +               while (!IsListEmpty(&(CommRegion->HostNormCmdQue.CommandQueue))) {
6388 +                       PLIST_ENTRY Entry;
6389 +                       PAIFCOMMANDTOHOST AifCommandToHost;
6390 +
6391 +                       Entry = RemoveHeadList(&(CommRegion->HostNormCmdQue.CommandQueue));
6392 +
6393 +                       OsSpinLockRelease(CommRegion->HostNormCmdQue.QueueLock);
6394 +
6395 +                       Fib = CONTAINING_RECORD( Entry, FIB, Header.FibLinks );
6396 +                                               
6397 +                       //
6398 +                       // We will process the FIB here or pass it to a worker thread that is TBD. We Really
6399 +                       // can't do anything at this point since we don't have anything defined for this thread to
6400 +                       // do.
6401 +                       //
6402 +                       
6403 +                       // cmn_err(CE_DEBUG, "Got Fib from the adapter with a NORMAL priority, command 0x%x.\n", Fib->Header.Command);
6404 +
6405 +                       RtlZeroMemory( &FibContext, sizeof(COMM_FIB_CONTEXT) );
6406 +
6407 +
6408 +                   FibContext.NodeTypeCode = FSAFS_NTC_FIB_CONTEXT;
6409 +                   FibContext.NodeByteSize = sizeof( COMM_FIB_CONTEXT );
6410 +                       FibContext.Fib = Fib;
6411 +                       FibContext.FibData = Fib->data;
6412 +                       FibContext.Adapter = Adapter;
6413 +
6414 +                       
6415 +                       //
6416 +                       // We only handle AifRequest fibs from the adapter.
6417 +                       //
6418 +
6419 +                       ASSERT(Fib->Header.Command == AifRequest);
6420 +
6421 +
6422 +                       AifCommandToHost = (PAIFCOMMANDTOHOST) Fib->data;
6423 +
6424 +                       if (AifCommandToHost->command == AifCmdDriverNotify) {
6425 +
6426 +
6427 +
6428 +                               HandleDriverAif( Adapter, &FibContext );
6429 +
6430 +                       } else {
6431 +                                       AAC_UINT32 time_now, time_last;
6432 +                                       time_now = (AAC_UINT32)OsGetSeconds();
6433 +                       
6434 +
6435 +                               OsCvLockAcquire(Adapter->AdapterFibMutex);
6436 +
6437 +                               Entry = Adapter->AdapterFibContextList.Flink;
6438 +
6439 +                               //
6440 +                               // For each Context that is on the AdapterFibContextList, make a copy of the
6441 +                               // fib, and then set the event to wake up the thread that is waiting for it.
6442 +                               //
6443 +
6444 +                               while (Entry != &Adapter->AdapterFibContextList) {
6445 +
6446 +                                       //
6447 +                                       // Extract the AdapterFibContext
6448 +                                       //
6449 +
6450 +                                       AdapterFibContext = CONTAINING_RECORD( Entry, GET_ADAPTER_FIB_CONTEXT, NextContext );
6451 +
6452 +                                       //
6453 +                                       // Check if the queue is getting backlogged
6454 +                                       //
6455 +                                       if ( AdapterFibContext->FibCount > 20 ) {
6456 +                                               time_last = (AAC_UINT32)(AdapterFibContext->FileObject);
6457 +
6458 +                                               //
6459 +                                               // has it been > 2 minutes since the last read off the queue?
6460 +                                               //
6461 +                                               if ((time_now - time_last) > 120) {
6462 +                                                       Entry = Entry->Flink;
6463 +                                                       // cmn_err (CE_WARN, "aifd: Flushing orphaned AdapterFibContext: idle %d seconds, %d fibs",
6464 +                                                       //               time_now - time_last,
6465 +                                                       //               AdapterFibContext->FibCount);
6466 +                                                       FsaCloseAdapterFibContext ( Adapter, AdapterFibContext );
6467 +                                                       continue;
6468 +                                               }
6469 +                                       }
6470 +                                                                       
6471 +//  Warning: sleep possible while holding spinlock
6472 +                                       NewFib = OsAllocMemory(sizeof(FIB), OS_ALLOC_MEM_SLEEP);
6473 +
6474 +                                       if (NewFib) {
6475 +
6476 +                                               //
6477 +                                               // Make the copy of the FIB
6478 +                                               //
6479 +
6480 +                                               RtlCopyMemory(NewFib, Fib, sizeof(FIB));
6481 +
6482 +                                               //
6483 +                                               // Put the FIB onto the AdapterFibContext's FibList
6484 +                                               //
6485 +
6486 +                                               InsertTailList(&AdapterFibContext->FibList, &NewFib->Header.FibLinks);
6487 +                                               AdapterFibContext->FibCount++;
6488 +
6489 +                                               // 
6490 +                                               // Set the event to wake up the thread that will waiting.
6491 +                                               //
6492 +
6493 +                                               OsCv_signal(&AdapterFibContext->UserEvent);
6494 +
6495 +                                       } else {
6496 +
6497 +                                               cmn_err (CE_WARN, "aifd: didn't allocate NewFib");
6498 +
6499 +                                       }
6500 +
6501 +                                       Entry = Entry->Flink;
6502 +                               }
6503 +
6504 +                               //
6505 +                               // Set the status of this FIB
6506 +                               //
6507 +
6508 +                               *(FSASTATUS *)Fib->data = ST_OK;
6509 +                               
6510 +                               CompleteAdapterFib( &FibContext, sizeof(FSASTATUS) );
6511 +
6512 +                               OsCvLockRelease(Adapter->AdapterFibMutex);
6513 +
6514 +                       }
6515 +
6516 +                       OsSpinLockAcquire(CommRegion->HostNormCmdQue.QueueLock);
6517 +
6518 +               }
6519 +
6520 +               //
6521 +               // There are no more AIF's,  call cv_wait_sig to wait for more
6522 +               // to process.
6523 +               //
6524 +
6525 +               // cmn_err(CE_DEBUG, "no more AIF's going to sleep\n");
6526 +
6527 +               if (OsCv_wait_sig( &(CommRegion->HostNormCmdQue.CommandReady), 
6528 +                                                CommRegion->HostNormCmdQue.QueueLock ) == 0) {
6529 +
6530 +                       OsSpinLockRelease(CommRegion->HostNormCmdQue.QueueLock);
6531 +
6532 +                       Adapter->AifThreadStarted = FALSE;
6533 +
6534 +                       // cmn_err(CE_DEBUG, "AifThread awoken by a signal\n");
6535 +                       
6536 +                       return (EINTR);
6537 +                       
6538 +               }                                
6539 +
6540 +               // cmn_err(CE_DEBUG, "Aif thread awake, going to look for more AIF's\n");
6541 +
6542 +       }
6543 +}
6544 +    
6545 +
6546 +PVOID
6547 +FsaGetFibData(
6548 +       IN PFIB_CONTEXT Context
6549 +       )
6550 +{
6551 +    PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
6552 +
6553 +       return ((PVOID)FibContext->Fib->data);
6554 +}          
6555 +                              
6556 +
6557 +#ifdef API_THROTTLE
6558 +
6559 +void ThrottlePeriodEndDpcRtn(
6560 +    IN PKDPC Dpc,
6561 +    IN PVOID DeferredContext,
6562 +    IN PVOID SystemArgument1,
6563 +    IN PVOID SystemArgument2
6564 +    )
6565 +/*++
6566 +
6567 +Routine Description:
6568 +
6569 +    This routine is called as a DPC when a throttle period expires. It
6570 +       restarts all threads suspended due to the throttling flow control.
6571 +       
6572 +       The throttling counted semaphore is signalled for all waiting threads
6573 +       and the indicator of throttling active is cleared.
6574 +
6575 +Arguments:
6576 +
6577 +    Dpc                                - Pointer to Dpc structure. Not used.
6578 +       DefferedContext - Pointer to per-adapter context. This is used to locate the
6579 +                                         throttle information for this adapter.
6580 +    SystemArgument1    - Not used
6581 +       SystemArgument2 - Not used
6582 +       
6583 +Return Value:
6584 +
6585 +       None.
6586 +
6587 +--*/
6588 +{
6589 +       PCOMM_REGION CommRegion;
6590 +       PAFA_COMM_ADAPTER Adapter = (PAFA_COMM_ADAPTER) DeferredContext;
6591 +
6592 +       CommRegion = Adapter->CommRegion;
6593 +
6594 +       //
6595 +       // Acquire the spinlock protecting the throttle status.
6596 +       //
6597 +       OsSpinLockAcquire(CommRegion->AdapNormCmdQue.QueueLock);
6598 +
6599 +       FsaCommPrint("ThrottlePeriodEndDpc\n");
6600 +
6601 +       //
6602 +       // Check that the timer has fired as many times as it was set !
6603 +       //
6604 +
6605 +       CommRegion->ThrottleTimerFires++;
6606 +       ASSERT(CommRegion->ThrottleTimerFires == CommRegion->ThrottleTimerSets);
6607 +
6608 +       //
6609 +       // The throttle period is now over. Restart all threads waiting
6610 +       // on the throttle being released.
6611 +       // Clear the throttle active indicator. This will allow new FIBs
6612 +       // to be sent to the adapter once we release the spinlock on exiting
6613 +       // the DPC. This means all restarted threads will be runnable
6614 +       // threads by then.
6615 +       //
6616 +
6617 +       ASSERT(CommRegion->ThrottleActive == TRUE);             // The throttle had better be on !
6618 +       CommRegion->ThrottleActive = FALSE;                             // This allows new data FIBs to go to the adapter on dpc exit
6619 +
6620 +       OsSpinLockRelease(CommRegion->AdapNormCmdQue.QueueLock);
6621 +}
6622 +
6623 +#endif // #ifdef API_THROTTLE
6624 +
6625 +/*
6626 + * Overrides for Emacs so that we almost follow Linus's tabbing style.
6627 + * Emacs will notice this stuff at the end of the file and automatically
6628 + * adjust the settings for this buffer only.  This must remain at the end
6629 + * of the file.
6630 + * ---------------------------------------------------------------------------
6631 + * Local variables:
6632 + * c-indent-level: 4
6633 + * c-brace-imaginary-offset: 0
6634 + * c-brace-offset: -4
6635 + * c-argdecl-indent: 4
6636 + * c-label-offset: -4
6637 + * c-continued-statement-offset: 4
6638 + * c-continued-brace-offset: 0
6639 + * indent-tabs-mode: nil
6640 + * tab-width: 8
6641 + * End:
6642 + */
6643 diff -burN linux-2.4.7/drivers/scsi/aacraid/dpcsup.c linux/drivers/scsi/aacraid/dpcsup.c
6644 --- linux-2.4.7/drivers/scsi/aacraid/dpcsup.c   Wed Dec 31 18:00:00 1969
6645 +++ linux/drivers/scsi/aacraid/dpcsup.c Sat Jul 21 17:55:13 2001
6646 @@ -0,0 +1,443 @@
6647 +/*++
6648 + * Adaptec aacraid device driver for Linux.
6649 + *
6650 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
6651 + *
6652 + * This program is free software; you can redistribute it and/or modify
6653 + * it under the terms of the GNU General Public License as published by
6654 + * the Free Software Foundation; either version 2, or (at your option)
6655 + * any later version.
6656 + *
6657 + * This program is distributed in the hope that it will be useful,
6658 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
6659 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
6660 + * GNU General Public License for more details.
6661 + *
6662 + * You should have received a copy of the GNU General Public License
6663 + * along with this program; see the file COPYING.  If not, write to
6664 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
6665 + *
6666 + * Module Name:
6667 + *  dpcsup.c
6668 + *
6669 + * Abstract: All DPC processing routines for the cyclone board occur here.
6670 + *
6671 + *
6672 + --*/
6673 +
6674 +static char *ident_dpcsup = "aacraid_ident dpcsup.c 1.0.6 2000/10/09 Adaptec, Inc.";
6675 +
6676 +#include "comprocs.h"
6677 +
6678 +
6679 +//
6680 +//  The Bug check file id for this module
6681 +//
6682 +
6683 +#define BugCheckFileId                   (FSAFS_BUG_CHECK_DPCSUP)
6684 +
6685 +#define Dbg                              (DEBUG_TRACE_DPCSUP)
6686 +
6687 +u_int
6688 +CommonNotFullDpc(
6689 +       IN PCOMM_REGION CommRegion
6690 +    )
6691 +/*++
6692 +
6693 +Routine Description:
6694 +
6695 +    This DPC routine will be queued when the adapter interrupts us to let us know the queue is
6696 +    no longer full. The Isr will pass the queue that we will set the not full event.
6697 +
6698 +Arguments:
6699 +
6700 +    Dpc - Pointer to this routine.
6701 +
6702 +    Dummy - is a pointer to the comm region which is global so we don't need it anyway
6703 +
6704 +    Queue is a pointer to the queue structure we will operate on.
6705 +
6706 +    MoreData2 are DPC parameters we don't need for this function. Maybe we can add some accounting
6707 +        stuff in here.
6708 +
6709 +Return Value:
6710 +    Nothing.
6711 +
6712 +--*/
6713 +{
6714 +
6715 +#ifdef unix_queue_full
6716 +    KeSetEvent(&Queue->QueueFull, 0, FALSE);
6717 +#endif
6718 +
6719 +}
6720 +
6721 +int GatherFibTimes = 0;
6722 +
6723 +// XXX - hack this in until I figure out which header file should contain it. <smb>
6724 +extern ULONG
6725 +FibGetMeterSize(
6726 +    PFIB pFib,
6727 +       ULONG MeterType,
6728 +       char SubCommand
6729 +       );
6730 +
6731 +
6732 +/*++
6733 +
6734 +Routine Description:
6735 +
6736 +    This DPC routine will be queued when the adapter interrupts us to let us know there
6737 +    is a response on our normal priority queue. We will pull off all QE there are and wake
6738 +    up all the waiters before exiting. We will take a spinlock out on the queue before operating
6739 +    on it.
6740 +
6741 +Arguments:
6742 +
6743 +    Dpc - Pointer to this routine.
6744 +
6745 +    OurQueue is a pointer to the queue structure we will operate on.
6746 +
6747 +    MoreData1&2 are DPC parameters we don't need for this function. Maybe we can add some accounting
6748 +        stuff in here.
6749 +
6750 +Return Value:
6751 +    Nothing.
6752 +
6753 +--*/
6754 +u_int
6755 +HostResponseNormalDpc (IN PCOMM_QUE OurQueue)
6756 +{
6757 +    PAFA_COMM_ADAPTER Adapter = OurQueue->Adapter;
6758 +    PQUEUE_ENTRY QueueEntry;
6759 +    PFIB Fib;
6760 +       PCOMM_FIB_CONTEXT FibContext;
6761 +    int Consumed = 0;
6762 +       KIRQL OldIrql;
6763 +
6764 +       LARGE_INTEGER ResponseAllocSize;
6765 +
6766 +#ifdef commdebug
6767 +    FsaCommPrint("entering the host normal reponse dpc routine.\n");
6768 +#endif
6769 +
6770 +       OsSpinLockAcquire( OurQueue->QueueLock );       
6771 +
6772 +    //
6773 +    // Keep pulling response QEs off the response queue and waking
6774 +    // up the waiters until there are no more QEs. We then return
6775 +    // back to the system. If no response was requesed we just
6776 +    // deallocate the Fib here and continue.
6777 +    //
6778 +
6779 + loop:
6780 +    while ( GetConsumerEntry( Adapter, OurQueue, &QueueEntry) ) {
6781 +
6782 +               int IsFastResponse;
6783 +
6784 +               IsFastResponse = (int) (QueueEntry->FibAddress & 0x01);
6785 +               Fib = (PFIB) (QueueEntry->FibAddress & ~0x01);
6786 +
6787 +               FreeConsumerEntry(Adapter, OurQueue, HostNormRespQueue);
6788 +
6789 +               FibContext = (PCOMM_FIB_CONTEXT)Fib->Header.SenderData;
6790 +
6791 +               ASSERT(FibContext->Fib == Fib);
6792 +
6793 +               //
6794 +               // Remove this FibContext from the Outstanding I/O queue.
6795 +               // But only if it has not already been timed out.
6796 +               //
6797 +               // If the fib has been timed out already, then just continue.
6798 +               // The caller has already been notified that the fib timed out.
6799 +               //
6800 +
6801 +               if (!(FibContext->Flags & FIB_CONTEXT_FLAG_TIMED_OUT)) {
6802 +
6803 +                       RemoveEntryList( &FibContext->QueueEntry );
6804 +                       Adapter->CommRegion->AdapNormCmdQue.NumOutstandingIos--;
6805 +
6806 +               } else {
6807 +
6808 +                       FsaCommLogEvent(FibContext,
6809 +                                                       FsaCommData.DeviceObject, 
6810 +                                                       FSAFS_TIMED_OUT_FIB_COMPLETED,
6811 +                                                       STATUS_UNSUCCESSFUL, 
6812 +                                                       BugCheckFileId | __LINE__,
6813 +                                                       FACILITY_FSAFS_ERROR_CODE,
6814 +                                                       NULL,
6815 +                                                       TRUE);                  
6816 +
6817 +                       continue;
6818 +
6819 +               }
6820 +
6821 +               OsSpinLockRelease( OurQueue->QueueLock );
6822 +
6823 +               if (IsFastResponse) {
6824 +
6825 +                       //
6826 +                       // doctor the fib
6827 +                       //
6828 +
6829 +                       *(FSASTATUS *)Fib->data = ST_OK;
6830 +
6831 +                       Fib->Header.XferState |= AdapterProcessed;
6832 +
6833 +               }
6834 +
6835 +               ASSERT((Fib->Header.XferState & (AdapterProcessed | HostOwned | SentFromHost)) == (AdapterProcessed | HostOwned | SentFromHost));
6836 +
6837 +               FIB_COUNTER_INCREMENT(FsaCommData.FibRecved);
6838 +
6839 +               ASSERT(FsaCommData.FibsSent >= FsaCommData.FibRecved);
6840 +
6841 +
6842 +               if (Fib->Header.Command == NuFileSystem) {
6843 +
6844 +                       FSASTATUS *pStatus = (FSASTATUS *)Fib->data;
6845 +
6846 +                       if (*pStatus & 0xffff0000) {
6847 +
6848 +                               ULONG Hint = *pStatus;
6849 +
6850 +                               *pStatus = ST_OK;
6851 +
6852 +/*
6853 +                               DbgPrint("Replacing hint in fid (drive = %d, f1 = 0x%x, f2 = 0x%x, hint = 0x%x, new_hint = 0x%x)\n", 
6854 +                                                IrpContext->NonPaged->FileId.fid_driveno,
6855 +                                                IrpContext->NonPaged->FileId.fid_f1,
6856 +                                                IrpContext->NonPaged->FileId.fid_f2,
6857 +                                                IrpContext->NonPaged->FileId.fid_hint,
6858 +                                                Hint);
6859 +*/
6860 +
6861 +                       }
6862 +
6863 +               }
6864 +
6865 +               if (Fib->Header.XferState & (NoResponseExpected | Async) ) {
6866 +
6867 +                       ASSERT(FibContext->FibCallback);
6868 +
6869 +               if (Fib->Header.XferState & NoResponseExpected)
6870 +                               FIB_COUNTER_INCREMENT(FsaCommData.NoResponseRecved);
6871 +                       else 
6872 +                               FIB_COUNTER_INCREMENT(FsaCommData.AsyncRecved);
6873 +
6874 +                       //
6875 +                       // NOTE:  we can not touch the FibContext after this call, because it may have been
6876 +                       // deallocated.
6877 +                       //
6878 +
6879 +                       FibContext->FibCallback(FibContext->FibCallbackContext, FibContext, STATUS_SUCCESS);
6880 +
6881 +               } else {
6882 +
6883 +                       OsCvLockAcquire( FibContext->FsaEventMutex);
6884 +
6885 +                       FibContext->FibComplete = 1;
6886 +
6887 +                       OsCv_signal( &FibContext->FsaEvent );
6888 +
6889 +                       OsCvLockRelease( FibContext->FsaEventMutex );
6890 +
6891 +                       FIB_COUNTER_INCREMENT(FsaCommData.NormalRecved);
6892 +                       
6893 +               }
6894 +
6895 +
6896 +               Consumed++;
6897 +
6898 +               OsSpinLockAcquire( OurQueue->QueueLock );
6899 +               
6900 +    }
6901 +
6902 +       if (Consumed > FsaCommData.PeakFibsConsumed)
6903 +               FsaCommData.PeakFibsConsumed = Consumed;
6904 +
6905 +       if (Consumed == 0) 
6906 +               FsaCommData.ZeroFibsConsumed++;
6907 +
6908 +       if (FsaCommData.HardInterruptModeration) {
6909 +
6910 +               //
6911 +               // Re-Enable the interrupt from the adapter, then recheck to see if anything has 
6912 +               // been put on the queue.  This removes the race condition that exists between the
6913 +               // last time we checked the queue, and when we re-enabled the interrupt.
6914 +               //
6915 +               // If there is something on the queue, then go handle it.
6916 +               //
6917 +
6918 +               EnableInterrupt( Adapter, HostNormRespQue, FALSE );
6919 +
6920 +               if (ConsumerEntryAvailable( Adapter, OurQueue ) ) {
6921 +
6922 +                       DisableInterrupt( Adapter, HostNormRespQue, FALSE );
6923 +
6924 +                       goto loop;
6925 +
6926 +               }
6927 +       }
6928 +
6929 +#ifdef commdebug
6930 +    FsaCommPrint("Exiting host normal reponse dpc routine after consuming %d QE(s).\n",Consumed);
6931 +#endif
6932 +
6933 +       OsSpinLockRelease( OurQueue->QueueLock );
6934 +
6935 +}
6936 +
6937 +/*++
6938 +
6939 +Routine Description:
6940 +
6941 +    This DPC routine wiol be queued when the adapter interrupts us to let us know there
6942 +    is a response on our high priority queue. We will pull off all QE there are and wake
6943 +    up all the waiters before exiting. We will take a spinlock out on the queue before operating
6944 +    on it.
6945 +
6946 +Arguments:
6947 +
6948 +    Dpc - Pointer to this routine.
6949 +
6950 +    OurQueue is a pointer to the queue structure we will operate on.
6951 +
6952 +    MoreData1&2 are DPC parameters we don't need for this function. Maybe we can add some accounting
6953 +        stuff in here.
6954 +
6955 +Return Value:
6956 +    Nothing.
6957 +
6958 +--*/
6959 +u_int
6960 +HostResponseHighDpc (IN PCOMM_QUE OurQueue)
6961 +{}
6962 +
6963 +
6964 +/*++
6965 +
6966 +Routine Description:
6967 +
6968 +    This DPC routine will be queued when the adapter interrupts us to let us know there
6969 +    is a command on our high priority queue. We will pull off all QE there are and wake
6970 +    up all the waiters before exiting. We will take a spinlock out on the queue before operating
6971 +    on it.
6972 +
6973 +Arguments:
6974 +
6975 +    Dpc - Pointer to this routine.
6976 +
6977 +    OurQueue is a pointer to the queue structure we will operate on.
6978 +
6979 +    MoreData1&2 are DPC parameters we don't need for this function. Maybe we can add some accounting
6980 +        stuff in here.
6981 +
6982 +Return Value:
6983 +    Nothing.
6984 +
6985 +--*/
6986 +u_int
6987 +HostCommandHighDpc (IN PCOMM_QUE OurQueue)
6988 +{}
6989 +
6990 +
6991 +/*++
6992 +
6993 +Routine Description:
6994 +
6995 +    This DPC routine will be queued when the adapter interrupts us to let us know there
6996 +    is a command on our normal priority queue. We will pull off all QE there are and wake
6997 +    up all the waiters before exiting. We will take a spinlock out on the queue before operating
6998 +    on it.
6999 +
7000 +Arguments:
7001 +
7002 +    Dpc - Pointer to this routine.
7003 +
7004 +    OurQueue is a pointer to the queue structure we will operate on.
7005 +
7006 +    MoreData1&2 are DPC parameters we don't need for this function. Maybe we can add some accounting
7007 +        stuff in here.
7008 +
7009 +Return Value:
7010 +    Nothing.
7011 +
7012 +--*/
7013 +u_int
7014 +HostCommandNormDpc (IN PCOMM_QUE OurQueue)
7015 +{
7016 +    PAFA_COMM_ADAPTER Adapter = OurQueue->Adapter;
7017 +    PQUEUE_ENTRY QueueEntry;
7018 +
7019 +       OsSpinLockAcquire( OurQueue->QueueLock );
7020 +
7021 +    //
7022 +    // Keep pulling response QEs off the response queue and waking
7023 +    // up the waiters until there are no more QEs. We then return
7024 +    // back to the system.
7025 +    //
7026 +
7027 +    while ( GetConsumerEntry( Adapter, OurQueue, &QueueEntry) ) {
7028 +
7029 +               PFIB Fib;
7030 +
7031 +               Fib = (PFIB)QueueEntry->FibAddress;
7032 +
7033 +
7034 +               if (Adapter->AifThreadStarted) {
7035 +
7036 +
7037 +//                     cmn_err(CE_CONT, "^Received AIF, putting onto command queue\n");
7038 +
7039 +
7040 +               InsertTailList(&OurQueue->CommandQueue, &Fib->Header.FibLinks);
7041 +               FreeConsumerEntry(Adapter, OurQueue, HostNormCmdQueue);
7042 +               OsCv_signal(&OurQueue->CommandReady);
7043 +
7044 +
7045 +
7046 +               } else {
7047 +
7048 +
7049 +
7050 +                       COMM_FIB_CONTEXT FibContext;
7051 +
7052 +               
7053 +
7054 +               FreeConsumerEntry(Adapter, OurQueue, HostNormCmdQueue);
7055 +
7056 +
7057 +
7058 +                       OsSpinLockRelease( OurQueue->QueueLock );
7059 +
7060 +
7061 +
7062 +//                     cmn_err(CE_CONT, "^Received AIF, thread not started\n");
7063 +
7064 +
7065 +                       RtlZeroMemory( &FibContext, sizeof(COMM_FIB_CONTEXT) );
7066 +
7067 +                   FibContext.NodeTypeCode = FSAFS_NTC_FIB_CONTEXT;
7068 +                   FibContext.NodeByteSize = sizeof( COMM_FIB_CONTEXT );
7069 +                       FibContext.Fib = Fib;
7070 +                       FibContext.FibData = Fib->data;
7071 +                       FibContext.Adapter = Adapter;
7072 +
7073 +                       //
7074 +                       // Set the status of this FIB
7075 +                       //
7076 +
7077 +                       *(FSASTATUS *)Fib->data = ST_OK;
7078 +                               
7079 +                       CompleteAdapterFib( &FibContext, sizeof(FSASTATUS) );
7080 +
7081 +
7082 +
7083 +                       OsSpinLockAcquire( OurQueue->QueueLock );
7084 +               }               
7085 +    }
7086 +
7087 +       OsSpinLockRelease( OurQueue->QueueLock );
7088 +
7089 +}
7090 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/AacGenericTypes.h linux/drivers/scsi/aacraid/include/AacGenericTypes.h
7091 --- linux-2.4.7/drivers/scsi/aacraid/include/AacGenericTypes.h  Wed Dec 31 18:00:00 1969
7092 +++ linux/drivers/scsi/aacraid/include/AacGenericTypes.h        Sat Jul 21 17:55:13 2001
7093 @@ -0,0 +1,57 @@
7094 +/*++
7095 + * Adaptec aacraid device driver for Linux.
7096 + *
7097 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
7098 + *
7099 + * This program is free software; you can redistribute it and/or modify
7100 + * it under the terms of the GNU General Public License as published by
7101 + * the Free Software Foundation; either version 2, or (at your option)
7102 + * any later version.
7103 + *
7104 + * This program is distributed in the hope that it will be useful,
7105 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7106 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
7107 + * GNU General Public License for more details.
7108 + *
7109 + * You should have received a copy of the GNU General Public License
7110 + * along with this program; see the file COPYING.  If not, write to
7111 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
7112 + *
7113 + * Module Name:
7114 + *
7115 + *  AacGenericTypes.h
7116 + *
7117 + * Abstract:
7118 + *
7119 + *     The module defines the generic data types that all of the other header files
7120 + *     depend upon.
7121 + --*/
7122 +
7123 +#ifndef _AAC_GENERIC_TYPES
7124 +#define _AAC_GENERIC_TYPES
7125 +
7126 +static char *ident_AacGeneric = "aacraid_ident AacGenericTypes.h 1.0.6 2000/10/09 Adaptec, Inc.";
7127 +
7128 +typedef        char                    AAC_INT8, *PAAC_INT8;
7129 +typedef short                  AAC_INT16, *PAAC_INT16;
7130 +typedef int                    AAC_INT32, *PAAC_INT32;
7131 +typedef long long              AAC_INT64, *PAAC_INT64;
7132 +
7133 +typedef unsigned char  AAC_UINT8, *PAAC_UINT8;
7134 +typedef unsigned short AAC_UINT16, *PAAC_UINT16;
7135 +typedef unsigned int   AAC_UINT32, *PAAC_UINT32;
7136 +typedef unsigned long long     AAC_UINT64, *PAAC_UINT64;
7137 +
7138 +typedef void                   AAC_VOID, *PAAC_VOID;
7139 +
7140 +//
7141 +// this compiler uses 32 bit enum data types
7142 +//
7143 +
7144 +#define        AAC_32BIT_ENUMS 1
7145 +#define FAILURE 1
7146 +#define INTR_UNCLAIMED 1
7147 +#define INTR_CLAIMED 0
7148 +
7149 +#endif // _AAC_GENERIC_TYPES
7150 +
7151 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/aac_unix_defs.h linux/drivers/scsi/aacraid/include/aac_unix_defs.h
7152 --- linux-2.4.7/drivers/scsi/aacraid/include/aac_unix_defs.h    Wed Dec 31 18:00:00 1969
7153 +++ linux/drivers/scsi/aacraid/include/aac_unix_defs.h  Sat Jul 21 17:55:13 2001
7154 @@ -0,0 +1,300 @@
7155 +/*++
7156 + * Adaptec aacraid device driver for Linux.
7157 + *
7158 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
7159 + *
7160 + * This program is free software; you can redistribute it and/or modify
7161 + * it under the terms of the GNU General Public License as published by
7162 + * the Free Software Foundation; either version 2, or (at your option)
7163 + * any later version.
7164 + *
7165 + * This program is distributed in the hope that it will be useful,
7166 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7167 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
7168 + * GNU General Public License for more details.
7169 + *
7170 + * You should have received a copy of the GNU General Public License
7171 + * along with this program; see the file COPYING.  If not, write to
7172 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
7173 + *
7174 + * Module Name:
7175 + *
7176 + *  aac_unix_defs.h
7177 + *
7178 + * Abstract:
7179 + *
7180 + *     Macro definition and typedefs
7181 + *
7182 + --*/
7183 +
7184 +#ifndef _AAC_UNIX_DEFS
7185 +#define _AAC_UNIX_DEFS
7186 +
7187 +static char *ident_aac_unix = "aacraid_ident aac_unix_defs.h 1.0.6 2000/10/09 Adaptec, Inc.";
7188 +
7189 +#define        AAC_MAX_ADAPTERS        64
7190 +
7191 +#ifndef        TRUE
7192 +#define TRUE   1
7193 +#define FALSE  0
7194 +#endif
7195 +
7196 +#define PAGE_SIZE      4096
7197 +
7198 +typedef        void    VOID;
7199 +typedef VOID   *PVOID;
7200 +
7201 +typedef char           CHAR, *PCHAR;
7202 +typedef unsigned char  UCHAR, *PUCHAR;
7203 +typedef short          SHORT, *PSHORT;
7204 +typedef short          CSHORT, *PCSHORT;
7205 +typedef unsigned short         USHORT, *PUSHORT;
7206 +typedef unsigned long  ULONG, *PULONG;
7207 +typedef long           LONG, *PLONG;
7208 +
7209 +typedef unsigned long  BOOLEAN;
7210 +
7211 +typedef unsigned long  AAC_STATUS, *PNT_STATUS;
7212 +
7213 +typedef struct {
7214 +       unsigned long   LowPart;
7215 +       unsigned long   HighPart;
7216 +} LARGE_INTEGER;
7217 +
7218 +typedef LARGE_INTEGER  PHYSICAL_ADDRESS;
7219 +
7220 +
7221 +typedef struct _AFA_IOCTL_CMD {
7222 +       int             cmd;
7223 +       intptr_t        arg;
7224 +       int             flag;
7225 +       cred_t          *cred_p;
7226 +       int             *rval_p;
7227 +} AFA_IOCTL_CMD, *PAFA_IOCTL_CMD;
7228 +
7229 +
7230 +//
7231 +//  Singly linked list structure. Can be used as either a list head, or
7232 +//  as link words.
7233 +//
7234 +
7235 +typedef struct _SINGLE_LIST_ENTRY {
7236 +    struct _SINGLE_LIST_ENTRY *Next;
7237 +} SINGLE_LIST_ENTRY, *PSINGLE_LIST_ENTRY;
7238 +
7239 +
7240 +//
7241 +// Calculate the address of the base of the structure given its type, and an
7242 +// address of a field within the structure.
7243 +//
7244 +
7245 +#define CONTAINING_RECORD(address, type, field) ((type *)( \
7246 +                                                  (PCHAR)(address) - \
7247 +                                                  (PCHAR)(&((type *)0)->field)))
7248 +
7249 +typedef        PVOID   PMDL;
7250 +typedef PVOID  PDEVICE_OBJECT;
7251 +typedef PVOID  PADAPTER_OBJECT;
7252 +typedef ULONG  KIRQL;
7253 +typedef PVOID  HANDLE;
7254 +typedef PVOID  KDPC, *PKDPC;
7255 +typedef PVOID  PFILE_OBJECT;
7256 +typedef PVOID  PIRP;
7257 +typedef PVOID  PDRIVER_OBJECT;
7258 +typedef ULONG  KTIMER;
7259 +
7260 +
7261 +#define        STATUS_SUCCESS          0x00000000
7262 +#define STATUS_PENDING         0x40000001
7263 +#define STATUS_IO_TIMEOUT                      0xc0000001
7264 +#define STATUS_UNSUCCESSFUL                    0xc0000002
7265 +#define STATUS_INSUFFICIENT_RESOURCES  0xc0000005
7266 +#define STATUS_BUFFER_OVERFLOW         0xc0000003
7267 +
7268 +
7269 +#define OUT
7270 +
7271 +
7272 +
7273 +typedef u_int
7274 +(*PUNIX_INTR_HANDLER)(caddr_t Arg);
7275 +
7276 +//
7277 +// Zone Allocation
7278 +//
7279 +
7280 +typedef struct _ZONE_SEGMENT_HEADER {
7281 +    SINGLE_LIST_ENTRY SegmentList;
7282 +    PVOID Reserved;
7283 +} ZONE_SEGMENT_HEADER, *PZONE_SEGMENT_HEADER;
7284 +
7285 +typedef struct _ZONE_HEADER {
7286 +    SINGLE_LIST_ENTRY FreeList;
7287 +    SINGLE_LIST_ENTRY SegmentList;
7288 +    ULONG BlockSize;
7289 +    ULONG TotalSegmentSize;
7290 +} ZONE_HEADER, *PZONE_HEADER;
7291 +
7292 +
7293 +//++
7294 +//
7295 +// PVOID
7296 +// ExAllocateFromZone(
7297 +//     IN PZONE_HEADER Zone
7298 +//     )
7299 +//
7300 +// Routine Description:
7301 +//
7302 +//     This routine removes an entry from the zone and returns a pointer to it.
7303 +//
7304 +// Arguments:
7305 +//
7306 +//     Zone - Pointer to the zone header controlling the storage from which the
7307 +//         entry is to be allocated.
7308 +//
7309 +// Return Value:
7310 +//
7311 +//     The function value is a pointer to the storage allocated from the zone.
7312 +//
7313 +//--
7314 +
7315 +#define ExAllocateFromZone(Zone) \
7316 +    (PVOID)((Zone)->FreeList.Next); \
7317 +    if ( (Zone)->FreeList.Next ) (Zone)->FreeList.Next = (Zone)->FreeList.Next->Next
7318 +
7319 +//++
7320 +//
7321 +// PVOID
7322 +// ExFreeToZone(
7323 +//     IN PZONE_HEADER Zone,
7324 +//     IN PVOID Block
7325 +//     )
7326 +//
7327 +// Routine Description:
7328 +//
7329 +//     This routine places the specified block of storage back onto the free
7330 +//     list in the specified zone.
7331 +//
7332 +// Arguments:
7333 +//
7334 +//     Zone - Pointer to the zone header controlling the storage to which the
7335 +//         entry is to be inserted.
7336 +//
7337 +//     Block - Pointer to the block of storage to be freed back to the zone.
7338 +//
7339 +// Return Value:
7340 +//
7341 +//     Pointer to previous block of storage that was at the head of the free
7342 +//         list.  NULL implies the zone went from no available free blocks to
7343 +//         at least one free block.
7344 +//
7345 +//--
7346 +
7347 +#define ExFreeToZone(Zone,Block)                                    \
7348 +    ( ((PSINGLE_LIST_ENTRY)(Block))->Next = (Zone)->FreeList.Next,  \
7349 +      (Zone)->FreeList.Next = ((PSINGLE_LIST_ENTRY)(Block)),        \
7350 +      ((PSINGLE_LIST_ENTRY)(Block))->Next                           \
7351 +    )
7352 +
7353 +//++
7354 +//
7355 +// BOOLEAN
7356 +// ExIsFullZone(
7357 +//     IN PZONE_HEADER Zone
7358 +//     )
7359 +//
7360 +// Routine Description:
7361 +//
7362 +//     This routine determines if the specified zone is full or not.  A zone
7363 +//     is considered full if the free list is empty.
7364 +//
7365 +// Arguments:
7366 +//
7367 +//     Zone - Pointer to the zone header to be tested.
7368 +//
7369 +// Return Value:
7370 +//
7371 +//     TRUE if the zone is full and FALSE otherwise.
7372 +//
7373 +//--
7374 +
7375 +#define ExIsFullZone(Zone) \
7376 +    ( (Zone)->FreeList.Next == (PSINGLE_LIST_ENTRY)NULL )
7377 +
7378 +
7379 +#define RtlCopyMemory( Destination, Source, Size )     bcopy( (Source), (Destination), (Size) )
7380 +#define RtlZeroMemory( Destination, Size )                     bzero( (Destination), (Size) )
7381 +
7382 +//
7383 +//  Doubly-linked list manipulation routines.  Implemented as macros
7384 +//  but logically these are procedures.
7385 +//
7386 +
7387 +//
7388 +//  VOID
7389 +//  InitializeListHead(
7390 +//      PLIST_ENTRY ListHead
7391 +//      );
7392 +//
7393 +
7394 +#define InitializeListHead(ListHead) (\
7395 +    (ListHead)->Flink = (ListHead)->Blink = (ListHead))
7396 +
7397 +//
7398 +//  BOOLEAN
7399 +//  IsListEmpty(
7400 +//      PLIST_ENTRY ListHead
7401 +//      );
7402 +//
7403 +
7404 +#define IsListEmpty(ListHead) \
7405 +    ((ListHead)->Flink == (ListHead))
7406 +
7407 +//
7408 +//  PLIST_ENTRY
7409 +//  RemoveHeadList(
7410 +//      PLIST_ENTRY ListHead
7411 +//      );
7412 +//
7413 +
7414 +#define RemoveHeadList(ListHead) \
7415 +    (ListHead)->Flink;\
7416 +    {RemoveEntryList((ListHead)->Flink)}
7417 +
7418 +
7419 +//
7420 +//  VOID
7421 +//  RemoveEntryList(
7422 +//      PLIST_ENTRY Entry
7423 +//      );
7424 +//
7425 +
7426 +#define RemoveEntryList(Entry) {\
7427 +    PLIST_ENTRY _EX_Blink;\
7428 +    PLIST_ENTRY _EX_Flink;\
7429 +    _EX_Flink = (Entry)->Flink;\
7430 +    _EX_Blink = (Entry)->Blink;\
7431 +    _EX_Blink->Flink = _EX_Flink;\
7432 +    _EX_Flink->Blink = _EX_Blink;\
7433 +    }
7434 +
7435 +//
7436 +//  VOID
7437 +//  InsertTailList(
7438 +//      PLIST_ENTRY ListHead,
7439 +//      PLIST_ENTRY Entry
7440 +//      );
7441 +//
7442 +
7443 +#define InsertTailList(ListHead,Entry) {\
7444 +    PLIST_ENTRY _EX_Blink;\
7445 +    PLIST_ENTRY _EX_ListHead;\
7446 +    _EX_ListHead = (ListHead);\
7447 +    _EX_Blink = _EX_ListHead->Blink;\
7448 +    (Entry)->Flink = _EX_ListHead;\
7449 +    (Entry)->Blink = _EX_Blink;\
7450 +    _EX_Blink->Flink = (Entry);\
7451 +    _EX_ListHead->Blink = (Entry);\
7452 +    }
7453 +
7454 +#endif /* AAC_UNIX_DEFS */
7455 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/adapter.h linux/drivers/scsi/aacraid/include/adapter.h
7456 --- linux-2.4.7/drivers/scsi/aacraid/include/adapter.h  Wed Dec 31 18:00:00 1969
7457 +++ linux/drivers/scsi/aacraid/include/adapter.h        Sat Jul 21 17:55:13 2001
7458 @@ -0,0 +1,164 @@
7459 +/*++
7460 + * Adaptec aacraid device driver for Linux.
7461 + *
7462 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
7463 + *
7464 + * This program is free software; you can redistribute it and/or modify
7465 + * it under the terms of the GNU General Public License as published by
7466 + * the Free Software Foundation; either version 2, or (at your option)
7467 + * any later version.
7468 + *
7469 + * This program is distributed in the hope that it will be useful,
7470 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7471 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
7472 + * GNU General Public License for more details.
7473 + *
7474 + * You should have received a copy of the GNU General Public License
7475 + * along with this program; see the file COPYING.  If not, write to
7476 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
7477 + *
7478 + * Module Name:
7479 + *
7480 + *   Adapter.h
7481 + *
7482 + * Abstract:
7483 + *   The module contains the definitions for a comm layer view of the adapter.
7484 + *
7485 + *
7486 + *
7487 + --*/
7488 +
7489 +#ifndef _ADAPTER_
7490 +#define _ADAPTER_
7491 +
7492 +static char *ident_adapter = "aacraid_ident adapter.h 1.0.6 2000/10/09 Adaptec, Inc.";
7493 +
7494 +typedef struct _GET_ADAPTER_FIB_CONTEXT {
7495 +
7496 +       NODE_TYPE_CODE          NodeTypeCode;   // used for verification of structure   
7497 +       NODE_BYTE_SIZE          NodeByteSize;
7498 +       PFILE_OBJECT            FileObject;     // used for cleanup
7499 +       LIST_ENTRY              NextContext;    // used to link context's into a linked list
7500 +       OS_CV_T                 UserEvent;      // this is used to wait for the next fib to arrive.
7501 +       BOOLEAN                 WaitingForFib;  // Set to true when thread is in WaitForSingleObject
7502 +       ULONG                   FibCount;       // total number of FIBs on FibList
7503 +       LIST_ENTRY              FibList;
7504 +} GET_ADAPTER_FIB_CONTEXT;
7505 +typedef GET_ADAPTER_FIB_CONTEXT *PGET_ADAPTER_FIB_CONTEXT;
7506 +
7507 +
7508 +typedef struct _FIB_CONTEXT_ZONE_SEGMENT {
7509 +
7510 +       struct _FIB_CONTEXT_ZONE_SEGMENT        *Next;
7511 +       ULONG                                   FibContextSegmentSize;
7512 +       PVOID                                   FibContextSegment;
7513 +       ULONG                                   ExtendSize;
7514 +       MAPFIB_CONTEXT                          MapFibContext;
7515 +
7516 +} FIB_CONTEXT_ZONE_SEGMENT;
7517 +typedef FIB_CONTEXT_ZONE_SEGMENT *PFIB_CONTEXT_ZONE_SEGMENT;
7518 +
7519 +typedef struct _AFA_COMM_ADAPTER {
7520 +
7521 +       struct _AFA_COMM_ADAPTER        *NextAdapter;
7522 +
7523 +    //
7524 +    //  The following fields are used to allocate FIB context structures
7525 +    //  using the zone allocator, and other fixed sized structures from a
7526 +    //  small cache.  The mutex protects access to the zone/lists
7527 +    //
7528 +
7529 +    ZONE_HEADER                FibContextZone;
7530 +       OS_SPINLOCK                     *FibContextZoneSpinLock;
7531 +       int                             FibContextZoneExtendSize;
7532 +
7533 +       PFIB_CONTEXT_ZONE_SEGMENT       FibContextSegmentList;
7534 +
7535 +       PVOID                           FibContextTimedOutList;
7536 +
7537 +       PFIB                            SyncFib;
7538 +       ULONG                           SyncFibPhysicalAddress;
7539 +
7540 +       PCOMM_REGION            CommRegion;
7541 +
7542 +       OS_SPINLOCK_COOKIE      SpinLockCookie;
7543 +
7544 +       //
7545 +       // The user API will use an IOCTL to register itself to receive FIBs
7546 +       // from the adapter.  The following list is used to keep track of all
7547 +       // the threads that have requested these FIBs.  The mutex is used to 
7548 +       // synchronize access to all data associated with the adapter fibs.
7549 +       //
7550 +       LIST_ENTRY                      AdapterFibContextList;
7551 +       OS_CVLOCK                       *AdapterFibMutex;
7552 +
7553 +       //
7554 +       // The following holds which FileObject is allow to send configuration
7555 +       // commands to the adapter that would modify the configuration.
7556 +       //
7557 +       // This is controlled by the FSACTL_OPEN_ADAPTER_CONFIG and FSACTL_CLOSE_ADAPTER_CONFIG
7558 +       // ioctls.
7559 +       //
7560 +       PFILE_OBJECT            AdapterConfigFileObject;
7561 +
7562 +       //
7563 +       // The following is really here because of the simulator
7564 +       //
7565 +       BOOLEAN                         InterruptsBelowDpc;
7566 +
7567 +       //
7568 +       // The following is the device specific extension.
7569 +       //
7570 +       PVOID                   AdapterExtension;       
7571 +       PFSAPORT_FUNCS          AdapterFuncs;
7572 +       void                    *Dip;
7573 +
7574 +       //
7575 +       // The following are user variables that are specific to the mini port.
7576 +       //
7577 +       PFSA_USER_VAR           AdapterUserVars;
7578 +       ULONG                   AdapterUserVarsSize;
7579 +
7580 +       //
7581 +       // The following is the number of the individual adapter..i.e. \Device\Afa0
7582 +       //
7583 +       LONG                    AdapterNumber;
7584 +
7585 +       AFACOMM_FUNCS           CommFuncs;
7586 +
7587 +       PAFA_CLASS_DRIVER       ClassDriverList;
7588 +
7589 +       BOOLEAN                 AifThreadStarted;
7590 +
7591 +} AFA_COMM_ADAPTER;
7592 +
7593 +typedef AFA_COMM_ADAPTER *PAFA_COMM_ADAPTER;
7594 +
7595 +
7596 +#define FsaAllocateAdapterCommArea(Adapter, BaseAddress, Size, Alignment) \
7597 +       Adapter->AdapterFuncs->AllocateAdapterCommArea(Adapter->AdapterExtension, BaseAddress, Size, Alignment)
7598 +
7599 +#define FsaFreeAdapterCommArea(Adapter) \
7600 +       Adapter->AdapterFuncs->FreeAdapterCommArea(Adapter->AdapterExtension)
7601 +
7602 +
7603 +#define AllocateAndMapFibSpace(Adapter, MapFibContext) \
7604 +       Adapter->AdapterFuncs->AllocateAndMapFibSpace(Adapter->AdapterExtension, MapFibContext)
7605 +
7606 +#define UnmapAndFreeFibSpace(Adapter, MapFibContext) \
7607 +       Adapter->AdapterFuncs->UnmapAndFreeFibSpace(Adapter->AdapterExtension, MapFibContext)
7608 +
7609 +#define InterruptAdapter(Adapter) \
7610 +       Adapter->AdapterFuncs->InterruptAdapter(Adapter->AdapterExtension)
7611 +
7612 +#define NotifyAdapter(Adapter, AdapterEvent) \
7613 +       Adapter->AdapterFuncs->NotifyAdapter(Adapter->AdapterExtension, AdapterEvent)
7614 +
7615 +#define EnableInterrupt(Adapter, AdapterEvent, AtDeviceIrq) \
7616 +       Adapter->AdapterFuncs->EnableInterrupt(Adapter->AdapterExtension, AdapterEvent, AtDeviceIrq)
7617 +
7618 +#define DisableInterrupt(Adapter, AdapterEvent, AtDeviceIrq) \
7619 +       Adapter->AdapterFuncs->DisableInterrupt(Adapter->AdapterExtension, AdapterEvent, AtDeviceIrq)
7620 +
7621 +
7622 +#endif // _ADAPTER_
7623 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/afacomm.h linux/drivers/scsi/aacraid/include/afacomm.h
7624 --- linux-2.4.7/drivers/scsi/aacraid/include/afacomm.h  Wed Dec 31 18:00:00 1969
7625 +++ linux/drivers/scsi/aacraid/include/afacomm.h        Sat Jul 21 17:55:13 2001
7626 @@ -0,0 +1,191 @@
7627 +/*++
7628 + * Adaptec aacraid device driver for Linux.
7629 + *
7630 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
7631 + *
7632 + * This program is free software; you can redistribute it and/or modify
7633 + * it under the terms of the GNU General Public License as published by
7634 + * the Free Software Foundation; either version 2, or (at your option)
7635 + * any later version.
7636 + *
7637 + * This program is distributed in the hope that it will be useful,
7638 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7639 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
7640 + * GNU General Public License for more details.
7641 + *
7642 + * You should have received a copy of the GNU General Public License
7643 + * along with this program; see the file COPYING.  If not, write to
7644 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
7645 + *
7646 + * Module Name:
7647 + *   AfaComm.h
7648 + *
7649 + * Abstract:
7650 + *   This module defines all of the external interfaces to the AFA comm layer.
7651 + *
7652 + *
7653 + *
7654 + --*/
7655 +#ifndef _AFACOMM_
7656 +#define _AFACOMM_
7657 +
7658 +static char *ident_afacomm = "aacraid_ident afacomm.h 1.0.6 2000/10/09 Adaptec, Inc.";
7659 +
7660 +#include "fsaport.h"
7661 +
7662 +typedef void   *PFIB_CONTEXT;
7663 +
7664 +typedef VOID
7665 +(*PFIB_CALLBACK)(
7666 +       PVOID           FibCallbackContext,
7667 +       PFIB_CONTEXT    FibContext,
7668 +       AAC_STATUS      Status
7669 +       );
7670 +
7671 +
7672 +typedef PFIB_CONTEXT
7673 +(*PAFA_COMM_ALLOCATE_FIB) (
7674 +       IN PVOID AdapterExtension
7675 +    );
7676 +
7677 +typedef VOID
7678 +(*PAFA_COMM_FREE_FIB) (
7679 +    IN PFIB_CONTEXT FibContext
7680 +    );
7681 +
7682 +
7683 +typedef AAC_STATUS
7684 +(*PAFA_COMM_DEALLOCATE_FIB) (
7685 +    IN PFIB_CONTEXT FibContext
7686 +    );
7687 +
7688 +
7689 +typedef VOID
7690 +(*PAFA_COMM_FREE_FIB_FROM_DPC) (
7691 +    IN PFIB_CONTEXT FibContext
7692 +    );
7693 +
7694 +typedef AAC_STATUS
7695 +(*PAFA_COMM_INITIALIZE_FIB) (
7696 +       IN PFIB_CONTEXT FibContext
7697 +    );
7698 +
7699 +typedef PVOID
7700 +(*PAFA_COMM_GET_FIB_DATA) (
7701 +       IN PFIB_CONTEXT FibContext
7702 +       );
7703 +
7704 +typedef AAC_STATUS
7705 +(*PAFA_COMM_SEND_FIB) (
7706 +    IN FIB_COMMAND Command, 
7707 +       IN PFIB_CONTEXT FibContext,
7708 +    IN ULONG Size,
7709 +    IN COMM_PRIORITIES Priority,
7710 +    IN BOOLEAN Wait,
7711 +    IN PVOID WaitOn,
7712 +    IN BOOLEAN ResponseExpected,
7713 +       IN PFIB_CALLBACK FibCallback,
7714 +       IN PVOID FibCallbackContext
7715 +    );
7716 +
7717 +typedef AAC_STATUS
7718 +(*PAFA_COMM_COMPLETE_FIB) (
7719 +       IN PFIB_CONTEXT FibContext
7720 +    );
7721 +
7722 +typedef AAC_STATUS
7723 +(*PAFA_COMM_COMPLETE_ADAPTER_FIB) (
7724 +       IN PFIB_CONTEXT FibContext,
7725 +       IN USHORT Size
7726 +    );
7727 +
7728 +typedef BOOLEAN
7729 +(*PAFA_COMM_SEND_SYNCH_FIB) (
7730 +       PVOID                   AdapterExtension,
7731 +       FIB_COMMAND     Command,
7732 +       PVOID                   Data,
7733 +       USHORT                  Size,
7734 +       PVOID                   Response,
7735 +       USHORT                  *ResponseSize
7736 +       );
7737 +
7738 +
7739 +typedef struct _AFACOMM_FUNCS {
7740 +       ULONG                                   SizeOfAfaCommFuncs;
7741 +       PAFA_COMM_ALLOCATE_FIB                  AllocateFib;
7742 +       PAFA_COMM_FREE_FIB                      FreeFib;
7743 +       PAFA_COMM_FREE_FIB_FROM_DPC             FreeFibFromDpc;
7744 +       PAFA_COMM_DEALLOCATE_FIB                DeallocateFib;
7745 +       PAFA_COMM_INITIALIZE_FIB                InitializeFib;
7746 +       PAFA_COMM_GET_FIB_DATA                  GetFibData;
7747 +       PAFA_COMM_SEND_FIB                      SendFib;
7748 +       PAFA_COMM_COMPLETE_FIB                  CompleteFib;
7749 +       PAFA_COMM_COMPLETE_ADAPTER_FIB          CompleteAdapterFib;
7750 +       PAFA_COMM_SEND_SYNCH_FIB                SendSynchFib;
7751 +       PFSA_FREE_DMA_RESOURCES                 FreeDmaResources;
7752 +       PFSA_BUILD_SGMAP                        BuildSgMap;
7753 +       PFSA_ADAPTER_ADDR_TO_SYSTEM_ADDR        AdapterAddressToSystemAddress;
7754 +} AFACOMM_FUNCS;
7755 +typedef AFACOMM_FUNCS *PAFACOMM_FUNCS;
7756 +
7757 +
7758 +typedef AAC_STATUS
7759 +(*PAFA_CLASS_OPEN_ADAPTER) (
7760 +       IN PVOID Adapter
7761 +       );
7762 +
7763 +
7764 +typedef AAC_STATUS
7765 +(*PAFA_CLASS_CLOSE_ADAPTER) (
7766 +       IN PVOID Adapter
7767 +       );
7768 +
7769 +
7770 +typedef BOOLEAN
7771 +(*PAFA_CLASS_DEV_CONTROL) (
7772 +       IN PVOID Adapter,
7773 +       IN PAFA_IOCTL_CMD       IoctlCmdPtr,
7774 +       OUT int * Status
7775 +       );
7776 +
7777 +typedef BOOLEAN
7778 +(*PAFA_CLASS_HANDLE_AIF) (
7779 +       IN PVOID Adapter,
7780 +       IN PFIB_CONTEXT FibContext
7781 +       );
7782 +
7783 +
7784 +typedef struct _AFA_NEW_CLASS_DRIVER {
7785 +       PVOID                           ClassDriverExtension;
7786 +       PAFA_CLASS_OPEN_ADAPTER         OpenAdapter;
7787 +        PAFA_CLASS_CLOSE_ADAPTER       CloseAdapter;
7788 +        PAFA_CLASS_DEV_CONTROL                 DeviceControl;
7789 +       PAFA_CLASS_HANDLE_AIF           HandleAif;
7790 +       PFSA_USER_VAR                   UserVars;
7791 +       ULONG                           NumUserVars;
7792 +} AFA_NEW_CLASS_DRIVER;
7793 +typedef AFA_NEW_CLASS_DRIVER *PAFA_NEW_CLASS_DRIVER;
7794 +
7795 +
7796 +typedef struct _AFA_NEW_CLASS_DRIVER_RESPONSE {
7797 +       PAFACOMM_FUNCS          CommFuncs;
7798 +       PVOID                   CommPortExtension;
7799 +       PVOID                   MiniPortExtension;
7800 +       OS_SPINLOCK_COOKIE      SpinLockCookie;
7801 +       void                    *Dip;
7802 +} AFA_NEW_CLASS_DRIVER_RESPONSE;
7803 +typedef AFA_NEW_CLASS_DRIVER_RESPONSE *PAFA_NEW_CLASS_DRIVER_RESPONSE;
7804 +
7805 +
7806 +typedef struct _AFA_CLASS_DRIVER {
7807 +       struct _AFA_CLASS_DRIVER        *Next;
7808 +       PVOID                           ClassDriverExtension;
7809 +       PAFA_CLASS_OPEN_ADAPTER         OpenAdapter;
7810 +       PAFA_CLASS_CLOSE_ADAPTER        CloseAdapter;
7811 +       PAFA_CLASS_DEV_CONTROL          DeviceControl;
7812 +       PAFA_CLASS_HANDLE_AIF           HandleAif;
7813 +} AFA_CLASS_DRIVER;
7814 +typedef AFA_CLASS_DRIVER *PAFA_CLASS_DRIVER;
7815 +
7816 +
7817 +#endif // _AFACOMM_
7818 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/aifstruc.h linux/drivers/scsi/aacraid/include/aifstruc.h
7819 --- linux-2.4.7/drivers/scsi/aacraid/include/aifstruc.h Wed Dec 31 18:00:00 1969
7820 +++ linux/drivers/scsi/aacraid/include/aifstruc.h       Sat Jul 21 17:55:13 2001
7821 @@ -0,0 +1,319 @@
7822 +/*++
7823 + * Adaptec aacraid device driver for Linux.
7824 + *
7825 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
7826 + *
7827 + * This program is free software; you can redistribute it and/or modify
7828 + * it under the terms of the GNU General Public License as published by
7829 + * the Free Software Foundation; either version 2, or (at your option)
7830 + * any later version.
7831 + *
7832 + * This program is distributed in the hope that it will be useful,
7833 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7834 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
7835 + * GNU General Public License for more details.
7836 + *
7837 + * You should have received a copy of the GNU General Public License
7838 + * along with this program; see the file COPYING.  If not, write to
7839 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
7840 + *
7841 + * Module Name:
7842 + *   Aifstruc.h
7843 + *
7844 + * Abstract:
7845 + *   Define all shared data types relating to
7846 + *   the set of features utilizing Adapter
7847 + *   Initiated Fibs.
7848 + *
7849 + *
7850 + *
7851 + --*/
7852 +#ifndef _AIFSTRUC_H
7853 +#define _AIFSTRUC_H
7854 +
7855 +static char *ident_aifstruc = "aacraid_ident aifstruc.h 1.0.6 2000/10/09 Adaptec, Inc.";
7856 +
7857 +#include <protocol.h>
7858 +
7859 +//
7860 +//     Progress report structure definitions
7861 +//
7862 +typedef enum {
7863 +       AifJobStsSuccess = 1,
7864 +       AifJobStsFinished,
7865 +       AifJobStsAborted,
7866 +       AifJobStsFailed,
7867 +       AifJobStsLastReportMarker = 100, // All before mean last report
7868 +       AifJobStsSuspended,
7869 +       AifJobStsRunning
7870 +} _E_AifJobStatus;
7871 +
7872 +#ifdef AAC_32BIT_ENUMS
7873 +typedef        _E_AifJobStatus AifJobStatus;
7874 +#else
7875 +typedef        AAC_UINT32              AifJobStatus;
7876 +#endif
7877 +
7878 +
7879 +typedef enum {
7880 +       AifJobScsiMin = 1,              // Minimum value for Scsi operation
7881 +       AifJobScsiZero,                 // SCSI device clear operation
7882 +       AifJobScsiVerify,               // SCSI device Verify operation NO REPAIR
7883 +       AifJobScsiExercise,             // SCSI device Exercise operation
7884 +       AifJobScsiVerifyRepair, // SCSI device Verify operation WITH repair
7885 +       // Add new SCSI task types above this line
7886 +       AifJobScsiMax = 99,             // Max Scsi value
7887 +       AifJobCtrMin,                   // Min Ctr op value
7888 +       AifJobCtrZero,                  // Container clear operation
7889 +       AifJobCtrCopy,                  // Container copy operation
7890 +       AifJobCtrCreateMirror,  // Container Create Mirror operation
7891 +       AifJobCtrMergeMirror,   // Container Merge Mirror operation
7892 +       AifJobCtrScrubMirror,   // Container Scrub Mirror operation
7893 +       AifJobCtrRebuildRaid5,  // Container Rebuild Raid5 operation
7894 +       AifJobCtrScrubRaid5,    // Container Scrub Raid5 operation
7895 +       AifJobCtrMorph,                 // Container morph operation
7896 +       AifJobCtrPartCopy,              // Container Partition copy operation
7897 +       AifJobCtrRebuildMirror, // Container Rebuild Mirror operation
7898 +       AifJobCtrCrazyCache,            // crazy cache
7899 +       // Add new container task types above this line
7900 +       AifJobCtrMax = 199,             // Max Ctr type operation
7901 +       AifJobFsMin,                    // Min Fs type operation
7902 +       AifJobFsCreate,                 // File System Create operation
7903 +       AifJobFsVerify,                 // File System Verify operation
7904 +       AifJobFsExtend,                 // File System Extend operation
7905 +       // Add new file system task types above this line
7906 +       AifJobFsMax = 299,              // Max Fs type operation
7907 +       // Add new API task types here
7908 +       AifJobApiFormatNTFS,    // Format a drive to NTFS
7909 +       AifJobApiFormatFAT,             // Format a drive to FAT
7910 +       AifJobApiUpdateSnapshot, // update the read/write half of a snapshot
7911 +       AifJobApiFormatFAT32,   // Format a drive to FAT32
7912 +       AifJobApiMax = 399,             // Max API type operation
7913 +       AifJobCtlContinuousCtrVerify,   // Controller operation
7914 +       AifJobCtlMax = 499              // Max Controller type operation
7915 +
7916 +} _E_AifJobType;
7917 +
7918 +#ifdef AAC_32BIT_ENUMS
7919 +typedef        _E_AifJobType   AifJobType;
7920 +#else
7921 +typedef        AAC_UINT32              AifJobType;
7922 +#endif
7923 +
7924 +union SrcContainer {
7925 +       AAC_UINT32 from;
7926 +       AAC_UINT32 master;
7927 +       AAC_UINT32 container;
7928 +};
7929 +
7930 +union DstContainer {
7931 +       AAC_UINT32 to;
7932 +       AAC_UINT32 slave;
7933 +       AAC_UINT32 container;
7934 +};
7935 +
7936 +
7937 +struct AifContainers {
7938 +       union SrcContainer src;
7939 +       union DstContainer dst;
7940 +};
7941 +
7942 +union AifJobClient {
7943 +       
7944 +       struct AifContainers container; // For Container nd file system progress ops;
7945 +       AAC_INT32 scsi_dh;                      // For SCSI progress ops
7946 +};
7947 +
7948 +struct AifJobDesc {
7949 +       AAC_UINT32 jobID;                       // DO NOT FILL IN! Will be filled in by AIF
7950 +       AifJobType type;                // Operation that is being performed
7951 +       union AifJobClient client; // Details
7952 +};
7953 +
7954 +struct AifJobProgressReport {
7955 +       struct AifJobDesc jd;
7956 +       AifJobStatus status;
7957 +       AAC_UINT32 finalTick;
7958 +       AAC_UINT32 currentTick;
7959 +       AAC_UINT32 jobSpecificData1;
7960 +       AAC_UINT32 jobSpecificData2;
7961 +};
7962 +
7963 +//
7964 +//     Notification of events structure definition starts here
7965 +//
7966 +typedef enum {
7967 +       // General application notifies start here
7968 +       AifEnGeneric = 1,                       // Generic notification
7969 +       AifEnTaskComplete,                      // Task has completed
7970 +       AifEnConfigChange,                      // Adapter configuration change occurred
7971 +       AifEnContainerChange,           // Adapter specific container configuration change
7972 +       AifEnDeviceFailure,                     // SCSI device failed
7973 +       AifEnMirrorFailover,            // Mirror failover started
7974 +       AifEnContainerEvent,            // Significant container event
7975 +       AifEnFileSystemChange,          // File system changed
7976 +       AifEnConfigPause,                       // Container pause event
7977 +       AifEnConfigResume,                      // Container resume event
7978 +       AifEnFailoverChange,            // Failover space assignment changed
7979 +       AifEnRAID5RebuildDone,          // RAID5 rebuild finished
7980 +       AifEnEnclosureManagement,       // Enclosure management event
7981 +       AifEnBatteryEvent,                      // Significant NV battery event
7982 +       AifEnAddContainer,                      // A new container was created.
7983 +       AifEnDeleteContainer,           // A container was deleted.
7984 +       AifEnSMARTEvent,            // SMART Event
7985 +       AifEnBatteryNeedsRecond,        // The battery needs reconditioning
7986 +       AifEnClusterEvent,                      // Some cluster event
7987 +       AifEnDiskSetEvent,                      // A disk set event occured.
7988 +       // Add general application notifies above this comment
7989 +       AifDriverNotifyStart=199,       // Notifies for host driver go here
7990 +       // Host driver notifications start here
7991 +       AifDenMorphComplete,            // A morph operation completed
7992 +       AifDenVolumeExtendComplete      // A volume expand operation completed
7993 +       // Add host driver notifications above this comment
7994 +} _E_AifEventNotifyType;
7995 +
7996 +#ifdef AAC_32BIT_ENUMS
7997 +typedef _E_AifEventNotifyType  AifEventNotifyType;
7998 +#else
7999 +typedef        AAC_UINT32                              AifEventNotifyType;
8000 +#endif
8001 +
8002 +struct AifEnsGeneric {
8003 +       AAC_INT8 text[132];                             // Generic text
8004 +};
8005 +
8006 +struct AifEnsDeviceFailure {
8007 +       AAC_INT32 deviceHandle; // SCSI device handle
8008 +};
8009 +
8010 +struct AifEnsMirrorFailover {
8011 +       AAC_UINT32 container;           // Container with failed element
8012 +       AAC_UINT32 failedSlice;         // Old slice which failed
8013 +       AAC_UINT32 creatingSlice;       // New slice used for auto-create
8014 +};
8015 +
8016 +struct AifEnsContainerChange {
8017 +       AAC_UINT32 container[2];                // container that changed, -1 if no container
8018 +};
8019 +
8020 +struct AifEnsContainerEvent {
8021 +       AAC_UINT32 container;           // container number 
8022 +       AAC_UINT32 eventType;           // event type
8023 +};
8024 +
8025 +struct AifEnsEnclosureEvent {
8026 +       AAC_UINT32 empID;                               // enclosure management processor number 
8027 +       AAC_UINT32 unitID;                      // unitId, fan id, power supply id, slot id, tempsensor id. 
8028 +       AAC_UINT32 eventType;           // event type
8029 +};
8030 +
8031 +
8032 +struct AifEnsBatteryEvent {
8033 +       NVBATT_TRANSITION transition_type;      // e.g. from low to ok
8034 +       NVBATTSTATUS current_state;                     // current battery state
8035 +       NVBATTSTATUS prior_state;                       // previous battery state
8036 +};
8037 +
8038 +struct AifEnsDiskSetEvent {
8039 +       AAC_UINT32      eventType;
8040 +       AAC_UINT32      DsNum[2];
8041 +       AAC_UINT32      CreatorId[2];
8042 +};
8043 +
8044 +
8045 +
8046 +typedef enum _CLUSTER_AIF_EVENT {
8047 +       CLUSTER_NULL_EVENT = 0,
8048 +       CLUSTER_PARTNER_NAME_EVENT,             // change in partner hostname or adaptername from NULL to non-NULL
8049 +                                                                       // (partner's agent may be up)
8050 +       CLUSTER_PARTNER_NULL_NAME_EVENT // change in partner hostname or adaptername from non-null to NULL
8051 +                                                                       // (partner has rebooted)
8052 +} _E_CLUSTER_AIF_EVENT;
8053 +
8054 +#ifdef AAC_32BIT_ENUMS
8055 +typedef        _E_CLUSTER_AIF_EVENT    CLUSTER_AIF_EVENT;
8056 +#else
8057 +typedef        AAC_UINT32                              CLUSTER_AIF_EVENT;
8058 +#endif
8059 +
8060 +struct AifEnsClusterEvent {
8061 +       CLUSTER_AIF_EVENT   eventType;
8062 +};
8063 +
8064 +struct AifEventNotify {
8065 +       AifEventNotifyType      type;
8066 +       union {
8067 +               struct AifEnsGeneric            EG;
8068 +               struct AifEnsDeviceFailure      EDF;
8069 +               struct AifEnsMirrorFailover EMF;
8070 +               struct AifEnsContainerChange ECC;
8071 +               struct AifEnsContainerEvent ECE;
8072 +               struct AifEnsEnclosureEvent EEE;
8073 +               struct AifEnsBatteryEvent       EBE;
8074 +               struct AifEnsDiskSetEvent       EDS;
8075 +#ifdef BRIDGE
8076 +               struct AifEnsSMARTEvent ES;
8077 +#endif
8078 +               struct AifEnsClusterEvent ECLE;
8079 +       } data;
8080 +};
8081 +
8082 +//
8083 +//     Generic API structure
8084 +//
8085 +#define AIF_API_REPORT_MAX_SIZE 64
8086 +typedef AAC_INT8 AifApiReport[AIF_API_REPORT_MAX_SIZE];
8087 +
8088 +
8089 +
8090 +//
8091 +//     For FIB communication, we need all of the following things
8092 +//     to send back to the user.
8093 +//
8094 +typedef enum {
8095 +       AifCmdEventNotify = 1,  // Notify of event
8096 +       AifCmdJobProgress,              // Progress report
8097 +       AifCmdAPIReport,                // Report from other user of API
8098 +       AifCmdDriverNotify,             // Notify host driver of event
8099 +       AifReqJobList = 100,    // Gets back complete job list
8100 +       AifReqJobsForCtr,               // Gets back jobs for specific container
8101 +       AifReqJobsForScsi,              // Gets back jobs for specific SCSI device
8102 +       AifReqJobReport,                // Gets back a specific job report or list of them
8103 +       AifReqTerminateJob,             // Terminates job
8104 +       AifReqSuspendJob,               // Suspends a job
8105 +       AifReqResumeJob,                // Resumes a job
8106 +       AifReqSendAPIReport,    // API generic report requests
8107 +       AifReqAPIJobStart,              // Start a job from the API
8108 +       AifReqAPIJobUpdate,             // Update a job report from the API
8109 +       AifReqAPIJobFinish              // Finish a job from the API
8110 +} _E_AIFCOMMAND;
8111 +
8112 +#ifdef AAC_32BIT_ENUMS
8113 +typedef _E_AIFCOMMAND  AIFCOMMAND;
8114 +#else
8115 +typedef        AAC_UINT32              AIFCOMMAND;
8116 +#endif
8117 +
8118 +
8119 +
8120 +//
8121 +//     Adapter Initiated FIB command structures. Start with the adapter
8122 +//     initiated FIBs that really come from the adapter, and get responded
8123 +//     to by the host.
8124 +//
8125 +typedef struct _AIFCOMMANDTOHOST {
8126 +       AIFCOMMAND command;                     // Tell host what type of notify this is
8127 +       AAC_UINT32 seqNumber;   // To allow ordering of reports (if necessary)
8128 +       union {
8129 +               // First define data going to the adapter
8130 +               struct AifEventNotify EN;       // Event notify structure
8131 +               struct AifJobProgressReport PR[1]; // Progress report
8132 +               AifApiReport AR;
8133 +       } data;
8134 +} AIFCOMMANDTOHOST, *PAIFCOMMANDTOHOST;
8135 +
8136 +
8137 +#endif // _AIFSTRUC_H
8138 +
8139 +
8140 +
8141 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/build_number.h linux/drivers/scsi/aacraid/include/build_number.h
8142 --- linux-2.4.7/drivers/scsi/aacraid/include/build_number.h     Wed Dec 31 18:00:00 1969
8143 +++ linux/drivers/scsi/aacraid/include/build_number.h   Sat Jul 21 17:55:13 2001
8144 @@ -0,0 +1,39 @@
8145 +/*++
8146 + * Adaptec aacraid device driver for Linux.
8147 + *
8148 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8149 + *
8150 + * This program is free software; you can redistribute it and/or modify
8151 + * it under the terms of the GNU General Public License as published by
8152 + * the Free Software Foundation; either version 2, or (at your option)
8153 + * any later version.
8154 + *
8155 + * This program is distributed in the hope that it will be useful,
8156 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8157 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
8158 + * GNU General Public License for more details.
8159 + *
8160 + * You should have received a copy of the GNU General Public License
8161 + * along with this program; see the file COPYING.  If not, write to
8162 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8163 + *
8164 + * Module Name:
8165 + *   build_number.h
8166 + *
8167 + * Abstract:
8168 + *   DThis module contains the single location where the build number
8169 + *   is kept.
8170 + *
8171 + *
8172 + *
8173 + --*/
8174 +#ifndef _BUILD_NUMBER_H 
8175 +#define _BUILD_NUMBER_H 
8176 +
8177 +static char *ident_build_num = "aacraid_ident build_number.h 1.0.6 2000/10/09 Adaptec, Inc.";
8178 +
8179 +#define REV_BUILD_NUMBER 3911 
8180 +
8181 +
8182 +#endif  // _BUILD_NUMBER_H 
8183 +
8184 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/commdata.h linux/drivers/scsi/aacraid/include/commdata.h
8185 --- linux-2.4.7/drivers/scsi/aacraid/include/commdata.h Wed Dec 31 18:00:00 1969
8186 +++ linux/drivers/scsi/aacraid/include/commdata.h       Sat Jul 21 17:55:13 2001
8187 @@ -0,0 +1,112 @@
8188 +/*++
8189 + * Adaptec aacraid device driver for Linux.
8190 + *
8191 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8192 + *
8193 + * This program is free software; you can redistribute it and/or modify
8194 + * it under the terms of the GNU General Public License as published by
8195 + * the Free Software Foundation; either version 2, or (at your option)
8196 + * any later version.
8197 + *
8198 + * This program is distributed in the hope that it will be useful,
8199 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8200 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
8201 + * GNU General Public License for more details.
8202 + *
8203 + * You should have received a copy of the GNU General Public License
8204 + * along with this program; see the file COPYING.  If not, write to
8205 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8206 + *
8207 + * Module Name:
8208 + *   commdata.h
8209 + *
8210 + * Abstract: Define the communication layer of the adapter
8211 + *
8212 + *
8213 + *
8214 + --*/
8215 +#ifndef _COMMDATA_
8216 +#define _COMMDATA_
8217 +
8218 +static char *ident_commdata = "aacraid_ident commdata.h 1.0.6 2000/10/09 Adaptec, Inc.";
8219 +
8220 +typedef struct _FSA_COMM_DATA {
8221 +  
8222 +  //
8223 +  //  A pointer to the Driver and Device object we were initialized with
8224 +  //
8225 +  
8226 +  PDRIVER_OBJECT DriverObject;
8227 +  PDEVICE_OBJECT DeviceObject;
8228 +  
8229 +  //
8230 +  // A list of all adapters we have configured.
8231 +  // 
8232 +  
8233 +  PAFA_COMM_ADAPTER AdapterList;
8234 +  ULONG                  TotalAdapters;
8235 +  
8236 +  //
8237 +  // Adapter timeout support. This is the default timeout to wait for the
8238 +  // adapter to respond(setup in initfs.c), and a boolean to indicate if
8239 +  // we should timeout requests to the adapter or not.
8240 +  //
8241 +
8242 +  LARGE_INTEGER QueueFreeTimeout;
8243 +  LARGE_INTEGER AdapterTimeout;
8244 +  BOOLEAN EnableAdapterTimeouts;
8245 +
8246 +  ULONG        FibTimeoutIncrement;
8247 +  
8248 +  ULONG FibsSent;
8249 +  ULONG FibRecved;
8250 +  ULONG NoResponseSent;
8251 +  ULONG NoResponseRecved;
8252 +  ULONG AsyncSent;
8253 +  ULONG AsyncRecved;
8254 +  ULONG NormalSent;
8255 +  ULONG NormalRecved;
8256 +  
8257 +  ULONG TimedOutFibs;
8258 +  
8259 +  KDPC         TimeoutDPC;
8260 +  KTIMER       TimeoutTimer;
8261 +  
8262 +  // 
8263 +  // If this value is set to 1 then interrupt moderation will occur 
8264 +  // in the base commuication support.
8265 +  //
8266 +
8267 +  ULONG EnableInterruptModeration;
8268 +
8269 +  int HardInterruptModeration;
8270 +  int HardInterruptModeration1;
8271 +  int PeakFibsConsumed;
8272 +  int ZeroFibsConsumed;
8273 +  int EnableFibTimeoutBreak;
8274 +  ULONG FibTimeoutSeconds;
8275 +  
8276 +  //
8277 +  // The following holds all of the available user settable variables.
8278 +  // This includes all for the comm layer as well as any from the class
8279 +  // drivers as well.
8280 +  //
8281 +  
8282 +  FSA_USER_VAR *UserVars;
8283 +  ULONG                        NumUserVars;
8284 +  
8285 +  
8286 +  ULONG           MeterFlag;
8287 +  
8288 +#ifdef FIB_CHECKSUMS
8289 +  int do_fib_checksums;
8290 +#endif
8291 +  
8292 +} FSA_COMM_DATA;
8293 +typedef FSA_COMM_DATA *PFSA_COMM_DATA;
8294 +
8295 +extern FSA_COMM_DATA FsaCommData;
8296 +
8297 +
8298 +#endif // _COMMDATA_
8299 +
8300 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/commerr.h linux/drivers/scsi/aacraid/include/commerr.h
8301 --- linux-2.4.7/drivers/scsi/aacraid/include/commerr.h  Wed Dec 31 18:00:00 1969
8302 +++ linux/drivers/scsi/aacraid/include/commerr.h        Sat Jul 21 17:55:13 2001
8303 @@ -0,0 +1,125 @@
8304 +/*++
8305 + * Adaptec aacraid device driver for Linux.
8306 + *
8307 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8308 + *
8309 + * This program is free software; you can redistribute it and/or modify
8310 + * it under the terms of the GNU General Public License as published by
8311 + * the Free Software Foundation; either version 2, or (at your option)
8312 + * any later version.
8313 + *
8314 + * This program is distributed in the hope that it will be useful,
8315 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8316 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
8317 + * GNU General Public License for more details.
8318 + *
8319 + * You should have received a copy of the GNU General Public License
8320 + * along with this program; see the file COPYING.  If not, write to
8321 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8322 + *
8323 + * Module Name:
8324 + *   commerr.h
8325 + *
8326 + * Abstract: This file defines all errors that are unique to the Adaptec Fsa Filesystem
8327 + *
8328 + *
8329 + *
8330 + --*/
8331 +
8332 +#ifndef _FSAERR_
8333 +#define _FSAERR_
8334 +
8335 +static char *ident_commerr = "aacraid_ident commerr.h 1.0.6 2000/10/09 Adaptec, Inc.";
8336 +
8337 +//
8338 +//  Note: comments in the .mc file must use both ";" and "//".
8339 +//
8340 +//  Status values are 32 bit values layed out as follows:
8341 +//
8342 +//   3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
8343 +//   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
8344 +//  +---+-+-------------------------+-------------------------------+
8345 +//  |Sev|C|       Facility          |               Code            |
8346 +//  +---+-+-------------------------+-------------------------------+
8347 +//
8348 +//  where
8349 +//
8350 +//      Sev - is the severity code
8351 +//
8352 +//          00 - Success
8353 +//          01 - Informational
8354 +//          10 - Warning
8355 +//          11 - Error
8356 +//
8357 +//      C - is the Customer code flag
8358 +//
8359 +//      Facility - is the facility code
8360 +//
8361 +//      Code - is the facility's status code
8362 +//
8363 +
8364 +
8365 +//
8366 +// %1 is reserved by the IO Manager. If IoAllocateErrorLogEntry is
8367 +// called with a device, the name of the device will be inserted into
8368 +// the message at %1. Otherwise, the place of %1 will be left empty.
8369 +// In either case, the insertion strings from the driver's error log
8370 +// entry starts at %2. In other words, the first insertion string goes
8371 +// to %2, the second to %3 and so on.
8372 +//
8373 +
8374 +//
8375 +//  Values are 32 bit values layed out as follows:
8376 +//
8377 +//   3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
8378 +//   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
8379 +//  +---+-+-+-----------------------+-------------------------------+
8380 +//  |Sev|C|R|     Facility          |               Code            |
8381 +//  +---+-+-+-----------------------+-------------------------------+
8382 +//
8383 +//  where
8384 +//
8385 +//      Sev - is the severity code
8386 +//
8387 +//          00 - Success
8388 +//          01 - Informational
8389 +//          10 - Warning
8390 +//          11 - Error
8391 +//
8392 +//      C - is the Customer code flag
8393 +//
8394 +//      R - is a reserved bit
8395 +//
8396 +//      Facility - is the facility code
8397 +//
8398 +//      Code - is the facility's status code
8399 +//
8400 +//
8401 +// Define the facility codes
8402 +//
8403 +
8404 +
8405 +#define FACILITY_FSAFS_ERROR_CODE        0x7
8406 +
8407 +
8408 +
8409 +//
8410 +// MessageId: FSAFS_FIB_INVALID
8411 +//
8412 +// MessageText:
8413 +//
8414 +//  A communication packet was detected to be formatted poorly. Please Contact Adaptec support.
8415 +//
8416 +#define FSAFS_FIB_INVALID                ((AAC_STATUS)0xE0070009L)
8417 +
8418 +
8419 +//
8420 +// MessageId: FSAFS_TIMED_OUT_FIB_COMPLETED
8421 +//
8422 +// MessageText:
8423 +//
8424 +//  A Fib previously timed out by host has been completed by the adapter. (\\.\Afa%2)
8425 +//
8426 +#define FSAFS_TIMED_OUT_FIB_COMPLETED    ((AAC_STATUS)0xA007000EL)
8427 +
8428 +#endif _FSAERR_
8429 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/commfibcontext.h linux/drivers/scsi/aacraid/include/commfibcontext.h
8430 --- linux-2.4.7/drivers/scsi/aacraid/include/commfibcontext.h   Wed Dec 31 18:00:00 1969
8431 +++ linux/drivers/scsi/aacraid/include/commfibcontext.h Sat Jul 21 17:55:13 2001
8432 @@ -0,0 +1,98 @@
8433 +/*++
8434 + * Adaptec aacraid device driver for Linux.
8435 + *
8436 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8437 + *
8438 + * This program is free software; you can redistribute it and/or modify
8439 + * it under the terms of the GNU General Public License as published by
8440 + * the Free Software Foundation; either version 2, or (at your option)
8441 + * any later version.
8442 + *
8443 + * This program is distributed in the hope that it will be useful,
8444 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8445 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
8446 + * GNU General Public License for more details.
8447 + *
8448 + * You should have received a copy of the GNU General Public License
8449 + * along with this program; see the file COPYING.  If not, write to
8450 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8451 + *
8452 + * Module Name:
8453 + *   commfibcontext.h
8454 + *
8455 + * Abstract: defines the _COMM_FIB_CONTEXT strcuture
8456 + *
8457 + *
8458 + *
8459 + --*/
8460 +#ifndef _COMM_FIB_CONTEXT_
8461 +#define _COMM_FIB_CONTEXT_
8462 +
8463 +static char *ident_commfib = "aacraid_ident commfibcontext.h 1.0.6 2000/10/09 Adaptec, Inc.";
8464 +
8465 +typedef struct _COMM_FIB_CONTEXT {
8466 +
8467 +       PVOID           Next;   // this is used by the zone allocation
8468 +
8469 +    //
8470 +    //  Type and size of this record (must be FSA_NTC_FIB_CONTEXT)
8471 +    //
8472 +    //  NOTE:  THIS STRUCTURE MUST REMAIN 64-bit ALIGNED IN SIZE, SINCE
8473 +    //         IT IS ZONE ALLOCATED, AND REPINNED_BCBS_ARRAY_SIZE AFFECTS
8474 +    //         ITS SIZE.
8475 +    //
8476 +
8477 +    NODE_TYPE_CODE NodeTypeCode;
8478 +    NODE_BYTE_SIZE NodeByteSize;
8479 +
8480 +       //
8481 +       //      The Adapter that this I/O is destined for.
8482 +       //
8483 +
8484 +       PAFA_COMM_ADAPTER Adapter;
8485 +
8486 +    PHYSICAL_ADDRESS LogicalFibAddress;
8487 +
8488 +    //
8489 +    // This is the event the sendfib routine will wait on if the
8490 +    // caller did not pass one and this is synch io.
8491 +    //
8492 +
8493 +  OS_CV_T      FsaEvent;
8494 +       OS_CVLOCK       *FsaEventMutex;
8495 +
8496 +       ULONG   FibComplete;    // gets set to 1 when fib is complete
8497 +    
8498 +       PFIB_CALLBACK FibCallback;
8499 +       PVOID FibCallbackContext;
8500 +
8501 +       ULONG   Flags;
8502 +
8503 +
8504 +#ifdef GATHER_FIB_TIMES
8505 +       LARGE_INTEGER   FibTimeStamp;
8506 +       PFIB_TIMES              FibTimesPtr;
8507 +#endif
8508 +
8509 +       //
8510 +       // The following is used to put this fib context onto the Outstanding I/O queue.
8511 +       //
8512 +               
8513 +       LIST_ENTRY      QueueEntry;     
8514 +
8515 +       //
8516 +       // The following is used to timeout a fib to the adapter.
8517 +       //
8518 +
8519 +       LARGE_INTEGER   TimeoutValue;
8520 +
8521 +       PVOID   FibData;
8522 +
8523 +    PFIB Fib;
8524 +
8525 +} COMM_FIB_CONTEXT;
8526 +typedef COMM_FIB_CONTEXT *PCOMM_FIB_CONTEXT;
8527 +
8528 +#define FIB_CONTEXT_FLAG_TIMED_OUT             (0x00000001)
8529 +
8530 +#endif /* _COMM_FIB_CONTEXT_ */
8531 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/comprocs.h linux/drivers/scsi/aacraid/include/comprocs.h
8532 --- linux-2.4.7/drivers/scsi/aacraid/include/comprocs.h Wed Dec 31 18:00:00 1969
8533 +++ linux/drivers/scsi/aacraid/include/comprocs.h       Sat Jul 21 17:55:13 2001
8534 @@ -0,0 +1,93 @@
8535 +/*++
8536 + * Adaptec aacraid device driver for Linux.
8537 + *
8538 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8539 + *
8540 + * This program is free software; you can redistribute it and/or modify
8541 + * it under the terms of the GNU General Public License as published by
8542 + * the Free Software Foundation; either version 2, or (at your option)
8543 + * any later version.
8544 + *
8545 + * This program is distributed in the hope that it will be useful,
8546 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8547 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
8548 + * GNU General Public License for more details.
8549 + *
8550 + * You should have received a copy of the GNU General Public License
8551 + * along with this program; see the file COPYING.  If not, write to
8552 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8553 + *
8554 + * Module Name:
8555 + *   comprocs.h
8556 + *
8557 + * Abstract: This module defines all of the globally used procedures in the Afa comm layer
8558 + *
8559 + *
8560 + *
8561 + --*/
8562 +#ifndef _COMPROCS_
8563 +#define _COMPROCS_
8564 +
8565 +static char *ident_comproc = "aacraid_ident comprocs.h 1.0.6 2000/10/09 Adaptec, Inc.";
8566 +
8567 +#include "osheaders.h"
8568 +
8569 +#include "AacGenericTypes.h"
8570 +
8571 +#include "aac_unix_defs.h"
8572 +
8573 +#include "nodetype.h"
8574 +
8575 +// #define GATHER_FIB_TIMES
8576 +
8577 +#include "fsatypes.h"
8578 +
8579 +#include "perfpack.h"
8580 +
8581 +#include "comstruc.h"
8582 +
8583 +//#include "unix_protocol.h"
8584 +
8585 +#include "fsact.h"
8586 +
8587 +#include "protocol.h"
8588 +
8589 +#include "fsaioctl.h"
8590 +
8591 +#undef GATHER_FIB_TIMES
8592 +
8593 +#include "aifstruc.h"
8594 +
8595 +#include "fsaport.h"
8596 +#include "comsup.h"
8597 +#include "afacomm.h"
8598 +#include "adapter.h"
8599 +
8600 +#include "commfibcontext.h"
8601 +#include "comproto.h"
8602 +#include "commdata.h"
8603 +#include "commerr.h"
8604 +
8605 +
8606 +
8607 +
8608 +//
8609 +// The following macro is used when sending and receiving FIBs.  It is only used for
8610 +// debugging.
8611 +
8612 +#if DBG
8613 +#define        FIB_COUNTER_INCREMENT(Counter)          InterlockedIncrement(&(Counter))
8614 +#else
8615 +#define        FIB_COUNTER_INCREMENT(Counter)          
8616 +#endif
8617 +
8618 +
8619 +
8620 +int
8621 +AfaCommAdapterDeviceControl (
8622 +       IN PVOID AdapterArg,
8623 +       IN PAFA_IOCTL_CMD       IoctlCmdPtr
8624 +       );
8625 +
8626 +
8627 +#endif // _COMPROCS_
8628 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/comproto.h linux/drivers/scsi/aacraid/include/comproto.h
8629 --- linux-2.4.7/drivers/scsi/aacraid/include/comproto.h Wed Dec 31 18:00:00 1969
8630 +++ linux/drivers/scsi/aacraid/include/comproto.h       Sat Jul 21 17:55:13 2001
8631 @@ -0,0 +1,170 @@
8632 +/*++
8633 + * Adaptec aacraid device driver for Linux.
8634 + *
8635 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8636 + *
8637 + * This program is free software; you can redistribute it and/or modify
8638 + * it under the terms of the GNU General Public License as published by
8639 + * the Free Software Foundation; either version 2, or (at your option)
8640 + * any later version.
8641 + *
8642 + * This program is distributed in the hope that it will be useful,
8643 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8644 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
8645 + * GNU General Public License for more details.
8646 + *
8647 + * You should have received a copy of the GNU General Public License
8648 + * along with this program; see the file COPYING.  If not, write to
8649 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8650 + *
8651 + * Module Name:
8652 + *   comproto.h
8653 + *
8654 + * Abstract: Global routines for the commuication interface that are device
8655 + *           independant.
8656 + *
8657 + *
8658 + *
8659 + --*/
8660 +#ifndef _COMM_PROTO
8661 +#define _COMM_PROTO
8662 +
8663 +static char *ident_comproto = "aacraid_ident comproto.h 1.0.6 2000/10/09 Adaptec, Inc.";
8664 +
8665 +//
8666 +// define the routines we need so we can commuicate with the
8667 +// fsa adapter
8668 +//
8669 +
8670 +//
8671 +// The following 4 dpc routines will support commuication from the adapter to the
8672 +// host. There is one DPC routine to deal with each type of queue that supports
8673 +// commuication from the adapter. (adapter to host resposes, adapter to host commands)
8674 +// These routines will simply pull off the QE and set an event. In the case of a
8675 +// adapter to host command they will also put the FIB on a queue to be processed by
8676 +// a FS thread running at passive level.
8677 +//
8678 +
8679 +// Handle queue not full notification to the file system thread waiting for a queue entry
8680 +
8681 +u_int
8682 +CommonNotFullDpc(
8683 +       IN PCOMM_REGION CommRegion
8684 +    );
8685 +
8686 +// Adapter to host normal priority responses
8687 +
8688 +u_int
8689 +HostResponseNormalDpc(
8690 +    IN PCOMM_QUE OurQueue
8691 +    );
8692 +
8693 +// Adapter to host high priority responses
8694 +u_int
8695 +HostResponseHighDpc(
8696 +    IN PCOMM_QUE OurQueue
8697 +    );
8698 +
8699 +// Adapter to host high priority commands
8700 +u_int
8701 +HostCommandHighDpc(
8702 +    IN PCOMM_QUE OurQueue
8703 +    );
8704 +    
8705 +
8706 +// Adapter to host normal priority commands
8707 +u_int
8708 +HostCommandNormDpc(
8709 +    IN PCOMM_QUE OurQueue
8710 +    );
8711 +
8712 +
8713 +
8714 +BOOLEAN
8715 +SendSynchFib(
8716 +       PVOID                   Arg,
8717 +       FIB_COMMAND     Command,
8718 +       PVOID                   Data,
8719 +       USHORT                  Size,
8720 +       PVOID                   Response,
8721 +       USHORT                  *ResponseSize
8722 +       );
8723 +
8724 +PFIB_CONTEXT
8725 +AllocateFib (
8726 +       IN PVOID Adapter
8727 +    );
8728 +
8729 +VOID
8730 +FreeFib (
8731 +    IN PFIB_CONTEXT FibContext
8732 +    );
8733 +
8734 +VOID
8735 +FreeFibFromDpc(
8736 +    IN PFIB_CONTEXT FibContext
8737 +    );
8738 +
8739 +AAC_STATUS
8740 +DeallocateFib(
8741 +    IN PFIB_CONTEXT FibContext
8742 +    );
8743 +
8744 +
8745 +
8746 +AAC_STATUS
8747 +SendFib(
8748 +    IN FIB_COMMAND Command, 
8749 +       IN PFIB_CONTEXT FibContext,
8750 +    IN ULONG Size,
8751 +    IN COMM_PRIORITIES Priority,
8752 +    IN BOOLEAN Wait,
8753 +    IN PVOID WaitOn,
8754 +    IN BOOLEAN ResponseExpected,
8755 +       IN PFIB_CALLBACK FibCallback,
8756 +       IN PVOID FibCallbackContext
8757 +    );
8758 +
8759 +AAC_STATUS
8760 +CompleteFib(
8761 +       IN PFIB_CONTEXT FibContext
8762 +    );
8763 +
8764 +AAC_STATUS
8765 +CompleteAdapterFib(
8766 +       IN PFIB_CONTEXT FibContext,
8767 +    IN USHORT Size
8768 +    );
8769 +
8770 +AAC_STATUS
8771 +InitializeFib(
8772 +       IN PFIB_CONTEXT FibContext
8773 +    );
8774 +
8775 +
8776 +PVOID
8777 +FsaGetFibData(
8778 +       IN PFIB_CONTEXT FibContext
8779 +       );
8780 +
8781 +
8782 +
8783 +AAC_STATUS
8784 +AfaCommOpenAdapter (
8785 +       IN PVOID AdapterArg
8786 +       );
8787 +
8788 +AAC_STATUS
8789 +AfaCommCloseAdapter (
8790 +       IN PVOID AdapterArg
8791 +       );
8792 +
8793 +
8794 +VOID
8795 +AfaCommInterruptHost(
8796 +       PVOID   Adapter,
8797 +       ADAPTER_EVENT   AdapterEvent
8798 +       );
8799 +
8800 +
8801 +#endif // _COMM_PROTO
8802 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/comstruc.h linux/drivers/scsi/aacraid/include/comstruc.h
8803 --- linux-2.4.7/drivers/scsi/aacraid/include/comstruc.h Wed Dec 31 18:00:00 1969
8804 +++ linux/drivers/scsi/aacraid/include/comstruc.h       Sat Jul 21 17:55:13 2001
8805 @@ -0,0 +1,435 @@
8806 +/*++
8807 + * Adaptec aacraid device driver for Linux.
8808 + *
8809 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8810 + *
8811 + * This program is free software; you can redistribute it and/or modify
8812 + * it under the terms of the GNU General Public License as published by
8813 + * the Free Software Foundation; either version 2, or (at your option)
8814 + * any later version.
8815 + *
8816 + * This program is distributed in the hope that it will be useful,
8817 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8818 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
8819 + * GNU General Public License for more details.
8820 + *
8821 + * You should have received a copy of the GNU General Public License
8822 + * along with this program; see the file COPYING.  If not, write to
8823 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8824 + *
8825 + * Module Name:
8826 + *   comstruc.h
8827 + *
8828 + * Abstract: This module defines the data structures that make up the communication
8829 + *           region for the FSA filesystem. This region is how the host based code
8830 + *           communicates both control and data to the adapter based code.
8831 + *
8832 + *
8833 + *
8834 + --*/
8835 +#ifndef _COMM_STRUCT
8836 +#define _COMM_STRUCT
8837 +
8838 +static char *ident_comstruc = "aacraid_ident comstruc.h 1.0.7 2000/10/11 Adaptec, Inc.";
8839 +
8840 +//
8841 +// Define all the constants needed for the communication interface
8842 +//
8843 +
8844 +// Define how many queue entries each queue will have and the total number of
8845 +// entries for the entire communication interface. Also define how many queues
8846 +// we support.
8847 +
8848 +#define NUMBER_OF_COMM_QUEUES  8   // 4 command; 4 response
8849 +#define HOST_HIGH_CMD_ENTRIES  4
8850 +#define HOST_NORM_CMD_ENTRIES  8
8851 +#define ADAP_HIGH_CMD_ENTRIES  4
8852 +#define ADAP_NORM_CMD_ENTRIES  512
8853 +#define HOST_HIGH_RESP_ENTRIES 4
8854 +#define HOST_NORM_RESP_ENTRIES 512
8855 +#define ADAP_HIGH_RESP_ENTRIES 4
8856 +#define ADAP_NORM_RESP_ENTRIES 8
8857 +
8858 +#define TOTAL_QUEUE_ENTRIES  \
8859 +    (HOST_NORM_CMD_ENTRIES + HOST_HIGH_CMD_ENTRIES + ADAP_NORM_CMD_ENTRIES + ADAP_HIGH_CMD_ENTRIES + \
8860 +           HOST_NORM_RESP_ENTRIES + HOST_HIGH_RESP_ENTRIES + ADAP_NORM_RESP_ENTRIES + ADAP_HIGH_RESP_ENTRIES)
8861 +
8862 +
8863 +
8864 +
8865 +// Set the queues on a 16 byte alignment
8866 +#define QUEUE_ALIGNMENT                16
8867 +
8868 +
8869 +//
8870 +// The queue headers define the Communication Region queues. These
8871 +// are physically contiguous and accessible by both the adapter and the
8872 +// host. Even though all queue headers are in the same contiguous block they will be
8873 +// represented as individual units in the data structures.
8874 +//
8875 +
8876 +typedef AAC_UINT32 QUEUE_INDEX;
8877 +
8878 +typedef QUEUE_INDEX *PQUEUE_INDEX;
8879 +
8880 +typedef struct _QUEUE_ENTRY {
8881 +
8882 +    AAC_UINT32 Size;                     // Size in bytes of the Fib which this QE points to
8883 +    AAC_UINT32 FibAddress;             // Receiver addressable address of the FIB (low 32 address bits)
8884 +
8885 +} QUEUE_ENTRY;
8886 +
8887 +typedef QUEUE_ENTRY *PQUEUE_ENTRY;
8888 +
8889 +
8890 +
8891 +// The adapter assumes the ProducerIndex and ConsumerIndex are grouped
8892 +// adjacently and in that order.
8893 +//
8894 +typedef struct _QUEUE_HEADERS {
8895 +
8896 +    PHYSICAL_ADDRESS LogicalHeaderAddress;  // Address to hand the adapter to access to this queue head
8897 +    PQUEUE_INDEX ProducerIndex;              // The producer index for this queue (host address)
8898 +    PQUEUE_INDEX ConsumerIndex;              // The consumer index for this queue (host address)
8899 +
8900 +} QUEUE_HEADERS;
8901 +typedef QUEUE_HEADERS *PQUEUE_HEADERS;
8902 +
8903 +//
8904 +// Define all the events which the adapter would like to notify
8905 +// the host of.
8906 +//
8907 +typedef enum _ADAPTER_EVENT {
8908 +    HostNormCmdQue = 1,         // Change in host normal priority command queue
8909 +    HostHighCmdQue,             // Change in host high priority command queue
8910 +    HostNormRespQue,            // Change in host normal priority response queue
8911 +    HostHighRespQue,            // Change in host high priority response queue
8912 +    AdapNormRespNotFull,
8913 +    AdapHighRespNotFull,
8914 +    AdapNormCmdNotFull,
8915 +    AdapHighCmdNotFull,
8916 +       SynchCommandComplete,
8917 +    AdapInternalError = 0xfe    // The adapter detected an internal error shutting down
8918 +
8919 +} _E_ADAPTER_EVENT;
8920 +
8921 +#ifdef AAC_32BIT_ENUMS
8922 +typedef _E_ADAPTER_EVENT       ADAPTER_EVENT;
8923 +#else
8924 +typedef AAC_UINT32                     ADAPTER_EVENT;
8925 +#endif
8926 +
8927 +//
8928 +// Define all the events the host wishes to notify the
8929 +// adapter of.
8930 +//
8931 +typedef enum _HOST_2_ADAP_EVENT {
8932 +    AdapNormCmdQue = 1,
8933 +    AdapHighCmdQue,
8934 +    AdapNormRespQue,
8935 +    AdapHighRespQue,
8936 +    HostShutdown,
8937 +    HostPowerFail,
8938 +    FatalCommError,
8939 +    HostNormRespNotFull,
8940 +    HostHighRespNotFull,
8941 +    HostNormCmdNotFull,
8942 +    HostHighCmdNotFull,
8943 +       FastIo,
8944 +       AdapPrintfDone
8945 +} _E_HOST_2_ADAP_EVENT;
8946 +
8947 +#ifdef AAC_32BIT_ENUMS
8948 +typedef _E_HOST_2_ADAP_EVENT   HOST_2_ADAP_EVENT;
8949 +#else
8950 +typedef        AAC_UINT32                              HOST_2_ADAP_EVENT;
8951 +#endif
8952 +
8953 +//
8954 +// Define all the queues that the adapter and host use to communicate
8955 +//
8956 +
8957 +typedef enum _QUEUE_TYPES {
8958 +        HostNormCmdQueue = 1,       // Adapter to host normal priority command traffic
8959 +        HostHighCmdQueue,           // Adapter to host high priority command traffic
8960 +        AdapNormRespQueue,          // Host to adapter normal priority response traffic
8961 +        AdapHighRespQueue,          // Host to adapter high priority response traffic
8962 +        AdapNormCmdQueue,           // Host to adapter normal priority command traffic
8963 +        AdapHighCmdQueue,           // Host to adapter high priority command traffic
8964 +        HostNormRespQueue,          // Adapter to host normal priority response traffic
8965 +        HostHighRespQueue           // Adapter to host high priority response traffic
8966 +} _E_QUEUE_TYPES;
8967 +
8968 +#ifdef AAC_32BIT_ENUMS
8969 +typedef _E_QUEUE_TYPES         QUEUE_TYPES;
8970 +#else
8971 +typedef        AAC_UINT32                      QUEUE_TYPES;
8972 +#endif
8973 +
8974 +
8975 +//
8976 +// Assign type values to the FSA communication data structures
8977 +//
8978 +
8979 +typedef enum _STRUCT_TYPES {
8980 +    TFib = 1,
8981 +    TQe,
8982 +       TCtPerf
8983 +} _E_STRUCT_TYPES;
8984 +
8985 +#ifdef AAC_32BIT_ENUMS
8986 +typedef        _E_STRUCT_TYPES STRUCT_TYPES;
8987 +#else
8988 +typedef        AAC_UINT32              STRUCT_TYPES;
8989 +#endif
8990 +
8991 +//
8992 +// Define the priority levels the FSA communication routines support.
8993 +//
8994 +
8995 +typedef enum _COMM_PRIORITIES {
8996 +    FsaNormal = 1,
8997 +    FsaHigh
8998 +} _E_COMM_PRIORITIES;
8999 +
9000 +#ifdef AAC_32BIT_ENUMS
9001 +typedef _E_COMM_PRIORITIES     COMM_PRIORITIES;
9002 +#else
9003 +typedef        AAC_UINT32                      COMM_PRIORITIES;
9004 +#endif
9005 +
9006 +
9007 +
9008 +//
9009 +// Define the LIST_ENTRY structure.  This structure is used on the NT side to link
9010 +// the FIBs together in a linked list.  Since this structure gets compiled on the adapter
9011 +// as well, we need to define this structure for the adapter's use.  If '_NT_DEF_'
9012 +// is defined, then this header is being included from the NT side, and therefore LIST_ENTRY
9013 +// is already defined.
9014 +#if !defined(_NTDEF_) && !defined(_WINNT_)
9015 +typedef struct _LIST_ENTRY {
9016 +   struct _LIST_ENTRY *Flink;
9017 +   struct _LIST_ENTRY *Blink;
9018 +} LIST_ENTRY;
9019 +typedef LIST_ENTRY *PLIST_ENTRY;
9020 +#endif
9021 +
9022 +
9023 +//
9024 +// Define the FIB. The FIB is the where all the requested data and
9025 +// command information are put to the application on the FSA adapter.
9026 +//
9027 +
9028 +typedef struct _FIB_HEADER {
9029 +    AAC_UINT32 XferState;                    // Current transfer state for this CCB
9030 +    AAC_UINT16 Command;                     // Routing information for the destination
9031 +    AAC_UINT8 StructType;                   // Type FIB
9032 +       AAC_UINT8 Flags;                                                  // Flags for FIB
9033 +    AAC_UINT16 Size;                        // Size of this FIB in bytes
9034 +    AAC_UINT16 SenderSize;                  // Size of the FIB in the sender (for response sizing)
9035 +    AAC_UINT32 SenderFibAddress;               // Host defined data in the FIB
9036 +    AAC_UINT32 ReceiverFibAddress;             // Logical address of this FIB for the adapter
9037 +    AAC_UINT32 SenderData;                     // Place holder for the sender to store data
9038 +#ifndef __midl
9039 +       union {
9040 +               struct {
9041 +                   AAC_UINT32 _ReceiverTimeStart;      // Timestamp for receipt of fib
9042 +                   AAC_UINT32 _ReceiverTimeDone;       // Timestamp for completion of fib
9043 +               } _s;
9044 +               LIST_ENTRY _FibLinks;                   // Used to link Adapter Initiated Fibs on the host
9045 +       } _u;
9046 +#else                          // The MIDL compiler does not support unions without a discriminant.
9047 +       struct {                // Since nothing during the midl compile actually looks into this
9048 +               struct {        // structure, this shoudl be ok.
9049 +                       AAC_UINT32 _ReceiverTimeStart;  // Timestamp for receipt of fib
9050 +                   AAC_UINT32 _ReceiverTimeDone;       // Timestamp for completion of fib
9051 +               } _s;
9052 +       } _u;
9053 +#endif
9054 +} FIB_HEADER;
9055 +
9056 +
9057 +#define FibLinks                       _u._FibLinks
9058 +
9059 +
9060 +#define FIB_DATA_SIZE_IN_BYTES (512 - sizeof(FIB_HEADER))
9061 +
9062 +
9063 +typedef struct _FIB {
9064 +
9065 +#ifdef BRIDGE //rma
9066 +       DLQUE link;
9067 +#endif
9068 +    FIB_HEADER Header;
9069 +
9070 +    AAC_UINT8 data[FIB_DATA_SIZE_IN_BYTES];            // Command specific data
9071 +
9072 +} FIB;
9073 +typedef FIB *PFIB;
9074 +
9075 +
9076 +
9077 +//
9078 +// FIB commands
9079 +//
9080 +
9081 +typedef enum _FIB_COMMANDS {
9082 +    TestCommandResponse =                      1,
9083 +    TestAdapterCommand =                       2,
9084 +
9085 +       // Lowlevel and comm commands
9086 +
9087 +    LastTestCommand =                          100,
9088 +    ReinitHostNormCommandQueue =       101,
9089 +    ReinitHostHighCommandQueue =       102,
9090 +    ReinitHostHighRespQueue =          103,
9091 +    ReinitHostNormRespQueue =          104,
9092 +    ReinitAdapNormCommandQueue =       105,
9093 +    ReinitAdapHighCommandQueue =       107,
9094 +    ReinitAdapHighRespQueue =          108,
9095 +    ReinitAdapNormRespQueue =          109,
9096 +    InterfaceShutdown =                        110,
9097 +    DmaCommandFib =                            120,
9098 +    StartProfile =                                     121,
9099 +    TermProfile =                                      122,
9100 +    SpeedTest =                                        123,
9101 +    TakeABreakPt =                                     124,
9102 +    RequestPerfData =                          125,
9103 +    SetInterruptDefTimer=           126,
9104 +    SetInterruptDefCount=           127,
9105 +    GetInterruptDefStatus=          128,
9106 +    LastCommCommand =                          129,
9107 +
9108 +       // Filesystem commands
9109 +
9110 +    NuFileSystem =                                     300,
9111 +    UFS =                                                      301,
9112 +    HostFileSystem =                           302,
9113 +    LastFileSystemCommand =            303,
9114 +
9115 +       // Container Commands
9116 +
9117 +    ContainerCommand =                                 500,
9118 +       ContainerCommand64 =                    501,
9119 +
9120 +       // Cluster Commands
9121 +
9122 +    ClusterCommand =                           550,
9123 +
9124 +       // Scsi Port commands (scsi passthrough)
9125 +
9126 +    ScsiPortCommand =                          600,
9127 +
9128 +       // misc house keeping and generic adapter initiated commands
9129 +
9130 +    AifRequest =                                       700,
9131 +    CheckRevision =                                    701,
9132 +    FsaHostShutdown =                          702,
9133 +    RequestAdapterInfo =                       703,
9134 +    IsAdapterPaused =                          704,
9135 +    SendHostTime =                                     705,
9136 +    LastMiscCommand =                          706
9137 +
9138 +} _E_FIB_COMMANDS;
9139 +
9140 +
9141 +
9142 +typedef AAC_UINT16 FIB_COMMAND;
9143 +
9144 +//
9145 +// Commands that will target the failover level on the FSA adapter
9146 +//
9147 +
9148 +typedef enum _FIB_XFER_STATE {
9149 +    HostOwned                          = (1<<0),
9150 +    AdapterOwned                       = (1<<1),
9151 +    FibInitialized                     = (1<<2),
9152 +    FibEmpty                           = (1<<3),
9153 +    AllocatedFromPool          = (1<<4),
9154 +    SentFromHost                       = (1<<5),
9155 +    SentFromAdapter            = (1<<6),
9156 +    ResponseExpected           = (1<<7),
9157 +    NoResponseExpected                 = (1<<8),
9158 +    AdapterProcessed           = (1<<9),
9159 +    HostProcessed                      = (1<<10),
9160 +    HighPriority                       = (1<<11),
9161 +    NormalPriority                     = (1<<12),
9162 +    Async                                      = (1<<13),
9163 +    AsyncIo                                    = (1<<13),      // rpbfix: remove with new regime
9164 +    PageFileIo                         = (1<<14),      // rpbfix: remove with new regime
9165 +    ShutdownRequest                    = (1<<15),
9166 +    LazyWrite                          = (1<<16),      // rpbfix: remove with new regime
9167 +    AdapterMicroFib                    = (1<<17),
9168 +    BIOSFibPath                                = (1<<18),
9169 +    FastResponseCapable                = (1<<19),
9170 +       ApiFib                                  = (1<<20)       // Its an API Fib.
9171 +
9172 +} _E_FIB_XFER_STATE;
9173 +
9174 +
9175 +typedef enum _FSA_ERRORS {
9176 +    FSA_NORMAL                  = 0,
9177 +    FSA_SUCCESS                 = 0,
9178 +    FSA_PENDING                 = 0x01,
9179 +    FSA_FATAL                   = 0x02,
9180 +    FSA_INVALID_QUEUE           = 0x03,
9181 +    FSA_NOENTRIES               = 0x04,
9182 +    FSA_SENDFAILED              = 0x05,
9183 +    FSA_INVALID_QUEUE_PRIORITY  = 0x06,
9184 +    FSA_FIB_ALLOCATION_FAILED   = 0x07,
9185 +    FSA_FIB_DEALLOCATION_FAILED = 0x08
9186 +
9187 +} _E_FSA_ERRORS;
9188 +
9189 +
9190 +//
9191 +// The following defines needs to be updated any time there is an incompatible change made
9192 +// to the ADAPTER_INIT_STRUCT structure.
9193 +//
9194 +#define ADAPTER_INIT_STRUCT_REVISION           3
9195 +
9196 +typedef struct _ADAPTER_INIT_STRUCT {
9197 +       AAC_UINT32              InitStructRevision;
9198 +       AAC_UINT32              MiniPortRevision;
9199 +       AAC_UINT32              FilesystemRevision;
9200 +       PAAC_VOID               CommHeaderAddress;
9201 +       PAAC_VOID               FastIoCommAreaAddress;
9202 +       PAAC_VOID               AdapterFibsPhysicalAddress;
9203 +       PAAC_VOID               AdapterFibsVirtualAddress;
9204 +       AAC_UINT32              AdapterFibsSize;
9205 +       AAC_UINT32              AdapterFibAlign;
9206 +       PAAC_VOID               PrintfBufferAddress;
9207 +       AAC_UINT32              PrintfBufferSize;
9208 +       AAC_UINT32              HostPhysMemPages;               // number of 4k pages of host physical memory
9209 +       AAC_UINT32              HostElapsedSeconds;             // number of seconds since 1970.
9210 +} ADAPTER_INIT_STRUCT;
9211 +typedef ADAPTER_INIT_STRUCT *PADAPTER_INIT_STRUCT;
9212 +
9213 +#ifdef AAC_32BIT_ENUMS
9214 +typedef _E_FSA_ERRORS  FSA_ERRORS;
9215 +#else
9216 +typedef        AAC_UINT32              FSA_ERRORS;
9217 +#endif
9218 +
9219 +typedef enum _LOG_LEVEL {
9220 +       LOG_INIT                                = 10,
9221 +       LOG_INFORMATIONAL               = 20,
9222 +       LOG_WARNING                             = 30,
9223 +       LOG_LOW_ERROR                   = 40,
9224 +       LOG_MEDIUM_ERROR                = 50,
9225 +       LOG_HIGH_ERROR                  = 60,
9226 +       LOG_PANIC                               = 70,
9227 +       LOG_DEBUG                               = 80,
9228 +       LOG_WINDBG_PRINT                = 90
9229 +} _E_LOG_LEVEL;
9230 +
9231 +#ifdef AAC_32BIT_ENUMS
9232 +typedef _E_LOG_LEVEL   LOG_LEVEL;
9233 +#else
9234 +typedef        AAC_UINT32              LOG_LEVEL;
9235 +#endif
9236 +
9237 +
9238 +#endif //_COMM_STRUCT
9239 +
9240 +
9241 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/comsup.h linux/drivers/scsi/aacraid/include/comsup.h
9242 --- linux-2.4.7/drivers/scsi/aacraid/include/comsup.h   Wed Dec 31 18:00:00 1969
9243 +++ linux/drivers/scsi/aacraid/include/comsup.h Sat Jul 21 17:55:13 2001
9244 @@ -0,0 +1,132 @@
9245 +/*++
9246 + * Adaptec aacraid device driver for Linux.
9247 + *
9248 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9249 + *
9250 + * This program is free software; you can redistribute it and/or modify
9251 + * it under the terms of the GNU General Public License as published by
9252 + * the Free Software Foundation; either version 2, or (at your option)
9253 + * any later version.
9254 + *
9255 + * This program is distributed in the hope that it will be useful,
9256 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9257 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9258 + * GNU General Public License for more details.
9259 + *
9260 + * You should have received a copy of the GNU General Public License
9261 + * along with this program; see the file COPYING.  If not, write to
9262 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9263 + *
9264 + * Module Name:
9265 + *   comsup.h
9266 + *
9267 + * Abstract: This module defines the data structures that make up the 
9268 + *           commuication region for the FSA filesystem. This region is
9269 + *           how the host based code commuicates both control and data
9270 + *           to the adapter based code. 
9271 + *
9272 + *
9273 + *
9274 + --*/
9275 +#ifndef _COMM_SUP_DEF
9276 +#define _COMM_SUP_DEF
9277 +
9278 +static char *ident_comsup = "aacraid_ident comsup.h 1.0.6 2000/10/09 Adaptec, Inc.";
9279 +
9280 +//
9281 +// The adapter interface specs all queues to be located in the same physically
9282 +// contigous block. The host structure that defines the commuication queues will
9283 +// assume they are each a seperate physically contigous memory region that will
9284 +// support them all being one big contigous block.
9285 +// There is a command and response queue for each level and direction of
9286 +// commuication. These regions are accessed by both the host and adapter.
9287 +//
9288 +typedef struct _COMM_QUE {
9289 +
9290 +    PHYSICAL_ADDRESS LogicalAddress;    // This is the address we give the adapter
9291 +    
9292 +    PQUEUE_ENTRY       BaseAddress;        // This is the system virtual address 
9293 +    QUEUE_HEADERS      Headers;            // A pointer to the producer and consumer queue headers for this queue
9294 +    ULONG                      QueueEntries;       // Number of queue entries on this queue
9295 +    OS_CV_T                    QueueFull;          // Event to wait on if the queue is full
9296 +    OS_CV_T                    CommandReady;       // Indicates there is a Command ready from the adapter on this queue.
9297 +                                        // This is only valid for adapter to host command queues.                                        
9298 +    OS_SPINLOCK                *QueueLock;         // Spinlock for this queue must take this lock before accessing the lock
9299 +    KIRQL                      SavedIrql;          // Previous IRQL when the spin lock is taken
9300 +    ddi_softintr_t     ConsumerRoutine;    // The DPC routine which will consume entries off this queue
9301 +                                        // Only queues which the host will be the consumer will this field be valid
9302 +    LIST_ENTRY                 CommandQueue;       // A queue of FIBs which need to be prcessed by the FS thread. This is
9303 +                                        // only valid for command queues which receive entries from the adapter.
9304 +       LIST_ENTRY              OutstandingIoQueue;     // A queue of outstanding fib's to the adapter.
9305 +       ULONG                   NumOutstandingIos;      // Number of entries on outstanding queue.
9306 +
9307 +       PVOID                   Adapter;                        // Back pointer to adapter structure
9308 +
9309 +} COMM_QUE;
9310 +typedef COMM_QUE *PCOMM_QUE;
9311 +
9312 +
9313 +typedef struct _COMM_REGION {
9314 +
9315 +    COMM_QUE HostNormCmdQue;           // Command queue for normal priority commands from the host
9316 +    COMM_QUE HostNormRespQue;           // A response for normal priority adapter responses
9317 +    
9318 +    COMM_QUE HostHighCmdQue;            // Command queue for high priority commands from the host
9319 +    COMM_QUE HostHighRespQue;           // A response for normal priority adapter responses
9320 +    
9321 +    COMM_QUE AdapNormCmdQue;            // Command queue for normal priority command from the adapter
9322 +    COMM_QUE AdapNormRespQue;           // A response for normal priority host responses
9323 +
9324 +    COMM_QUE AdapHighCmdQue;            // Command queue for high priority command from the adapter
9325 +    COMM_QUE AdapHighRespQue;           // A response for high priority host responses
9326 +
9327 +    //
9328 +    // The 2 threads below are the threads which handle command traffic from the
9329 +    // the adapter. There is one for normal priority and one for high priority queues.
9330 +    // These threads will wait on the commandready event for it's queue.
9331 +    //
9332 +
9333 +    HANDLE NormCommandThread;
9334 +    HANDLE HighCommandThread;
9335 +
9336 +    //
9337 +    // This dpc routine will handle the setting the of not full event when the adapter
9338 +    // lets us know the queue is not longer full via interrupt
9339 +    //
9340 +
9341 +    KDPC QueueNotFullDpc;
9342 +
9343 +#ifdef API_THROTTLE
9344 +       //
9345 +       // Support for data I/O throttling to improve CLI performance
9346 +       // while the system is under load.
9347 +       // This is the throttling mechanism built into the COMM layer.
9348 +       // Look in commsup.c, dpcsup.c and comminit.c for use.
9349 +       //
9350 +
9351 +       int                             ThrottleLimit;                          // Max queue depth of data ops allowed during throttle
9352 +       int                             ThrottleOutstandingFibs;        // Number of data FIBs outstanding to adapter
9353 +       LARGE_INTEGER   ThrottleTimeout;                        // Duration of a a throttle period
9354 +       LARGE_INTEGER   ThrottleWaitTimeout;            // Timeout for a suspended threads to wait
9355 +       BOOLEAN                 ThrottleActive;                         // Is there a current throttle active period ?
9356 +       KTIMER                  ThrottleTimer;                          // Throttle timer to end a throttle period.
9357 +       KDPC                    ThrottleDpc;                            // Throttle timer timeout DPC routine.
9358 +       KSEMAPHORE              ThrottleReleaseSema;            // Semaphore callers of SendFib wait on during a throttle.
9359 +
9360 +       unsigned int    ThrottleExceptionsCount;        // Number of times throttle exception handler executed (0!)
9361 +       unsigned int    ThrottleTimerFires;                     // Debug info - #times throttle timer Dpc has fired
9362 +       unsigned int    ThrottleTimerSets;                      // Debug info - #times throttle timer was set
9363 +
9364 +       unsigned int    ThrottledFibs;
9365 +       unsigned int    ThrottleTimedoutFibs;
9366 +       unsigned int    ApiFibs;
9367 +       unsigned int    NonPassiveFibs;
9368 +       unsigned int    TotalFibs;
9369 +       unsigned int    FSInfoFibs;
9370 +
9371 +#endif // #ifdef API_THROTTLE
9372 +
9373 +} COMM_REGION;
9374 +typedef COMM_REGION *PCOMM_REGION;
9375 +
9376 +#endif // _COMM_SUP
9377 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/fsact.h linux/drivers/scsi/aacraid/include/fsact.h
9378 --- linux-2.4.7/drivers/scsi/aacraid/include/fsact.h    Wed Dec 31 18:00:00 1969
9379 +++ linux/drivers/scsi/aacraid/include/fsact.h  Sat Jul 21 17:55:13 2001
9380 @@ -0,0 +1,165 @@
9381 +/*++
9382 + * Adaptec aacraid device driver for Linux.
9383 + *
9384 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9385 + *
9386 + * This program is free software; you can redistribute it and/or modify
9387 + * it under the terms of the GNU General Public License as published by
9388 + * the Free Software Foundation; either version 2, or (at your option)
9389 + * any later version.
9390 + *
9391 + * This program is distributed in the hope that it will be useful,
9392 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9393 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9394 + * GNU General Public License for more details.
9395 + *
9396 + * You should have received a copy of the GNU General Public License
9397 + * along with this program; see the file COPYING.  If not, write to
9398 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9399 + *
9400 + * Module Name:
9401 + *   fsact.h
9402 + *
9403 + * Abstract:  Common container structures that are required to be
9404 + *            known on both the host and adapter.
9405 + *
9406 + *
9407 + --*/
9408 +#ifndef _FSACT_H_
9409 +#define        _FSACT_H_
9410 +
9411 +static char *ident_fsact = "aacraid_ident fsact.h 1.0.6 2000/10/09 Adaptec, Inc.";
9412 +
9413 +//#include <comstruc.h>
9414 +//#include <fsatypes.h>
9415 +#include <protocol.h> // definitions for FSASTATUS
9416 +
9417 +
9418 +/*
9419 + * Object-Server / Volume-Manager Dispatch Classes
9420 + */
9421 +typedef enum _VM_COMMANDS {
9422 +   VM_Null = 0,
9423 +   VM_NameServe,
9424 +   VM_ContainerConfig,
9425 +   VM_Ioctl,
9426 +   VM_FilesystemIoctl,
9427 +   VM_CloseAll,
9428 +   VM_CtBlockRead,             // see protocol.h for BlockRead command layout
9429 +   VM_CtBlockWrite,            // see protocol.h for BlockWrite command layout
9430 +   VM_SliceBlockRead,  // raw access to configured "storage objects"
9431 +   VM_SliceBlockWrite,
9432 +   VM_DriveBlockRead,  // raw access to physical devices
9433 +   VM_DriveBlockWrite,
9434 +   VM_EnclosureMgt,            // enclosure management
9435 +   VM_Unused,                  // used to be diskset management
9436 +   VM_CtBlockVerify,   // see protocol.h for BlockVerify command layout
9437 +   VM_CtPerf,                  // performance test
9438 +   VM_CtBlockRead64,   // see protocol.h for BlockRead64 command layout
9439 +   VM_CtBlockWrite64,  // see protocol.h for BlockWrite64 command layout
9440 +   VM_CtBlockVerify64, // see protocol.h for BlockVerify64 command layout   
9441 +   MAX_VMCOMMAND_NUM   // used for sizing stats array - leave last
9442 +} _E_VMCOMMAND;
9443 +
9444 +#ifdef AAC_32BIT_ENUMS
9445 +typedef _E_VMCOMMAND   VMCOMMAND;
9446 +#else
9447 +typedef        AAC_UINT32              VMCOMMAND;
9448 +#endif
9449 +
9450 +
9451 +
9452 +//
9453 +// Descriptive information (eg, vital stats)
9454 +// that a content manager might report.  The
9455 +// FileArray filesystem component is one example
9456 +// of a content manager.  Raw mode might be
9457 +// another.
9458 +//
9459 +
9460 +struct FileSysInfo {
9461 +/*
9462 +       a) DOS usage - THINK ABOUT WHERE THIS MIGHT GO -- THXXX
9463 +       b) FSA usage (implemented by ObjType and ContentState fields)
9464 +       c) Block size
9465 +       d) Frag size
9466 +       e) Max file system extension size - (fsMaxExtendSize * fsSpaceUnits)
9467 +       f) I-node density - (computed from other fields)
9468 +*/
9469 +       AAC_UINT32  fsTotalSize;        // consumed by fs, incl. metadata
9470 +       AAC_UINT32  fsBlockSize;
9471 +       AAC_UINT32  fsFragSize;
9472 +       AAC_UINT32  fsMaxExtendSize;
9473 +       AAC_UINT32  fsSpaceUnits;
9474 +       AAC_UINT32  fsMaxNumFiles;
9475 +       AAC_UINT32  fsNumFreeFiles;
9476 +       AAC_UINT32  fsInodeDensity;
9477 +};     // valid iff ObjType == FT_FILESYS && !(ContentState & FSCS_NOTCLEAN)
9478 +
9479 +union ContentManagerInfo {
9480 +       struct FileSysInfo FileSys;     // valid iff ObjType == FT_FILESYS && !(ContentState & FSCS_NOTCLEAN)
9481 +};
9482 +
9483 +//
9484 +// Query for "mountable" objects, ie, objects that are typically
9485 +// associated with a drive letter on the client (host) side.
9486 +//
9487 +
9488 +typedef struct _MNTOBJ {
9489 +
9490 +   AAC_UINT32    ObjectId;
9491 +   FSASTRING  FileSystemName;   // if applicable
9492 +   ContainerCreationInfo   CreateInfo; // if applicable
9493 +   AAC_UINT32    Capacity;
9494 +   FSAVOLTYPE VolType;          // substrate structure
9495 +   FTYPE      ObjType;          // FT_FILESYS, FT_DATABASE, etc.
9496 +   AAC_UINT32     ContentState;     // unready for mounting, readonly, etc.
9497 +
9498 +   union ContentManagerInfo
9499 +              ObjExtension;     // Info specific to content manager (eg, filesystem)
9500 +
9501 +   AAC_UINT32    AlterEgoId;       // != ObjectId <==> snapshot or broken mirror exists
9502 +
9503 +} MNTOBJ;
9504 +
9505 +
9506 +#define FSCS_READONLY  0x0002  // possible result of broken mirror
9507 +
9508 +
9509 +
9510 +typedef struct _MNTINFO {
9511 +
9512 +   VMCOMMAND  Command;
9513 +   FTYPE      MntType;
9514 +   AAC_UINT32     MntCount;
9515 +
9516 +} MNTINFO;
9517 +typedef MNTINFO *PMNTINFO;
9518 +
9519 +typedef struct _MNTINFORESPONSE {
9520 +
9521 +   FSASTATUS Status;
9522 +   FTYPE     MntType;           // should be same as that requested
9523 +   AAC_UINT32    MntRespCount;
9524 +   MNTOBJ    MntTable[1];
9525 +
9526 +} MNTINFORESPONSE;
9527 +typedef MNTINFORESPONSE *PMNTINFORESPONSE;
9528 +
9529 +
9530 +//
9531 +// The following command is sent to shut down each container.
9532 +//
9533 +
9534 +typedef struct _CLOSECOMMAND {
9535 +
9536 +   VMCOMMAND  Command;
9537 +   AAC_UINT32    ContainerId;
9538 +
9539 +} CLOSECOMMAND;
9540 +typedef CLOSECOMMAND *PCLOSECOMMAND;
9541 +
9542 +
9543 +#endif /* _FSACT_H_ */
9544 +
9545 +
9546 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/fsafs.h linux/drivers/scsi/aacraid/include/fsafs.h
9547 --- linux-2.4.7/drivers/scsi/aacraid/include/fsafs.h    Wed Dec 31 18:00:00 1969
9548 +++ linux/drivers/scsi/aacraid/include/fsafs.h  Sat Jul 21 17:55:13 2001
9549 @@ -0,0 +1,78 @@
9550 +/*++
9551 + * Adaptec aacraid device driver for Linux.
9552 + *
9553 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9554 + *
9555 + * This program is free software; you can redistribute it and/or modify
9556 + * it under the terms of the GNU General Public License as published by
9557 + * the Free Software Foundation; either version 2, or (at your option)
9558 + * any later version.
9559 + *
9560 + * This program is distributed in the hope that it will be useful,
9561 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9562 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9563 + * GNU General Public License for more details.
9564 + *
9565 + * You should have received a copy of the GNU General Public License
9566 + * along with this program; see the file COPYING.  If not, write to
9567 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9568 + *
9569 + * Module Name:
9570 + *   fsafs.h
9571 + *
9572 + * Abstract: Common file system structures that are required to be
9573 + *           known on both the host and adapter
9574 + *
9575 + *
9576 + *
9577 + --*/
9578 +
9579 +#ifndef _FSAFS_H_
9580 +#define        _FSAFS_H_ 1
9581 +
9582 +static char *ident_fsafs = "aacraid_ident fsafs.h 1.0.6 2000/10/09 Adaptec, Inc.";
9583 +
9584 +#include <fsatypes.h>   // core types, shared by client and server, eg, u_long
9585 +
9586 +/*
9587 + *  Maximum number of filesystems.
9588 + */
9589 +#define NFILESYS   24
9590 +
9591 +/*
9592 + * File identifier.
9593 + * These are unique and self validating within a filesystem
9594 + * on a single machine and can persist across reboots.
9595 + * The hint field may be volatile and is not guaranteed to persist
9596 + * across reboots but is used to speed up the FID to file object translation
9597 + * if possible. The opaque f1 and f2 fields are guaranteed to uniquely identify
9598 + * the file object (assuming a filesystem context, i.e. driveno).
9599 + */
9600 +typedef struct {
9601 +                               AAC_UINT32  hint; // last used hint for fast reclaim
9602 +                               AAC_UINT32  f1;   // opaque
9603 +                               AAC_UINT32  f2;   // opaque
9604 +                       } fileid_t;             /* intra-filesystem file ID type */
9605 +
9606 +       
9607 +/*
9608 + * Generic file handle
9609 + */
9610 +struct fhandle {
9611 +       fsid_t   fh_fsid;       /* File system id of mount point */
9612 +       fileid_t fh_fid;        /* File sys specific file id */
9613 +};
9614 +typedef struct fhandle fhandle_t;
9615 +
9616 +#define        FIDSIZE         sizeof(fhandle_t)
9617 +
9618 +typedef struct {
9619 +       union {
9620 +               AAC_INT8        fid_data[FIDSIZE];
9621 +               struct  fhandle fsafid;
9622 +       } fidu;
9623 +} FSAFID;                                      /* FSA File ID type */
9624 +
9625 +                                                               
9626 +#endif /* _FSAFS_H_ */
9627 +
9628 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/fsaioctl.h linux/drivers/scsi/aacraid/include/fsaioctl.h
9629 --- linux-2.4.7/drivers/scsi/aacraid/include/fsaioctl.h Wed Dec 31 18:00:00 1969
9630 +++ linux/drivers/scsi/aacraid/include/fsaioctl.h       Sat Jul 21 17:55:13 2001
9631 @@ -0,0 +1,159 @@
9632 +/*++
9633 + * Adaptec aacraid device driver for Linux.
9634 + *
9635 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9636 + *
9637 + * This program is free software; you can redistribute it and/or modify
9638 + * it under the terms of the GNU General Public License as published by
9639 + * the Free Software Foundation; either version 2, or (at your option)
9640 + * any later version.
9641 + *
9642 + * This program is distributed in the hope that it will be useful,
9643 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9644 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9645 + * GNU General Public License for more details.
9646 + *
9647 + * You should have received a copy of the GNU General Public License
9648 + * along with this program; see the file COPYING.  If not, write to
9649 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9650 + *
9651 + * Module Name:
9652 + *   fsaioctl.h
9653 + *
9654 + * Abstract: Defines the interface structures between user mode applications
9655 + *           and the fsa driver.  This structures are used in 
9656 + *           DeviceIoControl() calls.
9657 + *
9658 + *
9659 + *
9660 + --*/
9661 +#ifndef _FSAIOCTL_H_
9662 +#define _FSAIOCTL_H_
9663 +
9664 +static char *ident_fsaioctl = "aacraid_ident fsaioctl.h 1.0.6 2000/10/09 Adaptec, Inc.";
9665 +
9666 +#ifndef IOTRACEUSER
9667 +
9668 +#ifndef CTL_CODE
9669 +
9670 +
9671 +#define FILE_DEVICE_CONTROLLER          0x00000004
9672 +
9673 +//
9674 +// Macro definition for defining IOCTL and FSCTL function control codes.  Note
9675 +// that function codes 0-2047 are reserved for Microsoft Corporation, and
9676 +// 2048-4095 are reserved for customers.
9677 +//
9678 +
9679 +#define CTL_CODE( DeviceType, Function, Method, Access ) (                 \
9680 +    ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
9681 +)
9682 +
9683 +//
9684 +// Define the method codes for how buffers are passed for I/O and FS controls
9685 +//
9686 +
9687 +#define METHOD_BUFFERED                 0
9688 +
9689 +
9690 +#define METHOD_NEITHER                  3
9691 +
9692 +//
9693 +// Define the access check value for any access
9694 +//
9695 +//
9696 +// The FILE_READ_ACCESS and FILE_WRITE_ACCESS constants are also defined in
9697 +// ntioapi.h as FILE_READ_DATA and FILE_WRITE_DATA. The values for these
9698 +// constants *MUST* always be in sync.
9699 +//
9700 +#define FILE_ANY_ACCESS                 0
9701 +
9702 +
9703 +
9704 +#endif
9705 +
9706 +
9707 +
9708 +typedef struct _UNIX_QUERY_DISK {
9709 +       AAC_INT32       ContainerNumber;
9710 +       AAC_INT32       Bus;
9711 +       AAC_INT32       Target;
9712 +       AAC_INT32       Lun;
9713 +       AAC_BOOLEAN     Valid;
9714 +       AAC_BOOLEAN     Locked;
9715 +       AAC_BOOLEAN     Deleted;
9716 +       AAC_INT32       Instance;
9717 +       AAC_INT8        diskDeviceName[10];
9718 +       AAC_BOOLEAN UnMapped;
9719 +} UNIX_QUERY_DISK;
9720 +typedef UNIX_QUERY_DISK *PUNIX_QUERY_DISK;
9721 +
9722 +
9723 +typedef struct _DELETE_DISK {
9724 +       AAC_UINT32      NtDiskNumber;
9725 +       AAC_UINT32      ContainerNumber;
9726 +} DELETE_DISK;
9727 +typedef DELETE_DISK *PDELETE_DISK;
9728 +
9729 +
9730 +#endif /*IOTRACEUSER*/
9731 +
9732 +#define FSACTL_NULL_IO_TEST             0x43    // CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 2048, METHOD_NEITHER, FILE_ANY_ACCESS)
9733 +#define FSACTL_SIM_IO_TEST              0x53    // CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 2049, METHOD_NEITHER, FILE_ANY_ACCESS)
9734 +
9735 +
9736 +#define FSACTL_SENDFIB                  CTL_CODE(FILE_DEVICE_CONTROLLER, 2050, METHOD_BUFFERED, FILE_ANY_ACCESS)
9737 +
9738 +
9739 +#define FSACTL_GET_VAR                                 0x93
9740 +#define FSACTL_SET_VAR                                 0xa3
9741 +#define FSACTL_GET_FIBTIMES                            0xb3
9742 +#define FSACTL_ZERO_FIBTIMES                   0xc3
9743 +
9744 +
9745 +#define FSACTL_DELETE_DISK                             0x163
9746 +#define FSACTL_QUERY_DISK                              0x173
9747 +
9748 +
9749 +// AfaComm perfmon ioctls
9750 +#define FSACTL_GET_COMM_PERF_DATA              CTL_CODE(FILE_DEVICE_CONTROLLER, 2084, METHOD_BUFFERED, FILE_ANY_ACCESS)
9751 +
9752 +
9753 +#define FSACTL_OPENCLS_COMM_PERF_DATA  CTL_CODE(FILE_DEVICE_CONTROLLER, 2085, METHOD_BUFFERED, FILE_ANY_ACCESS)
9754 +
9755 +
9756 +typedef struct _GET_ADAPTER_FIB_IOCTL {
9757 +       char    *AdapterFibContext;
9758 +       int             Wait;
9759 +       char    *AifFib;
9760 +} GET_ADAPTER_FIB_IOCTL, *PGET_ADAPTER_FIB_IOCTL;
9761 +
9762 +//
9763 +// filesystem ioctls
9764 +//
9765 +#define FSACTL_OPEN_GET_ADAPTER_FIB            CTL_CODE(FILE_DEVICE_CONTROLLER, 2100, METHOD_BUFFERED, FILE_ANY_ACCESS)
9766 +
9767 +#define FSACTL_GET_NEXT_ADAPTER_FIB            CTL_CODE(FILE_DEVICE_CONTROLLER, 2101, METHOD_BUFFERED, FILE_ANY_ACCESS)
9768 +
9769 +#define FSACTL_CLOSE_GET_ADAPTER_FIB   CTL_CODE(FILE_DEVICE_CONTROLLER, 2102, METHOD_BUFFERED, FILE_ANY_ACCESS)
9770 +
9771 +#define FSACTL_OPEN_ADAPTER_CONFIG             CTL_CODE(FILE_DEVICE_CONTROLLER, 2103, METHOD_NEITHER, FILE_ANY_ACCESS)
9772 +
9773 +#define FSACTL_CLOSE_ADAPTER_CONFIG            CTL_CODE(FILE_DEVICE_CONTROLLER, 2104, METHOD_NEITHER, FILE_ANY_ACCESS)
9774 +
9775 +
9776 +#define FSACTL_MINIPORT_REV_CHECK              CTL_CODE(FILE_DEVICE_CONTROLLER, 2107, METHOD_BUFFERED, FILE_ANY_ACCESS)
9777 +
9778 +
9779 +#define FSACTL_QUERY_ADAPTER_CONFIG            CTL_CODE(FILE_DEVICE_CONTROLLER, 2113, METHOD_BUFFERED, FILE_ANY_ACCESS)
9780 +
9781 +
9782 +#define FSACTL_FORCE_DELETE_DISK               CTL_CODE(FILE_DEVICE_CONTROLLER, 2120, METHOD_NEITHER, FILE_ANY_ACCESS)
9783 +
9784 +
9785 +#define FSACTL_AIF_THREAD                              CTL_CODE(FILE_DEVICE_CONTROLLER, 2127, METHOD_NEITHER, FILE_ANY_ACCESS)
9786 +
9787 +
9788 +#endif // _FSAIOCTL_H_
9789 +
9790 +
9791 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/fsaport.h linux/drivers/scsi/aacraid/include/fsaport.h
9792 --- linux-2.4.7/drivers/scsi/aacraid/include/fsaport.h  Wed Dec 31 18:00:00 1969
9793 +++ linux/drivers/scsi/aacraid/include/fsaport.h        Sat Jul 21 17:55:13 2001
9794 @@ -0,0 +1,223 @@
9795 +/*++
9796 + * Adaptec aacraid device driver for Linux.
9797 + *
9798 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9799 + *
9800 + * This program is free software; you can redistribute it and/or modify
9801 + * it under the terms of the GNU General Public License as published by
9802 + * the Free Software Foundation; either version 2, or (at your option)
9803 + * any later version.
9804 + *
9805 + * This program is distributed in the hope that it will be useful,
9806 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9807 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9808 + * GNU General Public License for more details.
9809 + *
9810 + * You should have received a copy of the GNU General Public License
9811 + * along with this program; see the file COPYING.  If not, write to
9812 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9813 + *
9814 + * Module Name:
9815 + *   fsaport.h
9816 + *
9817 + * Abstract: This module defines all of the globally used procedures in the FSA
9818 + *           file system.
9819 + *
9820 + *
9821 + *
9822 + --*/
9823 +#ifndef _FSAPORT_
9824 +#define _FSAPORT_
9825 +
9826 +static char *ident_fsaport = "aacraid_ident fsaport.h 1.0.6 2000/10/09 Adaptec, Inc.";
9827 +
9828 +//
9829 +// The scatter/gather map context is the information we 
9830 +// we need to keep the map and transfer data to and from the
9831 +// adapter.
9832 +//
9833 +
9834 +typedef struct _SGMAP_CONTEXT {
9835 +       
9836 +       caddr_t         BaseAddress;
9837 +    PVOID              MapRegBase;
9838 +    ULONG              NumberMapRegs;
9839 +       PSGMAP          SgMapPtr;
9840 +       ULONG           ByteCount;              // Used to check the Mdl length.
9841 +       BOOLEAN         WriteToDevice;
9842 +
9843 +       struct buf      *bp;
9844 +
9845 +
9846 +} SGMAP_CONTEXT;
9847 +typedef SGMAP_CONTEXT *PSGMAP_CONTEXT;
9848 +
9849 +typedef struct _MAPFIB_CONTEXT {
9850 +       PMDL            Mdl;    
9851 +    PVOID              MapRegBase;
9852 +    ULONG              NumberMapRegs;
9853 +       PVOID           FibVirtualAddress;
9854 +       ULONG           Size;
9855 +       PVOID       FibPhysicalAddress;
9856 +
9857 +
9858 +} MAPFIB_CONTEXT;
9859 +typedef MAPFIB_CONTEXT *PMAPFIB_CONTEXT;
9860 +
9861 +typedef BOOLEAN
9862 +(*PFSA_ALLOCATE_ADAPTER_COMM_AREA)(
9863 +       PVOID AdapterExtension,
9864 +       IN OUT PVOID    *BaseAddress,
9865 +       IN ULONG                Size,
9866 +       IN ULONG                Alignment
9867 +       );
9868 +
9869 +typedef BOOLEAN
9870 +(*PFSA_FREE_ADAPTER_COMM_AREA)(
9871 +       PVOID   AdapterExtension
9872 +       );
9873 +
9874 +typedef VOID
9875 +(*PFSA_FREE_DMA_RESOURCES)(     
9876 +       IN PVOID AdapterExtension,
9877 +    IN PSGMAP_CONTEXT SgMapContext
9878 +    );
9879 +
9880 +typedef BOOLEAN
9881 +(*PFSA_ALLOCATE_AND_MAP_FIB_SPACE)(
9882 +       IN PVOID AdapterExtension, 
9883 +       IN PMAPFIB_CONTEXT MapFibContext
9884 +    );
9885 +
9886 +typedef BOOLEAN
9887 +(*PFSA_UNMAP_AND_FREE_FIB_SPACE)(
9888 +       IN PVOID AdapterExtension, 
9889 +       IN PMAPFIB_CONTEXT MapFibContext
9890 +    );
9891 +
9892 +typedef VOID
9893 +(*PFSA_INTERRUPT_ADAPTER)(
9894 +       IN PVOID AdapterExtension
9895 +       );
9896 +
9897 +typedef VOID
9898 +(*PFSA_NOTIFY_ADAPTER)(
9899 +       IN PVOID AdapterExtension,
9900 +    IN HOST_2_ADAP_EVENT AdapterEvent
9901 +    );
9902 +
9903 +typedef VOID
9904 +(*PFSA_RESET_DEVICE)(
9905 +       PVOID AdapterExtension
9906 +       );
9907 +
9908 +typedef AAC_STATUS
9909 +(*PFSA_BUILD_SGMAP)(  
9910 +       IN PVOID AdapterExtension,
9911 +       IN PSGMAP_CONTEXT SgMapContext
9912 +       );
9913 +
9914 +typedef PVOID
9915 +(*PFSA_ADAPTER_ADDR_TO_SYSTEM_ADDR)(  
9916 +       IN PVOID AdapterExtension,
9917 +       IN PVOID AdapterAddress
9918 +       );
9919 +
9920 +typedef VOID
9921 +(*PFSA_INTERRUPT_HOST)(
9922 +       PVOID                   Adapter,
9923 +       ADAPTER_EVENT   AdapterEvent
9924 +       );
9925 +
9926 +typedef VOID
9927 +(*PFSA_ENABLE_INTERRUPT)(
9928 +       PVOID                   Adapter,
9929 +       ADAPTER_EVENT   AdapterEvent,
9930 +       BOOLEAN                 AtDeviceIrq
9931 +       );
9932 +
9933 +
9934 +typedef VOID
9935 +(*PFSA_DISABLE_INTERRUPT)(
9936 +       PVOID                   Adapter,
9937 +       ADAPTER_EVENT   AdapterEvent,
9938 +       BOOLEAN                 AtDeviceIrq
9939 +       );
9940 +
9941 +typedef AAC_STATUS
9942 +(*PFSA_OPEN_ADAPTER) (
9943 +       IN PVOID Adapter
9944 +       );
9945 +
9946 +typedef int
9947 +(*PFSA_DEVICE_CONTROL) (
9948 +       IN PVOID Adapter,
9949 +       IN PAFA_IOCTL_CMD IoctlCmdPtr
9950 +       );
9951 +
9952 +typedef AAC_STATUS
9953 +(*PFSA_CLOSE_ADAPTER) (
9954 +       IN PVOID Adapter
9955 +       );
9956 +
9957 +typedef BOOLEAN
9958 +(*PFSA_SEND_SYNCH_FIB) (
9959 +       IN PVOID Adapter,
9960 +       IN ULONG FibPhysicalAddress
9961 +       );
9962 +
9963 +typedef struct _FSAPORT_FUNCS {
9964 +       ULONG                                                           SizeOfFsaPortFuncs;
9965 +
9966 +       PFSA_ALLOCATE_ADAPTER_COMM_AREA         AllocateAdapterCommArea;
9967 +       PFSA_FREE_ADAPTER_COMM_AREA                     FreeAdapterCommArea;
9968 +       PFSA_FREE_DMA_RESOURCES                         FreeDmaResources;
9969 +       PFSA_ALLOCATE_AND_MAP_FIB_SPACE         AllocateAndMapFibSpace;
9970 +       PFSA_UNMAP_AND_FREE_FIB_SPACE           UnmapAndFreeFibSpace;
9971 +       PFSA_INTERRUPT_ADAPTER                          InterruptAdapter;
9972 +       PFSA_NOTIFY_ADAPTER                                     NotifyAdapter;
9973 +       PFSA_ENABLE_INTERRUPT                           EnableInterrupt;
9974 +       PFSA_DISABLE_INTERRUPT                          DisableInterrupt;
9975 +       PFSA_RESET_DEVICE                                       ResetDevice;
9976 +       PFSA_BUILD_SGMAP                                        BuildSgMap;
9977 +       PFSA_ADAPTER_ADDR_TO_SYSTEM_ADDR        AdapterAddressToSystemAddress;
9978 +
9979 +       PFSA_INTERRUPT_HOST                                     InterruptHost;
9980 +       PFSA_OPEN_ADAPTER                                       OpenAdapter;
9981 +       PFSA_DEVICE_CONTROL                                     DeviceControl;
9982 +       PFSA_CLOSE_ADAPTER                                      CloseAdapter;
9983 +
9984 +       PFSA_SEND_SYNCH_FIB                                     SendSynchFib;
9985 +
9986 +} FSAPORT_FUNCS;
9987 +typedef FSAPORT_FUNCS *PFSAPORT_FUNCS;
9988 +
9989 +typedef AAC_STATUS
9990 +(*PFSA_SETVAR_CALLBACK) (
9991 +       IN PVOID Adapter,
9992 +       IN ULONG NewValue
9993 +       );
9994 +
9995 +typedef struct _FSA_USER_VAR {
9996 +       char                                    Name[32];
9997 +       ULONG                                   *Address;
9998 +       PFSA_SETVAR_CALLBACK    SetVarCallback;
9999 +} FSA_USER_VAR;
10000 +
10001 +typedef FSA_USER_VAR *PFSA_USER_VAR;
10002 +
10003 +typedef struct _FSA_NEW_ADAPTER {
10004 +       PVOID                           AdapterExtension;
10005 +       PFSAPORT_FUNCS          AdapterFuncs;
10006 +       PVOID                           Adapter;
10007 +       BOOLEAN                         AdapterInterruptsBelowDpc;
10008 +       PFSA_USER_VAR           AdapterUserVars;
10009 +       ULONG                           AdapterUserVarsSize;
10010 +       void                            *Dip;
10011 +} FSA_NEW_ADAPTER;
10012 +typedef FSA_NEW_ADAPTER *PFSA_NEW_ADAPTER;
10013 +
10014 +#define        FSAFS_GET_NEXT_ADAPTER                  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 2048, METHOD_NEITHER, FILE_ANY_ACCESS)
10015 +#define        FSAFS_INIT_NEW_ADAPTER                  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 2049, METHOD_NEITHER, FILE_ANY_ACCESS)
10016 +
10017 +#endif
10018 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/fsatypes.h linux/drivers/scsi/aacraid/include/fsatypes.h
10019 --- linux-2.4.7/drivers/scsi/aacraid/include/fsatypes.h Wed Dec 31 18:00:00 1969
10020 +++ linux/drivers/scsi/aacraid/include/fsatypes.h       Sat Jul 21 17:55:13 2001
10021 @@ -0,0 +1,214 @@
10022 +/*++
10023 + * Adaptec aacraid device driver for Linux.
10024 + *
10025 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10026 + *
10027 + * This program is free software; you can redistribute it and/or modify
10028 + * it under the terms of the GNU General Public License as published by
10029 + * the Free Software Foundation; either version 2, or (at your option)
10030 + * any later version.
10031 + *
10032 + * This program is distributed in the hope that it will be useful,
10033 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10034 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10035 + * GNU General Public License for more details.
10036 + *
10037 + * You should have received a copy of the GNU General Public License
10038 + * along with this program; see the file COPYING.  If not, write to
10039 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10040 + *
10041 + * Module Name:
10042 + *   fsatypes.h
10043 + *
10044 + * Abstract: Define all shared data types here, ie, those
10045 + *           types shared among several components, such
10046 + *           as host (driver + apps), adapter, and BIOS.
10047 + *
10048 + *
10049 + --*/
10050 +#ifndef _FSATYPES_H
10051 +#define _FSATYPES_H
10052 +
10053 +static char *ident_fsatype = "aacraid_ident fsatypes.h 1.0.6 2000/10/09 Adaptec, Inc.";
10054 +
10055 +typedef        AAC_UINT32              AAC_BOOLEAN;
10056 +
10057 +//
10058 +// Define a 64-bit address structure for use on
10059 +// a 32-bit processor architecture.
10060 +//
10061 +typedef struct {
10062 +       AAC_UINT32              lo32;
10063 +       AAC_UINT32              hi32;
10064 +} AAC_UINT64S, *PAAC_UINT64S;
10065 +
10066 +
10067 +
10068 +//
10069 +// Container Types
10070 +//
10071 +typedef struct {
10072 +   AAC_UINT32 data[2];  // RMA FIX, make this a real serial number when we
10073 +                           // know what it looks like.  Note, BIOS sees this
10074 +                           // definition and it must be coded in such a way
10075 +                           // that it appears to be 64 bits.  ints are 16 bits
10076 +                           // in BIOS land; fortunately, longs are 32 bits.
10077 +} SerialNumberT;
10078 +
10079 +
10080 +
10081 +//
10082 +//     ***********************
10083 +//     DON'T CHANGE THE ORDER, ctdevsw use this order to map the drivers
10084 +//     ***********************
10085 +//     drivers for CT_NONE to CT_PASSTHRU
10086 +//
10087 +typedef enum _FSAVOLTYPE {
10088 +       CT_NONE = 0,                            
10089 +       CT_VOLUME,                                      
10090 +       CT_MIRROR,
10091 +       CT_STRIPE,
10092 +       CT_RAID5,
10093 +       CT_SSRW,
10094 +       CT_SSRO,
10095 +       CT_MORPH,
10096 +       CT_PASSTHRU,
10097 +       CT_RAID4,
10098 +       CT_RAID10,                                      // stripe of mirror
10099 +       CT_RAID00,                                      // stripe of stripe
10100 +       CT_VOLUME_OF_MIRRORS,           // volume of mirror
10101 +       CT_PSEUDO_RAID3,                        // really raid4
10102 +
10103 +       CT_LAST_VOLUME_TYPE
10104 +
10105 +} _E_FSAVOLTYPE;
10106 +
10107 +#ifdef AAC_32BIT_ENUMS
10108 +typedef        _E_FSAVOLTYPE   FSAVOLTYPE;
10109 +#else
10110 +typedef        AAC_UINT32              FSAVOLTYPE;
10111 +#endif
10112 +
10113 +
10114 +//
10115 +// Types of objects addressable in some fashion by the client.
10116 +// This is a superset of those objects handled just by the filesystem
10117 +// and includes "raw" objects that an administrator would use to
10118 +// configure containers and filesystems.
10119 +//
10120 +typedef enum _FTYPE {
10121 +    FT_REG = 1,     // regular file
10122 +    FT_DIR,         // directory
10123 +    FT_BLK,         // "block" device - reserved
10124 +    FT_CHR,         // "character special" device - reserved
10125 +    FT_LNK,         // symbolic link
10126 +    FT_SOCK,        // socket
10127 +    FT_FIFO,        // fifo
10128 +    FT_FILESYS,     // ADAPTEC's "FSA"(tm) filesystem
10129 +    FT_DRIVE,       // physical disk - addressable in scsi by bus/target/lun
10130 +    FT_SLICE,       // virtual disk - raw volume - slice
10131 +    FT_PARTITION,   // FSA partition - carved out of a slice - building block for containers
10132 +    FT_VOLUME,      // Container - Volume Set
10133 +    FT_STRIPE,      // Container - Stripe Set
10134 +    FT_MIRROR,      // Container - Mirror Set
10135 +    FT_RAID5,       // Container - Raid 5 Set
10136 +    FT_DATABASE     // Storage object with "foreign" content manager
10137 +} _E_FTYPE;
10138 +
10139 +#ifdef AAC_32BIT_ENUMS
10140 +typedef        _E_FTYPE        FTYPE;
10141 +#else
10142 +typedef        AAC_UINT32      FTYPE;
10143 +#endif
10144 +
10145 +
10146 +
10147 +//
10148 +// Host side memory scatter gather list
10149 +// Used by the adapter for read, write, and readdirplus operations
10150 +//
10151 +typedef  PAAC_UINT8 HOSTADDRESS;
10152 +
10153 +typedef struct _SGENTRY {
10154 +       HOSTADDRESS             SgAddress;              /* 32-bit Base address. */
10155 +       AAC_UINT32                      SgByteCount;    /* Length. */
10156 +} SGENTRY;
10157 +typedef SGENTRY *PSGENTRY;
10158 +
10159 +
10160 +
10161 +//
10162 +// SGMAP
10163 +//
10164 +// This is the SGMAP structure for all commands that use
10165 +// 32-bit addressing.
10166 +//
10167 +// Note that the upper 16 bits of SgCount are used as flags.
10168 +// Only the lower 16 bits of SgCount are actually used as the
10169 +// SG element count.
10170 +//
10171 +typedef struct _SGMAP {
10172 +       AAC_UINT32              SgCount;
10173 +       SGENTRY                 SgEntry[1];
10174 +} SGMAP;
10175 +typedef SGMAP *PSGMAP;
10176 +
10177 +
10178 +
10179 +//
10180 +// SGMAP64
10181 +//
10182 +// This is the SGMAP structure for 64-bit container commands.
10183 +//
10184 +typedef struct _SGMAP64 {
10185 +       AAC_UINT8       SgCount;
10186 +       AAC_UINT8       SgSectorsPerPage;
10187 +       AAC_UINT16      SgByteOffset; // For the first page 
10188 +       AAC_UINT64S     SgEntry[1];     // Must be last entry
10189 +} SGMAP64;
10190 +typedef SGMAP64 *PSGMAP64;
10191 +
10192 +
10193 +
10194 +
10195 +//
10196 +// attempt at common time structure across host and adapter
10197 +//
10198 +typedef struct __TIME_T {
10199 +
10200 +       AAC_UINT32      tv_sec;         /* seconds (maybe, depends upon host) */
10201 +       AAC_UINT32      tv_usec;        /* and nanoseconds (maybe, depends upon host)*/
10202 +
10203 +} TIME_T;
10204 +typedef TIME_T *PTIME_T;
10205 +
10206 +#ifndef _TIME_T
10207 +#define timespec __TIME_T
10208 +#define ts_sec tv_sec
10209 +#define ts_nsec        tv_usec
10210 +#endif
10211 +
10212 +
10213 +
10214 +
10215 +typedef struct _ContainerCreationInfo
10216 +{
10217 +
10218 +       AAC_UINT8               ViaBuildNumber;         // e.g., 588
10219 +       AAC_UINT8               MicroSecond;            // e.g., 588
10220 +       AAC_UINT8               Via;                            // e.g.,        1 = FSU,
10221 +                                                                               //                      2 = API,
10222 +       AAC_UINT8               YearsSince1900;         // e.g., 1997 = 97
10223 +       AAC_UINT32              Date;                   //
10224 +                                                                               // unsigned     Month           :4;             // 1 - 12
10225 +                                                                               // unsigned     Day                     :6;             // 1 - 32
10226 +                                                                               // unsigned     Hour            :6;             // 0 - 23
10227 +                                                                               // unsigned     Minute          :6;             // 0 - 60
10228 +                                                                               // unsigned     Second          :6;             // 0 - 60
10229 +       SerialNumberT   ViaAdapterSerialNumber; // e.g., 0x1DEADB0BFAFAF001
10230 +} ContainerCreationInfo;
10231 +
10232 +
10233 +#endif // _FSATYPES_H
10234 +
10235 +
10236 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/linit.h linux/drivers/scsi/aacraid/include/linit.h
10237 --- linux-2.4.7/drivers/scsi/aacraid/include/linit.h    Wed Dec 31 18:00:00 1969
10238 +++ linux/drivers/scsi/aacraid/include/linit.h  Sat Jul 21 17:55:13 2001
10239 @@ -0,0 +1,107 @@
10240 +/*++
10241 + * Adaptec aacraid device driver for Linux.
10242 + *
10243 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10244 + *
10245 + * This program is free software; you can redistribute it and/or modify
10246 + * it under the terms of the GNU General Public License as published by
10247 + * the Free Software Foundation; either version 2, or (at your option)
10248 + * any later version.
10249 + *
10250 + * This program is distributed in the hope that it will be useful,
10251 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10252 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10253 + * GNU General Public License for more details.
10254 + *
10255 + * You should have received a copy of the GNU General Public License
10256 + * along with this program; see the file COPYING.  If not, write to
10257 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10258 + *
10259 + * Module Name:
10260 + *   linit.h
10261 + *
10262 + * Abstract: Header file for Linux Driver for Adaptec RAID Array Controller
10263 + *
10264 + --*/
10265 +/*------------------------------------------------------------------------------
10266 + *              I N C L U D E S
10267 + *----------------------------------------------------------------------------*/
10268 +
10269 +#ifndef _LINIT_H_
10270 +#define _LINIT_H_
10271 +
10272 +static char *ident_linith = "aacraid_ident linit.h 1.0.6 2000/10/09 Adaptec, Inc.";
10273 +
10274 +#include <linux/config.h>
10275 +
10276 +/*------------------------------------------------------------------------------
10277 + *              D E F I N E S
10278 + *----------------------------------------------------------------------------*/
10279 +/* Define the AAC SCSI Host Template structure. */
10280 +#define AAC_HOST_TEMPLATE_ENTRY        \
10281 +  { name:           "AAC",                   /* Driver Name            */ \
10282 +    proc_info:      AAC_ProcDirectoryInfo,   /* ProcFS Info Func       */ \
10283 +    detect:         AAC_DetectHostAdapter,   /* Detect Host Adapter    */ \
10284 +    release:        AAC_ReleaseHostAdapter,  /* Release Host Adapter   */ \
10285 +    info:           AAC_DriverInfo,          /* Driver Info Function   */ \
10286 +    ioctl:          AAC_Ioctl,               /* ioctl Interface        */ \
10287 +    command:        AAC_Command,             /* unqueued command       */ \
10288 +    queuecommand:   AAC_QueueCommand,        /* Queue Command Function */ \
10289 +    abort:          AAC_AbortCommand,        /* Abort Command Function */ \
10290 +    reset:          AAC_ResetCommand,        /* Reset Command Function */ \
10291 +    bios_param:     AAC_BIOSDiskParameters,  /* BIOS Disk Parameters   */ \
10292 +    can_queue:      1,                       /* Default initial value  */ \
10293 +    this_id:        0,                       /* Default initial value  */ \
10294 +    sg_tablesize:   0,                       /* Default initial value  */ \
10295 +    max_sectors:    128,                     /* max xfer size of 64k   */ \
10296 +    cmd_per_lun:    0,                       /* Default initial value  */ \
10297 +    present:        0,                       /* Default initial value  */ \
10298 +    unchecked_isa_dma: 0,                    /* Default Initial Value  */ \
10299 +    use_new_eh_code:         0,                  /* Default initial value      */ \
10300 +    eh_abort_handler:        AAC_AbortCommand,   /* New Abort Command func     */ \
10301 +    eh_strategy_handler:     NULL,               /* New Strategy Error Handler */ \
10302 +    eh_device_reset_handler: NULL,               /* New Device Reset Handler   */ \
10303 +    eh_bus_reset_handler:    NULL,               /* New Bus Reset Handler      */ \
10304 +    eh_host_reset_handler:   NULL,               /* New Host reset Handler     */ \
10305 +    use_clustering: ENABLE_CLUSTERING        /* Disable Clustering      */ \
10306 +  }
10307 +
10308 +
10309 +/*------------------------------------------------------------------------------
10310 + *              T Y P E D E F S / S T R U C T S
10311 + *----------------------------------------------------------------------------*/
10312 +typedef struct AAC_BIOS_DiskParameters
10313 +{
10314 +       int heads;
10315 +       int sectors;
10316 +       int cylinders;
10317 +} AAC_BIOS_DiskParameters_T;
10318 +
10319 +
10320 +/*------------------------------------------------------------------------------
10321 + *              P R O G R A M   G L O B A L S
10322 + *----------------------------------------------------------------------------*/
10323 +
10324 +const char *AAC_DriverInfo( struct Scsi_Host * );
10325 +
10326 +
10327 +/*------------------------------------------------------------------------------
10328 + *              F U N C T I O N   P R O T O T Y P E S
10329 + *----------------------------------------------------------------------------*/
10330 +/* Define prototypes for the AAC Driver Interface Functions. */
10331 +int AAC_DetectHostAdapter( Scsi_Host_Template * );
10332 +int AAC_ReleaseHostAdapter( struct Scsi_Host * );
10333 +int AAC_QueueCommand( Scsi_Cmnd *, void ( *CompletionRoutine )( Scsi_Cmnd * ) );
10334 +int AAC_Command( Scsi_Cmnd * );
10335 +int AAC_ResetCommand( Scsi_Cmnd *, unsigned int );
10336 +int AAC_BIOSDiskParameters( Disk *, kdev_t, int * );
10337 +int AAC_ProcDirectoryInfo( char *, char **, off_t, int, int, int );
10338 +int AAC_Ioctl( Scsi_Device *, int, void * );
10339 +
10340 +
10341 +void AAC_SelectQueueDepths(    struct Scsi_Host *, Scsi_Device * );
10342 +
10343 +
10344 +int AAC_AbortCommand( Scsi_Cmnd *scsi_cmnd_ptr );
10345 +
10346 +#endif /* _LINIT_H_ */
10347 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/monkerapi.h linux/drivers/scsi/aacraid/include/monkerapi.h
10348 --- linux-2.4.7/drivers/scsi/aacraid/include/monkerapi.h        Wed Dec 31 18:00:00 1969
10349 +++ linux/drivers/scsi/aacraid/include/monkerapi.h      Sat Jul 21 17:55:13 2001
10350 @@ -0,0 +1,98 @@
10351 +/*++
10352 + * Adaptec aacraid device driver for Linux.
10353 + *
10354 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10355 + *
10356 + * This program is free software; you can redistribute it and/or modify
10357 + * it under the terms of the GNU General Public License as published by
10358 + * the Free Software Foundation; either version 2, or (at your option)
10359 + * any later version.
10360 + *
10361 + * This program is distributed in the hope that it will be useful,
10362 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10363 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10364 + * GNU General Public License for more details.
10365 + *
10366 + * You should have received a copy of the GNU General Public License
10367 + * along with this program; see the file COPYING.  If not, write to
10368 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10369 + *
10370 + * Module Name:
10371 + *   monkerapi.h
10372 + *
10373 + * Abstract: This module contains the definitions used by the Host Adapter
10374 + *      Communications interface.
10375 + *      This is the interface used for by host programs and the Adapter 
10376 + *      to communicate via synchronous commands via a shared set of registers
10377 + *      on a platform (typically doorbells and mailboxes).
10378 + *
10379 + --*/
10380 +//**********************************************************************
10381 +//
10382 +//     Monitor / Kernel API
10383 +//
10384 +//     03/24/1998 Bob Peret    Initial creation
10385 +//
10386 +//**********************************************************************
10387 +
10388 +#ifndef MONKER_H
10389 +#define MONKER_H
10390 +
10391 +static char *ident_monk = "aacraid_ident monkerapi.h 1.0.6 2000/10/09 Adaptec, Inc.";
10392 +
10393 +#define        BREAKPOINT_REQUEST                                      0x00000004
10394 +#define        INIT_STRUCT_BASE_ADDRESS                        0x00000005
10395 +
10396 +
10397 +#define        SEND_SYNCHRONOUS_FIB                            0x0000000c
10398 +
10399 +
10400 +
10401 +//
10402 +//     Adapter Status Register
10403 +//
10404 +//  Phase Staus mailbox is 32bits:
10405 +//     <31:16> = Phase Status
10406 +//     <15:0>  = Phase
10407 +//
10408 +//  The adapter reports is present state through the phase.  Only
10409 +//  a single phase should be ever be set.  Each phase can have multiple
10410 +//     phase status bits to provide more detailed information about the 
10411 +//     state of the board.  Care should be taken to ensure that any phase status 
10412 +//  bits that are set when changing the phase are also valid for the new phase
10413 +//  or be cleared out.  Adapter software (monitor, iflash, kernel) is responsible
10414 +//  for properly maintining the phase status mailbox when it is running.
10415 +
10416 +//                                                                                     
10417 +// MONKER_API Phases                                                   
10418 +//
10419 +// Phases are bit oriented.  It is NOT valid 
10420 +// to have multiple bits set                                           
10421 +//                                     
10422 +
10423 +
10424 +#define        SELF_TEST_FAILED                                        0x00000004
10425 +
10426 +
10427 +#define        KERNEL_UP_AND_RUNNING                           0x00000080
10428 +#define        KERNEL_PANIC                                            0x00000100
10429 +
10430 +
10431 +
10432 +//
10433 +// Doorbell bit defines
10434 +//
10435 +
10436 +
10437 +#define DoorBellPrintfDone                             (1<<5)  // Host -> Adapter
10438 +
10439 +
10440 +#define DoorBellAdapterNormCmdReady            (1<<1)  // Adapter -> Host
10441 +#define DoorBellAdapterNormRespReady   (1<<2)  // Adapter -> Host
10442 +#define DoorBellAdapterNormCmdNotFull  (1<<3)  // Adapter -> Host
10443 +#define DoorBellAdapterNormRespNotFull (1<<4)  // Adapter -> Host
10444 +#define DoorBellPrintfReady                            (1<<5)  // Adapter -> Host
10445 +
10446 +
10447 +#endif // MONKER_H
10448 +
10449 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/nodetype.h linux/drivers/scsi/aacraid/include/nodetype.h
10450 --- linux-2.4.7/drivers/scsi/aacraid/include/nodetype.h Wed Dec 31 18:00:00 1969
10451 +++ linux/drivers/scsi/aacraid/include/nodetype.h       Sat Jul 21 17:55:13 2001
10452 @@ -0,0 +1,67 @@
10453 +/*++
10454 + * Adaptec aacraid device driver for Linux.
10455 + *
10456 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10457 + *
10458 + * This program is free software; you can redistribute it and/or modify
10459 + * it under the terms of the GNU General Public License as published by
10460 + * the Free Software Foundation; either version 2, or (at your option)
10461 + * any later version.
10462 + *
10463 + * This program is distributed in the hope that it will be useful,
10464 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10465 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10466 + * GNU General Public License for more details.
10467 + *
10468 + * You should have received a copy of the GNU General Public License
10469 + * along with this program; see the file COPYING.  If not, write to
10470 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10471 + *
10472 + * Module Name:
10473 + *   nodetype.h
10474 + *
10475 + * Abstract:     This module defines all of the node type codes used in this development
10476 + *  shell.  Every major data structure in the file system is assigned a node
10477 + *  type code that is.  This code is the first CSHORT in the structure and is
10478 + *  followed by a CSHORT containing the size, in bytes, of the structure.
10479 + *
10480 + --*/
10481 +#ifndef _NODETYPE_
10482 +#define _NODETYPE_
10483 +
10484 +static char *ident_node = "aacraid_ident nodetype.h 1.0.6 2000/10/09 Adaptec, Inc.";
10485 +
10486 +typedef CSHORT NODE_TYPE_CODE;
10487 +
10488 +
10489 +#define FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT ((NODE_TYPE_CODE)0x030b)
10490 +#define FSAFS_NTC_FIB_CONTEXT            ((NODE_TYPE_CODE)0x030c)
10491 +
10492 +
10493 +typedef CSHORT NODE_BYTE_SIZE;
10494 +
10495 +
10496 +//
10497 +//  The following definitions are used to generate meaningful blue bugcheck
10498 +//  screens.  On a bugcheck the file system can output 4 ulongs of useful
10499 +//  information.  The first ulong will have encoded in it a source file id
10500 +//  (in the high word) and the line number of the bugcheck (in the low word).
10501 +//  The other values can be whatever the caller of the bugcheck routine deems
10502 +//  necessary.
10503 +//
10504 +//  Each individual file that calls bugcheck needs to have defined at the
10505 +//  start of the file a constant called BugCheckFileId with one of the
10506 +//  FSAFS_BUG_CHECK_ values defined below and then use FsaBugCheck to bugcheck
10507 +//  the system.
10508 +//
10509 +
10510 +
10511 +#define FSAFS_BUG_CHECK_COMMSUP           (0X001e0000)
10512 +#define FSAFS_BUG_CHECK_DPCSUP            (0X001f0000)
10513 +
10514 +
10515 +#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); }
10516 +
10517 +
10518 +#endif // _NODETYPE_
10519 +
10520 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/nvramioctl.h linux/drivers/scsi/aacraid/include/nvramioctl.h
10521 --- linux-2.4.7/drivers/scsi/aacraid/include/nvramioctl.h       Wed Dec 31 18:00:00 1969
10522 +++ linux/drivers/scsi/aacraid/include/nvramioctl.h     Sat Jul 21 17:55:13 2001
10523 @@ -0,0 +1,112 @@
10524 +/*++
10525 + * Adaptec aacraid device driver for Linux.
10526 + *
10527 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10528 + *
10529 + * This program is free software; you can redistribute it and/or modify
10530 + * it under the terms of the GNU General Public License as published by
10531 + * the Free Software Foundation; either version 2, or (at your option)
10532 + * any later version.
10533 + *
10534 + * This program is distributed in the hope that it will be useful,
10535 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10536 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10537 + * GNU General Public License for more details.
10538 + *
10539 + * You should have received a copy of the GNU General Public License
10540 + * along with this program; see the file COPYING.  If not, write to
10541 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10542 + *
10543 + * Module Name:
10544 + *   nvramioctl.h
10545 + *
10546 + * Abstract: This file defines the data structures related to querying
10547 + *    and controlling the FSA NVRAM/WriteCache subsystem via the NVRAMIOCTL FIB.
10548 + *
10549 + --*/
10550 +#ifndef _NVRAMIOCTL_H_
10551 +#define _NVRAMIOCTL_H_ 1
10552 +
10553 +static char *ident_nvram = "aacraid_ident nvramioctl.h 1.0.6 2000/10/09 Adaptec, Inc.";
10554 +
10555 +/*
10556 + * NVRAM/Write Cache subsystem states
10557 + */
10558 +typedef enum _NVSTATUS {
10559 +       NVSTATUS_DISABLED = 0,  // present, clean, not being used
10560 +       NVSTATUS_ENABLED,               // present, possibly dirty, ready for use
10561 +       NVSTATUS_ERROR,                 // present, dirty, contains dirty data
10562 +                                                       // for bad/missing device
10563 +       NVSTATUS_BATTERY,               // present, bad or low battery, may contain dirty data
10564 +                                                       // for bad/missing device
10565 +       NVSTATUS_UNKNOWN                // present?????
10566 +} _E_NVSTATUS;
10567 +
10568 +#ifdef AAC_32BIT_ENUMS
10569 +typedef _E_NVSTATUS    NVSTATUS;
10570 +#else
10571 +typedef AAC_UINT32     NVSTATUS;
10572 +#endif
10573 +
10574 +/*
10575 + * NVRAM/Write Cache subsystem battery component states
10576 + *
10577 + */
10578 +//NB: this enum should be identical to battery_status in nvram.h
10579 +//       or else collapsed into one enum someday
10580 +typedef enum _NVBATTSTATUS {
10581 +       NVBATTSTATUS_NONE = 0,  // battery has no power or is not present
10582 +       NVBATTSTATUS_LOW,               // battery is low on power
10583 +       NVBATTSTATUS_OK,                        // battery is okay - normal operation possible only in this state
10584 +       NVBATTSTATUS_RECONDITIONING     // no battery present - reconditioning in process
10585 +} _E_NVBATTSTATUS;
10586 +
10587 +#ifdef AAC_32BIT_ENUMS
10588 +typedef        _E_NVBATTSTATUS NVBATTSTATUS;
10589 +#else
10590 +typedef AAC_UINT32             NVBATTSTATUS;
10591 +#endif
10592 +
10593 +/*
10594 + * battery transition type
10595 + */
10596 +typedef enum _NVBATT_TRANSITION {
10597 +       NVBATT_TRANSITION_NONE = 0,     // battery now has no power or is not present
10598 +       NVBATT_TRANSITION_LOW,          // battery is now low on power
10599 +       NVBATT_TRANSITION_OK            // battery is now okay - normal operation possible only in this state
10600 +} _E_NVBATT_TRANSITION;
10601 +
10602 +#ifdef AAC_32BIT_ENUMS
10603 +typedef _E_NVBATT_TRANSITION   NVBATT_TRANSITION;
10604 +#else
10605 +typedef        AAC_UINT32                              NVBATT_TRANSITION;
10606 +#endif
10607 +
10608 +/*
10609 + * NVRAM Info structure returned for NVRAM_GetInfo call
10610 + */
10611 +typedef struct _NVRAMDEVINFO {
10612 +       AAC_UINT32              NV_Enabled;             /* write caching enabled */
10613 +       AAC_UINT32              NV_Error;               /* device in error state */
10614 +       AAC_UINT32              NV_NDirty;              /* count of dirty NVRAM buffers */
10615 +       AAC_UINT32              NV_NActive;             /* count of NVRAM buffers being written */
10616 +} NVRAMDEVINFO, *PNVRAMDEVINFO;
10617 +
10618 +typedef struct _NVRAMINFO {
10619 +       NVSTATUS                NV_Status;                              /* nvram subsystem status */
10620 +       NVBATTSTATUS    NV_BattStatus;                  /* battery status */
10621 +       AAC_UINT32              NV_Size;                                /* size of WriteCache NVRAM in bytes */
10622 +       AAC_UINT32              NV_BufSize;                             /* size of NVRAM buffers in bytes */
10623 +       AAC_UINT32              NV_NBufs;                               /* number of NVRAM buffers */
10624 +       AAC_UINT32              NV_NDirty;                              /* count of dirty NVRAM buffers */
10625 +       AAC_UINT32              NV_NClean;                              /* count of clean NVRAM buffers */
10626 +       AAC_UINT32              NV_NActive;                             /* count of NVRAM buffers being written */
10627 +       AAC_UINT32              NV_NBrokered;                   /* count of brokered NVRAM buffers */
10628 +       NVRAMDEVINFO    NV_DevInfo[NFILESYS];   /* per device info */
10629 +       AAC_UINT32              NV_BattNeedsReconditioning;     /* boolean */
10630 +       AAC_UINT32              NV_TotalSize;                   /* total size of all non-volatile memories in bytes */
10631 +} NVRAMINFO, *PNVRAMINFO;
10632 +
10633 +#endif /* !_NVRAMIOCTL_H_ */
10634 +
10635 +
10636 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/osheaders.h linux/drivers/scsi/aacraid/include/osheaders.h
10637 --- linux-2.4.7/drivers/scsi/aacraid/include/osheaders.h        Wed Dec 31 18:00:00 1969
10638 +++ linux/drivers/scsi/aacraid/include/osheaders.h      Sat Jul 21 17:55:13 2001
10639 @@ -0,0 +1,150 @@
10640 +/*++
10641 + * Adaptec aacraid device driver for Linux.
10642 + *
10643 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10644 + *
10645 + * This program is free software; you can redistribute it and/or modify
10646 + * it under the terms of the GNU General Public License as published by
10647 + * the Free Software Foundation; either version 2, or (at your option)
10648 + * any later version.
10649 + *
10650 + * This program is distributed in the hope that it will be useful,
10651 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10652 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10653 + * GNU General Public License for more details.
10654 + *
10655 + * You should have received a copy of the GNU General Public License
10656 + * along with this program; see the file COPYING.  If not, write to
10657 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10658 + *
10659 + * Module Name:
10660 + *   osheaders.h
10661 + *
10662 + * Abstract: Holds all of the header file includes for a particular O/S flavor.
10663 + *
10664 + --*/
10665 +#ifndef _OSHEADERS_H_
10666 +#define _OSHEADERS_H_
10667 +
10668 +static char *ident_oshead = "aacraid_ident osheaders.h 1.0.6 2000/10/09 Adaptec, Inc.";
10669 +
10670 +#include <linux/autoconf.h>    // retrieve the kernel configuration info
10671 +#if defined( CONFIG_MODVERSIONS ) && !defined( MODVERSIONS )
10672 +#define MODVERSIONS    // force it on
10673 +#endif
10674 +
10675 +#include <linux/version.h>
10676 +
10677 +#if defined( MODVERSIONS ) && defined( MODULE )
10678 +#if DRIVER_KERNEL_CODE >= KERNEL_VERSION(2,2,12)
10679 +#ifdef CONFIG_SMP
10680 +#include <linux/modversions-smp.h>
10681 +#elif defined( BOOT_DRIVER ) 
10682 +#include <linux/modversions-BOOT.h>
10683 +#else 
10684 +#include <linux/modversions-up.h>
10685 +#endif // ifdef CONFIG_SMP
10686 +#else
10687 +#include <linux/modversions.h>
10688 +#endif
10689 +#endif
10690 +
10691 +
10692 +#include <linux/kernel.h>
10693 +#include <linux/config.h>
10694 +#include <linux/init.h>
10695 +#include <linux/types.h>
10696 +#include <linux/blk.h>
10697 +#include <linux/blkdev.h>
10698 +#include <linux/delay.h>
10699 +#include <linux/ioport.h>
10700 +#include <linux/mm.h>
10701 +#include <linux/sched.h>
10702 +#include <linux/stat.h>
10703 +#include <linux/pci.h>
10704 +#include <linux/interrupt.h>
10705 +#include <asm/dma.h>
10706 +#include <asm/io.h>
10707 +#include <linux/spinlock.h>
10708 +#include <asm/system.h>
10709 +#include <asm/bitops.h>
10710 +#include <asm/uaccess.h>
10711 +#include <linux/wait.h>
10712 +#include <linux/malloc.h>
10713 +#include <linux/tqueue.h>
10714 +/* bmb fix
10715 +#include <linux/tasks.h>
10716 +*/
10717 +#include <ostypes.h>
10718 +#include "scsi.h"
10719 +#include "hosts.h"
10720 +
10721 +#ifndef intptr_t
10722 +#define intptr_t void *
10723 +#endif
10724 +
10725 +#ifndef cred_t
10726 +#define cred_t void
10727 +#endif
10728 +
10729 +#ifndef paddr32_t
10730 +#define paddr32_t unsigned
10731 +#endif
10732 +
10733 +#ifndef bzero 
10734 +#define bzero(b,len) memset(b,0,len)
10735 +#endif
10736 +
10737 +#ifndef bcopy
10738 +#define bcopy(src,dst,len) memcpy(dst,src,len )
10739 +#endif
10740 +
10741 +#ifndef DEVICE_NR
10742 +#define DEVICE_NR(device) ( ( ( MAJOR( device ) & 7 ) << 4 ) + ( MINOR( device ) >> 4 ) )
10743 +#endif
10744 +
10745 +typedef unsigned uint_t;
10746 +
10747 +typedef enum
10748 +{
10749 +       CE_PANIC = 0,
10750 +       CE_WARN,
10751 +       CE_NOTE, 
10752 +       CE_CONT, 
10753 +       CE_DEBUG,
10754 +       CE_DEBUG2,
10755 +       CE_TAIL
10756 +} CE_ENUM_T;
10757 +
10758 +#define CMN_ERR_LEVEL CE_NOTE
10759 +
10760 +#ifndef IN
10761 +#define IN
10762 +#endif
10763 +
10764 +// usage of READ & WRITE as a typedefs in protocol.h
10765 +// conflicts with <linux/fs.h> definition.
10766 +#ifdef READ
10767 +#undef READ
10768 +#endif
10769 +
10770 +#ifdef WRITE
10771 +#undef WRITE
10772 +#endif
10773 +
10774 +typedef struct aac_options
10775 +{
10776 +       int message_level;
10777 +       int reverse_scan; 
10778 +} aac_options_t;
10779 +
10780 +#endif // _OSHEADERS_H_
10781 +
10782 +
10783 +
10784 +
10785 +
10786 +
10787 +
10788 +
10789 +
10790 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/ostypes.h linux/drivers/scsi/aacraid/include/ostypes.h
10791 --- linux-2.4.7/drivers/scsi/aacraid/include/ostypes.h  Wed Dec 31 18:00:00 1969
10792 +++ linux/drivers/scsi/aacraid/include/ostypes.h        Sat Jul 21 17:55:13 2001
10793 @@ -0,0 +1,149 @@
10794 +/*++
10795 + * Adaptec aacraid device driver for Linux.
10796 + *
10797 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10798 + *
10799 + * This program is free software; you can redistribute it and/or modify
10800 + * it under the terms of the GNU General Public License as published by
10801 + * the Free Software Foundation; either version 2, or (at your option)
10802 + * any later version.
10803 + *
10804 + * This program is distributed in the hope that it will be useful,
10805 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10806 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10807 + * GNU General Public License for more details.
10808 + *
10809 + * You should have received a copy of the GNU General Public License
10810 + * along with this program; see the file COPYING.  If not, write to
10811 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10812 + *
10813 + * Module Name:
10814 + *   ostypes.h
10815 + *
10816 + * Abstract: Holds all of the O/S specific types.
10817 + *
10818 + --*/
10819 +/*------------------------------------------------------------------------------
10820 + *              D E F I N E S
10821 + *----------------------------------------------------------------------------*/
10822 +#ifndef _OSTYPES_H_
10823 +#define _OSTYPES_H_
10824 +
10825 +static char *ident_ostypes = "aacraid_ident ostypes.h 1.0.7 2000/10/11 Adaptec, Inc.";
10826 +
10827 +#include <linux/types.h>
10828 +
10829 +#define MAXIMUM_NUM_CONTAINERS 64              // 4 Luns * 16 Targets
10830 +#define MAXIMUM_NUM_ADAPTERS   8
10831 +
10832 +#define OS_ALLOC_MEM_SLEEP             GFP_KERNEL
10833 +
10834 +#define Os_remove_softintr OsSoftInterruptRemove
10835 +#define OsPrintf printk
10836 +#define FsaCommPrint
10837 +
10838 +// the return values for copy_from_user & copy_to_user is the 
10839 +// number of bytes not transferred. Thus if an internal error 
10840 +// occurs, the return value is greater than zero.
10841 +#define COPYIN(SRC,DST,COUNT,FLAGS)  copy_from_user(DST,SRC,COUNT)
10842 +#define COPYOUT(SRC,DST,COUNT,FLAGS) copy_to_user(DST,SRC,COUNT)
10843 +
10844 +#define copyin(SRC,DST,COUNT) copy_from_user(DST,SRC,COUNT)
10845 +#define copyout(SRC,DST,COUNT) copy_to_user(DST,SRC,COUNT)
10846 +
10847 +/*------------------------------------------------------------------------------
10848 + *              S T R U C T S / T Y P E D E F S
10849 + *----------------------------------------------------------------------------*/
10850 +typedef struct OS_MUTEX
10851 +{
10852 +       unsigned long lock_var;
10853 +       wait_queue_head_t wq;
10854 +       unsigned owner;
10855 +} OS_MUTEX;
10856 +
10857 +typedef        struct OS_SPINLOCK
10858 +{
10859 +       spinlock_t      spin_lock;
10860 +       unsigned cpu_lock_count[NR_CPUS];
10861 +       unsigned long cpu_flags[NR_CPUS];
10862 +       long lockout_count;
10863 +} OS_SPINLOCK;
10864 +
10865 +#ifdef CVLOCK_USE_SPINLOCK
10866 +       typedef OS_SPINLOCK OS_CVLOCK;
10867 +#else
10868 +       typedef OS_MUTEX OS_CVLOCK;
10869 +#endif
10870 +
10871 +typedef size_t         OS_SIZE_T;
10872 +
10873 +typedef        struct OS_CV_T
10874 +{
10875 +       unsigned long lock_var;
10876 +       unsigned long type;
10877 +       wait_queue_head_t wq;   
10878 +} OS_CV_T;
10879 +
10880 +struct fsa_scsi_hba {
10881 +       void                            *CommonExtension;
10882 +       unsigned long           ContainerSize[MAXIMUM_NUM_CONTAINERS];
10883 +       unsigned long           ContainerType[MAXIMUM_NUM_CONTAINERS];
10884 +       unsigned char           ContainerValid[MAXIMUM_NUM_CONTAINERS];
10885 +       unsigned char           ContainerReadOnly[MAXIMUM_NUM_CONTAINERS];
10886 +       unsigned char           ContainerLocked[MAXIMUM_NUM_CONTAINERS];
10887 +       unsigned char           ContainerDeleted[MAXIMUM_NUM_CONTAINERS];
10888 +       long                            ContainerDevNo[MAXIMUM_NUM_CONTAINERS];
10889 +};
10890 +
10891 +typedef struct fsa_scsi_hba fsadev_t;
10892 +
10893 +typedef struct OsKI
10894 +{
10895 +       struct Scsi_Host *scsi_host_ptr;
10896 +       void * dip;     // #REVISIT#
10897 +       fsadev_t fsa_dev;
10898 +       int thread_pid;
10899 +  int    MiniPortIndex;
10900 +} OsKI_t;
10901 +
10902 +#define dev_info_t     fsadev_t
10903 +
10904 +typedef int    OS_SPINLOCK_COOKIE;
10905 +
10906 +typedef unsigned int   OS_STATUS;
10907 +
10908 +typedef struct tq_struct OS_SOFTINTR;
10909 +
10910 +typedef        OS_SOFTINTR     *ddi_softintr_t;
10911 +
10912 +
10913 +
10914 +//-----------------------------------------------------------------------------
10915 +// Conditional variable functions
10916 +
10917 +void OsCv_init ( 
10918 +       OS_CV_T *cv_ptr );
10919 +
10920 +
10921 +//-----------------------------------------------------------------------------
10922 +// Printing functions
10923 +void printk_err(int flag, char *fmt, ...);
10924 +
10925 +#define cmn_err printk_err
10926 +
10927 +
10928 +//
10929 +// just ignore these solaris ddi functions in the code
10930 +//
10931 +#define DDI_SUCCESS                                            0
10932 +
10933 +#define ddi_add_softintr(A,B,C,D,E,F,G)                OsSoftInterruptAdd(C,F,G)
10934 +
10935 +//#REVIEW#
10936 +#define ddi_remove_softintr(A)                         0
10937 +#define ddi_get_soft_iblock_cookie(A, B, C)    0
10938 +
10939 +#define ASSERT(expr) ((void) 0)
10940 +#define drv_usecwait udelay
10941 +
10942 +#endif // _OSTYPES_H_
10943 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/pcisup.h linux/drivers/scsi/aacraid/include/pcisup.h
10944 --- linux-2.4.7/drivers/scsi/aacraid/include/pcisup.h   Wed Dec 31 18:00:00 1969
10945 +++ linux/drivers/scsi/aacraid/include/pcisup.h Sat Jul 21 17:55:13 2001
10946 @@ -0,0 +1,97 @@
10947 +/*++
10948 + * Adaptec aacraid device driver for Linux.
10949 + *
10950 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10951 + *
10952 + * This program is free software; you can redistribute it and/or modify
10953 + * it under the terms of the GNU General Public License as published by
10954 + * the Free Software Foundation; either version 2, or (at your option)
10955 + * any later version.
10956 + *
10957 + * This program is distributed in the hope that it will be useful,
10958 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10959 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10960 + * GNU General Public License for more details.
10961 + *
10962 + * You should have received a copy of the GNU General Public License
10963 + * along with this program; see the file COPYING.  If not, write to
10964 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10965 + *
10966 + * Module Name:
10967 + *   pcisup.h
10968 + *
10969 + * Abstract: This module defines functions that are defined in PciSup.c
10970 + *
10971 + --*/
10972 +#ifndef _PCISUP_
10973 +#define _PCISUP_
10974 +
10975 +static char *ident_pcisup = "aacraid_ident pcisup.h 1.0.6 2000/10/09 Adaptec, Inc.";
10976 +
10977 +       
10978 +/*
10979 + * define which interrupt handler needs to be installed
10980 + */
10981 +
10982 +#define SaISR  1
10983 +#define RxISR  2
10984 +
10985 +typedef struct _PCI_MINIPORT_COMMON_EXTENSION {
10986 +       ULONG                                   AdapterNumber;                  // Which FSA# this miniport is
10987 +       
10988 +       ULONG                                   PciBusNumber;                   // Which PCI bus we are located on
10989 +       ULONG                                   PciSlotNumber;                  // Whiat PCI slot we are in
10990 +       
10991 +       PVOID                                   Adapter;                                // Back pointer to Fsa adapter object
10992 +       ULONG                                   AdapterIndex;                   // Index into PlxAdapterTypes array
10993 +       PDEVICE_OBJECT                  DeviceObject;                   // Pointer to our device object
10994 +       
10995 +       FSAPORT_FUNCS                   AdapterFuncs;
10996 +       ULONG                                   FilesystemRevision;     // Main driver's revision number
10997 +       
10998 +       
10999 +       PADAPTER_INIT_STRUCT    InitStruct;                             // Holds initialization info to communicate with adapter
11000 +       PVOID                                   PhysicalInitStruct;     // Holds physical address of the init struct
11001 +       
11002 +       
11003 +       PVOID                                   PrintfBufferAddress;    // pointer to buffer used for printf's from the adapter
11004 +       
11005 +       BOOLEAN                                 AdapterPrintfsToScreen;                 
11006 +       BOOLEAN                                 AdapterConfigured;              // set to true when we know adapter can take FIBs
11007 +       
11008 +       void *                                  MiniPort;
11009 +       
11010 +       caddr_t                                 CommAddress;    // Base address of Comm area
11011 +       paddr32_t                               CommPhysAddr;   // Physical Address of Comm area
11012 +       size_t                                  CommSize;
11013 +
11014 +       OsKI_t                                  OsDep;                  // OS dependent kernel interfaces
11015 +
11016 +       
11017 +} PCI_MINIPORT_COMMON_EXTENSION;
11018 +
11019 +typedef PCI_MINIPORT_COMMON_EXTENSION *PPCI_MINIPORT_COMMON_EXTENSION;
11020 +
11021 +typedef int
11022 +(*PFSA_MINIPORT_INIT) (
11023 +       IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
11024 +       IN ULONG AdapterNumber,
11025 +       IN ULONG PciBus,
11026 +       IN ULONG PciSlot
11027 +       );
11028 +
11029 +typedef struct _FSA_MINIPORT {
11030 +       USHORT                          VendorId;
11031 +       USHORT                          DeviceId;
11032 +       USHORT                          SubVendorId;
11033 +       USHORT                          SubSystemId;
11034 +       PCHAR                           DevicePrefix;
11035 +  PFSA_MINIPORT_INIT   InitRoutine;
11036 +  PCHAR               DeviceName;
11037 +  PCHAR               Vendor;
11038 +  PCHAR               Model;
11039 +} FSA_MINIPORT;
11040 +typedef FSA_MINIPORT *PFSA_MINIPORT;
11041 +
11042 +
11043 +#endif // _PCISUP_
11044 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/perfpack.h linux/drivers/scsi/aacraid/include/perfpack.h
11045 --- linux-2.4.7/drivers/scsi/aacraid/include/perfpack.h Wed Dec 31 18:00:00 1969
11046 +++ linux/drivers/scsi/aacraid/include/perfpack.h       Sat Jul 21 17:55:13 2001
11047 @@ -0,0 +1,110 @@
11048 +/*++
11049 + * Adaptec aacraid device driver for Linux.
11050 + *
11051 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11052 + *
11053 + * This program is free software; you can redistribute it and/or modify
11054 + * it under the terms of the GNU General Public License as published by
11055 + * the Free Software Foundation; either version 2, or (at your option)
11056 + * any later version.
11057 + *
11058 + * This program is distributed in the hope that it will be useful,
11059 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11060 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11061 + * GNU General Public License for more details.
11062 + *
11063 + * You should have received a copy of the GNU General Public License
11064 + * along with this program; see the file COPYING.  If not, write to
11065 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11066 + *
11067 + * Module Name:
11068 + *   perfpack.h
11069 + *
11070 + * Abstract: This file defines the layout of the performance data that is passed
11071 + *           back from the FSA filesystem driver.
11072 + *
11073 + *     
11074 + --*/
11075 +
11076 +#ifndef _FSA_PERFPACK_H_
11077 +#define _FSA_PERFPACK_H_       1
11078 +
11079 +static char *ident_perf = "aacraid_ident perfpack.h 1.0.6 2000/10/09 Adaptec, Inc.";
11080 +
11081 +//#define FSA_DO_PERF          1               /* enable the engineering counters */
11082 +
11083 +#ifdef FSA_DO_PERF
11084 +//
11085 +// engineering counters
11086 +//
11087 +typedef struct _FSA_PERF_DATA {
11088 +                       ULONG FibsSent;
11089 +                       ULONG ReadDirs;
11090 +                       ULONG GetAttrs;
11091 +                       ULONG SetAttrs;
11092 +                       ULONG Lookups;
11093 +                       ULONG ReadFibs;
11094 +                       ULONG WriteFibs;
11095 +                       ULONG CreateFibs;
11096 +                       ULONG MakeDirs;
11097 +                       ULONG RemoveFibs;
11098 +                       ULONG RemoveDirs;
11099 +                       ULONG RenameFibs;
11100 +                       ULONG ReadDirPlus;
11101 +                       ULONG FsStat;
11102 +                       ULONG WriteBytes;
11103 +                       ULONG ReadBytes;
11104 +// NT FSA entry points
11105 +                       ULONG FsaFsdCreateCount;
11106 +                       ULONG FsaFsdCloseCount;
11107 +                       ULONG FsaFsdReadCount;
11108 +                       ULONG FsaFsdWriteCount;
11109 +                       ULONG FsaFsdQueryInformationCount;
11110 +
11111 +                       struct _FsaFsdSetInfomation{
11112 +                               ULONG FsaSetAllocationInfoCount;
11113 +                               ULONG FsaSetBasicInfoCount;
11114 +                               ULONG FsaSetDispositionInfoCount;
11115 +                               ULONG FsaSetEndOfFileInfoCount;
11116 +                               ULONG FsaSetPositionInfoCount;
11117 +                               ULONG FsaSetRenameInfoCount;
11118 +                               ULONG FsaClearArchiveBitCount;
11119 +                       };
11120 +
11121 +                       ULONG FsaFsdFlushBuffersCount;
11122 +                       ULONG FsaFsdQueryVolumeInfoCount;
11123 +                       ULONG FsaFsdSetVolumeInfoCount;
11124 +                       ULONG FsaFsdCleanupCount;
11125 +                       ULONG FsaFsdDirectoryControlCount;
11126 +                       ULONG FsaFsdFileSystemControlCount;
11127 +                       ULONG FsaFsdLockControlCount;
11128 +                       ULONG FsaFsdDeviceControlCount;
11129 +                       ULONG FsaFsdShutdownCount;
11130 +                       ULONG FsaFsdQuerySecurityInfo;
11131 +                       ULONG FsaFsdSetSecurityInfo;
11132 +                       ULONG FastIoCheckIfPossibleCount;
11133 +                       ULONG FastIoReadCount;
11134 +                       ULONG FastIoWriteCount;
11135 +                       ULONG FastIoQueryBasicInfoCount;
11136 +                       ULONG FastIoQueryStandardInfoCount;
11137 +                       ULONG FastIoLockCount;
11138 +                       ULONG FastIoUnlockSingleCount;
11139 +                       ULONG FastIoUnlockAllCount;
11140 +                       ULONG FastIoUnlockAllByKeyCount;
11141 +                       ULONG FastIoDeviceControlCount;
11142 + } FSA_PERF_DATA;
11143 +
11144 +typedef FSA_PERF_DATA *PFSA_PERF_DATA;
11145 +
11146 +
11147 +#else /* FSA_DO_PERF */
11148 +
11149 +//
11150 +// engineering performance counters are disabled
11151 +//
11152 +#define FSA_DO_PERF_INC(Counter)               /* */
11153 +#define FSA_DO_FSP_PERF_INC(Counter)   /* */
11154 +
11155 +#endif /* FSA_DO_PERF */
11156 +
11157 +#endif // _FSA_PERFPACK_H_
11158 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/port.h linux/drivers/scsi/aacraid/include/port.h
11159 --- linux-2.4.7/drivers/scsi/aacraid/include/port.h     Wed Dec 31 18:00:00 1969
11160 +++ linux/drivers/scsi/aacraid/include/port.h   Sat Jul 21 17:55:13 2001
11161 @@ -0,0 +1,87 @@
11162 +/*++
11163 + * Adaptec aacraid device driver for Linux.
11164 + *
11165 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11166 + *
11167 + * This program is free software; you can redistribute it and/or modify
11168 + * it under the terms of the GNU General Public License as published by
11169 + * the Free Software Foundation; either version 2, or (at your option)
11170 + * any later version.
11171 + *
11172 + * This program is distributed in the hope that it will be useful,
11173 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11174 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11175 + * GNU General Public License for more details.
11176 + *
11177 + * You should have received a copy of the GNU General Public License
11178 + * along with this program; see the file COPYING.  If not, write to
11179 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11180 + *
11181 + * Module Name:
11182 + *   port.h
11183 + *
11184 + * Abstract: This module defines functions and structures that are in common among all miniports
11185 + *
11186 + *     
11187 + --*/
11188 +
11189 +#ifndef _PORT_
11190 +#define _PORT_
11191 +
11192 +static char *ident_porth = "aacraid_ident port.h 1.0.6 2000/10/09 Adaptec, Inc.";
11193 +
11194 +#ifdef DBG
11195 +#define AfaPortPrint if (AfaPortPrinting) DbgPrint
11196 +extern int AfaPortPrinting;
11197 +#else
11198 +#define AfaPortPrint 
11199 +#endif DBG
11200 +
11201 +extern int AfaPortPrinting;
11202 +
11203 +
11204 +BOOLEAN
11205 +AfaPortAllocateAdapterCommArea(
11206 +       IN PVOID                Arg1,
11207 +       IN OUT PVOID    *CommHeaderAddress,
11208 +       IN ULONG                CommAreaSize,
11209 +       IN ULONG                CommAreaAlignment
11210 +       );
11211 +
11212 +
11213 +BOOLEAN
11214 +AfaPortFreeAdapterCommArea(
11215 +       IN PVOID                Arg1
11216 +       );
11217 +
11218 +
11219 +AAC_STATUS
11220 +AfaPortBuildSgMap(
11221 +       PVOID Arg1,
11222 +       IN PSGMAP_CONTEXT SgMapContext
11223 +       );
11224 +
11225 +
11226 +VOID
11227 +AfaPortFreeDmaResources(
11228 +       PVOID Arg1,
11229 +    IN PSGMAP_CONTEXT SgMapContext
11230 +    );
11231 +
11232 +
11233 +BOOLEAN
11234 +AfaPortAllocateAndMapFibSpace(
11235 +       PVOID Arg1,
11236 +    IN PMAPFIB_CONTEXT MapFibContext
11237 +    );
11238 +
11239 +
11240 +BOOLEAN
11241 +AfaPortUnmapAndFreeFibSpace(
11242 +       PVOID Arg1,
11243 +    IN PMAPFIB_CONTEXT MapFibContext
11244 +    );
11245 +
11246 +
11247 +#endif // _PORT_
11248 +
11249 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/protocol.h linux/drivers/scsi/aacraid/include/protocol.h
11250 --- linux-2.4.7/drivers/scsi/aacraid/include/protocol.h Wed Dec 31 18:00:00 1969
11251 +++ linux/drivers/scsi/aacraid/include/protocol.h       Sat Jul 21 17:55:13 2001
11252 @@ -0,0 +1,249 @@
11253 +/*++
11254 + * Adaptec aacraid device driver for Linux.
11255 + *
11256 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11257 + *
11258 + * This program is free software; you can redistribute it and/or modify
11259 + * it under the terms of the GNU General Public License as published by
11260 + * the Free Software Foundation; either version 2, or (at your option)
11261 + * any later version.
11262 + *
11263 + * This program is distributed in the hope that it will be useful,
11264 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11265 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11266 + * GNU General Public License for more details.
11267 + *
11268 + * You should have received a copy of the GNU General Public License
11269 + * along with this program; see the file COPYING.  If not, write to
11270 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11271 + *
11272 + * Module Name:
11273 + *   protocol.h
11274 + *
11275 + * Abstract: Defines the commands and command data which enables the nt
11276 + *    filesystem driver to be the client of the fsa adapter
11277 + *    filesystem. This protocol is largely modeled after the NFS
11278 + *    V3 protocol with modifications allowed due to the unique
11279 + *    client/server model FSA works under.
11280 + *
11281 + *
11282 + *     
11283 + --*/
11284 +
11285 +#ifndef _PROTOCOL_H_
11286 +#define _PROTOCOL_H_
11287 +
11288 +static char *ident_protocol = "aacraid_ident protocol.h 1.0.6 2000/10/09 Adaptec, Inc.";
11289 +
11290 +#include <fsafs.h>      // definition of FSAFID; includes fsatypes.h
11291 +#include <nvramioctl.h> // for NVRAMINFO definition
11292 +
11293 +// #define MDL_READ_WRITE
11294 +
11295 +//
11296 +// Define the command values
11297 +//
11298 +typedef enum _FSA_COMMANDS {
11299 +        Null = 0,
11300 +        GetAttributes,
11301 +        SetAttributes,
11302 +        Lookup,
11303 +        ReadLink,
11304 +        Read,
11305 +        Write,
11306 +        Create,
11307 +        MakeDirectory,
11308 +        SymbolicLink,
11309 +        MakeNode,
11310 +        Removex,
11311 +        RemoveDirectoryx, // bkpfix added x to this because already defined in nt
11312 +        Rename,
11313 +        Link,
11314 +        ReadDirectory,
11315 +        ReadDirectoryPlus,
11316 +        FileSystemStatus,
11317 +        FileSystemInfo,
11318 +        PathConfigure,
11319 +        Commit,
11320 +        Mount,
11321 +        UnMount,
11322 +        Newfs,
11323 +        FsCheck,
11324 +        FsSync,
11325 +               SimReadWrite,
11326 +               SetFileSystemStatus,
11327 +               BlockRead,
11328 +               BlockWrite,
11329 +               NvramIoctl,
11330 +               FsSyncWait,
11331 +               ClearArchiveBit,
11332 +#ifdef MDL_READ_WRITE
11333 +               MdlReadComplete,
11334 +               MdlWriteComplete,
11335 +               MdlRead,                        // these are used solely for stats, Mdl really controlled by 
11336 +               MdlWrite,                       // flags field in Fib.
11337 +#endif
11338 +               SetAcl,
11339 +               GetAcl,
11340 +               AssignAcl,
11341 +               FaultInsertion,         // Fault Insertion Command
11342 +               CrazyCache,                     // crazycache
11343 +               MAX_FSACOMMAND_NUM      //CJ: used for sizing stats array - leave last
11344 +} _E_FSACOMMAND;
11345 +
11346 +#ifdef AAC_32BIT_ENUMS
11347 +typedef        _E_FSACOMMAND   FSACOMMAND;
11348 +#else
11349 +typedef AAC_UINT32             FSACOMMAND;
11350 +#endif
11351 +
11352 +
11353 +
11354 +//
11355 +// Define the status returns
11356 +//
11357 +// See include\comm\errno.h for adapter kernel errno's
11358 +typedef enum _FSASTATUS {
11359 +       ST_OK = 0,
11360 +       ST_PERM = 1,
11361 +       ST_NOENT = 2,
11362 +       ST_IO = 5,
11363 +       ST_NXIO = 6,
11364 +       ST_E2BIG = 7,
11365 +       ST_ACCES = 13,
11366 +       ST_EXIST = 17,
11367 +       ST_XDEV = 18,
11368 +       ST_NODEV = 19,
11369 +       ST_NOTDIR = 20,
11370 +       ST_ISDIR = 21,
11371 +       ST_INVAL = 22,
11372 +       ST_FBIG = 27,
11373 +       ST_NOSPC = 28,
11374 +       ST_ROFS = 30,
11375 +       ST_MLINK = 31,
11376 +       ST_WOULDBLOCK = 35,
11377 +       ST_NAMETOOLONG = 63,
11378 +       ST_NOTEMPTY = 66,
11379 +       ST_DQUOT = 69,
11380 +       ST_STALE = 70,
11381 +       ST_REMOTE = 71,
11382 +       ST_BADHANDLE = 10001,
11383 +       ST_NOT_SYNC = 10002,
11384 +       ST_BAD_COOKIE = 10003,
11385 +       ST_NOTSUPP = 10004,
11386 +       ST_TOOSMALL = 10005,
11387 +       ST_SERVERFAULT = 10006,
11388 +       ST_BADTYPE = 10007,
11389 +       ST_JUKEBOX = 10008,
11390 +       ST_NOTMOUNTED = 10009,
11391 +       ST_MAINTMODE = 10010,
11392 +       ST_STALEACL = 10011
11393 +} _E_FSASTATUS;
11394 +
11395 +#ifdef AAC_32BIT_ENUMS
11396 +typedef _E_FSASTATUS   FSASTATUS;
11397 +#else
11398 +typedef        AAC_UINT32              FSASTATUS;
11399 +#endif
11400 +
11401 +//
11402 +// On writes how does the client want the data written.
11403 +//
11404 +
11405 +typedef enum _CACHELEVEL {
11406 +       CSTABLE = 1,
11407 +    CUNSTABLE
11408 +} _E_CACHELEVEL;
11409 +
11410 +#ifdef AAC_32BIT_ENUMS
11411 +typedef _E_CACHELEVEL  CACHELEVEL;
11412 +#else
11413 +typedef        AAC_UINT32              CACHELEVEL;
11414 +#endif
11415 +
11416 +//
11417 +// Lets the client know at which level the data was commited on a write request
11418 +//
11419 +
11420 +typedef enum _COMMITLEVEL {
11421 +    CMFILE_SYNCH_NVRAM = 1,
11422 +    CMDATA_SYNCH_NVRAM,
11423 +    CMFILE_SYNCH,
11424 +    CMDATA_SYNCH,
11425 +    CMUNSTABLE
11426 +} _E_COMMITLEVEL;
11427 +
11428 +#ifdef AAC_32BIT_ENUMS
11429 +typedef _E_COMMITLEVEL COMMITLEVEL;
11430 +#else
11431 +typedef AAC_UINT32             COMMITLEVEL;
11432 +#endif
11433 +
11434 +
11435 +
11436 +//
11437 +// The following are all the different commands or FIBs which can be sent to the
11438 +// FSA filesystem. We will define a required subset which cannot return STATUS_NOT_IMPLEMENTED,
11439 +// but others outside that subset are allowed to return not implemented. The client is then
11440 +// responsible for dealing with the fact it is not implemented.
11441 +//
11442 +typedef AAC_INT8 FSASTRING[16];
11443 +
11444 +
11445 +typedef AAC_UINT32     BYTECOUNT;      // only 32 bit-ism
11446 +
11447 +
11448 +
11449 +//
11450 +// BlockRead
11451 +//
11452 +
11453 +typedef struct _BLOCKREAD { // variable size struct
11454 +
11455 +    FSACOMMAND                 Command;
11456 +    AAC_UINT32                 ContainerId;
11457 +    BYTECOUNT          BlockNumber;
11458 +    BYTECOUNT          ByteCount;
11459 +       SGMAP                   SgMap;  // Must be last in struct because it is variable
11460 +
11461 +} BLOCKREAD;
11462 +typedef BLOCKREAD *PBLOCKREAD;
11463 +
11464 +typedef struct _BLOCKREADRESPONSE {
11465 +
11466 +    FSASTATUS          Status;
11467 +    BYTECOUNT          ByteCount;
11468 +
11469 +} BLOCKREADRESPONSE;
11470 +typedef BLOCKREADRESPONSE *PBLOCKREADRESPONSE;
11471 +
11472 +//
11473 +// BlockWrite
11474 +//
11475 +
11476 +typedef struct _BLOCKWRITE {   // variable size struct
11477 +
11478 +    FSACOMMAND                 Command;
11479 +    AAC_UINT32                 ContainerId;
11480 +    BYTECOUNT          BlockNumber;
11481 +    BYTECOUNT          ByteCount;
11482 +    CACHELEVEL                 Stable;
11483 +       SGMAP                   SgMap;  // Must be last in struct because it is variable
11484 +
11485 +} BLOCKWRITE;
11486 +typedef BLOCKWRITE *PBLOCKWRITE;
11487 +
11488 +
11489 +typedef struct _BLOCKWRITERESPONSE {
11490 +
11491 +    FSASTATUS          Status;
11492 +    BYTECOUNT          ByteCount;
11493 +    COMMITLEVEL        Committed;
11494 +
11495 +} BLOCKWRITERESPONSE;
11496 +typedef BLOCKWRITERESPONSE *PBLOCKWRITERESPONSE;
11497 +
11498 +
11499 +
11500 +#endif // _PROTOCOL_H_
11501 +
11502 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/revision.h linux/drivers/scsi/aacraid/include/revision.h
11503 --- linux-2.4.7/drivers/scsi/aacraid/include/revision.h Wed Dec 31 18:00:00 1969
11504 +++ linux/drivers/scsi/aacraid/include/revision.h       Sat Jul 21 17:55:13 2001
11505 @@ -0,0 +1,350 @@
11506 +/*++
11507 + * Adaptec aacraid device driver for Linux.
11508 + *
11509 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11510 + *
11511 + * This program is free software; you can redistribute it and/or modify
11512 + * it under the terms of the GNU General Public License as published by
11513 + * the Free Software Foundation; either version 2, or (at your option)
11514 + * any later version.
11515 + *
11516 + * This program is distributed in the hope that it will be useful,
11517 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11518 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11519 + * GNU General Public License for more details.
11520 + *
11521 + * You should have received a copy of the GNU General Public License
11522 + * along with this program; see the file COPYING.  If not, write to
11523 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11524 + *
11525 + * Module Name:
11526 + *   revision.h
11527 + *
11528 + * Abstract: This module contains all of the revision information for
11529 + *     the FSA product, as well as the support routines for
11530 + *     checking module compatibility.
11531 + *
11532 + *     Before editing anything in this module, make sure that
11533 + *     you read the comments. Some lines are changed automatically
11534 + *     as part of the build, and should never be changed by hand.
11535 + *
11536 + * Routines (all inlines):
11537 + *
11538 + *     RevGetBuildNumber - Retrieve current build number
11539 + *     RevGetExternalRev - Retrieve revision for external use
11540 + *     RevGetFullRevision - Retrieve full revision structure
11541 + *
11542 + *     RevCheckCompatibility - Checks compatibility base on internal table
11543 + *
11544 + *     RevCheckCompatibilityFullInfo - Check for static component
11545 + *     RevGetCompInfoTableSize - Get size for static component table
11546 + *     RevGetCompInfoTable - Get actual table to place on static component
11547 + *     RevGetBuildNumberFromInfo - Get build number for static component.
11548 + *
11549 + *
11550 + *     
11551 + --*/
11552 +
11553 +#ifndef _REVISION_H
11554 +#define _REVISION_H
11555 +
11556 +static char *ident_revision = "aacraid_ident revision.h 1.0.6 2000/10/09 Adaptec, Inc.";
11557 +
11558 +#include "version.h" // revision numbers kept separate so they can be used by resource compiler as well
11559 +
11560 +typedef int REV_BOOL;
11561 +
11562 +#define REV_TRUE 1
11563 +#define REV_FALSE 0
11564 +
11565 +//
11566 +//     Define Revision Levels for this product
11567 +//
11568 +//  IMPORTANT: Do NOT modify BUILD_NUMBER define, this is modified
11569 +//                        automatically by the build.
11570 +//
11571 +//  Version is VMAJOR.MINOR-DASH TYPE (Build BUILD_NUMBER)
11572 +//
11573 +//     IMPORTANT: Don't access these revisions directly. They can be
11574 +//                        accessed via, the RevGetXxxxx rouines.
11575 +//
11576 +
11577 +
11578 +#define REV_AS_LONGWORD \
11579 +       ((REV_MAJOR << 24) | (REV_MINOR << 16) | (REV_TYPE << 8) | (REV_DASH))
11580 +
11581 +
11582 +
11583 +#ifndef BIOS
11584 +
11585 +//
11586 +//     Enumerate the types of product levels we can have
11587 +//
11588 +enum {
11589 +       RevType_Devo=1,         // Development mode, testing all of latest
11590 +       RevType_Alpha,          // Alpha - Internal field test
11591 +       RevType_Beta,           // Beta - External field test
11592 +       RevType_Release         // Release - Retail version
11593 +};
11594 +
11595 +//
11596 +//     Define the basic structure for all revision information. Note
11597 +//     that the ordering of the components is such that they should
11598 +//     always increase. dash will be updated the most, then the version
11599 +//     type, then minor and major.
11600 +//
11601 +typedef struct {
11602 +       union {
11603 +               struct {
11604 +                       unsigned char dash;     // Dash version number
11605 +                       unsigned char type;     // Type, 1=Devo, 2=Alpha, 3=Beta, 4=Release
11606 +                       unsigned char minor;// Minor version minor
11607 +                       unsigned char major;// Major version number
11608 +               } comp;                         // Components to external viewed rev number
11609 +               unsigned long ul;       // External revision as single 32-bit value
11610 +       } external;                     // External revision number (union)
11611 +       unsigned long buildNumber; // Automatically generated build number
11612 +} FsaRevision;
11613 +
11614 +
11615 +//
11616 +//     Define simple routines to get basic revision information. The
11617 +//     definitions should never be accessed directly. These routines
11618 +//     are meant to be used to access all relevant information no matter
11619 +//     how simple.
11620 +//
11621 +static inline unsigned long RevGetBuildNumber() {return REV_BUILD_NUMBER;}
11622 +
11623 +static inline unsigned long RevGetExternalRev() {return REV_AS_LONGWORD;}
11624 +
11625 +
11626 +//
11627 +//     Enumerate different components that may have to check
11628 +//     compatibility. This list of components can be changed
11629 +//     at any time.
11630 +//
11631 +//     IMPORTANT: ONLY add to the END of this enum structure. Otherwise,
11632 +//                        incompatibilities between component rev checking will
11633 +//                        cause wrong checking results.
11634 +//
11635 +typedef enum {
11636 +       RevApplication = 1,     // Any user End application
11637 +       RevDkiCli,                      // ADAPTEC proprietary interface (knows FIBs)
11638 +       RevNetService,          // Network Service Revision (under API)
11639 +       RevApi,                         // ADAPTEC User mode API
11640 +       RevFileSysDriver,       // FSA File System Driver
11641 +       RevMiniportDriver,      // FSA File System Miniport Driver
11642 +       RevAdapterSW,           // Adapter Software (or NT Simulator)
11643 +       RevMonitor,                     // Monitor for adapter hardware (MON960 for now)
11644 +       RevRemoteApi            // The remote API.
11645 +       // ALWAYS ADD NEW COMPONENTS HERE - AT END
11646 +} RevComponent;
11647 +
11648 +//
11649 +//     Define a structure so that we can create a compatibility table.
11650 +//
11651 +typedef struct {
11652 +       RevComponent A,B;
11653 +       unsigned long BuildNumOfB_RequiredByA;
11654 +       unsigned long BuildNumOfA_RequiredByB;
11655 +} RevCompareElement;
11656 +
11657 +//
11658 +//     Now, define the table. This table should only be included once,
11659 +//     in one program. If it is linked from 2 modules, there will likely
11660 +//     be a multiply defined symbol error from the linker.
11661 +//
11662 +//     To fix this problem, REV_REFERENCE_ONLY can be defined. This will
11663 +//     allow access to the revision information table without a redefinition
11664 +//     of the tables.
11665 +//
11666 +extern const int                          RevCompareTableLength;
11667 +
11668 +extern const RevCompareElement RevCompareTable[];
11669 +
11670 +/********************************************************************\
11671 +* Routine: RevCheckCompatibility(callerComp,compB,compB_BuildNumber)
11672 +*
11673 +*      The following routine is used to check compatibility between
11674 +*      the calling component and a component that has some dependencies
11675 +*      on it. If this routine returns REV_FALSE, it is expected that the caller
11676 +*      will send an appropriate incompatibility message and stop.
11677 +*
11678 +*      This routine is only meant to check for compatibility in the
11679 +*      absolute sense. If code wishes to execute a different path based
11680 +*      on the CompB_BuildNumber, then this routine is not useful. The
11681 +*      routine RevGetBuildNumber can be used to get the calling module's
11682 +*      current build number for a comparison check.
11683 +*
11684 +*      The return value is REV_TRUE, if compatibility is possible, and REV_FALSE
11685 +*      if the components are definitely not compatible, or there is an
11686 +*      error when trying to figure it out. To be more specific:
11687 +*
11688 +*              1) REV_TRUE if component B is newer than calling component. (In this
11689 +*                 case, the revision check done by component B with respect to
11690 +*                 this component will give the real compatibility information.
11691 +*                 It is the only one with the knowledge, since this component
11692 +*                 could not look into the future.)
11693 +*              2) REV_TRUE if calling component is more recent and table shows okay
11694 +*              3) REV_FALSE if calling component more recent and table show not okay
11695 +*              4) REV_FALSE if calling component is more recent and table entry to
11696 +*                 check does not exist.
11697 +*
11698 +*      Note that the CompB_BuildNumber must be attained by the calling
11699 +*      routine through some mechanism done by the caller.
11700 +*
11701 +* Input:
11702 +*
11703 +*      callerComp - Name of component making this call
11704 +*      compB - Name of component to check compatibility with
11705 +*      compB_BuildNumber - Build number to component B
11706 +*
11707 +* Output:
11708 +*
11709 +*      None
11710 +*
11711 +* Return Value:
11712 +*
11713 +*      REV_TRUE - Component compatibility is possible, continue as usual. compB
11714 +*                 must give true compatibility information.
11715 +*      REV_FALSE - Incompatible components, notify and end
11716 +*
11717 +\********************************************************************/
11718 +static inline REV_BOOL RevCheckCompatibility(
11719 +               RevComponent callerComp,
11720 +               RevComponent compB,
11721 +               unsigned long compB_BuildNumber)
11722 +{
11723 +       int i;
11724 +       unsigned long RevForB;
11725 +
11726 +       //
11727 +       //      Compatibility check is possible, so we should continue. When
11728 +       //      compB makes this call in its own component, it will get the
11729 +       //      true compatibility information, since only it can know.
11730 +       //
11731 +       if (RevGetBuildNumber() < compB_BuildNumber) return REV_TRUE;
11732 +
11733 +       //
11734 +       //      Go through rev table. When the components are found in the
11735 +       //      same table entry, return the approprate number.
11736 +       //
11737 +       for (i=0; i<RevCompareTableLength; i++) {
11738 +               if (RevCompareTable[i].A == callerComp) {
11739 +                       if (RevCompareTable[i].B == compB) {
11740 +                               RevForB = RevCompareTable[i].BuildNumOfB_RequiredByA;
11741 +                               return (compB_BuildNumber >= RevForB);
11742 +                       }
11743 +               } else if (RevCompareTable[i].B == callerComp) {
11744 +                       if (RevCompareTable[i].A == compB) {
11745 +                               RevForB = RevCompareTable[i].BuildNumOfA_RequiredByB;
11746 +                               return (compB_BuildNumber >= RevForB);
11747 +                       }
11748 +               }
11749 +       }
11750 +
11751 +       //
11752 +       //      Uh oh! No relevant table entry was found (this should never
11753 +       //      happen).
11754 +       //
11755 +       return REV_FALSE;
11756 +}
11757 +
11758 +
11759 +//
11760 +//     Now create a structure that can be used by a FIB to check
11761 +//     compatibility.
11762 +//
11763 +typedef struct _RevCheck {
11764 +       RevComponent callingComponent;
11765 +       FsaRevision callingRevision;
11766 +} RevCheck;
11767 +
11768 +typedef struct _RevCheckResp {
11769 +       REV_BOOL possiblyCompatible;
11770 +       FsaRevision adapterSWRevision;
11771 +} RevCheckResp;
11772 +
11773 +#endif /* bios */
11774 +#endif /* _REVISION_H */
11775 +
11776 +//
11777 +//     The following allows for inclusion of revision.h in other h
11778 +//     files. when you include this file in another h file, simply
11779 +//     define REV_REFERENCE_ONLY. This will be undefined later, so that
11780 +//     the single C file inclusion in the module will be used to
11781 +//     implement the global structures.
11782 +//
11783 +#ifndef REV_REFERENCE_ONLY
11784 +#ifndef _REVISION_H_GLOBAL
11785 +#define _REVISION_H_GLOBAL
11786 +
11787 +
11788 +
11789 +//
11790 +//     The following array is the table of compatibility. This table
11791 +//     can be modified in two ways:
11792 +//
11793 +//             1) A component which has an incompatible change done to
11794 +//                it, can get a new build number.
11795 +//
11796 +//             2) A new component can be added, requiring more entries
11797 +//                to be place into this table.
11798 +//
11799 +//
11800 +//     In case (1), you must change the revision number in the appropriate
11801 +//     column, based on which component absolutely requires an upgrade.
11802 +//
11803 +//     Example: A new FIB used by the API, in build number 105
11804 +//             {RevApi,        RevAdapterSW,           100,  100}
11805 +//                     ---> would be changed to <---
11806 +//             {RevApi,        RevAdapterSW,           105,  100}
11807 +//
11808 +//     Example: A structure is changed for a FIB that only the API uses
11809 +//             {RevApi,        RevAdapterSW,           100,  100}
11810 +//                     ---> would be changed to <---
11811 +//             {RevApi,        RevAdapterSW,           105,  105}
11812 +//
11813 +//
11814 +//     In case (2), the less common case, the enumerated list of
11815 +//     components must be changed to include the new component. Then
11816 +//     entries need to be placed into this table.
11817 +//
11818 +//     Since the revisions must be communicated between the two
11819 +//     components, it is likely that you would need to put in the
11820 +//     current build number for both columns. That is the recommended
11821 +//     way to start revision test.
11822 +//
11823 +const RevCompareElement RevCompareTable[] = {
11824 +       // Component A          Component B                     MinBForA        MinAForB
11825 +       // -----------          -----------                     --------        --------
11826 +       {RevApplication,        RevApi,                         2120,           2120    },
11827 +       {RevDkiCli,             RevApi,                         2120,           2120    },
11828 +       {RevDkiCli,             RevFileSysDriver,               257,            257     },
11829 +       {RevDkiCli,             RevMiniportDriver,              257,            257     },
11830 +       {RevDkiCli,             RevAdapterSW,                   257,            257     },
11831 +       {RevApi,                RevFileSysDriver,               2120,           2120    },
11832 +       {RevApi,                RevMiniportDriver,              2120,           2120    },
11833 +       {RevApi,                RevAdapterSW,                   2120,           2120    },
11834 +       {RevApi,                RevNetService,                  2120,           2120    },
11835 +       {RevFileSysDriver,      RevMiniportDriver,              100,            100     },
11836 +       {RevFileSysDriver,      RevAdapterSW,                   257,            257     },
11837 +       {RevMiniportDriver,     RevAdapterSW,                   257,            257     },
11838 +       {RevMiniportDriver,     RevMonitor,                     100,            100     },
11839 +       {RevApi,                RevNetService,                  2120,           2120    },
11840 +       {RevApi,                RevRemoteApi,                   2120,           2120    },
11841 +       {RevNetService,         RevRemoteApi,                   2120,           2120    }
11842 +};
11843 +
11844 +const int RevCompareTableLength = sizeof(RevCompareTable)/sizeof(RevCompareElement);
11845 +
11846 +#endif /* _REVISION_H_GLOBAL */
11847 +#endif /* REV_REFERENCE_ONLY */
11848 +#undef REV_REFERENCE_ONLY
11849 +
11850 +
11851 +
11852 +
11853 +
11854 +
11855 +
11856 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/rx.h linux/drivers/scsi/aacraid/include/rx.h
11857 --- linux-2.4.7/drivers/scsi/aacraid/include/rx.h       Wed Dec 31 18:00:00 1969
11858 +++ linux/drivers/scsi/aacraid/include/rx.h     Sat Jul 21 17:55:13 2001
11859 @@ -0,0 +1,81 @@
11860 +/*++
11861 + * Adaptec aacraid device driver for Linux.
11862 + *
11863 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11864 + *
11865 + * This program is free software; you can redistribute it and/or modify
11866 + * it under the terms of the GNU General Public License as published by
11867 + * the Free Software Foundation; either version 2, or (at your option)
11868 + * any later version.
11869 + *
11870 + * This program is distributed in the hope that it will be useful,
11871 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11872 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11873 + * GNU General Public License for more details.
11874 + *
11875 + * You should have received a copy of the GNU General Public License
11876 + * along with this program; see the file COPYING.  If not, write to
11877 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11878 + *
11879 + * Module Name:
11880 + *   rx.h
11881 + *
11882 + * Abstract: Prototypes and data structures unique to the Rx based controller board.
11883 + *
11884 + *     
11885 + --*/
11886 +
11887 +static char *ident_rxh = "aacraid_ident rx.h 1.0.6 2000/10/09 Adaptec, Inc.";
11888 +
11889 +typedef struct _Rx_ADAPTER_EXTENSION {
11890 +
11891 +       //
11892 +       // The following must be first.
11893 +       //
11894 +       PPCI_MINIPORT_COMMON_EXTENSION  Common;
11895 +       struct _Rx_ADAPTER_EXTENSION    *Next;                          // Next adapter miniport structure
11896 +    USHORT                                                     LocalMaskInterruptControl;
11897 +       PRx_DEVICE_REGISTERS                    Device;
11898 +
11899 +} Rx_ADAPTER_EXTENSION;
11900 +
11901 +    
11902 +typedef Rx_ADAPTER_EXTENSION *PRx_ADAPTER_EXTENSION;
11903 +
11904 +
11905 +
11906 +#ifdef LINUX
11907 +/*
11908 + * 
11909 + */
11910 +
11911 +#define Rx_READ_UCHAR(AEP,  CSR)                       *(volatile unsigned char *)  &((AEP)->Device->CSR)
11912 +    
11913 +
11914 +
11915 +#define Rx_READ_ULONG(AEP,  CSR)                       *(volatile unsigned int *)   &((AEP)->Device->CSR)
11916 +#define Rx_WRITE_UCHAR(AEP,  CSR, Value)       *(volatile unsigned char *)  &((AEP)->Device->CSR) = (Value)
11917 +
11918 +
11919 +#define Rx_WRITE_ULONG(AEP, CSR, Value)                *(volatile unsigned int *)   &((AEP)->Device->CSR) = (Value)
11920 +
11921 +#endif /* LINUX */
11922 +
11923 +
11924 +VOID
11925 +RxInterruptAdapter(
11926 +       PVOID Arg1
11927 +       );
11928 +
11929 +VOID
11930 +RxNotifyAdapter(
11931 +       PVOID Arg1,
11932 +    IN HOST_2_ADAP_EVENT AdapterEvent
11933 +    );
11934 +
11935 +VOID
11936 +RxResetDevice(
11937 +       PVOID Arg1
11938 +       );
11939 +
11940 +
11941 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/rxcommon.h linux/drivers/scsi/aacraid/include/rxcommon.h
11942 --- linux-2.4.7/drivers/scsi/aacraid/include/rxcommon.h Wed Dec 31 18:00:00 1969
11943 +++ linux/drivers/scsi/aacraid/include/rxcommon.h       Sat Jul 21 17:55:13 2001
11944 @@ -0,0 +1,105 @@
11945 +/*++
11946 + * Adaptec aacraid device driver for Linux.
11947 + *
11948 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11949 + *
11950 + * This program is free software; you can redistribute it and/or modify
11951 + * it under the terms of the GNU General Public License as published by
11952 + * the Free Software Foundation; either version 2, or (at your option)
11953 + * any later version.
11954 + *
11955 + * This program is distributed in the hope that it will be useful,
11956 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11957 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11958 + * GNU General Public License for more details.
11959 + *
11960 + * You should have received a copy of the GNU General Public License
11961 + * along with this program; see the file COPYING.  If not, write to
11962 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11963 + *
11964 + * Module Name:
11965 + *   rxcommon.h
11966 + *
11967 + * Abstract: Structures and defines for the i960 Rx chip.
11968 + *
11969 + *     
11970 + --*/
11971 +
11972 +#ifndef _Rx_COMMON_H_
11973 +#define _Rx_COMMON_H_
11974 +
11975 +static char *ident_rxcommon = "aacraid_ident rxcommon.h 1.0.6 2000/10/09 Adaptec, Inc.";
11976 +
11977 +//
11978 +// Rx Message Unit Registers
11979 +//
11980 +
11981 +typedef volatile struct _StructRxMURegisters {
11982 +                                                                               //       Local  |   PCI*        |       Name
11983 +                                                                               //                      |               |
11984 +       unsigned        ARSR;                                   //      1300h   |       00h     |       APIC Register Select Register
11985 +       unsigned        reserved0;                              //      1304h   |       04h     |       Reserved
11986 +       unsigned        AWR;                                    //      1308h   |       08h     |       APIC Window Register
11987 +       unsigned        reserved1;                              //      130Ch   |       0Ch     |       Reserved
11988 +       unsigned        IMRx[2];                                //      1310h   |       10h     |       Inbound Message Registers
11989 +       unsigned        OMRx[2];                                //      1318h   |       18h     |       Outbound Message Registers
11990 +       unsigned        IDR;                                    //      1320h   |       20h     |       Inbound Doorbell Register
11991 +       unsigned        IISR;                                   //      1324h   |       24h     |       Inbound Interrupt Status Register
11992 +       unsigned        IIMR;                                   //      1328h   |       28h     |       Inbound Interrupt Mask Register
11993 +       unsigned        ODR;                                    //      132Ch   |       2Ch     |       Outbound Doorbell Register
11994 +       unsigned        OISR;                                   //      1330h   |       30h     |       Outbound Interrupt Status Register
11995 +       unsigned        OIMR;                                   //      1334h   |       34h     |       Outbound Interrupt Mask Register
11996 +                                                                               // * Must access trhough ATU Inbound Translation Window
11997 +
11998 +}Rx_MU_CONFIG;
11999 +typedef Rx_MU_CONFIG *PRx_MU_CONFIG;
12000 +
12001 +typedef volatile struct _Rx_Inbound {
12002 +
12003 +       unsigned        Mailbox[8];
12004 +
12005 +}Rx_Inbound;
12006 +
12007 +typedef Rx_Inbound *PRx_Inbound;
12008 +
12009 +#define        InboundMailbox0         IndexRegs.Mailbox[0]
12010 +#define        InboundMailbox1         IndexRegs.Mailbox[1]
12011 +#define        InboundMailbox2         IndexRegs.Mailbox[2]
12012 +#define        InboundMailbox3         IndexRegs.Mailbox[3]
12013 +#define        InboundMailbox4         IndexRegs.Mailbox[4]
12014 +
12015 +
12016 +
12017 +#define        INBOUNDDOORBELL_0       0x00000001
12018 +#define INBOUNDDOORBELL_1      0x00000002
12019 +#define INBOUNDDOORBELL_2      0x00000004
12020 +#define INBOUNDDOORBELL_3      0x00000008
12021 +#define INBOUNDDOORBELL_4      0x00000010
12022 +#define INBOUNDDOORBELL_5      0x00000020
12023 +#define INBOUNDDOORBELL_6      0x00000040
12024 +
12025 +
12026 +#define        OUTBOUNDDOORBELL_0      0x00000001
12027 +#define OUTBOUNDDOORBELL_1     0x00000002
12028 +#define OUTBOUNDDOORBELL_2     0x00000004
12029 +#define OUTBOUNDDOORBELL_3     0x00000008
12030 +#define OUTBOUNDDOORBELL_4     0x00000010
12031 +
12032 +
12033 +#define InboundDoorbellReg     MUnit.IDR
12034 +
12035 +#define OutboundDoorbellReg    MUnit.ODR
12036 +
12037 +
12038 +typedef struct _Rx_DEVICE_REGISTERS {
12039 +       Rx_MU_CONFIG                    MUnit;                  // 1300h - 1334h
12040 +       unsigned                                reserved1[6];   // 1338h - 134ch
12041 +       Rx_Inbound                              IndexRegs;
12042 +} Rx_DEVICE_REGISTERS;
12043 +
12044 +typedef Rx_DEVICE_REGISTERS *PRx_DEVICE_REGISTERS;
12045 +
12046 +
12047 +#endif // _Rx_COMMON_H_
12048 +
12049 +
12050 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/sap1.h linux/drivers/scsi/aacraid/include/sap1.h
12051 --- linux-2.4.7/drivers/scsi/aacraid/include/sap1.h     Wed Dec 31 18:00:00 1969
12052 +++ linux/drivers/scsi/aacraid/include/sap1.h   Sat Jul 21 17:55:14 2001
12053 @@ -0,0 +1,85 @@
12054 +/*++
12055 + * Adaptec aacraid device driver for Linux.
12056 + *
12057 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
12058 + *
12059 + * This program is free software; you can redistribute it and/or modify
12060 + * it under the terms of the GNU General Public License as published by
12061 + * the Free Software Foundation; either version 2, or (at your option)
12062 + * any later version.
12063 + *
12064 + * This program is distributed in the hope that it will be useful,
12065 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
12066 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12067 + * GNU General Public License for more details.
12068 + *
12069 + * You should have received a copy of the GNU General Public License
12070 + * along with this program; see the file COPYING.  If not, write to
12071 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
12072 + *
12073 + * Module Name:
12074 + *   sap1.h
12075 + *
12076 + * Abstract: Prototypes and data structures unique to the Strong Arm based controller board.
12077 + *
12078 + *     
12079 + --*/
12080 +#ifndef _SAP1_H_
12081 +#define _SAP1_H_
12082 +
12083 +static char *ident_sap1h = "aacraid_ident sap1.h 1.0.6 2000/10/09 Adaptec, Inc.";
12084 +
12085 +#define Sa_MINIPORT_REVISION                   1
12086 +
12087 +typedef struct _Sa_ADAPTER_EXTENSION {
12088 +
12089 +       //
12090 +       // The following must be first.
12091 +       //
12092 +       PPCI_MINIPORT_COMMON_EXTENSION  Common;
12093 +       struct _Sa_ADAPTER_EXTENSION    *Next;                  // Next adapter miniport structure
12094 +       USHORT                                                  LocalMaskInterruptControl;
12095 +       PSa_DEVICE_REGISTERS                    Device;
12096 +
12097 +} Sa_ADAPTER_EXTENSION;
12098 +
12099 +typedef Sa_ADAPTER_EXTENSION *PSa_ADAPTER_EXTENSION;
12100 +
12101
12102 +
12103 +#ifdef LINUX
12104 +/*
12105 + * 
12106 + */
12107 +
12108
12109 +#define Sa_READ_USHORT(AEP, CSR)                       *(volatile unsigned short *) &((AEP)->Device->CSR)
12110 +#define Sa_READ_ULONG(AEP,  CSR)                       *(volatile unsigned int *)   &((AEP)->Device->CSR)
12111 +
12112
12113 +#define Sa_WRITE_USHORT(AEP, CSR, Value)       *(volatile unsigned short *) &((AEP)->Device->CSR) = (Value)
12114 +#define Sa_WRITE_ULONG(AEP, CSR, Value)                *(volatile unsigned int *)   &((AEP)->Device->CSR) = (Value)
12115 +
12116 +#endif /* LINUX */
12117 +
12118
12119 +VOID
12120 +SaInterruptAdapter(
12121 +       PVOID Arg1
12122 +       );
12123 +
12124 +VOID
12125 +SaNotifyAdapter(
12126 +       PVOID Arg1,
12127 +    IN HOST_2_ADAP_EVENT AdapterEvent
12128 +    );
12129 +
12130 +VOID
12131 +SaResetDevice(
12132 +       PVOID Arg1
12133 +       );
12134 +
12135
12136 +#endif /* _SAP1_H_ */
12137 +
12138 +
12139 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/sap1common.h linux/drivers/scsi/aacraid/include/sap1common.h
12140 --- linux-2.4.7/drivers/scsi/aacraid/include/sap1common.h       Wed Dec 31 18:00:00 1969
12141 +++ linux/drivers/scsi/aacraid/include/sap1common.h     Sat Jul 21 17:55:14 2001
12142 @@ -0,0 +1,111 @@
12143 +/*++
12144 + * Adaptec aacraid device driver for Linux.
12145 + *
12146 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
12147 + *
12148 + * This program is free software; you can redistribute it and/or modify
12149 + * it under the terms of the GNU General Public License as published by
12150 + * the Free Software Foundation; either version 2, or (at your option)
12151 + * any later version.
12152 + *
12153 + * This program is distributed in the hope that it will be useful,
12154 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
12155 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12156 + * GNU General Public License for more details.
12157 + *
12158 + * You should have received a copy of the GNU General Public License
12159 + * along with this program; see the file COPYING.  If not, write to
12160 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
12161 + *
12162 + * Module Name:
12163 + *   sap1common.h
12164 + *
12165 + * Abstract: Structures and defines for the Drawbridge and StrongArm110 chip.
12166 + *     
12167 + --*/
12168 +
12169 +#ifndef _Sa_COMMON_H_
12170 +#define _Sa_COMMON_H_
12171 +
12172 +static char *ident_sap1common = "aacraid_ident sap1common.h 1.0.6 2000/10/09 Adaptec, Inc.";
12173 +
12174 +//
12175 +// SaP1 Message Unit Registers
12176 +//
12177 +
12178 +typedef volatile struct _StructSaDrawbridge_CSR_RegisterMap {
12179 +                                                                                               //       Offset |       Name
12180 +       unsigned                        reserved[10];                   //      00h-27h |   Reserved
12181 +       unsigned char           LUT_Offset;                             //              28h     |       Looup Table Offset
12182 +       unsigned char           reserved1[3];                   //      29h-2bh |       Reserved
12183 +       unsigned                        LUT_Data;                               //              2ch     |       Looup Table Data        
12184 +       unsigned                        reserved2[26];                  //      30h-97h |       Reserved
12185 +       unsigned short          PRICLEARIRQ;                    //              98h     |       Primary Clear Irq
12186 +       unsigned short          SECCLEARIRQ;                    //              9ah     |       Secondary Clear Irq
12187 +       unsigned short          PRISETIRQ;                              //              9ch     |       Primary Set Irq
12188 +       unsigned short          SECSETIRQ;                              //              9eh     |       Secondary Set Irq
12189 +       unsigned short          PRICLEARIRQMASK;                //              a0h     |       Primary Clear Irq Mask
12190 +       unsigned short          SECCLEARIRQMASK;                //              a2h     |       Secondary Clear Irq Mask
12191 +       unsigned short          PRISETIRQMASK;                  //              a4h     |       Primary Set Irq Mask
12192 +       unsigned short          SECSETIRQMASK;                  //              a6h     |       Secondary Set Irq Mask
12193 +       unsigned                        MAILBOX0;                               //              a8h     |       Scratchpad 0
12194 +       unsigned                        MAILBOX1;                               //              ach     |       Scratchpad 1
12195 +       unsigned                        MAILBOX2;                               //              b0h     |       Scratchpad 2
12196 +       unsigned                        MAILBOX3;                               //              b4h     |       Scratchpad 3
12197 +       unsigned                        MAILBOX4;                               //              b8h     |       Scratchpad 4
12198 +       unsigned                        MAILBOX5;                               //              bch     |       Scratchpad 5
12199 +       unsigned                        MAILBOX6;                               //              c0h     |       Scratchpad 6
12200 +       unsigned                        MAILBOX7;                               //              c4h     |       Scratchpad 7
12201 +
12202 +       unsigned                        ROM_Setup_Data;                 //              c8h |   Rom Setup and Data
12203 +       unsigned                        ROM_Control_Addr;               //              cch |   Rom Control and Address
12204 +
12205 +       unsigned                        reserved3[12];                  //      d0h-ffh |       reserved
12206 +       unsigned                        LUT[64];                                // 100h-1ffh|   Lookup Table Entries
12207 +
12208 +       //
12209 +       //  TO DO
12210 +       //      need to add DMA, I2O, UART, etc registers form 80h to 364h
12211 +       //
12212 +
12213 +}Sa_Drawbridge_CSR;
12214 +
12215 +typedef Sa_Drawbridge_CSR *PSa_Drawbridge_CSR;
12216 +
12217 +
12218 +#define Mailbox0       SaDbCSR.MAILBOX0
12219 +#define Mailbox1       SaDbCSR.MAILBOX1
12220 +#define Mailbox2       SaDbCSR.MAILBOX2
12221 +#define Mailbox3       SaDbCSR.MAILBOX3
12222 +#define Mailbox4       SaDbCSR.MAILBOX4
12223 +
12224 +       
12225 +#define Mailbox7       SaDbCSR.MAILBOX7
12226 +       
12227 +#define DoorbellReg_p SaDbCSR.PRISETIRQ
12228 +#define DoorbellReg_s SaDbCSR.SECSETIRQ
12229 +#define DoorbellClrReg_p SaDbCSR.PRICLEARIRQ
12230 +
12231 +
12232 +#define        DOORBELL_0      0x00000001
12233 +#define DOORBELL_1     0x00000002
12234 +#define DOORBELL_2     0x00000004
12235 +#define DOORBELL_3     0x00000008
12236 +#define DOORBELL_4     0x00000010
12237 +#define DOORBELL_5     0x00000020
12238 +#define DOORBELL_6     0x00000040
12239 +
12240 +       
12241 +#define PrintfReady                    DOORBELL_5
12242 +#define PrintfDone                     DOORBELL_5
12243 +       
12244 +typedef struct _Sa_DEVICE_REGISTERS {
12245 +       Sa_Drawbridge_CSR       SaDbCSR;                        // 98h - c4h
12246 +} Sa_DEVICE_REGISTERS;
12247 +       
12248 +typedef Sa_DEVICE_REGISTERS *PSa_DEVICE_REGISTERS;
12249 +
12250 +       
12251 +#endif // _Sa_COMMON_H_
12252 +
12253 +
12254 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/version.h linux/drivers/scsi/aacraid/include/version.h
12255 --- linux-2.4.7/drivers/scsi/aacraid/include/version.h  Wed Dec 31 18:00:00 1969
12256 +++ linux/drivers/scsi/aacraid/include/version.h        Sat Jul 21 17:55:14 2001
12257 @@ -0,0 +1,40 @@
12258 +/*++
12259 + * Adaptec aacraid device driver for Linux.
12260 + *
12261 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
12262 + *
12263 + * This program is free software; you can redistribute it and/or modify
12264 + * it under the terms of the GNU General Public License as published by
12265 + * the Free Software Foundation; either version 2, or (at your option)
12266 + * any later version.
12267 + *
12268 + * This program is distributed in the hope that it will be useful,
12269 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
12270 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12271 + * GNU General Public License for more details.
12272 + *
12273 + * You should have received a copy of the GNU General Public License
12274 + * along with this program; see the file COPYING.  If not, write to
12275 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
12276 + *
12277 + * Module Name:
12278 + *   version.h
12279 + *
12280 + * Abstract: Keeps track of build number for development purposes.
12281 + *     
12282 + --*/
12283 +#ifndef _VERSION_H_
12284 +#define _VERSION_H_
12285 +
12286 +static char *ident_version = "aacraid_ident version.h 1.0.6 2000/10/09 Adaptec, Inc.";
12287 +
12288 +#include "build_number.h"
12289 +
12290 +#define REV_MAJOR 2
12291 +#define REV_MINOR 1
12292 +#define REV_TYPE RevType_Release
12293 +#define REV_DASH 5
12294 +
12295 +#define FSA_VERSION_STRING "2.1.5.3857\0"
12296 +
12297 +#endif /* _VERSION_H_ */
12298 diff -burN linux-2.4.7/drivers/scsi/aacraid/linit.c linux/drivers/scsi/aacraid/linit.c
12299 --- linux-2.4.7/drivers/scsi/aacraid/linit.c    Wed Dec 31 18:00:00 1969
12300 +++ linux/drivers/scsi/aacraid/linit.c  Sat Jul 21 17:55:14 2001
12301 @@ -0,0 +1,1063 @@
12302 +/*++
12303 + * Adaptec aacraid device driver for Linux.
12304 + *
12305 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
12306 + *
12307 + * This program is free software; you can redistribute it and/or modify
12308 + * it under the terms of the GNU General Public License as published by
12309 + * the Free Software Foundation; either version 2, or (at your option)
12310 + * any later version.
12311 + *
12312 + * This program is distributed in the hope that it will be useful,
12313 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
12314 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12315 + * GNU General Public License for more details.
12316 + *
12317 + * You should have received a copy of the GNU General Public License
12318 + * along with this program; see the file COPYING.  If not, write to
12319 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
12320 + *
12321 + * Module Name:
12322 + *   linit.c
12323 + *
12324 + * Abstract: Linux Driver entry module for Adaptec RAID Array Controller
12325 + *                             
12326 + *     Provides the following driver entry points:
12327 + *             AAC_DetectHostAdapter()
12328 + *             AAC_ReleaseHostAdapter()
12329 + *             AAC_QueueCommand()
12330 + *             AAC_ResetCommand()
12331 + *             AAC_BIOSDiskParameters()
12332 + *     
12333 + --*/
12334 +
12335 +static char *ident_linit = "aacraid_ident linit.c 1.0.6 2000/10/09 Adaptec, Inc.";
12336 +
12337 +/*------------------------------------------------------------------------------
12338 + *              D E F I N E S
12339 + *----------------------------------------------------------------------------*/
12340 +#define AAC_DRIVER_VERSION                             "0.1.1"
12341 +#define AAC_DRIVER_BUILD_DATE                  __DATE__
12342 +#define MAX_DRIVER_QUEUE_DEPTH                 500
12343 +
12344 +/*------------------------------------------------------------------------------
12345 + *              I N C L U D E S
12346 + *----------------------------------------------------------------------------*/
12347 +#include "osheaders.h"
12348 +
12349 +#include "AacGenericTypes.h"
12350 +
12351 +#ifdef MODULE
12352 +#include <linux/module.h>
12353 +#endif
12354 +#include "sd.h"
12355 +#include "linit.h"
12356 +#include "aac_unix_defs.h"
12357 +#include "fsatypes.h"
12358 +#include "comstruc.h"
12359 +#include "fsaport.h"
12360 +#include "pcisup.h"
12361 +#include "port.h"
12362 +#include "afacomm.h"
12363 +#include "nodetype.h"
12364 +#include "comsup.h"
12365 +#include "adapter.h"
12366 +
12367 +/*------------------------------------------------------------------------------
12368 + *              G L O B A L S
12369 + *----------------------------------------------------------------------------*/
12370 +extern FSA_MINIPORT MiniPorts[];
12371 +extern int CommPrinting;
12372 +extern char DescriptionString[];
12373 +extern char devicestr[];
12374 +
12375 +/*------------------------------------------------------------------------------
12376 + *              M O D U L E   G L O B A L S
12377 + *----------------------------------------------------------------------------*/
12378 +aac_options_t g_options = { CMN_ERR_LEVEL, 0 };        // default message_level
12379 +
12380 +char g_DriverName[] = { "aacraid" };
12381 +#define module_options aacraid_options
12382 +static char * aacraid_options = NULL;
12383 +
12384 +PCI_MINIPORT_COMMON_EXTENSION *g_CommonExtensionPtrArray[ MAXIMUM_NUM_ADAPTERS ];
12385 +unsigned g_HostAdapterCount = 0;
12386 +unsigned g_chardev_major = 0;
12387 +
12388 +int g_single_command_done = FALSE;
12389 +
12390 +/*------------------------------------------------------------------------------
12391 + *              F U N C T I O N   P R O T O T Y P E S
12392 + *----------------------------------------------------------------------------*/
12393 +int AacHba_Ioctl(
12394 +       PCI_MINIPORT_COMMON_EXTENSION *CommonExtension,
12395 +       int cmd,
12396 +       void * arg );
12397 +
12398 +int AacHba_ProbeContainers( 
12399 +       PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr );
12400 +
12401 +int AacHba_DoScsiCmd(
12402 +       Scsi_Cmnd *scsi_cmnd_ptr,
12403 +       int wait );
12404 +
12405 +void AacHba_DetachAdapter(
12406 +       IN PVOID AdapterArg );
12407 +
12408 +int AacHba_ClassDriverInit(
12409 +       PCI_MINIPORT_COMMON_EXTENSION * CommonExtensionPtr);
12410 +
12411 +void AacHba_AbortScsiCommand(
12412 +       Scsi_Cmnd *scsi_cmnd_ptr );
12413 +
12414 +
12415 +/*------------------------------------------------------------------------------
12416 + *              L O C A L   F U N C T I O N   P R O T O T Y P E S
12417 + *----------------------------------------------------------------------------*/
12418 +static int parse_keyword(
12419 +       char ** str_ptr, 
12420 +       char * keyword );
12421 +
12422 +static void AAC_ParseDriverOptions( 
12423 +       char * cmnd_line_options_str );
12424 +
12425 +static void AAC_AnnounceDriver( void );
12426 +
12427 +int AAC_ChardevIoctl(
12428 +       struct inode * inode_ptr, 
12429 +       struct file * file_ptr,
12430 +       unsigned int cmd,
12431 +       unsigned long arg );
12432 +
12433 +int AAC_ChardevOpen(
12434 +       struct inode * inode_ptr,
12435 +       struct file * file_ptr );
12436 +
12437 +int AAC_ChardevRelease(
12438 +       struct inode * inode_ptr,
12439 +       struct file * file_ptr );
12440 +
12441 +struct file_operations AAC_fops = {
12442 +       NULL,               // module name
12443 +       NULL,                           // lseek
12444 +       NULL,                           // read
12445 +       NULL,                           // write
12446 +       NULL,                           // readdir
12447 +       NULL,                           // poll
12448 +       AAC_ChardevIoctl,       // ioctl
12449 +       NULL,                           // mmap
12450 +       AAC_ChardevOpen,        // open
12451 +       NULL,                           // flush
12452 +       AAC_ChardevRelease,     // release
12453 +       NULL,                           // fsync
12454 +       NULL,                           // fasync
12455 +       NULL,                           // check media change
12456 +       NULL,                           // revalidate
12457 +       NULL                            // lock
12458 +};
12459 +
12460 +/*------------------------------------------------------------------------------
12461 + *              F U N C T I O N S
12462 + *----------------------------------------------------------------------------*/
12463 +/*------------------------------------------------------------------------------
12464 +       AAC_AnnounceDriver()
12465 +
12466 +               Announce the driver name, version and date.
12467 + *----------------------------------------------------------------------------*/
12468 +static void AAC_AnnounceDriver( void ){
12469 +  printk(KERN_ALERT "%s, %s\n", 
12470 +                "aacraid raid driver version", AAC_DRIVER_BUILD_DATE );   
12471 +  schedule();
12472 +}
12473 +
12474 +
12475 +/*------------------------------------------------------------------------------
12476 +       AAC_DetectHostAdapter()
12477 +
12478 +               Probe for AAC Host Adapters initialize, register, and report the 
12479 +               configuration of each AAC Host Adapter found.
12480 +
12481 +       Preconditions:
12482 +       Postconditions:
12483 +               - Returns the number of adapters successfully initialized and 
12484 +               registered.
12485 +               - Initialize all data necessary for this particular SCSI driver.
12486 +       Notes:
12487 +               The detect routine must not call any of the mid level functions 
12488 +               to queue commands because things are not guaranteed to be set 
12489 +               up yet. The detect routine can send commands to the host adapter 
12490 +               as long as the program control will not be passed to scsi.c in 
12491 +               the processing of the command. Note especially that 
12492 +               scsi_malloc/scsi_free must not be called.
12493 + *----------------------------------------------------------------------------*/
12494 +int AAC_DetectHostAdapter (Scsi_Host_Template *HostTemplate)
12495 +{
12496 +               int index;
12497 +               int ContainerId;
12498 +               uint16_t vendor_id, device_id, sub_vendor_id, sub_system_id;
12499 +               struct Scsi_Host *host_ptr;
12500 +               PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
12501 +               struct pci_dev *dev = NULL;
12502 +               extern int NumMiniPorts;
12503 +               fsadev_t *fsa_dev_ptr;
12504 +               char *DeviceName;
12505 +
12506 +               struct pci_dev *devp;
12507 +
12508 +               int     first_index, last_index, increment;
12509 +
12510 +               CommPrinting = TRUE;
12511 +
12512 +#ifdef MODULE
12513 +               EXPORT_NO_SYMBOLS;
12514 +#endif
12515 +
12516 +               AAC_AnnounceDriver();
12517 +
12518 +               /* setting up the proc directory structure */
12519 +               HostTemplate->proc_name = "aacraid";
12520 +
12521 +               if( module_options != NULL ) AAC_ParseDriverOptions( module_options );
12522 +
12523 +               // NumMiniPorts & MiniPorts[] defined in aacid.c
12524 +               if (g_options.reverse_scan == 0) {
12525 +                               first_index = 0;
12526 +                               last_index  = NumMiniPorts;
12527 +                               increment   = 1;
12528 +               } else {
12529 +                               first_index = NumMiniPorts -1;
12530 +                               last_index  = -1;
12531 +                               increment   = -1;
12532 +               }
12533 +
12534 +               for( index = first_index; index != last_index; index += increment )
12535 +               {
12536 +                               device_id = MiniPorts[index].DeviceId;
12537 +                               vendor_id = MiniPorts[index].VendorId;
12538 +                               DeviceName = MiniPorts[index].DeviceName;
12539 +                               cmn_err(CE_DEBUG, "Checking %s %x/%x/%x/%x", 
12540 +                                               DeviceName,     vendor_id, device_id,
12541 +                                               MiniPorts[index].SubVendorId,
12542 +                                               MiniPorts[index].SubSystemId);
12543 +
12544 +
12545 +                               // pci_find_device traverses the pci_devices linked list for devices
12546 +                               // with matching vendor and device ids.
12547 +
12548 +                               dev = NULL;     // start from beginning of list
12549 +                               while( ( dev = pci_find_device( vendor_id, device_id, dev ) ) )
12550 +                               {
12551 +                                               if (pci_enable_device(dev)) continue;
12552 +                 
12553 +                                               if( pci_read_config_word( dev, PCI_SUBSYSTEM_VENDOR_ID, &sub_vendor_id ) ){
12554 +                                                               cmn_err(CE_WARN, "pci_read_config_word SUBSYS_VENDOR_ID failed");
12555 +                                                               break;
12556 +                                               }
12557 +                                               if( pci_read_config_word( dev, PCI_SUBSYSTEM_ID, &sub_system_id ) ){
12558 +                                                               cmn_err(CE_WARN, "pci_read_config_work SUBSYSTEM_ID failed");
12559 +                                                               break;
12560 +                                               }
12561 +
12562 +                                               cmn_err(CE_DEBUG, "     found: %x/%x/%x/%x", vendor_id, device_id, sub_vendor_id, sub_system_id);
12563 +                                               if( ( sub_vendor_id != MiniPorts[index].SubVendorId ) || 
12564 +                                                       ( sub_system_id != MiniPorts[index].SubSystemId ) ){
12565 +                                                               continue;
12566 +                                               }
12567 +                       
12568 +
12569 +                                               printk(KERN_ALERT "%s device detected\n", DeviceName );
12570 +                                               cmn_err(CE_DEBUG, "%x/%x/%x/%x", vendor_id, device_id, sub_vendor_id, sub_system_id);
12571 +
12572 +                                               // Increment the host adapter count
12573 +                                               g_HostAdapterCount++;
12574 +
12575 +                                               // scsi_register() allocates memory for a Scsi_Hosts structure and
12576 +                                               // links it into the linked list of host adapters. This linked list
12577 +                                               // contains the data for all possible <supported> scsi hosts.
12578 +                                               // This is similar to the Scsi_Host_Template, except that we have
12579 +                                               // one entry for each actual physical host adapter on the system,
12580 +                                               // stored as a linked list. If there are two AAC boards, then we
12581 +                                               // will need to make two Scsi_Host entries, but there will be only
12582 +                                               // one Scsi_Host_Template entry. The second argument to scsi_register()
12583 +                                               // specifies the size of the extra memory we want to hold any device 
12584 +                                               // specific information.
12585 +                                               host_ptr = scsi_register( HostTemplate, sizeof( PCI_MINIPORT_COMMON_EXTENSION ) );
12586 +
12587 +                                               // These three parameters can be used to allow for wide SCSI 
12588 +                                               // and for host adapters that support multiple buses.
12589 +                                               host_ptr->max_id = 17;
12590 +                                               host_ptr->max_lun = 8;
12591 +                                               host_ptr->max_channel = 1;
12592 +
12593 +
12594 +                                               host_ptr->irq = dev->irq;               // Adapter IRQ number
12595 +                                               /* host_ptr->base = ( char * )(dev->resource[0].start & ~0xff); */
12596 +                                               host_ptr->base = ( char * )(dev->resource[0].start);
12597 +                                               scsi_set_pci_device(host_ptr, dev);
12598 +
12599 +                                               cmn_err( CE_DEBUG, "Device base address = 0x%lx [0x%lx]", host_ptr->base, dev->resource[0].start );
12600 +                                               cmn_err( CE_DEBUG, "Device irq = 0x%lx", dev->irq );
12601 +
12602 +                                               // The unique_id field is a unique identifier that must be assigned
12603 +                                               // so that we have some way of identifying each host adapter properly
12604 +                                               // and uniquely. For hosts that do not support more than one card in the
12605 +                                               // system, this does not need to be set. It is initialized to zero in
12606 +                                               // scsi_register(). This is the value returned from OsGetDeviceInstance().
12607 +
12608 +                                               host_ptr->unique_id = g_HostAdapterCount - 1;
12609 +                                               host_ptr->this_id = 16;                 // SCSI Id for the adapter itself
12610 +
12611 +                                               // Set the maximum number of simultaneous commands supported by the driver.
12612 +                                               host_ptr->can_queue = MAX_DRIVER_QUEUE_DEPTH;
12613 +
12614 +                                               // Define the maximum number of scatter/gather elements supported by 
12615 +                                               // the driver. 
12616 +
12617 +                                               host_ptr->sg_tablesize = 16;
12618 +                                               host_ptr->max_sectors = 128;
12619 +                                               host_ptr->cmd_per_lun = 1;              // untagged queue depth
12620 +
12621 +                                               // This function is called after the device list has been built to find
12622 +                                               // tagged queueing depth supported for each device.
12623 +
12624 +                                               host_ptr->select_queue_depths = AAC_SelectQueueDepths;
12625 +                                               CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )host_ptr->hostdata;
12626 +                       
12627 +                                               // attach a pointer back to Scsi_Host
12628 +                                               CommonExtensionPtr->OsDep.scsi_host_ptr = host_ptr;     
12629 +                                               CommonExtensionPtr->OsDep.MiniPortIndex =  index;
12630 +
12631 +                                               // Initialize the ordinal number of the device to -1
12632 +                                               fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
12633 +                                               for( ContainerId = 0; ContainerId < MAXIMUM_NUM_CONTAINERS; ContainerId++ )
12634 +                                                               fsa_dev_ptr->ContainerDevNo[ContainerId] = -1;
12635 +
12636 +                                               // Call initialization routine
12637 +                                               cmn_err (CE_DEBUG, "Initializing Hardware...\n");
12638 +                                               if( ( *MiniPorts[index].InitRoutine )
12639 +                                                       ( CommonExtensionPtr, host_ptr->unique_id, dev->bus->number, 0 ) != 0 )
12640 +                                               {
12641 +                                                               // device initialization failed
12642 +                                                               cmn_err( CE_WARN, "%s:%d device initialization failed", DeviceName, host_ptr->unique_id );
12643 +                                                               scsi_unregister( host_ptr );
12644 +                                                               g_HostAdapterCount--;
12645 +                                               } /* end if */
12646 +                                               else
12647 +                                               {
12648 +                                                       cmn_err( CE_NOTE, "%s:%d device initialization successful", DeviceName, host_ptr->unique_id  );
12649 +                                                       AacHba_ClassDriverInit( CommonExtensionPtr );
12650 +                                                       cmn_err(CE_NOTE, "%s:%d AacHba_ClassDriverInit complete", DeviceName, host_ptr->unique_id);
12651 +                                                       AacHba_ProbeContainers( CommonExtensionPtr );
12652 +                                                       g_CommonExtensionPtrArray[ g_HostAdapterCount - 1 ] = CommonExtensionPtr;
12653 +
12654 +                                               } /* end else */
12655 +
12656 +                               } /* end while */
12657 +
12658 +               } /* end for */
12659 +
12660 +               if( g_HostAdapterCount ){
12661 +                       if( !( g_chardev_major = register_chrdev( 0, devicestr, &AAC_fops ) ) )
12662 +                               cmn_err( CE_WARN, "%s: unable to register %s device", DeviceName, devicestr);
12663 +               }
12664 +
12665 +               HostTemplate->present = g_HostAdapterCount; // # of cards of this type found
12666 +
12667 +               return( g_HostAdapterCount ); 
12668 +}
12669 +
12670 +
12671 +/*------------------------------------------------------------------------------
12672 +       AAC_ReleaseHostAdapter()
12673 +
12674 +               Release all resources previously acquired to support a specific Host 
12675 +               Adapter and unregister the AAC Host Adapter.
12676 + *----------------------------------------------------------------------------*/
12677 +int AAC_ReleaseHostAdapter( 
12678 +       struct Scsi_Host *host_ptr )
12679 +/*----------------------------------------------------------------------------*/
12680 +{
12681 +       PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
12682 +
12683 +       cmn_err( CE_DEBUG, "AAC_ReleaseHostAdapter" );
12684 +
12685 +       CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )host_ptr->hostdata;
12686 +
12687 +       // kill any threads we started
12688 +       kill_proc( CommonExtensionPtr->OsDep.thread_pid, SIGKILL, 0 );
12689 +
12690 +       // Call the comm layer to detach from this adapter
12691 +       AacHba_DetachAdapter( CommonExtensionPtr->Adapter );
12692 +
12693 +       // remove interrupt binding
12694 +       OsDetachInterrupt( CommonExtensionPtr->MiniPort );
12695 +
12696 +       SaDetachDevice( CommonExtensionPtr );
12697 +
12698 +       // unregister adapter
12699 +       scsi_unregister( host_ptr );
12700 +
12701 +       if( g_chardev_major )
12702 +       {
12703 +               unregister_chrdev( g_chardev_major, devicestr );
12704 +               g_chardev_major = 0;
12705 +       }
12706 +
12707 +       return( 0 ); // #REVISIT# return code
12708 +}
12709 +
12710 +
12711 +/*------------------------------------------------------------------------------
12712 +       AAC_QueueCommand()
12713 +
12714 +               Queues a command for execution by the associated Host Adapter.
12715 + *----------------------------------------------------------------------------*/
12716 +int AAC_QueueCommand(
12717 +       Scsi_Cmnd *scsi_cmnd_ptr,
12718 +       void ( *CompletionRoutine )( Scsi_Cmnd * ) )
12719 +/*----------------------------------------------------------------------------*/
12720 +{
12721 +       int ret;
12722 +       scsi_cmnd_ptr->scsi_done = CompletionRoutine;
12723 +
12724 +       // AacHba_DoScsiCmd() handles command processing, setting the 
12725 +       // result code and calling completion routine. 
12726 +       #ifdef SYNC_FIB
12727 +       if( (ret = AacHba_DoScsiCmd( scsi_cmnd_ptr, 1 )) != 0 ) // call with wait = TRUE
12728 +       #else
12729 +       if( (ret = AacHba_DoScsiCmd( scsi_cmnd_ptr, 0 )) != 0 ) // call with wait = FALSE
12730 +       #endif
12731 +               cmn_err( CE_DEBUG, "AacHba_DoScsiCmd failed" );
12732 +       return ret;
12733 +} 
12734 +
12735 +
12736 +/*------------------------------------------------------------------------------
12737 +       AAC_Done()
12738 +
12739 +               Callback function for a non-queued command.
12740 +
12741 +       Postconditions
12742 +               Sets g_single_command done to TRUE
12743 + *----------------------------------------------------------------------------*/
12744 +void AAC_Done( 
12745 +       Scsi_Cmnd * scsi_cmnd_ptr ) 
12746 +/*----------------------------------------------------------------------------*/
12747 +{
12748 +       g_single_command_done = TRUE;
12749 +}
12750 +
12751 +
12752 +/*------------------------------------------------------------------------------
12753 +       AAC_Command()
12754 +       
12755 +               Accepts a single command for execution by the associated Host Adapter.
12756 +
12757 +       Postconditions
12758 +               Returns an int where:
12759 +               Byte 0 = SCSI status code
12760 +               Byte 1 = SCSI 1 byte message
12761 +               Byte 2 = host error return
12762 +               Byte 3 = mid level error return
12763 + *----------------------------------------------------------------------------*/
12764 +int AAC_Command(
12765 +       Scsi_Cmnd *scsi_cmnd_ptr )
12766 +/*----------------------------------------------------------------------------*/
12767 +{
12768 +       scsi_cmnd_ptr->scsi_done = AAC_Done;
12769 +
12770 +       cmn_err( CE_DEBUG, "AAC_Command" );
12771 +
12772 +       // AacHba_DoScsiCmd() handles command processing, setting the 
12773 +       // result code and calling completion routine.
12774 +       g_single_command_done = FALSE;
12775 +       
12776 +       AacHba_DoScsiCmd( scsi_cmnd_ptr, 0 );
12777 +       while( !g_single_command_done );
12778 +       return( scsi_cmnd_ptr->result );
12779 +} 
12780 +
12781 +
12782 +/*------------------------------------------------------------------------------
12783 +       AAC_AbortCommand()
12784 +
12785 +               Abort command if possible.
12786 + *----------------------------------------------------------------------------*/
12787 +int AAC_AbortCommand( 
12788 +       Scsi_Cmnd *scsi_cmnd_ptr )
12789 +/*----------------------------------------------------------------------------*/
12790 +{
12791 +       int target = scsi_cmnd_ptr->target;
12792 +       int hba = scsi_cmnd_ptr->host->unique_id;
12793 +       int result = 0;
12794 +       u_short interrupt_status;
12795 +       PCI_MINIPORT_COMMON_EXTENSION *cep;
12796 +       char   *DeviceName;
12797 +
12798 +       cmn_err( CE_WARN, "%s:%d ABORT", g_DriverName, hba, target );
12799 +       AacHba_AbortScsiCommand( scsi_cmnd_ptr );
12800 +
12801 +       cep = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
12802 +       DeviceName = MiniPorts[cep->OsDep.MiniPortIndex].DeviceName; 
12803 +
12804 +               /*
12805 +               cmn_err( CE_WARN, "%s:%d Unable to abort command to target %d - "
12806 +                 "command already completed", DeviceName, hba, target);
12807 +               result = SCSI_ABORT_NOT_RUNNING;
12808 +
12809 +               cmn_err(CE_WARN, "%s:%d Unable to abort command to target %d - "
12810 +                  "no command found\n", DeviceName, hba, target);
12811 +               result = SCSI_ABORT_NOT_RUNNING;
12812 +
12813 +               cmn_err(CE_WARN, "%s:%d Unable to abort command to target %d - "
12814 +                  "command reset\n", DeviceName, hba, target);
12815 +               result = SCSI_ABORT_PENDING;
12816 +
12817 +               cmn_err(CE_WARN, "%s:%d Unable to abort command to target %d - "
12818 +                  "abort tag not supported\n", DeviceName, hba, target);
12819 +               result = SCSI_ABORT_SNOOZE;
12820 +
12821 +               cmn_err(CE_WARN, "%s:%d Aborting command to target %d - pending",
12822 +                  DeviceName, hba, target);
12823 +               result = SCSI_ABORT_PENDING;
12824 +
12825 +               cmn_err(CE_WARN, "%s:%d Unable to abort command to target %d",
12826 +                  DeviceName, hba, target);
12827 +               result = SCSI_ABORT_BUSY;
12828 +
12829 +               cmn_err(CE_WARN, "%s:%d Aborted command to target %d\n",
12830 +                  DeviceName, hba, target);
12831 +               result = SCSI_ABORT_SUCCESS;
12832 +               */
12833 +
12834 +       // Abort not supported yet
12835 +       result = SCSI_ABORT_BUSY;
12836 +       return result;
12837 +}
12838 +
12839 +
12840 +/*------------------------------------------------------------------------------
12841 +       AAC_ResetCommand()
12842 +
12843 +               Reset command handling.
12844 + *----------------------------------------------------------------------------*/
12845 +int AAC_ResetCommand( 
12846 +       struct scsi_cmnd *scsi_cmnd_ptr, 
12847 +       unsigned int reset_flags )
12848 +/*----------------------------------------------------------------------------*/
12849 +{
12850 +       int target = scsi_cmnd_ptr->target;
12851 +       int hba = scsi_cmnd_ptr->host->unique_id;
12852 +       PCI_MINIPORT_COMMON_EXTENSION *cep;
12853 +       char    *DeviceName;
12854 +
12855 +       cep = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
12856 +       DeviceName = MiniPorts[cep->OsDep.MiniPortIndex].DeviceName;
12857 +
12858 +       cmn_err( CE_WARN, "%s:%d RESET", DeviceName, hba, target );
12859 +
12860 +       return SCSI_RESET_PUNT;
12861 +}
12862 +
12863 +
12864 +/*------------------------------------------------------------------------------
12865 +       AAC_DriverInfo()
12866 +
12867 +               Returns the host adapter name
12868 + *----------------------------------------------------------------------------*/
12869 +const char *AAC_DriverInfo( 
12870 +       struct Scsi_Host *host_ptr )
12871 +/*----------------------------------------------------------------------------*/
12872 +{
12873 +  PCI_MINIPORT_COMMON_EXTENSION *cep;
12874 +  char *DeviceName;
12875 +
12876 +  cep = ( PCI_MINIPORT_COMMON_EXTENSION * )( host_ptr->hostdata );
12877 +  DeviceName = MiniPorts[cep->OsDep.MiniPortIndex].DeviceName;
12878 +
12879 +  cmn_err( CE_DEBUG, "AAC_DriverInfo" );
12880 +  return (DeviceName);
12881 +}
12882 +
12883 +
12884 +/*------------------------------------------------------------------------------
12885 +       AAC_BIOSDiskParameters()
12886 +
12887 +               Return the Heads/Sectors/Cylinders BIOS Disk Parameters for Disk.  
12888 +               The default disk geometry is 64 heads, 32 sectors, and the appropriate 
12889 +               number of cylinders so as not to exceed drive capacity.  In order for 
12890 +               disks equal to or larger than 1 GB to be addressable by the BIOS
12891 +               without exceeding the BIOS limitation of 1024 cylinders, Extended 
12892 +               Translation should be enabled.   With Extended Translation enabled, 
12893 +               drives between 1 GB inclusive and 2 GB exclusive are given a disk 
12894 +               geometry of 128 heads and 32 sectors, and drives above 2 GB inclusive 
12895 +               are given a disk geometry of 255 heads and 63 sectors.  However, if 
12896 +               the BIOS detects that the Extended Translation setting does not match 
12897 +               the geometry in the partition table, then the translation inferred 
12898 +               from the partition table will be used by the BIOS, and a warning may 
12899 +               be displayed.
12900 + *----------------------------------------------------------------------------*/
12901 +int AAC_BIOSDiskParameters(
12902 +       Scsi_Disk *scsi_disk_ptr, 
12903 +       kdev_t device,
12904 +       int *parameter_ptr )
12905 +/*----------------------------------------------------------------------------*/
12906 +{
12907 +       AAC_BIOS_DiskParameters_T *disk_parameters = 
12908 +               ( AAC_BIOS_DiskParameters_T *)parameter_ptr;
12909 +       struct buffer_head * buffer_head_ptr;
12910 +
12911 +       cmn_err( CE_DEBUG, "AAC_BIOSDiskParameters" );
12912 +
12913 +       // Assuming extended translation is enabled - #REVISIT#
12914 +       if( scsi_disk_ptr->capacity >= 2 * 1024 * 1024 ) // 1 GB in 512 byte sectors
12915 +       {
12916 +               if( scsi_disk_ptr->capacity >= 4 * 1024 * 1024 ) // 2 GB in 512 byte sectors
12917 +               {
12918 +                       disk_parameters->heads = 255;
12919 +                       disk_parameters->sectors = 63;
12920 +               }
12921 +               else
12922 +               {
12923 +                       disk_parameters->heads = 128;
12924 +                       disk_parameters->sectors = 32;
12925 +               }
12926 +       }
12927 +       else
12928 +       {
12929 +               disk_parameters->heads = 64;
12930 +               disk_parameters->sectors = 32;
12931 +       }
12932 +
12933 +       disk_parameters->cylinders = scsi_disk_ptr->capacity
12934 +               /( disk_parameters->heads * disk_parameters->sectors );
12935 +
12936 +       // Read the first 1024 bytes from the disk device
12937 +       buffer_head_ptr = bread( 
12938 +                                               MKDEV( MAJOR( device ), 
12939 +                                               MINOR( device ) & ~0x0F ), 
12940 +                                               0, 1024 );
12941 +
12942 +       if( buffer_head_ptr == NULL )
12943 +               return( 0 );
12944 +       /* 
12945 +               If the boot sector partition table is valid, search for a partition 
12946 +               table entry whose end_head matches one of the standard geometry 
12947 +               translations ( 64/32, 128/32, 255/63 ).
12948 +       */
12949 +       if( *( unsigned short * )( buffer_head_ptr->b_data + 0x1fe ) == 0xaa55 )
12950 +       {
12951 +               struct partition *first_partition_entry =
12952 +                       ( struct partition * )( buffer_head_ptr->b_data + 0x1be );
12953 +               struct partition *partition_entry = first_partition_entry;
12954 +               int saved_cylinders = disk_parameters->cylinders;
12955 +               int partition_number;
12956 +               unsigned char partition_entry_end_head, partition_entry_end_sector;
12957 +
12958 +               for( partition_number = 0; partition_number < 4; partition_number++ )
12959 +               {
12960 +                       partition_entry_end_head   = partition_entry->end_head;
12961 +                       partition_entry_end_sector = partition_entry->end_sector & 0x3f;
12962 +
12963 +                       if( partition_entry_end_head == ( 64 - 1 ) )
12964 +                       {
12965 +                               disk_parameters->heads = 64;
12966 +                               disk_parameters->sectors = 32;
12967 +                               break;
12968 +                       }
12969 +                       else if( partition_entry_end_head == ( 128 - 1 ) )
12970 +                       {
12971 +                               disk_parameters->heads = 128;
12972 +                               disk_parameters->sectors = 32;
12973 +                               break;
12974 +                       }
12975 +                       else if( partition_entry_end_head == ( 255 - 1 ) ) 
12976 +                       {
12977 +                               disk_parameters->heads = 255;
12978 +                               disk_parameters->sectors = 63;
12979 +                               break;
12980 +                       }
12981 +                       partition_entry++;
12982 +               }
12983 +
12984 +               if( partition_number == 4 )
12985 +               {
12986 +                       partition_entry_end_head   = first_partition_entry->end_head;
12987 +                       partition_entry_end_sector = first_partition_entry->end_sector & 0x3f;
12988 +               }
12989 +
12990 +               disk_parameters->cylinders = scsi_disk_ptr->capacity
12991 +                       /( disk_parameters->heads * disk_parameters->sectors );
12992 +
12993 +               if( ( partition_number < 4 )  && ( partition_entry_end_sector == disk_parameters->sectors ) )
12994 +               {
12995 +                       if( disk_parameters->cylinders != saved_cylinders )
12996 +                               cmn_err( CE_DEBUG, "Adopting geometry: heads=%d, sectors=%d from partition table %d",
12997 +                                       disk_parameters->heads, disk_parameters->sectors, partition_number );
12998 +               }
12999 +               else if( ( partition_entry_end_head > 0 ) || ( partition_entry_end_sector > 0 ) )
13000 +               {
13001 +                       cmn_err( CE_DEBUG, "Strange geometry: heads=%d, sectors=%d in partition table %d",
13002 +                               partition_entry_end_head + 1, partition_entry_end_sector, partition_number );
13003 +                       cmn_err( CE_DEBUG, "Using geometry: heads=%d, sectors=%d",
13004 +                                       disk_parameters->heads, disk_parameters->sectors );
13005 +               }
13006 +       }
13007 +       
13008 +       brelse( buffer_head_ptr );
13009 +
13010 +       return( 0 );
13011 +}
13012 +
13013 +
13014 +/*------------------------------------------------------------------------------
13015 +       AAC_SelectQueueDepths()
13016 +
13017 +               Selects queue depths for each target device based on the host adapter's
13018 +               total capacity and the queue depth supported by the target device.
13019 +               A queue depth of one automatically disables tagged queueing.
13020 + *----------------------------------------------------------------------------*/
13021 +void AAC_SelectQueueDepths(
13022 +       struct Scsi_Host * host_ptr,
13023 +       Scsi_Device * scsi_device_ptr )
13024 +/*----------------------------------------------------------------------------*/
13025 +{
13026 +       Scsi_Device * device_ptr;
13027 +
13028 +       cmn_err( CE_DEBUG, "AAC_SelectQueueDepths" );
13029 +       cmn_err( CE_DEBUG, "Device #   Q Depth   Online" );
13030 +       cmn_err( CE_DEBUG, "---------------------------" );
13031 +       for( device_ptr = scsi_device_ptr; device_ptr != NULL; device_ptr = device_ptr->next )
13032 +               if( device_ptr->host == host_ptr )
13033 +               {
13034 +                       device_ptr->queue_depth = 10;           
13035 +                       cmn_err( CE_DEBUG, "  %2d         %d        %d", 
13036 +                               device_ptr->id, device_ptr->queue_depth, device_ptr->online );
13037 +               }
13038 +}
13039 +
13040 +
13041 +/*------------------------------------------------------------------------------
13042 +       AAC_SearchBiosSignature()
13043 +
13044 +               Locate adapter signature in BIOS
13045 + *----------------------------------------------------------------------------*/
13046 +int AAC_SearchBiosSignature( void )
13047 +/*----------------------------------------------------------------------------*/
13048 +{
13049 +       unsigned base;
13050 +       unsigned namep;
13051 +       int index;
13052 +       int val;
13053 +       char name_buf[32];
13054 +       int result = FALSE;
13055 +
13056 +       for( base = 0xc8000; base < 0xdffff; base += 0x4000 )
13057 +       {
13058 +               val = readb( base );
13059 +               if( val != 0x55 ) 
13060 +                       continue;
13061 +
13062 +               result = TRUE;
13063 +               namep = base + 0x1e;
13064 +               memcpy_fromio( name_buf, namep, 32 );
13065 +               name_buf[31] = '\0';
13066 +       }
13067 +       return( result );
13068 +}
13069 +
13070 +
13071 +/*------------------------------------------------------------------------------
13072 +       AAC_Ioctl()
13073 +
13074 +               Handle SCSI ioctls
13075 + *----------------------------------------------------------------------------*/
13076 +int AAC_Ioctl(
13077 +       Scsi_Device * scsi_dev_ptr,
13078 +       int cmd,
13079 +       void * arg )
13080 +/*----------------------------------------------------------------------------*/
13081 +{
13082 +       PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
13083 +
13084 +       cmn_err( CE_DEBUG, "AAC_Ioctl" );
13085 +       CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )scsi_dev_ptr->host->hostdata;
13086 +       return( AacHba_Ioctl( CommonExtensionPtr, cmd, arg ) );
13087 +}
13088 +
13089 +
13090 +
13091 +/*------------------------------------------------------------------------------
13092 +       AAC_ChardevOpen()
13093 +       
13094 +               Handle character device open
13095 +       
13096 +       Preconditions:
13097 +       Postconditions:
13098 +               Returns 0 if successful, -ENODEV or -EINVAL otherwise
13099 + *----------------------------------------------------------------------------*/
13100 +int AAC_ChardevOpen(
13101 +       struct inode * inode_ptr,
13102 +       struct file * file_ptr )
13103 +/*----------------------------------------------------------------------------*/
13104 +{
13105 +       unsigned minor_number;
13106 +
13107 +       cmn_err( CE_DEBUG, "AAC_ChardevOpen" );
13108 +
13109 +       // check device permissions in file_ptr->f_mode ??
13110 +
13111 +       // extract & check the minor number
13112 +       minor_number = MINOR( inode_ptr->i_rdev );
13113 +       if( minor_number > ( g_HostAdapterCount - 1 ) )
13114 +       {
13115 +               cmn_err( CE_WARN, "AAC_ChardevOpen: Minor number %d not supported", minor_number );
13116 +               return( -ENODEV );
13117 +       }
13118 +
13119 +#ifdef MODULE
13120 +       MOD_INC_USE_COUNT;
13121 +#endif
13122 +
13123 +       return( 0 );
13124 +}
13125 +
13126 +
13127 +/*------------------------------------------------------------------------------
13128 +       AAC_ChardevRelease()
13129 +       
13130 +               Handle character device release.
13131 +       
13132 +       Preconditions:
13133 +       Postconditions:
13134 +               Returns 0 if successful, -ENODEV or -EINVAL otherwise
13135 + *----------------------------------------------------------------------------*/
13136 +int AAC_ChardevRelease(
13137 +       struct inode * inode_ptr,
13138 +       struct file * file_ptr )
13139 +/*----------------------------------------------------------------------------*/
13140 +{
13141 +       cmn_err( CE_DEBUG, "AAC_ChardevRelease" );
13142 +
13143 +#ifdef MODULE
13144 +       MOD_DEC_USE_COUNT;
13145 +#endif
13146 +
13147 +       return( 0 );
13148 +}
13149 +
13150 +
13151 +/*------------------------------------------------------------------------------
13152 +       AAC_ChardevIoctl()
13153 +       
13154 +               Handle character device interface ioctls
13155 +       
13156 +       Preconditions:
13157 +       Postconditions:
13158 +               Returns 0 if successful, -ENODEV or -EINVAL otherwise
13159 + *----------------------------------------------------------------------------*/
13160 +int AAC_ChardevIoctl(
13161 +       struct inode * inode_ptr, 
13162 +       struct file * file_ptr,
13163 +       unsigned int cmd,
13164 +       unsigned long arg )
13165 +{
13166 +       unsigned minor_number;
13167 +       PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
13168 +
13169 +       cmn_err( CE_DEBUG, "AAC_ChardevIoctl" );
13170 +
13171 +       // check device permissions in file_ptr->f_mode ??
13172 +
13173 +       // extract & check the minor number
13174 +       minor_number = MINOR( inode_ptr->i_rdev );
13175 +       if( minor_number > ( g_HostAdapterCount - 1 ) )
13176 +       {
13177 +               cmn_err( CE_WARN, "AAC_ChardevIoctl: Minor number %d not supported", minor_number );
13178 +               return( -ENODEV );
13179 +       }
13180 +
13181 +       // get device pointer
13182 +       CommonExtensionPtr = g_CommonExtensionPtrArray[ minor_number ];
13183 +
13184 +       // dispatch ioctl - AacHba_Ioctl() returns zero on success
13185 +       if( AacHba_Ioctl( CommonExtensionPtr, cmd, ( void * )arg ) )
13186 +               return( -EINVAL );
13187 +
13188 +       return( 0 );
13189 +}
13190 +
13191 +
13192 +/*------------------------------------------------------------------------------
13193 +       parse_keyword()
13194 +
13195 +               Look for the keyword in str_ptr
13196 +
13197 +       Preconditions:
13198 +       Postconditions:
13199 +               If keyword found
13200 +                       - return true and update the pointer str_ptr.
13201 +               otherwise
13202 +                       - return false
13203 + *----------------------------------------------------------------------------*/
13204 +static int parse_keyword(
13205 +       char ** str_ptr, 
13206 +       char * keyword )
13207 +/*----------------------------------------------------------------------------*/
13208 +{
13209 +       char * ptr = *str_ptr;
13210 +       
13211 +       while( *keyword != '\0' )
13212 +       {
13213 +               char string_char = *ptr++;
13214 +               char keyword_char = *keyword++;
13215 +
13216 +               if ( ( string_char >= 'A' ) && ( string_char <= 'Z' ) )
13217 +                       string_char += 'a' - 'Z';
13218 +               if( ( keyword_char >= 'A' ) && ( keyword_char <= 'Z' ) ) 
13219 +                       keyword_char += 'a' - 'Z';
13220 +               if( string_char != keyword_char )
13221 +                       return FALSE;
13222 +       }
13223 +       *str_ptr = ptr;
13224 +       return TRUE;
13225 +}
13226 +
13227 +
13228 +/*------------------------------------------------------------------------------
13229 +       AAC_ParseDriverOptions()
13230 +
13231 +       For modules the usage is:
13232 +               insmod -f aacraid.o 'aacraid_options="<option_name:argument>"'
13233 + *----------------------------------------------------------------------------*/
13234 +static void AAC_ParseDriverOptions( 
13235 +       char * cmnd_line_options_str )
13236 +/*----------------------------------------------------------------------------*/
13237 +{
13238 +       int message_level;
13239 +       int reverse_scan;
13240 +       char *cp;
13241 +       char *endp;
13242 +
13243 +       cp = cmnd_line_options_str;
13244 +
13245 +       cmn_err(CE_DEBUG, "AAC_ParseDriverOptions: <%s>", cp);
13246 +
13247 +       while( *cp ) {
13248 +               if( parse_keyword( &cp, "message_level:" ) ) {
13249 +                       message_level = simple_strtoul( cp, 0, 0 );
13250 +                       if( ( message_level < CE_TAIL ) && ( message_level >= 0 ) ) {
13251 +                               g_options.message_level = message_level;
13252 +                               cmn_err( CE_WARN, "%s: new message level = %d", g_DriverName, g_options.message_level );
13253 +                       }
13254 +                       else {
13255 +                               cmn_err( CE_WARN, "%s: invalid message level = %d", g_DriverName, message_level );
13256 +                       }
13257 +               } else if (parse_keyword( &cp, "reverse_scan:" ) ) {
13258 +                       reverse_scan = simple_strtoul( cp, 0, 0 );
13259 +                       if (reverse_scan) {
13260 +                               g_options.reverse_scan = 1;
13261 +                               cmn_err( CE_WARN, "%s: reversing device discovery order", g_DriverName, g_options.message_level );
13262 +                       }
13263 +               }
13264 +               else {
13265 +                       cmn_err( CE_WARN, "%s: unknown command line option <%s>", g_DriverName, cp );
13266 +               }
13267 +
13268 +               /*
13269 +                * skip to next option,  accept " ", ";", and "," as delimiters
13270 +                */
13271 +               while ( *cp && (*cp != ' ')  && (*cp != ';')  && (*cp != ','))
13272 +                       cp++;
13273 +
13274 +               if (*cp)                                 /* skip over the delimiter */
13275 +                       cp++;
13276 +       }
13277 +
13278 +}
13279 +
13280 +
13281 +/*------------------------------------------------------------------------------
13282 +       Include Module support if requested.
13283 +
13284 +       To use the low level SCSI driver support using the linux kernel loadable 
13285 +       module interface we should initialize the global variable driver_interface  
13286 +       (datatype Scsi_Host_Template) and then include the file scsi_module.c.
13287 +       This should also be wrapped in a #ifdef MODULE/#endif
13288 + *----------------------------------------------------------------------------*/
13289 +#ifdef MODULE
13290 +
13291 +/*
13292 +       The Loadable Kernel Module Installation Facility may pass us
13293 +       a pointer to a driver specific options string to be parsed, 
13294 +       we assign this to options string. 
13295 +*/
13296 +MODULE_PARM( module_options, "s" );
13297 +
13298 +Scsi_Host_Template driver_template = AAC_HOST_TEMPLATE_ENTRY;
13299 +
13300 +#include "scsi_module.c"
13301 +
13302 +#else
13303 +Scsi_Host_Template driver_template = AAC_HOST_TEMPLATE_ENTRY;
13304 +
13305 +#include "scsi_module.c"
13306 +#endif
13307 +
13308 +/*********************************************************************
13309 +       AAC_ProcDirectoryInfo()
13310 +
13311 +               Implement /proc/scsi/<drivername>/<n>.
13312 +               Used to export driver statistics and other infos to the world outside 
13313 +               the kernel using the proc file system. Also provides an interface to
13314 +               feed the driver with information.
13315 +
13316 +       Postconditions
13317 +               For reads
13318 +                       - if offset > 0 return 0
13319 +                       - if offset == 0 write data to proc_buffer and set the start_ptr to
13320 +                       beginning of proc_buffer, return the number of characters written.
13321 +               For writes
13322 +                       - writes currently not supported, return 0
13323 +************************************************************/
13324 +int AAC_ProcDirectoryInfo(
13325 +       char *proc_buffer,              // read/write buffer
13326 +       char **start_ptr,               // start of valid data in the buffer
13327 +       off_t offset,                   // offset from the beginning of the imaginary file 
13328 +       int bytes_available,    // bytes available
13329 +       int host_no,                    // SCSI host number 
13330 +       int write )                             // direction of dataflow: TRUE for writes, FALSE for reads      
13331 +{
13332 +       int length = 0;
13333 +       cmn_err( CE_WARN, "AAC_ProcDirectoryInfo" );
13334 +
13335 +       if( ( write ) || ( offset > 0 ) )
13336 +               return( 0 );
13337 +
13338 +       *start_ptr = proc_buffer;
13339 +
13340 +       return( sprintf(&proc_buffer[length], "%s  %d\n", "Raid Controller, scsi hba number", host_no ) );
13341 +}
13342 +
13343 +void aac_allocate_SyncFibs (PCI_MINIPORT_COMMON_EXTENSION *CommonExtension)
13344 +{
13345 +  void         *BaseAddress;
13346 +  ULONG                PhysAddress;
13347 +  int          size;
13348 +  int          npages;
13349 +  int          i;
13350 +
13351 +  AFA_COMM_ADAPTER             *Adapter;
13352 +  Adapter = CommonExtension->Adapter;
13353 +
13354 +
13355 +  // Allocate 1 fib for synch fibs
13356 +  // Allocate 1 page.
13357 +  BaseAddress = OsAllocMemory ( PAGE_SIZE, OS_ALLOC_MEM_SLEEP);
13358 +  bzero(BaseAddress, PAGE_SIZE);
13359 +  PhysAddress = virt_to_phys (BaseAddress);
13360 +  Adapter->SyncFib = BaseAddress;
13361 +  Adapter->SyncFibPhysicalAddress = PhysAddress;
13362 +  cmn_err(CE_DEBUG,"aac_allocate_SyncFibs: syncFib: vaddr: 0x%x paddr: 0x%x ", BaseAddress, PhysAddress);
13363 +
13364 +}
13365 diff -burN linux-2.4.7/drivers/scsi/aacraid/osddi.c linux/drivers/scsi/aacraid/osddi.c
13366 --- linux-2.4.7/drivers/scsi/aacraid/osddi.c    Wed Dec 31 18:00:00 1969
13367 +++ linux/drivers/scsi/aacraid/osddi.c  Sat Jul 21 17:55:14 2001
13368 @@ -0,0 +1,512 @@
13369 +/*++
13370 + * Adaptec aacraid device driver for Linux.
13371 + *
13372 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
13373 + *
13374 + * This program is free software; you can redistribute it and/or modify
13375 + * it under the terms of the GNU General Public License as published by
13376 + * the Free Software Foundation; either version 2, or (at your option)
13377 + * any later version.
13378 + *
13379 + * This program is distributed in the hope that it will be useful,
13380 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
13381 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13382 + * GNU General Public License for more details.
13383 + *
13384 + * You should have received a copy of the GNU General Public License
13385 + * along with this program; see the file COPYING.  If not, write to
13386 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
13387 + *
13388 + * Module Name:
13389 + *   osddi.c
13390 + *
13391 + * Abstract: This file contains all the proceedures which use LINUX specific Device 
13392 + *             Driver Interfaces.
13393 + *     
13394 + --*/
13395 +
13396 +static char *ident_osddi = "aacraid_ident osddi.c 1.0.6 2000/10/09 Adaptec, Inc.";
13397 +
13398 +#include "osheaders.h"
13399 +
13400 +#include <linux/smp_lock.h>
13401 +
13402 +#ifdef fsid_t
13403 +#undef fsid_t
13404 +#endif
13405 +#include "AacGenericTypes.h"
13406 +#include "aac_unix_defs.h"
13407 +#include "comstruc.h"
13408 +#include "monkerapi.h"
13409 +#include "protocol.h"
13410 +#include "fsafs.h"
13411 +
13412 +#include "sap1common.h"
13413 +#include "fsaport.h"
13414 +#include "pcisup.h"
13415 +#include "sap1.h"
13416 +#include "nodetype.h"
13417 +#include "comsup.h"
13418 +#include "afacomm.h"
13419 +#include "adapter.h"
13420 +
13421 +
13422 +void AacSaPciIsr( 
13423 +       int irq,
13424 +       void * irq_data,
13425 +       struct pt_regs *regs);
13426 +
13427 +void AacRxPciIsr( 
13428 +       int irq,
13429 +       void * irq_data,
13430 +       struct pt_regs *regs);
13431 +
13432 +unsigned SaPciIsr (
13433 +    IN PSa_ADAPTER_EXTENSION AdapterExtension );
13434 +
13435 +unsigned RxPciIsr (
13436 +    IN PSa_ADAPTER_EXTENSION AdapterExtension );
13437 +
13438 +
13439 +/*----------------------------------------------------------------------------*/
13440 +VOID AfaCommInterruptHost(
13441 +       PVOID                   AdapterArg,
13442 +       ADAPTER_EVENT   AdapterEvent )
13443 +/*----------------------------------------------------------------------------*/
13444 +{
13445 +       PAFA_COMM_ADAPTER       Adapter = ( PAFA_COMM_ADAPTER ) AdapterArg;
13446 +       PCOMM_REGION CommRegion = Adapter->CommRegion;
13447 +
13448 +       switch (AdapterEvent) {
13449 +
13450 +         case HostNormRespQue:
13451 +               OsSoftInterruptTrigger( CommRegion->HostNormRespQue.ConsumerRoutine );
13452 +       
13453 +       // #REVIEW# - what do we do with this
13454 +       // if (FsaCommData.HardInterruptModeration)
13455 +       //                      DisableInterrupt( Adapter, HostNormRespQue, TRUE );
13456 +
13457 +                       break;
13458 +
13459 +      case AdapNormCmdNotFull:
13460 +               OsSoftInterruptTrigger( CommRegion->QueueNotFullDpc );
13461 +                       break;
13462 +
13463 +         case HostNormCmdQue:
13464 +               OsSoftInterruptTrigger( CommRegion->HostNormCmdQue.ConsumerRoutine );
13465 +                       break;
13466 +
13467 +      case AdapNormRespNotFull:
13468 +               OsSoftInterruptTrigger( CommRegion->QueueNotFullDpc );
13469 +                       break;
13470 +
13471 +       // #REVIEW# - what do we do with these
13472 +         case HostHighCmdQue:
13473 +         case HostHighRespQue:
13474 +         case AdapHighCmdNotFull:
13475 +         case AdapHighRespNotFull:
13476 +         case SynchCommandComplete:
13477 +         case AdapInternalError:
13478 +                 break;
13479 +       }
13480 +}
13481 +
13482 +
13483 +// get the device name associated with this instance of the device
13484 +/*----------------------------------------------------------------------------*/
13485 +char *OsGetDeviceName( 
13486 +       void *AdapterExtension )
13487 +/*----------------------------------------------------------------------------*/
13488 +{
13489 +       return( ( ( Sa_ADAPTER_EXTENSION * )AdapterExtension )->Common->
13490 +               OsDep.scsi_host_ptr->hostt->name );
13491 +}
13492 +
13493 +
13494 +/*----------------------------------------------------------------------------*/
13495 +int OsGetDeviceInstance( 
13496 +       void *AdapterExtension )
13497 +/*----------------------------------------------------------------------------*/
13498 +{
13499 +       return( ( int )( ( Sa_ADAPTER_EXTENSION * )AdapterExtension )->Common->
13500 +               OsDep.scsi_host_ptr->unique_id );
13501 +}
13502 +
13503 +
13504 +/*------------------------------------------------------------------------------
13505 +       OsMapDeviceRegisters()
13506 +
13507 +       Postconditions:
13508 +               Return zero on success non-zero otherwise.
13509 + *----------------------------------------------------------------------------*/
13510 +int OsMapDeviceRegisters( 
13511 +       Sa_ADAPTER_EXTENSION *AdapterExtension )
13512 +/*----------------------------------------------------------------------------*/
13513 +{
13514 +       PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
13515 +
13516 +       CommonExtension = AdapterExtension->Common;
13517 +
13518 +       if( AdapterExtension->Device = ( Sa_DEVICE_REGISTERS * )
13519 +                       ioremap( ( unsigned long )CommonExtension->OsDep.scsi_host_ptr->base, 8192 ) )
13520 +       {
13521 +               cmn_err( CE_WARN, "Device mapped to virtual address 0x%x", AdapterExtension->Device ); 
13522 +               return( 0 );
13523 +       }
13524 +       else
13525 +       {       
13526 +               cmn_err( CE_WARN, "OsMapDeviceRegisters: ioremap() failed" );
13527 +               return( 1 );
13528 +       }
13529 +}
13530 +
13531 +
13532 +/*------------------------------------------------------------------------------
13533 +       OsUnMapDeviceRegisters()
13534 +
13535 +       Postconditions:
13536 + *----------------------------------------------------------------------------*/
13537 +void OsUnMapDeviceRegisters( 
13538 +       Sa_ADAPTER_EXTENSION *AdapterExtension )
13539 +/*----------------------------------------------------------------------------*/
13540 +{
13541 +       iounmap( ( void * )AdapterExtension->Device );
13542 +}
13543 +
13544 +
13545 +/*----------------------------------------------------------------------------*/
13546 +int OsAttachInterrupt( 
13547 +       Sa_ADAPTER_EXTENSION *AdapterExtension ,
13548 +       int     WhichIsr )
13549 +/*----------------------------------------------------------------------------*/
13550 +{
13551 +       PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
13552 +       void *irq_data;
13553 +       void (*Isr)();
13554 +
13555 +       CommonExtension = AdapterExtension->Common;
13556 +       irq_data = ( void * )AdapterExtension;
13557 +
13558 +       switch (WhichIsr) {
13559 +               case SaISR:
13560 +                       Isr = AacSaPciIsr;
13561 +                       break;
13562 +               case RxISR:
13563 +                       Isr = AacRxPciIsr;
13564 +                       break;
13565 +               default:
13566 +                       cmn_err(CE_WARN, "OsAttachInterrupt: invalid ISR case: 0x%x", WhichIsr);
13567 +                       return( FAILURE );
13568 +                       break;
13569 +       }
13570 +
13571 +       
13572 +       if      ( OsRegisterInterrupt (
13573 +                               CommonExtension->OsDep.scsi_host_ptr->irq,      // interrupt number
13574 +                               Isr,                                                                            // handler function
13575 +                               irq_data )
13576 +               ) 
13577 +       {
13578 +               cmn_err( CE_WARN, "OsAttachInterrupt: Failed for IRQ: 0x%x", 
13579 +                       CommonExtension->OsDep.scsi_host_ptr->irq );
13580 +               return( FAILURE );
13581 +       }
13582 +
13583 +       return ( 0 );
13584 +}
13585 +
13586 +
13587 +/*----------------------------------------------------------------------------*/
13588 +void AacSaPciIsr( 
13589 +       int irq,
13590 +       void * irq_data,
13591 +       struct pt_regs *regs)
13592 +/*----------------------------------------------------------------------------*/
13593 +{
13594 +       // call the actual interrupt handler
13595 +       SaPciIsr( ( Sa_ADAPTER_EXTENSION * )irq_data );
13596 +}
13597 +
13598 +/*----------------------------------------------------------------------------*/
13599 +void AacRxPciIsr( 
13600 +       int irq,
13601 +       void * irq_data,
13602 +       struct pt_regs *regs)
13603 +/*----------------------------------------------------------------------------*/
13604 +{
13605 +       // call the actual interrupt handler
13606 +       RxPciIsr( ( Sa_ADAPTER_EXTENSION * )irq_data );
13607 +}
13608 +
13609 +
13610 +/*----------------------------------------------------------------------------*/
13611 +void OsDetachInterrupt( 
13612 +       Sa_ADAPTER_EXTENSION *AdapterExtension )
13613 +/*----------------------------------------------------------------------------*/
13614 +{
13615 +       PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
13616 +       void *irq_data;
13617 +
13618 +       CommonExtension = AdapterExtension->Common;
13619 +       irq_data = ( void * )AdapterExtension;
13620 +
13621 +       OsUnregisterInterrupt (
13622 +               CommonExtension->OsDep.scsi_host_ptr->irq,      // interrupt number
13623 +               irq_data );
13624 +}
13625 +
13626 +
13627 +/*----------------------------------------------------------------------------*/
13628 +int OsAttachDMA( 
13629 +       Sa_ADAPTER_EXTENSION *AdapterExtension )
13630 +/*----------------------------------------------------------------------------*/
13631 +{
13632 +       return( 0 );
13633 +}
13634 +
13635 +/*----------------------------------------------------------------------------*/
13636 +int OsAttachHBA( 
13637 +       Sa_ADAPTER_EXTENSION *AdapterExtension )
13638 +/*----------------------------------------------------------------------------*/
13639 +{
13640 +       return( 0 );
13641 +}
13642 +
13643 +/*----------------------------------------------------------------------------*/
13644 +void OsDetachDevice( 
13645 +       Sa_ADAPTER_EXTENSION *AdapterExtension )
13646 +/*----------------------------------------------------------------------------*/
13647 +{
13648 +       OsUnMapDeviceRegisters( AdapterExtension );
13649 +       return( 0 );
13650 +}
13651 +
13652 +/*----------------------------------------------------------------------------*/
13653 +ULONG *OsAllocCommPhysMem(
13654 +       Sa_ADAPTER_EXTENSION    *AdapterExtension, 
13655 +       ULONG                                   size,
13656 +       ULONG                                   **virt_addr_pptr,
13657 +       ULONG                                   *phys_addr_ptr )
13658 +/*----------------------------------------------------------------------------*/
13659 +{
13660 +       if( ( *virt_addr_pptr = ( ULONG * )OsAllocMemory( size, GFP_KERNEL ) ) )
13661 +       {
13662 +               *phys_addr_ptr = OsVirtToPhys( ( volatile void * )*virt_addr_pptr );
13663 +               if( !*phys_addr_ptr )
13664 +               {
13665 +                       cmn_err( CE_WARN, "OsAllocCommPhysMem: OsVirtToPhys failed" );
13666 +               }
13667 +                               
13668 +               return( *virt_addr_pptr );
13669 +       }
13670 +       else
13671 +               return( NULL );
13672 +}
13673 +
13674 +OsAifKernelThread(
13675 +       Sa_ADAPTER_EXTENSION    *AdapterExtension )
13676 +{
13677 +
13678 +       struct fs_struct *fs;
13679 +       int i;
13680 +       struct task_struct *tsk;
13681 +
13682 +       tsk = current;
13683 +
13684 +
13685 +       /*
13686 +        * set up the name that will appear in 'ps'
13687 +        * stored in  task_struct.comm[16].
13688 +        */
13689 +
13690 +       sprintf(tsk->comm, "AIFd");
13691 +
13692 +
13693 +       // use_init_fs_context();  only exists in 2.2.13 onward.
13694 +
13695 +#ifdef CONFIG_SMP
13696 +       lock_kernel();
13697 +#endif
13698 +
13699 +       /*
13700 +        * we were started as a result of loading the  module.
13701 +        * free all of user space pages
13702 +        */
13703 +
13704 +       exit_mm(tsk);
13705 +
13706 +       exit_files(tsk);
13707 +
13708 +       exit_fs(tsk);
13709 +
13710 +       fs = init_task.fs;
13711 +       tsk->fs = fs;
13712 +
13713 +       tsk->session = 1;
13714 +       tsk->pgrp = 1;
13715 +
13716 +       if (fs)
13717 +               atomic_inc(&fs->count);
13718 +
13719 +#ifdef CONFIG_SMP
13720 +       unlock_kernel();
13721 +#endif
13722 +
13723 +
13724 +
13725 +
13726 +       NormCommandThread(AdapterExtension);
13727 +       /* NOT REACHED */
13728 +}
13729 +
13730 +/*----------------------------------------------------------------------------*/
13731 +void OsStartKernelThreads(
13732 +       Sa_ADAPTER_EXTENSION    *AdapterExtension )
13733 +/*----------------------------------------------------------------------------*/
13734 +{
13735 +       PCI_MINIPORT_COMMON_EXTENSION   *CommonExtension;
13736 +       AFA_COMM_ADAPTER                                *Adapter;
13737 +       extern void                                     NormCommandThread(void *Adapter);
13738 +
13739 +       CommonExtension = AdapterExtension->Common;
13740 +       Adapter = (AFA_COMM_ADAPTER *)CommonExtension->Adapter;
13741 +
13742 +       // 
13743 +       // Start thread which will handle interrupts for this adapter
13744 +       //
13745 +       //kthread_spawn(FsaCommIntrHandler, AdapterExtension, "fsaintr",0);
13746 +
13747 +       //
13748 +       // Start thread which will handle AdapterInititatedFibs from this adapter
13749 +       //
13750 +       CommonExtension->OsDep.thread_pid = 
13751 +               kernel_thread( ( int ( * )( void * ) )OsAifKernelThread, Adapter, 0 );
13752 +//             kernel_thread( ( int ( * )( void * ) )NormCommandThread, Adapter, 0 );
13753 +}
13754 +
13755 +/*----------------------------------------------------------------------------*/
13756 +BOOLEAN AfaPortAllocateAndMapFibSpace(
13757 +       PVOID Arg1,
13758 +    IN PMAPFIB_CONTEXT MapFibContext )
13759 +/*----------------------------------------------------------------------------*/
13760 +{
13761 +       PVOID           BaseAddress;
13762 +       ULONG           PhysAddress;
13763 +
13764 +       if( !( BaseAddress = (ULONG *)OsAllocMemory( MapFibContext->Size, GFP_KERNEL ) ) )
13765 +       {
13766 +               cmn_err( CE_WARN, "AfaPortAllocateAndMapFibSpace: OsAllocMemory failed" );
13767 +               return( FALSE );
13768 +       }
13769 +
13770 +       PhysAddress = OsVirtToPhys( BaseAddress );
13771 +       
13772 +       MapFibContext->FibVirtualAddress = BaseAddress;
13773 +       MapFibContext->FibPhysicalAddress = (PVOID) PhysAddress;
13774 +
13775 +       return (TRUE);
13776 +}
13777 +
13778 +/*----------------------------------------------------------------------------*/
13779 +BOOLEAN AfaPortUnmapAndFreeFibSpace(
13780 +       PVOID Arg1,
13781 +    IN PMAPFIB_CONTEXT MapFibContext )
13782 +/*----------------------------------------------------------------------------*/
13783 +{
13784 +       PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
13785 +
13786 +       OsFreeMemory( MapFibContext->FibVirtualAddress, 0 );
13787 +
13788 +       return (TRUE);
13789 +}
13790 +
13791 +/*----------------------------------------------------------------------------*/
13792 +BOOLEAN AfaPortFreeAdapterCommArea(
13793 +       IN PVOID Arg1 )
13794 +/*----------------------------------------------------------------------------*/
13795 +{
13796 +       PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
13797 +
13798 +       OsFreeMemory( CommonExtension->CommAddress, 0 );
13799 +
13800 +       return (TRUE);
13801 +}
13802 +
13803 +
13804 +/* ================================================================================ */
13805 +/*
13806 + * Not sure if the functions below here ever get called in the current code
13807 + * These probably should be a different file.
13808 + */
13809 +/*
13810 +ddi_dma_attr_t AfaPortDmaAttributes = {
13811 +       //rpbfix : we may want something different for I/O
13812 +       DMA_ATTR_V0,
13813 +       0,
13814 +       0xffffffff,
13815 +       0x0000ffff,
13816 +       1,
13817 +       1,
13818 +       1,
13819 +       0x0000ffff,
13820 +       0x0000ffff,
13821 +       17,
13822 +       512,
13823 +       0
13824 +};
13825 +*/
13826 +
13827 +AAC_STATUS
13828 +AfaPortBuildSgMap(
13829 +       PVOID Arg1,
13830 +       IN PSGMAP_CONTEXT SgMapContext
13831 +       )
13832 +
13833 +/*++
13834 +
13835 +Routine Description:
13836 +
13837 +       This routine build a scatter gather map using the information
13838 +       in the SgMapContext.
13839 +
13840 +Arguments:
13841 +
13842 +       AdapterExtension - Pointer to adapter extension structure.
13843 +    SgMapContext - Pointer to the SgMapContext for the request.
13844 +
13845 +
13846 +Return Value:
13847 +
13848 +       AAC_STATUS      
13849 +--*/
13850 +{
13851 +       printk( KERN_ALERT "AfaPortBuildSgMap: unimplemented function called" );
13852 +       return (STATUS_UNSUCCESSFUL);
13853 +}
13854 +
13855 +VOID
13856 +AfaPortFreeDmaResources(
13857 +       PVOID Arg1,
13858 +    IN PSGMAP_CONTEXT SgMapContext
13859 +    )
13860 +
13861 +/*++
13862 +
13863 +Routine Description:
13864 +
13865 +    Given a pointer to the IRP context will free all reserved DMA resources allocated for
13866 +    the completed IO operation.
13867 +
13868 +Arguments:
13869 +
13870 +    Fib - Pointer to the Fib the caller wishes to have transfered over to the adapter.
13871 +    Context - Pointer to the Irp Context we use to store the dma mapping information
13872 +        we need to do and complete the IO.
13873 +
13874 +Return Value:
13875 +
13876 +    Nothing
13877 +
13878 +--*/
13879 +{
13880 +}
13881 diff -burN linux-2.4.7/drivers/scsi/aacraid/osfuncs.c linux/drivers/scsi/aacraid/osfuncs.c
13882 --- linux-2.4.7/drivers/scsi/aacraid/osfuncs.c  Wed Dec 31 18:00:00 1969
13883 +++ linux/drivers/scsi/aacraid/osfuncs.c        Sat Jul 21 17:55:14 2001
13884 @@ -0,0 +1,598 @@
13885 +/*++
13886 + * Adaptec aacraid device driver for Linux.
13887 + *
13888 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
13889 + *
13890 + * This program is free software; you can redistribute it and/or modify
13891 + * it under the terms of the GNU General Public License as published by
13892 + * the Free Software Foundation; either version 2, or (at your option)
13893 + * any later version.
13894 + *
13895 + * This program is distributed in the hope that it will be useful,
13896 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
13897 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13898 + * GNU General Public License for more details.
13899 + *
13900 + * You should have received a copy of the GNU General Public License
13901 + * along with this program; see the file COPYING.  If not, write to
13902 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
13903 + *
13904 + * Module Name:
13905 + *  osfuncs.c
13906 + *
13907 + * Abstract: Holds all of the O/S specific interface functions.
13908 + *     
13909 + --*/
13910 +
13911 +static char *ident_osfuncs = "aacraid_ident osfuncs.c 1.0.6 2000/10/09 Adaptec, Inc.";
13912 +
13913 +#include "osheaders.h"
13914 +
13915 +//static LKINFO_DECL(fsa_locks, "fsa_locks",0);
13916 +
13917 +extern aac_options_t g_options;
13918 +
13919 +OS_SOFTINTR g_idle_task = { 0, 0, 0, 0 };
13920 +wait_queue_t * g_wait_queue_ptr = NULL;
13921 +wait_queue_t g_wait;
13922 +
13923 +void OsTimeoutHandler( 
13924 +       struct semaphore * sem );
13925 +
13926 +int * OsIdleTask( void * data );
13927 +
13928 +//-----------------------------------------------------------------------------
13929 +// Memory Allocation functions
13930 +
13931 +/*----------------------------------------------------------------------------*/
13932 +void * OsAllocMemory(
13933 +       OS_SIZE_T Size,
13934 +       unsigned int Flags )
13935 +/*----------------------------------------------------------------------------*/
13936 +{
13937 +       void *mem_ptr;
13938 +
13939 +       if( !( mem_ptr = kmalloc( Size, GFP_KERNEL ) ) )
13940 +               cmn_err( CE_WARN, "OsAllocMemory: FAILED\n" );
13941 +       return( mem_ptr );
13942 +}
13943 +
13944 +
13945 +/*----------------------------------------------------------------------------*/
13946 +void OsFreeMemory(
13947 +       void * Buffer,
13948 +       OS_SIZE_T Size )
13949 +/*----------------------------------------------------------------------------*/
13950 +{
13951 +       kfree( Buffer );
13952 +}
13953 +
13954 +
13955 +/*----------------------------------------------------------------------------*/
13956 +int OsRegisterInterrupt(
13957 +       unsigned int irq,               // interrupt number
13958 +       void ( *handler )( int, void*, struct pt_regs * ),      // handler function
13959 +       void *irq_data )                // argument to handler function
13960 +/*----------------------------------------------------------------------------*/
13961 +{
13962 +  return( request_irq (irq, handler, SA_INTERRUPT | SA_SHIRQ,  "aacraid", irq_data ) );
13963 +}
13964 +
13965 +
13966 +/*----------------------------------------------------------------------------*/
13967 +void OsUnregisterInterrupt(
13968 +       unsigned int irq,               // interrupt number
13969 +       void *irq_data)
13970 +/*----------------------------------------------------------------------------*/
13971 +{
13972 +       free_irq (
13973 +               irq,                                                                            // interrupt number
13974 +               irq_data );
13975 +}
13976 +
13977 +
13978 +/*----------------------------------------------------------------------------*/
13979 +unsigned long OsVirtToPhys( 
13980 +       void * virtual_address )
13981 +/*----------------------------------------------------------------------------*/
13982 +{
13983 +       return( virt_to_phys( virtual_address ) );
13984 +}
13985 +
13986 +
13987 +//-----------------------------------------------------------------------------
13988 +// MUTEX functions
13989 +
13990 +/*----------------------------------------------------------------------------*/
13991 +OS_STATUS OsMutexInit( 
13992 +       OS_MUTEX *Mutex,
13993 +       OS_SPINLOCK_COOKIE Cookie )
13994 +/*----------------------------------------------------------------------------*/
13995 +{
13996 +       Mutex->lock_var = 0;
13997 +       //      bzero (&Mutex->wq, sizeof (Mutex->wq));
13998 +       init_waitqueue_head (&Mutex->wq);
13999 +       return ( 0 );
14000 +}
14001 +
14002 +
14003 +/*----------------------------------------------------------------------------*/
14004 +void OsMutexDestroy( 
14005 +       OS_MUTEX *Mutex )
14006 +/*----------------------------------------------------------------------------*/
14007 +{
14008 +}
14009 +
14010 +
14011 +/*----------------------------------------------------------------------------*/
14012 +void OsMutexAcquire( 
14013 +       OS_MUTEX *Mutex )
14014 +/*----------------------------------------------------------------------------*/
14015 +{
14016 +  //   wait_queue_t wait = { current, NULL };
14017 +       unsigned long time_stamp;
14018 +
14019 +       DECLARE_WAITQUEUE (wait, current);
14020 +
14021 +       time_stamp = jiffies;
14022 +
14023 +       if( test_and_set_bit( 0, &( Mutex->lock_var ) ) != 0 )
14024 +       {
14025 +               if( in_interrupt() )
14026 +                       panic( "OsMutexAcquire going to sleep at interrupt time\n" );
14027 +               current->state = TASK_INTERRUPTIBLE;
14028 +               add_wait_queue( &( Mutex->wq ), &wait );
14029 +               while( test_and_set_bit( 0, &( Mutex->lock_var ) ) != 0 )
14030 +                       schedule();
14031 +               remove_wait_queue( &( Mutex->wq ), &wait );
14032 +       }
14033 +
14034 +       if( ( jiffies - 1 ) > time_stamp )
14035 +               cmn_err( CE_WARN, "Mutex %ld locked out for %ld ticks", 
14036 +                       Mutex, jiffies - time_stamp );
14037 +}
14038 +
14039 +
14040 +/*----------------------------------------------------------------------------*/
14041 +void OsMutexRelease( 
14042 +       OS_MUTEX *Mutex )
14043 +/*----------------------------------------------------------------------------*/
14044 +{
14045 +       if( test_and_clear_bit( 0, &( Mutex->lock_var ) ) == 0 )
14046 +               cmn_err( CE_WARN, "OsMutexRelease: mutex not locked" );
14047 +       wake_up_interruptible( &( Mutex->wq ) );
14048 +}
14049 +
14050 +// see man hierarchy(D5)
14051 +#define FSA_LOCK 1
14052 +
14053 +//-----------------------------------------------------------------------------
14054 +// Spinlock functions
14055 +
14056 +/*----------------------------------------------------------------------------*/
14057 +OS_SPINLOCK * OsSpinLockAlloc( void ) 
14058 +/*----------------------------------------------------------------------------*/
14059 +{
14060 +       OS_SPINLOCK *SpinLock;
14061 +       int i;
14062 +
14063 +
14064 +       SpinLock = ( OS_SPINLOCK * )kmalloc( sizeof( OS_SPINLOCK ), GFP_KERNEL );
14065 +
14066 +       if (SpinLock == NULL)
14067 +               cmn_err (CE_WARN, "WARNING: OsSpinLockAlloc Failed!!!");
14068 +       
14069 +       SpinLock->spin_lock = SPIN_LOCK_UNLOCKED;
14070 +       for( i = 0; i < NR_CPUS; i++ )
14071 +               SpinLock->cpu_lock_count[ i ] = 0;
14072 +       return( SpinLock );
14073 +}
14074 +
14075 +
14076 +/*----------------------------------------------------------------------------*/
14077 +OS_STATUS OsSpinLockInit( 
14078 +       OS_SPINLOCK *SpinLock,
14079 +       OS_SPINLOCK_COOKIE Cookie )
14080 +/*----------------------------------------------------------------------------*/
14081 +{
14082 +       return( 0 );
14083 +}
14084 +
14085 +
14086 +/*----------------------------------------------------------------------------*/
14087 +void OsSpinLockDestroy( 
14088 +       OS_SPINLOCK *SpinLock )
14089 +/*----------------------------------------------------------------------------*/
14090 +{
14091 +       kfree( SpinLock );
14092 +       SpinLock = NULL;
14093 +}
14094 +
14095 +
14096 +/*----------------------------------------------------------------------------*/
14097 +void OsSpinLockAcquire( 
14098 +       OS_SPINLOCK *SpinLock )
14099 +/*----------------------------------------------------------------------------*/
14100 +{
14101 +       unsigned cpu_id;
14102 +
14103 +       if( SpinLock )
14104 +       {
14105 +               cpu_id = smp_processor_id();
14106 +               if( SpinLock->cpu_lock_count[ cpu_id ] ){
14107 +                       cmn_err (CE_PANIC, "CPU %d trying to acquire lock again: lock count = %d\n",
14108 +                                cpu_id, SpinLock->cpu_lock_count[ cpu_id ]);
14109 +               }                 
14110 +               
14111 +               spin_lock_irqsave( &( SpinLock->spin_lock ), SpinLock->cpu_flags[ cpu_id ] );
14112 +               SpinLock->cpu_lock_count[ cpu_id ]++;
14113 +          
14114 +       } else {
14115 +               cmn_err( CE_WARN, "OsSpinLockAcquire: lock does not exist" );
14116 +       }
14117 +}
14118 +
14119 +
14120 +/*----------------------------------------------------------------------------*/
14121 +void OsSpinLockRelease( 
14122 +       OS_SPINLOCK *SpinLock )
14123 +/*----------------------------------------------------------------------------*/
14124 +{
14125 +       unsigned cpu_id;
14126 +
14127 +       if( SpinLock )
14128 +       {
14129 +               cpu_id = smp_processor_id();
14130 +               SpinLock->cpu_lock_count[ cpu_id ]--;
14131 +               spin_unlock_irqrestore( &( SpinLock->spin_lock ), SpinLock->cpu_flags[ cpu_id ] );
14132 +       }
14133 +       else
14134 +               cmn_err( CE_WARN, "OsSpinLockRelease: lock does not exist" );
14135 +}
14136 +
14137 +
14138 +/*----------------------------------------------------------------------------*/
14139 +int OsSpinLockOwned(
14140 +       OS_SPINLOCK *SpinLock )
14141 +/*----------------------------------------------------------------------------*/
14142 +{
14143 +#ifdef CONFIG_SMP
14144 +       if( SpinLock->spin_lock.lock != 0 )
14145 +               return( 1 );
14146 +       else
14147 +#endif
14148 +               return( 0 );
14149 +}
14150 +
14151 +
14152 +//-----------------------------------------------------------------------------
14153 +// CvLock functions
14154 +
14155 +/*----------------------------------------------------------------------------*/
14156 +OS_CVLOCK *OsCvLockAlloc( void ) 
14157 +{
14158 +       OS_CVLOCK *cv_lock;
14159 +
14160 +
14161 +#ifdef CVLOCK_USE_SPINLOCK
14162 +       cv_lock = OsSpinLockAlloc(); 
14163 +#else
14164 +       cv_lock = ( OS_CVLOCK * )kmalloc( sizeof( OS_CVLOCK ), GFP_KERNEL );
14165 +       cv_lock->wq = NULL;
14166 +       cv_lock->lock_var = 0;
14167 +#endif
14168 +
14169 +       return( cv_lock );
14170 +}
14171 +
14172 +
14173 +/*----------------------------------------------------------------------------*/
14174 +OS_STATUS OsCvLockInit( 
14175 +       OS_CVLOCK *cv_lock,
14176 +       OS_SPINLOCK_COOKIE Cookie )
14177 +/*----------------------------------------------------------------------------*/
14178 +{
14179 +       return ( 0 );
14180 +}
14181 +
14182 +
14183 +/*----------------------------------------------------------------------------*/
14184 +void OsCvLockDestroy( 
14185 +       OS_CVLOCK *cv_lock )
14186 +/*----------------------------------------------------------------------------*/
14187 +{
14188 +       if( cv_lock )
14189 +               kfree( cv_lock );
14190 +       cv_lock = NULL;
14191 +}
14192 +
14193 +
14194 +/*----------------------------------------------------------------------------*/
14195 +void OsCvLockAcquire (OS_CVLOCK *cv_lock)
14196 +{
14197 +#ifdef CVLOCK_USE_SPINLOCK
14198 +               OsSpinLockAcquire( cv_lock );
14199 +#else
14200 +               OsMutexAcquire( cv_lock );
14201 +#endif
14202 +}
14203 +
14204 +
14205 +/*----------------------------------------------------------------------------*/
14206 +void OsCvLockRelease( 
14207 +       OS_CVLOCK *cv_lock )
14208 +/*----------------------------------------------------------------------------*/
14209 +{
14210 +#ifdef CVLOCK_USE_SPINLOCK
14211 +               OsSpinLockRelease( cv_lock );
14212 +#else
14213 +               OsMutexRelease( cv_lock );
14214 +#endif
14215 +}
14216 +
14217 +
14218 +/*----------------------------------------------------------------------------*/
14219 +int OsCvLockOwned(
14220 +       OS_CVLOCK *cv_lock )
14221 +/*----------------------------------------------------------------------------*/
14222 +{
14223 +       return( 1 );
14224 +}
14225 +
14226 +
14227 +//-----------------------------------------------------------------------------
14228 +// Conditional variable functions
14229 +
14230 +/*----------------------------------------------------------------------------*/
14231 +void OsCv_init ( 
14232 +       OS_CV_T *cv_ptr )
14233 +/*----------------------------------------------------------------------------*/
14234 +{
14235 +       cv_ptr->lock_var = 1;
14236 +       init_waitqueue_head (&cv_ptr->wq);
14237 +}
14238 +
14239 +
14240 +/*----------------------------------------------------------------------------*/
14241 +void OsCv_destroy( 
14242 +       OS_CV_T  *cv_ptr )
14243 +/*----------------------------------------------------------------------------*/
14244 +{
14245 +}
14246 +
14247 +
14248 +/*______________________________________________________________________________
14249 + -
14250 + -
14251 + -----------------------------------------------------------------------------*/
14252 +OsCv_wait (OS_CV_T *cv_ptr, OS_CVLOCK *cv_lock_ptr)
14253 +{
14254 +       unsigned long flags;
14255 +
14256 +       DECLARE_WAITQUEUE (wait, current);
14257 +       
14258 +       if( in_interrupt() )
14259 +               panic( "OsCv_wait going to sleep at interrupt time\n" );
14260 +
14261 +       cv_ptr->type = TASK_UNINTERRUPTIBLE;
14262 +       current->state = TASK_UNINTERRUPTIBLE;
14263 +
14264 +       add_wait_queue( &cv_ptr->wq, &wait );
14265 +
14266 +       OsCvLockRelease( cv_lock_ptr );
14267 +       schedule();
14268 +
14269 +       while( test_and_set_bit( 0, &( cv_ptr->lock_var ) ) != 0 )
14270 +       {
14271 +               if( in_interrupt() )
14272 +                       panic( "OsCv_wait going to sleep at interrupt time\n" );
14273 +               schedule();
14274 +       }
14275 +
14276 +       remove_wait_queue( &( cv_ptr->wq ), &wait );
14277 +
14278 +       OsCvLockAcquire( cv_lock_ptr );
14279 +}
14280 +
14281 +
14282 +/*----------------------------------------------------------------------------*/
14283 +int OsCv_wait_sig( 
14284 +       OS_CV_T *cv_ptr,
14285 +       OS_CVLOCK *cv_lock_ptr ) 
14286 +/*----------------------------------------------------------------------------*/
14287 +{
14288 +       unsigned long flags;
14289 +       int signal_state = 1;
14290 +
14291 +       DECLARE_WAITQUEUE (wait, current);
14292 +       
14293 +       if( in_interrupt() )
14294 +               panic( "OsCv_wait_sig going to sleep at interrupt time\n" );
14295 +
14296 +       cv_ptr->type = TASK_INTERRUPTIBLE;
14297 +       current->state = TASK_INTERRUPTIBLE;
14298 +
14299 +       add_wait_queue( &( cv_ptr->wq ), &wait );
14300 +
14301 +       OsCvLockRelease( cv_lock_ptr );
14302 +       schedule();
14303 +
14304 +       while( ( test_and_set_bit( 0, &( cv_ptr->lock_var ) ) != 0 ) && 
14305 +                       ( !signal_pending( current ) ) )
14306 +       {
14307 +               if( in_interrupt() )
14308 +                       panic( "OsCv_wait_sig going to sleep at interrupt time\n" );
14309 +               schedule();
14310 +       }
14311 +
14312 +       if( signal_pending( current ) )
14313 +               signal_state = 0;
14314 +       
14315 +       remove_wait_queue( &( cv_ptr->wq ), &wait );
14316 +       
14317 +       OsCvLockAcquire( cv_lock_ptr );
14318 +       return( signal_state );
14319 +}
14320 +
14321 +
14322 +/*----------------------------------------------------------------------------*/
14323 +void OsCv_signal( 
14324 +       OS_CV_T *cv_ptr )
14325 +/*----------------------------------------------------------------------------*/
14326 +{
14327 +
14328 +       clear_bit( 0, &( cv_ptr->lock_var ) );
14329 +       if( cv_ptr->type == TASK_INTERRUPTIBLE )
14330 +                       wake_up_interruptible( &( cv_ptr->wq ) );
14331 +       else{
14332 +                       wake_up( &( cv_ptr->wq ) );
14333 +       }
14334 +}
14335 +
14336 +
14337 +// return time in seconds
14338 +/*----------------------------------------------------------------------------*/
14339 +unsigned long OsGetSeconds( void )
14340 +/*----------------------------------------------------------------------------*/
14341 +{
14342 +       return( jiffies/HZ );
14343 +}
14344 +
14345 +
14346 +//-----------------------------------------------------------------------------
14347 +// Deferred procedure call functions
14348 +
14349 +// create a soft interrupt object
14350 +/*----------------------------------------------------------------------------*/
14351 +int OsSoftInterruptAdd( 
14352 +       OS_SOFTINTR **ptr,
14353 +       void * handler,
14354 +       void * data )
14355 +/*----------------------------------------------------------------------------*/
14356 +{
14357 +       OS_SOFTINTR *tmp_ptr;
14358 +
14359 +       if( !( tmp_ptr = ( OS_SOFTINTR * )kmalloc( sizeof( OS_SOFTINTR ), GFP_KERNEL ) ) )
14360 +               return( -1 );
14361 +       tmp_ptr->routine = handler;
14362 +       tmp_ptr->data = data;
14363 +       tmp_ptr->sync = 0;
14364 +
14365 +       *ptr = tmp_ptr; 
14366 +
14367 +       return( 0 );
14368 +}
14369 +
14370 +/*
14371 +       Use kernel_thread( ( int ( * )( void * ) )OsIdleTask, NULL, 0 ); to start
14372 +*/
14373 +/*----------------------------------------------------------------------------*/
14374 +int * OsIdleTask( void * data )
14375 +/*----------------------------------------------------------------------------*/
14376 +{
14377 +       DECLARE_WAITQUEUE (wait, current);
14378 +
14379 +       while( 1 )
14380 +       {
14381 +               current->state = TASK_INTERRUPTIBLE;
14382 +               add_wait_queue( &g_wait_queue_ptr, &wait );
14383 +               schedule();
14384 +               remove_wait_queue( &g_wait_queue_ptr, &wait );
14385 +               wait.task =  current;
14386 +               wait.task_list.next = NULL;
14387 +       }
14388 +       return( NULL );
14389 +}
14390 +
14391 +
14392 +// dispatch a soft interrupt 
14393 +/*----------------------------------------------------------------------------*/
14394 +void OsSoftInterruptTrigger( 
14395 +       OS_SOFTINTR *soft_intr_ptr )
14396 +/*----------------------------------------------------------------------------*/
14397 +{
14398 +       // call the completion routine directly
14399 +       soft_intr_ptr->routine( soft_intr_ptr->data );
14400 +}
14401 +
14402 +
14403 +// delete a soft interrupt object
14404 +/*----------------------------------------------------------------------------*/
14405 +void OsSoftInterruptRemove( 
14406 +       OS_SOFTINTR *arg )
14407 +/*----------------------------------------------------------------------------*/
14408 +{
14409 +       if( arg )
14410 +               kfree( arg );
14411 +       arg = NULL;
14412 +}
14413 +
14414 +
14415 +/*----------------------------------------------------------------------------*/
14416 +void OsSleep( 
14417 +       unsigned time )         // in seconds
14418 +/*----------------------------------------------------------------------------*/
14419 +{
14420 +       struct semaphore sem;
14421 +       struct timer_list timer_var;
14422 +       
14423 +       init_MUTEX_LOCKED (&sem);
14424 +
14425 +       //      if( in_interrupt() )
14426 +       //              panic( "OsSleep going to sleep at interrupt time\n" );
14427 +
14428 +       init_timer( &timer_var );
14429 +       timer_var.function = ( void ( * )( unsigned long ) )OsTimeoutHandler;
14430 +       timer_var.data = ( unsigned long )&sem;
14431 +       timer_var.expires = jiffies + time * HZ;
14432 +
14433 +       add_timer( &timer_var );
14434 +       down( &sem );
14435 +
14436 +       del_timer( &timer_var );
14437 +}
14438 +
14439 +
14440 +/*----------------------------------------------------------------------------*/
14441 +void OsTimeoutHandler( 
14442 +       struct semaphore * sem )
14443 +/*----------------------------------------------------------------------------*/
14444 +{
14445 +       if( sem != NULL )
14446 +               up( sem );
14447 +}
14448 +
14449 +
14450 +/*----------------------------------------------------------------------------*/
14451 +void printk_err(
14452 +       int flag, 
14453 +       char *fmt, 
14454 +       ...)
14455 +/*----------------------------------------------------------------------------*/
14456 +{
14457 +       char    buf[256];
14458 +       va_list ap;
14459 +
14460 +       va_start(ap, fmt);
14461 +       (void) vsprintf(buf, fmt, ap);
14462 +       va_end(ap);
14463 +       
14464 +       if( flag <= g_options.message_level )
14465 +               printk(KERN_ALERT "%s\n", buf);
14466 +}
14467 +
14468 +/*  void aac_show_tasks (struct list_head *our_tasks){ */
14469
14470 +/*             cmn_err (CE_DEBUG, "Entering aac_show_tasks"); */
14471 +
14472 +/*             if (our_tasks->next == NULL || our_tasks->next == 0) */
14473 +/*                             cmn_err (CE_DEBUG, "list_head->next is NULL or 0"); */
14474 +/*             else */
14475 +/*                             cmn_err (CE_DEBUG, "list_head->next: 0x%x", our_tasks->next); */
14476 +
14477 +/*             if (our_tasks->prev == NULL || our_tasks->prev == 0) */
14478 +/*                             cmn_err (CE_DEBUG, "list_head->prev is NULL or 0"); */
14479 +/*             else */
14480 +/*                             cmn_err (CE_DEBUG, "list_head->prev: 0x%x", our_tasks->prev); */
14481 +
14482 +/*  } */
14483 diff -burN linux-2.4.7/drivers/scsi/aacraid/ossup.c linux/drivers/scsi/aacraid/ossup.c
14484 --- linux-2.4.7/drivers/scsi/aacraid/ossup.c    Wed Dec 31 18:00:00 1969
14485 +++ linux/drivers/scsi/aacraid/ossup.c  Sat Jul 21 17:55:14 2001
14486 @@ -0,0 +1,199 @@
14487 +/*++
14488 + * Adaptec aacraid device driver for Linux.
14489 + *
14490 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
14491 + *
14492 + * This program is free software; you can redistribute it and/or modify
14493 + * it under the terms of the GNU General Public License as published by
14494 + * the Free Software Foundation; either version 2, or (at your option)
14495 + * any later version.
14496 + *
14497 + * This program is distributed in the hope that it will be useful,
14498 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
14499 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14500 + * GNU General Public License for more details.
14501 + *
14502 + * You should have received a copy of the GNU General Public License
14503 + * along with this program; see the file COPYING.  If not, write to
14504 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
14505 + *
14506 + * Module Name:
14507 + *  ossup.c
14508 + *
14509 + * 
14510 + *
14511 + --*/
14512 +
14513 +static char *ident_ossup = "aacraid_ident ossup.c 1.0.6 2000/10/09 Adaptec, Inc.";
14514 +
14515 +#include "osheaders.h"
14516 +
14517 +#include "aac_unix_defs.h"
14518 +
14519 +
14520 +AAC_STATUS
14521 +ExInitializeZone(
14522 +    IN PZONE_HEADER Zone,
14523 +    IN ULONG BlockSize,
14524 +    IN PVOID InitialSegment,
14525 +    IN ULONG InitialSegmentSize
14526 +    )
14527 +
14528 +/*++
14529 +
14530 +Routine Description:
14531 +
14532 +    This function initializes a zone header.  Once successfully
14533 +    initialized, blocks can be allocated and freed from the zone, and
14534 +    the zone can be extended.
14535 +
14536 +Arguments:
14537 +
14538 +    Zone - Supplies the address of a zone header to be initialized.
14539 +
14540 +    BlockSize - Supplies the block size of the allocatable unit within
14541 +                the zone.  The size must be larger that the size of the
14542 +                initial segment, and must be 64-bit aligned.
14543 +
14544 +    InitialSegment - Supplies the address of a segment of storage.  The
14545 +                     first ZONE_SEGMENT_HEADER-sized portion of the segment
14546 +                     is used by the zone allocator.  The remainder of
14547 +                     the segment is carved up into fixed size
14548 +                     (BlockSize) blocks and is made available for
14549 +                     allocation and deallocation from the zone.  The
14550 +                     address of the segment must be aligned on a 64-bit
14551 +                     boundary.
14552 +
14553 +    InitialSegmentSize - Supplies the size in bytes of the InitialSegment.
14554 +
14555 +Return Value:
14556 +
14557 +    STATUS_UNSUCCESSFUL - BlockSize or InitialSegment was not aligned on
14558 +                          64-bit boundaries, or BlockSize was larger than
14559 +                          the initial segment size.
14560 +
14561 +    STATUS_SUCCESS - The zone was successfully initialized.
14562 +
14563 +--*/
14564 +
14565 +{
14566 +    ULONG i;
14567 +    PCHAR p;
14568 +
14569 +
14570 +    Zone->BlockSize = BlockSize;
14571 +
14572 +    Zone->SegmentList.Next = &((PZONE_SEGMENT_HEADER) InitialSegment)->SegmentList;
14573 +    ((PZONE_SEGMENT_HEADER) InitialSegment)->SegmentList.Next = NULL;
14574 +    ((PZONE_SEGMENT_HEADER) InitialSegment)->Reserved = NULL;
14575 +
14576 +    Zone->FreeList.Next = NULL;
14577 +
14578 +    p = (PCHAR)InitialSegment + sizeof(ZONE_SEGMENT_HEADER);
14579 +
14580 +    for (i = sizeof(ZONE_SEGMENT_HEADER);
14581 +         i <= InitialSegmentSize - BlockSize;
14582 +         i += BlockSize
14583 +        ) {
14584 +        ((PSINGLE_LIST_ENTRY)p)->Next = Zone->FreeList.Next;
14585 +        Zone->FreeList.Next = (PSINGLE_LIST_ENTRY)p;
14586 +        p += BlockSize;
14587 +    }
14588 +    Zone->TotalSegmentSize = i;
14589 +
14590 +#if 0
14591 +    DbgPrint( "EX: ExInitializeZone( %lx, %lx, %lu, %lu, %lx )\n",
14592 +              Zone, InitialSegment, InitialSegmentSize,
14593 +              BlockSize, p
14594 +            );
14595 +#endif
14596 +
14597 +    return STATUS_SUCCESS;
14598 +}
14599 +
14600 +AAC_STATUS
14601 +ExExtendZone(
14602 +    IN PZONE_HEADER Zone,
14603 +    IN PVOID Segment,
14604 +    IN ULONG SegmentSize
14605 +    )
14606 +
14607 +/*++
14608 +
14609 +Routine Description:
14610 +
14611 +    This function extends a zone by adding another segment's worth of
14612 +    blocks to the zone.
14613 +
14614 +Arguments:
14615 +
14616 +    Zone - Supplies the address of a zone header to be extended.
14617 +
14618 +    Segment - Supplies the address of a segment of storage.  The first
14619 +              ZONE_SEGMENT_HEADER-sized portion of the segment is used by the
14620 +              zone allocator.  The remainder of the segment is carved up
14621 +              into fixed-size (BlockSize) blocks and is added to the
14622 +              zone.  The address of the segment must be aligned on a 64-
14623 +              bit boundary.
14624 +
14625 +    SegmentSize - Supplies the size in bytes of Segment.
14626 +
14627 +Return Value:
14628 +
14629 +    STATUS_UNSUCCESSFUL - BlockSize or Segment was not aligned on
14630 +                          64-bit boundaries, or BlockSize was larger than
14631 +                          the segment size.
14632 +
14633 +    STATUS_SUCCESS - The zone was successfully extended.
14634 +
14635 +--*/
14636 +
14637 +{
14638 +    ULONG i;
14639 +    PCHAR p;
14640 +
14641 +
14642 +    ((PZONE_SEGMENT_HEADER) Segment)->SegmentList.Next = Zone->SegmentList.Next;
14643 +    Zone->SegmentList.Next = &((PZONE_SEGMENT_HEADER) Segment)->SegmentList;
14644 +
14645 +    p = (PCHAR)Segment + sizeof(ZONE_SEGMENT_HEADER);
14646 +
14647 +    for (i = sizeof(ZONE_SEGMENT_HEADER);
14648 +         i <= SegmentSize - Zone->BlockSize;
14649 +         i += Zone->BlockSize
14650 +        ) {
14651 +
14652 +        ((PSINGLE_LIST_ENTRY)p)->Next = Zone->FreeList.Next;
14653 +        Zone->FreeList.Next = (PSINGLE_LIST_ENTRY)p;
14654 +        p += Zone->BlockSize;
14655 +    }
14656 +    Zone->TotalSegmentSize += i;
14657 +
14658 +#if 0
14659 +    DbgPrint( "EX: ExExtendZone( %lx, %lx, %lu, %lu, %lx )\n",
14660 +              Zone, Segment, SegmentSize, Zone->BlockSize, p
14661 +            );
14662 +#endif
14663 +
14664 +    return STATUS_SUCCESS;
14665 +}
14666 +
14667 +DbgPrint()
14668 +{
14669 +}
14670 +
14671 +/* Function: InqStrCopy()
14672 + *
14673 + * Arguments: [2] pointer to char
14674 + *
14675 + * Purpose: Copy a String from one location to another
14676 + * without copying \0
14677 + */
14678 +void
14679 +InqStrCopy(char *a, char *b)
14680 +{
14681 +
14682 +       while(*a != (char)0) 
14683 +               *b++ = *a++;
14684 +}
14685 +
14686 diff -burN linux-2.4.7/drivers/scsi/aacraid/port.c linux/drivers/scsi/aacraid/port.c
14687 --- linux-2.4.7/drivers/scsi/aacraid/port.c     Wed Dec 31 18:00:00 1969
14688 +++ linux/drivers/scsi/aacraid/port.c   Sat Jul 21 17:55:14 2001
14689 @@ -0,0 +1,287 @@
14690 +/*++
14691 + * Adaptec aacraid device driver for Linux.
14692 + *
14693 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
14694 + *
14695 + * This program is free software; you can redistribute it and/or modify
14696 + * it under the terms of the GNU General Public License as published by
14697 + * the Free Software Foundation; either version 2, or (at your option)
14698 + * any later version.
14699 + *
14700 + * This program is distributed in the hope that it will be useful,
14701 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
14702 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14703 + * GNU General Public License for more details.
14704 + *
14705 + * You should have received a copy of the GNU General Public License
14706 + * along with this program; see the file COPYING.  If not, write to
14707 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
14708 + *
14709 + * Module Name:
14710 + *  port.c
14711 + *
14712 + * Abstract: All support routines for FSA communication which are miniport specific.
14713 + *
14714 + --*/
14715 +
14716 +static char *ident_port = "aacraid_ident port.c 1.0.7 2000/10/11 Adaptec, Inc.";
14717 +
14718 +#include "osheaders.h"
14719 +
14720 +
14721 +#include "AacGenericTypes.h"
14722 +
14723 +#include "aac_unix_defs.h"
14724 +
14725 +#include "fsatypes.h"
14726 +#include "comstruc.h"
14727 +#include "protocol.h"
14728 +
14729 +#include "fsaport.h"
14730 +#include "fsaioctl.h"
14731 +
14732 +#include "pcisup.h"
14733 +#include "port.h"
14734 +
14735 +int AfaPortPrinting = 1;
14736 +
14737 +extern AAC_STATUS AfaPort_Err_Adapter_Printf;
14738 +extern AAC_STATUS AfaPort_Warn_Adapter_Printf;
14739 +extern AAC_STATUS AfaPort_Info_Adapter_Printf;
14740 +extern AAC_STATUS AfaPort_Err_FastAfa_Load_Driver;
14741 +
14742 +
14743 +
14744 +VOID
14745 +AfaPortLogError(
14746 +       IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
14747 +       IN AAC_STATUS ErrorCode,
14748 +       IN PUCHAR StringBuffer,
14749 +       IN ULONG StringLength
14750 +       )
14751 +/*++
14752 +
14753 +Routine Description:
14754 +
14755 +       Does all of the work to log an error log entry
14756 +Arguments:
14757 +
14758 +       CommonExtension - Pointer to the adapter that caused the error.
14759 +
14760 +       ErrorCode - Which error is being logged.
14761 +
14762 +       StringBuffer - Pointer to optional String for error log entry.
14763 +
14764 +       StringLength - Length of StringBuffer.
14765 +
14766 +Return Value:
14767 +
14768 +    Nothing
14769 +
14770 +--*/
14771 +
14772 +{
14773 +
14774 +}
14775 +
14776 +BOOLEAN
14777 +AfaPortGetNextAdapterNumber(
14778 +    IN  PDRIVER_OBJECT  DriverObject,
14779 +       OUT PDEVICE_OBJECT      *FsaDeviceObject,
14780 +       OUT PFILE_OBJECT        *FileObject,
14781 +       OUT PULONG                      AdapterNumber
14782 +       )
14783 +{
14784 +}
14785 +BOOLEAN
14786 +AfaPortAllocateAdapterCommArea(
14787 +       IN PVOID                Arg1,
14788 +       IN OUT PVOID    *CommHeaderAddress,
14789 +       IN ULONG                CommAreaSize,
14790 +       IN ULONG                CommAreaAlignment
14791 +       )
14792 +{
14793 +       PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
14794 +       PVOID BaseAddress;
14795 +       PHYSICAL_ADDRESS PhysicalBaseAddress;
14796 +       ULONG TotalSize, BytesToAlign;
14797 +       size_t          RealLength;
14798 +       uint_t          Count;
14799 +//     ULONG SizeOfFastIoComm = sizeof(FASTIO_STRUCT);
14800 +//     ULONG AdapterFibsSize = PAGE_SIZE;
14801 +       ULONG AdapterFibsSize = 4096;
14802 +       ULONG PrintfBufferSize = 256;
14803 +       PADAPTER_INIT_STRUCT InitStruct;
14804 +       extern int MiniPortRevision;
14805 +       ULONG   PhysAddress;
14806 +
14807 +//     TotalSize = AdapterFibsSize + sizeof(ADAPTER_INIT_STRUCT) + CommAreaSize + CommAreaAlignment +
14808 +//              SizeOfFastIoComm + PrintfBufferSize;
14809 +       TotalSize = AdapterFibsSize + sizeof(ADAPTER_INIT_STRUCT) + CommAreaSize + CommAreaAlignment +
14810 +                PrintfBufferSize;
14811 +
14812 +
14813 +       OsAllocCommPhysMem(CommonExtension->MiniPort, TotalSize, &BaseAddress, &PhysAddress);
14814 +
14815 +       CommonExtension->CommAddress  = BaseAddress;
14816 +       CommonExtension->CommPhysAddr = PhysAddress;
14817 +       CommonExtension->CommSize         = TotalSize;
14818 +
14819 +       PhysicalBaseAddress.HighPart = 0;
14820 +       PhysicalBaseAddress.LowPart = PhysAddress;
14821 +
14822 +       CommonExtension->InitStruct = (PADAPTER_INIT_STRUCT)((PUCHAR)(BaseAddress) + AdapterFibsSize);
14823 +       CommonExtension->PhysicalInitStruct = (PADAPTER_INIT_STRUCT)((PUCHAR)(PhysicalBaseAddress.LowPart) + AdapterFibsSize);
14824 +
14825 +       InitStruct = CommonExtension->InitStruct;
14826 +
14827 +       InitStruct->InitStructRevision = ADAPTER_INIT_STRUCT_REVISION;
14828 +       InitStruct->MiniPortRevision = MiniPortRevision;
14829 +       InitStruct->FilesystemRevision = CommonExtension->FilesystemRevision;
14830 +
14831 +       //
14832 +       // Adapter Fibs are the first thing allocated so that they start page aligned
14833 +       //
14834 +       InitStruct->AdapterFibsVirtualAddress = BaseAddress;
14835 +       InitStruct->AdapterFibsPhysicalAddress = (PVOID) PhysicalBaseAddress.LowPart;
14836 +       InitStruct->AdapterFibsSize = AdapterFibsSize;
14837 +       InitStruct->AdapterFibAlign = sizeof(FIB);
14838 +
14839 +       //
14840 +       // Increment the base address by the amount already used
14841 +       //
14842 +       BaseAddress = (PVOID)((PUCHAR)(BaseAddress) + AdapterFibsSize + sizeof(ADAPTER_INIT_STRUCT));
14843 +       PhysicalBaseAddress.LowPart = (ULONG)((PUCHAR)(PhysicalBaseAddress.LowPart) + AdapterFibsSize + sizeof(ADAPTER_INIT_STRUCT));
14844 +
14845 +       //
14846 +       // Align the beginning of Headers to CommAreaAlignment
14847 +       //
14848 +       BytesToAlign = (CommAreaAlignment - ((ULONG)(BaseAddress) & (CommAreaAlignment - 1)));
14849 +       BaseAddress = (PVOID)((PUCHAR)(BaseAddress) + BytesToAlign);
14850 +       PhysicalBaseAddress.LowPart = (ULONG)((PUCHAR)(PhysicalBaseAddress.LowPart) + BytesToAlign);
14851 +
14852 +       //
14853 +       // Fill in addresses of the Comm Area Headers and Queues
14854 +       //
14855 +       *CommHeaderAddress = BaseAddress;
14856 +       InitStruct->CommHeaderAddress = (PVOID)PhysicalBaseAddress.LowPart;
14857 +
14858 +       //
14859 +       //      Increment the base address by the size of the CommArea
14860 +       //
14861 +       BaseAddress = (PVOID)((PUCHAR)(BaseAddress) + CommAreaSize);
14862 +       PhysicalBaseAddress.LowPart = (ULONG)((PUCHAR)(PhysicalBaseAddress.LowPart) + CommAreaSize);
14863 +
14864 +
14865 +       //
14866 +       // Place the Printf buffer area after the Fast I/O comm area.
14867 +       //
14868 +       CommonExtension->PrintfBufferAddress = (PVOID)(BaseAddress);
14869 +       InitStruct->PrintfBufferAddress = (PVOID)PhysicalBaseAddress.LowPart;
14870 +       InitStruct->PrintfBufferSize = PrintfBufferSize;
14871 +       bzero (BaseAddress, PrintfBufferSize);
14872 +
14873 +       AfaPortPrint("FsaAllocateAdapterCommArea: allocated a common buffer of 0x%x bytes from address 0x%x to address 0x%x\n",
14874 +                        TotalSize, InitStruct->AdapterFibsVirtualAddress,
14875 +                        (PUCHAR)(InitStruct->AdapterFibsVirtualAddress) + TotalSize);
14876 +
14877 +       AfaPortPrint("Mapped on to PCI address 0x%x\n", InitStruct->AdapterFibsPhysicalAddress);
14878 +
14879 +       return (TRUE);
14880 +}
14881 +
14882 +AAC_STATUS
14883 +AfaPortCreate (
14884 +    IN PDEVICE_OBJECT DeviceObject,
14885 +    IN PIRP Irp
14886 +    )
14887 +/*++
14888 +
14889 +Routine Description:
14890 +
14891 +       The routine will get called each time a user issues a CreateFile on the DeviceObject
14892 +       for the adapter.
14893 +
14894 +       The main purpose of this routine is to set up any data structures that may be needed
14895 +       to handle any requests made on this DeviceObject.
14896 +
14897 +Arguments:
14898 +
14899 +       DeviceObject - Pointer to device object representing adapter
14900 +
14901 +       Irp - Pointer to Irp that caused this open
14902 +
14903 +
14904 +Return Value:
14905 +
14906 +       Status value returned from File system driver AdapterOpen
14907 +
14908 +--*/
14909 +
14910 +{
14911 +}
14912 +
14913 +AAC_STATUS
14914 +AfaPortClose (
14915 +    IN PDEVICE_OBJECT DeviceObject,
14916 +    IN PIRP Irp
14917 +    )
14918 +/*++
14919 +
14920 +Routine Description:
14921 +
14922 +       This routine will get called each time a user issues a CloseHandle on the DeviceObject
14923 +       for the adapter.
14924 +
14925 +       The main purpose of this routine is to cleanup any data structures that have been set up
14926 +       while this FileObject has been opened.
14927 +
14928 +Arguments:
14929 +
14930 +       DeviceObject - Pointer to device object representing adapter
14931 +
14932 +       Irp - Pointer to Irp that caused this close
14933 +
14934 +Return Value:
14935 +
14936 +       Status value returned from File system driver AdapterClose
14937 +
14938 +--*/
14939 +
14940 +{
14941 +
14942 +}
14943 +
14944 +AAC_STATUS
14945 +AfaPortDeviceControl (
14946 +    IN PDEVICE_OBJECT DeviceObject,
14947 +    IN PIRP Irp
14948 +    )
14949 +{
14950 +
14951 +}
14952 +
14953 +ULONG
14954 +AfaPortGetMaxPhysicalPage(
14955 +       IN PPCI_MINIPORT_COMMON_EXTENSION       CommonExtension
14956 +       )
14957 +/*++
14958 +
14959 +Routine Description:
14960 +
14961 +       This routine determines the max physical page in host memory.
14962 +
14963 +Arguments:
14964 +
14965 +       AdapterExtension
14966 +
14967 +Return Value:
14968 +
14969 +       Max physical page in host memory.
14970 +
14971 +--*/
14972 +{
14973 +
14974 +}
14975 +
14976 +
14977 diff -burN linux-2.4.7/drivers/scsi/aacraid/rx.c linux/drivers/scsi/aacraid/rx.c
14978 --- linux-2.4.7/drivers/scsi/aacraid/rx.c       Wed Dec 31 18:00:00 1969
14979 +++ linux/drivers/scsi/aacraid/rx.c     Sat Jul 21 17:55:14 2001
14980 @@ -0,0 +1,917 @@
14981 +/*++
14982 + * Adaptec aacraid device driver for Linux.
14983 + *
14984 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
14985 + *
14986 + * This program is free software; you can redistribute it and/or modify
14987 + * it under the terms of the GNU General Public License as published by
14988 + * the Free Software Foundation; either version 2, or (at your option)
14989 + * any later version.
14990 + *
14991 + * This program is distributed in the hope that it will be useful,
14992 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
14993 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14994 + * GNU General Public License for more details.
14995 + *
14996 + * You should have received a copy of the GNU General Public License
14997 + * along with this program; see the file COPYING.  If not, write to
14998 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
14999 + *
15000 + * Module Name:
15001 + *  rx.c
15002 + *
15003 + * Abstract: Hardware miniport for Drawbridge specific hardware functions.
15004 + *
15005 + --*/
15006 +
15007 +static char *ident_rx = "aacraid_ident rx.c 1.0.7 2000/10/11 Adaptec, Inc.";
15008 +
15009 +#include "osheaders.h"
15010 +
15011 +
15012 +#include "AacGenericTypes.h"
15013 +
15014 +#include "aac_unix_defs.h"
15015 +
15016 +#include "fsatypes.h"
15017 +#include "comstruc.h"
15018 +#include "fsact.h"
15019 +#include "protocol.h"
15020 +
15021 +#define DEFINE_PCI_IDS
15022 +#include "rxcommon.h"
15023 +#include "monkerapi.h"
15024 +
15025 +#include "fsaport.h"
15026 +#include "fsaioctl.h"
15027 +
15028 +#include "pcisup.h"
15029 +#include "rx.h"
15030 +
15031 +#include "port.h"
15032 +
15033 +#define BugCheckFileId                   (FSAFS_BUG_CHECK_CYCLONESUP)
15034 +
15035 +// #define RxBugCheck(A,B,C) { KeBugCheckEx(0x00000AFA, __LINE__, (ULONG)A, (ULONG)B,(ULONG)C ); }
15036 +
15037 +#define RxBugCheck(A, B, C) {  cmn_err(CE_PANIC, "aacdisk : line %s, 0x%x, 0x%x, 0x%x ", __LINE__, A, B, C);  }
15038 +
15039 +#define NUM_TICKS_PER_SECOND (1000 * 1000 * 10) /* time is in 100 nanoseconds */
15040 +
15041 +
15042 +//
15043 +// The list of all the Rx adapter structures
15044 +//
15045 +
15046 +PRx_ADAPTER_EXTENSION  RxAdapterList;
15047 +
15048 +int
15049 +RxInitDevice(
15050 +       IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
15051 +       IN ULONG AdapterNumber,
15052 +       IN ULONG PciBus,
15053 +       IN ULONG PciSlot
15054 +);
15055 +
15056 +BOOLEAN
15057 +RxSendSynchFib(
15058 +       PVOID Arg1,
15059 +       ULONG FibPhysicalAddress
15060 +       );
15061 +
15062 +FSA_USER_VAR   RxUserVars[] = {
15063 +       { "AfaPortPrinting", (PULONG)&AfaPortPrinting, NULL },
15064 +};
15065 +
15066 +
15067 +//
15068 +// Declare private use routines for this modual
15069 +//
15070 +
15071 +u_int
15072 +RxPciIsr (
15073 +    IN PRx_ADAPTER_EXTENSION AdapterExtension
15074 +    )
15075 +
15076 +/*++
15077 +
15078 +Routine Description:
15079 +
15080 +    The Isr routine for fsa Rx based adapter boards.
15081 +
15082 +Arguments:
15083 +
15084 +
15085 +Return Value:
15086 +
15087 +       TRUE - if the interrupt was handled by this isr
15088 +       FALSE - if the interrupt was not handled by this isr
15089 +
15090 +--*/
15091 +
15092 +{
15093 +       ULONG   DoorbellBits;
15094 +       UCHAR   InterruptStatus, Mask;
15095 +       u_int OurInterrupt = INTR_UNCLAIMED;
15096 +
15097 +       //cmn_err(CE_WARN, "RxPciIsr entered\n");
15098 +
15099 +       InterruptStatus = Rx_READ_UCHAR(AdapterExtension, MUnit.OISR);
15100 +
15101 +       //
15102 +       // Read mask and invert because drawbridge is reversed.
15103 +       //
15104 +       // This allows us to only service interrupts that have been enabled.
15105 +       //
15106 +
15107 +       Mask = ~(Rx_READ_UCHAR(AdapterExtension, MUnit.OIMR));
15108 +
15109 +       // Check to see if this is our interrupt.  If it isn't just return FALSE.
15110 +
15111 +
15112 +       if (InterruptStatus & Mask) {
15113 +
15114 +               DoorbellBits = Rx_READ_ULONG(AdapterExtension, OutboundDoorbellReg);
15115 +
15116 +               OurInterrupt = INTR_CLAIMED;
15117 +
15118 +               if (DoorbellBits & DoorBellPrintfReady) {
15119 +
15120 +                       ULONG Length, Level;
15121 +                       unsigned char *cp;
15122 +
15123 +                       cp = AdapterExtension->Common->PrintfBufferAddress;
15124 +
15125 +                       //
15126 +                       // The size of the Printfbuffer is set in port.c
15127 +                       // There is no variable or define for it
15128 +                       //
15129 +                       if (Length > 255)
15130 +                               Length = 255;
15131 +
15132 +                       if (cp[Length] != 0) {
15133 +                               // cmn_err (CE_NOTE, "byte %d is 0x%x, should be 0", Length, cp[Length]);
15134 +                               cp[Length] = 0;
15135 +                       }
15136 +
15137 +                       if (Level == LOG_HIGH_ERROR)
15138 +                               cmn_err (CE_WARN, "%s:%s", OsGetDeviceName(AdapterExtension), AdapterExtension->Common->PrintfBufferAddress);
15139 +                       else
15140 +                               cmn_err (CE_NOTE, "%s:%s", OsGetDeviceName(AdapterExtension), AdapterExtension->Common->PrintfBufferAddress);
15141 +
15142 +                       bzero (AdapterExtension->Common->PrintfBufferAddress, 256);
15143 +
15144 +                       Rx_WRITE_ULONG(AdapterExtension, MUnit.ODR,DoorBellPrintfReady); //clear PrintfReady
15145 +
15146 +                       Rx_WRITE_ULONG(AdapterExtension, InboundDoorbellReg,DoorBellPrintfDone);
15147 +
15148 +
15149 +               } else if (DoorbellBits & DoorBellAdapterNormCmdReady) {        // Adapter -> Host Normal Command Ready
15150 +
15151 +                       AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, HostNormCmdQue);
15152 +                       Rx_WRITE_ULONG(AdapterExtension, MUnit.ODR, DoorBellAdapterNormCmdReady);
15153 +
15154 +               } else if (DoorbellBits & DoorBellAdapterNormRespReady) {       // Adapter -> Host Normal Response Ready
15155 +
15156 +                       AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, HostNormRespQue);
15157 +                       Rx_WRITE_ULONG(AdapterExtension, MUnit.ODR,DoorBellAdapterNormRespReady);
15158 +
15159 +               } else if (DoorbellBits & DoorBellAdapterNormCmdNotFull) {      // Adapter -> Host Normal Command Not Full
15160 +
15161 +                       AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, AdapNormCmdNotFull);
15162 +                       Rx_WRITE_ULONG(AdapterExtension, MUnit.ODR, DoorBellAdapterNormCmdNotFull);
15163 +
15164 +               } else if (DoorbellBits & DoorBellAdapterNormRespNotFull) {     // Adapter -> Host Normal Response Not Full
15165 +
15166 +                       AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, AdapNormRespNotFull);
15167 +                       Rx_WRITE_ULONG(AdapterExtension, MUnit.ODR, DoorBellAdapterNormRespNotFull);
15168 +
15169 +               }
15170 +
15171 +       }
15172 +       return(OurInterrupt);
15173 +}
15174 +
15175 +VOID
15176 +RxEnableInterrupt(
15177 +       PVOID                                           Arg1,
15178 +       ADAPTER_EVENT                           AdapterEvent,
15179 +       BOOLEAN                                         AtDeviceIrq
15180 +       )
15181 +/*++
15182 +
15183 +Routine Description:
15184 +
15185 +       This routine will enable the corresponding adapter event to cause an interrupt on 
15186 +       the host.
15187 +
15188 +Arguments:
15189 +
15190 +       AdapterExtension - Which adapter to enable.
15191 +
15192 +       AdapterEvent - Which adapter event.
15193 +
15194 +       AtDeviceIrq - Whether the system is in DEVICE irql
15195 +
15196 +Return Value:
15197 +
15198 +    Nothing.
15199 +
15200 +--*/
15201 +{
15202 +       PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
15203 +       PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) CommonExtension->MiniPort;
15204 +
15205 +       //cmn_err(CE_WARN, "RxEnableInterrupt");
15206 +       switch (AdapterEvent) {
15207 +
15208 +         case HostNormCmdQue:
15209 +
15210 +               AdapterExtension->LocalMaskInterruptControl &= ~(OUTBOUNDDOORBELL_1);
15211 +
15212 +               break;
15213 +
15214 +         case HostNormRespQue:
15215 +
15216 +               AdapterExtension->LocalMaskInterruptControl &= ~(OUTBOUNDDOORBELL_2);
15217 +
15218 +               break;
15219 +
15220 +      case AdapNormCmdNotFull:
15221 +
15222 +               AdapterExtension->LocalMaskInterruptControl &= ~(OUTBOUNDDOORBELL_3);
15223 +
15224 +               break;
15225 +
15226 +      case AdapNormRespNotFull:
15227 +
15228 +               AdapterExtension->LocalMaskInterruptControl &= ~(OUTBOUNDDOORBELL_4);
15229 +
15230 +               break;
15231 +
15232 +       }
15233 +
15234 +}
15235 +
15236 +VOID
15237 +RxDisableInterrupt(
15238 +       PVOID                                           Arg1,
15239 +       ADAPTER_EVENT                           AdapterEvent,
15240 +       BOOLEAN                                         AtDeviceIrq
15241 +       )
15242 +/*++
15243 +
15244 +Routine Description:
15245 +
15246 +       This routine will disable the corresponding adapter event to cause an interrupt on 
15247 +       the host.
15248 +
15249 +Arguments:
15250 +
15251 +       AdapterExtension - Which adapter to enable.
15252 +
15253 +       AdapterEvent - Which adapter event.
15254 +
15255 +       AtDeviceIrq - Whether the system is in DEVICE irql
15256 +
15257 +Return Value:
15258 +
15259 +    Nothing.
15260 +
15261 +--*/
15262 +{
15263 +       PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
15264 +       PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) CommonExtension->MiniPort;
15265 +
15266 +       //cmn_err(CE_WARN, "RxEnableInterrupt");
15267 +
15268 +       switch (AdapterEvent) {
15269 +
15270 +
15271 +         case HostNormCmdQue:
15272 +
15273 +               AdapterExtension->LocalMaskInterruptControl |= (OUTBOUNDDOORBELL_1);
15274 +
15275 +               break;
15276 +
15277 +         case HostNormRespQue:
15278 +
15279 +               AdapterExtension->LocalMaskInterruptControl |= (OUTBOUNDDOORBELL_2);
15280 +
15281 +               break;
15282 +
15283 +      case AdapNormCmdNotFull:
15284 +
15285 +               AdapterExtension->LocalMaskInterruptControl |= (OUTBOUNDDOORBELL_3);
15286 +
15287 +               break;
15288 +
15289 +
15290 +      case AdapNormRespNotFull:
15291 +
15292 +               AdapterExtension->LocalMaskInterruptControl |= (OUTBOUNDDOORBELL_4);
15293 +
15294 +               break;
15295 +
15296 +       }
15297 +
15298 +}
15299 +
15300 +
15301 +
15302 +RxDetachDevice(
15303 +       IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension
15304 +       )
15305 +{
15306 +       PRx_ADAPTER_EXTENSION AdapterExtension = CommonExtension->MiniPort;
15307 +
15308 +       //
15309 +       // Free the register mapping.
15310 +       //
15311 +
15312 +       OsDetachDevice( AdapterExtension);
15313 +
15314 +       OsFreeMemory( AdapterExtension, sizeof(Rx_ADAPTER_EXTENSION) );
15315 +
15316 +}
15317 +
15318 +int
15319 +RxInitDevice(
15320 +       IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
15321 +       IN ULONG AdapterNumber,
15322 +       IN ULONG PciBus,
15323 +       IN ULONG PciSlot
15324 +)
15325 +
15326 +/*++
15327 +
15328 +Routine Description:
15329 +
15330 +       Scans the PCI bus looking for the Rx card. When found all resources for the
15331 +       device will be allocated and the interrupt vectors and csrs will be allocated and
15332 +       mapped.
15333 +
15334 +       The device_interface in the commregion will be allocated and linked to the comm region.
15335 +
15336 +Arguments:
15337 +
15338 +
15339 +Return Value:
15340 +
15341 +    TRUE - if the device was setup with not problems
15342 +    FALSE - if the device could not be mapped and init successfully
15343 +
15344 +--*/
15345 +
15346 +{
15347 +       AAC_STATUS Status;
15348 +       PRx_ADAPTER_EXTENSION AdapterExtension = NULL;
15349 +       FSA_NEW_ADAPTER NewAdapter;
15350 +       ULONG StartTime, EndTime, WaitTime;
15351 +       ULONG InitStatus;
15352 +       int instance;
15353 +       int nIntrs;
15354 +       char * name;
15355 +
15356 +    AfaPortPrint("In init device.\n");
15357 +
15358 +       //cmn_err(CE_WARN, "In RxInitDevice");
15359 +
15360 +//     AdapterExtension->Common->AdapterIndex = AdapterIndex;
15361 +       CommonExtension->AdapterNumber = AdapterNumber;
15362 +
15363 +
15364 +       CommonExtension->PciBusNumber = PciBus;
15365 +       CommonExtension->PciSlotNumber = PciSlot;
15366 +
15367 +
15368 +       AdapterExtension = OsAllocMemory( sizeof(Rx_ADAPTER_EXTENSION), OS_ALLOC_MEM_SLEEP );
15369 +       AdapterExtension->Common = CommonExtension;
15370 +       CommonExtension->MiniPort = AdapterExtension;
15371 +
15372 +       instance = OsGetDeviceInstance(AdapterExtension);
15373 +       name     = OsGetDeviceName(AdapterExtension);
15374 +       //
15375 +       // Map in the registers from the adapter, register space 0 is config space,
15376 +       // register space 1 is the memery space.
15377 +       //
15378 +
15379 +       if (OsMapDeviceRegisters(AdapterExtension)) {
15380 +
15381 +               cmn_err(CE_CONT, "%s%d: can't map device registers\n",
15382 +                               OsGetDeviceName(AdapterExtension), instance);
15383 +               return(FAILURE);
15384 +       }
15385 +
15386 +       //
15387 +       // Check to see if the board failed any self tests.
15388 +       //
15389 +
15390 +       if (Rx_READ_ULONG( AdapterExtension, IndexRegs.Mailbox[7]) & SELF_TEST_FAILED) {
15391 +
15392 +               cmn_err(CE_CONT, "%s%d: adapter self-test failed\n",
15393 +                               OsGetDeviceName(AdapterExtension), instance);
15394 +               return(FAILURE);
15395 +
15396 +       }
15397 +       //cmn_err(CE_WARN, "RxInitDevice: %s%d: adapter passwd self-test\n",
15398 +       //                      OsGetDeviceName(AdapterExtension), instance);
15399 +
15400 +       //
15401 +       // Check to see if the board panic'd while booting.
15402 +       //
15403 +
15404 +       if (Rx_READ_ULONG( AdapterExtension, IndexRegs.Mailbox[7]) & KERNEL_PANIC) {
15405 +
15406 +               cmn_err(CE_CONT, "%s%d: adapter kernel panic'd\n",
15407 +                               OsGetDeviceName(AdapterExtension), instance);
15408 +               return(FAILURE);
15409 +
15410 +       }
15411 +
15412 +       StartTime = OsGetSeconds();
15413 +       WaitTime = 0;
15414 +
15415 +
15416 +       //
15417 +       //  Wait for the adapter to be up and running. Wait up until 3 minutes.
15418 +       //
15419 +
15420 +       while (!(Rx_READ_ULONG( AdapterExtension, IndexRegs.Mailbox[7]) & KERNEL_UP_AND_RUNNING)) {
15421 +       
15422 +               EndTime = OsGetSeconds();
15423 +
15424 +               WaitTime = EndTime - StartTime;
15425 +
15426 +               if ( WaitTime > (3 * 10) ) {
15427 +
15428 +                       InitStatus = Rx_READ_ULONG( AdapterExtension, IndexRegs.Mailbox[7]) >> 16;
15429 +
15430 +                       cmn_err(CE_CONT, "%s%d: adapter kernel failed to start, init status = %d\n",
15431 +                                       OsGetDeviceName(AdapterExtension), instance, InitStatus);
15432 +                       return(FAILURE);
15433 +
15434 +               }
15435 +       }
15436 +
15437 +       if (OsAttachInterrupt(AdapterExtension,RxISR)) {
15438 +               cmn_err(CE_WARN, "%s%d RxInitDevice: failed OsAttachIntterupt", name, instance);
15439 +               return(FAILURE);
15440 +       }
15441 +
15442 +
15443 +       if (OsAttachDMA(AdapterExtension)) {
15444 +               cmn_err(CE_WARN, "%s%d SaInitDevice: failed OsAttachDMA", name, instance);
15445 +               return(FAILURE);
15446 +       }
15447 +
15448 +       //
15449 +       // Fill in the function dispatch table.
15450 +       //
15451 +
15452 +       AdapterExtension->Common->AdapterFuncs.SizeOfFsaPortFuncs = sizeof(FSAPORT_FUNCS);
15453 +       AdapterExtension->Common->AdapterFuncs.AllocateAdapterCommArea = AfaPortAllocateAdapterCommArea;
15454 +       AdapterExtension->Common->AdapterFuncs.FreeAdapterCommArea = AfaPortFreeAdapterCommArea;
15455 +       AdapterExtension->Common->AdapterFuncs.BuildSgMap = AfaPortBuildSgMap;
15456 +       AdapterExtension->Common->AdapterFuncs.FreeDmaResources = AfaPortFreeDmaResources;
15457 +       AdapterExtension->Common->AdapterFuncs.AllocateAndMapFibSpace = AfaPortAllocateAndMapFibSpace;
15458 +       AdapterExtension->Common->AdapterFuncs.UnmapAndFreeFibSpace = AfaPortUnmapAndFreeFibSpace;
15459 +       AdapterExtension->Common->AdapterFuncs.InterruptAdapter = RxInterruptAdapter;
15460 +       AdapterExtension->Common->AdapterFuncs.EnableInterrupt = RxEnableInterrupt;
15461 +       AdapterExtension->Common->AdapterFuncs.DisableInterrupt = RxDisableInterrupt;
15462 +       AdapterExtension->Common->AdapterFuncs.NotifyAdapter = RxNotifyAdapter;
15463 +       AdapterExtension->Common->AdapterFuncs.ResetDevice = RxResetDevice;
15464 +       AdapterExtension->Common->AdapterFuncs.InterruptHost = NULL;
15465 +
15466 +       AdapterExtension->Common->AdapterFuncs.SendSynchFib = RxSendSynchFib;
15467 +
15468 +       NewAdapter.AdapterExtension = CommonExtension;
15469 +       NewAdapter.AdapterFuncs = &AdapterExtension->Common->AdapterFuncs;
15470 +       NewAdapter.AdapterInterruptsBelowDpc = FALSE;
15471 +       NewAdapter.AdapterUserVars = RxUserVars;
15472 +       NewAdapter.AdapterUserVarsSize = sizeof(RxUserVars) / sizeof(FSA_USER_VAR);
15473 +
15474 +       NewAdapter.Dip = CommonExtension->OsDep.dip;
15475 +
15476 +       
15477 +       if (AfaCommInitNewAdapter( &NewAdapter ) == NULL) {
15478 +               
15479 +               cmn_err(CE_WARN, "AfaCommInitNewAdapter failed\n");
15480 +               return (FAILURE);
15481 +       }
15482 +
15483 +
15484 +       AdapterExtension->Common->Adapter = NewAdapter.Adapter;
15485 +
15486 +       if (AdapterExtension->Common->Adapter == NULL) {
15487 +
15488 +               AfaPortLogError(AdapterExtension->Common, FAILURE, NULL, 0);
15489 +               cmn_err(CE_WARN, "%s%d RxInitDevice: No Adapter pointer", name, instance);
15490 +
15491 +
15492 +               return (FAILURE);
15493 +       }
15494 +
15495 +
15496 +       //
15497 +       // Start any kernel threads needed
15498 +       //
15499 +       OsStartKernelThreads(AdapterExtension);
15500 +
15501 +       //
15502 +       // Tell the adapter that all is configure, and it can start accepting requests
15503 +       //
15504 +
15505 +       RxStartAdapter(AdapterExtension);
15506 +
15507 +
15508 +#ifdef AACDISK
15509 +#endif
15510 +
15511 +
15512 +       //
15513 +       // Put this adapter into the list of Rx adapters
15514 +       //
15515 +
15516 +       AdapterExtension->Next = RxAdapterList;
15517 +       RxAdapterList = AdapterExtension;
15518 +
15519 +       AdapterExtension->Common->AdapterConfigured = TRUE;
15520 +
15521 +
15522 +#ifdef AACDISK
15523 +       //
15524 +       // Call the disk layer to initialize itself.
15525 +       //
15526 +
15527 +       AfaDiskInitNewAdapter( AdapterExtension->Common->AdapterNumber, AdapterExtension->Common->Adapter );
15528 +#endif
15529 +
15530 +
15531 +init_done:
15532 +
15533 +       AdapterExtension->Common->AdapterPrintfsToScreen = FALSE;
15534 +
15535 +
15536 +
15537 +       OsAttachHBA(AdapterExtension);
15538 +
15539 +    return(0);
15540 +}
15541 +
15542 +VOID
15543 +RxStartAdapter(
15544 +       PRx_ADAPTER_EXTENSION AdapterExtension
15545 +       )
15546 +{
15547 +       ULONG ReturnStatus;
15548 +       LARGE_INTEGER HostTime;
15549 +       ULONG ElapsedSeconds;
15550 +       PADAPTER_INIT_STRUCT InitStruct;
15551 +
15552 +       //cmn_err(CE_WARN, "RxStartAdapter");
15553 +       //
15554 +       // Fill in the remaining pieces of the InitStruct.
15555 +       //
15556 +
15557 +       InitStruct = AdapterExtension->Common->InitStruct;
15558 +
15559 +       InitStruct->HostPhysMemPages = AfaPortGetMaxPhysicalPage(AdapterExtension->Common);
15560 +
15561 +       ElapsedSeconds = OsGetSeconds();
15562 +
15563 +       InitStruct->HostElapsedSeconds = ElapsedSeconds;
15564 +
15565 +       //
15566 +       // Tell the adapter we are back and up and running so it will scan its command
15567 +       // queues and enable our interrupts
15568 +       //
15569 +
15570 +       AdapterExtension->LocalMaskInterruptControl =
15571 +               (DoorBellPrintfReady | OUTBOUNDDOORBELL_1 | OUTBOUNDDOORBELL_2 | OUTBOUNDDOORBELL_3 | OUTBOUNDDOORBELL_4);
15572 +
15573 +       //
15574 +       // First clear out all interrupts.  Then enable the one's that we can handle.
15575 +       //
15576 +
15577 +       Rx_WRITE_UCHAR( AdapterExtension, MUnit.OIMR, 0xff);
15578 +       Rx_WRITE_ULONG( AdapterExtension, MUnit.ODR, 0xffffffff);
15579 +//     Rx_WRITE_UCHAR(AdapterExtension, MUnit.OIMR, ~(UCHAR)OUTBOUND_DOORBELL_INTERRUPT_MASK);
15580 +       Rx_WRITE_UCHAR( AdapterExtension, MUnit.OIMR, 0xfb);
15581 +
15582 +       RxSendSynchCommand(AdapterExtension, 
15583 +                                        INIT_STRUCT_BASE_ADDRESS, 
15584 +                                        (ULONG) AdapterExtension->Common->PhysicalInitStruct,
15585 +                                        0,
15586 +                                        0,
15587 +                                        0,
15588 +                                        &ReturnStatus);
15589 +
15590 +}
15591 +
15592 +
15593 +VOID
15594 +RxResetDevice(
15595 +       PVOID Arg1
15596 +    )
15597 +
15598 +{
15599 +}
15600 +
15601 +VOID
15602 +RxInterruptAdapter(
15603 +       PVOID Arg1
15604 +       )
15605 +/*++
15606 +
15607 +Routine Description:
15608 +
15609 +       The will cause the adapter to take a break point.
15610 +
15611 +Arguments:
15612 +
15613 +       None
15614 +
15615 +Return Value:
15616 +
15617 +    Nothing
15618 +
15619 +--*/
15620 +{
15621 +       PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
15622 +       PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) CommonExtension->MiniPort;
15623 +
15624 +       ULONG ReturnStatus;
15625 +
15626 +       RxSendSynchCommand(AdapterExtension, 
15627 +                                          BREAKPOINT_REQUEST,
15628 +                                          0,
15629 +                                          0,
15630 +                                          0,
15631 +                                          0,
15632 +                                          &ReturnStatus);
15633 +
15634 +}
15635 +
15636 +VOID
15637 +RxNotifyAdapter(
15638 +       PVOID Arg1,
15639 +    IN HOST_2_ADAP_EVENT AdapterEvent
15640 +    )
15641 +/*++
15642 +
15643 +Routine Description:
15644 +
15645 +    Will read the adapter CSRs to find the reason the adapter has
15646 +    interrupted us.
15647 +
15648 +Arguments:
15649 +
15650 +    AdapterEvent - Enumerated type the returns the reason why we were interrutped.
15651 +
15652 +Return Value:
15653 +
15654 +    Nothing
15655 +
15656 +--*/
15657 +{
15658 +       PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
15659 +       PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) CommonExtension->MiniPort;
15660 +       ULONG ReturnStatus;
15661 +
15662 +       //cmn_err(CE_WARN, "RxNotifyAdapter %d", AdapterEvent);
15663 +
15664 +    switch (AdapterEvent) {
15665 +        case AdapNormCmdQue:
15666 +
15667 +                       Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_1);
15668 +            break;
15669 +
15670 +        case HostNormRespNotFull:
15671 +
15672 +                       Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_4);
15673 +            break;
15674 +
15675 +        case AdapNormRespQue:
15676 +
15677 +                       Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_2);
15678 +            break;
15679 +
15680 +        case HostNormCmdNotFull:
15681 +
15682 +                       Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_3);
15683 +            break;
15684 +
15685 +        case HostShutdown:
15686 +
15687 +//                     RxSendSynchCommand(AdapterExtension, HOST_CRASHING, 0, 0, 0, 0, &ReturnStatus);
15688 +
15689 +            break;
15690 +
15691 +               case FastIo:
15692 +                       Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_6);
15693 +                       break;
15694 +
15695 +               case AdapPrintfDone:
15696 +                       Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_5);
15697 +                       break;
15698 +
15699 +        default:
15700 +
15701 +                       RxBugCheck(0,0,0);
15702 +            AfaPortPrint("Notify requested with an invalid request 0x%x.\n",AdapterEvent);
15703 +            break;
15704 +    }
15705 +}
15706 +
15707 +AAC_STATUS
15708 +RxSendSynchCommand(
15709 +       PVOID Arg1,
15710 +       ULONG Command,
15711 +       ULONG Parameter1,
15712 +       ULONG Parameter2,
15713 +       ULONG Parameter3,
15714 +       ULONG Parameter4,
15715 +       PULONG  ReturnStatus
15716 +       )
15717 +/*++
15718 +
15719 +Routine Description:
15720 +
15721 +       This routine will send a synchronous comamnd to the adapter and wait for its
15722 +       completion.
15723 +
15724 +Arguments:
15725 +
15726 +       AdapterExtension - Pointer to adapter extension structure.
15727 +       Command - Which command to send
15728 +       Parameter1 - 4  - Parameters for command
15729 +       ReturnStatus - return status from adapter after completion of command
15730 +
15731 +
15732 +Return Value:
15733 +
15734 +       AAC_STATUS
15735 +
15736 +--*/
15737 +{
15738 +       PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) Arg1;
15739 +       ULONG StartTime,EndTime,WaitTime;
15740 +       BOOLEAN CommandSucceeded;
15741 +
15742 +       //cmn_err(CE_WARN, "RxSendSyncCommand");
15743 +       //
15744 +       // Write the Command into Mailbox 0
15745 +       //
15746 +
15747 +       Rx_WRITE_ULONG( AdapterExtension, InboundMailbox0, Command);
15748 +
15749 +       //
15750 +       // Write the parameters into Mailboxes 1 - 4
15751 +       //
15752 +
15753 +       Rx_WRITE_ULONG( AdapterExtension, InboundMailbox1, Parameter1);
15754 +       Rx_WRITE_ULONG( AdapterExtension, InboundMailbox2, Parameter2);
15755 +       Rx_WRITE_ULONG( AdapterExtension, InboundMailbox3, Parameter3);
15756 +       Rx_WRITE_ULONG( AdapterExtension, InboundMailbox4, Parameter4);
15757 +
15758 +       //
15759 +       // Clear the synch command doorbell to start on a clean slate.
15760 +       //
15761 +               
15762 +       Rx_WRITE_ULONG( AdapterExtension, OutboundDoorbellReg, OUTBOUNDDOORBELL_0);
15763 +
15764 +       //
15765 +       // disable doorbell interrupts
15766 +       //
15767 +
15768 +       Rx_WRITE_UCHAR( AdapterExtension, MUnit.OIMR, 
15769 +                                       Rx_READ_UCHAR(AdapterExtension, MUnit.OIMR) | 0x04);
15770 +
15771 +       //
15772 +       // force the completion of the mask register write before issuing the interrupt.
15773 +       //
15774 +
15775 +       Rx_READ_UCHAR ( AdapterExtension, MUnit.OIMR);
15776 +
15777 +       //
15778 +       // Signal that there is a new synch command
15779 +       //
15780 +
15781 +       Rx_WRITE_ULONG( AdapterExtension, InboundDoorbellReg, INBOUNDDOORBELL_0);
15782 +
15783 +       CommandSucceeded = FALSE;
15784 +
15785 +       StartTime = OsGetSeconds();
15786 +       WaitTime = 0;
15787 +
15788 +       while (WaitTime < 30) { // wait up to 30 seconds
15789 +
15790 +               drv_usecwait(5);                                // delay 5 microseconds to let Mon960 get info.
15791 +
15792 +               //
15793 +               // Mon110 will set doorbell0 bit when it has completed the command.
15794 +               //
15795 +
15796 +               if (Rx_READ_ULONG(AdapterExtension, OutboundDoorbellReg) & OUTBOUNDDOORBELL_0) {
15797 +
15798 +                       //
15799 +                       // clear the doorbell.
15800 +                       //
15801 +
15802 +                       Rx_WRITE_ULONG(AdapterExtension, OutboundDoorbellReg, OUTBOUNDDOORBELL_0);
15803 +
15804 +                       CommandSucceeded = TRUE;
15805 +                       break;
15806 +               }
15807 +
15808 +               EndTime = OsGetSeconds();
15809 +               WaitTime = EndTime - StartTime;
15810 +
15811 +       }
15812 +
15813 +       if (CommandSucceeded != TRUE) {
15814 +
15815 +               //
15816 +               // restore interrupt mask even though we timed out
15817 +               //
15818 +
15819 +               Rx_WRITE_UCHAR(AdapterExtension, MUnit.OIMR, 
15820 +                                          Rx_READ_ULONG(AdapterExtension, MUnit.OIMR) & 0xfb);
15821 +
15822 +               return (STATUS_IO_TIMEOUT);
15823 +
15824 +       }
15825 +
15826 +       //
15827 +       // Pull the synch status from Mailbox 0.
15828 +       //
15829 +
15830 +       *ReturnStatus = Rx_READ_ULONG(AdapterExtension, IndexRegs.Mailbox[0]);
15831 +
15832 +       //
15833 +       // Clear the synch command doorbell.
15834 +       //
15835 +               
15836 +       Rx_WRITE_ULONG(AdapterExtension, OutboundDoorbellReg, OUTBOUNDDOORBELL_0);
15837 +
15838 +       //
15839 +       // restore interrupt mask
15840 +       //
15841 +
15842 +       Rx_WRITE_UCHAR(AdapterExtension, MUnit.OIMR, 
15843 +                                  Rx_READ_ULONG(AdapterExtension, MUnit.OIMR) & 0xfb);
15844 +
15845 +       //
15846 +       // Return SUCCESS
15847 +       //
15848 +
15849 +       return (STATUS_SUCCESS);
15850 +
15851 +}
15852 +
15853 +BOOLEAN
15854 +RxSendSynchFib(
15855 +       PVOID Arg1,
15856 +       ULONG FibPhysicalAddress
15857 +       )
15858 +/*++
15859 +
15860 +Routine Description:
15861 +
15862 +       This routine will send a synchronous fib to the adapter and wait for its
15863 +       completion.
15864 +
15865 +Arguments:
15866 +
15867 +       AdapterExtension - Pointer to adapter extension structure.
15868 +       FibPhysicalAddress - Physical address of fib to send.
15869 +
15870 +
15871 +Return Value:
15872 +
15873 +       BOOLEAN
15874 +
15875 +--*/
15876 +{
15877 +       PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
15878 +       PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) CommonExtension->MiniPort;
15879 +       ULONG returnStatus;
15880 +
15881 +       if (RxSendSynchCommand( AdapterExtension,
15882 +                                                   SEND_SYNCHRONOUS_FIB,
15883 +                                                   FibPhysicalAddress,
15884 +                                                   0,
15885 +                                                   0,
15886 +                                                   0,
15887 +                                                   &returnStatus ) != STATUS_SUCCESS ) {
15888 +
15889 +               return (FALSE);
15890 +               
15891 +       }
15892 +       
15893 +       return (TRUE);
15894 +                                                                               
15895 +}
15896 +
15897 +
15898 diff -burN linux-2.4.7/drivers/scsi/aacraid/sap1sup.c linux/drivers/scsi/aacraid/sap1sup.c
15899 --- linux-2.4.7/drivers/scsi/aacraid/sap1sup.c  Wed Dec 31 18:00:00 1969
15900 +++ linux/drivers/scsi/aacraid/sap1sup.c        Sat Jul 21 17:55:14 2001
15901 @@ -0,0 +1,859 @@
15902 +/*++
15903 + * Adaptec aacraid device driver for Linux.
15904 + *
15905 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
15906 + *
15907 + * This program is free software; you can redistribute it and/or modify
15908 + * it under the terms of the GNU General Public License as published by
15909 + * the Free Software Foundation; either version 2, or (at your option)
15910 + * any later version.
15911 + *
15912 + * This program is distributed in the hope that it will be useful,
15913 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
15914 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15915 + * GNU General Public License for more details.
15916 + *
15917 + * You should have received a copy of the GNU General Public License
15918 + * along with this program; see the file COPYING.  If not, write to
15919 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
15920 + *
15921 + * Module Name:
15922 + *  sap1sup.c
15923 + *
15924 + * Abstract: Drawbridge specific support functions
15925 + *
15926 + --*/
15927 +
15928 +static char *ident_sap1 = "aacraid_ident sap1sup.c 1.0.7 2000/10/11 Adaptec, Inc.";
15929 +
15930 +#include "osheaders.h"
15931 +
15932 +
15933 +#include "AacGenericTypes.h"
15934 +
15935 +#include "aac_unix_defs.h"
15936 +
15937 +#include "fsatypes.h"
15938 +#include "comstruc.h"
15939 +#include "fsact.h"
15940 +#include "protocol.h"
15941 +
15942 +#define DEFINE_PCI_IDS
15943 +#include "sap1common.h"
15944 +#include "monkerapi.h"
15945 +
15946 +#include "fsaport.h"
15947 +#include "fsaioctl.h"
15948 +
15949 +
15950 +#include "pcisup.h"
15951 +#include "sap1.h"
15952 +
15953 +#include "port.h"
15954 +
15955 +#include "nodetype.h"
15956 +#include "comsup.h"
15957 +#include "afacomm.h"
15958 +#include "adapter.h"
15959 +
15960 +#define BugCheckFileId                   (FSAFS_BUG_CHECK_CYCLONESUP)
15961 +
15962 +// #define SaBugCheck(A,B,C) { KeBugCheckEx(0x00000AFA, __LINE__, (ULONG)A, (ULONG)B,(ULONG)C ); }
15963 +
15964 +#define SaBugCheck(A, B, C) {  cmn_err(CE_PANIC, "aacdisk : line %s, 0x%x, 0x%x, 0x%x ", __LINE__, A, B, C);  }
15965 +
15966 +#define NUM_TICKS_PER_SECOND (1000 * 1000 * 10) /* time is in 100 nanoseconds */
15967 +
15968 +int MiniPortRevision = Sa_MINIPORT_REVISION;
15969 +
15970 +
15971 +//
15972 +// The list of all the Sa adapter structures
15973 +//
15974 +
15975 +PSa_ADAPTER_EXTENSION  SaAdapterList;
15976 +
15977 +int
15978 +SaInitDevice(
15979 +       IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
15980 +       IN ULONG AdapterNumber,
15981 +       IN ULONG PciBus,
15982 +       IN ULONG PciSlot
15983 +);
15984 +
15985 +BOOLEAN
15986 +SaSendSynchFib(
15987 +       PVOID Arg1,
15988 +       ULONG FibPhysicalAddress
15989 +       );
15990 +
15991 +FSA_USER_VAR   SaUserVars[] = {
15992 +       { "AfaPortPrinting", (PULONG)&AfaPortPrinting, NULL },
15993 +};
15994 +
15995 +
15996 +//
15997 +// Declare private use routines for this modual
15998 +//
15999 +
16000 +
16001 +/*++
16002 +
16003 +Routine Description:
16004 +
16005 +    The Isr routine for fsa Sa based adapter boards.
16006 +
16007 +Arguments:
16008 +
16009 +
16010 +Return Value:
16011 +
16012 +       TRUE - if the interrupt was handled by this isr
16013 +       FALSE - if the interrupt was not handled by this isr
16014 +
16015 +--*/
16016 +u_int
16017 +SaPciIsr (IN PSa_ADAPTER_EXTENSION AdapterExtension)
16018 +{
16019 +               USHORT InterruptStatus, Mask;
16020 +               u_int OurInterrupt = INTR_UNCLAIMED;
16021 +
16022 +       InterruptStatus = Sa_READ_USHORT( AdapterExtension, DoorbellReg_p);
16023 +
16024 +       //
16025 +       // Read mask and invert because drawbridge is reversed.
16026 +       //
16027 +       // This allows us to only service interrupts that have been enabled.
16028 +       //
16029 +
16030 +       Mask = ~(Sa_READ_USHORT( AdapterExtension, SaDbCSR.PRISETIRQMASK));
16031 +
16032 +       // Check to see if this is our interrupt.  If it isn't just return FALSE.
16033 +
16034 +
16035 +       if (InterruptStatus & Mask) {
16036 +
16037 +               OurInterrupt = INTR_CLAIMED;
16038 +
16039 +               if (InterruptStatus & PrintfReady) {
16040 +
16041 +                       ULONG Length, Level;
16042 +                       unsigned char *cp;
16043 +
16044 +                       cp = AdapterExtension->Common->PrintfBufferAddress;
16045 +
16046 +                       //
16047 +                       // The size of the Printbuffer is set in port.c
16048 +                       // There is no variable or define for it
16049 +                       //
16050 +                       if (Length > 255)
16051 +                               Length = 255;
16052 +
16053 +                       if (cp[Length] != 0) {
16054 +                               // cmn_err (CE_NOTE, "byte %d is 0x%x, should be 0", Length, cp[Length]);
16055 +                               cp[Length] = 0;
16056 +                       }
16057 +
16058 +                       if (Level == LOG_HIGH_ERROR)
16059 +                               cmn_err (CE_WARN, "%s:%s", OsGetDeviceName(AdapterExtension), AdapterExtension->Common->PrintfBufferAddress);
16060 +                       else
16061 +                               cmn_err (CE_NOTE, "%s:%s", OsGetDeviceName(AdapterExtension), AdapterExtension->Common->PrintfBufferAddress);
16062 +
16063 +                       bzero (AdapterExtension->Common->PrintfBufferAddress, 256);
16064 +
16065 +                       Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p,PrintfReady); //clear PrintfReady
16066 +
16067 +                       Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,PrintfDone);
16068 +
16069 +               } else if (InterruptStatus & DOORBELL_1) {      // Adapter -> Host Normal Command Ready
16070 +
16071 +                       AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, HostNormCmdQue);
16072 +                       Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p, DOORBELL_1);
16073 +
16074 +               } else if (InterruptStatus & DOORBELL_2) {      // Adapter -> Host Normal Response Ready
16075 +
16076 +                               AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, HostNormRespQue);
16077 +                               Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p,DOORBELL_2);
16078 +
16079 +               } else if (InterruptStatus & DOORBELL_3) {      // Adapter -> Host Normal Command Not Full
16080 +
16081 +                       AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, AdapNormCmdNotFull);
16082 +                       Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p, DOORBELL_3);
16083 +
16084 +               } else if (InterruptStatus & DOORBELL_4) {      // Adapter -> Host Normal Response Not Full
16085 +
16086 +                       AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, AdapNormRespNotFull);
16087 +                       Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p, DOORBELL_4);
16088 +
16089 +               }
16090 +
16091 +       }
16092 +       return(OurInterrupt);
16093 +}
16094 +
16095 +
16096 +/*++
16097 +
16098 +Routine Description:
16099 +
16100 +       This routine will enable the corresponding adapter event to cause an interrupt on 
16101 +       the host.
16102 +
16103 +Arguments:
16104 +
16105 +       AdapterExtension - Which adapter to enable.
16106 +
16107 +       AdapterEvent - Which adapter event.
16108 +
16109 +       AtDeviceIrq - Whether the system is in DEVICE irql
16110 +
16111 +Return Value:
16112 +
16113 +    Nothing.
16114 +
16115 +--*/
16116 +VOID
16117 +SaEnableInterrupt (PVOID Arg1, ADAPTER_EVENT AdapterEvent, BOOLEAN AtDeviceIrq)
16118 +{
16119 +       PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
16120 +       PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) CommonExtension->MiniPort;
16121 +
16122 +       switch (AdapterEvent) {
16123 +
16124 +         case HostNormCmdQue:
16125 +
16126 +               Sa_WRITE_USHORT( AdapterExtension,  SaDbCSR.PRICLEARIRQMASK, DOORBELL_1 );
16127 +
16128 +               break;
16129 +
16130 +         case HostNormRespQue:
16131 +
16132 +               Sa_WRITE_USHORT( AdapterExtension,  SaDbCSR.PRICLEARIRQMASK, DOORBELL_2 );
16133 +
16134 +               break;
16135 +
16136 +      case AdapNormCmdNotFull:
16137 +
16138 +               Sa_WRITE_USHORT( AdapterExtension,  SaDbCSR.PRICLEARIRQMASK, DOORBELL_3 );
16139 +
16140 +               break;
16141 +
16142 +      case AdapNormRespNotFull:
16143 +
16144 +               Sa_WRITE_USHORT( AdapterExtension,  SaDbCSR.PRICLEARIRQMASK, DOORBELL_4 );
16145 +
16146 +               break;
16147 +
16148 +       }
16149 +
16150 +}
16151 +
16152 +
16153 +
16154 +/*++
16155 +
16156 +Routine Description:
16157 +
16158 +       This routine will disable the corresponding adapter event to cause an interrupt on 
16159 +       the host.
16160 +
16161 +Arguments:
16162 +
16163 +       AdapterExtension - Which adapter to enable.
16164 +
16165 +       AdapterEvent - Which adapter event.
16166 +
16167 +       AtDeviceIrq - Whether the system is in DEVICE irql
16168 +
16169 +Return Value:
16170 +
16171 +    Nothing.
16172 +
16173 +--*/
16174 +VOID
16175 +SaDisableInterrupt (PVOID Arg1,        ADAPTER_EVENT AdapterEvent, BOOLEAN AtDeviceIrq)
16176 +{
16177 +       PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
16178 +       PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) CommonExtension->MiniPort;
16179 +
16180 +       switch (AdapterEvent) {
16181 +
16182 +
16183 +         case HostNormCmdQue:
16184 +
16185 +               Sa_WRITE_USHORT( AdapterExtension,  SaDbCSR.PRISETIRQMASK, DOORBELL_1 );
16186 +
16187 +               break;
16188 +
16189 +         case HostNormRespQue:
16190 +
16191 +               Sa_WRITE_USHORT( AdapterExtension,  SaDbCSR.PRISETIRQMASK, DOORBELL_2 );
16192 +
16193 +               break;
16194 +
16195 +      case AdapNormCmdNotFull:
16196 +
16197 +               Sa_WRITE_USHORT( AdapterExtension,  SaDbCSR.PRISETIRQMASK, DOORBELL_3 );
16198 +
16199 +               break;
16200 +
16201 +
16202 +      case AdapNormRespNotFull:
16203 +
16204 +               Sa_WRITE_USHORT( AdapterExtension,  SaDbCSR.PRISETIRQMASK, DOORBELL_4 );
16205 +
16206 +               break;
16207 +
16208 +       }
16209 +
16210 +}
16211 +
16212 +
16213 +SaDetachDevice (IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension)
16214 +{
16215 +       PSa_ADAPTER_EXTENSION AdapterExtension = CommonExtension->MiniPort;
16216 +
16217 +       //
16218 +       // Free the register mapping.
16219 +       //
16220 +
16221 +       OsDetachDevice(AdapterExtension);
16222 +
16223 +       OsFreeMemory( AdapterExtension, sizeof(Sa_ADAPTER_EXTENSION) );
16224 +
16225 +}
16226 +
16227 +
16228 +/*++
16229 +
16230 +Routine Description:
16231 +
16232 +       Scans the PCI bus looking for the Sa card. When found all resources for the
16233 +       device will be allocated and the interrupt vectors and csrs will be allocated and
16234 +       mapped.
16235 +
16236 +       The device_interface in the commregion will be allocated and linked to the comm region.
16237 +
16238 +Arguments:
16239 +
16240 +
16241 +Return Value:
16242 +
16243 +    TRUE - if the device was setup with not problems
16244 +    FALSE - if the device could not be mapped and init successfully
16245 +
16246 +--*/
16247 +int
16248 +SaInitDevice (IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
16249 +                         IN ULONG AdapterNumber, IN ULONG PciBus,
16250 +                         IN ULONG PciSlot)
16251 +{
16252 +       AAC_STATUS Status;
16253 +       PSa_ADAPTER_EXTENSION AdapterExtension = NULL;
16254 +       FSA_NEW_ADAPTER NewAdapter;
16255 +       ULONG StartTime, EndTime, WaitTime;
16256 +       ULONG InitStatus;
16257 +       int instance;
16258 +       char *name;
16259 +
16260 +    AfaPortPrint("In init device.\n");
16261 +
16262 +       CommonExtension->AdapterNumber = AdapterNumber;
16263 +
16264 +       CommonExtension->PciBusNumber = PciBus;
16265 +       CommonExtension->PciSlotNumber = PciSlot;
16266 +
16267 +       AdapterExtension = OsAllocMemory( sizeof(Sa_ADAPTER_EXTENSION), OS_ALLOC_MEM_SLEEP );
16268 +       AdapterExtension->Common = CommonExtension;
16269 +       CommonExtension->MiniPort = AdapterExtension;
16270 +
16271 +       instance = OsGetDeviceInstance(AdapterExtension);
16272 +       name     = OsGetDeviceName(AdapterExtension);
16273 +
16274 +       //
16275 +       // Map in the registers from the adapter, register space 0 is config space,
16276 +       // register space 1 is the memery space.
16277 +       //
16278 +
16279 +       if (OsMapDeviceRegisters(AdapterExtension)){
16280 +               cmn_err(CE_WARN, "%s%d SaInitDevice: failed OsMapDeviceRegisters", name, instance);
16281 +               return(FAILURE);
16282 +       }
16283 +
16284 +
16285 +       //
16286 +       // Check to see if the board failed any self tests.
16287 +       //
16288 +
16289 +       if (Sa_READ_ULONG( AdapterExtension, Mailbox7) & SELF_TEST_FAILED) {
16290 +
16291 +               cmn_err(CE_WARN, "%s%d: adapter self-test failed\n",
16292 +                               name, instance);
16293 +               return(FAILURE);
16294 +       }
16295 +
16296 +       //
16297 +       // Check to see if the board panic'd while booting.
16298 +       //
16299 +
16300 +       if (Sa_READ_ULONG( AdapterExtension, Mailbox7) & KERNEL_PANIC) {
16301 +
16302 +               cmn_err(CE_WARN, "%s%d: adapter kernel panic'd\n",
16303 +                               name, instance);
16304 +               return(FAILURE);
16305 +       }
16306 +
16307 +
16308 +       StartTime = OsGetSeconds();
16309 +       WaitTime = 0;
16310 +
16311 +
16312 +       //
16313 +       //  Wait for the adapter to be up and running. Wait up until 3 minutes.
16314 +       //
16315 +
16316 +       while (!(Sa_READ_ULONG( AdapterExtension, Mailbox7) & KERNEL_UP_AND_RUNNING)) {
16317 +       
16318 +               EndTime = OsGetSeconds();
16319 +
16320 +               WaitTime = EndTime - StartTime;
16321 +
16322 +               if ( WaitTime > (3 * 60) ) {
16323 +
16324 +                       InitStatus = Sa_READ_ULONG( AdapterExtension, Mailbox7) >> 16;
16325 +
16326 +                       cmn_err(CE_WARN, "%s%d: adapter kernel failed to start, init status = %d\n",
16327 +                                       name, instance, InitStatus);
16328 +                       return(FAILURE);
16329 +
16330 +               }
16331 +       }
16332 +
16333 +       if (OsAttachInterrupt(AdapterExtension, SaISR)) {
16334 +               cmn_err(CE_WARN, "%s%d SaInitDevice: failed OsAttachIntterupt", name, instance);
16335 +               return(FAILURE);
16336 +       }
16337 +
16338 +       if (OsAttachDMA(AdapterExtension)) {
16339 +               cmn_err(CE_WARN, "%s%d SaInitDevice: failed OsAttachDMA", name, instance);
16340 +               return(FAILURE);
16341 +       }
16342 +
16343 +
16344 +       //
16345 +       // Fill in the function dispatch table.
16346 +       //
16347 +
16348 +       AdapterExtension->Common->AdapterFuncs.SizeOfFsaPortFuncs = sizeof(FSAPORT_FUNCS);
16349 +       AdapterExtension->Common->AdapterFuncs.AllocateAdapterCommArea = AfaPortAllocateAdapterCommArea;
16350 +       AdapterExtension->Common->AdapterFuncs.FreeAdapterCommArea = AfaPortFreeAdapterCommArea;
16351 +       AdapterExtension->Common->AdapterFuncs.BuildSgMap = AfaPortBuildSgMap;
16352 +       AdapterExtension->Common->AdapterFuncs.FreeDmaResources = AfaPortFreeDmaResources;
16353 +       AdapterExtension->Common->AdapterFuncs.AllocateAndMapFibSpace = AfaPortAllocateAndMapFibSpace;
16354 +       AdapterExtension->Common->AdapterFuncs.UnmapAndFreeFibSpace = AfaPortUnmapAndFreeFibSpace;
16355 +       AdapterExtension->Common->AdapterFuncs.InterruptAdapter = SaInterruptAdapter;
16356 +       AdapterExtension->Common->AdapterFuncs.EnableInterrupt = SaEnableInterrupt;
16357 +       AdapterExtension->Common->AdapterFuncs.DisableInterrupt = SaDisableInterrupt;
16358 +       AdapterExtension->Common->AdapterFuncs.NotifyAdapter = SaNotifyAdapter;
16359 +       AdapterExtension->Common->AdapterFuncs.ResetDevice = SaResetDevice;
16360 +       AdapterExtension->Common->AdapterFuncs.InterruptHost = NULL;
16361 +
16362 +       AdapterExtension->Common->AdapterFuncs.SendSynchFib = SaSendSynchFib;
16363 +
16364 +       NewAdapter.AdapterExtension = CommonExtension;
16365 +       NewAdapter.AdapterFuncs = &AdapterExtension->Common->AdapterFuncs;
16366 +       NewAdapter.AdapterInterruptsBelowDpc = FALSE;
16367 +       NewAdapter.AdapterUserVars = SaUserVars;
16368 +       NewAdapter.AdapterUserVarsSize = sizeof(SaUserVars) / sizeof(FSA_USER_VAR);
16369 +
16370 +       NewAdapter.Dip = CommonExtension->OsDep.dip;
16371 +
16372 +       
16373 +       if ( AfaCommInitNewAdapter( &NewAdapter ) == NULL) {
16374 +                       cmn_err(CE_WARN, "SaInitDevice: AfaCommInitNewAdapter failed\n");
16375 +                       return (FAILURE);
16376 +       };
16377 +
16378 +
16379 +       AdapterExtension->Common->Adapter = NewAdapter.Adapter;
16380 +
16381 +       if (AdapterExtension->Common->Adapter == NULL) {
16382 +
16383 +               AfaPortLogError(AdapterExtension->Common, FAILURE, NULL, 0);
16384 +               cmn_err(CE_WARN, "%s%d SaInitDevice: No Adapter pointer", name, instance);
16385 +
16386 +               return (FAILURE); 
16387 +       }
16388 +
16389 +
16390 +    //
16391 +       // Start any kernel threads needed
16392 +       OsStartKernelThreads(AdapterExtension);
16393 +
16394 +       //
16395 +       // Tell the adapter that all is configure, and it can start accepting requests
16396 +       //
16397 +
16398 +       SaStartAdapter(AdapterExtension);
16399 +
16400 +
16401 +
16402 +       //
16403 +       // Put this adapter into the list of Sa adapters
16404 +       //
16405 +
16406 +       AdapterExtension->Next = SaAdapterList;
16407 +       SaAdapterList = AdapterExtension;
16408 +
16409 +       AdapterExtension->Common->AdapterConfigured = TRUE;
16410 +
16411 +
16412 +#ifdef AACDISK
16413 +       //
16414 +       // Call the disk layer to initialize itself.
16415 +       //
16416 +
16417 +       AfaDiskInitNewAdapter( AdapterExtension->Common->AdapterNumber, AdapterExtension->Common->Adapter );
16418 +#endif
16419 +
16420 +
16421 +init_done:
16422 +
16423 +       AdapterExtension->Common->AdapterPrintfsToScreen = FALSE;
16424 +
16425 +       OsAttachHBA(AdapterExtension);
16426 +
16427 +       return (0);
16428 +
16429 +init_error:
16430 +
16431 +       return (FAILURE);
16432 +}
16433 +
16434 +
16435 +
16436 +VOID
16437 +SaStartAdapter (PSa_ADAPTER_EXTENSION AdapterExtension)
16438 +{
16439 +       ULONG ReturnStatus;
16440 +       LARGE_INTEGER HostTime;
16441 +       ULONG ElapsedSeconds;
16442 +       PADAPTER_INIT_STRUCT InitStruct;
16443 +
16444 +       //
16445 +       // Fill in the remaining pieces of the InitStruct.
16446 +       //
16447 +
16448 +       InitStruct = AdapterExtension->Common->InitStruct;
16449 +
16450 +       InitStruct->HostPhysMemPages = AfaPortGetMaxPhysicalPage(AdapterExtension->Common);
16451 +
16452 +       ElapsedSeconds = OsGetSeconds();
16453 +
16454 +       InitStruct->HostElapsedSeconds = ElapsedSeconds;
16455 +
16456 +       //
16457 +       // Tell the adapter we are back and up and running so it will scan its command
16458 +       // queues and enable our interrupts
16459 +       //
16460 +
16461 +       AdapterExtension->LocalMaskInterruptControl =
16462 +               (PrintfReady | DOORBELL_1 | DOORBELL_2 | DOORBELL_3 | DOORBELL_4);
16463 +
16464 +
16465 +       //
16466 +       // First clear out all interrupts.  Then enable the one's that we can handle.
16467 +       //
16468 +
16469 +       Sa_WRITE_USHORT( AdapterExtension,  SaDbCSR.PRISETIRQMASK, (USHORT) 0xffff );
16470 +       Sa_WRITE_USHORT( AdapterExtension,  SaDbCSR.PRICLEARIRQMASK,
16471 +                                       (PrintfReady | DOORBELL_1 | DOORBELL_2 | DOORBELL_3 | DOORBELL_4) );
16472 +
16473 +       SaSendSynchCommand(AdapterExtension, 
16474 +                          INIT_STRUCT_BASE_ADDRESS, 
16475 +                          (ULONG) AdapterExtension->Common->PhysicalInitStruct,
16476 +                          0,
16477 +                          0,
16478 +                          0,
16479 +                          &ReturnStatus);
16480 +
16481 +}
16482 +
16483 +
16484 +VOID
16485 +SaResetDevice (PVOID Arg1){
16486 +
16487 +}
16488 +
16489 +
16490 +/*++
16491 +
16492 +Routine Description:
16493 +
16494 +       The will cause the adapter to take a break point.
16495 +
16496 +Arguments:
16497 +
16498 +       None
16499 +
16500 +Return Value:
16501 +
16502 +    Nothing
16503 +
16504 +--*/
16505 +VOID
16506 +SaInterruptAdapter (PVOID Arg1)
16507 +{
16508 +       PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
16509 +       PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) CommonExtension->MiniPort;
16510 +
16511 +       ULONG ReturnStatus;
16512 +
16513 +       SaSendSynchCommand(AdapterExtension, 
16514 +                          BREAKPOINT_REQUEST,
16515 +                          0,
16516 +                          0,
16517 +                          0,
16518 +                          0,
16519 +                          &ReturnStatus);
16520 +
16521 +}
16522 +
16523 +
16524 +/*++
16525 +
16526 +Routine Description:
16527 +
16528 +    Will read the adapter CSRs to find the reason the adapter has
16529 +    interrupted us.
16530 +
16531 +Arguments:
16532 +
16533 +    AdapterEvent - Enumerated type the returns the reason why we were interrutped.
16534 +
16535 +Return Value:
16536 +
16537 +    Nothing
16538 +
16539 +--*/
16540 +VOID
16541 +SaNotifyAdapter (PVOID Arg1, IN HOST_2_ADAP_EVENT AdapterEvent)
16542 +{
16543 +       PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
16544 +       PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) CommonExtension->MiniPort;
16545 +       ULONG ReturnStatus;
16546 +
16547 +    switch (AdapterEvent) {
16548 +        case AdapNormCmdQue:
16549 +
16550 +                       Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_1);
16551 +            break;
16552 +
16553 +        case HostNormRespNotFull:
16554 +
16555 +                       Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_4);
16556 +            break;
16557 +
16558 +        case AdapNormRespQue:
16559 +
16560 +                       Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_2);
16561 +            break;
16562 +
16563 +        case HostNormCmdNotFull:
16564 +
16565 +                       Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_3);
16566 +            break;
16567 +
16568 +        case HostShutdown:
16569 +
16570 +//                     SaSendSynchCommand(AdapterExtension, HOST_CRASHING, 0, 0, 0, 0, &ReturnStatus);
16571 +
16572 +            break;
16573 +
16574 +               case FastIo:
16575 +                       Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_6);
16576 +                       break;
16577 +
16578 +               case AdapPrintfDone:
16579 +                       Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_5);
16580 +                       break;
16581 +
16582 +        default:
16583 +
16584 +                       SaBugCheck(0,0,0);
16585 +            AfaPortPrint("Notify requested with an invalid request 0x%x.\n",AdapterEvent);
16586 +            break;
16587 +    }
16588 +}
16589 +
16590 +
16591 +/*++
16592 +
16593 +Routine Description:
16594 +
16595 +       This routine will send a synchronous comamnd to the adapter and wait for its
16596 +       completion.
16597 +
16598 +Arguments:
16599 +
16600 +       AdapterExtension - Pointer to adapter extension structure.
16601 +       Command - Which command to send
16602 +       Parameter1 - 4  - Parameters for command
16603 +       ReturnStatus - return status from adapter after completion of command
16604 +
16605 +
16606 +Return Value:
16607 +
16608 +       AAC_STATUS
16609 +
16610 +--*/
16611 +AAC_STATUS
16612 +SaSendSynchCommand(
16613 +                  PVOID Arg1,
16614 +                  ULONG Command,
16615 +                  ULONG Parameter1,
16616 +                  ULONG Parameter2,
16617 +                  ULONG Parameter3,
16618 +                  ULONG Parameter4,
16619 +                  PULONG       ReturnStatus
16620 +       )
16621 +{
16622 +       PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) Arg1;
16623 +       ULONG StartTime,EndTime,WaitTime;
16624 +       BOOLEAN CommandSucceeded;
16625 +
16626 +       //
16627 +       // Write the Command into Mailbox 0
16628 +       //
16629 +
16630 +       Sa_WRITE_ULONG( AdapterExtension, Mailbox0, Command);
16631 +
16632 +       //
16633 +       // Write the parameters into Mailboxes 1 - 4
16634 +       //
16635 +
16636 +       Sa_WRITE_ULONG( AdapterExtension, Mailbox1, Parameter1);
16637 +       Sa_WRITE_ULONG( AdapterExtension, Mailbox2, Parameter2);
16638 +       Sa_WRITE_ULONG( AdapterExtension, Mailbox3, Parameter3);
16639 +       Sa_WRITE_ULONG( AdapterExtension, Mailbox4, Parameter4);
16640 +
16641 +       //
16642 +       // Clear the synch command doorbell to start on a clean slate.
16643 +       //
16644 +               
16645 +       Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p, DOORBELL_0);
16646 +
16647 +       //
16648 +       // Signal that there is a new synch command
16649 +       //
16650 +
16651 +       Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s, DOORBELL_0);
16652 +
16653 +       CommandSucceeded = FALSE;
16654 +
16655 +       StartTime = OsGetSeconds();
16656 +       WaitTime = 0;
16657 +
16658 +       while (WaitTime < 30) { // wait up to 30 seconds
16659 +
16660 +               drv_usecwait(5);                                // delay 5 microseconds to let Mon960 get info.
16661 +
16662 +               //
16663 +               // Mon110 will set doorbell0 bit when it has completed the command.
16664 +               //
16665 +
16666 +               if( Sa_READ_USHORT( AdapterExtension, DoorbellReg_p) & DOORBELL_0 )  {
16667 +
16668 +                       CommandSucceeded = TRUE;
16669 +                       break;
16670 +               }
16671 +
16672 +               EndTime = OsGetSeconds();
16673 +               WaitTime = EndTime - StartTime;
16674 +
16675 +       }
16676 +
16677 +       if (CommandSucceeded != TRUE) {
16678 +
16679 +               return (STATUS_IO_TIMEOUT);
16680 +
16681 +       }
16682 +
16683 +       //
16684 +       // Clear the synch command doorbell.
16685 +       //
16686 +               
16687 +       Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p, DOORBELL_0);
16688 +
16689 +       //
16690 +       // Pull the synch status from Mailbox 0.
16691 +       //
16692 +
16693 +       *ReturnStatus = Sa_READ_ULONG( AdapterExtension, Mailbox0);
16694 +
16695 +       //
16696 +       // Return SUCCESS
16697 +       //
16698 +
16699 +       return (STATUS_SUCCESS);
16700 +
16701 +}
16702 +
16703 +
16704 +/*++
16705 +
16706 +Routine Description:
16707 +
16708 +       This routine will send a synchronous fib to the adapter and wait for its
16709 +       completion.
16710 +
16711 +Arguments:
16712 +
16713 +       AdapterExtension - Pointer to adapter extension structure.
16714 +       FibPhysicalAddress - Physical address of fib to send.
16715 +
16716 +
16717 +Return Value:
16718 +
16719 +       BOOLEAN
16720 +
16721 +--*/
16722 +BOOLEAN
16723 +SaSendSynchFib (PVOID Arg1, ULONG FibPhysicalAddress)
16724 +{
16725 +       PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
16726 +       PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) CommonExtension->MiniPort;
16727 +       ULONG returnStatus;
16728 +
16729 +       if (SaSendSynchCommand( AdapterExtension,
16730 +                                                   SEND_SYNCHRONOUS_FIB,
16731 +                                                   FibPhysicalAddress,
16732 +                                                   0,
16733 +                                                   0,
16734 +                                                   0,
16735 +                                                   &returnStatus ) != STATUS_SUCCESS ) {
16736 +
16737 +               return (FALSE);
16738 +               
16739 +       }
16740 +       
16741 +       return (TRUE);
16742 +                                                                               
16743 +}
16744 +
16745 +BOOLEAN
16746 +WriteFlash(
16747 +       PVOID AdapterExtension,
16748 +       ULONG *MappedBuffer)
16749 +{
16750 +       return (FALSE);
16751 +}
16752 +
16753 +BOOLEAN
16754 +ReadFlash(
16755 +       PVOID AdapterExtension,
16756 +       ULONG *MappedBuffer)
16757 +{
16758 +       return (FALSE);
16759 +}
16760 +
This page took 1.884596 seconds and 3 git commands to generate.