]> git.pld-linux.org Git - packages/kernel.git/blob - linux-2.4.9-aacraid-20010816.patch
- obsolete
[packages/kernel.git] / linux-2.4.9-aacraid-20010816.patch
1 diff -burN linux-2.4.9/MAINTAINERS linux/MAINTAINERS
2 --- linux-2.4.9/MAINTAINERS     Thu Aug 16 13:40:30 2001
3 +++ linux/MAINTAINERS   Thu Aug 16 13:41:30 2001
4 @@ -126,6 +126,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.9/arch/i386/defconfig linux/arch/i386/defconfig
20 --- linux-2.4.9/arch/i386/defconfig     Thu Aug 16 13:40:30 2001
21 +++ linux/arch/i386/defconfig   Thu Aug 16 13:41:30 2001
22 @@ -286,6 +286,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.9/drivers/scsi/Config.in linux/drivers/scsi/Config.in
31 --- linux-2.4.9/drivers/scsi/Config.in  Thu Aug 16 13:40:11 2001
32 +++ linux/drivers/scsi/Config.in        Thu Aug 16 13:41:30 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.9/drivers/scsi/Makefile linux/drivers/scsi/Makefile
42 --- linux-2.4.9/drivers/scsi/Makefile   Thu Aug 16 13:40:11 2001
43 +++ linux/drivers/scsi/Makefile Thu Aug 16 13:41:30 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,6 +194,10 @@
53  sim710_u.h: sim710_d.h
54  
55  sim710.o : sim710_d.h
56 +
57 +aacraid.o:
58 +       cd aacraid; make
59 +
60
61  53c700_d.h: 53c700.scr script_asm.pl
62         $(PERL) -s script_asm.pl -ncr7x0_family < 53c700.scr
63 diff -burN linux-2.4.9/drivers/scsi/aacraid/ChangeLog linux/drivers/scsi/aacraid/ChangeLog
64 --- linux-2.4.9/drivers/scsi/aacraid/ChangeLog  Wed Dec 31 18:00:00 1969
65 +++ linux/drivers/scsi/aacraid/ChangeLog        Thu Aug 16 18:18:10 2001
66 @@ -0,0 +1,30 @@
67 +2001-08-16  Matt Domsch <Matt_Domsch@dell.com>
68 +* renamed aacraid_pciid to perc_pciid for future Dell controllers
69 +* added rx_pciid and sa_pciid options for future Adaptec controllers
70 +* applied changes from Adaptec (new PCI ID, some cleanups)
71 +* released patch against 2.4.8
72 +* released patch against 2.4.9
73 +       
74 +2001-08-11  Matt Domsch <Matt_Domsch@dell.com>
75 +* applied pciid patch to allow passing a new PCI ID to the module at insmod
76 +* removed all #ifdef CONFIG_SMP and #ifdef MODULE stuff
77 +* released patch against 2.4.7
78 +* released patch against 2.4.8
79 +
80 +2001-07-21  Matt Domsch <Matt_Domsch@dell.com>
81 +* changed __SMP__ to CONFIG_SMP everywhere (really this time)
82 +* Applied read capacity patch
83 +* released patch against 2.4.6
84 +* released patch against 2.4.7
85 +       
86 +2001-07-04  Matt Domsch <Matt_Domsch@dell.com>
87 +* Started with linux-2.4.5-aacraid-043001.patch
88 +* Applied Chris Pascoe's SMP fix patch
89 +* Released patch against 2.4.6
90 +
91 +
92 +2001-04-30  Matt Domsch <Matt_Domsch@dell.com>
93 +* Started with linux-2.4.3-aacraid-030101.patch
94 +* Applied against 2.4.4.
95 +* Added scsi_set_pci_device() call in linit.c
96 +       
97 diff -burN linux-2.4.9/drivers/scsi/aacraid/Makefile linux/drivers/scsi/aacraid/Makefile
98 --- linux-2.4.9/drivers/scsi/aacraid/Makefile   Wed Dec 31 18:00:00 1969
99 +++ linux/drivers/scsi/aacraid/Makefile Thu Aug 16 13:41:30 2001
100 @@ -0,0 +1,169 @@
101 +#
102 +# Makefile aacraid Raid Controller
103 +#
104 +
105 +###############################################################################
106 +### SOURCE FILES DEFINES
107 +###############################################################################
108 +
109 +CFILES_DRIVER=\
110 +       ./aachba.c \
111 +       ./aacid.c \
112 +       ./commctrl.c \
113 +       ./comminit.c \
114 +       ./commsup.c \
115 +       ./dpcsup.c \
116 +       ./linit.c \
117 +       ./osddi.c \
118 +       ./osfuncs.c \
119 +       ./ossup.c \
120 +       ./port.c \
121 +       ./rx.c \
122 +       ./sap1sup.c
123 +
124 +IFILES_DRIVER=\
125 +       ./include/AacGenericTypes.h \
126 +       ./include/aac_unix_defs.h \
127 +       ./include/adapter.h \
128 +       ./include/afacomm.h \
129 +       ./include/aifstruc.h \
130 +       ./include/build_number.h \
131 +       ./include/commdata.h \
132 +       ./include/commerr.h \
133 +       ./include/commfibcontext.h \
134 +       ./include/comprocs.h \
135 +       ./include/comproto.h \
136 +       ./include/comstruc.h \
137 +       ./include/comsup.h \
138 +       ./include/fsact.h \
139 +       ./include/fsafs.h  \
140 +       ./include/fsaioctl.h \
141 +       ./include/fsaport.h \
142 +       ./include/fsatypes.h \
143 +       ./include/linit.h \
144 +       ./include/monkerapi.h \
145 +       ./include/nodetype.h \
146 +       ./include/nvramioctl.h \
147 +       ./include/osheaders.h \
148 +       ./include/ostypes.h \
149 +       ./include/pcisup.h \
150 +       ./include/perfpack.h \
151 +       ./include/port.h \
152 +       ./include/protocol.h \
153 +       ./include/revision.h \
154 +       ./include/rxcommon.h \
155 +       ./include/rx.h \
156 +       ./include/sap1common.h \
157 +       ./include/sap1.h \
158 +       ./include/version.h
159 +
160 +ALL_SOURCE=\
161 +       ${CFILES_DRIVER} \
162 +       ${IFILES_DRIVER} 
163 +
164 +###############################################################################
165 +### OBJECT FILES DEFINES
166 +###############################################################################
167 +
168 +
169 +OFILES_DRIVER=\
170 +       linit.o \
171 +       osfuncs.o \
172 +       osddi.o \
173 +       aachba.o \
174 +       commctrl.o \
175 +       comminit.o \
176 +       commsup.o \
177 +       dpcsup.o \
178 +       ossup.o \
179 +       port.o \
180 +       rx.o \
181 +       sap1sup.o
182 +
183 +TARGET_OFILES= ${OFILES_DRIVER} aacid.o
184 +
185 +###############################################################################
186 +### GENERAL DEFINES
187 +###############################################################################
188 +
189 +#  Remember that we're doing a chdir one level lower, so we need an extra ../
190 +INCS= \
191 +       -I./include \
192 +       -I../../../include -I..
193 +
194 +WARNINGS= -w -Wall -Wno-unused -Wno-switch -Wno-missing-prototypes -Wno-implicit
195 +
196 +
197 +COMMON_FLAGS=\
198 +       -D__KERNEL__=1 -DUNIX -DCVLOCK_USE_SPINLOCK -DLINUX \
199 +       ${INCS} \
200 +       ${WARNINGS}
201 +
202 +AACFLAGS=${CFLAGS} ${COMMON_FLAGS} ${EXTRA_FLAGS}
203 +
204 +###############################################################################
205 +### DO GENERAL STUFF
206 +###############################################################################
207 +
208 +.SUFFIXES:
209 +.SUFFIXES: .c .o .h .a
210 +
211 +all: source ${TARGET_OFILES} aacraid.o
212 +
213 +source: ${ALL_SOURCE}
214 +
215 +clean:
216 +       rm *.o
217 +
218 +###############################################################################
219 +### DRIVER LINKS
220 +###############################################################################
221 +
222 +aacraid.o: source ${TARGET_OFILES}
223 +       ld -r -o $@ $(TARGET_OFILES)
224 +       cp -r aacraid.o ../
225 +
226 +###############################################################################
227 +### SIMPLE COMPILES
228 +###############################################################################
229 +
230 +linit.o: ./linit.c
231 +       $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o linit.o ./linit.c
232 +
233 +aachba.o: ./aachba.c
234 +       $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o aachba.o ./aachba.c
235 +
236 +osddi.o: ./osddi.c
237 +       $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o osddi.o ./osddi.c
238 +
239 +osfuncs.o: ./osfuncs.c
240 +       $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o osfuncs.o ./osfuncs.c
241 +
242 +commctrl.o:  ./commctrl.c
243 +       $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o commctrl.o ./commctrl.c
244 +
245 +comminit.o:  ./comminit.c
246 +       $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o comminit.o ./comminit.c
247 +
248 +commsup.o:  ./commsup.c
249 +       $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o commsup.o ./commsup.c
250 +
251 +dpcsup.o:  ./dpcsup.c
252 +       $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o dpcsup.o ./dpcsup.c
253 +
254 +aacid.o:  ./aacid.c
255 +       $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o aacid.o ./aacid.c
256 +
257 +port.o:  ./port.c
258 +       $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o port.o ./port.c
259 +
260 +ossup.o:  ./ossup.c
261 +       $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o ossup.o ./ossup.c
262 +
263 +rx.o:  ./rx.c
264 +       $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o rx.o ./rx.c
265 +
266 +sap1sup.o: ./sap1sup.c
267 +       $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o sap1sup.o ./sap1sup.c
268 +
269 +
270 diff -burN linux-2.4.9/drivers/scsi/aacraid/README linux/drivers/scsi/aacraid/README
271 --- linux-2.4.9/drivers/scsi/aacraid/README     Wed Dec 31 18:00:00 1969
272 +++ linux/drivers/scsi/aacraid/README   Thu Aug 16 13:41:30 2001
273 @@ -0,0 +1,46 @@
274 +                               AACRAID Driver for Linux
275 +
276 +Introduction
277 +-------------------------
278 +The aacraid driver adds support for Adaptec (http://www.adaptec.com)
279 +OEM based RAID controllers.
280 +
281 +It is important to note the amount of test time the 2.4.x driver
282 +received. Though not a great deal has changed between 2.2 and 2.4
283 +for this version, it has not recevied a great deal of test time.
284 +
285 +A new driver version is in the works and that version will be
286 +submitted to the standard distribution kernel. The previous
287 +2.2 version was submitted but rejected due to the large
288 +amount of code reduncdancy and NTisms. This driver was
289 +initially ported from NT to Solaris and then to Linux.
290 +
291 +The new version is being written on Unix for Unix and
292 +should be much easier to read and a great deal cleaner.
293 +
294 +Supported Cards/Chipsets
295 +-------------------------
296 +       Dell Computer Corporation PERC 2 Quad Channel
297 +       Dell Computer Corporation PERC 2/Si
298 +       Dell Computer Corporation PERC 3/Si
299 +       Dell Computer Corporation PERC 3/Di
300 +       HP NetRAID-4M
301 +
302 +Not Supported Devices
303 +-------------------------
304 +       Any and All Adaptec branded raid controllers.
305 +
306 +People
307 +-------------------------
308 +       Adaptec Unix OEM Product Group
309 +
310 +Mailing List
311 +-------------------------
312 +please see http://domsch.com/linux for information
313 +on mailing lists. There is both a development and
314 +an announcment list. Due to the overwhelming amount
315 +of mail I receive about this driver, I can not
316 +answer questions individually and requests should
317 +be directed to the list server. Thanks.
318 +
319 +Modified by Brian Boerner February 2001
320 diff -burN linux-2.4.9/drivers/scsi/aacraid/aachba.c linux/drivers/scsi/aacraid/aachba.c
321 --- linux-2.4.9/drivers/scsi/aacraid/aachba.c   Wed Dec 31 18:00:00 1969
322 +++ linux/drivers/scsi/aacraid/aachba.c Thu Aug 16 13:41:30 2001
323 @@ -0,0 +1,1897 @@
324 +/*++
325 + * Adaptec aacraid device driver for Linux.
326 + *
327 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
328 + *
329 + * This program is free software; you can redistribute it and/or modify
330 + * it under the terms of the GNU General Public License as published by
331 + * the Free Software Foundation; either version 2, or (at your option)
332 + * any later version.
333 + *
334 + * This program is distributed in the hope that it will be useful,
335 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
336 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
337 + * GNU General Public License for more details.
338 + *
339 + * You should have received a copy of the GNU General Public License
340 + * along with this program; see the file COPYING.  If not, write to
341 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
342 + *
343 + * Module Name:
344 + *   aachba.c
345 + *
346 + * Abstract: driver...
347 + *
348 +--*/
349 +
350 +static char *ident_aachba = "aacraid_ident aachba.c 1.0.6 2000/10/09 Adaptec, Inc.";
351 +
352 +/*------------------------------------------------------------------------------
353 + *              I N C L U D E S
354 + *----------------------------------------------------------------------------*/
355 +#include "osheaders.h"
356 +#include "AacGenericTypes.h"
357 +#include "aac_unix_defs.h"
358 +#include "comstruc.h"
359 +#include "monkerapi.h"
360 +#include "protocol.h"
361 +#include "fsafs.h"
362 +#include "fsact.h"
363 +#include "fsaioctl.h"
364 +
365 +#include "sap1common.h"
366 +#include "fsaport.h"
367 +#include "pcisup.h"
368 +#include "sap1.h"
369 +#include "nodetype.h"
370 +#include "comsup.h"
371 +#include "afacomm.h"
372 +#include "adapter.h"
373 +
374 +/*------------------------------------------------------------------------------
375 + *              D E F I N E S
376 + *----------------------------------------------------------------------------*/
377 +/*     SCSI Commands */
378 +#define        SS_TEST                 0x00    /* Test unit ready */
379 +#define SS_REZERO              0x01    /* Rezero unit */
380 +#define        SS_REQSEN               0x03    /* Request Sense */
381 +#define SS_REASGN              0x07    /* Reassign blocks */
382 +#define        SS_READ                 0x08    /* Read 6   */
383 +#define        SS_WRITE                0x0A    /* Write 6  */
384 +#define        SS_INQUIR               0x12    /* inquiry */
385 +#define        SS_ST_SP                0x1B    /* Start/Stop unit */
386 +#define        SS_LOCK                 0x1E    /* prevent/allow medium removal */
387 +#define SS_RESERV              0x16    /* Reserve */
388 +#define SS_RELES               0x17    /* Release */
389 +#define SS_MODESEN             0x1A    /* Mode Sense 6 */
390 +#define        SS_RDCAP                0x25    /* Read Capacity */
391 +#define        SM_READ                 0x28    /* Read 10  */
392 +#define        SM_WRITE                0x2A    /* Write 10 */
393 +#define SS_SEEK                        0x2B    /* Seek */
394 +
395 +/* values for inqd_pdt: Peripheral device type in plain English */
396 +#define        INQD_PDT_DA     0x00    /* Direct-access (DISK) device */
397 +#define        INQD_PDT_PROC   0x03    /* Processor device */
398 +#define        INQD_PDT_CHNGR  0x08    /* Changer (jukebox, scsi2) */
399 +#define        INQD_PDT_COMM   0x09    /* Communication device (scsi2) */
400 +#define        INQD_PDT_NOLUN2 0x1f    /* Unknown Device (scsi2) */
401 +#define        INQD_PDT_NOLUN  0x7f    /* Logical Unit Not Present */
402 +
403 +#define        INQD_PDT_DMASK  0x1F    /* Peripheral Device Type Mask */
404 +#define        INQD_PDT_QMASK  0xE0    /* Peripheral Device Qualifer Mask */
405 +
406 +#define        TARGET_LUN_TO_CONTAINER(Target, Lun)    (((Lun) << 4) | Target)
407 +#define CONTAINER_TO_TARGET(Container)          ((Container) & 0xf)
408 +#define CONTAINER_TO_LUN(Container)             ((Container) >> 4)
409 +
410 +#define MAX_FIB_DATA (sizeof(FIB) - sizeof(FIB_HEADER))
411 +
412 +#define MAX_DRIVER_SG_SEGMENT_COUNT 17
413 +
414 +// ------------------------------------------------------
415 +// Sense keys
416 +//
417 +#define SENKEY_NO_SENSE      0x00 //
418 +#define SENKEY_UNDEFINED     0x01 //
419 +#define SENKEY_NOT_READY     0x02 //
420 +#define SENKEY_MEDIUM_ERR    0x03 //
421 +#define SENKEY_HW_ERR        0x04 //
422 +#define SENKEY_ILLEGAL       0x05 //
423 +#define SENKEY_ATTENTION     0x06 //
424 +#define SENKEY_PROTECTED     0x07 //
425 +#define SENKEY_BLANK         0x08 //
426 +#define SENKEY_V_UNIQUE      0x09 //
427 +#define SENKEY_CPY_ABORT     0x0A //
428 +#define SENKEY_ABORT         0x0B //
429 +#define SENKEY_EQUAL         0x0C //
430 +#define SENKEY_VOL_OVERFLOW  0x0D //
431 +#define SENKEY_MISCOMP       0x0E //
432 +#define SENKEY_RESERVED      0x0F //
433 +
434 +// ------------------------------------------------------
435 +// Sense codes
436 +//
437 +#define SENCODE_NO_SENSE                        0x00
438 +#define SENCODE_END_OF_DATA                     0x00
439 +#define SENCODE_BECOMING_READY                  0x04
440 +#define SENCODE_INIT_CMD_REQUIRED               0x04
441 +#define SENCODE_PARAM_LIST_LENGTH_ERROR         0x1A
442 +#define SENCODE_INVALID_COMMAND                 0x20
443 +#define SENCODE_LBA_OUT_OF_RANGE                0x21
444 +#define SENCODE_INVALID_CDB_FIELD               0x24
445 +#define SENCODE_LUN_NOT_SUPPORTED               0x25
446 +#define SENCODE_INVALID_PARAM_FIELD             0x26
447 +#define SENCODE_PARAM_NOT_SUPPORTED             0x26
448 +#define SENCODE_PARAM_VALUE_INVALID             0x26
449 +#define SENCODE_RESET_OCCURRED                  0x29
450 +#define SENCODE_LUN_NOT_SELF_CONFIGURED_YET     0x3E
451 +#define SENCODE_INQUIRY_DATA_CHANGED            0x3F
452 +#define SENCODE_SAVING_PARAMS_NOT_SUPPORTED     0x39
453 +#define SENCODE_DIAGNOSTIC_FAILURE              0x40
454 +#define SENCODE_INTERNAL_TARGET_FAILURE         0x44
455 +#define SENCODE_INVALID_MESSAGE_ERROR           0x49
456 +#define SENCODE_LUN_FAILED_SELF_CONFIG          0x4c
457 +#define SENCODE_OVERLAPPED_COMMAND              0x4E
458 +
459 +// ------------------------------------------------------
460 +// Additional sense codes
461 +//
462 +#define ASENCODE_NO_SENSE                       0x00
463 +#define ASENCODE_END_OF_DATA                    0x05
464 +#define ASENCODE_BECOMING_READY                 0x01
465 +#define ASENCODE_INIT_CMD_REQUIRED              0x02
466 +#define ASENCODE_PARAM_LIST_LENGTH_ERROR        0x00
467 +#define ASENCODE_INVALID_COMMAND                0x00
468 +#define ASENCODE_LBA_OUT_OF_RANGE               0x00
469 +#define ASENCODE_INVALID_CDB_FIELD              0x00
470 +#define ASENCODE_LUN_NOT_SUPPORTED              0x00
471 +#define ASENCODE_INVALID_PARAM_FIELD            0x00
472 +#define ASENCODE_PARAM_NOT_SUPPORTED            0x01
473 +#define ASENCODE_PARAM_VALUE_INVALID            0x02
474 +#define ASENCODE_RESET_OCCURRED                 0x00
475 +#define ASENCODE_LUN_NOT_SELF_CONFIGURED_YET    0x00
476 +#define ASENCODE_INQUIRY_DATA_CHANGED           0x03
477 +#define ASENCODE_SAVING_PARAMS_NOT_SUPPORTED    0x00
478 +#define ASENCODE_DIAGNOSTIC_FAILURE             0x80
479 +#define ASENCODE_INTERNAL_TARGET_FAILURE        0x00
480 +#define ASENCODE_INVALID_MESSAGE_ERROR          0x00
481 +#define ASENCODE_LUN_FAILED_SELF_CONFIG         0x00
482 +#define ASENCODE_OVERLAPPED_COMMAND             0x00
483 +
484 +#define BYTE0( x ) ( unsigned char )( x )
485 +#define BYTE1( x ) ( unsigned char )( x >> 8  )
486 +#define BYTE2( x ) ( unsigned char )( x >> 16 )
487 +#define BYTE3( x ) ( unsigned char )( x >> 24 )
488 +
489 +/*------------------------------------------------------------------------------
490 + *              S T R U C T S / T Y P E D E F S
491 + *----------------------------------------------------------------------------*/
492 +/* SCSI inquiry data */
493 +struct inquiry_data {
494 +       unchar inqd_pdt;     /* Peripheral qualifier | Peripheral Device Type  */
495 +       unchar inqd_dtq;     /* RMB | Device Type Qualifier  */
496 +       unchar inqd_ver;     /* ISO version | ECMA version | ANSI-approved version */
497 +       unchar inqd_rdf;     /* AENC | TrmIOP | Response data format */
498 +       unchar inqd_len;     /* Additional length (n-4) */
499 +       unchar inqd_pad1[2]; /* Reserved - must be zero */
500 +       unchar inqd_pad2;    /* RelAdr | WBus32 | WBus16 |  Sync  | Linked |Reserved| CmdQue | SftRe */
501 +       unchar inqd_vid[8];  /* Vendor ID */
502 +       unchar inqd_pid[16]; /* Product ID */
503 +       unchar inqd_prl[4];  /* Product Revision Level */
504 +};
505 +
506 +struct sense_data {
507 +       unchar error_code;              // 70h (current errors), 71h(deferred errors)
508 +       unchar valid:1;                 // A valid bit of one indicates that the information 
509 +                                       // field contains valid information as defined in the
510 +                                       // SCSI-2 Standard.
511 +       
512 +       unchar segment_number;  // Only used for COPY, COMPARE, or COPY AND VERIFY 
513 +                               // commands
514 +       
515 +       unchar sense_key:4;             // Sense Key
516 +       unchar reserved:1;
517 +       unchar ILI:1;                   // Incorrect Length Indicator
518 +       unchar EOM:1;                   // End Of Medium - reserved for random access devices
519 +       unchar filemark:1;              // Filemark - reserved for random access devices
520 +       
521 +       unchar information[4];  // for direct-access devices, contains the unsigned 
522 +                               // logical block address or residue associated with 
523 +                               // the sense key 
524 +       unchar add_sense_len;   // number of additional sense bytes to follow this field
525 +       unchar cmnd_info[4];    // not used
526 +       unchar ASC;             // Additional Sense Code
527 +       unchar ASCQ;            // Additional Sense Code Qualifier
528 +       unchar FRUC;            // Field Replaceable Unit Code - not used
529 +       
530 +       unchar bit_ptr:3;       // indicates which byte of the CDB or parameter data
531 +                               // was in error
532 +       unchar BPV:1;           // bit pointer valid (BPV): 1- indicates that 
533 +                               // the bit_ptr field has valid value
534 +       unchar reserved2:2;
535 +       unchar CD:1;            // command data bit: 1- illegal parameter in CDB.
536 +                               //                   0- illegal parameter in data.
537 +       unchar SKSV:1;
538 +       
539 +       unchar field_ptr[2];    // byte of the CDB or parameter data in error
540 +};
541 +
542 +/*------------------------------------------------------------------------------
543 + *              G L O B A L S
544 + *----------------------------------------------------------------------------*/
545 +/*------------------------------------------------------------------------------
546 + *              M O D U L E   G L O B A L S
547 + *----------------------------------------------------------------------------*/
548 +static fsadev_t *g_fsa_dev_array[8];   // SCSI Device Instance Pointers
549 +static struct sense_data g_sense_data[MAXIMUM_NUM_CONTAINERS];
550 +
551 +/*------------------------------------------------------------------------------
552 + *              F U N C T I O N   P R O T O T Y P E S
553 + *----------------------------------------------------------------------------*/
554 +AAC_STATUS AacHba_OpenAdapter( PVOID AdapterArg);
555 +AAC_STATUS AacHba_CloseAdapter( PVOID AdapterArg);
556 +BOOLEAN AacHba_HandleAif( PVOID AdapterArg, PFIB_CONTEXT FibContext);
557 +BOOLEAN AacHba_AdapterDeviceControl ( PVOID AdapterArg, 
558 +       PAFA_IOCTL_CMD IoctlCmdPtr, int * ReturnStatus);
559 +
560 +void AacHba_CompleteScsi( 
561 +       Scsi_Cmnd *scsi_cmnd_ptr );
562 +
563 +void AacHba_CompleteScsiNoLock( 
564 +       Scsi_Cmnd *scsi_cmnd_ptr );
565 +
566 +static void AacHba_ReadCallback( 
567 +       void *Context, 
568 +       PFIB_CONTEXT FibContext, 
569 +       int FibStatus );
570 +
571 +static void AacHba_WriteCallback( 
572 +       void *Context, 
573 +       PFIB_CONTEXT FibContext, 
574 +       int FibStatus );
575 +
576 +int AacHba_DoScsiRead(
577 +       Scsi_Cmnd *scsi_cmnd_ptr,
578 +       int ContainerId,
579 +       int wait );
580 +
581 +int AacHba_DoScsiWrite(
582 +       Scsi_Cmnd *scsi_cmnd_ptr,
583 +       int ContainerId,
584 +       int wait );
585 +
586 +int AacHba_QueryDisk(
587 +       PVOID AdapterArg,               // CommonExtensionPtr
588 +       IN PAFA_IOCTL_CMD IoctlCmdPtr );
589 +
590 +int AacHba_ForceDeleteDisk(
591 +       PVOID AdapterArg,               // CommonExtensionPtr
592 +       IN PAFA_IOCTL_CMD IoctlCmdPtr );
593 +
594 +int AacHba_DeleteDisk(
595 +       PVOID AdapterArg,
596 +       IN PAFA_IOCTL_CMD IoctlCmdPtr );
597 +
598 +void AacHba_DetachAdapter(
599 +       IN PVOID AdapterArg );
600 +
601 +BOOLEAN AacCommDetachAdapter(
602 +       IN PAFA_COMM_ADAPTER Adapter );
603 +
604 +void AacHba_SetSenseData(
605 +       char * sense_buf,
606 +       unchar sense_key,
607 +       unchar sense_code,
608 +       unchar a_sense_code,
609 +       unchar incorrect_length,
610 +       unchar bit_pointer,
611 +       unsigned field_pointer,
612 +       unsigned long residue );
613 +
614 +static void get_sd_devname(
615 +       long disknum, 
616 +       char * buffer);
617 +
618 +// Keep these here for the time being - #REVIEW#
619 +int
620 +AfaCommAdapterDeviceControl (
621 +       IN PVOID AdapterArg,
622 +       IN PAFA_IOCTL_CMD       IoctlCmdPtr
623 +       );
624 +
625 +AAC_STATUS
626 +AfaCommRegisterNewClassDriver(
627 +       IN PAFA_COMM_ADAPTER    Adapter,
628 +       IN PAFA_NEW_CLASS_DRIVER        NewClassDriver,
629 +       OUT PAFA_NEW_CLASS_DRIVER_RESPONSE NewClassDriverResponse
630 +       );
631 +
632 +void
633 +SetInqDataStr (int, void *, int);
634 +/*------------------------------------------------------------------------------
635 + *              F U N C T I O N S
636 + *----------------------------------------------------------------------------*/
637 +
638 +/*------------------------------------------------------------------------------
639 +       AacHba_ClassDriverInit()
640 +
641 +               Setup 'core' class driver to answer ioctl's
642 + *----------------------------------------------------------------------------*/
643 +int AacHba_ClassDriverInit(
644 +       PCI_MINIPORT_COMMON_EXTENSION * CommonExtensionPtr)
645 +/*----------------------------------------------------------------------------*/
646 +{
647 +    AFA_NEW_CLASS_DRIVER                               NewClassDriver;
648 +       AFA_NEW_CLASS_DRIVER_RESPONSE           NewClassDriverResponse;
649 +       PAFA_COMM_ADAPTER                                       Adapter;
650 +
651 +       Adapter = (AFA_COMM_ADAPTER *)CommonExtensionPtr->Adapter;
652 +
653 +       RtlZeroMemory( &NewClassDriver, sizeof( AFA_NEW_CLASS_DRIVER ) );
654 +       
655 +       // ClassDriverExtension is the first argument passed to class driver functions below
656 +       NewClassDriver.ClassDriverExtension = CommonExtensionPtr;
657 +       
658 +       NewClassDriver.OpenAdapter = AacHba_OpenAdapter;
659 +       NewClassDriver.CloseAdapter = AacHba_CloseAdapter;
660 +       NewClassDriver.DeviceControl = AacHba_AdapterDeviceControl;
661 +       NewClassDriver.HandleAif = AacHba_HandleAif;
662 +       AfaCommRegisterNewClassDriver( Adapter, &NewClassDriver, &NewClassDriverResponse );
663 +
664 +       return(0);
665 +}
666 +
667 +
668 +/*------------------------------------------------------------------------------
669 +       AacHba_ProbeContainers()
670 +
671 +               Make a list of all containers in the system.
672 +------------------------------------------------------------------------------*/
673 +int AacHba_ProbeContainers (PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr)
674 +{
675 +       fsadev_t                                                *fsa_dev_ptr;
676 +       int                                                             Index, Status;
677 +       PMNTINFO                                                DiskInfo;
678 +       PMNTINFORESPONSE                                DiskInfoResponse;
679 +       PFIB_CONTEXT                                    FibContext;
680 +       AFA_COMM_ADAPTER                                *Adapter;
681 +       unsigned                                                instance;
682 +       char                            *bufp;
683 +       int                             size;
684 +
685 +
686 +       Adapter = ( AFA_COMM_ADAPTER * )CommonExtensionPtr->Adapter;
687 +       fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
688 +       instance = CommonExtensionPtr->OsDep.scsi_host_ptr->unique_id;
689 +
690 +       if( !( FibContext = Adapter->CommFuncs.AllocateFib( Adapter ) ) )
691 +       {
692 +               cmn_err( CE_WARN, "AacHba_ProbeContainers: AllocateFib failed" );
693 +               return( STATUS_UNSUCCESSFUL );
694 +       }
695 +
696 +    for ( Index = 0; Index < MAXIMUM_NUM_CONTAINERS; Index++ ) 
697 +       {
698 +               Adapter->CommFuncs.InitializeFib( FibContext );
699 +
700 +               DiskInfo = ( PMNTINFO )Adapter->CommFuncs.GetFibData( FibContext );
701 +
702 +               DiskInfo->Command  = VM_NameServe;
703 +               DiskInfo->MntCount = Index;
704 +               DiskInfo->MntType  = FT_FILESYS;
705 +               
706 +               Status =  Adapter->CommFuncs.SendFib(   ContainerCommand,
707 +                                                       FibContext,
708 +                                                       sizeof(MNTINFO),
709 +                                                       FsaNormal,
710 +                                                       TRUE,
711 +                                                       NULL,
712 +                                                       TRUE,
713 +                                                       NULL,
714 +                                                       NULL );
715 +               if ( Status ) 
716 +               {
717 +                       cmn_err( CE_WARN, "ProbeContainers: SendFIb Failed" );
718 +                       break;
719 +               }
720 +
721 +               DiskInfoResponse = ( PMNTINFORESPONSE )Adapter->CommFuncs.GetFibData( FibContext );
722 +               
723 +
724 +               if ( ( DiskInfoResponse->Status == ST_OK ) &&
725 +                       ( DiskInfoResponse->MntTable[0].VolType != CT_NONE ) ) 
726 +               {
727 +
728 +
729 +                       fsa_dev_ptr->ContainerValid[Index] = TRUE;
730 +                       fsa_dev_ptr->ContainerType[Index]  = DiskInfoResponse->MntTable[0].VolType;
731 +                       fsa_dev_ptr->ContainerSize[Index]  = DiskInfoResponse->MntTable[0].Capacity;
732 +
733 +                       if (DiskInfoResponse->MntTable[0].ContentState & FSCS_READONLY)
734 +                               fsa_dev_ptr->ContainerReadOnly[Index] = TRUE;
735 +               }
736 +               
737 +               Adapter->CommFuncs.CompleteFib( FibContext );
738 +
739 +               // If there are no more containers, then stop asking.
740 +               if ((Index + 1) >= DiskInfoResponse->MntRespCount)
741 +                       break;
742 +    } // end for()
743 +
744 +       Adapter->CommFuncs.FreeFib( FibContext );
745 +
746 +       g_fsa_dev_array[instance] = fsa_dev_ptr;
747 +       return( Status );
748 +}
749 +
750 +
751 +/*------------------------------------------------------------------------------
752 +       AacHba_ProbeContainer()
753 +
754 +               Probe a single container.
755 + *----------------------------------------------------------------------------*/
756 +int AacHba_ProbeContainer( 
757 +       PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr,
758 +       int ContainerId )
759 +/*----------------------------------------------------------------------------*/
760 +{
761 +       fsadev_t                                                *fsa_dev_ptr;
762 +    int                                                                Status;
763 +    PMNTINFO                                           DiskInfo;
764 +    PMNTINFORESPONSE                           DiskInfoResponse;
765 +       PFIB_CONTEXT                                    FibContext;
766 +       AFA_COMM_ADAPTER                                *Adapter;
767 +       unsigned                                                instance;
768 +       
769 +       Adapter = ( AFA_COMM_ADAPTER * )CommonExtensionPtr->Adapter;
770 +       fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
771 +       instance = CommonExtensionPtr->OsDep.scsi_host_ptr->unique_id;
772 +
773 +       if( !( FibContext = Adapter->CommFuncs.AllocateFib( Adapter ) ) )
774 +       {
775 +               cmn_err( CE_WARN, "AacHba_ProbeContainers: AllocateFib failed" );
776 +               return( STATUS_UNSUCCESSFUL );
777 +       }
778 +
779 +       Adapter->CommFuncs.InitializeFib( FibContext );
780 +
781 +       DiskInfo = ( PMNTINFO )Adapter->CommFuncs.GetFibData( FibContext );
782 +
783 +       DiskInfo->Command  = VM_NameServe;
784 +       DiskInfo->MntCount = ContainerId;
785 +       DiskInfo->MntType  = FT_FILESYS;
786 +               
787 +       Status =  Adapter->CommFuncs.SendFib (ContainerCommand,
788 +                                             FibContext,
789 +                                             sizeof(MNTINFO),
790 +                                             FsaNormal,
791 +                                             TRUE,
792 +                                             NULL,
793 +                                             TRUE,
794 +                                             NULL,
795 +                                             NULL );
796 +       if ( Status ) 
797 +       {
798 +               cmn_err( CE_WARN, "ProbeContainers: SendFIb Failed" );
799 +               Adapter->CommFuncs.CompleteFib( FibContext );
800 +               Adapter->CommFuncs.FreeFib( FibContext );
801 +               return( Status );
802 +       }
803 +
804 +       DiskInfoResponse = ( PMNTINFORESPONSE )Adapter->CommFuncs.GetFibData( FibContext );
805 +               
806 +
807 +       if ( ( DiskInfoResponse->Status == ST_OK ) &&
808 +               ( DiskInfoResponse->MntTable[0].VolType != CT_NONE ) ) 
809 +       {
810 +
811 +               fsa_dev_ptr->ContainerValid[ContainerId] = TRUE;
812 +               fsa_dev_ptr->ContainerType[ContainerId]  = DiskInfoResponse->MntTable[0].VolType;
813 +               fsa_dev_ptr->ContainerSize[ContainerId]  = DiskInfoResponse->MntTable[0].Capacity;
814 +               if (DiskInfoResponse->MntTable[0].ContentState & FSCS_READONLY)
815 +                       fsa_dev_ptr->ContainerReadOnly[ContainerId] = TRUE;
816 +       }
817 +               
818 +       Adapter->CommFuncs.CompleteFib( FibContext );
819 +       Adapter->CommFuncs.FreeFib( FibContext );
820 +
821 +       return( Status );
822 +}
823 +
824 +
825 +/*------------------------------------------------------------------------------
826 +       AacHba_CompleteScsi()
827 +
828 +               Call SCSI completion routine after acquiring io_request_lock
829 +
830 +       Preconditions:
831 +       Postconditions:
832 + *----------------------------------------------------------------------------*/
833 +void AacHba_CompleteScsi( 
834 +       Scsi_Cmnd *scsi_cmnd_ptr )
835 +{
836 +       unsigned long cpu_flags;
837 +
838 +       spin_lock_irqsave( &io_request_lock, cpu_flags );
839 +       scsi_cmnd_ptr->scsi_done( scsi_cmnd_ptr );
840 +       spin_unlock_irqrestore( &io_request_lock, cpu_flags );
841 +}
842 +
843 +
844 +/*------------------------------------------------------------------------------
845 +       AacHba_CompleteScsiNoLock()
846 +
847 +               Call SCSI completion routine
848 +
849 +       Preconditions:
850 +       Postconditions:
851 + *----------------------------------------------------------------------------*/
852 +void AacHba_CompleteScsiNoLock( 
853 +       Scsi_Cmnd *scsi_cmnd_ptr )
854 +{
855 +       scsi_cmnd_ptr->scsi_done( scsi_cmnd_ptr );
856 +}
857 +
858 +/*------------------------------------------------------------------------------
859 +       AacHba_DoScsiCmd()
860 +
861 +               Process SCSI command
862 +
863 +       Preconditions:
864 +       Postconditions:
865 +               Returns 0 on success, -1 on failure
866 + *----------------------------------------------------------------------------*/
867 +int AacHba_DoScsiCmd(
868 +       Scsi_Cmnd *scsi_cmnd_ptr,
869 +       int wait )
870 +{
871 +       int                     ContainerId = 0;
872 +       fsadev_t        *fsa_dev_ptr;
873 +       PCI_MINIPORT_COMMON_EXTENSION   *CommonExtensionPtr;
874 +       int MiniPortIndex;
875 +
876 +       CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
877 +       MiniPortIndex = CommonExtensionPtr->OsDep.MiniPortIndex;
878 +
879 +       fsa_dev_ptr = g_fsa_dev_array[ scsi_cmnd_ptr->host->unique_id ];
880 +
881 +       // If the bus, target or lun is out of range, return fail
882 +       // Test does not apply to ID 16, the pseudo id for the controller itself.
883 +       if ( scsi_cmnd_ptr->target != scsi_cmnd_ptr->host->this_id ) 
884 +       {
885 +               if( ( scsi_cmnd_ptr->channel > 0 ) ||
886 +                       ( scsi_cmnd_ptr->target > 15 ) || 
887 +                       ( scsi_cmnd_ptr->lun > 7 ) )
888 +               {
889 +                       cmn_err( CE_DEBUG, "The bus, target or lun is out of range = %d, %d, %d",
890 +                               scsi_cmnd_ptr->channel,
891 +                               scsi_cmnd_ptr->target, 
892 +                               scsi_cmnd_ptr->lun );
893 +                       scsi_cmnd_ptr->result = DID_BAD_TARGET << 16;
894 +
895 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
896 +
897 +                       return ( -1 );
898 +               }
899 +
900 +               ContainerId = TARGET_LUN_TO_CONTAINER( scsi_cmnd_ptr->target, scsi_cmnd_ptr->lun );
901 +
902 +
903 +               // If the target container doesn't exist, it may have been newly created
904 +               if( fsa_dev_ptr->ContainerValid[ContainerId] == 0 )
905 +               {       
906 +                       switch( scsi_cmnd_ptr->cmnd[0] )
907 +                       {
908 +                               case SS_INQUIR:
909 +                               case SS_RDCAP:
910 +                               case SS_TEST:
911 +                                       spin_unlock_irq( &io_request_lock );
912 +                                       AacHba_ProbeContainer( CommonExtensionPtr, ContainerId );               
913 +                                       spin_lock_irq( &io_request_lock );
914 +                               default:
915 +                                       break;
916 +                       }
917 +               }
918 +
919 +               // If the target container still doesn't exist, return failure
920 +               if( fsa_dev_ptr->ContainerValid[ContainerId] == 0 )
921 +               {       
922 +
923 +                       scsi_cmnd_ptr->result = DID_BAD_TARGET << 16;
924 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
925 +
926 +                       return ( -1 );
927 +               }
928 +       }
929 +       else    // the command is for the controller itself
930 +               if( ( scsi_cmnd_ptr->cmnd[0] != SS_INQUIR )     && // only INQUIRY & TUR cmnd supported for controller 
931 +                       ( scsi_cmnd_ptr->cmnd[0] != SS_TEST ) )
932 +               {
933 +                       cmn_err( CE_WARN, "Only INQUIRY & TUR command supported for controller, rcvd = 0x%x", 
934 +                               scsi_cmnd_ptr->cmnd[0] );
935 +
936 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
937 +                       
938 +                       AacHba_SetSenseData( (char *)&g_sense_data[ ContainerId ],
939 +                               SENKEY_ILLEGAL, SENCODE_INVALID_COMMAND, ASENCODE_INVALID_COMMAND, 
940 +                               0, 0, 0, 0 );
941 +
942 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
943 +
944 +                       return ( -1 );
945 +               }
946 +
947 +       // Handle commands here that don't really require going out to the adapter
948 +       switch ( scsi_cmnd_ptr->cmnd[0] ) 
949 +       {
950 +               case SS_INQUIR:
951 +               {
952 +                       struct inquiry_data *inq_data_ptr;
953 +               
954 +                       cmn_err( CE_DEBUG, "INQUIRY command, ID: %d", scsi_cmnd_ptr->target );
955 +                       inq_data_ptr = ( struct inquiry_data * )scsi_cmnd_ptr->request_buffer;
956 +                       bzero( inq_data_ptr, sizeof( struct inquiry_data ) );
957 +
958 +                       inq_data_ptr->inqd_ver = 2;             // claim compliance to SCSI-2
959 +
960 +                       inq_data_ptr->inqd_dtq = 0x80;  // set RMB bit to one indicating 
961 +                                                                                       // that the medium is removable
962 +                       inq_data_ptr->inqd_rdf = 2;             // A response data format value of
963 +                                                                                       // two indicates that the data shall 
964 +                                                                                       // be in the format specified in SCSI-2
965 +                       inq_data_ptr->inqd_len = 31;
966 +
967 +                       // Set the Vendor, Product, and Revision Level see: <vendor>.c i.e. aac.c
968 +                       SetInqDataStr(  MiniPortIndex, 
969 +                                                       (void *)(inq_data_ptr->inqd_vid),
970 +                                                       fsa_dev_ptr->ContainerType[ContainerId]);
971 +
972 +                       if ( scsi_cmnd_ptr->target == scsi_cmnd_ptr->host->this_id )
973 +                               inq_data_ptr->inqd_pdt = INQD_PDT_PROC; // Processor device
974 +                       else
975 +                               inq_data_ptr->inqd_pdt = INQD_PDT_DA;   // Direct/random access device
976 +
977 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
978 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
979 +
980 +                       return ( 0 );
981 +               }
982 +
983 +               case SS_RDCAP:
984 +               {
985 +                       int capacity;
986 +                       char *cp;
987 +
988 +                       cmn_err( CE_DEBUG, "READ CAPACITY command" );
989 +                       capacity = fsa_dev_ptr->ContainerSize[ContainerId] - 1;
990 +                       cp = scsi_cmnd_ptr->request_buffer;
991 +                       cp[0] = ( capacity >> 24 ) & 0xff;
992 +                       cp[1] = ( capacity >> 16 ) & 0xff;
993 +                       cp[2] = ( capacity >>  8 ) & 0xff;
994 +                       cp[3] = ( capacity >>  0 ) & 0xff;
995 +                       cp[4] = 0;
996 +                       cp[5] = 0;
997 +                       cp[6] = 2;
998 +                       cp[7] = 0;
999 +       
1000 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1001 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1002 +
1003 +                       return ( 0 );
1004 +               }
1005 +
1006 +               case SS_MODESEN:
1007 +               {
1008 +                       char *mode_buf;
1009 +
1010 +                       cmn_err( CE_DEBUG, "MODE SENSE command" );
1011 +                       mode_buf = scsi_cmnd_ptr->request_buffer;
1012 +                       mode_buf[0] = 0;        // Mode data length (MSB)
1013 +                       mode_buf[1] = 6;        // Mode data length (LSB)
1014 +                       mode_buf[2] = 0;        // Medium type - default
1015 +                       mode_buf[3] = 0;        // Device-specific param, bit 8: 0/1 = write enabled/protected
1016 +                       mode_buf[4] = 0;        // reserved
1017 +                       mode_buf[5] = 0;        // reserved
1018 +                       mode_buf[6] = 0;        // Block descriptor length (MSB)
1019 +                       mode_buf[7] = 0;        // Block descriptor length (LSB)
1020 +       
1021 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1022 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1023 +
1024 +                       return ( 0 );
1025 +               }
1026 +
1027 +
1028 +               // These commands are all No-Ops
1029 +               case SS_TEST:
1030 +                       cmn_err( CE_DEBUG, "TEST UNIT READY command" );
1031 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1032 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1033 +                       return ( 0 );
1034 +
1035 +               case SS_REQSEN:
1036 +                       cmn_err( CE_DEBUG, "REQUEST SENSE command" );
1037 +
1038 +                       memcpy( scsi_cmnd_ptr->sense_buffer, &g_sense_data[ContainerId],
1039 +                               sizeof( struct sense_data ) );
1040 +                       bzero( &g_sense_data[ContainerId], sizeof( struct sense_data ) );
1041 +
1042 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1043 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1044 +                       return ( 0 );
1045 +
1046 +               case SS_LOCK:
1047 +                       cmn_err(CE_DEBUG, "LOCK command");
1048 +
1049 +                       if( scsi_cmnd_ptr->cmnd[4] )
1050 +                               fsa_dev_ptr->ContainerLocked[ContainerId] = 1;
1051 +                       else
1052 +                               fsa_dev_ptr->ContainerLocked[ContainerId] = 0;
1053 +
1054 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1055 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1056 +                       return ( 0 );
1057 +
1058 +               case SS_RESERV:
1059 +                       cmn_err( CE_DEBUG, "RESERVE command" );
1060 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1061 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1062 +                       return ( 0 );
1063 +
1064 +               case SS_RELES:
1065 +                       cmn_err( CE_DEBUG, "RELEASE command" );
1066 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1067 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1068 +                       return ( 0 );
1069 +
1070 +               case SS_REZERO:
1071 +                       cmn_err( CE_DEBUG, "REZERO command" );
1072 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1073 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1074 +                       return ( 0 );
1075 +
1076 +               case SS_REASGN:
1077 +                       cmn_err( CE_DEBUG, "REASSIGN command" );
1078 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1079 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1080 +                       return ( 0 );
1081 +
1082 +               case SS_SEEK:
1083 +                       cmn_err( CE_DEBUG, "SEEK command" );
1084 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1085 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1086 +                       return ( 0 );
1087 +
1088 +               case SS_ST_SP:
1089 +                       cmn_err( CE_DEBUG, "START/STOP command" );
1090 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1091 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1092 +                       return ( 0 );
1093 +       }
1094 +
1095 +       switch ( scsi_cmnd_ptr->cmnd[0] ) 
1096 +       {
1097 +               case SS_READ:
1098 +               case SM_READ:
1099 +                       // Hack to keep track of ordinal number of the device that corresponds
1100 +                       // to a container. Needed to convert containers to /dev/sd device names
1101 +                       fsa_dev_ptr->ContainerDevNo[ContainerId] = 
1102 +                               DEVICE_NR( scsi_cmnd_ptr->request.rq_dev );
1103 +
1104 +                       return( AacHba_DoScsiRead( scsi_cmnd_ptr, ContainerId,  wait ) );
1105 +                       break;
1106 +
1107 +               case SS_WRITE:
1108 +               case SM_WRITE:
1109 +
1110 +                       return( AacHba_DoScsiWrite( scsi_cmnd_ptr, ContainerId,  wait ) );
1111 +                       break;
1112 +       }
1113 +       //
1114 +       // Unhandled commands
1115 +       //
1116 +       cmn_err( CE_WARN, "Unhandled SCSI Command: 0x%x", scsi_cmnd_ptr->cmnd[0] );
1117 +       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1118 +
1119 +       AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1120 +               SENKEY_ILLEGAL, SENCODE_INVALID_COMMAND, ASENCODE_INVALID_COMMAND, 
1121 +               0, 0, 0, 0 );
1122 +
1123 +       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1124 +       return ( -1 );
1125 +}
1126 +
1127 +
1128 +/*------------------------------------------------------------------------------
1129 +       AacHba_DoScsiRead()
1130 +               
1131 +               Handles SCSI READ requests
1132 +
1133 +       Preconditions:
1134 +       Postconditions:
1135 +               Returns 0 on success, -1 on failure
1136 + *----------------------------------------------------------------------------*/
1137 +int AacHba_DoScsiRead(
1138 +       Scsi_Cmnd *scsi_cmnd_ptr,
1139 +       int ContainerId,
1140 +       int wait )
1141 +/*----------------------------------------------------------------------------*/
1142 +{
1143 +       u_long                          lba;
1144 +       u_long                          count;
1145 +       u_long                          byte_count;
1146 +       int                                     Status;
1147 +
1148 +       PBLOCKREAD                      BlockReadDisk;
1149 +       PBLOCKREADRESPONSE      BlockReadResponse;
1150 +       uint16_t                        FibSize;
1151 +       PCI_MINIPORT_COMMON_EXTENSION   *CommonExtension;
1152 +       AFA_COMM_ADAPTER                                *Adapter;
1153 +       PFIB_CONTEXT                                    cmd_fibcontext;
1154 +
1155 +       CommonExtension = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
1156 +       Adapter         = ( AFA_COMM_ADAPTER * )CommonExtension->Adapter;
1157 +
1158 +       // Get block address and transfer length
1159 +       if ( scsi_cmnd_ptr->cmnd[0] == SS_READ ) // 6 byte command
1160 +       {
1161 +               cmn_err( CE_DEBUG, "aachba: received a read(6) command on target %d", ContainerId );
1162 +
1163 +               lba = ( ( scsi_cmnd_ptr->cmnd[1] & 0x1F ) << 16 ) | 
1164 +                       ( scsi_cmnd_ptr->cmnd[2] << 8 ) |
1165 +                       scsi_cmnd_ptr->cmnd[3];
1166 +               count = scsi_cmnd_ptr->cmnd[4];
1167 +
1168 +               if ( count == 0 )
1169 +                       count = 256;
1170 +       } 
1171 +       else 
1172 +       {               
1173 +               cmn_err( CE_DEBUG, "aachba: received a read(10) command on target %d", ContainerId );
1174 +               
1175 +               lba = ( scsi_cmnd_ptr->cmnd[2] << 24 ) | ( scsi_cmnd_ptr->cmnd[3] << 16 ) | 
1176 +                       ( scsi_cmnd_ptr->cmnd[4] << 8 ) | scsi_cmnd_ptr->cmnd[5];
1177 +
1178 +               count = ( scsi_cmnd_ptr->cmnd[7] << 8 ) | scsi_cmnd_ptr->cmnd[8];
1179 +       }       
1180 +       cmn_err( CE_DEBUG, "AacHba_DoScsiRead[cpu %d]: lba = %lu, t = %ld", smp_processor_id(), lba, jiffies );
1181 +
1182 +       //-------------------------------------------------------------------------
1183 +       // Alocate and initialize a Fib
1184 +       //  Setup BlockRead command
1185 +       if( !( cmd_fibcontext = Adapter->CommFuncs.AllocateFib( Adapter ) ) )
1186 +       {
1187 +               cmn_err( CE_WARN, "AacHba_DoScsiRead: AllocateFib failed\n" );
1188 +               scsi_cmnd_ptr->result = DID_ERROR << 16;
1189 +               AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1190 +               return ( -1 );
1191 +       }
1192 +
1193 +    Adapter->CommFuncs.InitializeFib( cmd_fibcontext );
1194 +
1195 +       BlockReadDisk = ( PBLOCKREAD )Adapter->CommFuncs.GetFibData( cmd_fibcontext );
1196 +       BlockReadDisk->Command     = VM_CtBlockRead;
1197 +       BlockReadDisk->ContainerId = ContainerId;
1198 +       BlockReadDisk->BlockNumber = lba;
1199 +       BlockReadDisk->ByteCount   = count * 512;
1200 +       BlockReadDisk->SgMap.SgCount = 1;
1201 +
1202 +       if( BlockReadDisk->ByteCount > ( 64 * 1024 ) )
1203 +       {
1204 +               cmn_err( CE_WARN, "AacHba_DoScsiRead: READ request is larger than 64K" );
1205 +               scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1206 +
1207 +               AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1208 +                               SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD, 
1209 +                               0, 0, 7, 0 );
1210 +
1211 +               goto err_return;
1212 +       }
1213 +
1214 +       //-------------------------------------------------------------------------
1215 +       // Build Scatter/Gather list
1216 +       //
1217 +       if ( scsi_cmnd_ptr->use_sg )    // use scatter/gather list
1218 +       {
1219 +               struct scatterlist *scatterlist_ptr;
1220 +               int segment;
1221 +               
1222 +               scatterlist_ptr = ( struct scatterlist * )scsi_cmnd_ptr->request_buffer;
1223 +
1224 +               byte_count = 0;
1225 +               for( segment = 0; segment< scsi_cmnd_ptr->use_sg; segment++ ) 
1226 +               {
1227 +                       BlockReadDisk->SgMap.SgEntry[segment].SgAddress = 
1228 +                               ( void * )OsVirtToPhys( scatterlist_ptr[segment].address );
1229 +                       BlockReadDisk->SgMap.SgEntry[segment].SgByteCount = 
1230 +                               scatterlist_ptr[segment].length;
1231 +
1232 +#ifdef DEBUG_SGBUFFER
1233 +                       memset( scatterlist_ptr[segment].address, 0xa5, 
1234 +                               scatterlist_ptr[segment].length );
1235 +#endif
1236 +
1237 +                       byte_count += scatterlist_ptr[segment].length;
1238 +                       
1239 +                       if( BlockReadDisk->SgMap.SgEntry[segment].SgByteCount > ( 64 * 1024 ) )
1240 +                       {
1241 +                               cmn_err( CE_WARN, "AacHba_DoScsiRead: Segment byte count is larger than 64K" );
1242 +                               scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1243 +
1244 +                               AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1245 +                                       SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD, 
1246 +                                       0, 0, 7, 0 );
1247 +
1248 +                               goto err_return;
1249 +                       }
1250 +                       /*
1251 +                       cmn_err(CE_DEBUG, "SgEntry[%d].SgAddress = 0x%x, Byte count = 0x%x", 
1252 +                                       segment,
1253 +                                       BlockReadDisk->SgMap.SgEntry[segment].SgAddress,
1254 +                                       BlockReadDisk->SgMap.SgEntry[segment].SgByteCount);
1255 +                       */
1256 +               }
1257 +               BlockReadDisk->SgMap.SgCount = scsi_cmnd_ptr->use_sg;
1258 +
1259 +               if( BlockReadDisk->SgMap.SgCount > MAX_DRIVER_SG_SEGMENT_COUNT ) 
1260 +               {
1261 +                       cmn_err( CE_WARN, "AacHba_DoScsiRead: READ request with SgCount > %d", 
1262 +                               MAX_DRIVER_SG_SEGMENT_COUNT );
1263 +                       scsi_cmnd_ptr->result = DID_ERROR << 16;
1264 +                       goto err_return;
1265 +               }
1266 +       }       
1267 +       else            // one piece of contiguous phys mem
1268 +       {
1269 +               BlockReadDisk->SgMap.SgEntry[0].SgAddress = 
1270 +                       ( void * )OsVirtToPhys( scsi_cmnd_ptr->request_buffer );
1271 +               BlockReadDisk->SgMap.SgEntry[0].SgByteCount = scsi_cmnd_ptr->request_bufflen;
1272 +
1273 +               byte_count = scsi_cmnd_ptr->request_bufflen;
1274 +
1275 +               if( BlockReadDisk->SgMap.SgEntry[0].SgByteCount > ( 64 * 1024 ) )
1276 +               {
1277 +                       cmn_err( CE_WARN, "AacHba_DoScsiRead: Single segment byte count is larger than 64K" );
1278 +                       cmn_err( CE_WARN, "AacHba_DoScsiRead: ByteCount: %d", BlockReadDisk->ByteCount);
1279 +                       cmn_err( CE_WARN, "AacHba_DoScsiRead: SG ELEMENTS: %d", scsi_cmnd_ptr->use_sg);
1280 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1281 +
1282 +                       AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1283 +                               SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD, 
1284 +                               0, 0, 7, 0 );
1285 +
1286 +                       goto err_return;
1287 +               }
1288 +       }
1289 +
1290 +       if( byte_count != BlockReadDisk->ByteCount )
1291 +               cmn_err( CE_WARN, "AacHba_DoScsiRead: byte_count != BlockReadDisk->ByteCount" );
1292 +
1293 +       //-------------------------------------------------------------------------
1294 +       // Now send the Fib to the adapter
1295 +       //
1296 +       FibSize = sizeof( BLOCKREAD ) + ( ( BlockReadDisk->SgMap.SgCount - 1 ) * sizeof( SGENTRY ) );
1297 +
1298 +       if( wait ) 
1299 +       {
1300 +               // This path shouldn't ever get executed with the current driver
1301 +               Status = Adapter->CommFuncs.SendFib( ContainerCommand,
1302 +                                                                                        cmd_fibcontext,
1303 +                                                                                        FibSize,
1304 +                                                                                        FsaNormal,
1305 +                                                                                        TRUE,
1306 +                                                                                        NULL,
1307 +                                                                                        TRUE,
1308 +                                                                                        NULL,
1309 +                                                                                        NULL);
1310 +
1311 +               BlockReadResponse = ( PBLOCKREADRESPONSE )
1312 +                       Adapter->CommFuncs.GetFibData( cmd_fibcontext );        
1313 +
1314 +               Adapter->CommFuncs.CompleteFib( cmd_fibcontext );
1315 +               Adapter->CommFuncs.FreeFib( cmd_fibcontext );
1316 +               
1317 +               if( BlockReadResponse->Status != ST_OK )
1318 +               {
1319 +                       cmn_err( CE_WARN, "AacHba_DoScsiRead: BlockReadCommand failed with status: %d", 
1320 +                               BlockReadResponse->Status );
1321 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1322 +
1323 +                       AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1324 +                               SENKEY_HW_ERR, SENCODE_INTERNAL_TARGET_FAILURE, ASENCODE_INTERNAL_TARGET_FAILURE, 
1325 +                               0, 0, 0, 0 );
1326 +
1327 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1328 +                       return ( -1 );
1329 +               }
1330 +               else
1331 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1332 +
1333 +               AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1334 +               return ( 0 );
1335 +       } 
1336 +       else 
1337 +       {
1338 +               Status = Adapter->CommFuncs.SendFib( ContainerCommand,
1339 +                                                                                        cmd_fibcontext,
1340 +                                                                                        FibSize,
1341 +                                                                                        FsaNormal,
1342 +                                                                                        FALSE,
1343 +                                                                                        NULL,
1344 +                                                                                        TRUE,
1345 +                                                                                        ( PFIB_CALLBACK )AacHba_ReadCallback,
1346 +                                                                                        ( void *)scsi_cmnd_ptr );
1347 +
1348 +               // Check that the command queued to the controller
1349 +               if (Status != STATUS_PENDING) { 
1350 +                       cmn_err( CE_WARN, "AacHba_DoScsiRead: SendFib failed with status: %d\n", 
1351 +                                       Status);
1352 +
1353 +                       // For some reason, the Fib didn't queue, return QUEUE_FULL
1354 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | QUEUE_FULL ;
1355 +                       goto err_return;
1356 +               }
1357 +
1358 +               // don't call done func here
1359 +               return ( 0 );
1360 +       }
1361 +
1362 +err_return:
1363 +       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1364 +
1365 +       Adapter->CommFuncs.CompleteFib( cmd_fibcontext );
1366 +       Adapter->CommFuncs.FreeFib( cmd_fibcontext );
1367 +
1368 +       return ( -1 );
1369 +}
1370 +
1371 +
1372 +/*------------------------------------------------------------------------------
1373 +       AacHba_DoScsiWrite()
1374 +
1375 +               Handles SCSI WRITE requests
1376 +       
1377 +       Preconditions:
1378 +       Postconditions:
1379 +               Returns 0 on success, -1 on failure
1380 + *----------------------------------------------------------------------------*/
1381 +int AacHba_DoScsiWrite(
1382 +       Scsi_Cmnd *scsi_cmnd_ptr,
1383 +       int ContainerId,
1384 +       int wait )
1385 +/*----------------------------------------------------------------------------*/
1386 +{
1387 +       u_long                          lba;
1388 +       u_long                          count;
1389 +       u_long                          byte_count;
1390 +       int                                     Status;
1391 +
1392 +       PBLOCKWRITE                                             BlockWriteDisk;
1393 +       PBLOCKWRITERESPONSE                             BlockWriteResponse;
1394 +       uint16_t                                                FibSize;
1395 +       PCI_MINIPORT_COMMON_EXTENSION   *CommonExtension;
1396 +       AFA_COMM_ADAPTER                                *Adapter;
1397 +       PFIB_CONTEXT                                    cmd_fibcontext;
1398 +
1399 +       CommonExtension = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
1400 +       Adapter         = ( AFA_COMM_ADAPTER * )CommonExtension->Adapter;
1401 +
1402 +       // Get block address and transfer length
1403 +       if ( scsi_cmnd_ptr->cmnd[0] == SS_WRITE ) // 6 byte command
1404 +       {
1405 +               lba = ( ( scsi_cmnd_ptr->cmnd[1] & 0x1F ) << 16 ) | 
1406 +                       ( scsi_cmnd_ptr->cmnd[2] << 8 ) |
1407 +                       scsi_cmnd_ptr->cmnd[3];
1408 +               count = scsi_cmnd_ptr->cmnd[4];
1409 +
1410 +               if ( count == 0 )
1411 +                       count = 256;
1412 +       } 
1413 +       else 
1414 +       {               
1415 +               cmn_err( CE_DEBUG, "aachba: received a write(10) command on target %d", ContainerId );
1416 +               
1417 +               lba = ( scsi_cmnd_ptr->cmnd[2] << 24 ) | ( scsi_cmnd_ptr->cmnd[3] << 16 ) | 
1418 +                       ( scsi_cmnd_ptr->cmnd[4] << 8 ) | scsi_cmnd_ptr->cmnd[5];
1419 +
1420 +               count = ( scsi_cmnd_ptr->cmnd[7] << 8 ) | scsi_cmnd_ptr->cmnd[8];
1421 +
1422 +       }       
1423 +       cmn_err( CE_DEBUG, "AacHba_DoScsiWrite[cpu %d]: lba = %lu, t = %ld", smp_processor_id(), lba, jiffies );
1424 +
1425 +       //-------------------------------------------------------------------------
1426 +       // Alocate and initialize a Fib
1427 +       //  Setup BlockWrite command
1428 +       if( !( cmd_fibcontext = Adapter->CommFuncs.AllocateFib( Adapter ) ) ) 
1429 +       {
1430 +               cmn_err( CE_WARN, "AacHba_DoScsiWrite: AllocateFib failed\n" );
1431 +               scsi_cmnd_ptr->result = DID_ERROR << 16;
1432 +               AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1433 +               return ( -1 );
1434 +       }
1435 +
1436 +    Adapter->CommFuncs.InitializeFib( cmd_fibcontext );
1437 +
1438 +       BlockWriteDisk = (PBLOCKWRITE) Adapter->CommFuncs.GetFibData( cmd_fibcontext );
1439 +       BlockWriteDisk->Command     = VM_CtBlockWrite;
1440 +       BlockWriteDisk->ContainerId = ContainerId;
1441 +       BlockWriteDisk->BlockNumber = lba;
1442 +       BlockWriteDisk->ByteCount   = count * 512;
1443 +       BlockWriteDisk->SgMap.SgCount = 1;
1444 +
1445 +
1446 +       if ( BlockWriteDisk->ByteCount > ( 64 * 1024 ) )
1447 +         {
1448 +                 struct scatterlist *scatterlist_ptr;
1449 +                 int segment;
1450 +                 scatterlist_ptr = (struct scatterlist *)scsi_cmnd_ptr->request_buffer;
1451 +
1452 +                 cmn_err( CE_WARN, "\n");
1453 +                 cmn_err( CE_WARN, "AacHba_DoScsiWrite: WRITE request is larger than 64K");
1454 +                 cmn_err( CE_WARN, "AacHba_DoScsiWrite: ByteCount: %d", BlockWriteDisk->ByteCount);
1455 +/*               cmn_err( CE_WARN, "AacHba_DoScsiWrite: SG ELEMENTS: %d", scsi_cmnd_ptr->use_sg); */
1456 +/*               cmn_err( CE_WARN, "Dump SG Element Size..."); */
1457 +/*               for( segment = 0; segment < scsi_cmnd_ptr->use_sg; segment++ )  */
1458 +/*               { */
1459 +/*                       cmn_err (CE_WARN, "SG Segment %d: %d", segment, scatterlist_ptr[segment].length); */
1460 +/*               } */
1461 +/*               cmn_err (CE_WARN, "\n"); */
1462 +
1463 +               scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1464 +
1465 +               AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1466 +                               SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD, 
1467 +                               0, 0, 7, 0 );
1468 +
1469 +               goto err_return;
1470 +       }
1471 +
1472 +       //-------------------------------------------------------------------------
1473 +       // Build Scatter/Gather list
1474 +       //
1475 +       if ( scsi_cmnd_ptr->use_sg )    // use scatter/gather list
1476 +       {
1477 +               struct scatterlist *scatterlist_ptr;
1478 +               int segment;
1479 +               
1480 +               scatterlist_ptr = ( struct scatterlist * )scsi_cmnd_ptr->request_buffer;
1481 +
1482 +               byte_count = 0;
1483 +               for( segment = 0; segment< scsi_cmnd_ptr->use_sg; segment++ ) 
1484 +               {
1485 +                       BlockWriteDisk->SgMap.SgEntry[segment].SgAddress = 
1486 +                               ( HOSTADDRESS )OsVirtToPhys( scatterlist_ptr[segment].address );
1487 +                       BlockWriteDisk->SgMap.SgEntry[segment].SgByteCount = 
1488 +                               scatterlist_ptr[segment].length;
1489 +                       
1490 +                       byte_count += scatterlist_ptr[segment].length;
1491 +
1492 +                       if ( BlockWriteDisk->SgMap.SgEntry[segment].SgByteCount > ( 64 * 1024 ) )
1493 +                       {
1494 +                               cmn_err( CE_WARN, "AacHba_DoScsiWrite: Segment byte count is larger than 64K" );
1495 +                               scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1496 +
1497 +                               AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1498 +                                       SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD, 
1499 +                                       0, 0, 7, 0 );
1500 +
1501 +                               goto err_return;
1502 +                       }
1503 +
1504 +                       /*
1505 +                       cmn_err(CE_DEBUG, "SgEntry[%d].SgAddress = 0x%x, Byte count = 0x%x", 
1506 +                                       segment,
1507 +                                       BlockWriteDisk->SgMap.SgEntry[segment].SgAddress,
1508 +                                       BlockWriteDisk->SgMap.SgEntry[segment].SgByteCount); 
1509 +                       */
1510 +               }
1511 +               BlockWriteDisk->SgMap.SgCount = scsi_cmnd_ptr->use_sg;
1512 +
1513 +               if( BlockWriteDisk->SgMap.SgCount > MAX_DRIVER_SG_SEGMENT_COUNT ) 
1514 +               {
1515 +                       cmn_err( CE_WARN, "AacHba_DoScsiWrite: WRITE request with SgCount > %d", 
1516 +                               MAX_DRIVER_SG_SEGMENT_COUNT );
1517 +                       scsi_cmnd_ptr->result = DID_ERROR << 16;
1518 +                       goto err_return;
1519 +               }
1520 +       } 
1521 +       else            // one piece of contiguous phys mem
1522 +       {
1523 +               BlockWriteDisk->SgMap.SgEntry[0].SgAddress = 
1524 +                       ( HOSTADDRESS )OsVirtToPhys( scsi_cmnd_ptr->request_buffer );
1525 +               BlockWriteDisk->SgMap.SgEntry[0].SgByteCount = scsi_cmnd_ptr->request_bufflen;
1526 +
1527 +               byte_count = scsi_cmnd_ptr->request_bufflen;
1528 +
1529 +               if ( BlockWriteDisk->SgMap.SgEntry[0].SgByteCount > ( 64 * 1024 ) )
1530 +               {
1531 +                       cmn_err( CE_WARN, "AacHba_DoScsiWrite: Single segment byte count is larger than 64K" );
1532 +
1533 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1534 +                       AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1535 +                               SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD, 
1536 +                               0, 0, 7, 0 );
1537 +
1538 +                       goto err_return;
1539 +               }
1540 +       }
1541 +
1542 +       if( byte_count != BlockWriteDisk->ByteCount )
1543 +         cmn_err( CE_WARN, "AacHba_DoScsiWrite: byte_count != BlockReadDisk->ByteCount" );
1544 +
1545 +       //-------------------------------------------------------------------------
1546 +       // Now send the Fib to the adapter
1547 +       //
1548 +       FibSize = sizeof( BLOCKWRITE ) + ( ( BlockWriteDisk->SgMap.SgCount - 1 ) * sizeof( SGENTRY ) );
1549 +
1550 +       if( wait ) 
1551 +       {
1552 +               // This path shouldn't ever get executed with the current driver
1553 +               Status = Adapter->CommFuncs.SendFib( ContainerCommand,
1554 +                                                                                        cmd_fibcontext,
1555 +                                                                                        FibSize,
1556 +                                                                                        FsaNormal,
1557 +                                                                                        TRUE,
1558 +                                                                                        NULL,
1559 +                                                                                        TRUE,
1560 +                                                                                        NULL,
1561 +                                                                                        NULL );
1562 +
1563 +               BlockWriteResponse = ( PBLOCKWRITERESPONSE ) 
1564 +                       Adapter->CommFuncs.GetFibData( cmd_fibcontext );        
1565 +
1566 +               Adapter->CommFuncs.CompleteFib(  cmd_fibcontext );
1567 +               Adapter->CommFuncs.FreeFib(  cmd_fibcontext );
1568 +
1569 +               if( BlockWriteResponse->Status != ST_OK )
1570 +               {
1571 +                       cmn_err( CE_WARN, "AacHba_DoScsiWrite: BlockWriteCommand failed with status: %d\n", 
1572 +                               BlockWriteResponse->Status );
1573 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;;
1574 +                       AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1575 +                               SENKEY_HW_ERR, SENCODE_INTERNAL_TARGET_FAILURE, ASENCODE_INTERNAL_TARGET_FAILURE, 
1576 +                               0, 0, 0, 0 );
1577 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1578 +                       return ( -1 );
1579 +               }
1580 +               else
1581 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1582 +
1583 +               AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1584 +               return ( 0 );
1585 +       } 
1586 +       else 
1587 +       {
1588 +               Status = Adapter->CommFuncs.SendFib( ContainerCommand,
1589 +                                                                                        cmd_fibcontext,
1590 +                                                                                        FibSize,
1591 +                                                                                        FsaNormal,
1592 +                                                                                        FALSE,
1593 +                                                                                        NULL,
1594 +                                                                                        TRUE,
1595 +                                                                                        ( PFIB_CALLBACK )AacHba_WriteCallback,
1596 +                                                                                        ( void * )scsi_cmnd_ptr );
1597 +
1598 +               // Check that the command queued to the controller
1599 +               if (Status != STATUS_PENDING) { 
1600 +                       cmn_err( CE_WARN, "AacHba_DoScsiWrite: SendFib failed with status: %d\n", 
1601 +                                       Status);
1602 +
1603 +                       // For some reason, the Fib didn't queue, return QUEUE_FULL
1604 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | QUEUE_FULL ;
1605 +                       goto err_return;
1606 +               }
1607 +
1608 +               // don't call done func here - it should be called by the WriteCallback
1609 +               return ( 0 );
1610 +       }
1611 +
1612 +err_return:
1613 +       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1614 +
1615 +       Adapter->CommFuncs.CompleteFib( cmd_fibcontext );
1616 +       Adapter->CommFuncs.FreeFib( cmd_fibcontext );
1617 +
1618 +       return ( -1 );
1619 +}
1620 +
1621 +
1622 +/*------------------------------------------------------------------------------
1623 +       AacHba_ReadCallback()
1624 + *----------------------------------------------------------------------------*/
1625 +void AacHba_ReadCallback(  
1626 +       VOID                    *Context,
1627 +       PFIB_CONTEXT    FibContext,
1628 +       int                             FibStatus )
1629 +/*----------------------------------------------------------------------------*/
1630 +{
1631 +       PCI_MINIPORT_COMMON_EXTENSION   *CommonExtension;
1632 +       AFA_COMM_ADAPTER                                *Adapter;
1633 +       BLOCKREADRESPONSE                               *BlockReadResponse;
1634 +       Scsi_Cmnd * scsi_cmnd_ptr;
1635 +       u_long                                                  lba;
1636 +       int                     ContainerId;
1637 +
1638 +       scsi_cmnd_ptr = ( Scsi_Cmnd * )Context;
1639 +
1640 +       CommonExtension = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
1641 +       Adapter         = ( AFA_COMM_ADAPTER * )CommonExtension->Adapter;
1642 +
1643 +       ContainerId = TARGET_LUN_TO_CONTAINER( scsi_cmnd_ptr->target, scsi_cmnd_ptr->lun );
1644 +       
1645 +       lba = ( ( scsi_cmnd_ptr->cmnd[1] & 0x1F ) << 16 ) | 
1646 +                       ( scsi_cmnd_ptr->cmnd[2] << 8 ) |
1647 +                       scsi_cmnd_ptr->cmnd[3];
1648 +       cmn_err( CE_DEBUG, "AacHba_ReadCallback[cpu %d]: lba = %ld, t = %ld", smp_processor_id(), lba, jiffies );
1649 +
1650 +       if( FibContext == 0 ) 
1651 +       {
1652 +               cmn_err( CE_WARN, "AacHba_ReadCallback: no fib context" );
1653 +               scsi_cmnd_ptr->result = DID_ERROR << 16;
1654 +               AacHba_CompleteScsi( scsi_cmnd_ptr );
1655 +               return;
1656 +       }
1657 +
1658 +    BlockReadResponse = ( PBLOCKREADRESPONSE )Adapter->CommFuncs.GetFibData( FibContext );
1659 +
1660 +       if ( BlockReadResponse->Status == ST_OK ) 
1661 +               scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1662 +       else 
1663 +       {
1664 +               cmn_err( CE_WARN, "AacHba_ReadCallback: read failed, status = %d\n", 
1665 +                       BlockReadResponse->Status );
1666 +               scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1667 +               AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1668 +                       SENKEY_HW_ERR, SENCODE_INTERNAL_TARGET_FAILURE, ASENCODE_INTERNAL_TARGET_FAILURE, 
1669 +                       0, 0, 0, 0 );
1670 +       }
1671 +
1672 +#ifdef DEBUG_SGBUFFER
1673 +       if ( scsi_cmnd_ptr->use_sg )    // use scatter/gather list
1674 +       {
1675 +               struct scatterlist *scatterlist_ptr;
1676 +               int i, segment, count;
1677 +               char *ptr;
1678 +               
1679 +               scatterlist_ptr = ( struct scatterlist * )scsi_cmnd_ptr->request_buffer;
1680 +
1681 +               for( segment = 0; segment < scsi_cmnd_ptr->use_sg; segment++ ) 
1682 +               {
1683 +                       count = 0;
1684 +                       ptr = scatterlist_ptr[segment].address;
1685 +                       for( i = 0; i < scatterlist_ptr[segment].length; i++ )
1686 +                       {
1687 +                               if( *( ptr++ ) == 0xa5 )
1688 +                                       count++;
1689 +                       }
1690 +                       if( count == scatterlist_ptr[segment].length )
1691 +                               cmn_err( CE_WARN, "AacHba_ReadCallback: segment %d not filled", segment );
1692 +
1693 +               }
1694 +       }
1695 +#endif
1696 +
1697 +       Adapter->CommFuncs.CompleteFib( FibContext );
1698 +       Adapter->CommFuncs.FreeFib( FibContext );
1699 +
1700 +       AacHba_CompleteScsi( scsi_cmnd_ptr );
1701 +}
1702 +
1703 +/*------------------------------------------------------------------------------
1704 +       AacHba_WriteCallback()
1705 + *----------------------------------------------------------------------------*/
1706 +void AacHba_WriteCallback(  
1707 +       VOID                    *Context,
1708 +       PFIB_CONTEXT    FibContext,
1709 +       int                             FibStatus )
1710 +/*----------------------------------------------------------------------------*/
1711 +{
1712 +       PCI_MINIPORT_COMMON_EXTENSION   *CommonExtension;
1713 +       AFA_COMM_ADAPTER                                *Adapter;
1714 +       BLOCKWRITERESPONSE                              *BlockWriteResponse;
1715 +       Scsi_Cmnd                                               *scsi_cmnd_ptr;
1716 +       u_long                                                  lba;
1717 +       int                     ContainerId;
1718 +
1719 +       scsi_cmnd_ptr = ( Scsi_Cmnd * )Context;
1720 +
1721 +       CommonExtension = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
1722 +       Adapter         = ( AFA_COMM_ADAPTER * )CommonExtension->Adapter;
1723 +       
1724 +       ContainerId = TARGET_LUN_TO_CONTAINER( scsi_cmnd_ptr->target, scsi_cmnd_ptr->lun );
1725 +
1726 +       lba = ( ( scsi_cmnd_ptr->cmnd[1] & 0x1F ) << 16 ) | 
1727 +                       ( scsi_cmnd_ptr->cmnd[2] << 8 ) |
1728 +                       scsi_cmnd_ptr->cmnd[3];
1729 +       cmn_err( CE_DEBUG, "AacHba_WriteCallback[cpu %d]: lba = %ld, t = %ld", smp_processor_id(), lba, jiffies );
1730 +       if( FibContext == 0 ) 
1731 +       {
1732 +               cmn_err( CE_WARN, "AacHba_WriteCallback: no fib context" );
1733 +               scsi_cmnd_ptr->result = DID_ERROR << 16;
1734 +               AacHba_CompleteScsi( scsi_cmnd_ptr );
1735 +               return;
1736 +       }
1737 +
1738 +    BlockWriteResponse = (PBLOCKWRITERESPONSE) Adapter->CommFuncs.GetFibData( FibContext );
1739 +       if (BlockWriteResponse->Status == ST_OK) 
1740 +               scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1741 +       else 
1742 +       {
1743 +               cmn_err( CE_WARN, "AacHba_WriteCallback: write failed, status = %d\n", 
1744 +                       BlockWriteResponse->Status );
1745 +               scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1746 +               AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1747 +                       SENKEY_HW_ERR, SENCODE_INTERNAL_TARGET_FAILURE, ASENCODE_INTERNAL_TARGET_FAILURE, 
1748 +                       0, 0, 0, 0 );
1749 +       }
1750 +
1751 +       Adapter->CommFuncs.CompleteFib( FibContext );
1752 +       Adapter->CommFuncs.FreeFib( FibContext );
1753 +
1754 +       AacHba_CompleteScsi( scsi_cmnd_ptr );
1755 +}
1756 +
1757 +
1758 +/*------------------------------------------------------------------------------
1759 +       AacHba_Ioctl()
1760 +
1761 +               Handle IOCTL requests
1762 +
1763 +       Preconditions:
1764 +       Postconditions:
1765 + *----------------------------------------------------------------------------*/
1766 +int AacHba_Ioctl(
1767 +       PCI_MINIPORT_COMMON_EXTENSION *CommonExtension,
1768 +       int cmd,
1769 +       void * arg )
1770 +/*----------------------------------------------------------------------------*/
1771 +{
1772 +       Sa_ADAPTER_EXTENSION              *AdapterExtension;
1773 +       AFA_IOCTL_CMD IoctlCmd;
1774 +       int status;
1775 +       
1776 +       AdapterExtension = ( Sa_ADAPTER_EXTENSION * )CommonExtension->MiniPort;
1777 +
1778 +       cmn_err( CE_DEBUG, "AacHba_Ioctl, type = %d", cmd );
1779 +       switch( cmd )
1780 +       {
1781 +         case FSACTL_SENDFIB:
1782 +                 cmn_err( CE_DEBUG, "FSACTL_SENDFIB" );
1783 +               break;
1784 +
1785 +         case FSACTL_AIF_THREAD:
1786 +                 cmn_err( CE_DEBUG, "FSACTL_AIF_THREAD" );
1787 +               break;
1788 +
1789 +         case FSACTL_NULL_IO_TEST:
1790 +                 cmn_err( CE_DEBUG, "FSACTL_NULL_IO_TEST" );
1791 +               break;
1792 +
1793 +         case FSACTL_SIM_IO_TEST:
1794 +                 cmn_err( CE_DEBUG, "FSACTL_SIM_IO_TEST" );
1795 +               break;
1796 +
1797 +         case FSACTL_GET_FIBTIMES:
1798 +                 cmn_err( CE_DEBUG, "FSACTL_GET_FIBTIMES" );
1799 +               break;
1800 +
1801 +         case FSACTL_ZERO_FIBTIMES:
1802 +                 cmn_err( CE_DEBUG, "FSACTL_ZERO_FIBTIMES");
1803 +               break;
1804 +
1805 +         case FSACTL_GET_VAR:
1806 +                 cmn_err( CE_DEBUG, "FSACTL_GET_VAR" );
1807 +               break;
1808 +
1809 +         case FSACTL_SET_VAR:
1810 +                 cmn_err( CE_DEBUG, "FSACTL_SET_VAR" );
1811 +               break;
1812 +
1813 +         case FSACTL_OPEN_ADAPTER_CONFIG:
1814 +                 cmn_err( CE_DEBUG, "FSACTL_OPEN_ADAPTER_CONFIG" );
1815 +               break;  
1816 +
1817 +         case FSACTL_CLOSE_ADAPTER_CONFIG:
1818 +                 cmn_err( CE_DEBUG, "FSACTL_CLOSE_ADAPTER_CONFIG" );
1819 +               break;
1820 +
1821 +         case FSACTL_QUERY_ADAPTER_CONFIG:
1822 +                 cmn_err( CE_DEBUG, "FSACTL_QUERY_ADAPTER_CONFIG" );
1823 +               break;
1824 +
1825 +         case FSACTL_OPEN_GET_ADAPTER_FIB:
1826 +                 cmn_err( CE_DEBUG, "FSACTL_OPEN_GET_ADAPTER_FIB" );
1827 +               break;
1828 +
1829 +         case FSACTL_GET_NEXT_ADAPTER_FIB:
1830 +                 cmn_err( CE_DEBUG, "FSACTL_GET_NEXT_ADAPTER_FIB" );
1831 +               break;
1832 +
1833 +         case FSACTL_CLOSE_GET_ADAPTER_FIB:
1834 +                 cmn_err( CE_DEBUG, "FSACTL_CLOSE_GET_ADAPTER_FIB" );
1835 +               break;
1836 +
1837 +         case FSACTL_MINIPORT_REV_CHECK:
1838 +                 cmn_err( CE_DEBUG, "FSACTL_MINIPORT_REV_CHECK" );
1839 +               break;
1840 +
1841 +         case FSACTL_OPENCLS_COMM_PERF_DATA:
1842 +                 cmn_err( CE_DEBUG, "FSACTL_OPENCLS_COMM_PERF_DATA" );
1843 +               break;
1844 +       
1845 +         case FSACTL_GET_COMM_PERF_DATA:
1846 +                 cmn_err( CE_DEBUG, "FSACTL_GET_COMM_PERF_DATA" );
1847 +               break;
1848 +
1849 +         case FSACTL_QUERY_DISK:
1850 +                 cmn_err( CE_DEBUG, "FSACTL_QUERY_DISK" );
1851 +               break;
1852 +               
1853 +         case FSACTL_DELETE_DISK:
1854 +                 cmn_err( CE_DEBUG, "FSACTL_DELETE_DISK" );
1855 +               break;
1856 +
1857 +         default:
1858 +                 cmn_err( CE_DEBUG, "Unknown ioctl: 0x%x", cmd );
1859 +       }
1860 +
1861 +       IoctlCmd.cmd = cmd;
1862 +       IoctlCmd.arg = ( intptr_t )arg;
1863 +       IoctlCmd.flag = 0;
1864 +       IoctlCmd.cred_p = 0;
1865 +       IoctlCmd.rval_p = 0;
1866 +
1867 +       status = AfaCommAdapterDeviceControl( CommonExtension->Adapter, &IoctlCmd );
1868 +       cmn_err( CE_DEBUG, "AAC_Ioctl, completion status = %d", status );
1869 +       return( status );
1870 +}
1871 +
1872 +
1873 +/*------------------------------------------------------------------------------
1874 +       AacHba_AdapterDeviceControl()
1875 +
1876 +       Preconditions:
1877 +       Postconditions:
1878 +               Returns TRUE if ioctl handled, FALSE otherwise
1879 +               *ReturnStatus set to completion status
1880 + *----------------------------------------------------------------------------*/
1881 +BOOLEAN AacHba_AdapterDeviceControl (
1882 +       PVOID AdapterArg,               // CommonExtensionPtr
1883 +       IN PAFA_IOCTL_CMD IoctlCmdPtr,
1884 +       OUT int * ReturnStatus )
1885 +/*----------------------------------------------------------------------------*/
1886 +{
1887 +       BOOLEAN Handled = TRUE; // start out handling it.
1888 +       int Status = EFAULT;
1889 +
1890 +       switch( IoctlCmdPtr->cmd )
1891 +       {
1892 +               case FSACTL_QUERY_DISK:
1893 +                       Status = AacHba_QueryDisk( AdapterArg, IoctlCmdPtr );
1894 +                       break;
1895 +
1896 +               case FSACTL_DELETE_DISK:
1897 +                       Status = AacHba_DeleteDisk( AdapterArg, IoctlCmdPtr );
1898 +                       break;
1899 +
1900 +               case FSACTL_FORCE_DELETE_DISK:
1901 +                       Status = AacHba_ForceDeleteDisk( AdapterArg, IoctlCmdPtr );
1902 +                       break;
1903 +
1904 +               case 2131:
1905 +                       if( AacHba_ProbeContainers( ( PCI_MINIPORT_COMMON_EXTENSION * )AdapterArg ) )
1906 +                               Status = -EFAULT;
1907 +                       break;
1908 +
1909 +               default:
1910 +                       Handled = FALSE;
1911 +                       break;
1912 +       }
1913 +
1914 +       *ReturnStatus = Status;
1915 +
1916 +       return( Handled );
1917 +}
1918 +
1919 +
1920 +/*------------------------------------------------------------------------------
1921 +       AacHba_QueryDisk()
1922 +
1923 +       Postconditions:
1924 +               Return values
1925 +               0       = OK
1926 +               -EFAULT = Bad address
1927 +               -EINVAL = Bad container number
1928 + *----------------------------------------------------------------------------*/
1929 +int AacHba_QueryDisk(
1930 +       PVOID AdapterArg,               // CommonExtensionPtr
1931 +       IN PAFA_IOCTL_CMD IoctlCmdPtr )
1932 +/*----------------------------------------------------------------------------*/
1933 +{
1934 +       UNIX_QUERY_DISK QueryDisk;
1935 +       PCI_MINIPORT_COMMON_EXTENSION   *CommonExtensionPtr;
1936 +       fsadev_t                                                *fsa_dev_ptr;
1937 +
1938 +       CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )AdapterArg;
1939 +       fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
1940 +
1941 +       if( copyin( IoctlCmdPtr->arg, &QueryDisk, sizeof( UNIX_QUERY_DISK ) ) )
1942 +               return( -EFAULT );
1943 +
1944 +       if (QueryDisk.ContainerNumber == -1)
1945 +               QueryDisk.ContainerNumber = TARGET_LUN_TO_CONTAINER( QueryDisk.Target, QueryDisk.Lun );
1946 +       else 
1947 +               if( ( QueryDisk.Bus == -1 ) && ( QueryDisk.Target == -1 ) && ( QueryDisk.Lun == -1 ) )
1948 +               {
1949 +                       if( QueryDisk.ContainerNumber > MAXIMUM_NUM_CONTAINERS )
1950 +                               return( -EINVAL );
1951 +
1952 +                       QueryDisk.Instance = CommonExtensionPtr->OsDep.scsi_host_ptr->host_no;
1953 +                       QueryDisk.Bus = 0;
1954 +                       QueryDisk.Target = CONTAINER_TO_TARGET( QueryDisk.ContainerNumber );
1955 +                       QueryDisk.Lun = CONTAINER_TO_LUN( QueryDisk.ContainerNumber );
1956 +               }
1957 +               else 
1958 +                       return( -EINVAL );
1959 +
1960 +       QueryDisk.Valid = fsa_dev_ptr->ContainerValid[QueryDisk.ContainerNumber];
1961 +       QueryDisk.Locked = fsa_dev_ptr->ContainerLocked[QueryDisk.ContainerNumber];
1962 +       QueryDisk.Deleted = fsa_dev_ptr->ContainerDeleted[QueryDisk.ContainerNumber];
1963 +
1964 +       if( fsa_dev_ptr->ContainerDevNo[QueryDisk.ContainerNumber] == -1 )
1965 +               QueryDisk.UnMapped = TRUE;
1966 +       else
1967 +               QueryDisk.UnMapped = FALSE;
1968 +
1969 +       get_sd_devname( fsa_dev_ptr->ContainerDevNo[QueryDisk.ContainerNumber], 
1970 +               QueryDisk.diskDeviceName );
1971 +
1972 +       if( copyout( &QueryDisk, IoctlCmdPtr->arg, sizeof( UNIX_QUERY_DISK ) ) )
1973 +               return( -EFAULT );
1974 +
1975 +       return( 0 );
1976 +}
1977 +
1978 +
1979 +/*------------------------------------------------------------------------------
1980 +       get_sd_devname()
1981 + *----------------------------------------------------------------------------*/
1982 +static void get_sd_devname(
1983 +       long disknum, 
1984 +       char * buffer)
1985 +/*----------------------------------------------------------------------------*/
1986 +{
1987 +       if( disknum < 0 )
1988 +       {
1989 +        sprintf(buffer, "%s", "");
1990 +               return;
1991 +       }
1992 +
1993 +   if( disknum < 26 )
1994 +        sprintf(buffer, "sd%c", 'a' + disknum);
1995 +    else {
1996 +        unsigned int min1;
1997 +        unsigned int min2;
1998 +        /*
1999 +         * For larger numbers of disks, we need to go to a new
2000 +         * naming scheme.
2001 +         */
2002 +        min1 = disknum / 26;
2003 +        min2 = disknum % 26;
2004 +        sprintf(buffer, "sd%c%c", 'a' + min1 - 1, 'a' + min2);
2005 +    }
2006 +}
2007 +
2008 +
2009 +/*------------------------------------------------------------------------------
2010 +       AacHba_ForceDeleteDisk()
2011 +
2012 +       Postconditions:
2013 +               Return values
2014 +               0       = OK
2015 +               -EFAULT = Bad address
2016 +               -EINVAL = Bad container number
2017 + *----------------------------------------------------------------------------*/
2018 +int AacHba_ForceDeleteDisk(
2019 +       PVOID AdapterArg,               // CommonExtensionPtr
2020 +       IN PAFA_IOCTL_CMD IoctlCmdPtr )
2021 +/*----------------------------------------------------------------------------*/
2022 +{
2023 +       DELETE_DISK      DeleteDisk;
2024 +       PCI_MINIPORT_COMMON_EXTENSION   *CommonExtensionPtr;
2025 +       fsadev_t                                                *fsa_dev_ptr;
2026 +
2027 +       CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )AdapterArg;
2028 +       fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
2029 +
2030 +       if ( copyin( IoctlCmdPtr->arg,  &DeleteDisk, sizeof( DELETE_DISK ) ) )
2031 +               return( -EFAULT );
2032 +
2033 +       if ( DeleteDisk.ContainerNumber > MAXIMUM_NUM_CONTAINERS ) 
2034 +               return( -EINVAL );
2035 +       
2036 +       // Mark this container as being deleted.
2037 +       fsa_dev_ptr->ContainerDeleted[DeleteDisk.ContainerNumber] = TRUE;
2038 +
2039 +       // Mark the container as no longer valid
2040 +       fsa_dev_ptr->ContainerValid[DeleteDisk.ContainerNumber] = 0;
2041 +
2042 +       return( 0 );
2043 +}
2044 +
2045 +
2046 +/*------------------------------------------------------------------------------
2047 +       AacHba_DeleteDisk()
2048 +
2049 +       Postconditions:
2050 +               Return values
2051 +               0       = OK
2052 +               -EFAULT = Bad address
2053 +               -EINVAL = Bad container number
2054 +               -EBUSY  = Device locked
2055 + *----------------------------------------------------------------------------*/
2056 +int AacHba_DeleteDisk(
2057 +       PVOID AdapterArg,
2058 +       IN PAFA_IOCTL_CMD IoctlCmdPtr )
2059 +/*----------------------------------------------------------------------------*/
2060 +{
2061 +       DELETE_DISK DeleteDisk;
2062 +       PCI_MINIPORT_COMMON_EXTENSION   *CommonExtensionPtr;
2063 +       fsadev_t                                                *fsa_dev_ptr;
2064 +
2065 +       CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )AdapterArg;
2066 +       fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
2067 +
2068 +       if( copyin( IoctlCmdPtr->arg, &DeleteDisk, sizeof( DELETE_DISK ) ) ) 
2069 +               return( -EFAULT );
2070 +
2071 +       if( DeleteDisk.ContainerNumber > MAXIMUM_NUM_CONTAINERS )
2072 +               return( -EINVAL );
2073 +       
2074 +       // If the container is locked, it can not be deleted by the API.
2075 +       if( fsa_dev_ptr->ContainerLocked[DeleteDisk.ContainerNumber] )
2076 +               return( -EBUSY );
2077 +       else 
2078 +       {       
2079 +               // Mark the container as no longer being valid.
2080 +               fsa_dev_ptr->ContainerValid[DeleteDisk.ContainerNumber] = 0;
2081 +               fsa_dev_ptr->ContainerDevNo[DeleteDisk.ContainerNumber] = -1;
2082 +               return(0);
2083 +       }       
2084 +}
2085 +
2086 +
2087 +/*------------------------------------------------------------------------------
2088 +       AacHba_OpenAdapter()
2089 + *----------------------------------------------------------------------------*/
2090 +AAC_STATUS AacHba_OpenAdapter(
2091 +       IN PVOID AdapterArg )
2092 +/*----------------------------------------------------------------------------*/
2093 +{
2094 +       return( STATUS_SUCCESS );
2095 +}
2096 +
2097 +
2098 +/*------------------------------------------------------------------------------
2099 +       AacHba_CloseAdapter()
2100 + *----------------------------------------------------------------------------*/
2101 +AAC_STATUS AacHba_CloseAdapter(
2102 +       IN PVOID AdapterArg )
2103 +/*----------------------------------------------------------------------------*/
2104 +{
2105 +       return( STATUS_SUCCESS );
2106 +}
2107 +
2108 +
2109 +/*------------------------------------------------------------------------------
2110 +       AacHba_DetachAdapter()
2111 + *----------------------------------------------------------------------------*/
2112 +void AacHba_DetachAdapter(
2113 +       IN PVOID AdapterArg )
2114 +/*----------------------------------------------------------------------------*/
2115 +{
2116 +       AacCommDetachAdapter( AdapterArg );
2117 +}
2118 +
2119 +
2120 +/*------------------------------------------------------------------------------
2121 +       AacHba_AbortScsiCommand()
2122 + *----------------------------------------------------------------------------*/
2123 +void AacHba_AbortScsiCommand(
2124 +       Scsi_Cmnd *scsi_cmnd_ptr )
2125 +/*----------------------------------------------------------------------------*/
2126 +{
2127 +       u_short interrupt_status;
2128 +       PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
2129 +
2130 +       CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
2131 +       interrupt_status = Sa_READ_USHORT( ( PSa_ADAPTER_EXTENSION )( CommonExtensionPtr->MiniPort ),
2132 +               DoorbellReg_p );
2133 +       cmn_err( CE_WARN, "interrupt_status = %d", interrupt_status );
2134 +       
2135 +       if( interrupt_status & DOORBELL_1) {    // Adapter -> Host Normal Command Ready
2136 +               cmn_err( CE_WARN, "DOORBELL_1: Adapter -> Host Normal Command Ready" );
2137 +       } 
2138 +
2139 +       if( interrupt_status & DOORBELL_2) {    // Adapter -> Host Normal Response Ready
2140 +               cmn_err( CE_WARN, "DOORBELL_2: Adapter -> Host Normal Response Ready" );
2141 +       }
2142 +
2143 +       if ( interrupt_status & DOORBELL_3) {   // Adapter -> Host Normal Command Not Full
2144 +               cmn_err( CE_WARN, "DOORBELL_3: Adapter -> Host Normal Command Not Full" );
2145 +       }
2146 +
2147 +       if ( interrupt_status & DOORBELL_4) {   // Adapter -> Host Normal Response Not Full
2148 +               cmn_err( CE_WARN, "DOORBELL_4: Adapter -> Host Normal Response Not Full" );
2149 +       }
2150 +
2151 +}
2152 +
2153 +
2154 +/*------------------------------------------------------------------------------
2155 +       AacHba_HandleAif()
2156 + *----------------------------------------------------------------------------*/
2157 +BOOLEAN AacHba_HandleAif(
2158 +       IN PVOID AdapterArg,
2159 +       IN PFIB_CONTEXT FibContext )
2160 +/*----------------------------------------------------------------------------*/
2161 +{
2162 +       return( FALSE );
2163 +}
2164 +
2165 +
2166 +/*------------------------------------------------------------------------------
2167 +       AacHba_SetSenseData()
2168 +               Fill in the sense data.
2169 +       Preconditions:
2170 +       Postconditions:
2171 + *----------------------------------------------------------------------------*/
2172 +void AacHba_SetSenseData(
2173 +       char * sense_buf,
2174 +       unchar sense_key,
2175 +       unchar sense_code,
2176 +       unchar a_sense_code,
2177 +       unchar incorrect_length,
2178 +       unchar bit_pointer,
2179 +       unsigned field_pointer,
2180 +       unsigned long residue )
2181 +/*----------------------------------------------------------------------------*/
2182 +{
2183 +       sense_buf[0] = 0xF0;                    // Sense data valid, err code 70h (current error)
2184 +       sense_buf[1] = 0;                                                               // Segment number, always zero
2185 +
2186 +       if( incorrect_length )
2187 +       {
2188 +               sense_buf[2] = sense_key | 0x20;                // Set the ILI bit | sense key
2189 +               sense_buf[3] = BYTE3(residue);
2190 +               sense_buf[4] = BYTE2(residue);
2191 +               sense_buf[5] = BYTE1(residue);
2192 +               sense_buf[6] = BYTE0(residue);
2193 +       }
2194 +       else
2195 +               sense_buf[2] = sense_key;                               // Sense key
2196 +
2197 +       if( sense_key == SENKEY_ILLEGAL )
2198 +               sense_buf[7] = 10;                                              // Additional sense length
2199 +       else
2200 +               sense_buf[7] = 6;                                               // Additional sense length
2201 +
2202 +       sense_buf[12] = sense_code;                             // Additional sense code
2203 +       sense_buf[13] = a_sense_code;                           // Additional sense code qualifier
2204 +       if( sense_key == SENKEY_ILLEGAL )
2205 +       {
2206 +               sense_buf[15] = 0;
2207 +
2208 +               if( sense_code == SENCODE_INVALID_PARAM_FIELD )
2209 +                       sense_buf[15] = 0x80;                           // Std sense key specific field
2210 +                                                                                               // Illegal parameter is in the parameter block
2211 +
2212 +               if( sense_code == SENCODE_INVALID_CDB_FIELD )
2213 +                       sense_buf[15] = 0xc0;                           // Std sense key specific field
2214 +                                                                                               // Illegal parameter is in the CDB block
2215 +               sense_buf[15] |= bit_pointer;
2216 +               sense_buf[16] = field_pointer >> 8;     // MSB
2217 +               sense_buf[17] = field_pointer;          // LSB
2218 +       }
2219 +}
2220 +
2221 diff -burN linux-2.4.9/drivers/scsi/aacraid/aacid.c linux/drivers/scsi/aacraid/aacid.c
2222 --- linux-2.4.9/drivers/scsi/aacraid/aacid.c    Wed Dec 31 18:00:00 1969
2223 +++ linux/drivers/scsi/aacraid/aacid.c  Thu Aug 16 18:10:23 2001
2224 @@ -0,0 +1,157 @@
2225 +/*++
2226 + * Adaptec aacraid device driver for Linux.
2227 + *
2228 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
2229 + *
2230 + * This program is free software; you can redistribute it and/or modify
2231 + * it under the terms of the GNU General Public License as published by
2232 + * the Free Software Foundation; either version 2, or (at your option)
2233 + * any later version.
2234 + *
2235 + * This program is distributed in the hope that it will be useful,
2236 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2237 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
2238 + * GNU General Public License for more details.
2239 + *
2240 + * You should have received a copy of the GNU General Public License
2241 + * along with this program; see the file COPYING.  If not, write to
2242 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
2243 + *
2244 + * Module Name:
2245 + *  aac.c
2246 + *
2247 + * Abstract: Data structures for controller specific info.
2248 + *
2249 +--*/
2250 +
2251 +static char *ident_aacid = "aacraid_ident aacid.c 1.0.6 2000/10/09 Adaptec, Inc.";
2252 +
2253 +#include "osheaders.h"
2254 +
2255 +#include "AacGenericTypes.h"
2256 +
2257 +#include "aac_unix_defs.h"
2258 +
2259 +#include "fsatypes.h"
2260 +#include "comstruc.h"
2261 +#include "fsaport.h"
2262 +#include "pcisup.h"
2263 +
2264 +#include "version.h"
2265 +
2266 +
2267 +/* Function Prototypes */
2268 +void InqStrCopy(char *a, char *b); /* ossup.c */
2269 +
2270 +/* Device name used to register and unregister
2271 +   the device in linit.c */
2272 +char devicestr[]="aac";
2273 +
2274 +char *container_types[] = {
2275 +        "None",
2276 +        "Volume",
2277 +        "Mirror",
2278 +        "Stripe",
2279 +        "RAID5",
2280 +        "SSRW",
2281 +        "SSRO",
2282 +        "Morph",
2283 +        "Legacy",
2284 +        "RAID4",
2285 +        "RAID10",             
2286 +        "RAID00",             
2287 +        "V-MIRRORS",          
2288 +        "PSEUDO R4",          
2289 +       "RAID50",
2290 +        "Unknown"
2291 +};
2292 +
2293 +/* Local Structure to set SCSI inquiry data strings */
2294 +typedef struct _INQSTR {
2295 +  char vid[8];         /* Vendor ID */
2296 +  char pid[16];        /* Product ID */
2297 +  char prl[4];         /* Product Revision Level */
2298 +} INQSTR, *INQSTRP;
2299 +
2300 +FSA_MINIPORT MiniPorts[];
2301 +
2302 +/* Function: SetInqDataStr
2303 + *
2304 + * Arguments: [1] pointer to void [1] int
2305 + *
2306 + * Purpose: Sets SCSI inquiry data strings for vendor, product
2307 + * and revision level. Allows strings to be set in platform dependant
2308 + * files instead of in OS dependant driver source.
2309 + */
2310 +void
2311 +SetInqDataStr (
2312 +  int MiniPortIndex,
2313 +  void *dataPtr,
2314 +  int tindex)
2315 +{
2316 +  INQSTRP InqStrPtr;
2317 +   char *findit;
2318 +   FSA_MINIPORT   *mp;
2319 +
2320 +   mp = &MiniPorts[MiniPortIndex];
2321 +   
2322 +    InqStrPtr = (INQSTRP)(dataPtr); /* cast dataPtr to type INQSTRP */
2323 +
2324 +    InqStrCopy (mp->Vendor, InqStrPtr->vid); 
2325 +    InqStrCopy (mp->Model,  InqStrPtr->pid); /* last six chars reserved for vol type */
2326 +
2327 +    findit = InqStrPtr->pid;
2328 +
2329 +    for ( ; *findit != ' '; findit++); /* walk till we find a space then incr by 1 */
2330 +        findit++;
2331 +       
2332 +    if (tindex < (sizeof(container_types)/sizeof(char *))){
2333 +      InqStrCopy (container_types[tindex], findit);
2334 +    }
2335 +   InqStrCopy ("0001", InqStrPtr->prl);
2336 +}
2337 +
2338 +int
2339 +SaInitDevice(
2340 +       IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
2341 +       IN ULONG AdapterNumber,
2342 +       IN ULONG PciBus,
2343 +       IN ULONG PciSlot
2344 +);
2345 +
2346 +int
2347 +RxInitDevice(
2348 +       IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
2349 +       IN ULONG AdapterNumber,
2350 +       IN ULONG PciBus,
2351 +       IN ULONG PciSlot
2352 +);
2353 +
2354 +
2355 +/*
2356 + * Because of the way Linux names scsi devices, the order in this table has
2357 + * become important.  Check for on-board Raid first, add-in cards second.
2358 + */
2359 +
2360 +FSA_MINIPORT MiniPorts[] = {
2361 +       { 0x0000, 0x0000, 0x0000, 0x0000, "afa", RxInitDevice, "percraid", "DELL    ", "PERCRAID        " }, /* Dell unknown - uses perc_pciid */
2362 +       { 0x0000, 0x0000, 0x0000, 0x0000, "aac", RxInitDevice, "aacraid", "ADAPTEC  ", "AACRAID         " }, /* unknown - uses rx_pciid */
2363 +       { 0x0000, 0x0000, 0x0000, 0x0000, "aac", SaInitDevice, "aacraid", "ADAPTEC  ", "AACRAID         " }, /* unknown - uses sa_pciid */
2364 +       { 0x1028, 0x0001, 0x1028, 0x0001, "afa", RxInitDevice, "percraid", "DELL    ", "PERCRAID        " }, /* PERC 2/Si */
2365 +       { 0x1028, 0x0002, 0x1028, 0x0002, "afa", RxInitDevice, "percraid", "DELL    ", "PERCRAID        " }, /* PERC 3/Di */
2366 +       { 0x1028, 0x0003, 0x1028, 0x0003, "afa", RxInitDevice, "percraid", "DELL    ", "PERCRAID        " }, /* PERC 3/Si */
2367 +       { 0x1028, 0x0004, 0x1028, 0x00d0, "afa", RxInitDevice, "percraid", "DELL    ", "PERCRAID        " }, /* PERC 3/Si */
2368 +       { 0x1028, 0x0002, 0x1028, 0x00d1, "afa", RxInitDevice, "percraid", "DELL    ", "PERCRAID        " }, /* PERC 3/Di */
2369 +       { 0x1028, 0x0002, 0x1028, 0x00d9, "afa", RxInitDevice, "percraid", "DELL    ", "PERCRAID        " }, /* PERC 3/Di */
2370 +       { 0x1028, 0x000a, 0x1028, 0x0106, "afa", RxInitDevice, "percraid", "DELL    ", "PERCRAID        " }, /* PERC 3/Di */
2371 +       { 0x1011, 0x0046, 0x9005, 0x1364, "afa", SaInitDevice, "percraid", "DELL    ", "PERCRAID        " }, /* Dell PERC2 "Quad Channel" */
2372 +       { 0x1011, 0x0046, 0x9005, 0x0365, "aac", SaInitDevice, "aacraid",  "ADAPTEC ", "Adaptec 5400S   " }, /* Adaptec 5400S */
2373 +       { 0x1011, 0x0046, 0x103c, 0x10c2, "hpn", SaInitDevice, "hpnraid",  "HP      ", "NetRAID-4M      " }  /* HP NetRAID-4M */
2374 +};
2375 +
2376 +
2377 +#define NUM_MINIPORTS  (sizeof(MiniPorts) / sizeof(FSA_MINIPORT))
2378 +
2379 +int NumMiniPorts = NUM_MINIPORTS;
2380 +
2381 +char DescriptionString[] =     "AACxxx Raid Controller" FSA_VERSION_STRING ;
2382 diff -burN linux-2.4.9/drivers/scsi/aacraid/commctrl.c linux/drivers/scsi/aacraid/commctrl.c
2383 --- linux-2.4.9/drivers/scsi/aacraid/commctrl.c Wed Dec 31 18:00:00 1969
2384 +++ linux/drivers/scsi/aacraid/commctrl.c       Thu Aug 16 13:41:30 2001
2385 @@ -0,0 +1,1098 @@
2386 +/*++
2387 + * Adaptec aacraid device driver for Linux.
2388 + *
2389 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
2390 + *
2391 + * This program is free software; you can redistribute it and/or modify
2392 + * it under the terms of the GNU General Public License as published by
2393 + * the Free Software Foundation; either version 2, or (at your option)
2394 + * any later version.
2395 + *
2396 + * This program is distributed in the hope that it will be useful,
2397 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2398 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
2399 + * GNU General Public License for more details.
2400 + *
2401 + * You should have received a copy of the GNU General Public License
2402 + * along with this program; see the file COPYING.  If not, write to
2403 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
2404 + *
2405 + * Module Name:
2406 + *  commctrl.c
2407 + *
2408 + * Abstract: Contains all routines for control of the AFA comm layer
2409 + *
2410 +--*/
2411 +
2412 +static char *ident_commctrl = "aacraid_ident commctrl.c 1.0.7 2000/10/11 Adaptec, Inc.";
2413 +
2414 +#include "comprocs.h"
2415 +#include "osheaders.h"
2416 +#include "ostypes.h"
2417 +
2418 +
2419 +
2420 +
2421 +
2422 +typedef BOOLEAN BOOL;
2423 +#define inline /* _inline */
2424 +
2425 +#include <revision.h>
2426 +AAC_STATUS
2427 +FsaCtlCheckRevision(
2428 +       IN PAFA_COMM_ADAPTER    Adapter,
2429 +       IN PAFA_IOCTL_CMD               IoctlCmdPtr
2430 +       )
2431 +/*++
2432 +
2433 +Routine Description:
2434 +
2435 +       This routine validates the revision of the caller with the current revision
2436 +       of the filesystem.
2437 +
2438 +Arguments:
2439 +
2440 +       Adapter - Supplies which adapter is being processed.
2441 +
2442 +    Irp - Supplies the Irp being processed.
2443 +
2444 +       IrpContext - Supplies the IrpContext.
2445 +
2446 +Return Value:
2447 +
2448 +       AAC_STATUS
2449 +
2450 +--*/
2451 +
2452 +{
2453 +       RevCheck APIRevCheck;
2454 +       RevCheckResp APIRevCheckResp;
2455 +       RevComponent APICallingComponent;
2456 +       ULONG APIBuildNumber;
2457 +
2458 +       if (COPYIN( (caddr_t) IoctlCmdPtr->arg, (caddr_t) &APIRevCheck, sizeof(RevCheck), IoctlCmdPtr->flag )) {
2459 +               return (EFAULT);
2460 +       }
2461 +
2462 +       APICallingComponent = APIRevCheck.callingComponent;
2463 +       APIBuildNumber = APIRevCheck.callingRevision.buildNumber;
2464 +
2465 +       APIRevCheckResp.possiblyCompatible = RevCheckCompatibility( RevMiniportDriver , APICallingComponent, APIBuildNumber );
2466 +
2467 +       APIRevCheckResp.adapterSWRevision.external.ul = RevGetExternalRev();
2468 +       APIRevCheckResp.adapterSWRevision.buildNumber = RevGetBuildNumber();
2469 +
2470 +       if (COPYOUT( (caddr_t) &APIRevCheckResp, (caddr_t) IoctlCmdPtr->arg, sizeof(RevCheckResp), IoctlCmdPtr->flag )) {
2471 +               return (EFAULT);
2472 +       }
2473 +
2474 +       return (0);
2475 +}
2476 +
2477 +
2478 +int
2479 +AfaCommAdapterDeviceControl(
2480 +       IN PVOID AdapterArg,
2481 +       IN PAFA_IOCTL_CMD IoctlCmdPtr
2482 +       )
2483 +{
2484 +       PAFA_COMM_ADAPTER Adapter = (PAFA_COMM_ADAPTER) AdapterArg;
2485 +    int Status = ENOTTY;
2486 +//    PIO_STACK_LOCATION IrpSp;
2487 +       PAFA_CLASS_DRIVER ClassDriver;
2488 +
2489 +       //
2490 +       // First loop through all of the class drivers to give them a chance to handle
2491 +       // the Device control first.
2492 +       //
2493 +
2494 +       ClassDriver = Adapter->ClassDriverList;
2495 +
2496 +       while (ClassDriver) {
2497 +
2498 +               if (ClassDriver->DeviceControl) {
2499 +
2500 +                       if (ClassDriver->DeviceControl( ClassDriver->ClassDriverExtension, IoctlCmdPtr, &Status ) ) {
2501 +
2502 +                               return (Status);
2503 +
2504 +                       }
2505 +               }
2506 +
2507 +               ClassDriver = ClassDriver->Next;
2508 +       }
2509 +
2510 +    switch (IoctlCmdPtr->cmd) {
2511 +
2512 +
2513 +         case FSACTL_SENDFIB:
2514 +
2515 +               Status = AfaCommCtlSendFib( Adapter, IoctlCmdPtr );
2516 +               break;
2517 +
2518 +         case FSACTL_AIF_THREAD:
2519 +
2520 +               Status = AfaCommCtlAifThread( Adapter, IoctlCmdPtr );   
2521 +               break;
2522 +
2523 +
2524 +         case FSACTL_OPEN_GET_ADAPTER_FIB:
2525 +
2526 +               Status = FsaCtlOpenGetAdapterFib( Adapter, IoctlCmdPtr );
2527 +               break;
2528 +
2529 +         case FSACTL_GET_NEXT_ADAPTER_FIB:
2530 +
2531 +               Status = FsaCtlGetNextAdapterFib( Adapter, IoctlCmdPtr );
2532 +               break;
2533 +
2534 +         case FSACTL_CLOSE_GET_ADAPTER_FIB:
2535 +
2536 +               Status = FsaCtlCloseGetAdapterFib( Adapter, IoctlCmdPtr );
2537 +               break;
2538 +
2539 +         case FSACTL_MINIPORT_REV_CHECK:
2540 +        
2541 +               Status = FsaCtlCheckRevision( Adapter , IoctlCmdPtr );
2542 +               break;
2543 +
2544 +
2545 +      default:
2546 +         
2547 +               Status = ENOTTY;
2548 +               break;  
2549 +
2550 +       }
2551 +
2552 +
2553 +       return (Status);
2554 +}
2555 +
2556 +AAC_STATUS
2557 +AfaCommRegisterNewClassDriver(
2558 +       IN PAFA_COMM_ADAPTER    Adapter,
2559 +       IN PAFA_NEW_CLASS_DRIVER        NewClassDriver,
2560 +       OUT PAFA_NEW_CLASS_DRIVER_RESPONSE NewClassDriverResponse
2561 +       )
2562 +/*++
2563 +
2564 +Routine Description:
2565 +
2566 +       This routine registers a new class driver for the comm layer.
2567 +
2568 +       It will return a pointer to the communication functions for the class driver
2569 +       to use.
2570 +
2571 +Arguments:
2572 +
2573 +       Adapter - Supplies which adapter is being processed.
2574 +
2575 +    Irp - Supplies the Irp being processed.
2576 +
2577 +Return Value:
2578 +
2579 +       STATUS_SUCCESS           - Everything OK.
2580 +
2581 +--*/
2582 +{
2583 +       AAC_STATUS Status;
2584 +       PAFA_CLASS_DRIVER ClassDriver;
2585 +
2586 +
2587 +       ClassDriver = (PAFA_CLASS_DRIVER) OsAllocMemory( sizeof(AFA_CLASS_DRIVER), OS_ALLOC_MEM_SLEEP );
2588 +
2589 +       if (ClassDriver == NULL) {
2590 +
2591 +               Status = STATUS_INSUFFICIENT_RESOURCES;
2592 +
2593 +               return Status;
2594 +       }
2595 +
2596 +       //
2597 +       // If the class driver has sent in user Vars, then copy them into the global
2598 +       // area.
2599 +       //
2600 +
2601 +       if (NewClassDriver->NumUserVars) {
2602 +
2603 +               PFSA_USER_VAR   NewUserVars;
2604 +
2605 +               NewUserVars = OsAllocMemory( (FsaCommData.NumUserVars +
2606 +                                                                  NewClassDriver->NumUserVars) * sizeof(FSA_USER_VAR), OS_ALLOC_MEM_SLEEP );
2607 +
2608 +               //
2609 +               // First copy the existing into the new area.
2610 +               //
2611 +
2612 +               RtlCopyMemory( NewUserVars, FsaCommData.UserVars, FsaCommData.NumUserVars * sizeof(FSA_USER_VAR) );
2613 +
2614 +               //
2615 +               // Next copy the new vars passed in from class driver.
2616 +               //
2617 +
2618 +               RtlCopyMemory( (NewUserVars + FsaCommData.NumUserVars),
2619 +                                          NewClassDriver->UserVars,
2620 +                                          NewClassDriver->NumUserVars * sizeof(FSA_USER_VAR) );
2621 +
2622 +               //
2623 +               // Free up the old user vars.
2624 +               //
2625 +
2626 +               OsFreeMemory( FsaCommData.UserVars, FsaCommData.NumUserVars * sizeof(FSA_USER_VAR) );
2627 +
2628 +               //
2629 +               // Point the global to the new area.
2630 +               //
2631 +
2632 +               FsaCommData.UserVars = NewUserVars;
2633 +
2634 +               //
2635 +               // Update the total count.
2636 +               //
2637 +
2638 +               FsaCommData.NumUserVars += NewClassDriver->NumUserVars;
2639 +
2640 +       }
2641 +
2642 +       ClassDriver->OpenAdapter = NewClassDriver->OpenAdapter;
2643 +       ClassDriver->CloseAdapter = NewClassDriver->CloseAdapter;
2644 +       ClassDriver->DeviceControl = NewClassDriver->DeviceControl;
2645 +       ClassDriver->HandleAif = NewClassDriver->HandleAif;
2646 +       ClassDriver->ClassDriverExtension = NewClassDriver->ClassDriverExtension;
2647 +
2648 +       ClassDriver->Next = Adapter->ClassDriverList;
2649 +       Adapter->ClassDriverList = ClassDriver;
2650 +
2651 +       //
2652 +       // Now return the information needed by the class driver to communicate to us.
2653 +       //
2654 +
2655 +       NewClassDriverResponse->CommFuncs = &Adapter->CommFuncs;
2656 +       NewClassDriverResponse->CommPortExtension = Adapter;
2657 +       NewClassDriverResponse->MiniPortExtension = Adapter->AdapterExtension;
2658 +       NewClassDriverResponse->SpinLockCookie = Adapter->SpinLockCookie;
2659 +       NewClassDriverResponse->Dip = Adapter->Dip;
2660 +
2661 +       return (STATUS_SUCCESS);
2662 +
2663 +
2664 +}
2665 +
2666 +int
2667 +AfaCommCtlSendFib(
2668 +       IN PAFA_COMM_ADAPTER    Adapter,
2669 +       IN PAFA_IOCTL_CMD               IoctlCmdPtr
2670 +)
2671 +/*++
2672 +
2673 +Routine Description:
2674 +
2675 +       This routine sends a fib to the adapter on behalf of a user level
2676 +       program.
2677 +
2678 +Arguments:
2679 +
2680 +       Adapter - Supplies which adapter is being processed.
2681 +
2682 +       IoctlCmdPtr - Pointer to the arguments to the IOCTL call
2683 +
2684 +Return Value:
2685 +
2686 +       STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2687 +
2688 +       STATUS_INSUFFICIENT_RESOURCES - If a memory allocation failed.
2689 +
2690 +       STATUS_SUCCESS           - Everything OK.
2691 +
2692 +--*/
2693 +{
2694 +    PFIB KFib;
2695 +//    PMDL DmaMdl = NULL;
2696 +       PCOMM_FIB_CONTEXT FibContext;
2697 +       PSGMAP_CONTEXT SgMapContext;
2698 +       SGMAP_CONTEXT _SgMapContext;
2699 +    QUEUE_TYPES WhichQueue;
2700 +    PVOID UsersAddress;
2701 +       AAC_STATUS Status;
2702 +
2703 +       FibContext = AllocateFib( Adapter );
2704 +
2705 +    KFib = FibContext->Fib;
2706 +
2707 +       //
2708 +       // First copy in the header so that we can check the size field.
2709 +       //
2710 +
2711 +       if (COPYIN( (caddr_t) IoctlCmdPtr->arg, (caddr_t) KFib, sizeof(FIB_HEADER), IoctlCmdPtr->flag )) {
2712 +               FreeFib( FibContext );
2713 +               Status = EFAULT;
2714 +               return (Status);
2715 +       }
2716 +
2717 +       //
2718 +       //      Since we copy based on the fib header size, make sure that we
2719 +       //      will not overrun the buffer when we copy the memory. Return
2720 +       //      an error if we would.
2721 +       //
2722 +
2723 +       if (KFib->Header.Size > sizeof(FIB) - sizeof(FIB_HEADER)) {
2724 +               FreeFib( FibContext );
2725 +               Status = EINVAL;
2726 +               return Status;
2727 +
2728 +       }
2729 +
2730 +       if (COPYIN( (caddr_t) IoctlCmdPtr->arg, (caddr_t) KFib, KFib->Header.Size + sizeof(FIB_HEADER), IoctlCmdPtr->flag )) {
2731 +               FreeFib( FibContext );
2732 +               Status = EFAULT;
2733 +               return (Status);
2734 +       }
2735 +
2736 +    WhichQueue = AdapNormCmdQueue;
2737 +
2738 +
2739 +       if (KFib->Header.Command == TakeABreakPt) {
2740 +
2741 +               InterruptAdapter(Adapter);
2742 +
2743 +               //
2744 +               // Since we didn't really send a fib, zero out the state to allow 
2745 +               // cleanup code not to assert.
2746 +               //
2747 +
2748 +               KFib->Header.XferState = 0;
2749 +
2750 +
2751 +       } else {
2752 +       
2753 +               if (SendFib(KFib->Header.Command, FibContext, KFib->Header.Size , FsaNormal,
2754 +                                       TRUE, NULL, TRUE, NULL, NULL) != FSA_SUCCESS) {
2755 +               FsaCommPrint("User SendFib failed!.\n");
2756 +
2757 +
2758 +                       FreeFib( FibContext );
2759 +                       return (ENXIO);
2760 +               }
2761 +
2762 +           if (CompleteFib(FibContext) != FSA_SUCCESS) {
2763 +               FsaCommPrint("User Complete FIB failed.\n");
2764 +
2765 +                       FreeFib( FibContext );
2766 +                       return (ENXIO);
2767 +               }
2768 +
2769 +
2770 +    }
2771 +
2772 +
2773 +       //
2774 +       //      Make sure that the size returned by the adapter (which includes
2775 +       //      the header) is less than or equal to the size of a fib, so we
2776 +       //      don't corrupt application data. Then copy that size to the user
2777 +       //      buffer. (Don't try to add the header information again, since it
2778 +       //      was already included by the adapter.)
2779 +       //
2780 +    ASSERT(KFib->Header.Size <= sizeof(FIB));
2781 +
2782 +       if (COPYOUT( (caddr_t) KFib, (caddr_t) IoctlCmdPtr->arg, KFib->Header.Size, IoctlCmdPtr->flag )) {
2783 +               FreeFib( FibContext );
2784 +               Status = EFAULT;
2785 +               return (Status);
2786 +       }
2787 +
2788 +       FreeFib( FibContext );
2789 +
2790 +    return (0);
2791 +
2792 +}
2793 +
2794 +int
2795 +AfaCommCtlAifThread(
2796 +       IN PAFA_COMM_ADAPTER    Adapter,
2797 +       IN PAFA_IOCTL_CMD               IoctlCmdPtr
2798 +)
2799 +/*++
2800 +
2801 +Routine Description:
2802 +
2803 +       This routine will act as the AIF thread for this adapter.
2804 +
2805 +Arguments:
2806 +
2807 +       Adapter - Supplies which adapter is being processed.
2808 +
2809 +       IoctlCmdPtr - Pointer to the arguments to the IOCTL call
2810 +
2811 +Return Value:
2812 +
2813 +       STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2814 +
2815 +       STATUS_INSUFFICIENT_RESOURCES - If a memory allocation failed.
2816 +
2817 +       STATUS_SUCCESS           - Everything OK.
2818 +
2819 +--*/
2820 +{
2821 +       return (NormCommandThread(Adapter));
2822 +}
2823 +
2824 +
2825 +
2826 +#ifdef GATHER_FIB_TIMES
2827 +AAC_STATUS
2828 +AfaCommGetFibTimes(
2829 +       IN PAFA_COMM_ADAPTER    Adapter,
2830 +       IN PIRP                                 Irp
2831 +       )
2832 +/*++
2833 +
2834 +Routine Description:
2835 +
2836 +       This routine returns the gathered fibtimes to the user.
2837 +
2838 +Arguments:
2839 +
2840 +       Adapter - Supplies which adapter is being processed.
2841 +
2842 +    Irp - Supplies the Irp being processed.
2843 +
2844 +Return Value:
2845 +
2846 +       STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2847 +
2848 +       STATUS_INSUFFICIENT_RESOURCES - If a memory allocation failed.
2849 +
2850 +       STATUS_SUCCESS           - Everything OK.
2851 +
2852 +--*/
2853 +{
2854 +       PALL_FIB_TIMES AllFibTimes;
2855 +       PLARGE_INTEGER FreqPtr;
2856 +    PIO_STACK_LOCATION IrpSp;
2857 +
2858 +    //
2859 +    //  Get a pointer to the current Irp stack location
2860 +    //
2861 +
2862 +    IrpSp = IoGetCurrentIrpStackLocation( Irp );
2863 +
2864 +       FreqPtr = (PLARGE_INTEGER)IrpSp->Parameters.FileSystemControl.Type3InputBuffer;
2865 +
2866 +       *FreqPtr = Adapter->FibTimesFrequency;
2867 +
2868 +       AllFibTimes = (PALL_FIB_TIMES)((PUCHAR)FreqPtr + sizeof(LARGE_INTEGER));
2869 +
2870 +       RtlCopyMemory(AllFibTimes, Adapter->FibTimes, sizeof(ALL_FIB_TIMES));
2871 +
2872 +       Irp->IoStatus.Information = 0;
2873 +
2874 +       return (STATUS_SUCCESS);
2875 +
2876 +}
2877 +
2878 +AAC_STATUS
2879 +AfaCommZeroFibTimes(
2880 +       IN PAFA_COMM_ADAPTER    Adapter,
2881 +       IN PIRP                                 Irp
2882 +       )
2883 +/*++
2884 +
2885 +Routine Description:
2886 +
2887 +       This routine zero's the FibTimes structure within the adapter structure.
2888 +
2889 +Arguments:
2890 +
2891 +       Adapter - Supplies which adapter is being processed.
2892 +
2893 +    Irp - Supplies the Irp being processed.
2894 +
2895 +Return Value:
2896 +
2897 +       STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2898 +
2899 +       STATUS_INSUFFICIENT_RESOURCES - If a memory allocation failed.
2900 +
2901 +       STATUS_SUCCESS           - Everything OK.
2902 +
2903 +--*/
2904 +{
2905 +       PFIB_TIMES FibTimesPtr;
2906 +       int i;
2907 +    PIO_STACK_LOCATION IrpSp;
2908 +
2909 +    //
2910 +    //  Get a pointer to the current Irp stack location
2911 +    //
2912 +
2913 +    IrpSp = IoGetCurrentIrpStackLocation( Irp );
2914 +
2915 +       //
2916 +       // Initialize the Fib timing data structures
2917 +       //
2918 +       RtlZeroMemory(Adapter->FibTimes, sizeof(ALL_FIB_TIMES));
2919 +
2920 +       for (i = 0; i < MAX_FSACOMMAND_NUM; i++) {
2921 +
2922 +               FibTimesPtr = &Adapter->FibTimes->FileSys[i];
2923 +
2924 +               FibTimesPtr->Minimum.LowPart = 0xffffffff;
2925 +               FibTimesPtr->Minimum.HighPart = 0x7fffffff;
2926 +               FibTimesPtr->AdapterMinimum.LowPart = 0xffffffff;
2927 +               FibTimesPtr->AdapterMinimum.HighPart = 0x7fffffff;
2928 +       }
2929 +       for (i = 0; i < MAX_RW_FIB_TIMES; i++) {
2930 +
2931 +               FibTimesPtr = &Adapter->FibTimes->Read[i];
2932 +
2933 +               FibTimesPtr->Minimum.LowPart = 0xffffffff;
2934 +               FibTimesPtr->Minimum.HighPart = 0x7fffffff;
2935 +               FibTimesPtr->AdapterMinimum.LowPart = 0xffffffff;
2936 +               FibTimesPtr->AdapterMinimum.HighPart = 0x7fffffff;
2937 +       }
2938 +       for (i = 0; i < MAX_RW_FIB_TIMES; i++) {
2939 +
2940 +               FibTimesPtr = &Adapter->FibTimes->Write[i];
2941 +
2942 +               FibTimesPtr->Minimum.LowPart = 0xffffffff;
2943 +               FibTimesPtr->Minimum.HighPart = 0x7fffffff;
2944 +               FibTimesPtr->AdapterMinimum.LowPart = 0xffffffff;
2945 +               FibTimesPtr->AdapterMinimum.HighPart = 0x7fffffff;
2946 +       }
2947 +
2948 +       FibTimesPtr = &Adapter->FibTimes->Other;
2949 +
2950 +       FibTimesPtr->Minimum.LowPart = 0xffffffff;
2951 +       FibTimesPtr->Minimum.HighPart = 0x7fffffff;
2952 +       FibTimesPtr->AdapterMinimum.LowPart = 0xffffffff;
2953 +       FibTimesPtr->AdapterMinimum.HighPart = 0x7fffffff;
2954 +
2955 +       Irp->IoStatus.Information = 0;
2956 +
2957 +       return (STATUS_SUCCESS);
2958 +
2959 +}
2960 +#endif // GATHER_FIB_TIMES
2961 +
2962 +#ifndef unix_aif
2963 +int
2964 +FsaCtlOpenGetAdapterFib(
2965 +       IN PAFA_COMM_ADAPTER    Adapter,
2966 +       IN PAFA_IOCTL_CMD               IoctlCmdPtr
2967 +       )
2968 +/*++
2969 +
2970 +Routine Description:
2971 +
2972 +    This routine will get the next Fib, if available, from the AdapterFibContext
2973 +       passed in from the user.
2974 +
2975 +Arguments:
2976 +
2977 +       Adapter - Supplies which adapter is being processed.
2978 +
2979 +    Irp - Supplies the Irp being processed.
2980 +
2981 +Return Value:
2982 +
2983 +       STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2984 +
2985 +       STATUS_INSUFFICIENT_RESOURCES - If a memory allocation failed.
2986 +
2987 +       STATUS_SUCCESS           - Everything OK.
2988 +
2989 +--*/
2990 +{
2991 +       PGET_ADAPTER_FIB_CONTEXT AdapterFibContext;
2992 +//     HANDLE Event;
2993 +//    PKEVENT eventObject = (PKEVENT) NULL;
2994 +       int Status;
2995 +
2996 +       //
2997 +       // The context must be allocated from NonPagedPool because we need to use MmIsAddressValid.
2998 +       //
2999 +
3000 +       AdapterFibContext = OsAllocMemory(sizeof(GET_ADAPTER_FIB_CONTEXT), OS_ALLOC_MEM_SLEEP);
3001 +
3002 +       if (AdapterFibContext == NULL) {
3003 +
3004 +               Status = ENOMEM;
3005 +
3006 +       } else {
3007 +
3008 +               AdapterFibContext->NodeTypeCode = FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT;
3009 +               AdapterFibContext->NodeByteSize = sizeof(GET_ADAPTER_FIB_CONTEXT);
3010 +
3011 +
3012 +               //
3013 +               // Initialize the conditional variable use to wait for the next AIF.
3014 +               //
3015 +
3016 +               OsCv_init( &AdapterFibContext->UserEvent);
3017 +
3018 +               //
3019 +               // Set WaitingForFib to FALSE to indicate we are not in a WaitForSingleObject
3020 +               //
3021 +
3022 +               AdapterFibContext->WaitingForFib = FALSE;
3023 +
3024 +               //
3025 +               // Initialize the FibList and set the count of fibs on the list to 0.
3026 +               //
3027 +
3028 +               AdapterFibContext->FibCount = 0;
3029 +               InitializeListHead(&AdapterFibContext->FibList);
3030 +
3031 +               //
3032 +               // Overload FileObject with a time stamp.
3033 +               //
3034 +               AdapterFibContext->FileObject = (void *)OsGetSeconds();
3035 +
3036 +               //
3037 +               // Now add this context onto the adapter's AdapterFibContext list.
3038 +               //
3039 +
3040 +               OsCvLockAcquire(Adapter->AdapterFibMutex);
3041 +
3042 +               InsertTailList(&Adapter->AdapterFibContextList, &AdapterFibContext->NextContext);
3043 +
3044 +               OsCvLockRelease(Adapter->AdapterFibMutex);
3045 +
3046 +               if (COPYOUT( &AdapterFibContext, (caddr_t) IoctlCmdPtr->arg, sizeof(PGET_ADAPTER_FIB_CONTEXT), 
3047 +                                                IoctlCmdPtr->flag )) {
3048 +
3049 +                       Status = EFAULT;
3050 +                       
3051 +               } else {
3052 +               
3053 +                       Status = 0;
3054 +
3055 +               }       
3056 +
3057 +       }
3058 +
3059 +       return (Status);
3060 +}
3061 +
3062 +int
3063 +FsaCtlGetNextAdapterFib(
3064 +       IN PAFA_COMM_ADAPTER    Adapter,
3065 +       IN PAFA_IOCTL_CMD               IoctlCmdPtr
3066 +       )
3067 +/*++
3068 +
3069 +Routine Description:
3070 +
3071 +    This routine will get the next Fib, if available, from the AdapterFibContext
3072 +       passed in from the user.
3073 +
3074 +Arguments:
3075 +
3076 +       Adapter - Supplies which adapter is being processed.
3077 +
3078 +    Irp - Supplies the Irp being processed.
3079 +
3080 +Return Value:
3081 +
3082 +       STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
3083 +
3084 +       STATUS_NO_MORE_ENTRIES - There are no more Fibs for this AdapterFibContext.
3085 +
3086 +       STATUS_SUCCESS           - Everything OK.
3087 +
3088 +--*/
3089 +{
3090 +       GET_ADAPTER_FIB_IOCTL AdapterFibIoctl;
3091 +       PGET_ADAPTER_FIB_CONTEXT AdapterFibContext, aifcp;
3092 +       PFIB Fib;
3093 +       int Status;
3094 +       PLIST_ENTRY Entry;
3095 +       int found;
3096 +
3097 +       if (COPYIN( (caddr_t) IoctlCmdPtr->arg, (caddr_t) &AdapterFibIoctl,
3098 +                                       sizeof(GET_ADAPTER_FIB_IOCTL), IoctlCmdPtr->flag )) {
3099 +               return (EFAULT);
3100 +       }
3101 +
3102 +       //
3103 +       // Extract the AdapterFibContext from the Input parameters.
3104 +       //
3105 +
3106 +       AdapterFibContext = (PGET_ADAPTER_FIB_CONTEXT) AdapterFibIoctl.AdapterFibContext;
3107 +
3108 +       //
3109 +       // Verify that the HANDLE passed in was a valid AdapterFibContext
3110 +       //
3111 +       // Search the list of AdapterFibContext addresses on the adapter to be sure
3112 +       // this is a valid address
3113 +
3114 +       found = 0;
3115 +       Entry = Adapter->AdapterFibContextList.Flink;
3116 +
3117 +       while ( Entry != &Adapter->AdapterFibContextList ) {
3118 +                       aifcp = CONTAINING_RECORD ( Entry, GET_ADAPTER_FIB_CONTEXT, NextContext );
3119 +                       if ( AdapterFibContext == aifcp ) {   // We found a winner
3120 +                                       found = 1;
3121 +                                       break;
3122 +                       }
3123 +                       Entry = Entry->Flink;
3124 +       }
3125 +
3126 +       if ( found == 0 ) {
3127 +                       return ( EINVAL );;
3128 +       }
3129 +
3130 +       if ( (AdapterFibContext->NodeTypeCode != FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT) ||
3131 +                (AdapterFibContext->NodeByteSize != sizeof(GET_ADAPTER_FIB_CONTEXT)) ) {
3132 +
3133 +               return ( EINVAL );
3134 +
3135 +       }
3136 +
3137 +       Status = STATUS_SUCCESS;
3138 +
3139 +       OsCvLockAcquire(Adapter->AdapterFibMutex);
3140 +
3141 +       //
3142 +       // If there are no fibs to send back, then either wait or return EAGAIN
3143 +       //
3144 +return_fib:
3145 +
3146 +       if (!IsListEmpty(&AdapterFibContext->FibList)) {
3147 +
3148 +               PLIST_ENTRY Entry;
3149 +
3150 +               //
3151 +               // Pull the next fib from the FibList
3152 +               //
3153 +               Entry = RemoveHeadList(&AdapterFibContext->FibList);
3154 +
3155 +               Fib = CONTAINING_RECORD( Entry, FIB, Header.FibLinks );
3156 +
3157 +               AdapterFibContext->FibCount--;
3158 +
3159 +               if (COPYOUT( Fib, AdapterFibIoctl.AifFib, sizeof(FIB), IoctlCmdPtr->flag )) {
3160 +
3161 +                       OsCvLockRelease( Adapter->AdapterFibMutex );
3162 +                       OsFreeMemory( Fib, sizeof(Fib) );
3163 +                       return (EFAULT);
3164 +
3165 +               }       
3166 +
3167 +               //
3168 +               // Free the space occupied by this copy of the fib.
3169 +               //
3170 +
3171 +               OsFreeMemory(Fib, sizeof(FIB));
3172 +
3173 +        Status = 0;
3174 +
3175 +               //
3176 +               // Overload FileObject with a time stamp
3177 +               // 
3178 +               AdapterFibContext->FileObject = ( void * )OsGetSeconds();
3179 +
3180 +       } else {
3181 +
3182 +               if (AdapterFibIoctl.Wait) {
3183 +                       
3184 +                       if (OsCv_wait_sig( &AdapterFibContext->UserEvent, Adapter->AdapterFibMutex ) == 0) {
3185 +
3186 +                               Status = EINTR;
3187 +
3188 +                       } else {
3189 +                       
3190 +                               goto return_fib;
3191 +                               
3192 +                       }
3193 +               } else {
3194 +                                       
3195 +                       Status = EAGAIN;
3196 +
3197 +               }       
3198 +
3199 +       }
3200 +       OsCvLockRelease( Adapter->AdapterFibMutex );
3201 +
3202 +       return (Status);
3203 +}
3204 +
3205 +int
3206 +FsaCtlCloseGetAdapterFib(
3207 +       IN PAFA_COMM_ADAPTER    Adapter,
3208 +       IN PAFA_IOCTL_CMD               IoctlCmdPtr
3209 +       )
3210 +/*++
3211 +
3212 +Routine Description:
3213 +
3214 +    This routine will close down the AdapterFibContext passed in from the user.
3215 +
3216 +Arguments:
3217 +
3218 +       Adapter - Supplies which adapter is being processed.
3219 +
3220 +    Irp - Supplies the Irp being processed.
3221 +
3222 +Return Value:
3223 +
3224 +       STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
3225 +
3226 +       STATUS_SUCCESS           - Everything OK.
3227 +
3228 +--*/
3229 +{
3230 +       PGET_ADAPTER_FIB_CONTEXT AdapterFibContext, aifcp;
3231 +       AAC_STATUS Status;
3232 +
3233 +       PLIST_ENTRY Entry;
3234 +       int found;
3235 +
3236 +       //
3237 +       // Extract the AdapterFibContext from the Input parameters
3238 +       //
3239 +
3240 +       AdapterFibContext = (PGET_ADAPTER_FIB_CONTEXT) IoctlCmdPtr->arg;
3241 +
3242 +       if (AdapterFibContext == 0) {
3243 +               cmn_err(CE_WARN, "FsaCtlCloseGetAdapterFib: AdapterFibContext is NULL");
3244 +               return(EINVAL);
3245 +       }
3246 +
3247 +       //
3248 +       // Verify that the HANDLE passed in was a valid AdapterFibContext
3249 +       //
3250 +       // Search the list of AdapterFibContext addresses on the adapter to be sure
3251 +       // this is a valid address
3252 +
3253 +       found = 0;
3254 +       Entry = Adapter->AdapterFibContextList.Flink;
3255 +
3256 +       while ( Entry != &Adapter->AdapterFibContextList ) {
3257 +                       aifcp = CONTAINING_RECORD ( Entry, GET_ADAPTER_FIB_CONTEXT, NextContext );
3258 +                       if ( AdapterFibContext == aifcp ) {   // We found a winner
3259 +                                       found = 1;
3260 +                                       break;
3261 +                       }
3262 +                       Entry = Entry->Flink;
3263 +       }
3264 +
3265 +       if ( found == 0 ) {
3266 +               return ( 0 ); // Already Gone
3267 +       }
3268 +
3269 +       if ( (AdapterFibContext->NodeTypeCode != FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT) ||
3270 +                (AdapterFibContext->NodeByteSize != sizeof(GET_ADAPTER_FIB_CONTEXT)) ) {
3271 +
3272 +               return (EINVAL);
3273 +
3274 +       }
3275 +
3276 +       OsCvLockAcquire(Adapter->AdapterFibMutex);
3277 +
3278 +       Status = FsaCloseAdapterFibContext(Adapter, AdapterFibContext);
3279 +
3280 +       OsCvLockRelease(Adapter->AdapterFibMutex);
3281 +
3282 +       return (Status);
3283 +}
3284 +
3285 +int
3286 +FsaCloseAdapterFibContext(
3287 +       IN PAFA_COMM_ADAPTER                    Adapter,
3288 +       IN PGET_ADAPTER_FIB_CONTEXT             AdapterFibContext
3289 +       )
3290 +{
3291 +       int Status;
3292 +       PFIB Fib;
3293 +
3294 +       //
3295 +       // First free any FIBs that have not been consumed yet.
3296 +       //
3297 +
3298 +       while (!IsListEmpty(&AdapterFibContext->FibList)) {
3299 +
3300 +               PLIST_ENTRY Entry;
3301 +
3302 +               //
3303 +               // Pull the next fib from the FibList
3304 +               //
3305 +
3306 +               Entry = RemoveHeadList(&AdapterFibContext->FibList);
3307 +
3308 +               Fib = CONTAINING_RECORD( Entry, FIB, Header.FibLinks );
3309 +
3310 +               AdapterFibContext->FibCount--;
3311 +
3312 +               //
3313 +               // Free the space occupied by this copy of the fib.
3314 +               //
3315 +
3316 +               OsFreeMemory(Fib, sizeof(FIB));
3317 +       }
3318 +
3319 +       //
3320 +       // Remove the Context from the AdapterFibContext List
3321 +       //
3322 +
3323 +       RemoveEntryList(&AdapterFibContext->NextContext);
3324 +
3325 +       OsCv_destroy( &AdapterFibContext->UserEvent );
3326 +
3327 +       //
3328 +       // Invalidate context
3329 +       //
3330 +
3331 +       AdapterFibContext->NodeTypeCode = 0;
3332 +
3333 +       //
3334 +       // Free the space occupied by the Context
3335 +       //
3336 +
3337 +       OsFreeMemory(AdapterFibContext, sizeof(GET_ADAPTER_FIB_CONTEXT));
3338 +
3339 +       Status = STATUS_SUCCESS;
3340 +
3341 +    return Status;
3342 +}
3343 +#endif 
3344 +
3345 +AAC_STATUS
3346 +AfaCommOpenAdapter(
3347 +       IN PVOID Arg
3348 +       )
3349 +/*++
3350 +
3351 +Routine Description:
3352 +
3353 +       The routine will get called by the miniport each time a user issues a CreateFile on the DeviceObject
3354 +       for the adapter.
3355 +
3356 +       The main purpose of this routine is to set up any data structures that may be needed
3357 +       to handle any requests made on this DeviceObject.
3358 +
3359 +Arguments:
3360 +
3361 +       Adapter - Pointer to which adapter miniport was opened.
3362 +
3363 +
3364 +Return Value:
3365 +
3366 +       STATUS_SUCCESS
3367 +
3368 +--*/
3369 +
3370 +{
3371 +       PAFA_COMM_ADAPTER       Adapter = (PAFA_COMM_ADAPTER) Arg;
3372 +       AAC_STATUS Status = STATUS_SUCCESS;
3373 +       PAFA_CLASS_DRIVER ClassDriver;
3374 +
3375 +       ClassDriver = Adapter->ClassDriverList;
3376 +
3377 +       while (ClassDriver) {
3378 +
3379 +               if (ClassDriver->OpenAdapter) {
3380 +
3381 +                       Status = ClassDriver->OpenAdapter( ClassDriver->ClassDriverExtension );
3382 +
3383 +                       if (Status != STATUS_SUCCESS)
3384 +                               break;
3385 +               }
3386 +
3387 +               ClassDriver = ClassDriver->Next;
3388 +       }
3389 +
3390 +       return ( Status );
3391 +}
3392 +
3393 +AAC_STATUS
3394 +AfaCommCloseAdapter(
3395 +       IN PVOID Arg
3396 +       )
3397 +/*++
3398 +
3399 +Routine Description:
3400 +
3401 +       This routine will get called by the miniport each time a user issues a CloseHandle on the DeviceObject
3402 +       for the adapter.
3403 +
3404 +       The main purpose of this routine is to cleanup any data structures that have been set up
3405 +       while this FileObject has been opened.
3406 +
3407 +       This routine loops through all of the AdapterFibContext structures to determine if any need
3408 +       to be deleted for this FileObject.
3409 +
3410 +Arguments:
3411 +
3412 +       Adapter - Pointer to adapter miniport
3413 +
3414 +       Irp - Pointer to Irp that caused this close
3415 +
3416 +Return Value:
3417 +
3418 +       Status value returned from File system driver AdapterClose
3419 +
3420 +--*/
3421 +{
3422 +       PAFA_COMM_ADAPTER       Adapter = (PAFA_COMM_ADAPTER) Arg;
3423 +       PLIST_ENTRY Entry, NextEntry;
3424 +       PGET_ADAPTER_FIB_CONTEXT AdapterFibContext;
3425 +       AAC_STATUS Status = STATUS_SUCCESS;
3426 +       PAFA_CLASS_DRIVER ClassDriver;
3427 +
3428 +       OsCvLockAcquire(Adapter->AdapterFibMutex);
3429 +
3430 +       Entry = Adapter->AdapterFibContextList.Flink;
3431 +
3432 +       //
3433 +       // Loop through all of the AdapterFibContext, looking for any that
3434 +       // were created with the FileObject that is being closed.
3435 +       //
3436 +       while (Entry != &Adapter->AdapterFibContextList) {
3437 +
3438 +               //
3439 +               // Extract the AdapterFibContext
3440 +               //
3441 +               AdapterFibContext = CONTAINING_RECORD( Entry, GET_ADAPTER_FIB_CONTEXT, NextContext );
3442 +
3443 +               // 
3444 +               // Save the next entry because CloseAdapterFibContext will delete the AdapterFibContext
3445 +               //
3446 +               NextEntry = Entry->Flink;
3447 +
3448 +               Entry = NextEntry;
3449 +
3450 +       }
3451 +
3452 +#ifdef unix_config_file
3453 +       //
3454 +       // If this FileObject had the adapter open for configuration, then release it.
3455 +       //
3456 +       if ( Adapter->AdapterConfigFileObject == IrpSp->FileObject ) {
3457 +
3458 +               Adapter->AdapterConfigFileObject = NULL;
3459 +
3460 +       }
3461 +#endif
3462 +
3463 +       OsCvLockRelease(Adapter->AdapterFibMutex);
3464 +
3465 +       ClassDriver = Adapter->ClassDriverList;
3466 +
3467 +       while (ClassDriver) {
3468 +
3469 +               if (ClassDriver->CloseAdapter) {
3470 +
3471 +                       Status = ClassDriver->CloseAdapter( ClassDriver->ClassDriverExtension );
3472 +
3473 +                       if (Status != STATUS_SUCCESS)
3474 +                               break;
3475 +               }
3476 +
3477 +               ClassDriver = ClassDriver->Next;
3478 +       }
3479 +
3480 +       return ( Status );
3481 +
3482 +}
3483 +
3484 diff -burN linux-2.4.9/drivers/scsi/aacraid/comminit.c linux/drivers/scsi/aacraid/comminit.c
3485 --- linux-2.4.9/drivers/scsi/aacraid/comminit.c Wed Dec 31 18:00:00 1969
3486 +++ linux/drivers/scsi/aacraid/comminit.c       Thu Aug 16 13:41:30 2001
3487 @@ -0,0 +1,986 @@
3488 +/*++
3489 + * Adaptec aacraid device driver for Linux.
3490 + *
3491 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
3492 + *
3493 + * This program is free software; you can redistribute it and/or modify
3494 + * it under the terms of the GNU General Public License as published by
3495 + * the Free Software Foundation; either version 2, or (at your option)
3496 + * any later version.
3497 + *
3498 + * This program is distributed in the hope that it will be useful,
3499 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
3500 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
3501 + * GNU General Public License for more details.
3502 + *
3503 + * You should have received a copy of the GNU General Public License
3504 + * along with this program; see the file COPYING.  If not, write to
3505 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
3506 + *
3507 + * Module Name:
3508 + *  comminit.c
3509 + *
3510 + * Abstract: This supports the initialization of the host adapter commuication interface.
3511 + *    This is a platform dependent module for the pci cyclone board.
3512 + *
3513 + --*/
3514 +
3515 +static char *ident_comminit = "aacraid_ident comminit.c 1.0.6 2000/10/09 Adaptec, Inc.";
3516 +
3517 +#include "comprocs.h"
3518 +
3519 +#define BugCheckFileId                   (FSAFS_BUG_CHECK_COMMINIT)
3520 +
3521 +VOID
3522 +AfaCommBugcheckHandler(
3523 +               IN PVOID Buffer,
3524 +               IN ULONG Length
3525 +               );
3526 +
3527 +VOID
3528 +ThrottlePeriodEndDpcRtn(
3529 +       IN PKDPC Dpc,
3530 +       IN PVOID DeferredContext,
3531 +       IN PVOID SystemArgument1,
3532 +       IN PVOID SystemArgument2);
3533 +
3534 +FSA_COMM_DATA FsaCommData;
3535 +
3536 +AAC_STATUS
3537 +HardInterruptModeration1Changed(
3538 +       IN PVOID AdapterContext,
3539 +       IN ULONG NewValue
3540 +       )
3541 +{
3542 +       PAFA_COMM_ADAPTER Adapter = AdapterContext;
3543 +
3544 +       //
3545 +       // If we are using interrupt moderation, then disable the interrupt
3546 +       // until we need to use it.
3547 +       //
3548 +       if (FsaCommData.HardInterruptModeration1)
3549 +               DisableInterrupt( Adapter, AdapNormCmdNotFull, FALSE );
3550 +       else
3551 +               EnableInterrupt( Adapter, AdapNormCmdNotFull, FALSE );
3552 +
3553 +       return (STATUS_SUCCESS);
3554 +}
3555 +
3556 +AAC_STATUS
3557 +FsaFibTimeoutChanged(
3558 +       IN PVOID AdapterContext,
3559 +       IN ULONG NewValue
3560 +       )
3561 +{
3562 +       //
3563 +       // scale the new timeout from seconds to 100 nsec units
3564 +       //
3565 +//     FsaCommData.AdapterTimeout = RtlConvertLongToLargeInteger(-10*1000*1000*NewValue);
3566 +
3567 +       return (STATUS_SUCCESS);
3568 +}
3569 +
3570 +#ifdef GATHER_FIB_TIMES
3571 +extern int GatherFibTimes;
3572 +#endif
3573 +
3574 +FSA_USER_VAR FsaCommUserVars[] = {
3575 +#ifdef FIB_CHECKSUMS
3576 +    { "do_fib_checksums", (PULONG)&FsaCommData.do_fib_checksums, NULL },
3577 +#endif
3578 +#ifdef GATHER_FIB_TIMES
3579 +       { "GatherFibTimes", (PULONG)&GatherFibTimes, NULL },
3580 +#endif
3581 +       { "EnableAdapterTimeouts", (PULONG)&FsaCommData.EnableAdapterTimeouts, NULL},
3582 +       { "EnableInterruptModeration", (PULONG)&FsaCommData.EnableInterruptModeration, NULL },
3583 +       { "FsaDataFibsSent", (PULONG) &FsaCommData.FibsSent, NULL },
3584 +       { "FsaDataFibRecved", (PULONG) &FsaCommData.FibRecved, NULL },
3585 +       { "HardInterruptModeration", (PULONG)&FsaCommData.HardInterruptModeration, NULL},
3586 +       { "HardInterruptModeration1", (PULONG)&FsaCommData.HardInterruptModeration1, HardInterruptModeration1Changed},
3587 +       { "EnableFibTimeoutBreak", (PULONG)&FsaCommData.EnableFibTimeoutBreak, NULL},
3588 +       { "PeakFibsConsumed", (PULONG)&FsaCommData.PeakFibsConsumed, NULL },
3589 +       { "ZeroFibsConsumed", (PULONG)&FsaCommData.ZeroFibsConsumed, NULL },
3590 +       { "FibTimeoutSeconds", (PULONG) &FsaCommData.FibTimeoutSeconds, FsaFibTimeoutChanged },
3591 +};
3592 +
3593 +#define NUM_COMM_USER_VARS     (sizeof(FsaCommUserVars) / sizeof(FSA_USER_VAR) )
3594 +
3595 +\f
3596 +AAC_STATUS
3597 +AacCommDriverEntry(
3598 +    )
3599 +
3600 +/*++
3601 +
3602 +Routine Description:
3603 +
3604 +    This is the initialization routine for the FileArray Comm layer device driver.
3605 +
3606 +Arguments:
3607 +
3608 +    DriverObject - Pointer to driver object created by the system.
3609 +
3610 +Return Value:
3611 +
3612 +    AAC_STATUS - The function value is the final status from the initialization
3613 +        operation.
3614 +
3615 +--*/
3616 +
3617 +{
3618 +    AAC_STATUS Status;
3619 +       PVOID BugCheckBuffer;
3620 +
3621 +       RtlZeroMemory( &FsaCommData, sizeof(FSA_COMM_DATA) );
3622 +
3623 +
3624 +    //
3625 +    // Load the global timeout value for the adapter timeout
3626 +    // Also init the global that enables or disables adapter timeouts
3627 +    //
3628 +
3629 +//     FsaCommData.AdapterTimeout = RtlConvertLongToLargeInteger(-10*1000*1000*180);
3630 +
3631 +       FsaCommData.FibTimeoutSeconds = 180;
3632 +
3633 +       FsaCommData.EnableAdapterTimeouts = TRUE; 
3634 +
3635 +//     FsaCommData.QueueFreeTimeout = RtlConvertLongToLargeInteger(QUEUE_ENTRY_FREE_TIMEOUT);
3636 +
3637 +#ifdef unix_fib_timeout
3638 +       FsaCommData.FibTimeoutIncrement = (180 * 1000 * 1000 * 10) / KeQueryTimeIncrement();
3639 +#endif
3640 +
3641 +       FsaCommData.EnableInterruptModeration = FALSE;
3642 +
3643 +       //
3644 +       // Preload UserVars with all variables from the comm layer.  The class layers will
3645 +       // include theirs when they register.
3646 +       //
3647 +
3648 +       FsaCommData.UserVars = OsAllocMemory(NUM_COMM_USER_VARS * sizeof(FSA_USER_VAR), OS_ALLOC_MEM_SLEEP );
3649 +       FsaCommData.NumUserVars = NUM_COMM_USER_VARS;
3650 +
3651 +       RtlCopyMemory( FsaCommData.UserVars, &FsaCommUserVars, NUM_COMM_USER_VARS * sizeof(FSA_USER_VAR) );
3652 +
3653 +
3654 +#ifdef AACDISK
3655 +       //
3656 +       // Call the disk driver to initialize itself.
3657 +       //
3658 +
3659 +       AacDiskDriverEntry();
3660 +
3661 +#endif
3662 +
3663 +
3664 +
3665 +       return (STATUS_SUCCESS);
3666 +}
3667 +
3668 +
3669 +VOID
3670 +DetachNTQueue(
3671 +       IN PAFA_COMM_ADAPTER Adapter,
3672 +    IN OUT PCOMM_QUE Queue,
3673 +    IN QUEUE_TYPES WhichQueue
3674 +    )
3675 +/*++
3676 +
3677 +Routine Description:
3678 +
3679 +       This routine will release all of the resources used by a given queue.
3680 +
3681 +Arguments:
3682 +
3683 +       Adapter - Which adapter the queue belongs to
3684 +       Queue - Pointer to the queue itself
3685 +       WhichQueue - Identifies which of the host queues this is.
3686 +
3687 +Return Value:
3688 +
3689 +       NONE.
3690 +
3691 +--*/
3692 +{
3693 +    switch (WhichQueue) {
3694 +
3695 +        case HostNormCmdQueue:
3696 +
3697 +                       Os_remove_softintr( Queue->ConsumerRoutine );
3698 +                       OsSpinLockDestroy( Queue->QueueLock );
3699 +                       OsCv_destroy( &Queue->CommandReady );
3700 +                               
3701 +            break;
3702 +
3703 +        case HostHighCmdQueue:
3704 +
3705 +                       Os_remove_softintr( Queue->ConsumerRoutine );
3706 +                       OsSpinLockDestroy( Queue->QueueLock );
3707 +                       OsCv_destroy( &Queue->CommandReady );
3708 +                               
3709 +            break;
3710 +
3711 +        case HostNormRespQueue:
3712 +
3713 +                       Os_remove_softintr( Queue->ConsumerRoutine );
3714 +                       OsSpinLockDestroy( Queue->QueueLock );
3715 +            break;
3716 +
3717 +        case HostHighRespQueue:
3718 +
3719 +                       Os_remove_softintr( Queue->ConsumerRoutine );
3720 +                       OsSpinLockDestroy( Queue->QueueLock );
3721 +            break;
3722 +
3723 +        case AdapNormCmdQueue:
3724 +        case AdapHighCmdQueue:
3725 +        case AdapNormRespQueue:
3726 +        case AdapHighRespQueue:
3727 +                       OsCv_destroy( &Queue->QueueFull );
3728 +            break;
3729 +    }
3730 +}
3731 +    
3732 +VOID
3733 +InitializeNTQueue(
3734 +       IN PAFA_COMM_ADAPTER Adapter,
3735 +    IN OUT PCOMM_QUE Queue,
3736 +    IN QUEUE_TYPES WhichQueue
3737 +    )
3738 +/*++
3739 +
3740 +Routine Description:
3741 +
3742 +    Will initialize all entries in the queue that is NT specific.
3743 +
3744 +Arguments:
3745 +
3746 +Return Value:
3747 +
3748 +    Nothing there is nothing to allocate so nothing should fail
3749 +
3750 +--*/
3751 +{
3752 +    
3753 +       Queue->NumOutstandingIos = 0;
3754 +
3755 +       //
3756 +       // Store a pointer to the adapter structure.
3757 +       //
3758 +
3759 +       Queue->Adapter = Adapter;
3760 +
3761 +       InitializeListHead( &Queue->OutstandingIoQueue );
3762 +           
3763 +    switch (WhichQueue) {
3764 +
3765 +        case HostNormCmdQueue:
3766 +
3767 +                       OsCv_init( &Queue->CommandReady);
3768 +                       OsSpinLockInit( Queue->QueueLock, Adapter->SpinLockCookie);
3769 +                       if (ddi_add_softintr( Adapter->Dip, DDI_SOFTINT_HIGH, &Queue->ConsumerRoutine, NULL,
3770 +                                                                 NULL, (PUNIX_INTR_HANDLER)HostCommandNormDpc,
3771 +                                                                 (caddr_t)Queue ) != DDI_SUCCESS) {
3772 +
3773 +                               cmn_err(CE_CONT, "OS_addr_intr failed\n");                                      
3774 +                       }                                       
3775 +
3776 +            InitializeListHead(&Queue->CommandQueue);
3777 +
3778 +            break;
3779 +
3780 +        case HostHighCmdQueue:
3781 +
3782 +                       OsCv_init( &Queue->CommandReady);
3783 +                       OsSpinLockInit( Queue->QueueLock, Adapter->SpinLockCookie);
3784 +                       if (ddi_add_softintr( Adapter->Dip, DDI_SOFTINT_HIGH, &Queue->ConsumerRoutine, NULL,
3785 +                                                                 NULL, (PUNIX_INTR_HANDLER)HostCommandHighDpc,
3786 +                                                                 (caddr_t) Queue ) != DDI_SUCCESS) {
3787 +
3788 +                               cmn_err(CE_CONT, "OS_addr_intr failed\n");                                      
3789 +                       }                                       
3790 +
3791 +            InitializeListHead(&Queue->CommandQueue);
3792 +            break;
3793 +
3794 +        case HostNormRespQueue:
3795 +
3796 +                       OsSpinLockInit( Queue->QueueLock, Adapter->SpinLockCookie);
3797 +                       if (ddi_add_softintr( Adapter->Dip, DDI_SOFTINT_HIGH, &Queue->ConsumerRoutine, NULL,
3798 +                                                                 NULL, (PUNIX_INTR_HANDLER)HostResponseNormalDpc, 
3799 +                                                                 (caddr_t) Queue ) != DDI_SUCCESS) {
3800 +
3801 +                               cmn_err(CE_CONT, "OS_addr_intr failed\n");                                      
3802 +                       }                                       
3803 +            break;
3804 +
3805 +        case HostHighRespQueue:
3806 +
3807 +
3808 +                       OsSpinLockInit( Queue->QueueLock, Adapter->SpinLockCookie);
3809 +                       if (ddi_add_softintr( Adapter->Dip, DDI_SOFTINT_HIGH, &Queue->ConsumerRoutine, NULL,
3810 +                                                                 NULL, (PUNIX_INTR_HANDLER)HostResponseHighDpc, 
3811 +                                                                 (caddr_t) Queue ) != DDI_SUCCESS) {
3812 +
3813 +                               cmn_err(CE_CONT, "OS_addr_intr failed\n");                                      
3814 +                       }                                       
3815 +            break;
3816 +
3817 +        case AdapNormCmdQueue:
3818 +        case AdapHighCmdQueue:
3819 +        case AdapNormRespQueue:
3820 +        case AdapHighRespQueue:
3821 +
3822 +                       OsCv_init( &Queue->QueueFull);
3823 +            break;
3824 +    }
3825 +}
3826 +
3827 +BOOLEAN
3828 +StartFsaCommandThreads(PAFA_COMM_ADAPTER Adapter)
3829 +/*++
3830 +
3831 +Routine Description:
3832 +
3833 +    Create and start the command receiver threads.
3834 +
3835 +Arguments:
3836 +
3837 +
3838 +Return Value:
3839 +
3840 +    Nothing
3841 +
3842 +--*/
3843 +
3844 +{
3845 +    return(TRUE);
3846 +}
3847 +
3848 +
3849 +
3850 +/*++
3851 +
3852 +Routine Description:
3853 +
3854 +       This routine gets called to detach all resources that have been allocated for 
3855 +       this adapter.
3856 +
3857 +Arguments:
3858 +
3859 +       Adapter - Pointer to the adapter structure to detach.
3860 +
3861 +Return Value:
3862 +
3863 +    TRUE - All resources have been properly released.
3864 +    FALSE - An error occured while trying to release resources.
3865 +--*/
3866 +BOOLEAN
3867 +AacCommDetachAdapter (IN PAFA_COMM_ADAPTER     Adapter)
3868 +{
3869 +       PAFA_CLASS_DRIVER ClassDriver;
3870 +       //
3871 +       // First remove this adapter from the list of adapters.
3872 +       //
3873 +
3874 +       if (FsaCommData.AdapterList == Adapter) {
3875 +               
3876 +               FsaCommData.AdapterList = Adapter->NextAdapter;
3877 +
3878 +       } else {
3879 +
3880 +               PAFA_COMM_ADAPTER CurrentAdapter, NextAdapter;
3881 +       
3882 +               CurrentAdapter = FsaCommData.AdapterList;
3883 +               NextAdapter = CurrentAdapter->NextAdapter;
3884 +
3885 +               while (NextAdapter) {
3886 +                               
3887 +                       if (NextAdapter == Adapter) {
3888 +
3889 +                               CurrentAdapter->NextAdapter = NextAdapter->NextAdapter;
3890 +                               break;
3891 +                        
3892 +                       }
3893 +                       
3894 +                       CurrentAdapter = NextAdapter;
3895 +                       NextAdapter = CurrentAdapter->NextAdapter;
3896 +               }
3897 +       }                       
3898 +               
3899 +       //
3900 +       // First send a shutdown to the adapter.
3901 +       //
3902 +
3903 +       AfaCommShutdown( Adapter );
3904 +
3905 +       //
3906 +       // Destroy the FibContextZone for this adapter.  This will free up all
3907 +       // of the fib space used by this adapter.
3908 +       //
3909 +       
3910 +       FsaFreeFibContextZone( Adapter );
3911 +
3912 +       //
3913 +       // Destroy the mutex used for synch'ing adapter fibs.
3914 +       //
3915 +
3916 +       OsCvLockDestroy( Adapter->AdapterFibMutex );
3917 +
3918 +       //
3919 +       // Detach all of the host queues.
3920 +       //
3921 +
3922 +    DetachNTQueue( Adapter, &Adapter->CommRegion->AdapHighRespQue, AdapHighRespQueue );
3923 +    DetachNTQueue( Adapter, &Adapter->CommRegion->AdapNormRespQue, AdapNormRespQueue );
3924 +    DetachNTQueue( Adapter, &Adapter->CommRegion->HostHighRespQue, HostHighRespQueue );
3925 +    DetachNTQueue( Adapter, &Adapter->CommRegion->HostNormRespQue, HostNormRespQueue );
3926 +    DetachNTQueue( Adapter, &Adapter->CommRegion->AdapHighCmdQue, AdapHighCmdQueue );
3927 +    DetachNTQueue( Adapter, &Adapter->CommRegion->AdapNormCmdQue, AdapNormCmdQueue );
3928 +    DetachNTQueue( Adapter, &Adapter->CommRegion->HostHighCmdQue, HostHighCmdQueue );
3929 +       DetachNTQueue( Adapter, &Adapter->CommRegion->HostNormCmdQue, HostNormCmdQueue );
3930 +
3931 +       //
3932 +       // Destroy the mutex used to protect the FibContextZone
3933 +       //
3934 +
3935 +       OsSpinLockDestroy( Adapter->FibContextZoneSpinLock );
3936 +
3937 +       //
3938 +       // Call the miniport to free the space allocated for the shared comm queues
3939 +       // between the host and the adapter.
3940 +       //
3941 +
3942 +       FsaFreeAdapterCommArea( Adapter );
3943 +
3944 +       //
3945 +       // Free the memory used by the comm region for this adapter
3946 +       //
3947 +
3948 +       OsFreeMemory( Adapter->CommRegion, sizeof(COMM_REGION) );
3949 +
3950 +       //
3951 +       // Free the memory used by the adapter structure.
3952 +       //
3953 +       ClassDriver = Adapter->ClassDriverList;
3954 +       Adapter->ClassDriverList = Adapter->ClassDriverList->Next;
3955 +       OsFreeMemory( ClassDriver, sizeof(AFA_CLASS_DRIVER) );
3956 +       
3957 +       OsFreeMemory( Adapter, sizeof(AFA_COMM_ADAPTER) );
3958 +
3959 +       return (TRUE);
3960 +}
3961 +
3962 +PVOID
3963 +AfaCommInitNewAdapter (IN PFSA_NEW_ADAPTER NewAdapter)
3964 +{
3965 +       PVOID BugCheckBuffer;
3966 +       PAFA_COMM_ADAPTER Adapter;
3967 +       MAPFIB_CONTEXT MapFibContext;
3968 +       LARGE_INTEGER Time;
3969 +       char ErrorBuffer[60];
3970 +
3971 +       Adapter = (PAFA_COMM_ADAPTER) OsAllocMemory( sizeof(AFA_COMM_ADAPTER) , OS_ALLOC_MEM_SLEEP );
3972 +
3973 +       if (Adapter == NULL)
3974 +               return (NULL);
3975 +
3976 +       RtlZeroMemory(Adapter, sizeof(AFA_COMM_ADAPTER));
3977 +
3978 +
3979 +       //
3980 +       // Save the current adapter number and increment the total number.
3981 +       //
3982 +
3983 +       Adapter->AdapterNumber = FsaCommData.TotalAdapters++;
3984 +
3985 +
3986 +       //
3987 +       // Fill in the pointer back to the device specific structures.
3988 +       // The device specific driver has also passed a pointer for us to 
3989 +       // fill in with the Adapter object that we have created.
3990 +       //
3991 +
3992 +       Adapter->AdapterExtension = NewAdapter->AdapterExtension;
3993 +       Adapter->AdapterFuncs = NewAdapter->AdapterFuncs;
3994 +       Adapter->InterruptsBelowDpc = NewAdapter->AdapterInterruptsBelowDpc;
3995 +       Adapter->AdapterUserVars = NewAdapter->AdapterUserVars;
3996 +       Adapter->AdapterUserVarsSize = NewAdapter->AdapterUserVarsSize;
3997 +
3998 +       Adapter->Dip = NewAdapter->Dip;
3999 +
4000 +       //
4001 +       // Fill in Our address into the function dispatch table
4002 +       //
4003 +
4004 +       NewAdapter->AdapterFuncs->InterruptHost = AfaCommInterruptHost;
4005 +       NewAdapter->AdapterFuncs->OpenAdapter = AfaCommOpenAdapter;
4006 +       NewAdapter->AdapterFuncs->CloseAdapter = AfaCommCloseAdapter;
4007 +       NewAdapter->AdapterFuncs->DeviceControl = AfaCommAdapterDeviceControl;
4008 +
4009 +       //
4010 +       // Ok now init the communication subsystem
4011 +       //
4012 +
4013 +       Adapter->CommRegion = (PCOMM_REGION) OsAllocMemory(sizeof(COMM_REGION), OS_ALLOC_MEM_SLEEP);
4014 +       if (Adapter->CommRegion == NULL) {
4015 +               cmn_err(CE_WARN, "Error could not allocate comm region.\n");
4016 +               return (NULL);
4017 +       }
4018 +       RtlZeroMemory(Adapter->CommRegion, sizeof(COMM_REGION));
4019 +
4020 +       //
4021 +       // Get a pointer to the iblock_cookie
4022 +       //
4023 +
4024 +       ddi_get_soft_iblock_cookie( Adapter->Dip, DDI_SOFTINT_HIGH, &Adapter->SpinLockCookie );
4025 +
4026 +       if (!CommInit(Adapter)) {
4027 +               FsaCommPrint("Failed to init the commuication subsystem.\n");
4028 +               return(NULL);
4029 +       }
4030 +
4031 +
4032 +       //
4033 +       // Initialize the list of AdapterFibContext's.
4034 +       //
4035 +
4036 +       InitializeListHead(&Adapter->AdapterFibContextList);
4037 +
4038 +       //
4039 +       // Initialize the fast mutex used for synchronization of the adapter fibs
4040 +       //
4041 +
4042 +       Adapter->AdapterFibMutex = OsCvLockAlloc();
4043 +       OsCvLockInit(Adapter->AdapterFibMutex, NULL);
4044 +
4045 +    //
4046 +    // Allocate and start the FSA command threads. These threads will handle
4047 +    // command requests from the adapter. They will wait on an event then pull
4048 +    // all CDBs off the thread's queue. Each CDB will be given to a worker thread
4049 +    // upto a defined limit. When that limit is reached wait a event will be waited
4050 +    // on till a worker thread is finished.
4051 +    //
4052 +
4053 +    if (!StartFsaCommandThreads(Adapter)) {
4054 +           FsaCommPrint("Fsainit could not initilize the command receiver threads.\n");
4055 +               return (NULL);
4056 +    }
4057 +
4058 +#ifdef unix_crash_dump
4059 +       //
4060 +       // Allocate and map a fib for use by the synch path, which is used for crash
4061 +       // dumps.
4062 +       //
4063 +       // Allocate an entire page so that alignment is correct.
4064 +       //
4065 +
4066 +       Adapter->SyncFib = OsAllocMemory( PAGE_SIZE, OS_ALLOC_MEM_SLEEP );
4067 +       MapFibContext.Fib = Adapter->SyncFib;
4068 +       MapFibContext.Size = sizeof(FIB);
4069 +       MapFib( Adapter, &MapFibContext );
4070 +       Adapter->SyncFibPhysicalAddress = MapFibContext.LogicalFibAddress.LowPart;
4071 +#endif
4072 +
4073 +       Adapter->CommFuncs.SizeOfAfaCommFuncs = sizeof(AFACOMM_FUNCS);
4074 +
4075 +       Adapter->CommFuncs.AllocateFib = AllocateFib;
4076 +
4077 +       Adapter->CommFuncs.FreeFib = FreeFib;
4078 +       Adapter->CommFuncs.FreeFibFromDpc = FreeFibFromDpc;
4079 +       Adapter->CommFuncs.DeallocateFib = DeallocateFib;
4080 +
4081 +       Adapter->CommFuncs.InitializeFib = InitializeFib;
4082 +       Adapter->CommFuncs.GetFibData = FsaGetFibData;
4083 +       Adapter->CommFuncs.SendFib = SendFib;
4084 +       Adapter->CommFuncs.CompleteFib = CompleteFib;
4085 +       Adapter->CommFuncs.CompleteAdapterFib = CompleteAdapterFib;
4086 +
4087 +       Adapter->CommFuncs.SendSynchFib = SendSynchFib;
4088 +
4089 +       Adapter->CommFuncs.FreeDmaResources = Adapter->AdapterFuncs->FreeDmaResources;
4090 +       Adapter->CommFuncs.BuildSgMap = Adapter->AdapterFuncs->BuildSgMap;
4091 +
4092 +       //
4093 +       // Add this adapter in to our Adapter List.
4094 +       //
4095 +
4096 +       Adapter->NextAdapter = FsaCommData.AdapterList;
4097 +       FsaCommData.AdapterList = Adapter;
4098 +
4099 +       NewAdapter->Adapter = Adapter;
4100 +
4101 +//     AfaDiskInitNewAdapter( Adapter->AdapterNumber, Adapter );
4102 +
4103 +       return (Adapter);
4104 +}
4105 +
4106 +AAC_STATUS
4107 +CommInitialize(
4108 +       PAFA_COMM_ADAPTER Adapter
4109 +       )
4110 +{
4111 +    //
4112 +    //  Now allocate and initialize the zone structures used as our pool
4113 +    //  of FIB context records.  The size of the zone is based on the
4114 +    //  system memory size.  We also initialize the mutex used to protect
4115 +    //  the zone.
4116 +    //
4117 +       Adapter->FibContextZoneSpinLock = OsSpinLockAlloc();
4118 +       OsSpinLockInit( Adapter->FibContextZoneSpinLock, Adapter->SpinLockCookie );
4119 +
4120 +       Adapter->FibContextZoneExtendSize = 64;
4121 +
4122 +       return (STATUS_SUCCESS);
4123 +}
4124 +
4125 +
4126 +    
4127 +/*++
4128 +
4129 +Routine Description:
4130 +
4131 +    Initializes the data structures that are required for the FSA commuication
4132 +    interface to operate.
4133 +
4134 +Arguments:
4135 +
4136 +    None - all global or allocated data.
4137 +
4138 +Return Value:
4139 +
4140 +    TRUE - if we were able to init the commuication interface.
4141 +    FALSE - If there were errors initing. This is a fatal error.
4142 +--*/
4143 +BOOLEAN
4144 +CommInit(PAFA_COMM_ADAPTER Adapter)
4145 +{
4146 +    
4147 +    ULONG SizeOfHeaders = (sizeof(QUEUE_INDEX) * NUMBER_OF_COMM_QUEUES) * 2;
4148 +    ULONG SizeOfQueues = sizeof(QUEUE_ENTRY) * TOTAL_QUEUE_ENTRIES;
4149 +    PQUEUE_INDEX Headers;
4150 +    PQUEUE_ENTRY Queues;
4151 +       ULONG TotalSize;
4152 +       PCOMM_REGION CommRegion = Adapter->CommRegion;
4153 +
4154 +        CommInitialize( Adapter );
4155 +
4156 +       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",
4157 +                         sizeof(QUEUE_ENTRY), sizeof(QUEUE_INDEX), TOTAL_QUEUE_ENTRIES, NUMBER_OF_COMM_QUEUES);
4158 +       //
4159 +       //
4160 +       // Allocate the physically contigous space for the commuication queue
4161 +       // headers. 
4162 +       //
4163 +
4164 +       TotalSize = SizeOfHeaders + SizeOfQueues;
4165 +
4166 +       if (!FsaAllocateAdapterCommArea(Adapter, (PVOID *)&Headers, TotalSize, QUEUE_ALIGNMENT))
4167 +               return (FALSE);
4168 +
4169 +       Queues = (PQUEUE_ENTRY)((PUCHAR)Headers + SizeOfHeaders);
4170 +
4171 +       if (ddi_add_softintr( Adapter->Dip, DDI_SOFTINT_HIGH, &CommRegion->QueueNotFullDpc, NULL,
4172 +                                                 NULL, (PUNIX_INTR_HANDLER)CommonNotFullDpc,
4173 +                                                 (caddr_t)CommRegion ) != DDI_SUCCESS) {
4174 +
4175 +         cmn_err(CE_CONT, "Os_addr_intr failed\n");                                    
4176 +       }                                       
4177 +
4178 +
4179 +    // Adapter to Host normal priority Command queue
4180 +
4181 +
4182 +    CommRegion->HostNormCmdQue.Headers.ProducerIndex = Headers++;
4183 +    CommRegion->HostNormCmdQue.Headers.ConsumerIndex = Headers++;
4184 +    *CommRegion->HostNormCmdQue.Headers.ProducerIndex = HOST_NORM_CMD_ENTRIES;
4185 +    *CommRegion->HostNormCmdQue.Headers.ConsumerIndex = HOST_NORM_CMD_ENTRIES;
4186 +
4187 +    CommRegion->HostNormCmdQue.SavedIrql = 0;
4188 +    CommRegion->HostNormCmdQue.BaseAddress = Queues;
4189 +    CommRegion->HostNormCmdQue.QueueEntries = HOST_NORM_CMD_ENTRIES;
4190 +
4191 +       CommRegion->HostNormCmdQue.QueueLock = OsSpinLockAlloc();
4192 +       if (CommRegion->HostNormCmdQue.QueueLock == NULL) {
4193 +               return (FALSE);
4194 +       }
4195 +    InitializeNTQueue(Adapter, &CommRegion->HostNormCmdQue, HostNormCmdQueue);
4196 +
4197 +    
4198 +    Queues += HOST_NORM_CMD_ENTRIES;
4199 +
4200 +    // Adapter to Host high priority command queue
4201 +    
4202 +    CommRegion->HostHighCmdQue.Headers.ProducerIndex = Headers++;
4203 +    CommRegion->HostHighCmdQue.Headers.ConsumerIndex = Headers++;
4204 +    *CommRegion->HostHighCmdQue.Headers.ProducerIndex = HOST_HIGH_CMD_ENTRIES;
4205 +    *CommRegion->HostHighCmdQue.Headers.ConsumerIndex = HOST_HIGH_CMD_ENTRIES;
4206 +
4207 +    CommRegion->HostHighCmdQue.SavedIrql = 0;
4208 +    CommRegion->HostHighCmdQue.BaseAddress = Queues;
4209 +    CommRegion->HostHighCmdQue.QueueEntries = HOST_HIGH_CMD_ENTRIES;
4210 +//     CommRegion->HostHighCmdQue.QueueLock = (PKSPIN_LOCK) ExAllocatePool(NonPagedPool, sizeof(KSPIN_LOCK));
4211 +       CommRegion->HostHighCmdQue.QueueLock = OsSpinLockAlloc();
4212 +       if (CommRegion->HostHighCmdQue.QueueLock == NULL) {
4213 +               return (FALSE);
4214 +       }
4215 +    InitializeNTQueue(Adapter, &CommRegion->HostHighCmdQue, HostHighCmdQueue);
4216 +    
4217 +    Queues += HOST_HIGH_CMD_ENTRIES;
4218 +
4219 +    // Host to adapter normal priority command queue
4220 +    
4221 +    CommRegion->AdapNormCmdQue.Headers.ProducerIndex = Headers++;
4222 +    CommRegion->AdapNormCmdQue.Headers.ConsumerIndex = Headers++;
4223 +    *CommRegion->AdapNormCmdQue.Headers.ProducerIndex = ADAP_NORM_CMD_ENTRIES;
4224 +    *CommRegion->AdapNormCmdQue.Headers.ConsumerIndex = ADAP_NORM_CMD_ENTRIES;
4225 +
4226 +    CommRegion->AdapNormCmdQue.SavedIrql = 0;    
4227 +    CommRegion->AdapNormCmdQue.BaseAddress = Queues;
4228 +    CommRegion->AdapNormCmdQue.QueueEntries = ADAP_NORM_CMD_ENTRIES;
4229 +    InitializeNTQueue(Adapter, &CommRegion->AdapNormCmdQue, AdapNormCmdQueue);
4230 +    
4231 +    Queues += ADAP_NORM_CMD_ENTRIES;
4232 +
4233 +    // host to adapter high priority command queue
4234 +    
4235 +    CommRegion->AdapHighCmdQue.Headers.ProducerIndex = Headers++;
4236 +    CommRegion->AdapHighCmdQue.Headers.ConsumerIndex = Headers++;
4237 +    *CommRegion->AdapHighCmdQue.Headers.ProducerIndex = ADAP_HIGH_CMD_ENTRIES;
4238 +    *CommRegion->AdapHighCmdQue.Headers.ConsumerIndex = ADAP_HIGH_CMD_ENTRIES;
4239 +
4240 +    CommRegion->AdapHighCmdQue.SavedIrql = 0;    
4241 +    CommRegion->AdapHighCmdQue.BaseAddress = Queues;
4242 +    CommRegion->AdapHighCmdQue.QueueEntries = ADAP_HIGH_CMD_ENTRIES;
4243 +    InitializeNTQueue(Adapter, &CommRegion->AdapHighCmdQue, AdapHighCmdQueue);
4244 +    
4245 +    Queues += ADAP_HIGH_CMD_ENTRIES;
4246 +
4247 +    // adapter to host normal priority response queue
4248 +    
4249 +    CommRegion->HostNormRespQue.Headers.ProducerIndex = Headers++;
4250 +    CommRegion->HostNormRespQue.Headers.ConsumerIndex = Headers++;
4251 +    *CommRegion->HostNormRespQue.Headers.ProducerIndex = HOST_NORM_RESP_ENTRIES;
4252 +    *CommRegion->HostNormRespQue.Headers.ConsumerIndex = HOST_NORM_RESP_ENTRIES;
4253 +
4254 +    CommRegion->HostNormRespQue.SavedIrql = 0;    
4255 +    CommRegion->HostNormRespQue.BaseAddress = Queues;
4256 +    CommRegion->HostNormRespQue.QueueEntries = HOST_NORM_RESP_ENTRIES;
4257 +//     CommRegion->HostNormRespQue.QueueLock = (PKSPIN_LOCK) ExAllocatePool(NonPagedPool, sizeof(KSPIN_LOCK));
4258 +       CommRegion->HostNormRespQue.QueueLock = OsSpinLockAlloc();
4259 +       if (CommRegion->HostNormRespQue.QueueLock == NULL) {
4260 +               return (FALSE);
4261 +       }
4262 +    InitializeNTQueue(Adapter, &CommRegion->HostNormRespQue, HostNormRespQueue);
4263 +    
4264 +    Queues += HOST_NORM_RESP_ENTRIES;
4265 +
4266 +    // adapter to host high priority response queue
4267 +    
4268 +    CommRegion->HostHighRespQue.Headers.ProducerIndex = Headers++;
4269 +    CommRegion->HostHighRespQue.Headers.ConsumerIndex = Headers++;
4270 +    *CommRegion->HostHighRespQue.Headers.ProducerIndex = HOST_HIGH_RESP_ENTRIES;
4271 +    *CommRegion->HostHighRespQue.Headers.ConsumerIndex = HOST_HIGH_RESP_ENTRIES;
4272 +
4273 +    CommRegion->HostHighRespQue.SavedIrql = 0;    
4274 +    CommRegion->HostHighRespQue.BaseAddress = Queues;
4275 +    CommRegion->HostHighRespQue.QueueEntries = HOST_HIGH_RESP_ENTRIES;
4276 +//     CommRegion->HostHighRespQue.QueueLock = (PKSPIN_LOCK) ExAllocatePool(NonPagedPool, sizeof(KSPIN_LOCK));
4277 +       CommRegion->HostHighRespQue.QueueLock = OsSpinLockAlloc();
4278 +       if (CommRegion->HostHighRespQue.QueueLock == NULL) {
4279 +               return (FALSE);
4280 +       }
4281 +    InitializeNTQueue(Adapter, &CommRegion->HostHighRespQue, HostHighRespQueue);
4282 +    
4283 +    Queues += HOST_HIGH_RESP_ENTRIES;
4284 +
4285 +    // host to adapter normal priority response queue
4286 +    
4287 +    CommRegion->AdapNormRespQue.Headers.ProducerIndex = Headers++;
4288 +    CommRegion->AdapNormRespQue.Headers.ConsumerIndex = Headers++;
4289 +    *CommRegion->AdapNormRespQue.Headers.ProducerIndex = ADAP_NORM_RESP_ENTRIES;
4290 +    *CommRegion->AdapNormRespQue.Headers.ConsumerIndex = ADAP_NORM_RESP_ENTRIES;
4291 +
4292 +    CommRegion->AdapNormRespQue.SavedIrql = 0;    
4293 +    CommRegion->AdapNormRespQue.BaseAddress = Queues;
4294 +    CommRegion->AdapNormRespQue.QueueEntries = ADAP_NORM_RESP_ENTRIES;
4295 +    InitializeNTQueue(Adapter, &CommRegion->AdapNormRespQue, AdapNormRespQueue);
4296 +    
4297 +    Queues += ADAP_NORM_RESP_ENTRIES;
4298 +
4299 +    // host to adapter high priority response queue
4300 +    
4301 +    CommRegion->AdapHighRespQue.Headers.ProducerIndex = Headers++;
4302 +    CommRegion->AdapHighRespQue.Headers.ConsumerIndex = Headers++;
4303 +    *CommRegion->AdapHighRespQue.Headers.ProducerIndex = ADAP_HIGH_RESP_ENTRIES;
4304 +    *CommRegion->AdapHighRespQue.Headers.ConsumerIndex = ADAP_HIGH_RESP_ENTRIES;
4305 +
4306 +    CommRegion->AdapHighRespQue.SavedIrql = 0;    
4307 +    CommRegion->AdapHighRespQue.BaseAddress = Queues;
4308 +    CommRegion->AdapHighRespQue.QueueEntries = ADAP_HIGH_RESP_ENTRIES;
4309 +    InitializeNTQueue(Adapter, &CommRegion->AdapHighRespQue, AdapHighRespQueue);
4310 +
4311 +       CommRegion->AdapNormCmdQue.QueueLock = CommRegion->HostNormRespQue.QueueLock;
4312 +       CommRegion->AdapHighCmdQue.QueueLock = CommRegion->HostHighRespQue.QueueLock;
4313 +       CommRegion->AdapNormRespQue.QueueLock = CommRegion->HostNormCmdQue.QueueLock;
4314 +       CommRegion->AdapHighRespQue.QueueLock = CommRegion->HostHighCmdQue.QueueLock;
4315 +
4316 +    return(TRUE);
4317 +}
4318 +
4319 +AAC_STATUS
4320 +AfaCommShutdown(
4321 +       PAFA_COMM_ADAPTER Adapter
4322 +       )
4323 +/*++
4324 +
4325 +Routine Description:
4326 +
4327 +       This routine will send a shutdown request to each adapter.
4328 +
4329 +Arguments:
4330 +
4331 +       Adapter - which adapter to send the shutdown to.
4332 +
4333 +Return Value:
4334 +
4335 +    NT Status success.
4336 +
4337 +--*/
4338 +
4339 +{
4340 +       PFIB_CONTEXT FibContext;
4341 +       PCLOSECOMMAND CloseCommand;
4342 +       AAC_STATUS Status;
4343 +
4344 +       FibContext = AllocateFib( Adapter );
4345 +
4346 +       InitializeFib( FibContext );
4347 +
4348 +       CloseCommand = (PCLOSECOMMAND) FsaGetFibData( FibContext );
4349 +
4350 +       CloseCommand->Command = VM_CloseAll;
4351 +       CloseCommand->ContainerId = 0xffffffff;
4352 +
4353 +       Status = SendFib( ContainerCommand, FibContext, sizeof(CLOSECOMMAND), FsaNormal, TRUE, NULL, TRUE, NULL, NULL );
4354 +
4355 +       if (Status != STATUS_SUCCESS) {
4356 +
4357 +               FreeFib( FibContext );
4358 +
4359 +               goto ret;
4360 +
4361 +       }
4362 +
4363 +       CompleteFib( FibContext );
4364 +
4365 +       FreeFib( FibContext );
4366 +
4367 +
4368 +       Status = STATUS_SUCCESS;
4369 +
4370 +ret:
4371 +
4372 +       return (Status);
4373 +
4374 +}
4375 +
4376 +VOID
4377 +AfaCommBugcheckHandler(
4378 +               IN PVOID Buffer,
4379 +               IN ULONG Length
4380 +               )
4381 +/*++
4382 +
4383 +Routine Description:
4384 +
4385 +       This routine will shutdown the adapter if there is a bugcheck and
4386 +       copy the shutdown data from the adapter response into the buffer
4387 +       so it will show up in the host dump file.
4388 +p
4389 +Arguments:
4390 +
4391 +       Buffer - This buffer will be written to the host dump by nt for us.
4392 +
4393 +       Length - The size of the buffer.
4394 +
4395 +Return Value:
4396 +
4397 +       N/A
4398 +
4399 +--*/
4400 +{
4401 +       PAFA_COMM_ADAPTER Adapter = FsaCommData.AdapterList;
4402 +
4403 +       while (Adapter) {
4404 +
4405 +               NotifyAdapter(Adapter, HostShutdown);
4406 +
4407 +               Adapter = Adapter->NextAdapter;
4408 +
4409 +       }
4410 +
4411 +}      
4412 +
4413 +VOID
4414 +FsaCommLogEvent(
4415 +       PFIB_CONTEXT FibContext, 
4416 +       PDEVICE_OBJECT DeviceObject,
4417 +       AAC_STATUS FsaStatus,
4418 +       AAC_STATUS AacStatus,
4419 +       ULONG LocationCode,
4420 +       USHORT Category,
4421 +       PUCHAR String,
4422 +       BOOLEAN DumpFib
4423 +)
4424 +{
4425 +}
4426 +
4427 +AfaCommProbeDisks(
4428 +       PAFA_COMM_ADAPTER       Adapter
4429 +       )
4430 +{
4431 +    PMNTINFO DiskInfo;
4432 +    PMNTINFORESPONSE DiskInfoResponse;
4433 +       AAC_STATUS Status;
4434 +       PCOMM_FIB_CONTEXT FibContext;
4435 +    
4436 +       FibContext = AllocateFib( Adapter );
4437 +
4438 +       InitializeFib( FibContext );
4439 +
4440 +       DiskInfo = (PMNTINFO) FibContext->Fib->data;
4441 +       DiskInfo->Command = VM_NameServe;
4442 +       DiskInfo->MntCount = 0;
4443 +       DiskInfo->MntType = FT_FILESYS;
4444 +
4445 +    Status = SendFib(ContainerCommand,
4446 +                            FibContext,
4447 +                        sizeof(MNTINFO),
4448 +                        FsaNormal,
4449 +                        TRUE,
4450 +                        NULL,
4451 +                        TRUE,
4452 +                        NULL,
4453 +                        NULL);
4454 +
4455 +       DiskInfoResponse = (PMNTINFORESPONSE) FibContext->Fib->data;
4456 +
4457 +       if (DiskInfoResponse->MntRespCount) {
4458 +
4459 +               cmn_err(CE_CONT, "container found on adapter, size = 0x%x blocks\n", 
4460 +                               DiskInfoResponse->MntTable[0].Capacity);
4461 +                               
4462 +       } else {
4463 +       
4464 +               cmn_err(CE_CONT, "no containers found on adapter\n");
4465 +               
4466 +       }
4467 +                                       
4468 +       CompleteFib( FibContext );
4469 +       
4470 +       FreeFib( FibContext );                           
4471 +}
4472 +
4473 +
4474 diff -burN linux-2.4.9/drivers/scsi/aacraid/commsup.c linux/drivers/scsi/aacraid/commsup.c
4475 --- linux-2.4.9/drivers/scsi/aacraid/commsup.c  Wed Dec 31 18:00:00 1969
4476 +++ linux/drivers/scsi/aacraid/commsup.c        Thu Aug 16 13:41:30 2001
4477 @@ -0,0 +1,2185 @@
4478 +/*++
4479 + * Adaptec aacraid device driver for Linux.
4480 + *
4481 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
4482 + *
4483 + * This program is free software; you can redistribute it and/or modify
4484 + * it under the terms of the GNU General Public License as published by
4485 + * the Free Software Foundation; either version 2, or (at your option)
4486 + * any later version.
4487 + *
4488 + * This program is distributed in the hope that it will be useful,
4489 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
4490 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
4491 + * GNU General Public License for more details.
4492 + *
4493 + * You should have received a copy of the GNU General Public License
4494 + * along with this program; see the file COPYING.  If not, write to
4495 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
4496 + *
4497 + * Module Name:
4498 + *  commsup.c
4499 + *
4500 + * Abstract: Contain all routines that are required for FSA host/adapter
4501 + *    commuication.
4502 + *
4503 + *
4504 + --*/
4505 +
4506 +static char *ident_commsup = "aacraid_ident commsup.c 1.0.7 2000/10/11 Adaptec, Inc.";
4507 +
4508 +#include "comprocs.h"
4509 +
4510 +#define BugCheckFileId                   (FSAFS_BUG_CHECK_COMMSUP)
4511 +
4512 +int CommPrinting;
4513 +
4514 +void
4515 +ThrottleExceptionHandler(
4516 +       IN PCOMM_REGION CommRegion,
4517 +       AAC_STATUS              Status
4518 +       );
4519 +
4520 +void ThrottlePeriodEndDpcRtn(
4521 +    IN PKDPC Dpc,
4522 +    IN PVOID DeferredContext,
4523 +    IN PVOID SystemArgument1,
4524 +    IN PVOID SystemArgument2
4525 +    );
4526 +
4527 +
4528 +/*++
4529 +
4530 +Routine Description:
4531 +
4532 +       This routine will free all resources used by a given FibContextSegment.
4533 +
4534 +Arguments:
4535 +
4536 +       Adapter - The adapter that this COMM_FIB_CONTEXT will communicate with.
4537 +       ZoneSegment - The segment to release resources from.
4538 +
4539 +Return Value:
4540 +
4541 +       TRUE - All resources were properly freed.
4542 +       FALSE - An Error occured while freeing resources.
4543 +
4544 +--*/
4545 +BOOLEAN
4546 +FsaFreeFibContextSegment (PAFA_COMM_ADAPTER Adapter,
4547 +                                                 PFIB_CONTEXT_ZONE_SEGMENT     ZoneSegment)
4548 +{
4549 +       PCOMM_FIB_CONTEXT FibContext;
4550 +       int i;
4551 +       
4552 +       // Account for the ZONE_SEGMENT_HEADER before the first actual FibContext.
4553 +
4554 +       for (i = 0, FibContext = (PCOMM_FIB_CONTEXT)((PUCHAR)ZoneSegment->FibContextSegment + sizeof(ZONE_SEGMENT_HEADER));
4555 +                i < ZoneSegment->ExtendSize; i++, FibContext++) {
4556 +
4557 +               OsCvLockDestroy( FibContext->FsaEventMutex );
4558 +               OsCv_destroy( &FibContext->FsaEvent );
4559 +
4560 +       }
4561 +
4562 +       UnmapAndFreeFibSpace( Adapter, &ZoneSegment->MapFibContext );
4563 +
4564 +       OsFreeMemory( ZoneSegment->FibContextSegment, ZoneSegment->FibContextSegmentSize );
4565 +
4566 +       OsFreeMemory( ZoneSegment, sizeof( FIB_CONTEXT_ZONE_SEGMENT ) );
4567 +
4568 +       return (TRUE);
4569 +}
4570 +
4571 +BOOLEAN
4572 +FsaFreeFibContextZone(
4573 +       PAFA_COMM_ADAPTER Adapter
4574 +       )
4575 +/*++
4576 +
4577 +Routine Description:
4578 +
4579 +       This routine will walk through the FibContextSegmentList and free up all
4580 +       resources used by the FibContextZone.
4581 +
4582 +Arguments:
4583 +
4584 +       Adapter - The adapter that this COMM_FIB_CONTEXT will communicate with.
4585 +
4586 +Return Value:
4587 +
4588 +       TRUE - All resources were properly freed.
4589 +       FALSE - An Error occured while freeing resources.
4590 +
4591 +--*/
4592 +
4593 +{
4594 +       PFIB_CONTEXT_ZONE_SEGMENT ZoneSegment, NextZoneSegment;
4595 +
4596 +       ZoneSegment = Adapter->FibContextSegmentList;
4597 +
4598 +       while (ZoneSegment) {
4599 +
4600 +               NextZoneSegment = ZoneSegment->Next;
4601 +
4602 +               FsaFreeFibContextSegment( Adapter, ZoneSegment );
4603 +
4604 +               ZoneSegment = NextZoneSegment;
4605 +       }
4606 +
4607 +       return (TRUE);
4608 +}
4609 +
4610 +       
4611 +
4612 +BOOLEAN
4613 +FsaExtendFibContextZone (IN PAFA_COMM_ADAPTER Adapter)
4614 +{
4615 +    int ExtendSize;
4616 +    KIRQL SavedIrql;
4617 +       ULONG ZoneSegmentAllocSize, FibAllocSize;
4618 +       PVOID FibContextSegment;
4619 +       PCOMM_FIB_CONTEXT FibContext;
4620 +       PFIB Fib;
4621 +       PVOID FibPhysicalAddress;
4622 +       int i;
4623 +       PFIB_CONTEXT_ZONE_SEGMENT ZoneSegment;
4624 +       
4625 +       //
4626 +       // Allocate space to describe this zone segment.
4627 +       //
4628 +
4629 +       cmn_err (CE_DEBUG, "Entered FsaExtendFibContextZone");
4630 +       ZoneSegment = OsAllocMemory( sizeof( FIB_CONTEXT_ZONE_SEGMENT ), OS_ALLOC_MEM_SLEEP );
4631 +       if (ZoneSegment == NULL) {
4632 +               return (FALSE);
4633 +       }
4634 +
4635 +       ExtendSize = Adapter->FibContextZoneExtendSize;
4636 +       ZoneSegmentAllocSize = (ExtendSize * sizeof(COMM_FIB_CONTEXT)) + sizeof(ZONE_SEGMENT_HEADER);
4637 +
4638 +       FibContextSegment = OsAllocMemory( ZoneSegmentAllocSize, OS_ALLOC_MEM_SLEEP );
4639 +
4640 +       if (FibContextSegment == NULL) {
4641 +               OsFreeMemory(ZoneSegment);
4642 +               return (FALSE);
4643 +       }       
4644 +
4645 +       RtlZeroMemory( FibContextSegment, ZoneSegmentAllocSize );
4646 +
4647 +       ZoneSegment->FibContextSegment = FibContextSegment;
4648 +       ZoneSegment->FibContextSegmentSize = ZoneSegmentAllocSize;
4649 +       ZoneSegment->ExtendSize = ExtendSize;
4650 +
4651 +       FibAllocSize = ExtendSize * sizeof(FIB);
4652 +
4653 +
4654 +       ZoneSegment->MapFibContext.Size = FibAllocSize;
4655 +
4656 +       AllocateAndMapFibSpace( Adapter, &ZoneSegment->MapFibContext );
4657 +
4658 +       Fib = ZoneSegment->MapFibContext.FibVirtualAddress;
4659 +       FibPhysicalAddress = ZoneSegment->MapFibContext.FibPhysicalAddress;
4660 +
4661 +       RtlZeroMemory( Fib, FibAllocSize );
4662 +
4663 +       // Account for the ZONE_SEGMENT_HEADER before the first actual FibContext.
4664 +
4665 +       for (i = 0, FibContext = (PCOMM_FIB_CONTEXT)((PUCHAR)FibContextSegment + sizeof(ZONE_SEGMENT_HEADER));
4666 +                i < ExtendSize; i++, FibContext++) {
4667 +
4668 +               FibContext->Adapter = Adapter;
4669 +
4670 +               FibContext->Fib = Fib;
4671 +               FibContext->FibData = (PVOID) FibContext->Fib->data;
4672 +
4673 +               OsCv_init( &FibContext->FsaEvent);
4674 +               FibContext->FsaEventMutex = OsCvLockAlloc();
4675 +               OsCvLockInit( FibContext->FsaEventMutex, Adapter->SpinLockCookie );
4676 +
4677 +               Fib->Header.XferState = 0xffffffff;
4678 +               Fib->Header.SenderSize = sizeof(FIB);
4679 +
4680 +               FibContext->LogicalFibAddress.LowPart = (ULONG) FibPhysicalAddress;
4681 +
4682 +               Fib = (PFIB)((PUCHAR)Fib + sizeof(FIB));
4683 +               FibPhysicalAddress = (PVOID)((PUCHAR)FibPhysicalAddress + sizeof(FIB));
4684 +       }
4685 +
4686 +       //
4687 +       // If FibContextZone.TotalSegmentSize is non-zero, then a zone has already been
4688 +       // initialized, we just need to extend it.
4689 +       //
4690 +
4691 +       if (Adapter->FibContextZone.TotalSegmentSize) {
4692 +
4693 +               OsSpinLockAcquire( Adapter->FibContextZoneSpinLock );
4694 +
4695 +               ExExtendZone( &Adapter->FibContextZone,
4696 +                                         FibContextSegment,
4697 +                                         ZoneSegmentAllocSize );
4698 +
4699 +               OsSpinLockRelease( Adapter->FibContextZoneSpinLock );
4700 +
4701 +       } else {
4702 +
4703 +           if (ExInitializeZone( &Adapter->FibContextZone,
4704 +                                                         sizeof(COMM_FIB_CONTEXT),
4705 +                             FibContextSegment,
4706 +                                 ZoneSegmentAllocSize ) != STATUS_SUCCESS)
4707 +                       FsaBugCheck(0,0,0);
4708 +
4709 +       }
4710 +
4711 +       //
4712 +       // Add this segment to the adapter's list of segments
4713 +       //
4714 +
4715 +       ZoneSegment->Next = Adapter->FibContextSegmentList;
4716 +       Adapter->FibContextSegmentList = ZoneSegment;
4717 +
4718 +       return (TRUE);
4719 +}
4720 +
4721 +
4722 +
4723 +/*++
4724 +
4725 +Routine Description:
4726 +
4727 +    This routine creates a new COMM_FIB_CONTEXT record
4728 +
4729 +Arguments:
4730 +
4731 +       Adapter - The adapter that this COMM_FIB_CONTEXT will communicate with.
4732 +
4733 +Return Value:
4734 +
4735 +    PCOMM_FIB_CONTEXT - returns a pointer to the newly allocate COMM_FIB_CONTEXT Record
4736 +
4737 +--*/
4738 +PFIB_CONTEXT
4739 +AllocateFib (IN PVOID AdapterArg)
4740 +{
4741 +       PAFA_COMM_ADAPTER Adapter = (PAFA_COMM_ADAPTER) AdapterArg;
4742 +    KIRQL SavedIrql;
4743 +    PCOMM_FIB_CONTEXT FibContext;
4744 +       int FullZoneLoopCounter = 0;
4745 +        
4746 +
4747 +        //
4748 +       // Acquire the zone spin lock, and check to see if the zone is full.
4749 +       // If it is, then release the spin lock and allocate more fibs for the 
4750 +       // zone.  The ExtendFibZone routine will re-acquire the spin lock to add
4751 +       // the new fibs onto the zone.
4752 +        //
4753 +
4754 +    OsSpinLockAcquire( Adapter->FibContextZoneSpinLock );
4755 +
4756 +    while (ExIsFullZone( &Adapter->FibContextZone )) {
4757 +
4758 +               if (++FullZoneLoopCounter >  10)
4759 +                       FsaBugCheck(0,0,0);
4760 +
4761 +               OsSpinLockRelease( Adapter->FibContextZoneSpinLock );
4762 +
4763 +                // bmb debug
4764 +                cmn_err (CE_DEBUG, "Extending FibContextZone");
4765 +               if (FsaExtendFibContextZone(Adapter) == FALSE) {
4766 +                       return (NULL);
4767 +               }
4768 +
4769 +                OsSpinLockAcquire( Adapter->FibContextZoneSpinLock );
4770 +
4771 +       }
4772 +
4773 +    //
4774 +       //  At this point we now know that the zone has at least one more
4775 +    //  IRP context record available.  So allocate from the zone and
4776 +    //  then release the mutex.
4777 +    //
4778 +
4779 +    FibContext = (PCOMM_FIB_CONTEXT) ExAllocateFromZone( &Adapter->FibContextZone );
4780 +
4781 +       OsSpinLockRelease( Adapter->FibContextZoneSpinLock );
4782 +
4783 +    //
4784 +    //  Set the proper node type code and node byte size
4785 +    //
4786 +
4787 +    FibContext->NodeTypeCode = FSAFS_NTC_FIB_CONTEXT;
4788 +    FibContext->NodeByteSize = sizeof( COMM_FIB_CONTEXT );
4789 +
4790 +       // 
4791 +       // Null out fields that depend on being zero at the start of each I/O
4792 +       //
4793 +
4794 +       FibContext->Fib->Header.XferState = 0;
4795 +       FibContext->FibCallback = NULL;
4796 +       FibContext->FibCallbackContext = NULL;
4797 +
4798 +
4799 +    //
4800 +    //  return and tell the caller
4801 +    //
4802 +
4803 +    return ((PFIB_CONTEXT) FibContext);
4804 +}
4805 +
4806 +
4807 +/*++
4808 +
4809 +Routine Description:
4810 +
4811 +    This routine deallocates and removes the specified COMM_FIB_CONTEXT record
4812 +    from the Fsafs in memory data structures.  It should only be called
4813 +    by FsaCompleteRequest.
4814 +
4815 +Arguments:
4816 +
4817 +       FibContext - Supplies the COMM_FIB_CONTEXT to remove
4818 +
4819 +Return Value:
4820 +
4821 +    None
4822 +
4823 +--*/
4824 +VOID
4825 +FreeFib (IN PFIB_CONTEXT Context)
4826 +{
4827 +    KIRQL SavedIrql;
4828 +       PCOMM_FIB_CONTEXT FibContext = Context;
4829 +
4830 +    ASSERT(FibContext->NodeTypeCode == FSAFS_NTC_FIB_CONTEXT);
4831 +
4832 +    OsSpinLockAcquire( FibContext->Adapter->FibContextZoneSpinLock );
4833 +
4834 +       if (FibContext->Flags & FIB_CONTEXT_FLAG_TIMED_OUT) {
4835 +
4836 +               FsaCommData.TimedOutFibs++;
4837 +
4838 +               FibContext->Next = FibContext->Adapter->FibContextTimedOutList;
4839 +               FibContext->Adapter->FibContextTimedOutList = FibContext;
4840 +
4841 +       } else {
4842 +
4843 +           ASSERT(FibContext->Fib->Header.XferState == 0);
4844 +
4845 +               if (FibContext->Fib->Header.XferState != 0) {
4846 +                               cmn_err(CE_WARN, "FreeFib, XferState != 0, FibContext = 0x%x, XferState = 0x%x\n", 
4847 +                                        FibContext, FibContext->Fib->Header.XferState);
4848 +               }
4849 +
4850 +           ExFreeToZone( &FibContext->Adapter->FibContextZone, FibContext );
4851 +
4852 +       }       
4853 +
4854 +       OsSpinLockRelease( FibContext->Adapter->FibContextZoneSpinLock );
4855 +
4856 +    //
4857 +    //  return and tell the caller
4858 +    //
4859 +
4860 +    return;
4861 +}
4862 +
4863 +
4864 +/*++
4865 +
4866 +Routine Description:
4867 +
4868 +    This routine deallocates and removes the specified COMM_FIB_CONTEXT record
4869 +    from the Fsafs in memory data structures.  It should only be called
4870 +    from the dpc routines to from dpc to free an FibContext from an async or
4871 +       no response io
4872 +
4873 +Arguments:
4874 +
4875 +    FibContext - Supplies the COMM_FIB_CONTEXT to remove
4876 +
4877 +Return Value:
4878 +
4879 +    None
4880 +
4881 +--*/
4882 +VOID
4883 +FreeFibFromDpc (IN PFIB_CONTEXT Context)
4884 +{
4885 +    PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
4886 +
4887 +    ASSERT(FibContext->NodeTypeCode == FSAFS_NTC_FIB_CONTEXT);
4888 +
4889 +    OsSpinLockAcquire(FibContext->Adapter->FibContextZoneSpinLock);
4890 +
4891 +       if (FibContext->Flags & FIB_CONTEXT_FLAG_TIMED_OUT) {
4892 +
4893 +               FsaCommData.TimedOutFibs++;
4894 +
4895 +               FibContext->Next = FibContext->Adapter->FibContextTimedOutList;
4896 +               FibContext->Adapter->FibContextTimedOutList = FibContext;
4897 +
4898 +       } else {
4899 +
4900 +           ASSERT(FibContext->Fib->Header.XferState == 0);
4901 +
4902 +               if (FibContext->Fib->Header.XferState != 0) {
4903 +                               cmn_err(CE_WARN, "FreeFibFromDpc, XferState != 0, FibContext = 0x%x, XferState = 0x%x\n", 
4904 +                                        FibContext, FibContext->Fib->Header.XferState);
4905 +               }
4906 +
4907 +
4908 +           ExFreeToZone( &FibContext->Adapter->FibContextZone, FibContext );
4909 +
4910 +       }
4911 +               
4912 +       OsSpinLockRelease(FibContext->Adapter->FibContextZoneSpinLock);
4913 +
4914 +    //
4915 +    //  return and tell the caller
4916 +    //
4917 +
4918 +    return;
4919 +}
4920 +
4921 +
4922 +/*++
4923 +
4924 +Routine Description:
4925 +
4926 +    Will initialize a FIB of the requested size.
4927 +    
4928 +Arguments:
4929 +
4930 +    Fib is a pointer to a location which will receive the address of the allocated
4931 +        FIB.
4932 +
4933 +    Size is the size of the Fib to allocate.
4934 +
4935 +Return Value:
4936 +
4937 +    NT_SUCCESS if a Fib was returned to the caller.
4938 +    NT_ERROR if event was an invalid event. 
4939 +
4940 +--*/
4941 +AAC_STATUS
4942 +InitializeFib (IN PFIB_CONTEXT Context)
4943 +{
4944 +    PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
4945 +       PFIB Fib = FibContext->Fib;
4946 +
4947 +    Fib->Header.StructType = TFib;
4948 +    Fib->Header.Size = sizeof(FIB);
4949 +//    if (Fib->Header.XferState & AllocatedFromPool)
4950 +//        Fib->Header.XferState = HostOwned | FibInitialized | FibEmpty | AllocatedFromPool;
4951 +//    else
4952 +        Fib->Header.XferState = HostOwned | FibInitialized | FibEmpty | FastResponseCapable;
4953 +    Fib->Header.SenderFibAddress = 0;
4954 +    Fib->Header.ReceiverFibAddress = 0;
4955 +    Fib->Header.SenderSize = sizeof(FIB);
4956 +
4957 +    return(STATUS_SUCCESS);
4958 +}
4959 +    
4960 +
4961 +/*++
4962 +
4963 +Routine Description:
4964 +
4965 +    Will allocate and initialize a FIB of the requested size and return a
4966 +    pointer to the structure. The size allocated may be larger than the size
4967 +    requested due to allocation performace optimizations.
4968 +    
4969 +Arguments:
4970 +
4971 +    Fib is a pointer to a location which will receive the address of the allocated
4972 +        FIB.
4973 +
4974 +    Size is the size of the Fib to allocate.
4975 +
4976 +    JustInitialize is a boolean which indicates a Fib has been allocated most likly in an
4977 +        imbedded structure the FS always allocates. So just initiaize it and return.
4978 +    
4979 +Return Value:
4980 +
4981 +    NT_SUCCESS if a Fib was returned to the caller.
4982 +    NT_ERROR if event was an invalid event. 
4983 +
4984 +--*/
4985 +AAC_STATUS
4986 +AllocatePoolFib (OUT PFIB *Fib, IN USHORT Size)
4987 +{}
4988 +    
4989 +
4990 +/*++
4991 +
4992 +Routine Description:
4993 +
4994 +    Will deallocate and return to the free pool the FIB pointed to by the
4995 +    caller. Upon return accessing locations pointed to by the FIB parameter
4996 +    could cause system access faults.
4997 +
4998 +Arguments:
4999 +
5000 +    Fib is a pointer to the FIB that caller wishes to deallocate.
5001 +    
5002 +Return Value:
5003 +
5004 +    NT_SUCCESS if a Fib was returned to the caller.
5005 +    NT_ERROR if event was an invalid event. 
5006 +
5007 +--*/
5008 +AAC_STATUS
5009 +DeallocateFib (PFIB_CONTEXT Context)
5010 +{
5011 +    PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
5012 +       PFIB Fib = FibContext->Fib;
5013 +
5014 +    if ( Fib->Header.StructType != TFib ) {
5015 +        FsaCommPrint("Error CompleteFib called with a non Fib structure.\n");
5016 +        return(STATUS_UNSUCCESSFUL);
5017 +    }
5018 +
5019 +
5020 +    Fib->Header.XferState = 0;        
5021 +        
5022 +    return(STATUS_SUCCESS);
5023 +
5024 +}
5025 +
5026 +
5027 +AAC_STATUS
5028 +GetResponse(
5029 +    IN PCOMM_QUE ResponseQueue,
5030 +    OUT PFIB Fib
5031 +    )
5032 +/*++
5033 +
5034 +Routine Description:
5035 +
5036 +    Gets a QE off the requested response queue and gets the response FIB into
5037 +    host memory. The FIB may already be in host memory depending on the bus
5038 +    interface, or may require the host to DMA it over from the adapter. The routine
5039 +    will return the FIB to the caller.
5040 +
5041 +Arguments:
5042 +
5043 +    ResponseQueue - Is the queue the caller wishes to have the response gotten from.
5044 +    Fib - Is the Fib which was the response from the adapter
5045 +
5046 +Return Value:
5047 +
5048 +    NT_SUCCESS if a Fib was returned to the caller.
5049 +    NT_ERROR if there was no Fib to return to the caller.
5050 +    bkpfix - add in all the other possible errors ect
5051 +
5052 +--*/
5053 +{
5054 +return(STATUS_UNSUCCESSFUL);
5055 +}
5056 +
5057 +//
5058 +// Commuication primitives define and support the queuing method we use to
5059 +// support host to adapter commuication. All queue accesses happen through
5060 +// these routines and are the only routines which have a knowledge of the
5061 +// how these queues are implemented.
5062 +//
5063 +
5064 +
5065 +/*++
5066 +
5067 +Routine Description:
5068 +
5069 +    With a priority the routine returns a queue entry if the queue has free entries. If the queue
5070 +    is full(no free entries) than no entry is returned and the function returns FALSE otherwise TRUE is
5071 +    returned.
5072 +
5073 +Arguments:
5074 +
5075 +    Priority is an enumerated type which determines which priority level
5076 +        command queue the QE is going to be queued on.
5077 +
5078 +    Entry is a pointer to the address of where to return the address of
5079 +        the queue entry from the requested command queue.
5080 +
5081 +    Index is a pointer to the address of where to store the index of the new
5082 +        queue entry returned.
5083 +
5084 +       DontInterrupt - We set this true if the queue state is such that we don't
5085 +               need to interrupt the adapter for this queue entry.
5086 +
5087 +Return Value:
5088 +
5089 +    TRUE - If a queue entry is returned
5090 +    FALSE - If there are no free queue entries on the requested command queue.
5091 +
5092 +--*/
5093 +BOOLEAN
5094 +GetEntry (IN PAFA_COMM_ADAPTER Adapter, IN QUEUE_TYPES WhichQueue,
5095 +                 OUT PQUEUE_ENTRY *Entry, OUT PQUEUE_INDEX Index,
5096 +                 OUT ULONG *DontInterrupt)
5097 +{
5098 +    ULONG QueueOffset;
5099 +       BOOLEAN status;
5100 +       PCOMM_REGION CommRegion;
5101 +
5102 +       CommRegion = Adapter->CommRegion;
5103 +
5104 +    //
5105 +    // All of the queues wrap when they reach the end, so we check to see if they
5106 +    // have reached the end and if they have we just set the index back to zero.
5107 +    // This is a wrap. You could or off the high bits in all updates but this is
5108 +    // a bit faster I think.
5109 +    //
5110 +
5111 +    if (WhichQueue == AdapHighCmdQueue) {
5112 +        *Index = *(CommRegion->AdapHighCmdQue.Headers.ProducerIndex);
5113 +
5114 +               if (*Index - 2 == *(CommRegion->AdapHighCmdQue.Headers.ConsumerIndex))
5115 +                       *DontInterrupt = TRUE; 
5116 +
5117 +        if (*Index >= ADAP_HIGH_CMD_ENTRIES)
5118 +            *Index = 0;
5119 +
5120 +        if (*Index + 1 == *(CommRegion->AdapHighCmdQue.Headers.ConsumerIndex)) { // Queue is full
5121 +                       status = FALSE;
5122 +                       cmn_err(CE_WARN, "Adapter High Command Queue full, %d outstanding",
5123 +                                       CommRegion->AdapHighCmdQue.NumOutstandingIos);
5124 +               } else {
5125 +               QueueOffset = sizeof(QUEUE_ENTRY) * (*Index);
5126 +               *Entry = QueueOffset + CommRegion->AdapHighCmdQue.BaseAddress;
5127 +
5128 +                       status = TRUE;
5129 +               }
5130 +    } else if (WhichQueue == AdapNormCmdQueue) {
5131 +
5132 +        *Index = *(CommRegion->AdapNormCmdQue.Headers.ProducerIndex);
5133 +
5134 +               if (*Index - 2 == *(CommRegion->AdapNormCmdQue.Headers.ConsumerIndex))
5135 +                       *DontInterrupt = TRUE; 
5136 +
5137 +               //
5138 +               // If we are at the end of the QUEUE then wrap back to 
5139 +               // the beginning.
5140 +        //
5141 +
5142 +        if (*Index >= ADAP_NORM_CMD_ENTRIES) 
5143 +            *Index = 0; // Wrap to front of the Producer Queue.
5144 +
5145 +               //
5146 +        // The IEEE spec says that it the producer is one behind the consumer then
5147 +        // the queue is full.
5148 +        //       
5149 +
5150 +               ASSERT(*(CommRegion->AdapNormCmdQue.Headers.ConsumerIndex) != 0);
5151 +
5152 +        if (*Index + 1 == *(CommRegion->AdapNormCmdQue.Headers.ConsumerIndex)) { // Queue is full
5153 +                       cmn_err(CE_WARN, "Adapter Norm Command Queue full, %d outstanding",
5154 +                                       CommRegion->AdapNormCmdQue.NumOutstandingIos);
5155 +                       status = FALSE;
5156 +               } else {        
5157 +               //
5158 +                       // The success case just falls through and returns the a valid queue entry.
5159 +                       //
5160 +
5161 +#ifdef commdebug
5162 +               FsaCommPrint("queue entry = %x.\n",CommRegion->AdapNormCmdQue.BaseAddress + *Index);
5163 +               FsaCommPrint("GetEntry: Index = %d, QueueOffset = %x, Entry = %x, *Entry = %x.\n",
5164 +                            *Index, QueueOffset, Entry, *Entry);
5165 +#endif
5166 +               *Entry = CommRegion->AdapNormCmdQue.BaseAddress + *Index;
5167 +
5168 +                       status = TRUE;
5169 +               }
5170 +    } else if (WhichQueue == AdapHighRespQueue) {
5171 +
5172 +        *Index = *(CommRegion->AdapHighRespQue.Headers.ProducerIndex);
5173 +
5174 +               if (*Index - 2 == *(CommRegion->AdapHighRespQue.Headers.ConsumerIndex))
5175 +                       *DontInterrupt = TRUE; 
5176 +
5177 +        if (*Index >= ADAP_HIGH_RESP_ENTRIES)
5178 +            *Index = 0;
5179 +
5180 +        if (*Index + 1 == *(CommRegion->AdapHighRespQue.Headers.ConsumerIndex)) { // Queue is full
5181 +                       status = FALSE;
5182 +                       cmn_err(CE_WARN, "Adapter High Resp Queue full, %d outstanding",
5183 +                                       CommRegion->AdapHighRespQue.NumOutstandingIos);
5184 +               } else {                                                        
5185 +               *Entry = CommRegion->AdapHighRespQue.BaseAddress + *Index;
5186 +               status = TRUE;
5187 +               } 
5188 +    } else if (WhichQueue == AdapNormRespQueue) {
5189 +
5190 +        *Index = *(CommRegion->AdapNormRespQue.Headers.ProducerIndex);
5191 +
5192 +               if (*Index - 2 == *(CommRegion->AdapNormRespQue.Headers.ConsumerIndex))
5193 +                       *DontInterrupt = TRUE; 
5194 +
5195 +               //
5196 +               // If we are at the end of the QUEUE then wrap back to 
5197 +               // the beginning.
5198 +        //
5199 +
5200 +        if (*Index >= ADAP_NORM_RESP_ENTRIES) 
5201 +            *Index = 0; // Wrap to front of the Producer Queue.
5202 +
5203 +               //
5204 +        // The IEEE spec says that it the producer is one behind the consumer then
5205 +        // the queue is full.
5206 +        //       
5207 +
5208 +        if (*Index + 1 == *(CommRegion->AdapNormRespQue.Headers.ConsumerIndex)) { // Queue is full
5209 +                       status = FALSE; 
5210 +                       cmn_err(CE_WARN, "Adapter Norm Resp Queue full, %d outstanding",
5211 +                                       CommRegion->AdapNormRespQue.NumOutstandingIos);
5212 +               } else {        
5213 +               //
5214 +                       // The success case just falls through and returns the a valid queue entry.
5215 +                       //
5216 +
5217 +               *Entry = CommRegion->AdapNormRespQue.BaseAddress + *Index;
5218 +
5219 +#ifdef commdebug
5220 +               FsaCommPrint("queue entry = %x.\n",CommRegion->AdapNormRespQue.BaseAddress + *Index);
5221 +               FsaCommPrint("GetEntry: Index = %d, Entry = %x, *Entry = %x.\n",*Index, Entry, *Entry);
5222 +#endif
5223 +                       status = TRUE;
5224 +               }     
5225 +    } else {
5226 +               cmn_err(CE_PANIC, "GetEntry: invalid queue %d", WhichQueue);
5227 +       }
5228 +
5229 +
5230 +       return (status);
5231 +}
5232 +   
5233 +
5234 +
5235 +#ifdef API_THROTTLE
5236 +
5237 +void ThrottleCheck(
5238 +       IN PAFA_COMM_ADAPTER Adapter,
5239 +       IN PFIB Fib
5240 +       )
5241 +/*++
5242 +
5243 +Routine Description:
5244 +
5245 +    This routine implements data I/O throttling. Throttling occurs when
5246 +       a CLI FIB is detected. To ensure the CLI responds quickly (the user
5247 +       is waiting for the response), this mechanism restricts the queue
5248 +       depth of data IOs at the adapter for a period of time (called the
5249 +       Throttle Period, default 5 seconds).
5250 +
5251 +    The mechanism uses a counted semaphore to place threads into a wait
5252 +       state should there be too many data I/Os outstanding.
5253 +
5254 +       At the start of a throttle period (indicated by the first CLI FIB)
5255 +       a timer is started. When the timer expires, new requests can go to
5256 +       the adapter freely. Throttled requests gradually drain to the
5257 +       adapter as each outstanding throttle I/O completes.
5258 +
5259 +    To avoid hurting regular I/O performance, we use a flag in the FIB
5260 +       header to mark FIBs involved in throttling. This means we only need
5261 +       take the extra spinlock in the response DPC routine for FIBs who
5262 +       were subject to throttling. If no throttling is occurring, the cost
5263 +       to the regular code paths is a handful of instructions.
5264 +
5265 +Arguments:
5266 +
5267 +       Adapter - Pointer to per-adapter context. This is used to locate the
5268 +                         throttle information for this adapter.
5269 +       
5270 +       Fib             - Pointer to the header for the fib being sent.
5271 +
5272 +Return Value:
5273 +
5274 +       None.
5275 +
5276 +--*/
5277 +{
5278 +       PCOMM_REGION CommRegion = Adapter->CommRegion;
5279 +       AAC_STATUS       Status;
5280 +
5281 +       //
5282 +       // This routine is called under protection of the queue spinlock.
5283 +       // As such we are allowed to check and change the counts for the
5284 +       // throttle.
5285 +       // Check the FIB. If its not a data operation, send it on without
5286 +       // throttle check. If it is a data operation, check for throttle.
5287 +       //
5288 +
5289 +       CommRegion->TotalFibs++;                                                        // Keep statistics
5290 +
5291 +       if ((Fib->Header.XferState & ApiFib) != 0) {
5292 +
5293 +               CommRegion->ApiFibs++;                                                  // Keep statistics
5294 +
5295 +               //
5296 +               // Its an API fib. If the throttle is not already active,
5297 +               // make it so. This will prevent new data Fibs being sent
5298 +               // if they exceed the throttle check.
5299 +               //
5300 +
5301 +               if (!CommRegion->ThrottleActive) {
5302 +                       BOOLEAN          InQue;
5303 +
5304 +                       CommRegion->ThrottleActive = TRUE;                      // This causes new data I/Os to be throttled
5305 +
5306 +                       //
5307 +                       // Schedule a timer for the throttle active period. When
5308 +                       // it expires, we'll be called back at routine ThrottleDpcRoutine
5309 +                       // above. This will signify the throttle active period ended
5310 +                       // and any waiting threads will be signalled to restart.
5311 +                       //
5312 +
5313 +                       FsaCommPrint("Throttle Period Start - CommRegion: %x\n", CommRegion);
5314 +                       CommRegion->ThrottleTimerSets++;
5315 +                       InQue = KeSetTimer( &CommRegion->ThrottleTimer,
5316 +                                                               CommRegion->ThrottleTimeout,
5317 +                                                               &CommRegion->ThrottleDpc);
5318 +                       ASSERT(InQue == FALSE);
5319 +               }
5320 +
5321 +               return;
5322 +       }
5323 +
5324 +       //
5325 +       // Its a non-API fib, so subject to throttle checks.
5326 +       // The following are exempt from throttling:
5327 +       //              o FIBs marked as "throttle exempt" by upper layers.
5328 +       //              o I/Os issued from a raised IRQL. We can't suspend
5329 +       //                a thread when at raised IRQL so throttling is exempt.
5330 +       //
5331 +
5332 +       if (CommRegion->AdapNormCmdQue.SavedIrql != PASSIVE_LEVEL) {
5333 +
5334 +               CommRegion->NonPassiveFibs++;
5335 +               FsaCommPrint("ThrottleCheck: Non-Passive level FIB bypasses throttle: %x\n", Fib);
5336 +               return;
5337 +
5338 +       }
5339 +
5340 +       if (CommRegion->ThrottleActive) {
5341 +
5342 +               //
5343 +               // Throttle is active.
5344 +               // Check if the FIB is a read or write. If so, and its to the
5345 +               // file system information area, let it through without throttling.
5346 +               //
5347 +
5348 +               if (Fib->Header.Command == ContainerCommand) {
5349 +                       PBLOCKREAD BlockDisk = (PBLOCKREAD) &Fib->data;
5350 +
5351 +                       //
5352 +                       // *** Note *** We are using read and write command formats
5353 +                       // interchangably here. This is ok for this purpose as the
5354 +                       // command is in the same place for both. Read and write command
5355 +                       // formats are different at higher offsets though.
5356 +                       //
5357 +
5358 +                       if ( ((BlockDisk->Command == VM_CtBlockRead) ||
5359 +                                 (BlockDisk->Command == VM_CtBlockWrite)) &&
5360 +                                 (BlockDisk->BlockNumber <= FILESYSTEM_INFO_MAX_BLKNO)) {
5361 +
5362 +                               CommRegion->FSInfoFibs++;                                                       // Keep statistics
5363 +                               return;
5364 +
5365 +                       }
5366 +
5367 +               }
5368 +
5369 +               //
5370 +               // Throttle the FIB.
5371 +               // Mark it as throttle active so that it can signal a waiter
5372 +               // when it completes.
5373 +
5374 +               CommRegion->ThrottledFibs++;
5375 +               Fib->Header.Flags |= ThrottledFib;
5376 +               
5377 +               //
5378 +               // Release the spinlock so we can wait the thread if necessary.
5379 +               // Since we specify a timeout, check the caller is at passive level.
5380 +               //
5381 +
5382 +               OsSpinLockRelease((CommRegion->AdapNormCmdQue.QueueLock), CommRegion->AdapNormCmdQue.SavedIrql);
5383 +
5384 +               FsaCommPrint("ThrottleCheck - Thread Suspension - FIB: %x\n", Fib);
5385 +
5386 +               Status = KeWaitForSingleObject(&CommRegion->ThrottleReleaseSema,
5387 +                                                                               Executive,                                                      // Don't allow user APCs to wake us
5388 +                                                                               KernelMode,                                                     // Wait in kernel mode
5389 +                                                                               FALSE,                                                          // Not alertable
5390 +                                                                               &CommRegion->ThrottleWaitTimeout);      // Timeout after this time
5391 +
5392 +               //
5393 +               // Check the signal status. If we've timed out, clear the throttle
5394 +               // flag on the FIB to avoid us signalling the semaphore on completion.
5395 +               // We never acquired the semaphore.
5396 +               //
5397 +               if (Status == STATUS_TIMEOUT) {
5398 +
5399 +                       CommRegion->ThrottleTimedoutFibs++;
5400 +                       FsaCommPrint("ThrottledFib Timed Out - FIB: %x\n", Fib);
5401 +                       Fib->Header.Flags &= ~ThrottledFib;                                             // Clear the throttledfib flag
5402 +
5403 +               } else {
5404 +
5405 +                       ASSERT(Status == STATUS_SUCCESS);                                               // No other return is possible
5406 +
5407 +               }
5408 +
5409 +               //
5410 +               // We've been woken up and can now send the FIB to the adapter.
5411 +               // Acquire the spinlock again so we can get a queue entry. This
5412 +               // returns to GetQueueEntry.
5413 +               //
5414 +
5415 +               FsaCommPrint("ThrottleCheck - Thread Resume - FIB: %x\n", Fib);
5416 +               KeAcquireSpinLock((CommRegion->AdapNormCmdQue.QueueLock), &(CommRegion->AdapNormCmdQue.SavedIrql));
5417 +               CommRegion->ThrottleOutstandingFibs++;          // There's another throttle controlled FIB going.
5418 +               return;
5419 +
5420 +       }
5421 +}
5422 +
5423 +#endif //#ifdef API_THROTTLE
5424 +
5425 +int GetQueueEntryTimeouts = 0;
5426 +
5427 +
5428 +/*++
5429 +
5430 +Routine Description:
5431 +
5432 +    Gets the next free QE off the requested priorty adapter command queue and
5433 +    associates the Fib with the QE. The QE represented by index is ready to
5434 +     insert on the queue when this routine returns success.
5435 +
5436 +Arguments:
5437 +
5438 +    Index is the returned value which represents the QE which is ready to
5439 +        insert on the adapter's command queue.
5440 +
5441 +    Priority is an enumerated type which determines which priority level
5442 +        command queue the QE is going to be queued on.
5443 +
5444 +    Fib is a pointer to the FIB the caller wishes to have associated with the
5445 +        QE.
5446 +
5447 +    Wait is a boolean which determines if the routine will wait if there are
5448 +        no free QEs on the requested priority command queue.
5449 +
5450 +    FibContext is where the driver stores all system resources required to execute the
5451 +        command requested from the calling thread. This includes mapping resources for
5452 +        the FIB and the 'users' buffer.
5453 +
5454 +       DontInterrupt - We set this true if the queue state is such that we don't
5455 +               need to interrupt the adapter for this queue entry.
5456 +
5457 +Return Value:
5458 +
5459 +    NT_SUCCESS if a Fib was returned to the caller.
5460 +    NT_ERROR if event was an invalid event. 
5461 +
5462 +--*/
5463 +AAC_STATUS
5464 +GetQueueEntry (IN PAFA_COMM_ADAPTER Adapter, OUT PQUEUE_INDEX Index,
5465 +                          IN QUEUE_TYPES WhichQueue, IN PFIB Fib, IN BOOLEAN Wait,
5466 +                          IN PCOMM_FIB_CONTEXT FibContext, OUT ULONG *DontInterrupt)
5467 +{
5468 +    PQUEUE_ENTRY QueueEntry = NULL;
5469 +    BOOLEAN MapAddress = FALSE;
5470 +       int timeouts = 0;
5471 +       AAC_STATUS Status;
5472 +       PCOMM_REGION CommRegion;
5473 +
5474 +       CommRegion = Adapter->CommRegion;
5475 +
5476 +    //
5477 +    // Get the spinlock for the queue we are putting a command on
5478 +    //
5479 +
5480 +    if (WhichQueue == AdapHighCmdQueue) 
5481 +        OsSpinLockAcquire(CommRegion->AdapHighCmdQue.QueueLock);
5482 +    else if (WhichQueue == AdapNormCmdQueue)
5483 +        OsSpinLockAcquire(CommRegion->AdapNormCmdQue.QueueLock);
5484 +    else if (WhichQueue == AdapHighRespQueue)
5485 +        OsSpinLockAcquire(CommRegion->AdapHighRespQue.QueueLock);
5486 +    else if (WhichQueue == AdapNormRespQueue)
5487 +        OsSpinLockAcquire(CommRegion->AdapNormRespQue.QueueLock);
5488 +    else {
5489 +        FsaCommPrint("Invalid queue priority passed to GetQueueEntry.\n");
5490 +        return(FSA_INVALID_QUEUE);
5491 +    }
5492 +    
5493 +    //
5494 +    // Get the pointers to a queue entry on the queue the caller wishes to queue
5495 +    // a command request on. If there are no entries then wait if that is what the
5496 +    // caller requested. 
5497 +    //
5498 +
5499 +    if (WhichQueue == AdapHighCmdQueue) {
5500 +         // if no entries wait for some if caller wants to
5501 +        while ( !GetEntry(Adapter, AdapHighCmdQueue, &QueueEntry, Index, DontInterrupt) ) { 
5502 +                       cmn_err(CE_PANIC, "GetEntries failed (1)\n");
5503 +               }
5504 +
5505 +        //
5506 +        // Setup queue entry with a command, status and Fib mapped
5507 +        //
5508 +
5509 +        QueueEntry->Size = Fib->Header.Size;
5510 +        MapAddress = TRUE;
5511 +       
5512 +    } else if (WhichQueue == AdapNormCmdQueue) {
5513 +         // if no entries wait for some if caller wants to
5514 +        while ( !GetEntry(Adapter, AdapNormCmdQueue, &QueueEntry, Index, DontInterrupt) ) { 
5515 +                       cmn_err(CE_PANIC, "GetEntries failed (2)\n");
5516 +               }
5517
5518 +        //
5519 +        // Setup queue entry with command, status and Fib mapped
5520 +        //
5521 +
5522 +        QueueEntry->Size = Fib->Header.Size;
5523 +        MapAddress = TRUE;
5524 +        
5525 +     } else if (WhichQueue == AdapHighRespQueue) {
5526 +
5527 +        while ( !GetEntry(Adapter, AdapHighRespQueue, &QueueEntry, Index, DontInterrupt) ) { // if no entries wait for some if caller wants to
5528 +               }
5529 +
5530 +        //
5531 +        // Setup queue entry with command, status and Fib mapped
5532 +        //
5533 +
5534 +        QueueEntry->Size = Fib->Header.Size;
5535 +        QueueEntry->FibAddress = Fib->Header.SenderFibAddress;                         // Restore adapters pointer to the FIB
5536 +               Fib->Header.ReceiverFibAddress = Fib->Header.SenderFibAddress;          // Let the adapter now where to find its data
5537 +        MapAddress = FALSE;
5538 +        
5539 +     } else if (WhichQueue == AdapNormRespQueue) {
5540 +        while ( !GetEntry(Adapter, AdapNormRespQueue, &QueueEntry, Index, DontInterrupt) ) { // if no entries wait for some if caller wants to
5541 +               }
5542 +
5543 +               //
5544 +               // Setup queue entry with command, status, adapter's pointer to the Fib it sent
5545 +               //
5546 +       
5547 +        QueueEntry->Size = Fib->Header.Size;
5548 +        QueueEntry->FibAddress = Fib->Header.SenderFibAddress;                         // Restore adapters pointer to the FIB
5549 +               Fib->Header.ReceiverFibAddress = Fib->Header.SenderFibAddress;          // Let the adapter now where to find its data
5550 +        MapAddress = FALSE;
5551 +     }
5552 +                
5553 +    //
5554 +    // If MapFib is true than we need to map the Fib and put pointers in the queue entry.
5555 +    //
5556 +
5557 +    if (MapAddress) {
5558 +               QueueEntry->FibAddress = (ULONG)(FibContext->LogicalFibAddress.LowPart);
5559 +    }
5560 +    
5561 +    //
5562 +    // Return
5563 +    //
5564 +#ifdef commdebug    
5565 +    FsaCommPrint("Queue Entry contents:.\n");
5566 +    FsaCommPrint("  Command =               %d.\n", QueueEntry->Command);
5567 +    FsaCommPrint("  Status  =               %x.\n", QueueEntry->Status);
5568 +    FsaCommPrint("  Rec Fib address low =   %x.\n", QueueEntry->FibAddressLow);        
5569 +    FsaCommPrint("  Fib size in bytes =     %d.\n", QueueEntry->Size);
5570 +#endif
5571 +
5572 +    return(FSA_SUCCESS);
5573 +}
5574 +
5575 +
5576 +/*++
5577 +
5578 +Routine Description:
5579 +
5580 +    Gets the next free QE off the requested priorty adapter command queue and
5581 +      associates the Fib with the QE. The QE represented by index is ready to
5582 +    insert on the queue when this routine returns success.
5583 +
5584 +Arguments:
5585 +
5586 +    Index is the returned value which represents the QE which is ready to
5587 +        insert on the adapter's command queue.
5588 +
5589 +    WhichQueue tells us which queue the caller wishes to have the entry put.
5590 +        
5591 +Return Value:
5592 +
5593 +    NT_SUCCESS if a Fib was returned to the caller.
5594 +    NT_ERROR if event was an invalid event. 
5595 +
5596 +--*/
5597 +AAC_STATUS
5598 +InsertQueueEntry(
5599 +                 IN PAFA_COMM_ADAPTER Adapter,
5600 +                 IN QUEUE_INDEX Index,
5601 +                 IN QUEUE_TYPES WhichQueue,
5602 +                 IN ULONG DontInterrupt
5603 +                 )
5604 +{
5605 +       PCOMM_REGION CommRegion;
5606 +    
5607 +       CommRegion = Adapter->CommRegion;
5608 +
5609 +    //
5610 +    // We have already verified the queue in getentry, but we still have to make
5611 +    // sure we don't wrap here too.
5612 +    //
5613 +
5614 +    if (WhichQueue == AdapHighCmdQueue) {
5615 +
5616 +        *(CommRegion->AdapHighCmdQue.Headers.ProducerIndex) = Index + 1;
5617 +            
5618 +        OsSpinLockRelease(CommRegion->AdapHighCmdQue.QueueLock);
5619 +
5620 +               if (!DontInterrupt)
5621 +               NotifyAdapter(Adapter, AdapHighCmdQue);
5622 +        
5623 +    } else if (WhichQueue == AdapNormCmdQueue) {
5624 +
5625 +#ifdef commdebug
5626 +        FsaCommPrint("InsertQueueEntry: Inerting with an index of %d.\n",Index);
5627 +#endif
5628 +        *(CommRegion->AdapNormCmdQue.Headers.ProducerIndex) = Index + 1;
5629 +       
5630 +        OsSpinLockRelease(CommRegion->AdapNormCmdQue.QueueLock);
5631 +
5632 +               if (!DontInterrupt)
5633 +               NotifyAdapter(Adapter, AdapNormCmdQue);
5634 +
5635 +    } else if (WhichQueue == AdapHighRespQueue) {
5636 +
5637 +        *(CommRegion->AdapHighRespQue.Headers.ProducerIndex) = Index + 1;
5638 +
5639 +        OsSpinLockRelease(CommRegion->AdapHighRespQue.QueueLock);
5640 +
5641 +               if (!DontInterrupt)
5642 +               NotifyAdapter(Adapter, AdapHighRespQue);
5643 +
5644 +    } else if (WhichQueue == AdapNormRespQueue) {
5645 +
5646 +           *(CommRegion->AdapNormRespQue.Headers.ProducerIndex) = Index + 1;
5647 +           
5648 +           OsSpinLockRelease(CommRegion->AdapNormRespQue.QueueLock);
5649 +
5650 +           if (!DontInterrupt)
5651 +                   NotifyAdapter(Adapter, AdapNormRespQue);
5652 +
5653 +    } else {        
5654 +        FsaCommPrint("Invalid queue priority passed to InsertQueueEntry.\n");
5655 +        return(FSA_INVALID_QUEUE_PRIORITY);
5656 +    }
5657 +
5658 +    return(FSA_SUCCESS);                
5659 +}
5660 +
5661 +extern int GatherFibTimes;
5662 +
5663 +BOOLEAN
5664 +SendSynchFib(
5665 +       PVOID                   Arg,
5666 +       FIB_COMMAND     Command,
5667 +       PVOID                   Data,
5668 +       USHORT                  Size,
5669 +       PVOID                   Response,
5670 +       USHORT                  *ResponseSize
5671 +       )
5672 +/*++
5673 +
5674 +Routine Description:
5675 +
5676 +       This routine will send a synchronous FIB to the adapter and wait for its
5677 +       completion.
5678 +
5679 +Arguments:
5680 +
5681 +       DeviceExtension - Pointer to adapter extension structure.
5682 +
5683 +
5684 +Return Value:
5685 +
5686 +       BOOLEAN
5687 +
5688 +--*/
5689 +{
5690 +       PAFA_COMM_ADAPTER Adapter = Arg;
5691 +       FIB *Fib;
5692 +       ULONG returnStatus;
5693 +
5694 +       Fib = Adapter->SyncFib;
5695 +
5696 +    Fib->Header.StructType = TFib;
5697 +    Fib->Header.Size = sizeof(FIB);
5698 +    Fib->Header.XferState = HostOwned | FibInitialized | FibEmpty;
5699 +    Fib->Header.ReceiverFibAddress = 0;
5700 +    Fib->Header.SenderSize = sizeof(FIB);
5701 +    Fib->Header.SenderFibAddress = (ULONG)Fib;
5702 +    Fib->Header.Command = Command;
5703 +
5704 +       //
5705 +       // Copy the Data portion into the Fib.
5706 +       //
5707 +
5708 +       RtlCopyMemory( Fib->data, Data, Size );
5709 +
5710 +
5711 +    Fib->Header.XferState |= (SentFromHost | NormalPriority);
5712 +    
5713 +       //
5714 +    // Set the size of the Fib we want to send to the adapter
5715 +       //
5716 +
5717 +    Fib->Header.Size = sizeof(FIB_HEADER) + Size;
5718 +
5719 +       if (!Adapter->AdapterFuncs->SendSynchFib( Adapter->AdapterExtension,
5720 +                                                                                         Adapter->SyncFibPhysicalAddress )) {
5721 +
5722 +                       return (FALSE);
5723 +
5724 +       }
5725 +
5726 +       //
5727 +       // Copy the response back to the caller's buffer.
5728 +       //
5729 +
5730 +       RtlCopyMemory( Response, Fib->data, Fib->Header.Size - sizeof(FIB_HEADER) );
5731 +
5732 +       *ResponseSize = Fib->Header.Size - sizeof(FIB_HEADER);
5733 +
5734 +       //
5735 +       // Indicate success
5736 +       //
5737 +
5738 +       return (TRUE);
5739 +}
5740 +
5741 +//
5742 +// Define the highest level of host to adapter communication routines. These
5743 +// routines will support host to adapter FS commuication. These routines have
5744 +// no knowledge of the commuication method used. This level sends and receives
5745 +// FIBs. This level has no knowledge of how these FIBs get passed back and forth.
5746 +//
5747 +
5748 +
5749 +
5750 +/*++
5751 +
5752 +Routine Description:
5753 +
5754 +    Sends the requested FIB to the adapter and optionally will wait for a
5755 +     response FIB. If the caller does not wish to wait for a response than
5756 +    an event to wait on must be supplied. This event will be set when a
5757 +    response FIB is received from the adapter.
5758 +
5759 +Arguments:
5760 +
5761 +    Fib is a pointer to the FIB the caller wishes to send to the adapter.
5762 +    
5763 +    Size - Size of the data portion of the Fib.
5764 +    
5765 +    Priority is an enumerated type which determines which priority level
5766 +        the caller wishes to send this command at. 
5767 +
5768 +    Wait is a boolean which determines if the routine will wait for the
5769 +        completion Fib to be returned(TRUE), or return when the Fib has been
5770 +        successfully received by the adapter(FALSE).
5771 +
5772 +    WaitOn is only vaild when Wait is FALSE. The Event will be set when the response
5773 +        FIB has been returned by the adapter.
5774 +
5775 +    ReturnFib is an optional pointer to a FIB that if present the response FIB will
5776 +        copied to.     
5777 +        
5778 +Return Value:
5779 +
5780 +    NT_SUCCESS if a Fib was returned to the caller.
5781 +    NT_ERROR if event was an invalid event. 
5782 +
5783 +       --*/
5784 +AAC_STATUS
5785 +SendFib (IN FIB_COMMAND Command,
5786 +         IN PFIB_CONTEXT Context,
5787 +         IN ULONG Size, 
5788 +         IN COMM_PRIORITIES Priority,
5789 +         IN BOOLEAN Wait,
5790 +         IN PVOID WaitOn,
5791 +         IN BOOLEAN ResponseExpected,
5792 +         IN PFIB_CALLBACK FibCallback,
5793 +         IN PVOID FibCallbackContext)
5794 +{
5795 +               PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
5796 +               QUEUE_INDEX Index;
5797 +               QUEUE_TYPES WhichQueue;
5798 +               LARGE_INTEGER Timeout;
5799 +               AAC_STATUS Status;
5800 +               PAFA_COMM_ADAPTER Adapter = FibContext->Adapter;
5801 +               ULONG DontInterrupt = FALSE;
5802 +               PFIB Fib = FibContext->Fib;
5803 +               IN PCOMM_QUE OurQueue;
5804 +
5805 +               Timeout = FsaCommData.AdapterTimeout;
5806 +
5807 +               if (!(Fib->Header.XferState & HostOwned)) {
5808 +                               FsaCommPrint("SendFib was called with a xfer state not set to HostOwned!\n");
5809 +                               FsaCommLogEvent(FibContext,
5810 +                                                               FsaCommData.DeviceObject, 
5811 +                                                               FSAFS_FIB_INVALID, 
5812 +                                                               STATUS_UNSUCCESSFUL, 
5813 +                                                               BugCheckFileId | __LINE__,
5814 +                                                               FACILITY_FSAFS_ERROR_CODE,
5815 +                                                               NULL,
5816 +                                                               TRUE);                  
5817 +
5818 +                               return(STATUS_UNSUCCESSFUL);
5819 +
5820 +               }
5821 +    
5822 +               //
5823 +               // There are 5 cases with the wait and reponse requested flags. The only invalid cases
5824 +               // are if the caller requests to wait and  does not request a response and if the
5825 +               // caller does not want a response and the Fib is not allocated from pool. If a response
5826 +               // is not requesed the Fib will just be deallocaed by the DPC routine when the response
5827 +               // comes back from the adapter. No further processing will be done besides deleting the
5828 +               // Fib. We will have a debug mode where the adapter can notify the host it had a problem
5829 +               // and the host can log that fact.
5830 +
5831 +               if (Wait && !ResponseExpected) {
5832 +
5833 +                               FsaCommLogEvent(FibContext,
5834 +                                                FsaCommData.DeviceObject, 
5835 +                                                FSAFS_FIB_INVALID, 
5836 +                                                STATUS_UNSUCCESSFUL, 
5837 +                                                BugCheckFileId | __LINE__,
5838 +                                                FACILITY_FSAFS_ERROR_CODE,
5839 +                                                NULL,
5840 +                                                TRUE);                 
5841 +
5842 +                               return(STATUS_UNSUCCESSFUL);
5843 +
5844 +               } else if (!Wait && ResponseExpected) {
5845 +                               Fib->Header.XferState |= (Async | ResponseExpected);
5846 +                               FIB_COUNTER_INCREMENT(FsaCommData.AsyncSent);
5847 +               } else if (!Wait && !ResponseExpected) {
5848 +                               Fib->Header.XferState |= NoResponseExpected;
5849 +                               FIB_COUNTER_INCREMENT(FsaCommData.NoResponseSent);
5850 +               } else if (Wait && ResponseExpected) {
5851 +                  Fib->Header.XferState |= ResponseExpected;
5852 +                  FIB_COUNTER_INCREMENT(FsaCommData.NormalSent);
5853 +               } 
5854 +
5855 +               Fib->Header.SenderData = (ULONG)FibContext; // so we can complete the io in the dpc routine
5856 +
5857 +               //
5858 +               // Set FIB state to indicate where it came from and if we want a response from the
5859 +               // adapter. Also load the command from the caller.
5860 +               //
5861 +
5862 +               Fib->Header.SenderFibAddress = (ULONG)Fib;
5863 +               Fib->Header.Command = Command;
5864 +               Fib->Header.XferState |= SentFromHost;
5865 +               FibContext->Fib->Header.Flags = 0;                              // Zero the flags field - its internal only...
5866 +    
5867 +               //
5868 +               // Set the size of the Fib we want to send to the adapter
5869 +               //
5870 +
5871 +               Fib->Header.Size = sizeof(FIB_HEADER) + Size;
5872 +               if (Fib->Header.Size > Fib->Header.SenderSize) {
5873 +                               return(STATUS_BUFFER_OVERFLOW);
5874 +               }                
5875 +
5876 +               //
5877 +               // Get a queue entry connect the FIB to it and send an notify the adapter a command is ready.
5878 +               //
5879 +            
5880 +               if (Priority == FsaHigh) {
5881 +                               Fib->Header.XferState |= HighPriority;
5882 +                               WhichQueue = AdapHighCmdQueue;
5883 +                               OurQueue = &Adapter->CommRegion->AdapHighCmdQue;
5884 +               } else {
5885 +                               Fib->Header.XferState |= NormalPriority;
5886 +                               WhichQueue = AdapNormCmdQueue;
5887 +                               OurQueue = &Adapter->CommRegion->AdapNormCmdQue;
5888 +               }
5889 +
5890 +               if (Wait) {
5891 +                               OsCvLockAcquire( FibContext->FsaEventMutex );
5892 +               }
5893 +
5894 +               if ( GetQueueEntry( Adapter, &Index, WhichQueue, Fib, TRUE, FibContext, &DontInterrupt) != FSA_SUCCESS )
5895 +                               return(STATUS_UNSUCCESSFUL);
5896 +
5897 +               // bmb debug
5898 +
5899 +               cmn_err (CE_DEBUG,"SendFib: inserting a queue entry at index %d.\n",Index);
5900 +               cmn_err (CE_DEBUG,"Fib contents:.\n");
5901 +               cmn_err (CE_DEBUG,"  Command =               %d.\n", Fib->Header.Command);
5902 +               cmn_err (CE_DEBUG,"  XferState  =            %x.\n", Fib->Header.XferState );
5903 +
5904 +               //
5905 +               // Fill in the Callback and CallbackContext if we are not going to wait.
5906 +               //
5907 +
5908 +               if (!Wait) {
5909 +
5910 +                               FibContext->FibCallback = FibCallback;
5911 +                               FibContext->FibCallbackContext = FibCallbackContext;
5912 +
5913 +               }
5914 +
5915 +               FIB_COUNTER_INCREMENT(FsaCommData.FibsSent);
5916 +
5917 +               InsertTailList( &OurQueue->OutstandingIoQueue, &FibContext->QueueEntry );
5918 +               OurQueue->NumOutstandingIos++;
5919 +
5920 +               FibContext->FibComplete = 0;
5921 +
5922 +
5923 +
5924 +               if ( InsertQueueEntry( Adapter, Index, WhichQueue, (DontInterrupt & FsaCommData.EnableInterruptModeration)) != FSA_SUCCESS )
5925 +                        return(STATUS_UNSUCCESSFUL);
5926 +
5927 +               //
5928 +               // If the caller wanted us to wait for response wait now. 
5929 +               // If Timeouts are enabled than set the timeout otherwise wait forever.
5930 +               //
5931 +    
5932 +               if (Wait) {
5933 +                        while (FibContext->FibComplete == 0) {
5934 +                                OsCv_wait( &FibContext->FsaEvent, FibContext->FsaEventMutex );
5935 +                        }      
5936 +                        
5937 +                        OsCvLockRelease( FibContext->FsaEventMutex );
5938 +                                       
5939 +                        if ( (FibContext->Flags & FIB_CONTEXT_FLAG_TIMED_OUT) ) {
5940 +                                return(STATUS_IO_TIMEOUT);
5941 +                        } else {
5942 +                                return(STATUS_SUCCESS);
5943 +                        }
5944 +               }
5945 +
5946 +               //
5947 +               // If the user does not want a response than return success otherwise return pending
5948 +               // 
5949 +
5950 +               ASSERT( FibCallback );
5951 +
5952 +               if (ResponseExpected)
5953 +                               return(STATUS_PENDING);
5954 +               else
5955 +                               return(STATUS_SUCCESS);
5956 +}
5957 +
5958 +BOOLEAN
5959 +GetConsumerEntry(
5960 +       IN PAFA_COMM_ADAPTER Adapter,
5961 +    PCOMM_QUE OurQueue,
5962 +    OUT PQUEUE_ENTRY *Entry
5963 +    )
5964 +/*++
5965 +
5966 +Routine Description:
5967 +
5968 +    Will return a pointer to the entry on the top of the queue requested that we are a consumer
5969 +    of, and return the address of the queue entry. It does not change the state of the queue. 
5970 +
5971 +Arguments:
5972 +
5973 +    OurQueue - is the queue the queue entry should be removed from.
5974 +
5975 +    Entry - is a pointer where the address  of the queue entry should be returned.    
5976 +    
5977 +Return Value:
5978 +
5979 +    TRUE if there was a queue entry on the response queue for the host to consume.
5980 +    FALSE if there were no queue entries to consume.
5981 +    
5982 +--*/
5983 +
5984 +{
5985 +    QUEUE_INDEX Index;
5986 +       BOOLEAN status;
5987 +
5988 +    if (*OurQueue->Headers.ProducerIndex == *OurQueue->Headers.ConsumerIndex) {
5989 +               status = FALSE;
5990 +       } else {
5991 +
5992 +           //
5993 +           // The consumer index must be wrapped if we have reached the end of
5994 +           // the queue. 
5995 +           // Else we just use the entry pointed to by the header index
5996 +           //
5997 +           
5998 +           if (*OurQueue->Headers.ConsumerIndex >= OurQueue->QueueEntries) 
5999 +                       Index = 0;              
6000 +           else
6001 +               Index = *OurQueue->Headers.ConsumerIndex;
6002 +           
6003 +           *Entry = OurQueue->BaseAddress + Index;
6004 +
6005 +#ifdef commdebug
6006 +           FsaCommPrint("Got a QE at Index %d, QE Addrss of %x.\n",Index,*Entry);
6007 +#endif
6008 +               status = TRUE;
6009 +       }
6010 +
6011 +    return(status);
6012 +}
6013 +
6014 +BOOLEAN
6015 +ConsumerEntryAvailable(
6016 +       IN PAFA_COMM_ADAPTER Adapter,
6017 +    PCOMM_QUE OurQueue
6018 +       )
6019 +{
6020 +    return (*OurQueue->Headers.ProducerIndex != *OurQueue->Headers.ConsumerIndex);
6021 +}
6022 +
6023 +VOID
6024 +FreeConsumerEntry(
6025 +       IN PAFA_COMM_ADAPTER Adapter,
6026 +    PCOMM_QUE OurQueue,
6027 +    QUEUE_TYPES WhichQueue
6028 +    )
6029 +/*++
6030 +
6031 +Routine Description:
6032 +
6033 +    Frees up the current top of the queue we are a consumer of. If the queue was full
6034 +    notify the producer that the queue is no longer full.
6035 +
6036 +Arguments:
6037 +
6038 +    OurQueue - is the queue we will free the current consumer entry on.
6039 +
6040 +Return Value:
6041 +
6042 +    TRUE if there was a queue entry on the response queue for the host to consume.
6043 +    FALSE if there were no queue entries to consume.
6044 +    
6045 +--*/
6046 +
6047 +{
6048 +    BOOLEAN WasFull = FALSE;
6049 +    HOST_2_ADAP_EVENT Notify;
6050 +
6051 +    if (*OurQueue->Headers.ProducerIndex+1 == *OurQueue->Headers.ConsumerIndex)
6052 +        WasFull = TRUE;
6053 +        
6054 +    if (*OurQueue->Headers.ConsumerIndex >= OurQueue->QueueEntries)
6055 +        *OurQueue->Headers.ConsumerIndex = 1;
6056 +    else
6057 +        *OurQueue->Headers.ConsumerIndex += 1;
6058 +        
6059 +    if (WasFull) {
6060 +        switch (WhichQueue) {
6061 +
6062 +            case HostNormCmdQueue:
6063 +                Notify = HostNormCmdNotFull;
6064 +                break;
6065 +            case HostHighCmdQueue:
6066 +                Notify = HostHighCmdNotFull;
6067 +                break;
6068 +
6069 +            case HostNormRespQueue:
6070 +                Notify = HostNormRespNotFull;
6071 +                break;
6072 +
6073 +            case HostHighRespQueue:
6074 +                Notify = HostHighRespNotFull;
6075 +                break;
6076 +
6077 +        }
6078 +        NotifyAdapter(Adapter, Notify);
6079 +    }
6080 +
6081 +}        
6082 +
6083 +AAC_STATUS
6084 +CompleteAdapterFib(
6085 +       IN PFIB_CONTEXT Context,
6086 +    IN USHORT Size
6087 +    )
6088 +/*++
6089 +
6090 +Routine Description:
6091 +
6092 +    Will do all necessary work to complete a FIB that was sent from the adapter.
6093 +
6094 +Arguments:
6095 +
6096 +    Fib is a pointer to the FIB that caller wishes to complete processing on. 
6097 +
6098 +    Size - Size of the completion Packet(Opitional). If not present than the current
6099 +           largest size in the Fib will be used
6100 +    
6101 +       Adapter - Pointer to which adapter sent this FIB
6102 +
6103 +Return Value:
6104 +
6105 +    NT_SUCCESS if a Fib was returned to the caller.
6106 +    NT_ERROR if event was an invalid event. 
6107 +
6108 +--*/
6109 +{
6110 +       PCOMM_FIB_CONTEXT FibContext = Context;
6111 +    PFIB Fib = FibContext->Fib;
6112 +       PAFA_COMM_ADAPTER Adapter = FibContext->Adapter;
6113 +    ULONG DontInterrupt = FALSE;
6114 +
6115 +    if (Fib->Header.XferState == 0)
6116 +        return(STATUS_SUCCESS);
6117 +
6118 +    //
6119 +    // If we plan to do anything check the structure type first.
6120 +    // 
6121 +
6122 +    if ( Fib->Header.StructType != TFib ) {
6123 +        FsaCommPrint("Error CompleteFib called with a non Fib structure.\n");
6124 +        return(STATUS_UNSUCCESSFUL);
6125 +    }
6126 +
6127 +    //
6128 +    // This block handles the case where the adapter had sent us a command and we
6129 +    // have finished processing the command. We call completeFib when we are done
6130 +    // processing the command and want to send a response back to the adapter. This
6131 +    // will send the completed cdb to the adapter.
6132 +    //
6133 +
6134 +    if (Fib->Header.XferState & SentFromAdapter) {
6135 +        Fib->Header.XferState |= HostProcessed;
6136 +        if (Fib->Header.XferState & HighPriority) {
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, AdapHighRespQueue, 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 +                                               AdapHighRespQueue, 
6153 +                                               (DontInterrupt & (BOOLEAN)FsaCommData.EnableInterruptModeration)) != STATUS_SUCCESS) {
6154 +                FsaCommPrint("CompleteFib failed while inserting entry on the queue.\n");
6155 +            }
6156 +        } else if (Fib->Header.XferState & NormalPriority) {
6157 +            QUEUE_INDEX Index;
6158 +
6159 +            if (Size) {
6160 +                Size += sizeof(FIB_HEADER);
6161 +                if (Size > Fib->Header.SenderSize) 
6162 +                    return(STATUS_BUFFER_OVERFLOW);
6163 +                Fib->Header.Size = Size;
6164 +            }
6165 +            
6166 +            if (GetQueueEntry(Adapter, &Index, AdapNormRespQueue, Fib, TRUE, NULL, &DontInterrupt) != STATUS_SUCCESS) {
6167 +                FsaCommPrint("CompleteFib got an error geting a queue entry for a response.\n");
6168 +                return(FSA_FATAL);
6169 +            }
6170 +            if (InsertQueueEntry(Adapter, 
6171 +                                               Index, 
6172 +                                               AdapNormRespQueue, 
6173 +                                               (DontInterrupt & (BOOLEAN)FsaCommData.EnableInterruptModeration)) != STATUS_SUCCESS) {
6174 +                FsaCommPrint("CompleteFib failed while inserting entry on the queue.\n");
6175 +            }
6176 +               }
6177 +    } else {
6178 +        cmn_err(CE_WARN, "CompleteFib: Unknown xferstate detected.\n");
6179 +               FsaBugCheck(0,0,0);
6180 +    }   
6181 +    return(STATUS_SUCCESS);
6182 +}
6183 +
6184 +AAC_STATUS
6185 +CompleteFib(
6186 +       IN PFIB_CONTEXT Context
6187 +    )
6188 +/*++
6189 +
6190 +Routine Description:
6191 +
6192 +    Will do all necessary work to complete a FIB. If the caller wishes to
6193 +    reuse the FIB after post processing has been completed Reinitialize
6194 +    should be called set to TRUE, otherwise the FIB will be returned to the
6195 +    free FIB pool. If Reinitialize is set to TRUE then the FIB header is
6196 +    reinitialzied and is ready for reuse on return from this routine.
6197 +
6198 +Arguments:
6199 +
6200 +    Fib is a pointer to the FIB that caller wishes to complete processing on. 
6201 +
6202 +    Size - Size of the completion Packet(Opitional). If not present than the current
6203 +           largest size in the Fib will be used
6204 +    
6205 +    Reinitialize is a boolean which determines if the routine will ready the
6206 +        completed FIB for reuse(TRUE) or not(FALSE).
6207 +
6208 +Return Value:
6209 +
6210 +    NT_SUCCESS if a Fib was returned to the caller.
6211 +    NT_ERROR if event was an invalid event. 
6212 +
6213 +--*/
6214 +{
6215 +    PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
6216 +       PAFA_COMM_ADAPTER Adapter = FibContext->Adapter;
6217 +       PFIB Fib = FibContext->Fib;
6218 +
6219 +    //
6220 +    // Check for a fib which has already been completed
6221 +    //
6222 +
6223 +//     ASSERT(Fib->Header.XferState & AdapterProcessed);
6224 +    if (Fib->Header.XferState == 0)
6225 +        return(STATUS_SUCCESS);
6226 +
6227 +    //
6228 +    // If we plan to do anything check the structure type first.
6229 +    // 
6230 +
6231 +    if ( Fib->Header.StructType != TFib ) {
6232 +        FsaCommPrint("Error CompleteFib called with a non Fib structure.\n");
6233 +        return(STATUS_UNSUCCESSFUL);
6234 +    }
6235 +
6236 +#if 0
6237 +//#if FSA_ADAPTER_METER
6238 +       //
6239 +       // Meter the completion
6240 +       //
6241 +       fsaMeterEnd(                                            // meter the end of an operation
6242 +               &(Adapter->FibMeter),                   // .. the meter
6243 +               IrpContext->FibMeterType,               // .. type of operation
6244 +               &(IrpContext->FibStartTime),    // .. ptr to operation start timestamp
6245 +               FibGetMeterSize(Fib,                    // .. number of bytes in operation
6246 +                               IrpContext->FibMeterType, 
6247 +                               IrpContext->FibSubCommand));
6248 +#endif // FSA_ADAPTER_METER
6249 +       
6250 +    //
6251 +    // This block completes a cdb which orginated on the host and we just need
6252 +    // to deallocate the cdb or reinit it. At this point the command is complete
6253 +    // that we had sent to the adapter and this cdb could be reused.
6254 +    //
6255 +       
6256 +    if ( (Fib->Header.XferState & SentFromHost) &&
6257 +         (Fib->Header.XferState & AdapterProcessed)) {
6258 +        
6259 +        ASSERT(FibContext->LogicalFibAddress.LowPart != 0);
6260 +
6261 +        return( DeallocateFib(FibContext) ); 
6262 +       
6263 +    //
6264 +    // This handles the case when the host has aborted the I/O to the
6265 +    // adapter because the adapter is not responding
6266 +    //
6267 +
6268 +    } else if (Fib->Header.XferState & SentFromHost) {
6269 +
6270 +        ASSERT(FibContext->LogicalFibAddress.LowPart != 0);
6271 +
6272 +
6273 +        return( DeallocateFib(FibContext) ); 
6274 +
6275 +    } else if (Fib->Header.XferState & HostOwned) {
6276 +
6277 +        return(DeallocateFib(FibContext));
6278 +
6279 +    } else {
6280 +        cmn_err(CE_WARN, "CompleteFib: Unknown xferstate detected.\n");
6281 +               FsaBugCheck(0,0,0);
6282 +    }   
6283 +    return(STATUS_SUCCESS);
6284 +}
6285 +
6286 +VOID
6287 +HandleDriverAif(
6288 +    IN PAFA_COMM_ADAPTER Adapter,
6289 +       IN PCOMM_FIB_CONTEXT FibContext
6290 +    )
6291 +/*++
6292 +
6293 +Routine Description:
6294 +
6295 +       This routine handles a driver notify fib from the adapter and dispatches it to 
6296 +       the appropriate routine for handling.
6297 +
6298 +Arguments:
6299 +
6300 +       Adapter - Which adapter this fib is from
6301 +       FibContext - Pointer to FibContext from adapter.
6302 +    
6303 +Return Value:
6304 +
6305 +    Nothing.
6306 +    
6307 +--*/
6308 +{
6309 +       PFIB Fib = FibContext->Fib;
6310 +       PAFA_CLASS_DRIVER ClassDriver;
6311 +       BOOLEAN Handled = FALSE;
6312 +
6313 +
6314 +       //
6315 +       // First loop through all of the class drivers to give them a chance to handle
6316 +       // the Fib.
6317 +       //
6318 +
6319 +       ClassDriver = Adapter->ClassDriverList;
6320 +
6321 +       while (ClassDriver) {
6322 +
6323 +               if (ClassDriver->HandleAif) {
6324 +
6325 +                       if (ClassDriver->HandleAif( ClassDriver->ClassDriverExtension, FibContext ) ) {
6326 +
6327 +                               Handled = TRUE;
6328 +                               break;
6329 +
6330 +                       }
6331 +               }
6332 +
6333 +               ClassDriver = ClassDriver->Next;
6334 +       }
6335 +
6336 +       if (!Handled) {
6337 +
6338 +               //
6339 +               // Set the status of this FIB to be Invalid parameter.
6340 +               //
6341 +
6342 +//             *(FSASTATUS *)Fib->data = ST_INVAL;
6343 +               *(FSASTATUS *)Fib->data = ST_OK;
6344 +
6345 +
6346 +               CompleteAdapterFib(FibContext, sizeof(FSASTATUS));
6347 +
6348 +       }
6349 +}
6350 +
6351 +int
6352 +NormCommandThread(
6353 +    IN PAFA_COMM_ADAPTER Adapter
6354 +    )
6355 +/*++
6356 +
6357 +Routine Description:
6358 +
6359 +    Waits on the commandready event in it's queue. When the event gets set it will
6360 +    pull FIBs off it's queue. It will continue to pull FIBs off till the queue is empty.
6361 +    When the queue is empty it will wait for more FIBs.
6362 +
6363 +Arguments:
6364 +
6365 +    Context is used. All data os global
6366 +    
6367 +Return Value:
6368 +    Nothing.
6369 +    
6370 +--*/
6371 +{
6372 +    PFIB Fib, NewFib;
6373 +       COMM_FIB_CONTEXT FibContext; // for error logging
6374 +    KIRQL SavedIrql;
6375 +       PCOMM_REGION CommRegion = Adapter->CommRegion;
6376 +       PLIST_ENTRY Entry;
6377 +       PGET_ADAPTER_FIB_CONTEXT AdapterFibContext;
6378 +
6379 +       //
6380 +       // We can only have one thread per adapter for AIF's.
6381 +       //
6382 +
6383 +       if (Adapter->AifThreadStarted) {
6384 +               return (EINVAL);
6385 +       }
6386 +
6387 +// cmn_err(CE_DEBUG, "AIF thread started");
6388 +
6389 +       //
6390 +       // Let the DPC know it has a place to send the AIF's to.
6391 +       //
6392 +
6393 +       Adapter->AifThreadStarted = TRUE;
6394 +
6395 +       RtlZeroMemory(&FibContext, sizeof(COMM_FIB_CONTEXT));
6396 +
6397 +       OsSpinLockAcquire(CommRegion->HostNormCmdQue.QueueLock);
6398 +
6399 +    while (TRUE) {
6400 +
6401 +               //
6402 +               // NOTE : the QueueLock is held at the top of each loop.
6403 +               //
6404 +
6405 +               ASSERT(OsSpinLockOwned(CommRegion->HostNormCmdQue.QueueLock));
6406 +
6407 +               while (!IsListEmpty(&(CommRegion->HostNormCmdQue.CommandQueue))) {
6408 +                       PLIST_ENTRY Entry;
6409 +                       PAIFCOMMANDTOHOST AifCommandToHost;
6410 +
6411 +                       Entry = RemoveHeadList(&(CommRegion->HostNormCmdQue.CommandQueue));
6412 +
6413 +                       OsSpinLockRelease(CommRegion->HostNormCmdQue.QueueLock);
6414 +
6415 +                       Fib = CONTAINING_RECORD( Entry, FIB, Header.FibLinks );
6416 +                                               
6417 +                       //
6418 +                       // We will process the FIB here or pass it to a worker thread that is TBD. We Really
6419 +                       // can't do anything at this point since we don't have anything defined for this thread to
6420 +                       // do.
6421 +                       //
6422 +                       
6423 +                       // cmn_err(CE_DEBUG, "Got Fib from the adapter with a NORMAL priority, command 0x%x.\n", Fib->Header.Command);
6424 +
6425 +                       RtlZeroMemory( &FibContext, sizeof(COMM_FIB_CONTEXT) );
6426 +
6427 +
6428 +                   FibContext.NodeTypeCode = FSAFS_NTC_FIB_CONTEXT;
6429 +                   FibContext.NodeByteSize = sizeof( COMM_FIB_CONTEXT );
6430 +                       FibContext.Fib = Fib;
6431 +                       FibContext.FibData = Fib->data;
6432 +                       FibContext.Adapter = Adapter;
6433 +
6434 +                       
6435 +                       //
6436 +                       // We only handle AifRequest fibs from the adapter.
6437 +                       //
6438 +
6439 +                       ASSERT(Fib->Header.Command == AifRequest);
6440 +
6441 +
6442 +                       AifCommandToHost = (PAIFCOMMANDTOHOST) Fib->data;
6443 +
6444 +                       if (AifCommandToHost->command == AifCmdDriverNotify) {
6445 +
6446 +
6447 +
6448 +                               HandleDriverAif( Adapter, &FibContext );
6449 +
6450 +                       } else {
6451 +                                       AAC_UINT32 time_now, time_last;
6452 +                                       time_now = (AAC_UINT32)OsGetSeconds();
6453 +                       
6454 +
6455 +                               OsCvLockAcquire(Adapter->AdapterFibMutex);
6456 +
6457 +                               Entry = Adapter->AdapterFibContextList.Flink;
6458 +
6459 +                               //
6460 +                               // For each Context that is on the AdapterFibContextList, make a copy of the
6461 +                               // fib, and then set the event to wake up the thread that is waiting for it.
6462 +                               //
6463 +
6464 +                               while (Entry != &Adapter->AdapterFibContextList) {
6465 +
6466 +                                       //
6467 +                                       // Extract the AdapterFibContext
6468 +                                       //
6469 +
6470 +                                       AdapterFibContext = CONTAINING_RECORD( Entry, GET_ADAPTER_FIB_CONTEXT, NextContext );
6471 +
6472 +                                       //
6473 +                                       // Check if the queue is getting backlogged
6474 +                                       //
6475 +                                       if ( AdapterFibContext->FibCount > 20 ) {
6476 +                                               time_last = (AAC_UINT32)(AdapterFibContext->FileObject);
6477 +
6478 +                                               //
6479 +                                               // has it been > 2 minutes since the last read off the queue?
6480 +                                               //
6481 +                                               if ((time_now - time_last) > 120) {
6482 +                                                       Entry = Entry->Flink;
6483 +                                                       // cmn_err (CE_WARN, "aifd: Flushing orphaned AdapterFibContext: idle %d seconds, %d fibs",
6484 +                                                       //               time_now - time_last,
6485 +                                                       //               AdapterFibContext->FibCount);
6486 +                                                       FsaCloseAdapterFibContext ( Adapter, AdapterFibContext );
6487 +                                                       continue;
6488 +                                               }
6489 +                                       }
6490 +                                                                       
6491 +//  Warning: sleep possible while holding spinlock
6492 +                                       NewFib = OsAllocMemory(sizeof(FIB), OS_ALLOC_MEM_SLEEP);
6493 +
6494 +                                       if (NewFib) {
6495 +
6496 +                                               //
6497 +                                               // Make the copy of the FIB
6498 +                                               //
6499 +
6500 +                                               RtlCopyMemory(NewFib, Fib, sizeof(FIB));
6501 +
6502 +                                               //
6503 +                                               // Put the FIB onto the AdapterFibContext's FibList
6504 +                                               //
6505 +
6506 +                                               InsertTailList(&AdapterFibContext->FibList, &NewFib->Header.FibLinks);
6507 +                                               AdapterFibContext->FibCount++;
6508 +
6509 +                                               // 
6510 +                                               // Set the event to wake up the thread that will waiting.
6511 +                                               //
6512 +
6513 +                                               OsCv_signal(&AdapterFibContext->UserEvent);
6514 +
6515 +                                       } else {
6516 +
6517 +                                               cmn_err (CE_WARN, "aifd: didn't allocate NewFib");
6518 +
6519 +                                       }
6520 +
6521 +                                       Entry = Entry->Flink;
6522 +                               }
6523 +
6524 +                               //
6525 +                               // Set the status of this FIB
6526 +                               //
6527 +
6528 +                               *(FSASTATUS *)Fib->data = ST_OK;
6529 +                               
6530 +                               CompleteAdapterFib( &FibContext, sizeof(FSASTATUS) );
6531 +
6532 +                               OsCvLockRelease(Adapter->AdapterFibMutex);
6533 +
6534 +                       }
6535 +
6536 +                       OsSpinLockAcquire(CommRegion->HostNormCmdQue.QueueLock);
6537 +
6538 +               }
6539 +
6540 +               //
6541 +               // There are no more AIF's,  call cv_wait_sig to wait for more
6542 +               // to process.
6543 +               //
6544 +
6545 +               // cmn_err(CE_DEBUG, "no more AIF's going to sleep\n");
6546 +
6547 +               if (OsCv_wait_sig( &(CommRegion->HostNormCmdQue.CommandReady), 
6548 +                                                CommRegion->HostNormCmdQue.QueueLock ) == 0) {
6549 +
6550 +                       OsSpinLockRelease(CommRegion->HostNormCmdQue.QueueLock);
6551 +
6552 +                       Adapter->AifThreadStarted = FALSE;
6553 +
6554 +                       // cmn_err(CE_DEBUG, "AifThread awoken by a signal\n");
6555 +                       
6556 +                       return (EINTR);
6557 +                       
6558 +               }                                
6559 +
6560 +               // cmn_err(CE_DEBUG, "Aif thread awake, going to look for more AIF's\n");
6561 +
6562 +       }
6563 +}
6564 +    
6565 +
6566 +PVOID
6567 +FsaGetFibData(
6568 +       IN PFIB_CONTEXT Context
6569 +       )
6570 +{
6571 +    PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
6572 +
6573 +       return ((PVOID)FibContext->Fib->data);
6574 +}          
6575 +                              
6576 +
6577 +#ifdef API_THROTTLE
6578 +
6579 +void ThrottlePeriodEndDpcRtn(
6580 +    IN PKDPC Dpc,
6581 +    IN PVOID DeferredContext,
6582 +    IN PVOID SystemArgument1,
6583 +    IN PVOID SystemArgument2
6584 +    )
6585 +/*++
6586 +
6587 +Routine Description:
6588 +
6589 +    This routine is called as a DPC when a throttle period expires. It
6590 +       restarts all threads suspended due to the throttling flow control.
6591 +       
6592 +       The throttling counted semaphore is signalled for all waiting threads
6593 +       and the indicator of throttling active is cleared.
6594 +
6595 +Arguments:
6596 +
6597 +    Dpc                                - Pointer to Dpc structure. Not used.
6598 +       DefferedContext - Pointer to per-adapter context. This is used to locate the
6599 +                                         throttle information for this adapter.
6600 +    SystemArgument1    - Not used
6601 +       SystemArgument2 - Not used
6602 +       
6603 +Return Value:
6604 +
6605 +       None.
6606 +
6607 +--*/
6608 +{
6609 +       PCOMM_REGION CommRegion;
6610 +       PAFA_COMM_ADAPTER Adapter = (PAFA_COMM_ADAPTER) DeferredContext;
6611 +
6612 +       CommRegion = Adapter->CommRegion;
6613 +
6614 +       //
6615 +       // Acquire the spinlock protecting the throttle status.
6616 +       //
6617 +       OsSpinLockAcquire(CommRegion->AdapNormCmdQue.QueueLock);
6618 +
6619 +       FsaCommPrint("ThrottlePeriodEndDpc\n");
6620 +
6621 +       //
6622 +       // Check that the timer has fired as many times as it was set !
6623 +       //
6624 +
6625 +       CommRegion->ThrottleTimerFires++;
6626 +       ASSERT(CommRegion->ThrottleTimerFires == CommRegion->ThrottleTimerSets);
6627 +
6628 +       //
6629 +       // The throttle period is now over. Restart all threads waiting
6630 +       // on the throttle being released.
6631 +       // Clear the throttle active indicator. This will allow new FIBs
6632 +       // to be sent to the adapter once we release the spinlock on exiting
6633 +       // the DPC. This means all restarted threads will be runnable
6634 +       // threads by then.
6635 +       //
6636 +
6637 +       ASSERT(CommRegion->ThrottleActive == TRUE);             // The throttle had better be on !
6638 +       CommRegion->ThrottleActive = FALSE;                             // This allows new data FIBs to go to the adapter on dpc exit
6639 +
6640 +       OsSpinLockRelease(CommRegion->AdapNormCmdQue.QueueLock);
6641 +}
6642 +
6643 +#endif // #ifdef API_THROTTLE
6644 +
6645 +/*
6646 + * Overrides for Emacs so that we almost follow Linus's tabbing style.
6647 + * Emacs will notice this stuff at the end of the file and automatically
6648 + * adjust the settings for this buffer only.  This must remain at the end
6649 + * of the file.
6650 + * ---------------------------------------------------------------------------
6651 + * Local variables:
6652 + * c-indent-level: 4
6653 + * c-brace-imaginary-offset: 0
6654 + * c-brace-offset: -4
6655 + * c-argdecl-indent: 4
6656 + * c-label-offset: -4
6657 + * c-continued-statement-offset: 4
6658 + * c-continued-brace-offset: 0
6659 + * indent-tabs-mode: nil
6660 + * tab-width: 8
6661 + * End:
6662 + */
6663 diff -burN linux-2.4.9/drivers/scsi/aacraid/dpcsup.c linux/drivers/scsi/aacraid/dpcsup.c
6664 --- linux-2.4.9/drivers/scsi/aacraid/dpcsup.c   Wed Dec 31 18:00:00 1969
6665 +++ linux/drivers/scsi/aacraid/dpcsup.c Thu Aug 16 13:41:30 2001
6666 @@ -0,0 +1,443 @@
6667 +/*++
6668 + * Adaptec aacraid device driver for Linux.
6669 + *
6670 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
6671 + *
6672 + * This program is free software; you can redistribute it and/or modify
6673 + * it under the terms of the GNU General Public License as published by
6674 + * the Free Software Foundation; either version 2, or (at your option)
6675 + * any later version.
6676 + *
6677 + * This program is distributed in the hope that it will be useful,
6678 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
6679 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
6680 + * GNU General Public License for more details.
6681 + *
6682 + * You should have received a copy of the GNU General Public License
6683 + * along with this program; see the file COPYING.  If not, write to
6684 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
6685 + *
6686 + * Module Name:
6687 + *  dpcsup.c
6688 + *
6689 + * Abstract: All DPC processing routines for the cyclone board occur here.
6690 + *
6691 + *
6692 + --*/
6693 +
6694 +static char *ident_dpcsup = "aacraid_ident dpcsup.c 1.0.6 2000/10/09 Adaptec, Inc.";
6695 +
6696 +#include "comprocs.h"
6697 +
6698 +
6699 +//
6700 +//  The Bug check file id for this module
6701 +//
6702 +
6703 +#define BugCheckFileId                   (FSAFS_BUG_CHECK_DPCSUP)
6704 +
6705 +#define Dbg                              (DEBUG_TRACE_DPCSUP)
6706 +
6707 +u_int
6708 +CommonNotFullDpc(
6709 +       IN PCOMM_REGION CommRegion
6710 +    )
6711 +/*++
6712 +
6713 +Routine Description:
6714 +
6715 +    This DPC routine will be queued when the adapter interrupts us to let us know the queue is
6716 +    no longer full. The Isr will pass the queue that we will set the not full event.
6717 +
6718 +Arguments:
6719 +
6720 +    Dpc - Pointer to this routine.
6721 +
6722 +    Dummy - is a pointer to the comm region which is global so we don't need it anyway
6723 +
6724 +    Queue is a pointer to the queue structure we will operate on.
6725 +
6726 +    MoreData2 are DPC parameters we don't need for this function. Maybe we can add some accounting
6727 +        stuff in here.
6728 +
6729 +Return Value:
6730 +    Nothing.
6731 +
6732 +--*/
6733 +{
6734 +
6735 +#ifdef unix_queue_full
6736 +    KeSetEvent(&Queue->QueueFull, 0, FALSE);
6737 +#endif
6738 +
6739 +}
6740 +
6741 +int GatherFibTimes = 0;
6742 +
6743 +// XXX - hack this in until I figure out which header file should contain it. <smb>
6744 +extern ULONG
6745 +FibGetMeterSize(
6746 +    PFIB pFib,
6747 +       ULONG MeterType,
6748 +       char SubCommand
6749 +       );
6750 +
6751 +
6752 +/*++
6753 +
6754 +Routine Description:
6755 +
6756 +    This DPC routine will be queued when the adapter interrupts us to let us know there
6757 +    is a response on our normal priority queue. We will pull off all QE there are and wake
6758 +    up all the waiters before exiting. We will take a spinlock out on the queue before operating
6759 +    on it.
6760 +
6761 +Arguments:
6762 +
6763 +    Dpc - Pointer to this routine.
6764 +
6765 +    OurQueue is a pointer to the queue structure we will operate on.
6766 +
6767 +    MoreData1&2 are DPC parameters we don't need for this function. Maybe we can add some accounting
6768 +        stuff in here.
6769 +
6770 +Return Value:
6771 +    Nothing.
6772 +
6773 +--*/
6774 +u_int
6775 +HostResponseNormalDpc (IN PCOMM_QUE OurQueue)
6776 +{
6777 +    PAFA_COMM_ADAPTER Adapter = OurQueue->Adapter;
6778 +    PQUEUE_ENTRY QueueEntry;
6779 +    PFIB Fib;
6780 +       PCOMM_FIB_CONTEXT FibContext;
6781 +    int Consumed = 0;
6782 +       KIRQL OldIrql;
6783 +
6784 +       LARGE_INTEGER ResponseAllocSize;
6785 +
6786 +#ifdef commdebug
6787 +    FsaCommPrint("entering the host normal reponse dpc routine.\n");
6788 +#endif
6789 +
6790 +       OsSpinLockAcquire( OurQueue->QueueLock );       
6791 +
6792 +    //
6793 +    // Keep pulling response QEs off the response queue and waking
6794 +    // up the waiters until there are no more QEs. We then return
6795 +    // back to the system. If no response was requesed we just
6796 +    // deallocate the Fib here and continue.
6797 +    //
6798 +
6799 + loop:
6800 +    while ( GetConsumerEntry( Adapter, OurQueue, &QueueEntry) ) {
6801 +
6802 +               int IsFastResponse;
6803 +
6804 +               IsFastResponse = (int) (QueueEntry->FibAddress & 0x01);
6805 +               Fib = (PFIB) (QueueEntry->FibAddress & ~0x01);
6806 +
6807 +               FreeConsumerEntry(Adapter, OurQueue, HostNormRespQueue);
6808 +
6809 +               FibContext = (PCOMM_FIB_CONTEXT)Fib->Header.SenderData;
6810 +
6811 +               ASSERT(FibContext->Fib == Fib);
6812 +
6813 +               //
6814 +               // Remove this FibContext from the Outstanding I/O queue.
6815 +               // But only if it has not already been timed out.
6816 +               //
6817 +               // If the fib has been timed out already, then just continue.
6818 +               // The caller has already been notified that the fib timed out.
6819 +               //
6820 +
6821 +               if (!(FibContext->Flags & FIB_CONTEXT_FLAG_TIMED_OUT)) {
6822 +
6823 +                       RemoveEntryList( &FibContext->QueueEntry );
6824 +                       Adapter->CommRegion->AdapNormCmdQue.NumOutstandingIos--;
6825 +
6826 +               } else {
6827 +
6828 +                       FsaCommLogEvent(FibContext,
6829 +                                                       FsaCommData.DeviceObject, 
6830 +                                                       FSAFS_TIMED_OUT_FIB_COMPLETED,
6831 +                                                       STATUS_UNSUCCESSFUL, 
6832 +                                                       BugCheckFileId | __LINE__,
6833 +                                                       FACILITY_FSAFS_ERROR_CODE,
6834 +                                                       NULL,
6835 +                                                       TRUE);                  
6836 +
6837 +                       continue;
6838 +
6839 +               }
6840 +
6841 +               OsSpinLockRelease( OurQueue->QueueLock );
6842 +
6843 +               if (IsFastResponse) {
6844 +
6845 +                       //
6846 +                       // doctor the fib
6847 +                       //
6848 +
6849 +                       *(FSASTATUS *)Fib->data = ST_OK;
6850 +
6851 +                       Fib->Header.XferState |= AdapterProcessed;
6852 +
6853 +               }
6854 +
6855 +               ASSERT((Fib->Header.XferState & (AdapterProcessed | HostOwned | SentFromHost)) == (AdapterProcessed | HostOwned | SentFromHost));
6856 +
6857 +               FIB_COUNTER_INCREMENT(FsaCommData.FibRecved);
6858 +
6859 +               ASSERT(FsaCommData.FibsSent >= FsaCommData.FibRecved);
6860 +
6861 +
6862 +               if (Fib->Header.Command == NuFileSystem) {
6863 +
6864 +                       FSASTATUS *pStatus = (FSASTATUS *)Fib->data;
6865 +
6866 +                       if (*pStatus & 0xffff0000) {
6867 +
6868 +                               ULONG Hint = *pStatus;
6869 +
6870 +                               *pStatus = ST_OK;
6871 +
6872 +/*
6873 +                               DbgPrint("Replacing hint in fid (drive = %d, f1 = 0x%x, f2 = 0x%x, hint = 0x%x, new_hint = 0x%x)\n", 
6874 +                                                IrpContext->NonPaged->FileId.fid_driveno,
6875 +                                                IrpContext->NonPaged->FileId.fid_f1,
6876 +                                                IrpContext->NonPaged->FileId.fid_f2,
6877 +                                                IrpContext->NonPaged->FileId.fid_hint,
6878 +                                                Hint);
6879 +*/
6880 +
6881 +                       }
6882 +
6883 +               }
6884 +
6885 +               if (Fib->Header.XferState & (NoResponseExpected | Async) ) {
6886 +
6887 +                       ASSERT(FibContext->FibCallback);
6888 +
6889 +               if (Fib->Header.XferState & NoResponseExpected)
6890 +                               FIB_COUNTER_INCREMENT(FsaCommData.NoResponseRecved);
6891 +                       else 
6892 +                               FIB_COUNTER_INCREMENT(FsaCommData.AsyncRecved);
6893 +
6894 +                       //
6895 +                       // NOTE:  we can not touch the FibContext after this call, because it may have been
6896 +                       // deallocated.
6897 +                       //
6898 +
6899 +                       FibContext->FibCallback(FibContext->FibCallbackContext, FibContext, STATUS_SUCCESS);
6900 +
6901 +               } else {
6902 +
6903 +                       OsCvLockAcquire( FibContext->FsaEventMutex);
6904 +
6905 +                       FibContext->FibComplete = 1;
6906 +
6907 +                       OsCv_signal( &FibContext->FsaEvent );
6908 +
6909 +                       OsCvLockRelease( FibContext->FsaEventMutex );
6910 +
6911 +                       FIB_COUNTER_INCREMENT(FsaCommData.NormalRecved);
6912 +                       
6913 +               }
6914 +
6915 +
6916 +               Consumed++;
6917 +
6918 +               OsSpinLockAcquire( OurQueue->QueueLock );
6919 +               
6920 +    }
6921 +
6922 +       if (Consumed > FsaCommData.PeakFibsConsumed)
6923 +               FsaCommData.PeakFibsConsumed = Consumed;
6924 +
6925 +       if (Consumed == 0) 
6926 +               FsaCommData.ZeroFibsConsumed++;
6927 +
6928 +       if (FsaCommData.HardInterruptModeration) {
6929 +
6930 +               //
6931 +               // Re-Enable the interrupt from the adapter, then recheck to see if anything has 
6932 +               // been put on the queue.  This removes the race condition that exists between the
6933 +               // last time we checked the queue, and when we re-enabled the interrupt.
6934 +               //
6935 +               // If there is something on the queue, then go handle it.
6936 +               //
6937 +
6938 +               EnableInterrupt( Adapter, HostNormRespQue, FALSE );
6939 +
6940 +               if (ConsumerEntryAvailable( Adapter, OurQueue ) ) {
6941 +
6942 +                       DisableInterrupt( Adapter, HostNormRespQue, FALSE );
6943 +
6944 +                       goto loop;
6945 +
6946 +               }
6947 +       }
6948 +
6949 +#ifdef commdebug
6950 +    FsaCommPrint("Exiting host normal reponse dpc routine after consuming %d QE(s).\n",Consumed);
6951 +#endif
6952 +
6953 +       OsSpinLockRelease( OurQueue->QueueLock );
6954 +
6955 +}
6956 +
6957 +/*++
6958 +
6959 +Routine Description:
6960 +
6961 +    This DPC routine wiol be queued when the adapter interrupts us to let us know there
6962 +    is a response on our high priority queue. We will pull off all QE there are and wake
6963 +    up all the waiters before exiting. We will take a spinlock out on the queue before operating
6964 +    on it.
6965 +
6966 +Arguments:
6967 +
6968 +    Dpc - Pointer to this routine.
6969 +
6970 +    OurQueue is a pointer to the queue structure we will operate on.
6971 +
6972 +    MoreData1&2 are DPC parameters we don't need for this function. Maybe we can add some accounting
6973 +        stuff in here.
6974 +
6975 +Return Value:
6976 +    Nothing.
6977 +
6978 +--*/
6979 +u_int
6980 +HostResponseHighDpc (IN PCOMM_QUE OurQueue)
6981 +{}
6982 +
6983 +
6984 +/*++
6985 +
6986 +Routine Description:
6987 +
6988 +    This DPC routine will be queued when the adapter interrupts us to let us know there
6989 +    is a command on our high priority queue. We will pull off all QE there are and wake
6990 +    up all the waiters before exiting. We will take a spinlock out on the queue before operating
6991 +    on it.
6992 +
6993 +Arguments:
6994 +
6995 +    Dpc - Pointer to this routine.
6996 +
6997 +    OurQueue is a pointer to the queue structure we will operate on.
6998 +
6999 +    MoreData1&2 are DPC parameters we don't need for this function. Maybe we can add some accounting
7000 +        stuff in here.
7001 +
7002 +Return Value:
7003 +    Nothing.
7004 +
7005 +--*/
7006 +u_int
7007 +HostCommandHighDpc (IN PCOMM_QUE OurQueue)
7008 +{}
7009 +
7010 +
7011 +/*++
7012 +
7013 +Routine Description:
7014 +
7015 +    This DPC routine will be queued when the adapter interrupts us to let us know there
7016 +    is a command on our normal priority queue. We will pull off all QE there are and wake
7017 +    up all the waiters before exiting. We will take a spinlock out on the queue before operating
7018 +    on it.
7019 +
7020 +Arguments:
7021 +
7022 +    Dpc - Pointer to this routine.
7023 +
7024 +    OurQueue is a pointer to the queue structure we will operate on.
7025 +
7026 +    MoreData1&2 are DPC parameters we don't need for this function. Maybe we can add some accounting
7027 +        stuff in here.
7028 +
7029 +Return Value:
7030 +    Nothing.
7031 +
7032 +--*/
7033 +u_int
7034 +HostCommandNormDpc (IN PCOMM_QUE OurQueue)
7035 +{
7036 +    PAFA_COMM_ADAPTER Adapter = OurQueue->Adapter;
7037 +    PQUEUE_ENTRY QueueEntry;
7038 +
7039 +       OsSpinLockAcquire( OurQueue->QueueLock );
7040 +
7041 +    //
7042 +    // Keep pulling response QEs off the response queue and waking
7043 +    // up the waiters until there are no more QEs. We then return
7044 +    // back to the system.
7045 +    //
7046 +
7047 +    while ( GetConsumerEntry( Adapter, OurQueue, &QueueEntry) ) {
7048 +
7049 +               PFIB Fib;
7050 +
7051 +               Fib = (PFIB)QueueEntry->FibAddress;
7052 +
7053 +
7054 +               if (Adapter->AifThreadStarted) {
7055 +
7056 +
7057 +//                     cmn_err(CE_CONT, "^Received AIF, putting onto command queue\n");
7058 +
7059 +
7060 +               InsertTailList(&OurQueue->CommandQueue, &Fib->Header.FibLinks);
7061 +               FreeConsumerEntry(Adapter, OurQueue, HostNormCmdQueue);
7062 +               OsCv_signal(&OurQueue->CommandReady);
7063 +
7064 +
7065 +
7066 +               } else {
7067 +
7068 +
7069 +
7070 +                       COMM_FIB_CONTEXT FibContext;
7071 +
7072 +               
7073 +
7074 +               FreeConsumerEntry(Adapter, OurQueue, HostNormCmdQueue);
7075 +
7076 +
7077 +
7078 +                       OsSpinLockRelease( OurQueue->QueueLock );
7079 +
7080 +
7081 +
7082 +//                     cmn_err(CE_CONT, "^Received AIF, thread not started\n");
7083 +
7084 +
7085 +                       RtlZeroMemory( &FibContext, sizeof(COMM_FIB_CONTEXT) );
7086 +
7087 +                   FibContext.NodeTypeCode = FSAFS_NTC_FIB_CONTEXT;
7088 +                   FibContext.NodeByteSize = sizeof( COMM_FIB_CONTEXT );
7089 +                       FibContext.Fib = Fib;
7090 +                       FibContext.FibData = Fib->data;
7091 +                       FibContext.Adapter = Adapter;
7092 +
7093 +                       //
7094 +                       // Set the status of this FIB
7095 +                       //
7096 +
7097 +                       *(FSASTATUS *)Fib->data = ST_OK;
7098 +                               
7099 +                       CompleteAdapterFib( &FibContext, sizeof(FSASTATUS) );
7100 +
7101 +
7102 +
7103 +                       OsSpinLockAcquire( OurQueue->QueueLock );
7104 +               }               
7105 +    }
7106 +
7107 +       OsSpinLockRelease( OurQueue->QueueLock );
7108 +
7109 +}
7110 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/AacGenericTypes.h linux/drivers/scsi/aacraid/include/AacGenericTypes.h
7111 --- linux-2.4.9/drivers/scsi/aacraid/include/AacGenericTypes.h  Wed Dec 31 18:00:00 1969
7112 +++ linux/drivers/scsi/aacraid/include/AacGenericTypes.h        Thu Aug 16 13:41:30 2001
7113 @@ -0,0 +1,57 @@
7114 +/*++
7115 + * Adaptec aacraid device driver for Linux.
7116 + *
7117 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
7118 + *
7119 + * This program is free software; you can redistribute it and/or modify
7120 + * it under the terms of the GNU General Public License as published by
7121 + * the Free Software Foundation; either version 2, or (at your option)
7122 + * any later version.
7123 + *
7124 + * This program is distributed in the hope that it will be useful,
7125 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7126 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
7127 + * GNU General Public License for more details.
7128 + *
7129 + * You should have received a copy of the GNU General Public License
7130 + * along with this program; see the file COPYING.  If not, write to
7131 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
7132 + *
7133 + * Module Name:
7134 + *
7135 + *  AacGenericTypes.h
7136 + *
7137 + * Abstract:
7138 + *
7139 + *     The module defines the generic data types that all of the other header files
7140 + *     depend upon.
7141 + --*/
7142 +
7143 +#ifndef _AAC_GENERIC_TYPES
7144 +#define _AAC_GENERIC_TYPES
7145 +
7146 +static char *ident_AacGeneric = "aacraid_ident AacGenericTypes.h 1.0.6 2000/10/09 Adaptec, Inc.";
7147 +
7148 +typedef        char                    AAC_INT8, *PAAC_INT8;
7149 +typedef short                  AAC_INT16, *PAAC_INT16;
7150 +typedef int                    AAC_INT32, *PAAC_INT32;
7151 +typedef long long              AAC_INT64, *PAAC_INT64;
7152 +
7153 +typedef unsigned char  AAC_UINT8, *PAAC_UINT8;
7154 +typedef unsigned short AAC_UINT16, *PAAC_UINT16;
7155 +typedef unsigned int   AAC_UINT32, *PAAC_UINT32;
7156 +typedef unsigned long long     AAC_UINT64, *PAAC_UINT64;
7157 +
7158 +typedef void                   AAC_VOID, *PAAC_VOID;
7159 +
7160 +//
7161 +// this compiler uses 32 bit enum data types
7162 +//
7163 +
7164 +#define        AAC_32BIT_ENUMS 1
7165 +#define FAILURE 1
7166 +#define INTR_UNCLAIMED 1
7167 +#define INTR_CLAIMED 0
7168 +
7169 +#endif // _AAC_GENERIC_TYPES
7170 +
7171 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/aac_unix_defs.h linux/drivers/scsi/aacraid/include/aac_unix_defs.h
7172 --- linux-2.4.9/drivers/scsi/aacraid/include/aac_unix_defs.h    Wed Dec 31 18:00:00 1969
7173 +++ linux/drivers/scsi/aacraid/include/aac_unix_defs.h  Thu Aug 16 13:41:30 2001
7174 @@ -0,0 +1,300 @@
7175 +/*++
7176 + * Adaptec aacraid device driver for Linux.
7177 + *
7178 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
7179 + *
7180 + * This program is free software; you can redistribute it and/or modify
7181 + * it under the terms of the GNU General Public License as published by
7182 + * the Free Software Foundation; either version 2, or (at your option)
7183 + * any later version.
7184 + *
7185 + * This program is distributed in the hope that it will be useful,
7186 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7187 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
7188 + * GNU General Public License for more details.
7189 + *
7190 + * You should have received a copy of the GNU General Public License
7191 + * along with this program; see the file COPYING.  If not, write to
7192 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
7193 + *
7194 + * Module Name:
7195 + *
7196 + *  aac_unix_defs.h
7197 + *
7198 + * Abstract:
7199 + *
7200 + *     Macro definition and typedefs
7201 + *
7202 + --*/
7203 +
7204 +#ifndef _AAC_UNIX_DEFS
7205 +#define _AAC_UNIX_DEFS
7206 +
7207 +static char *ident_aac_unix = "aacraid_ident aac_unix_defs.h 1.0.6 2000/10/09 Adaptec, Inc.";
7208 +
7209 +#define        AAC_MAX_ADAPTERS        64
7210 +
7211 +#ifndef        TRUE
7212 +#define TRUE   1
7213 +#define FALSE  0
7214 +#endif
7215 +
7216 +#define PAGE_SIZE      4096
7217 +
7218 +typedef        void    VOID;
7219 +typedef VOID   *PVOID;
7220 +
7221 +typedef char           CHAR, *PCHAR;
7222 +typedef unsigned char  UCHAR, *PUCHAR;
7223 +typedef short          SHORT, *PSHORT;
7224 +typedef short          CSHORT, *PCSHORT;
7225 +typedef unsigned short         USHORT, *PUSHORT;
7226 +typedef unsigned long  ULONG, *PULONG;
7227 +typedef long           LONG, *PLONG;
7228 +
7229 +typedef unsigned long  BOOLEAN;
7230 +
7231 +typedef unsigned long  AAC_STATUS, *PNT_STATUS;
7232 +
7233 +typedef struct {
7234 +       unsigned long   LowPart;
7235 +       unsigned long   HighPart;
7236 +} LARGE_INTEGER;
7237 +
7238 +typedef LARGE_INTEGER  PHYSICAL_ADDRESS;
7239 +
7240 +
7241 +typedef struct _AFA_IOCTL_CMD {
7242 +       int             cmd;
7243 +       intptr_t        arg;
7244 +       int             flag;
7245 +       cred_t          *cred_p;
7246 +       int             *rval_p;
7247 +} AFA_IOCTL_CMD, *PAFA_IOCTL_CMD;
7248 +
7249 +
7250 +//
7251 +//  Singly linked list structure. Can be used as either a list head, or
7252 +//  as link words.
7253 +//
7254 +
7255 +typedef struct _SINGLE_LIST_ENTRY {
7256 +    struct _SINGLE_LIST_ENTRY *Next;
7257 +} SINGLE_LIST_ENTRY, *PSINGLE_LIST_ENTRY;
7258 +
7259 +
7260 +//
7261 +// Calculate the address of the base of the structure given its type, and an
7262 +// address of a field within the structure.
7263 +//
7264 +
7265 +#define CONTAINING_RECORD(address, type, field) ((type *)( \
7266 +                                                  (PCHAR)(address) - \
7267 +                                                  (PCHAR)(&((type *)0)->field)))
7268 +
7269 +typedef        PVOID   PMDL;
7270 +typedef PVOID  PDEVICE_OBJECT;
7271 +typedef PVOID  PADAPTER_OBJECT;
7272 +typedef ULONG  KIRQL;
7273 +typedef PVOID  HANDLE;
7274 +typedef PVOID  KDPC, *PKDPC;
7275 +typedef PVOID  PFILE_OBJECT;
7276 +typedef PVOID  PIRP;
7277 +typedef PVOID  PDRIVER_OBJECT;
7278 +typedef ULONG  KTIMER;
7279 +
7280 +
7281 +#define        STATUS_SUCCESS          0x00000000
7282 +#define STATUS_PENDING         0x40000001
7283 +#define STATUS_IO_TIMEOUT                      0xc0000001
7284 +#define STATUS_UNSUCCESSFUL                    0xc0000002
7285 +#define STATUS_INSUFFICIENT_RESOURCES  0xc0000005
7286 +#define STATUS_BUFFER_OVERFLOW         0xc0000003
7287 +
7288 +
7289 +#define OUT
7290 +
7291 +
7292 +
7293 +typedef u_int
7294 +(*PUNIX_INTR_HANDLER)(caddr_t Arg);
7295 +
7296 +//
7297 +// Zone Allocation
7298 +//
7299 +
7300 +typedef struct _ZONE_SEGMENT_HEADER {
7301 +    SINGLE_LIST_ENTRY SegmentList;
7302 +    PVOID Reserved;
7303 +} ZONE_SEGMENT_HEADER, *PZONE_SEGMENT_HEADER;
7304 +
7305 +typedef struct _ZONE_HEADER {
7306 +    SINGLE_LIST_ENTRY FreeList;
7307 +    SINGLE_LIST_ENTRY SegmentList;
7308 +    ULONG BlockSize;
7309 +    ULONG TotalSegmentSize;
7310 +} ZONE_HEADER, *PZONE_HEADER;
7311 +
7312 +
7313 +//++
7314 +//
7315 +// PVOID
7316 +// ExAllocateFromZone(
7317 +//     IN PZONE_HEADER Zone
7318 +//     )
7319 +//
7320 +// Routine Description:
7321 +//
7322 +//     This routine removes an entry from the zone and returns a pointer to it.
7323 +//
7324 +// Arguments:
7325 +//
7326 +//     Zone - Pointer to the zone header controlling the storage from which the
7327 +//         entry is to be allocated.
7328 +//
7329 +// Return Value:
7330 +//
7331 +//     The function value is a pointer to the storage allocated from the zone.
7332 +//
7333 +//--
7334 +
7335 +#define ExAllocateFromZone(Zone) \
7336 +    (PVOID)((Zone)->FreeList.Next); \
7337 +    if ( (Zone)->FreeList.Next ) (Zone)->FreeList.Next = (Zone)->FreeList.Next->Next
7338 +
7339 +//++
7340 +//
7341 +// PVOID
7342 +// ExFreeToZone(
7343 +//     IN PZONE_HEADER Zone,
7344 +//     IN PVOID Block
7345 +//     )
7346 +//
7347 +// Routine Description:
7348 +//
7349 +//     This routine places the specified block of storage back onto the free
7350 +//     list in the specified zone.
7351 +//
7352 +// Arguments:
7353 +//
7354 +//     Zone - Pointer to the zone header controlling the storage to which the
7355 +//         entry is to be inserted.
7356 +//
7357 +//     Block - Pointer to the block of storage to be freed back to the zone.
7358 +//
7359 +// Return Value:
7360 +//
7361 +//     Pointer to previous block of storage that was at the head of the free
7362 +//         list.  NULL implies the zone went from no available free blocks to
7363 +//         at least one free block.
7364 +//
7365 +//--
7366 +
7367 +#define ExFreeToZone(Zone,Block)                                    \
7368 +    ( ((PSINGLE_LIST_ENTRY)(Block))->Next = (Zone)->FreeList.Next,  \
7369 +      (Zone)->FreeList.Next = ((PSINGLE_LIST_ENTRY)(Block)),        \
7370 +      ((PSINGLE_LIST_ENTRY)(Block))->Next                           \
7371 +    )
7372 +
7373 +//++
7374 +//
7375 +// BOOLEAN
7376 +// ExIsFullZone(
7377 +//     IN PZONE_HEADER Zone
7378 +//     )
7379 +//
7380 +// Routine Description:
7381 +//
7382 +//     This routine determines if the specified zone is full or not.  A zone
7383 +//     is considered full if the free list is empty.
7384 +//
7385 +// Arguments:
7386 +//
7387 +//     Zone - Pointer to the zone header to be tested.
7388 +//
7389 +// Return Value:
7390 +//
7391 +//     TRUE if the zone is full and FALSE otherwise.
7392 +//
7393 +//--
7394 +
7395 +#define ExIsFullZone(Zone) \
7396 +    ( (Zone)->FreeList.Next == (PSINGLE_LIST_ENTRY)NULL )
7397 +
7398 +
7399 +#define RtlCopyMemory( Destination, Source, Size )     bcopy( (Source), (Destination), (Size) )
7400 +#define RtlZeroMemory( Destination, Size )                     bzero( (Destination), (Size) )
7401 +
7402 +//
7403 +//  Doubly-linked list manipulation routines.  Implemented as macros
7404 +//  but logically these are procedures.
7405 +//
7406 +
7407 +//
7408 +//  VOID
7409 +//  InitializeListHead(
7410 +//      PLIST_ENTRY ListHead
7411 +//      );
7412 +//
7413 +
7414 +#define InitializeListHead(ListHead) (\
7415 +    (ListHead)->Flink = (ListHead)->Blink = (ListHead))
7416 +
7417 +//
7418 +//  BOOLEAN
7419 +//  IsListEmpty(
7420 +//      PLIST_ENTRY ListHead
7421 +//      );
7422 +//
7423 +
7424 +#define IsListEmpty(ListHead) \
7425 +    ((ListHead)->Flink == (ListHead))
7426 +
7427 +//
7428 +//  PLIST_ENTRY
7429 +//  RemoveHeadList(
7430 +//      PLIST_ENTRY ListHead
7431 +//      );
7432 +//
7433 +
7434 +#define RemoveHeadList(ListHead) \
7435 +    (ListHead)->Flink;\
7436 +    {RemoveEntryList((ListHead)->Flink)}
7437 +
7438 +
7439 +//
7440 +//  VOID
7441 +//  RemoveEntryList(
7442 +//      PLIST_ENTRY Entry
7443 +//      );
7444 +//
7445 +
7446 +#define RemoveEntryList(Entry) {\
7447 +    PLIST_ENTRY _EX_Blink;\
7448 +    PLIST_ENTRY _EX_Flink;\
7449 +    _EX_Flink = (Entry)->Flink;\
7450 +    _EX_Blink = (Entry)->Blink;\
7451 +    _EX_Blink->Flink = _EX_Flink;\
7452 +    _EX_Flink->Blink = _EX_Blink;\
7453 +    }
7454 +
7455 +//
7456 +//  VOID
7457 +//  InsertTailList(
7458 +//      PLIST_ENTRY ListHead,
7459 +//      PLIST_ENTRY Entry
7460 +//      );
7461 +//
7462 +
7463 +#define InsertTailList(ListHead,Entry) {\
7464 +    PLIST_ENTRY _EX_Blink;\
7465 +    PLIST_ENTRY _EX_ListHead;\
7466 +    _EX_ListHead = (ListHead);\
7467 +    _EX_Blink = _EX_ListHead->Blink;\
7468 +    (Entry)->Flink = _EX_ListHead;\
7469 +    (Entry)->Blink = _EX_Blink;\
7470 +    _EX_Blink->Flink = (Entry);\
7471 +    _EX_ListHead->Blink = (Entry);\
7472 +    }
7473 +
7474 +#endif /* AAC_UNIX_DEFS */
7475 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/adapter.h linux/drivers/scsi/aacraid/include/adapter.h
7476 --- linux-2.4.9/drivers/scsi/aacraid/include/adapter.h  Wed Dec 31 18:00:00 1969
7477 +++ linux/drivers/scsi/aacraid/include/adapter.h        Thu Aug 16 13:41:30 2001
7478 @@ -0,0 +1,164 @@
7479 +/*++
7480 + * Adaptec aacraid device driver for Linux.
7481 + *
7482 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
7483 + *
7484 + * This program is free software; you can redistribute it and/or modify
7485 + * it under the terms of the GNU General Public License as published by
7486 + * the Free Software Foundation; either version 2, or (at your option)
7487 + * any later version.
7488 + *
7489 + * This program is distributed in the hope that it will be useful,
7490 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7491 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
7492 + * GNU General Public License for more details.
7493 + *
7494 + * You should have received a copy of the GNU General Public License
7495 + * along with this program; see the file COPYING.  If not, write to
7496 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
7497 + *
7498 + * Module Name:
7499 + *
7500 + *   Adapter.h
7501 + *
7502 + * Abstract:
7503 + *   The module contains the definitions for a comm layer view of the adapter.
7504 + *
7505 + *
7506 + *
7507 + --*/
7508 +
7509 +#ifndef _ADAPTER_
7510 +#define _ADAPTER_
7511 +
7512 +static char *ident_adapter = "aacraid_ident adapter.h 1.0.6 2000/10/09 Adaptec, Inc.";
7513 +
7514 +typedef struct _GET_ADAPTER_FIB_CONTEXT {
7515 +
7516 +       NODE_TYPE_CODE          NodeTypeCode;   // used for verification of structure   
7517 +       NODE_BYTE_SIZE          NodeByteSize;
7518 +       PFILE_OBJECT            FileObject;     // used for cleanup
7519 +       LIST_ENTRY              NextContext;    // used to link context's into a linked list
7520 +       OS_CV_T                 UserEvent;      // this is used to wait for the next fib to arrive.
7521 +       BOOLEAN                 WaitingForFib;  // Set to true when thread is in WaitForSingleObject
7522 +       ULONG                   FibCount;       // total number of FIBs on FibList
7523 +       LIST_ENTRY              FibList;
7524 +} GET_ADAPTER_FIB_CONTEXT;
7525 +typedef GET_ADAPTER_FIB_CONTEXT *PGET_ADAPTER_FIB_CONTEXT;
7526 +
7527 +
7528 +typedef struct _FIB_CONTEXT_ZONE_SEGMENT {
7529 +
7530 +       struct _FIB_CONTEXT_ZONE_SEGMENT        *Next;
7531 +       ULONG                                   FibContextSegmentSize;
7532 +       PVOID                                   FibContextSegment;
7533 +       ULONG                                   ExtendSize;
7534 +       MAPFIB_CONTEXT                          MapFibContext;
7535 +
7536 +} FIB_CONTEXT_ZONE_SEGMENT;
7537 +typedef FIB_CONTEXT_ZONE_SEGMENT *PFIB_CONTEXT_ZONE_SEGMENT;
7538 +
7539 +typedef struct _AFA_COMM_ADAPTER {
7540 +
7541 +       struct _AFA_COMM_ADAPTER        *NextAdapter;
7542 +
7543 +    //
7544 +    //  The following fields are used to allocate FIB context structures
7545 +    //  using the zone allocator, and other fixed sized structures from a
7546 +    //  small cache.  The mutex protects access to the zone/lists
7547 +    //
7548 +
7549 +    ZONE_HEADER                FibContextZone;
7550 +       OS_SPINLOCK                     *FibContextZoneSpinLock;
7551 +       int                             FibContextZoneExtendSize;
7552 +
7553 +       PFIB_CONTEXT_ZONE_SEGMENT       FibContextSegmentList;
7554 +
7555 +       PVOID                           FibContextTimedOutList;
7556 +
7557 +       PFIB                            SyncFib;
7558 +       ULONG                           SyncFibPhysicalAddress;
7559 +
7560 +       PCOMM_REGION            CommRegion;
7561 +
7562 +       OS_SPINLOCK_COOKIE      SpinLockCookie;
7563 +
7564 +       //
7565 +       // The user API will use an IOCTL to register itself to receive FIBs
7566 +       // from the adapter.  The following list is used to keep track of all
7567 +       // the threads that have requested these FIBs.  The mutex is used to 
7568 +       // synchronize access to all data associated with the adapter fibs.
7569 +       //
7570 +       LIST_ENTRY                      AdapterFibContextList;
7571 +       OS_CVLOCK                       *AdapterFibMutex;
7572 +
7573 +       //
7574 +       // The following holds which FileObject is allow to send configuration
7575 +       // commands to the adapter that would modify the configuration.
7576 +       //
7577 +       // This is controlled by the FSACTL_OPEN_ADAPTER_CONFIG and FSACTL_CLOSE_ADAPTER_CONFIG
7578 +       // ioctls.
7579 +       //
7580 +       PFILE_OBJECT            AdapterConfigFileObject;
7581 +
7582 +       //
7583 +       // The following is really here because of the simulator
7584 +       //
7585 +       BOOLEAN                         InterruptsBelowDpc;
7586 +
7587 +       //
7588 +       // The following is the device specific extension.
7589 +       //
7590 +       PVOID                   AdapterExtension;       
7591 +       PFSAPORT_FUNCS          AdapterFuncs;
7592 +       void                    *Dip;
7593 +
7594 +       //
7595 +       // The following are user variables that are specific to the mini port.
7596 +       //
7597 +       PFSA_USER_VAR           AdapterUserVars;
7598 +       ULONG                   AdapterUserVarsSize;
7599 +
7600 +       //
7601 +       // The following is the number of the individual adapter..i.e. \Device\Afa0
7602 +       //
7603 +       LONG                    AdapterNumber;
7604 +
7605 +       AFACOMM_FUNCS           CommFuncs;
7606 +
7607 +       PAFA_CLASS_DRIVER       ClassDriverList;
7608 +
7609 +       BOOLEAN                 AifThreadStarted;
7610 +
7611 +} AFA_COMM_ADAPTER;
7612 +
7613 +typedef AFA_COMM_ADAPTER *PAFA_COMM_ADAPTER;
7614 +
7615 +
7616 +#define FsaAllocateAdapterCommArea(Adapter, BaseAddress, Size, Alignment) \
7617 +       Adapter->AdapterFuncs->AllocateAdapterCommArea(Adapter->AdapterExtension, BaseAddress, Size, Alignment)
7618 +
7619 +#define FsaFreeAdapterCommArea(Adapter) \
7620 +       Adapter->AdapterFuncs->FreeAdapterCommArea(Adapter->AdapterExtension)
7621 +
7622 +
7623 +#define AllocateAndMapFibSpace(Adapter, MapFibContext) \
7624 +       Adapter->AdapterFuncs->AllocateAndMapFibSpace(Adapter->AdapterExtension, MapFibContext)
7625 +
7626 +#define UnmapAndFreeFibSpace(Adapter, MapFibContext) \
7627 +       Adapter->AdapterFuncs->UnmapAndFreeFibSpace(Adapter->AdapterExtension, MapFibContext)
7628 +
7629 +#define InterruptAdapter(Adapter) \
7630 +       Adapter->AdapterFuncs->InterruptAdapter(Adapter->AdapterExtension)
7631 +
7632 +#define NotifyAdapter(Adapter, AdapterEvent) \
7633 +       Adapter->AdapterFuncs->NotifyAdapter(Adapter->AdapterExtension, AdapterEvent)
7634 +
7635 +#define EnableInterrupt(Adapter, AdapterEvent, AtDeviceIrq) \
7636 +       Adapter->AdapterFuncs->EnableInterrupt(Adapter->AdapterExtension, AdapterEvent, AtDeviceIrq)
7637 +
7638 +#define DisableInterrupt(Adapter, AdapterEvent, AtDeviceIrq) \
7639 +       Adapter->AdapterFuncs->DisableInterrupt(Adapter->AdapterExtension, AdapterEvent, AtDeviceIrq)
7640 +
7641 +
7642 +#endif // _ADAPTER_
7643 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/afacomm.h linux/drivers/scsi/aacraid/include/afacomm.h
7644 --- linux-2.4.9/drivers/scsi/aacraid/include/afacomm.h  Wed Dec 31 18:00:00 1969
7645 +++ linux/drivers/scsi/aacraid/include/afacomm.h        Thu Aug 16 13:41:30 2001
7646 @@ -0,0 +1,191 @@
7647 +/*++
7648 + * Adaptec aacraid device driver for Linux.
7649 + *
7650 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
7651 + *
7652 + * This program is free software; you can redistribute it and/or modify
7653 + * it under the terms of the GNU General Public License as published by
7654 + * the Free Software Foundation; either version 2, or (at your option)
7655 + * any later version.
7656 + *
7657 + * This program is distributed in the hope that it will be useful,
7658 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7659 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
7660 + * GNU General Public License for more details.
7661 + *
7662 + * You should have received a copy of the GNU General Public License
7663 + * along with this program; see the file COPYING.  If not, write to
7664 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
7665 + *
7666 + * Module Name:
7667 + *   AfaComm.h
7668 + *
7669 + * Abstract:
7670 + *   This module defines all of the external interfaces to the AFA comm layer.
7671 + *
7672 + *
7673 + *
7674 + --*/
7675 +#ifndef _AFACOMM_
7676 +#define _AFACOMM_
7677 +
7678 +static char *ident_afacomm = "aacraid_ident afacomm.h 1.0.6 2000/10/09 Adaptec, Inc.";
7679 +
7680 +#include "fsaport.h"
7681 +
7682 +typedef void   *PFIB_CONTEXT;
7683 +
7684 +typedef VOID
7685 +(*PFIB_CALLBACK)(
7686 +       PVOID           FibCallbackContext,
7687 +       PFIB_CONTEXT    FibContext,
7688 +       AAC_STATUS      Status
7689 +       );
7690 +
7691 +
7692 +typedef PFIB_CONTEXT
7693 +(*PAFA_COMM_ALLOCATE_FIB) (
7694 +       IN PVOID AdapterExtension
7695 +    );
7696 +
7697 +typedef VOID
7698 +(*PAFA_COMM_FREE_FIB) (
7699 +    IN PFIB_CONTEXT FibContext
7700 +    );
7701 +
7702 +
7703 +typedef AAC_STATUS
7704 +(*PAFA_COMM_DEALLOCATE_FIB) (
7705 +    IN PFIB_CONTEXT FibContext
7706 +    );
7707 +
7708 +
7709 +typedef VOID
7710 +(*PAFA_COMM_FREE_FIB_FROM_DPC) (
7711 +    IN PFIB_CONTEXT FibContext
7712 +    );
7713 +
7714 +typedef AAC_STATUS
7715 +(*PAFA_COMM_INITIALIZE_FIB) (
7716 +       IN PFIB_CONTEXT FibContext
7717 +    );
7718 +
7719 +typedef PVOID
7720 +(*PAFA_COMM_GET_FIB_DATA) (
7721 +       IN PFIB_CONTEXT FibContext
7722 +       );
7723 +
7724 +typedef AAC_STATUS
7725 +(*PAFA_COMM_SEND_FIB) (
7726 +    IN FIB_COMMAND Command, 
7727 +       IN PFIB_CONTEXT FibContext,
7728 +    IN ULONG Size,
7729 +    IN COMM_PRIORITIES Priority,
7730 +    IN BOOLEAN Wait,
7731 +    IN PVOID WaitOn,
7732 +    IN BOOLEAN ResponseExpected,
7733 +       IN PFIB_CALLBACK FibCallback,
7734 +       IN PVOID FibCallbackContext
7735 +    );
7736 +
7737 +typedef AAC_STATUS
7738 +(*PAFA_COMM_COMPLETE_FIB) (
7739 +       IN PFIB_CONTEXT FibContext
7740 +    );
7741 +
7742 +typedef AAC_STATUS
7743 +(*PAFA_COMM_COMPLETE_ADAPTER_FIB) (
7744 +       IN PFIB_CONTEXT FibContext,
7745 +       IN USHORT Size
7746 +    );
7747 +
7748 +typedef BOOLEAN
7749 +(*PAFA_COMM_SEND_SYNCH_FIB) (
7750 +       PVOID                   AdapterExtension,
7751 +       FIB_COMMAND     Command,
7752 +       PVOID                   Data,
7753 +       USHORT                  Size,
7754 +       PVOID                   Response,
7755 +       USHORT                  *ResponseSize
7756 +       );
7757 +
7758 +
7759 +typedef struct _AFACOMM_FUNCS {
7760 +       ULONG                                   SizeOfAfaCommFuncs;
7761 +       PAFA_COMM_ALLOCATE_FIB                  AllocateFib;
7762 +       PAFA_COMM_FREE_FIB                      FreeFib;
7763 +       PAFA_COMM_FREE_FIB_FROM_DPC             FreeFibFromDpc;
7764 +       PAFA_COMM_DEALLOCATE_FIB                DeallocateFib;
7765 +       PAFA_COMM_INITIALIZE_FIB                InitializeFib;
7766 +       PAFA_COMM_GET_FIB_DATA                  GetFibData;
7767 +       PAFA_COMM_SEND_FIB                      SendFib;
7768 +       PAFA_COMM_COMPLETE_FIB                  CompleteFib;
7769 +       PAFA_COMM_COMPLETE_ADAPTER_FIB          CompleteAdapterFib;
7770 +       PAFA_COMM_SEND_SYNCH_FIB                SendSynchFib;
7771 +       PFSA_FREE_DMA_RESOURCES                 FreeDmaResources;
7772 +       PFSA_BUILD_SGMAP                        BuildSgMap;
7773 +       PFSA_ADAPTER_ADDR_TO_SYSTEM_ADDR        AdapterAddressToSystemAddress;
7774 +} AFACOMM_FUNCS;
7775 +typedef AFACOMM_FUNCS *PAFACOMM_FUNCS;
7776 +
7777 +
7778 +typedef AAC_STATUS
7779 +(*PAFA_CLASS_OPEN_ADAPTER) (
7780 +       IN PVOID Adapter
7781 +       );
7782 +
7783 +
7784 +typedef AAC_STATUS
7785 +(*PAFA_CLASS_CLOSE_ADAPTER) (
7786 +       IN PVOID Adapter
7787 +       );
7788 +
7789 +
7790 +typedef BOOLEAN
7791 +(*PAFA_CLASS_DEV_CONTROL) (
7792 +       IN PVOID Adapter,
7793 +       IN PAFA_IOCTL_CMD       IoctlCmdPtr,
7794 +       OUT int * Status
7795 +       );
7796 +
7797 +typedef BOOLEAN
7798 +(*PAFA_CLASS_HANDLE_AIF) (
7799 +       IN PVOID Adapter,
7800 +       IN PFIB_CONTEXT FibContext
7801 +       );
7802 +
7803 +
7804 +typedef struct _AFA_NEW_CLASS_DRIVER {
7805 +       PVOID                           ClassDriverExtension;
7806 +       PAFA_CLASS_OPEN_ADAPTER         OpenAdapter;
7807 +        PAFA_CLASS_CLOSE_ADAPTER       CloseAdapter;
7808 +        PAFA_CLASS_DEV_CONTROL                 DeviceControl;
7809 +       PAFA_CLASS_HANDLE_AIF           HandleAif;
7810 +       PFSA_USER_VAR                   UserVars;
7811 +       ULONG                           NumUserVars;
7812 +} AFA_NEW_CLASS_DRIVER;
7813 +typedef AFA_NEW_CLASS_DRIVER *PAFA_NEW_CLASS_DRIVER;
7814 +
7815 +
7816 +typedef struct _AFA_NEW_CLASS_DRIVER_RESPONSE {
7817 +       PAFACOMM_FUNCS          CommFuncs;
7818 +       PVOID                   CommPortExtension;
7819 +       PVOID                   MiniPortExtension;
7820 +       OS_SPINLOCK_COOKIE      SpinLockCookie;
7821 +       void                    *Dip;
7822 +} AFA_NEW_CLASS_DRIVER_RESPONSE;
7823 +typedef AFA_NEW_CLASS_DRIVER_RESPONSE *PAFA_NEW_CLASS_DRIVER_RESPONSE;
7824 +
7825 +
7826 +typedef struct _AFA_CLASS_DRIVER {
7827 +       struct _AFA_CLASS_DRIVER        *Next;
7828 +       PVOID                           ClassDriverExtension;
7829 +       PAFA_CLASS_OPEN_ADAPTER         OpenAdapter;
7830 +       PAFA_CLASS_CLOSE_ADAPTER        CloseAdapter;
7831 +       PAFA_CLASS_DEV_CONTROL          DeviceControl;
7832 +       PAFA_CLASS_HANDLE_AIF           HandleAif;
7833 +} AFA_CLASS_DRIVER;
7834 +typedef AFA_CLASS_DRIVER *PAFA_CLASS_DRIVER;
7835 +
7836 +
7837 +#endif // _AFACOMM_
7838 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/aifstruc.h linux/drivers/scsi/aacraid/include/aifstruc.h
7839 --- linux-2.4.9/drivers/scsi/aacraid/include/aifstruc.h Wed Dec 31 18:00:00 1969
7840 +++ linux/drivers/scsi/aacraid/include/aifstruc.h       Thu Aug 16 13:41:30 2001
7841 @@ -0,0 +1,319 @@
7842 +/*++
7843 + * Adaptec aacraid device driver for Linux.
7844 + *
7845 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
7846 + *
7847 + * This program is free software; you can redistribute it and/or modify
7848 + * it under the terms of the GNU General Public License as published by
7849 + * the Free Software Foundation; either version 2, or (at your option)
7850 + * any later version.
7851 + *
7852 + * This program is distributed in the hope that it will be useful,
7853 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7854 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
7855 + * GNU General Public License for more details.
7856 + *
7857 + * You should have received a copy of the GNU General Public License
7858 + * along with this program; see the file COPYING.  If not, write to
7859 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
7860 + *
7861 + * Module Name:
7862 + *   Aifstruc.h
7863 + *
7864 + * Abstract:
7865 + *   Define all shared data types relating to
7866 + *   the set of features utilizing Adapter
7867 + *   Initiated Fibs.
7868 + *
7869 + *
7870 + *
7871 + --*/
7872 +#ifndef _AIFSTRUC_H
7873 +#define _AIFSTRUC_H
7874 +
7875 +static char *ident_aifstruc = "aacraid_ident aifstruc.h 1.0.6 2000/10/09 Adaptec, Inc.";
7876 +
7877 +#include <protocol.h>
7878 +
7879 +//
7880 +//     Progress report structure definitions
7881 +//
7882 +typedef enum {
7883 +       AifJobStsSuccess = 1,
7884 +       AifJobStsFinished,
7885 +       AifJobStsAborted,
7886 +       AifJobStsFailed,
7887 +       AifJobStsLastReportMarker = 100, // All before mean last report
7888 +       AifJobStsSuspended,
7889 +       AifJobStsRunning
7890 +} _E_AifJobStatus;
7891 +
7892 +#ifdef AAC_32BIT_ENUMS
7893 +typedef        _E_AifJobStatus AifJobStatus;
7894 +#else
7895 +typedef        AAC_UINT32              AifJobStatus;
7896 +#endif
7897 +
7898 +
7899 +typedef enum {
7900 +       AifJobScsiMin = 1,              // Minimum value for Scsi operation
7901 +       AifJobScsiZero,                 // SCSI device clear operation
7902 +       AifJobScsiVerify,               // SCSI device Verify operation NO REPAIR
7903 +       AifJobScsiExercise,             // SCSI device Exercise operation
7904 +       AifJobScsiVerifyRepair, // SCSI device Verify operation WITH repair
7905 +       // Add new SCSI task types above this line
7906 +       AifJobScsiMax = 99,             // Max Scsi value
7907 +       AifJobCtrMin,                   // Min Ctr op value
7908 +       AifJobCtrZero,                  // Container clear operation
7909 +       AifJobCtrCopy,                  // Container copy operation
7910 +       AifJobCtrCreateMirror,  // Container Create Mirror operation
7911 +       AifJobCtrMergeMirror,   // Container Merge Mirror operation
7912 +       AifJobCtrScrubMirror,   // Container Scrub Mirror operation
7913 +       AifJobCtrRebuildRaid5,  // Container Rebuild Raid5 operation
7914 +       AifJobCtrScrubRaid5,    // Container Scrub Raid5 operation
7915 +       AifJobCtrMorph,                 // Container morph operation
7916 +       AifJobCtrPartCopy,              // Container Partition copy operation
7917 +       AifJobCtrRebuildMirror, // Container Rebuild Mirror operation
7918 +       AifJobCtrCrazyCache,            // crazy cache
7919 +       // Add new container task types above this line
7920 +       AifJobCtrMax = 199,             // Max Ctr type operation
7921 +       AifJobFsMin,                    // Min Fs type operation
7922 +       AifJobFsCreate,                 // File System Create operation
7923 +       AifJobFsVerify,                 // File System Verify operation
7924 +       AifJobFsExtend,                 // File System Extend operation
7925 +       // Add new file system task types above this line
7926 +       AifJobFsMax = 299,              // Max Fs type operation
7927 +       // Add new API task types here
7928 +       AifJobApiFormatNTFS,    // Format a drive to NTFS
7929 +       AifJobApiFormatFAT,             // Format a drive to FAT
7930 +       AifJobApiUpdateSnapshot, // update the read/write half of a snapshot
7931 +       AifJobApiFormatFAT32,   // Format a drive to FAT32
7932 +       AifJobApiMax = 399,             // Max API type operation
7933 +       AifJobCtlContinuousCtrVerify,   // Controller operation
7934 +       AifJobCtlMax = 499              // Max Controller type operation
7935 +
7936 +} _E_AifJobType;
7937 +
7938 +#ifdef AAC_32BIT_ENUMS
7939 +typedef        _E_AifJobType   AifJobType;
7940 +#else
7941 +typedef        AAC_UINT32              AifJobType;
7942 +#endif
7943 +
7944 +union SrcContainer {
7945 +       AAC_UINT32 from;
7946 +       AAC_UINT32 master;
7947 +       AAC_UINT32 container;
7948 +};
7949 +
7950 +union DstContainer {
7951 +       AAC_UINT32 to;
7952 +       AAC_UINT32 slave;
7953 +       AAC_UINT32 container;
7954 +};
7955 +
7956 +
7957 +struct AifContainers {
7958 +       union SrcContainer src;
7959 +       union DstContainer dst;
7960 +};
7961 +
7962 +union AifJobClient {
7963 +       
7964 +       struct AifContainers container; // For Container nd file system progress ops;
7965 +       AAC_INT32 scsi_dh;                      // For SCSI progress ops
7966 +};
7967 +
7968 +struct AifJobDesc {
7969 +       AAC_UINT32 jobID;                       // DO NOT FILL IN! Will be filled in by AIF
7970 +       AifJobType type;                // Operation that is being performed
7971 +       union AifJobClient client; // Details
7972 +};
7973 +
7974 +struct AifJobProgressReport {
7975 +       struct AifJobDesc jd;
7976 +       AifJobStatus status;
7977 +       AAC_UINT32 finalTick;
7978 +       AAC_UINT32 currentTick;
7979 +       AAC_UINT32 jobSpecificData1;
7980 +       AAC_UINT32 jobSpecificData2;
7981 +};
7982 +
7983 +//
7984 +//     Notification of events structure definition starts here
7985 +//
7986 +typedef enum {
7987 +       // General application notifies start here
7988 +       AifEnGeneric = 1,                       // Generic notification
7989 +       AifEnTaskComplete,                      // Task has completed
7990 +       AifEnConfigChange,                      // Adapter configuration change occurred
7991 +       AifEnContainerChange,           // Adapter specific container configuration change
7992 +       AifEnDeviceFailure,                     // SCSI device failed
7993 +       AifEnMirrorFailover,            // Mirror failover started
7994 +       AifEnContainerEvent,            // Significant container event
7995 +       AifEnFileSystemChange,          // File system changed
7996 +       AifEnConfigPause,                       // Container pause event
7997 +       AifEnConfigResume,                      // Container resume event
7998 +       AifEnFailoverChange,            // Failover space assignment changed
7999 +       AifEnRAID5RebuildDone,          // RAID5 rebuild finished
8000 +       AifEnEnclosureManagement,       // Enclosure management event
8001 +       AifEnBatteryEvent,                      // Significant NV battery event
8002 +       AifEnAddContainer,                      // A new container was created.
8003 +       AifEnDeleteContainer,           // A container was deleted.
8004 +       AifEnSMARTEvent,            // SMART Event
8005 +       AifEnBatteryNeedsRecond,        // The battery needs reconditioning
8006 +       AifEnClusterEvent,                      // Some cluster event
8007 +       AifEnDiskSetEvent,                      // A disk set event occured.
8008 +       // Add general application notifies above this comment
8009 +       AifDriverNotifyStart=199,       // Notifies for host driver go here
8010 +       // Host driver notifications start here
8011 +       AifDenMorphComplete,            // A morph operation completed
8012 +       AifDenVolumeExtendComplete      // A volume expand operation completed
8013 +       // Add host driver notifications above this comment
8014 +} _E_AifEventNotifyType;
8015 +
8016 +#ifdef AAC_32BIT_ENUMS
8017 +typedef _E_AifEventNotifyType  AifEventNotifyType;
8018 +#else
8019 +typedef        AAC_UINT32                              AifEventNotifyType;
8020 +#endif
8021 +
8022 +struct AifEnsGeneric {
8023 +       AAC_INT8 text[132];                             // Generic text
8024 +};
8025 +
8026 +struct AifEnsDeviceFailure {
8027 +       AAC_INT32 deviceHandle; // SCSI device handle
8028 +};
8029 +
8030 +struct AifEnsMirrorFailover {
8031 +       AAC_UINT32 container;           // Container with failed element
8032 +       AAC_UINT32 failedSlice;         // Old slice which failed
8033 +       AAC_UINT32 creatingSlice;       // New slice used for auto-create
8034 +};
8035 +
8036 +struct AifEnsContainerChange {
8037 +       AAC_UINT32 container[2];                // container that changed, -1 if no container
8038 +};
8039 +
8040 +struct AifEnsContainerEvent {
8041 +       AAC_UINT32 container;           // container number 
8042 +       AAC_UINT32 eventType;           // event type
8043 +};
8044 +
8045 +struct AifEnsEnclosureEvent {
8046 +       AAC_UINT32 empID;                               // enclosure management processor number 
8047 +       AAC_UINT32 unitID;                      // unitId, fan id, power supply id, slot id, tempsensor id. 
8048 +       AAC_UINT32 eventType;           // event type
8049 +};
8050 +
8051 +
8052 +struct AifEnsBatteryEvent {
8053 +       NVBATT_TRANSITION transition_type;      // e.g. from low to ok
8054 +       NVBATTSTATUS current_state;                     // current battery state
8055 +       NVBATTSTATUS prior_state;                       // previous battery state
8056 +};
8057 +
8058 +struct AifEnsDiskSetEvent {
8059 +       AAC_UINT32      eventType;
8060 +       AAC_UINT32      DsNum[2];
8061 +       AAC_UINT32      CreatorId[2];
8062 +};
8063 +
8064 +
8065 +
8066 +typedef enum _CLUSTER_AIF_EVENT {
8067 +       CLUSTER_NULL_EVENT = 0,
8068 +       CLUSTER_PARTNER_NAME_EVENT,             // change in partner hostname or adaptername from NULL to non-NULL
8069 +                                                                       // (partner's agent may be up)
8070 +       CLUSTER_PARTNER_NULL_NAME_EVENT // change in partner hostname or adaptername from non-null to NULL
8071 +                                                                       // (partner has rebooted)
8072 +} _E_CLUSTER_AIF_EVENT;
8073 +
8074 +#ifdef AAC_32BIT_ENUMS
8075 +typedef        _E_CLUSTER_AIF_EVENT    CLUSTER_AIF_EVENT;
8076 +#else
8077 +typedef        AAC_UINT32                              CLUSTER_AIF_EVENT;
8078 +#endif
8079 +
8080 +struct AifEnsClusterEvent {
8081 +       CLUSTER_AIF_EVENT   eventType;
8082 +};
8083 +
8084 +struct AifEventNotify {
8085 +       AifEventNotifyType      type;
8086 +       union {
8087 +               struct AifEnsGeneric            EG;
8088 +               struct AifEnsDeviceFailure      EDF;
8089 +               struct AifEnsMirrorFailover EMF;
8090 +               struct AifEnsContainerChange ECC;
8091 +               struct AifEnsContainerEvent ECE;
8092 +               struct AifEnsEnclosureEvent EEE;
8093 +               struct AifEnsBatteryEvent       EBE;
8094 +               struct AifEnsDiskSetEvent       EDS;
8095 +#ifdef BRIDGE
8096 +               struct AifEnsSMARTEvent ES;
8097 +#endif
8098 +               struct AifEnsClusterEvent ECLE;
8099 +       } data;
8100 +};
8101 +
8102 +//
8103 +//     Generic API structure
8104 +//
8105 +#define AIF_API_REPORT_MAX_SIZE 64
8106 +typedef AAC_INT8 AifApiReport[AIF_API_REPORT_MAX_SIZE];
8107 +
8108 +
8109 +
8110 +//
8111 +//     For FIB communication, we need all of the following things
8112 +//     to send back to the user.
8113 +//
8114 +typedef enum {
8115 +       AifCmdEventNotify = 1,  // Notify of event
8116 +       AifCmdJobProgress,              // Progress report
8117 +       AifCmdAPIReport,                // Report from other user of API
8118 +       AifCmdDriverNotify,             // Notify host driver of event
8119 +       AifReqJobList = 100,    // Gets back complete job list
8120 +       AifReqJobsForCtr,               // Gets back jobs for specific container
8121 +       AifReqJobsForScsi,              // Gets back jobs for specific SCSI device
8122 +       AifReqJobReport,                // Gets back a specific job report or list of them
8123 +       AifReqTerminateJob,             // Terminates job
8124 +       AifReqSuspendJob,               // Suspends a job
8125 +       AifReqResumeJob,                // Resumes a job
8126 +       AifReqSendAPIReport,    // API generic report requests
8127 +       AifReqAPIJobStart,              // Start a job from the API
8128 +       AifReqAPIJobUpdate,             // Update a job report from the API
8129 +       AifReqAPIJobFinish              // Finish a job from the API
8130 +} _E_AIFCOMMAND;
8131 +
8132 +#ifdef AAC_32BIT_ENUMS
8133 +typedef _E_AIFCOMMAND  AIFCOMMAND;
8134 +#else
8135 +typedef        AAC_UINT32              AIFCOMMAND;
8136 +#endif
8137 +
8138 +
8139 +
8140 +//
8141 +//     Adapter Initiated FIB command structures. Start with the adapter
8142 +//     initiated FIBs that really come from the adapter, and get responded
8143 +//     to by the host.
8144 +//
8145 +typedef struct _AIFCOMMANDTOHOST {
8146 +       AIFCOMMAND command;                     // Tell host what type of notify this is
8147 +       AAC_UINT32 seqNumber;   // To allow ordering of reports (if necessary)
8148 +       union {
8149 +               // First define data going to the adapter
8150 +               struct AifEventNotify EN;       // Event notify structure
8151 +               struct AifJobProgressReport PR[1]; // Progress report
8152 +               AifApiReport AR;
8153 +       } data;
8154 +} AIFCOMMANDTOHOST, *PAIFCOMMANDTOHOST;
8155 +
8156 +
8157 +#endif // _AIFSTRUC_H
8158 +
8159 +
8160 +
8161 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/build_number.h linux/drivers/scsi/aacraid/include/build_number.h
8162 --- linux-2.4.9/drivers/scsi/aacraid/include/build_number.h     Wed Dec 31 18:00:00 1969
8163 +++ linux/drivers/scsi/aacraid/include/build_number.h   Thu Aug 16 18:16:55 2001
8164 @@ -0,0 +1,39 @@
8165 +/*++
8166 + * Adaptec aacraid device driver for Linux.
8167 + *
8168 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8169 + *
8170 + * This program is free software; you can redistribute it and/or modify
8171 + * it under the terms of the GNU General Public License as published by
8172 + * the Free Software Foundation; either version 2, or (at your option)
8173 + * any later version.
8174 + *
8175 + * This program is distributed in the hope that it will be useful,
8176 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8177 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
8178 + * GNU General Public License for more details.
8179 + *
8180 + * You should have received a copy of the GNU General Public License
8181 + * along with this program; see the file COPYING.  If not, write to
8182 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8183 + *
8184 + * Module Name:
8185 + *   build_number.h
8186 + *
8187 + * Abstract:
8188 + *   DThis module contains the single location where the build number
8189 + *   is kept.
8190 + *
8191 + *
8192 + *
8193 + --*/
8194 +#ifndef _BUILD_NUMBER_H 
8195 +#define _BUILD_NUMBER_H 
8196 +
8197 +static char *ident_build_num = "aacraid_ident build_number.h 1.0.7 2001/08/10 Adaptec, Inc.";
8198 +
8199 +#define REV_BUILD_NUMBER 5125 
8200 +
8201 +
8202 +#endif  // _BUILD_NUMBER_H 
8203 +
8204 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/commdata.h linux/drivers/scsi/aacraid/include/commdata.h
8205 --- linux-2.4.9/drivers/scsi/aacraid/include/commdata.h Wed Dec 31 18:00:00 1969
8206 +++ linux/drivers/scsi/aacraid/include/commdata.h       Thu Aug 16 13:41:30 2001
8207 @@ -0,0 +1,112 @@
8208 +/*++
8209 + * Adaptec aacraid device driver for Linux.
8210 + *
8211 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8212 + *
8213 + * This program is free software; you can redistribute it and/or modify
8214 + * it under the terms of the GNU General Public License as published by
8215 + * the Free Software Foundation; either version 2, or (at your option)
8216 + * any later version.
8217 + *
8218 + * This program is distributed in the hope that it will be useful,
8219 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8220 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
8221 + * GNU General Public License for more details.
8222 + *
8223 + * You should have received a copy of the GNU General Public License
8224 + * along with this program; see the file COPYING.  If not, write to
8225 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8226 + *
8227 + * Module Name:
8228 + *   commdata.h
8229 + *
8230 + * Abstract: Define the communication layer of the adapter
8231 + *
8232 + *
8233 + *
8234 + --*/
8235 +#ifndef _COMMDATA_
8236 +#define _COMMDATA_
8237 +
8238 +static char *ident_commdata = "aacraid_ident commdata.h 1.0.6 2000/10/09 Adaptec, Inc.";
8239 +
8240 +typedef struct _FSA_COMM_DATA {
8241 +  
8242 +  //
8243 +  //  A pointer to the Driver and Device object we were initialized with
8244 +  //
8245 +  
8246 +  PDRIVER_OBJECT DriverObject;
8247 +  PDEVICE_OBJECT DeviceObject;
8248 +  
8249 +  //
8250 +  // A list of all adapters we have configured.
8251 +  // 
8252 +  
8253 +  PAFA_COMM_ADAPTER AdapterList;
8254 +  ULONG                  TotalAdapters;
8255 +  
8256 +  //
8257 +  // Adapter timeout support. This is the default timeout to wait for the
8258 +  // adapter to respond(setup in initfs.c), and a boolean to indicate if
8259 +  // we should timeout requests to the adapter or not.
8260 +  //
8261 +
8262 +  LARGE_INTEGER QueueFreeTimeout;
8263 +  LARGE_INTEGER AdapterTimeout;
8264 +  BOOLEAN EnableAdapterTimeouts;
8265 +
8266 +  ULONG        FibTimeoutIncrement;
8267 +  
8268 +  ULONG FibsSent;
8269 +  ULONG FibRecved;
8270 +  ULONG NoResponseSent;
8271 +  ULONG NoResponseRecved;
8272 +  ULONG AsyncSent;
8273 +  ULONG AsyncRecved;
8274 +  ULONG NormalSent;
8275 +  ULONG NormalRecved;
8276 +  
8277 +  ULONG TimedOutFibs;
8278 +  
8279 +  KDPC         TimeoutDPC;
8280 +  KTIMER       TimeoutTimer;
8281 +  
8282 +  // 
8283 +  // If this value is set to 1 then interrupt moderation will occur 
8284 +  // in the base commuication support.
8285 +  //
8286 +
8287 +  ULONG EnableInterruptModeration;
8288 +
8289 +  int HardInterruptModeration;
8290 +  int HardInterruptModeration1;
8291 +  int PeakFibsConsumed;
8292 +  int ZeroFibsConsumed;
8293 +  int EnableFibTimeoutBreak;
8294 +  ULONG FibTimeoutSeconds;
8295 +  
8296 +  //
8297 +  // The following holds all of the available user settable variables.
8298 +  // This includes all for the comm layer as well as any from the class
8299 +  // drivers as well.
8300 +  //
8301 +  
8302 +  FSA_USER_VAR *UserVars;
8303 +  ULONG                        NumUserVars;
8304 +  
8305 +  
8306 +  ULONG           MeterFlag;
8307 +  
8308 +#ifdef FIB_CHECKSUMS
8309 +  int do_fib_checksums;
8310 +#endif
8311 +  
8312 +} FSA_COMM_DATA;
8313 +typedef FSA_COMM_DATA *PFSA_COMM_DATA;
8314 +
8315 +extern FSA_COMM_DATA FsaCommData;
8316 +
8317 +
8318 +#endif // _COMMDATA_
8319 +
8320 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/commerr.h linux/drivers/scsi/aacraid/include/commerr.h
8321 --- linux-2.4.9/drivers/scsi/aacraid/include/commerr.h  Wed Dec 31 18:00:00 1969
8322 +++ linux/drivers/scsi/aacraid/include/commerr.h        Thu Aug 16 18:16:55 2001
8323 @@ -0,0 +1,125 @@
8324 +/*++
8325 + * Adaptec aacraid device driver for Linux.
8326 + *
8327 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8328 + *
8329 + * This program is free software; you can redistribute it and/or modify
8330 + * it under the terms of the GNU General Public License as published by
8331 + * the Free Software Foundation; either version 2, or (at your option)
8332 + * any later version.
8333 + *
8334 + * This program is distributed in the hope that it will be useful,
8335 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8336 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
8337 + * GNU General Public License for more details.
8338 + *
8339 + * You should have received a copy of the GNU General Public License
8340 + * along with this program; see the file COPYING.  If not, write to
8341 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8342 + *
8343 + * Module Name:
8344 + *   commerr.h
8345 + *
8346 + * Abstract: This file defines all errors that are unique to the Adaptec Fsa Filesystem
8347 + *
8348 + *
8349 + *
8350 + --*/
8351 +
8352 +#ifndef _FSAERR_
8353 +#define _FSAERR_
8354 +
8355 +static char *ident_commerr = "aacraid_ident commerr.h 1.0.6 2000/10/09 Adaptec, Inc.";
8356 +
8357 +//
8358 +//  Note: comments in the .mc file must use both ";" and "//".
8359 +//
8360 +//  Status values are 32 bit values layed out as follows:
8361 +//
8362 +//   3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
8363 +//   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
8364 +//  +---+-+-------------------------+-------------------------------+
8365 +//  |Sev|C|       Facility          |               Code            |
8366 +//  +---+-+-------------------------+-------------------------------+
8367 +//
8368 +//  where
8369 +//
8370 +//      Sev - is the severity code
8371 +//
8372 +//          00 - Success
8373 +//          01 - Informational
8374 +//          10 - Warning
8375 +//          11 - Error
8376 +//
8377 +//      C - is the Customer code flag
8378 +//
8379 +//      Facility - is the facility code
8380 +//
8381 +//      Code - is the facility's status code
8382 +//
8383 +
8384 +
8385 +//
8386 +// %1 is reserved by the IO Manager. If IoAllocateErrorLogEntry is
8387 +// called with a device, the name of the device will be inserted into
8388 +// the message at %1. Otherwise, the place of %1 will be left empty.
8389 +// In either case, the insertion strings from the driver's error log
8390 +// entry starts at %2. In other words, the first insertion string goes
8391 +// to %2, the second to %3 and so on.
8392 +//
8393 +
8394 +//
8395 +//  Values are 32 bit values layed out as follows:
8396 +//
8397 +//   3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
8398 +//   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
8399 +//  +---+-+-+-----------------------+-------------------------------+
8400 +//  |Sev|C|R|     Facility          |               Code            |
8401 +//  +---+-+-+-----------------------+-------------------------------+
8402 +//
8403 +//  where
8404 +//
8405 +//      Sev - is the severity code
8406 +//
8407 +//          00 - Success
8408 +//          01 - Informational
8409 +//          10 - Warning
8410 +//          11 - Error
8411 +//
8412 +//      C - is the Customer code flag
8413 +//
8414 +//      R - is a reserved bit
8415 +//
8416 +//      Facility - is the facility code
8417 +//
8418 +//      Code - is the facility's status code
8419 +//
8420 +//
8421 +// Define the facility codes
8422 +//
8423 +
8424 +
8425 +#define FACILITY_FSAFS_ERROR_CODE        0x7
8426 +
8427 +
8428 +
8429 +//
8430 +// MessageId: FSAFS_FIB_INVALID
8431 +//
8432 +// MessageText:
8433 +//
8434 +//  A communication packet was detected to be formatted poorly. Please Contact Adaptec support.
8435 +//
8436 +#define FSAFS_FIB_INVALID                ((AAC_STATUS)0xE0070009L)
8437 +
8438 +
8439 +//
8440 +// MessageId: FSAFS_TIMED_OUT_FIB_COMPLETED
8441 +//
8442 +// MessageText:
8443 +//
8444 +//  A Fib previously timed out by host has been completed by the adapter. (\\.\Afa%2)
8445 +//
8446 +#define FSAFS_TIMED_OUT_FIB_COMPLETED    ((AAC_STATUS)0xA007000EL)
8447 +
8448 +#endif /* _FSAERR_ */
8449 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/commfibcontext.h linux/drivers/scsi/aacraid/include/commfibcontext.h
8450 --- linux-2.4.9/drivers/scsi/aacraid/include/commfibcontext.h   Wed Dec 31 18:00:00 1969
8451 +++ linux/drivers/scsi/aacraid/include/commfibcontext.h Thu Aug 16 13:41:30 2001
8452 @@ -0,0 +1,98 @@
8453 +/*++
8454 + * Adaptec aacraid device driver for Linux.
8455 + *
8456 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8457 + *
8458 + * This program is free software; you can redistribute it and/or modify
8459 + * it under the terms of the GNU General Public License as published by
8460 + * the Free Software Foundation; either version 2, or (at your option)
8461 + * any later version.
8462 + *
8463 + * This program is distributed in the hope that it will be useful,
8464 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8465 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
8466 + * GNU General Public License for more details.
8467 + *
8468 + * You should have received a copy of the GNU General Public License
8469 + * along with this program; see the file COPYING.  If not, write to
8470 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8471 + *
8472 + * Module Name:
8473 + *   commfibcontext.h
8474 + *
8475 + * Abstract: defines the _COMM_FIB_CONTEXT strcuture
8476 + *
8477 + *
8478 + *
8479 + --*/
8480 +#ifndef _COMM_FIB_CONTEXT_
8481 +#define _COMM_FIB_CONTEXT_
8482 +
8483 +static char *ident_commfib = "aacraid_ident commfibcontext.h 1.0.6 2000/10/09 Adaptec, Inc.";
8484 +
8485 +typedef struct _COMM_FIB_CONTEXT {
8486 +
8487 +       PVOID           Next;   // this is used by the zone allocation
8488 +
8489 +    //
8490 +    //  Type and size of this record (must be FSA_NTC_FIB_CONTEXT)
8491 +    //
8492 +    //  NOTE:  THIS STRUCTURE MUST REMAIN 64-bit ALIGNED IN SIZE, SINCE
8493 +    //         IT IS ZONE ALLOCATED, AND REPINNED_BCBS_ARRAY_SIZE AFFECTS
8494 +    //         ITS SIZE.
8495 +    //
8496 +
8497 +    NODE_TYPE_CODE NodeTypeCode;
8498 +    NODE_BYTE_SIZE NodeByteSize;
8499 +
8500 +       //
8501 +       //      The Adapter that this I/O is destined for.
8502 +       //
8503 +
8504 +       PAFA_COMM_ADAPTER Adapter;
8505 +
8506 +    PHYSICAL_ADDRESS LogicalFibAddress;
8507 +
8508 +    //
8509 +    // This is the event the sendfib routine will wait on if the
8510 +    // caller did not pass one and this is synch io.
8511 +    //
8512 +
8513 +  OS_CV_T      FsaEvent;
8514 +       OS_CVLOCK       *FsaEventMutex;
8515 +
8516 +       ULONG   FibComplete;    // gets set to 1 when fib is complete
8517 +    
8518 +       PFIB_CALLBACK FibCallback;
8519 +       PVOID FibCallbackContext;
8520 +
8521 +       ULONG   Flags;
8522 +
8523 +
8524 +#ifdef GATHER_FIB_TIMES
8525 +       LARGE_INTEGER   FibTimeStamp;
8526 +       PFIB_TIMES              FibTimesPtr;
8527 +#endif
8528 +
8529 +       //
8530 +       // The following is used to put this fib context onto the Outstanding I/O queue.
8531 +       //
8532 +               
8533 +       LIST_ENTRY      QueueEntry;     
8534 +
8535 +       //
8536 +       // The following is used to timeout a fib to the adapter.
8537 +       //
8538 +
8539 +       LARGE_INTEGER   TimeoutValue;
8540 +
8541 +       PVOID   FibData;
8542 +
8543 +    PFIB Fib;
8544 +
8545 +} COMM_FIB_CONTEXT;
8546 +typedef COMM_FIB_CONTEXT *PCOMM_FIB_CONTEXT;
8547 +
8548 +#define FIB_CONTEXT_FLAG_TIMED_OUT             (0x00000001)
8549 +
8550 +#endif /* _COMM_FIB_CONTEXT_ */
8551 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/comprocs.h linux/drivers/scsi/aacraid/include/comprocs.h
8552 --- linux-2.4.9/drivers/scsi/aacraid/include/comprocs.h Wed Dec 31 18:00:00 1969
8553 +++ linux/drivers/scsi/aacraid/include/comprocs.h       Thu Aug 16 13:41:30 2001
8554 @@ -0,0 +1,93 @@
8555 +/*++
8556 + * Adaptec aacraid device driver for Linux.
8557 + *
8558 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8559 + *
8560 + * This program is free software; you can redistribute it and/or modify
8561 + * it under the terms of the GNU General Public License as published by
8562 + * the Free Software Foundation; either version 2, or (at your option)
8563 + * any later version.
8564 + *
8565 + * This program is distributed in the hope that it will be useful,
8566 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8567 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
8568 + * GNU General Public License for more details.
8569 + *
8570 + * You should have received a copy of the GNU General Public License
8571 + * along with this program; see the file COPYING.  If not, write to
8572 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8573 + *
8574 + * Module Name:
8575 + *   comprocs.h
8576 + *
8577 + * Abstract: This module defines all of the globally used procedures in the Afa comm layer
8578 + *
8579 + *
8580 + *
8581 + --*/
8582 +#ifndef _COMPROCS_
8583 +#define _COMPROCS_
8584 +
8585 +static char *ident_comproc = "aacraid_ident comprocs.h 1.0.6 2000/10/09 Adaptec, Inc.";
8586 +
8587 +#include "osheaders.h"
8588 +
8589 +#include "AacGenericTypes.h"
8590 +
8591 +#include "aac_unix_defs.h"
8592 +
8593 +#include "nodetype.h"
8594 +
8595 +// #define GATHER_FIB_TIMES
8596 +
8597 +#include "fsatypes.h"
8598 +
8599 +#include "perfpack.h"
8600 +
8601 +#include "comstruc.h"
8602 +
8603 +//#include "unix_protocol.h"
8604 +
8605 +#include "fsact.h"
8606 +
8607 +#include "protocol.h"
8608 +
8609 +#include "fsaioctl.h"
8610 +
8611 +#undef GATHER_FIB_TIMES
8612 +
8613 +#include "aifstruc.h"
8614 +
8615 +#include "fsaport.h"
8616 +#include "comsup.h"
8617 +#include "afacomm.h"
8618 +#include "adapter.h"
8619 +
8620 +#include "commfibcontext.h"
8621 +#include "comproto.h"
8622 +#include "commdata.h"
8623 +#include "commerr.h"
8624 +
8625 +
8626 +
8627 +
8628 +//
8629 +// The following macro is used when sending and receiving FIBs.  It is only used for
8630 +// debugging.
8631 +
8632 +#if DBG
8633 +#define        FIB_COUNTER_INCREMENT(Counter)          InterlockedIncrement(&(Counter))
8634 +#else
8635 +#define        FIB_COUNTER_INCREMENT(Counter)          
8636 +#endif
8637 +
8638 +
8639 +
8640 +int
8641 +AfaCommAdapterDeviceControl (
8642 +       IN PVOID AdapterArg,
8643 +       IN PAFA_IOCTL_CMD       IoctlCmdPtr
8644 +       );
8645 +
8646 +
8647 +#endif // _COMPROCS_
8648 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/comproto.h linux/drivers/scsi/aacraid/include/comproto.h
8649 --- linux-2.4.9/drivers/scsi/aacraid/include/comproto.h Wed Dec 31 18:00:00 1969
8650 +++ linux/drivers/scsi/aacraid/include/comproto.h       Thu Aug 16 13:41:30 2001
8651 @@ -0,0 +1,170 @@
8652 +/*++
8653 + * Adaptec aacraid device driver for Linux.
8654 + *
8655 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8656 + *
8657 + * This program is free software; you can redistribute it and/or modify
8658 + * it under the terms of the GNU General Public License as published by
8659 + * the Free Software Foundation; either version 2, or (at your option)
8660 + * any later version.
8661 + *
8662 + * This program is distributed in the hope that it will be useful,
8663 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8664 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
8665 + * GNU General Public License for more details.
8666 + *
8667 + * You should have received a copy of the GNU General Public License
8668 + * along with this program; see the file COPYING.  If not, write to
8669 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8670 + *
8671 + * Module Name:
8672 + *   comproto.h
8673 + *
8674 + * Abstract: Global routines for the commuication interface that are device
8675 + *           independant.
8676 + *
8677 + *
8678 + *
8679 + --*/
8680 +#ifndef _COMM_PROTO
8681 +#define _COMM_PROTO
8682 +
8683 +static char *ident_comproto = "aacraid_ident comproto.h 1.0.6 2000/10/09 Adaptec, Inc.";
8684 +
8685 +//
8686 +// define the routines we need so we can commuicate with the
8687 +// fsa adapter
8688 +//
8689 +
8690 +//
8691 +// The following 4 dpc routines will support commuication from the adapter to the
8692 +// host. There is one DPC routine to deal with each type of queue that supports
8693 +// commuication from the adapter. (adapter to host resposes, adapter to host commands)
8694 +// These routines will simply pull off the QE and set an event. In the case of a
8695 +// adapter to host command they will also put the FIB on a queue to be processed by
8696 +// a FS thread running at passive level.
8697 +//
8698 +
8699 +// Handle queue not full notification to the file system thread waiting for a queue entry
8700 +
8701 +u_int
8702 +CommonNotFullDpc(
8703 +       IN PCOMM_REGION CommRegion
8704 +    );
8705 +
8706 +// Adapter to host normal priority responses
8707 +
8708 +u_int
8709 +HostResponseNormalDpc(
8710 +    IN PCOMM_QUE OurQueue
8711 +    );
8712 +
8713 +// Adapter to host high priority responses
8714 +u_int
8715 +HostResponseHighDpc(
8716 +    IN PCOMM_QUE OurQueue
8717 +    );
8718 +
8719 +// Adapter to host high priority commands
8720 +u_int
8721 +HostCommandHighDpc(
8722 +    IN PCOMM_QUE OurQueue
8723 +    );
8724 +    
8725 +
8726 +// Adapter to host normal priority commands
8727 +u_int
8728 +HostCommandNormDpc(
8729 +    IN PCOMM_QUE OurQueue
8730 +    );
8731 +
8732 +
8733 +
8734 +BOOLEAN
8735 +SendSynchFib(
8736 +       PVOID                   Arg,
8737 +       FIB_COMMAND     Command,
8738 +       PVOID                   Data,
8739 +       USHORT                  Size,
8740 +       PVOID                   Response,
8741 +       USHORT                  *ResponseSize
8742 +       );
8743 +
8744 +PFIB_CONTEXT
8745 +AllocateFib (
8746 +       IN PVOID Adapter
8747 +    );
8748 +
8749 +VOID
8750 +FreeFib (
8751 +    IN PFIB_CONTEXT FibContext
8752 +    );
8753 +
8754 +VOID
8755 +FreeFibFromDpc(
8756 +    IN PFIB_CONTEXT FibContext
8757 +    );
8758 +
8759 +AAC_STATUS
8760 +DeallocateFib(
8761 +    IN PFIB_CONTEXT FibContext
8762 +    );
8763 +
8764 +
8765 +
8766 +AAC_STATUS
8767 +SendFib(
8768 +    IN FIB_COMMAND Command, 
8769 +       IN PFIB_CONTEXT FibContext,
8770 +    IN ULONG Size,
8771 +    IN COMM_PRIORITIES Priority,
8772 +    IN BOOLEAN Wait,
8773 +    IN PVOID WaitOn,
8774 +    IN BOOLEAN ResponseExpected,
8775 +       IN PFIB_CALLBACK FibCallback,
8776 +       IN PVOID FibCallbackContext
8777 +    );
8778 +
8779 +AAC_STATUS
8780 +CompleteFib(
8781 +       IN PFIB_CONTEXT FibContext
8782 +    );
8783 +
8784 +AAC_STATUS
8785 +CompleteAdapterFib(
8786 +       IN PFIB_CONTEXT FibContext,
8787 +    IN USHORT Size
8788 +    );
8789 +
8790 +AAC_STATUS
8791 +InitializeFib(
8792 +       IN PFIB_CONTEXT FibContext
8793 +    );
8794 +
8795 +
8796 +PVOID
8797 +FsaGetFibData(
8798 +       IN PFIB_CONTEXT FibContext
8799 +       );
8800 +
8801 +
8802 +
8803 +AAC_STATUS
8804 +AfaCommOpenAdapter (
8805 +       IN PVOID AdapterArg
8806 +       );
8807 +
8808 +AAC_STATUS
8809 +AfaCommCloseAdapter (
8810 +       IN PVOID AdapterArg
8811 +       );
8812 +
8813 +
8814 +VOID
8815 +AfaCommInterruptHost(
8816 +       PVOID   Adapter,
8817 +       ADAPTER_EVENT   AdapterEvent
8818 +       );
8819 +
8820 +
8821 +#endif // _COMM_PROTO
8822 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/comstruc.h linux/drivers/scsi/aacraid/include/comstruc.h
8823 --- linux-2.4.9/drivers/scsi/aacraid/include/comstruc.h Wed Dec 31 18:00:00 1969
8824 +++ linux/drivers/scsi/aacraid/include/comstruc.h       Thu Aug 16 13:41:30 2001
8825 @@ -0,0 +1,435 @@
8826 +/*++
8827 + * Adaptec aacraid device driver for Linux.
8828 + *
8829 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8830 + *
8831 + * This program is free software; you can redistribute it and/or modify
8832 + * it under the terms of the GNU General Public License as published by
8833 + * the Free Software Foundation; either version 2, or (at your option)
8834 + * any later version.
8835 + *
8836 + * This program is distributed in the hope that it will be useful,
8837 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8838 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
8839 + * GNU General Public License for more details.
8840 + *
8841 + * You should have received a copy of the GNU General Public License
8842 + * along with this program; see the file COPYING.  If not, write to
8843 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8844 + *
8845 + * Module Name:
8846 + *   comstruc.h
8847 + *
8848 + * Abstract: This module defines the data structures that make up the communication
8849 + *           region for the FSA filesystem. This region is how the host based code
8850 + *           communicates both control and data to the adapter based code.
8851 + *
8852 + *
8853 + *
8854 + --*/
8855 +#ifndef _COMM_STRUCT
8856 +#define _COMM_STRUCT
8857 +
8858 +static char *ident_comstruc = "aacraid_ident comstruc.h 1.0.7 2000/10/11 Adaptec, Inc.";
8859 +
8860 +//
8861 +// Define all the constants needed for the communication interface
8862 +//
8863 +
8864 +// Define how many queue entries each queue will have and the total number of
8865 +// entries for the entire communication interface. Also define how many queues
8866 +// we support.
8867 +
8868 +#define NUMBER_OF_COMM_QUEUES  8   // 4 command; 4 response
8869 +#define HOST_HIGH_CMD_ENTRIES  4
8870 +#define HOST_NORM_CMD_ENTRIES  8
8871 +#define ADAP_HIGH_CMD_ENTRIES  4
8872 +#define ADAP_NORM_CMD_ENTRIES  512
8873 +#define HOST_HIGH_RESP_ENTRIES 4
8874 +#define HOST_NORM_RESP_ENTRIES 512
8875 +#define ADAP_HIGH_RESP_ENTRIES 4
8876 +#define ADAP_NORM_RESP_ENTRIES 8
8877 +
8878 +#define TOTAL_QUEUE_ENTRIES  \
8879 +    (HOST_NORM_CMD_ENTRIES + HOST_HIGH_CMD_ENTRIES + ADAP_NORM_CMD_ENTRIES + ADAP_HIGH_CMD_ENTRIES + \
8880 +           HOST_NORM_RESP_ENTRIES + HOST_HIGH_RESP_ENTRIES + ADAP_NORM_RESP_ENTRIES + ADAP_HIGH_RESP_ENTRIES)
8881 +
8882 +
8883 +
8884 +
8885 +// Set the queues on a 16 byte alignment
8886 +#define QUEUE_ALIGNMENT                16
8887 +
8888 +
8889 +//
8890 +// The queue headers define the Communication Region queues. These
8891 +// are physically contiguous and accessible by both the adapter and the
8892 +// host. Even though all queue headers are in the same contiguous block they will be
8893 +// represented as individual units in the data structures.
8894 +//
8895 +
8896 +typedef AAC_UINT32 QUEUE_INDEX;
8897 +
8898 +typedef QUEUE_INDEX *PQUEUE_INDEX;
8899 +
8900 +typedef struct _QUEUE_ENTRY {
8901 +
8902 +    AAC_UINT32 Size;                     // Size in bytes of the Fib which this QE points to
8903 +    AAC_UINT32 FibAddress;             // Receiver addressable address of the FIB (low 32 address bits)
8904 +
8905 +} QUEUE_ENTRY;
8906 +
8907 +typedef QUEUE_ENTRY *PQUEUE_ENTRY;
8908 +
8909 +
8910 +
8911 +// The adapter assumes the ProducerIndex and ConsumerIndex are grouped
8912 +// adjacently and in that order.
8913 +//
8914 +typedef struct _QUEUE_HEADERS {
8915 +
8916 +    PHYSICAL_ADDRESS LogicalHeaderAddress;  // Address to hand the adapter to access to this queue head
8917 +    PQUEUE_INDEX ProducerIndex;              // The producer index for this queue (host address)
8918 +    PQUEUE_INDEX ConsumerIndex;              // The consumer index for this queue (host address)
8919 +
8920 +} QUEUE_HEADERS;
8921 +typedef QUEUE_HEADERS *PQUEUE_HEADERS;
8922 +
8923 +//
8924 +// Define all the events which the adapter would like to notify
8925 +// the host of.
8926 +//
8927 +typedef enum _ADAPTER_EVENT {
8928 +    HostNormCmdQue = 1,         // Change in host normal priority command queue
8929 +    HostHighCmdQue,             // Change in host high priority command queue
8930 +    HostNormRespQue,            // Change in host normal priority response queue
8931 +    HostHighRespQue,            // Change in host high priority response queue
8932 +    AdapNormRespNotFull,
8933 +    AdapHighRespNotFull,
8934 +    AdapNormCmdNotFull,
8935 +    AdapHighCmdNotFull,
8936 +       SynchCommandComplete,
8937 +    AdapInternalError = 0xfe    // The adapter detected an internal error shutting down
8938 +
8939 +} _E_ADAPTER_EVENT;
8940 +
8941 +#ifdef AAC_32BIT_ENUMS
8942 +typedef _E_ADAPTER_EVENT       ADAPTER_EVENT;
8943 +#else
8944 +typedef AAC_UINT32                     ADAPTER_EVENT;
8945 +#endif
8946 +
8947 +//
8948 +// Define all the events the host wishes to notify the
8949 +// adapter of.
8950 +//
8951 +typedef enum _HOST_2_ADAP_EVENT {
8952 +    AdapNormCmdQue = 1,
8953 +    AdapHighCmdQue,
8954 +    AdapNormRespQue,
8955 +    AdapHighRespQue,
8956 +    HostShutdown,
8957 +    HostPowerFail,
8958 +    FatalCommError,
8959 +    HostNormRespNotFull,
8960 +    HostHighRespNotFull,
8961 +    HostNormCmdNotFull,
8962 +    HostHighCmdNotFull,
8963 +       FastIo,
8964 +       AdapPrintfDone
8965 +} _E_HOST_2_ADAP_EVENT;
8966 +
8967 +#ifdef AAC_32BIT_ENUMS
8968 +typedef _E_HOST_2_ADAP_EVENT   HOST_2_ADAP_EVENT;
8969 +#else
8970 +typedef        AAC_UINT32                              HOST_2_ADAP_EVENT;
8971 +#endif
8972 +
8973 +//
8974 +// Define all the queues that the adapter and host use to communicate
8975 +//
8976 +
8977 +typedef enum _QUEUE_TYPES {
8978 +        HostNormCmdQueue = 1,       // Adapter to host normal priority command traffic
8979 +        HostHighCmdQueue,           // Adapter to host high priority command traffic
8980 +        AdapNormRespQueue,          // Host to adapter normal priority response traffic
8981 +        AdapHighRespQueue,          // Host to adapter high priority response traffic
8982 +        AdapNormCmdQueue,           // Host to adapter normal priority command traffic
8983 +        AdapHighCmdQueue,           // Host to adapter high priority command traffic
8984 +        HostNormRespQueue,          // Adapter to host normal priority response traffic
8985 +        HostHighRespQueue           // Adapter to host high priority response traffic
8986 +} _E_QUEUE_TYPES;
8987 +
8988 +#ifdef AAC_32BIT_ENUMS
8989 +typedef _E_QUEUE_TYPES         QUEUE_TYPES;
8990 +#else
8991 +typedef        AAC_UINT32                      QUEUE_TYPES;
8992 +#endif
8993 +
8994 +
8995 +//
8996 +// Assign type values to the FSA communication data structures
8997 +//
8998 +
8999 +typedef enum _STRUCT_TYPES {
9000 +    TFib = 1,
9001 +    TQe,
9002 +       TCtPerf
9003 +} _E_STRUCT_TYPES;
9004 +
9005 +#ifdef AAC_32BIT_ENUMS
9006 +typedef        _E_STRUCT_TYPES STRUCT_TYPES;
9007 +#else
9008 +typedef        AAC_UINT32              STRUCT_TYPES;
9009 +#endif
9010 +
9011 +//
9012 +// Define the priority levels the FSA communication routines support.
9013 +//
9014 +
9015 +typedef enum _COMM_PRIORITIES {
9016 +    FsaNormal = 1,
9017 +    FsaHigh
9018 +} _E_COMM_PRIORITIES;
9019 +
9020 +#ifdef AAC_32BIT_ENUMS
9021 +typedef _E_COMM_PRIORITIES     COMM_PRIORITIES;
9022 +#else
9023 +typedef        AAC_UINT32                      COMM_PRIORITIES;
9024 +#endif
9025 +
9026 +
9027 +
9028 +//
9029 +// Define the LIST_ENTRY structure.  This structure is used on the NT side to link
9030 +// the FIBs together in a linked list.  Since this structure gets compiled on the adapter
9031 +// as well, we need to define this structure for the adapter's use.  If '_NT_DEF_'
9032 +// is defined, then this header is being included from the NT side, and therefore LIST_ENTRY
9033 +// is already defined.
9034 +#if !defined(_NTDEF_) && !defined(_WINNT_)
9035 +typedef struct _LIST_ENTRY {
9036 +   struct _LIST_ENTRY *Flink;
9037 +   struct _LIST_ENTRY *Blink;
9038 +} LIST_ENTRY;
9039 +typedef LIST_ENTRY *PLIST_ENTRY;
9040 +#endif
9041 +
9042 +
9043 +//
9044 +// Define the FIB. The FIB is the where all the requested data and
9045 +// command information are put to the application on the FSA adapter.
9046 +//
9047 +
9048 +typedef struct _FIB_HEADER {
9049 +    AAC_UINT32 XferState;                    // Current transfer state for this CCB
9050 +    AAC_UINT16 Command;                     // Routing information for the destination
9051 +    AAC_UINT8 StructType;                   // Type FIB
9052 +       AAC_UINT8 Flags;                                                  // Flags for FIB
9053 +    AAC_UINT16 Size;                        // Size of this FIB in bytes
9054 +    AAC_UINT16 SenderSize;                  // Size of the FIB in the sender (for response sizing)
9055 +    AAC_UINT32 SenderFibAddress;               // Host defined data in the FIB
9056 +    AAC_UINT32 ReceiverFibAddress;             // Logical address of this FIB for the adapter
9057 +    AAC_UINT32 SenderData;                     // Place holder for the sender to store data
9058 +#ifndef __midl
9059 +       union {
9060 +               struct {
9061 +                   AAC_UINT32 _ReceiverTimeStart;      // Timestamp for receipt of fib
9062 +                   AAC_UINT32 _ReceiverTimeDone;       // Timestamp for completion of fib
9063 +               } _s;
9064 +               LIST_ENTRY _FibLinks;                   // Used to link Adapter Initiated Fibs on the host
9065 +       } _u;
9066 +#else                          // The MIDL compiler does not support unions without a discriminant.
9067 +       struct {                // Since nothing during the midl compile actually looks into this
9068 +               struct {        // structure, this shoudl be ok.
9069 +                       AAC_UINT32 _ReceiverTimeStart;  // Timestamp for receipt of fib
9070 +                   AAC_UINT32 _ReceiverTimeDone;       // Timestamp for completion of fib
9071 +               } _s;
9072 +       } _u;
9073 +#endif
9074 +} FIB_HEADER;
9075 +
9076 +
9077 +#define FibLinks                       _u._FibLinks
9078 +
9079 +
9080 +#define FIB_DATA_SIZE_IN_BYTES (512 - sizeof(FIB_HEADER))
9081 +
9082 +
9083 +typedef struct _FIB {
9084 +
9085 +#ifdef BRIDGE //rma
9086 +       DLQUE link;
9087 +#endif
9088 +    FIB_HEADER Header;
9089 +
9090 +    AAC_UINT8 data[FIB_DATA_SIZE_IN_BYTES];            // Command specific data
9091 +
9092 +} FIB;
9093 +typedef FIB *PFIB;
9094 +
9095 +
9096 +
9097 +//
9098 +// FIB commands
9099 +//
9100 +
9101 +typedef enum _FIB_COMMANDS {
9102 +    TestCommandResponse =                      1,
9103 +    TestAdapterCommand =                       2,
9104 +
9105 +       // Lowlevel and comm commands
9106 +
9107 +    LastTestCommand =                          100,
9108 +    ReinitHostNormCommandQueue =       101,
9109 +    ReinitHostHighCommandQueue =       102,
9110 +    ReinitHostHighRespQueue =          103,
9111 +    ReinitHostNormRespQueue =          104,
9112 +    ReinitAdapNormCommandQueue =       105,
9113 +    ReinitAdapHighCommandQueue =       107,
9114 +    ReinitAdapHighRespQueue =          108,
9115 +    ReinitAdapNormRespQueue =          109,
9116 +    InterfaceShutdown =                        110,
9117 +    DmaCommandFib =                            120,
9118 +    StartProfile =                                     121,
9119 +    TermProfile =                                      122,
9120 +    SpeedTest =                                        123,
9121 +    TakeABreakPt =                                     124,
9122 +    RequestPerfData =                          125,
9123 +    SetInterruptDefTimer=           126,
9124 +    SetInterruptDefCount=           127,
9125 +    GetInterruptDefStatus=          128,
9126 +    LastCommCommand =                          129,
9127 +
9128 +       // Filesystem commands
9129 +
9130 +    NuFileSystem =                                     300,
9131 +    UFS =                                                      301,
9132 +    HostFileSystem =                           302,
9133 +    LastFileSystemCommand =            303,
9134 +
9135 +       // Container Commands
9136 +
9137 +    ContainerCommand =                                 500,
9138 +       ContainerCommand64 =                    501,
9139 +
9140 +       // Cluster Commands
9141 +
9142 +    ClusterCommand =                           550,
9143 +
9144 +       // Scsi Port commands (scsi passthrough)
9145 +
9146 +    ScsiPortCommand =                          600,
9147 +
9148 +       // misc house keeping and generic adapter initiated commands
9149 +
9150 +    AifRequest =                                       700,
9151 +    CheckRevision =                                    701,
9152 +    FsaHostShutdown =                          702,
9153 +    RequestAdapterInfo =                       703,
9154 +    IsAdapterPaused =                          704,
9155 +    SendHostTime =                                     705,
9156 +    LastMiscCommand =                          706
9157 +
9158 +} _E_FIB_COMMANDS;
9159 +
9160 +
9161 +
9162 +typedef AAC_UINT16 FIB_COMMAND;
9163 +
9164 +//
9165 +// Commands that will target the failover level on the FSA adapter
9166 +//
9167 +
9168 +typedef enum _FIB_XFER_STATE {
9169 +    HostOwned                          = (1<<0),
9170 +    AdapterOwned                       = (1<<1),
9171 +    FibInitialized                     = (1<<2),
9172 +    FibEmpty                           = (1<<3),
9173 +    AllocatedFromPool          = (1<<4),
9174 +    SentFromHost                       = (1<<5),
9175 +    SentFromAdapter            = (1<<6),
9176 +    ResponseExpected           = (1<<7),
9177 +    NoResponseExpected                 = (1<<8),
9178 +    AdapterProcessed           = (1<<9),
9179 +    HostProcessed                      = (1<<10),
9180 +    HighPriority                       = (1<<11),
9181 +    NormalPriority                     = (1<<12),
9182 +    Async                                      = (1<<13),
9183 +    AsyncIo                                    = (1<<13),      // rpbfix: remove with new regime
9184 +    PageFileIo                         = (1<<14),      // rpbfix: remove with new regime
9185 +    ShutdownRequest                    = (1<<15),
9186 +    LazyWrite                          = (1<<16),      // rpbfix: remove with new regime
9187 +    AdapterMicroFib                    = (1<<17),
9188 +    BIOSFibPath                                = (1<<18),
9189 +    FastResponseCapable                = (1<<19),
9190 +       ApiFib                                  = (1<<20)       // Its an API Fib.
9191 +
9192 +} _E_FIB_XFER_STATE;
9193 +
9194 +
9195 +typedef enum _FSA_ERRORS {
9196 +    FSA_NORMAL                  = 0,
9197 +    FSA_SUCCESS                 = 0,
9198 +    FSA_PENDING                 = 0x01,
9199 +    FSA_FATAL                   = 0x02,
9200 +    FSA_INVALID_QUEUE           = 0x03,
9201 +    FSA_NOENTRIES               = 0x04,
9202 +    FSA_SENDFAILED              = 0x05,
9203 +    FSA_INVALID_QUEUE_PRIORITY  = 0x06,
9204 +    FSA_FIB_ALLOCATION_FAILED   = 0x07,
9205 +    FSA_FIB_DEALLOCATION_FAILED = 0x08
9206 +
9207 +} _E_FSA_ERRORS;
9208 +
9209 +
9210 +//
9211 +// The following defines needs to be updated any time there is an incompatible change made
9212 +// to the ADAPTER_INIT_STRUCT structure.
9213 +//
9214 +#define ADAPTER_INIT_STRUCT_REVISION           3
9215 +
9216 +typedef struct _ADAPTER_INIT_STRUCT {
9217 +       AAC_UINT32              InitStructRevision;
9218 +       AAC_UINT32              MiniPortRevision;
9219 +       AAC_UINT32              FilesystemRevision;
9220 +       PAAC_VOID               CommHeaderAddress;
9221 +       PAAC_VOID               FastIoCommAreaAddress;
9222 +       PAAC_VOID               AdapterFibsPhysicalAddress;
9223 +       PAAC_VOID               AdapterFibsVirtualAddress;
9224 +       AAC_UINT32              AdapterFibsSize;
9225 +       AAC_UINT32              AdapterFibAlign;
9226 +       PAAC_VOID               PrintfBufferAddress;
9227 +       AAC_UINT32              PrintfBufferSize;
9228 +       AAC_UINT32              HostPhysMemPages;               // number of 4k pages of host physical memory
9229 +       AAC_UINT32              HostElapsedSeconds;             // number of seconds since 1970.
9230 +} ADAPTER_INIT_STRUCT;
9231 +typedef ADAPTER_INIT_STRUCT *PADAPTER_INIT_STRUCT;
9232 +
9233 +#ifdef AAC_32BIT_ENUMS
9234 +typedef _E_FSA_ERRORS  FSA_ERRORS;
9235 +#else
9236 +typedef        AAC_UINT32              FSA_ERRORS;
9237 +#endif
9238 +
9239 +typedef enum _LOG_LEVEL {
9240 +       LOG_INIT                                = 10,
9241 +       LOG_INFORMATIONAL               = 20,
9242 +       LOG_WARNING                             = 30,
9243 +       LOG_LOW_ERROR                   = 40,
9244 +       LOG_MEDIUM_ERROR                = 50,
9245 +       LOG_HIGH_ERROR                  = 60,
9246 +       LOG_PANIC                               = 70,
9247 +       LOG_DEBUG                               = 80,
9248 +       LOG_WINDBG_PRINT                = 90
9249 +} _E_LOG_LEVEL;
9250 +
9251 +#ifdef AAC_32BIT_ENUMS
9252 +typedef _E_LOG_LEVEL   LOG_LEVEL;
9253 +#else
9254 +typedef        AAC_UINT32              LOG_LEVEL;
9255 +#endif
9256 +
9257 +
9258 +#endif //_COMM_STRUCT
9259 +
9260 +
9261 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/comsup.h linux/drivers/scsi/aacraid/include/comsup.h
9262 --- linux-2.4.9/drivers/scsi/aacraid/include/comsup.h   Wed Dec 31 18:00:00 1969
9263 +++ linux/drivers/scsi/aacraid/include/comsup.h Thu Aug 16 13:41:30 2001
9264 @@ -0,0 +1,132 @@
9265 +/*++
9266 + * Adaptec aacraid device driver for Linux.
9267 + *
9268 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9269 + *
9270 + * This program is free software; you can redistribute it and/or modify
9271 + * it under the terms of the GNU General Public License as published by
9272 + * the Free Software Foundation; either version 2, or (at your option)
9273 + * any later version.
9274 + *
9275 + * This program is distributed in the hope that it will be useful,
9276 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9277 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9278 + * GNU General Public License for more details.
9279 + *
9280 + * You should have received a copy of the GNU General Public License
9281 + * along with this program; see the file COPYING.  If not, write to
9282 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9283 + *
9284 + * Module Name:
9285 + *   comsup.h
9286 + *
9287 + * Abstract: This module defines the data structures that make up the 
9288 + *           commuication region for the FSA filesystem. This region is
9289 + *           how the host based code commuicates both control and data
9290 + *           to the adapter based code. 
9291 + *
9292 + *
9293 + *
9294 + --*/
9295 +#ifndef _COMM_SUP_DEF
9296 +#define _COMM_SUP_DEF
9297 +
9298 +static char *ident_comsup = "aacraid_ident comsup.h 1.0.6 2000/10/09 Adaptec, Inc.";
9299 +
9300 +//
9301 +// The adapter interface specs all queues to be located in the same physically
9302 +// contigous block. The host structure that defines the commuication queues will
9303 +// assume they are each a seperate physically contigous memory region that will
9304 +// support them all being one big contigous block.
9305 +// There is a command and response queue for each level and direction of
9306 +// commuication. These regions are accessed by both the host and adapter.
9307 +//
9308 +typedef struct _COMM_QUE {
9309 +
9310 +    PHYSICAL_ADDRESS LogicalAddress;    // This is the address we give the adapter
9311 +    
9312 +    PQUEUE_ENTRY       BaseAddress;        // This is the system virtual address 
9313 +    QUEUE_HEADERS      Headers;            // A pointer to the producer and consumer queue headers for this queue
9314 +    ULONG                      QueueEntries;       // Number of queue entries on this queue
9315 +    OS_CV_T                    QueueFull;          // Event to wait on if the queue is full
9316 +    OS_CV_T                    CommandReady;       // Indicates there is a Command ready from the adapter on this queue.
9317 +                                        // This is only valid for adapter to host command queues.                                        
9318 +    OS_SPINLOCK                *QueueLock;         // Spinlock for this queue must take this lock before accessing the lock
9319 +    KIRQL                      SavedIrql;          // Previous IRQL when the spin lock is taken
9320 +    ddi_softintr_t     ConsumerRoutine;    // The DPC routine which will consume entries off this queue
9321 +                                        // Only queues which the host will be the consumer will this field be valid
9322 +    LIST_ENTRY                 CommandQueue;       // A queue of FIBs which need to be prcessed by the FS thread. This is
9323 +                                        // only valid for command queues which receive entries from the adapter.
9324 +       LIST_ENTRY              OutstandingIoQueue;     // A queue of outstanding fib's to the adapter.
9325 +       ULONG                   NumOutstandingIos;      // Number of entries on outstanding queue.
9326 +
9327 +       PVOID                   Adapter;                        // Back pointer to adapter structure
9328 +
9329 +} COMM_QUE;
9330 +typedef COMM_QUE *PCOMM_QUE;
9331 +
9332 +
9333 +typedef struct _COMM_REGION {
9334 +
9335 +    COMM_QUE HostNormCmdQue;           // Command queue for normal priority commands from the host
9336 +    COMM_QUE HostNormRespQue;           // A response for normal priority adapter responses
9337 +    
9338 +    COMM_QUE HostHighCmdQue;            // Command queue for high priority commands from the host
9339 +    COMM_QUE HostHighRespQue;           // A response for normal priority adapter responses
9340 +    
9341 +    COMM_QUE AdapNormCmdQue;            // Command queue for normal priority command from the adapter
9342 +    COMM_QUE AdapNormRespQue;           // A response for normal priority host responses
9343 +
9344 +    COMM_QUE AdapHighCmdQue;            // Command queue for high priority command from the adapter
9345 +    COMM_QUE AdapHighRespQue;           // A response for high priority host responses
9346 +
9347 +    //
9348 +    // The 2 threads below are the threads which handle command traffic from the
9349 +    // the adapter. There is one for normal priority and one for high priority queues.
9350 +    // These threads will wait on the commandready event for it's queue.
9351 +    //
9352 +
9353 +    HANDLE NormCommandThread;
9354 +    HANDLE HighCommandThread;
9355 +
9356 +    //
9357 +    // This dpc routine will handle the setting the of not full event when the adapter
9358 +    // lets us know the queue is not longer full via interrupt
9359 +    //
9360 +
9361 +    KDPC QueueNotFullDpc;
9362 +
9363 +#ifdef API_THROTTLE
9364 +       //
9365 +       // Support for data I/O throttling to improve CLI performance
9366 +       // while the system is under load.
9367 +       // This is the throttling mechanism built into the COMM layer.
9368 +       // Look in commsup.c, dpcsup.c and comminit.c for use.
9369 +       //
9370 +
9371 +       int                             ThrottleLimit;                          // Max queue depth of data ops allowed during throttle
9372 +       int                             ThrottleOutstandingFibs;        // Number of data FIBs outstanding to adapter
9373 +       LARGE_INTEGER   ThrottleTimeout;                        // Duration of a a throttle period
9374 +       LARGE_INTEGER   ThrottleWaitTimeout;            // Timeout for a suspended threads to wait
9375 +       BOOLEAN                 ThrottleActive;                         // Is there a current throttle active period ?
9376 +       KTIMER                  ThrottleTimer;                          // Throttle timer to end a throttle period.
9377 +       KDPC                    ThrottleDpc;                            // Throttle timer timeout DPC routine.
9378 +       KSEMAPHORE              ThrottleReleaseSema;            // Semaphore callers of SendFib wait on during a throttle.
9379 +
9380 +       unsigned int    ThrottleExceptionsCount;        // Number of times throttle exception handler executed (0!)
9381 +       unsigned int    ThrottleTimerFires;                     // Debug info - #times throttle timer Dpc has fired
9382 +       unsigned int    ThrottleTimerSets;                      // Debug info - #times throttle timer was set
9383 +
9384 +       unsigned int    ThrottledFibs;
9385 +       unsigned int    ThrottleTimedoutFibs;
9386 +       unsigned int    ApiFibs;
9387 +       unsigned int    NonPassiveFibs;
9388 +       unsigned int    TotalFibs;
9389 +       unsigned int    FSInfoFibs;
9390 +
9391 +#endif // #ifdef API_THROTTLE
9392 +
9393 +} COMM_REGION;
9394 +typedef COMM_REGION *PCOMM_REGION;
9395 +
9396 +#endif // _COMM_SUP
9397 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/fsact.h linux/drivers/scsi/aacraid/include/fsact.h
9398 --- linux-2.4.9/drivers/scsi/aacraid/include/fsact.h    Wed Dec 31 18:00:00 1969
9399 +++ linux/drivers/scsi/aacraid/include/fsact.h  Thu Aug 16 13:41:30 2001
9400 @@ -0,0 +1,165 @@
9401 +/*++
9402 + * Adaptec aacraid device driver for Linux.
9403 + *
9404 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9405 + *
9406 + * This program is free software; you can redistribute it and/or modify
9407 + * it under the terms of the GNU General Public License as published by
9408 + * the Free Software Foundation; either version 2, or (at your option)
9409 + * any later version.
9410 + *
9411 + * This program is distributed in the hope that it will be useful,
9412 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9413 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9414 + * GNU General Public License for more details.
9415 + *
9416 + * You should have received a copy of the GNU General Public License
9417 + * along with this program; see the file COPYING.  If not, write to
9418 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9419 + *
9420 + * Module Name:
9421 + *   fsact.h
9422 + *
9423 + * Abstract:  Common container structures that are required to be
9424 + *            known on both the host and adapter.
9425 + *
9426 + *
9427 + --*/
9428 +#ifndef _FSACT_H_
9429 +#define        _FSACT_H_
9430 +
9431 +static char *ident_fsact = "aacraid_ident fsact.h 1.0.6 2000/10/09 Adaptec, Inc.";
9432 +
9433 +//#include <comstruc.h>
9434 +//#include <fsatypes.h>
9435 +#include <protocol.h> // definitions for FSASTATUS
9436 +
9437 +
9438 +/*
9439 + * Object-Server / Volume-Manager Dispatch Classes
9440 + */
9441 +typedef enum _VM_COMMANDS {
9442 +   VM_Null = 0,
9443 +   VM_NameServe,
9444 +   VM_ContainerConfig,
9445 +   VM_Ioctl,
9446 +   VM_FilesystemIoctl,
9447 +   VM_CloseAll,
9448 +   VM_CtBlockRead,             // see protocol.h for BlockRead command layout
9449 +   VM_CtBlockWrite,            // see protocol.h for BlockWrite command layout
9450 +   VM_SliceBlockRead,  // raw access to configured "storage objects"
9451 +   VM_SliceBlockWrite,
9452 +   VM_DriveBlockRead,  // raw access to physical devices
9453 +   VM_DriveBlockWrite,
9454 +   VM_EnclosureMgt,            // enclosure management
9455 +   VM_Unused,                  // used to be diskset management
9456 +   VM_CtBlockVerify,   // see protocol.h for BlockVerify command layout
9457 +   VM_CtPerf,                  // performance test
9458 +   VM_CtBlockRead64,   // see protocol.h for BlockRead64 command layout
9459 +   VM_CtBlockWrite64,  // see protocol.h for BlockWrite64 command layout
9460 +   VM_CtBlockVerify64, // see protocol.h for BlockVerify64 command layout   
9461 +   MAX_VMCOMMAND_NUM   // used for sizing stats array - leave last
9462 +} _E_VMCOMMAND;
9463 +
9464 +#ifdef AAC_32BIT_ENUMS
9465 +typedef _E_VMCOMMAND   VMCOMMAND;
9466 +#else
9467 +typedef        AAC_UINT32              VMCOMMAND;
9468 +#endif
9469 +
9470 +
9471 +
9472 +//
9473 +// Descriptive information (eg, vital stats)
9474 +// that a content manager might report.  The
9475 +// FileArray filesystem component is one example
9476 +// of a content manager.  Raw mode might be
9477 +// another.
9478 +//
9479 +
9480 +struct FileSysInfo {
9481 +/*
9482 +       a) DOS usage - THINK ABOUT WHERE THIS MIGHT GO -- THXXX
9483 +       b) FSA usage (implemented by ObjType and ContentState fields)
9484 +       c) Block size
9485 +       d) Frag size
9486 +       e) Max file system extension size - (fsMaxExtendSize * fsSpaceUnits)
9487 +       f) I-node density - (computed from other fields)
9488 +*/
9489 +       AAC_UINT32  fsTotalSize;        // consumed by fs, incl. metadata
9490 +       AAC_UINT32  fsBlockSize;
9491 +       AAC_UINT32  fsFragSize;
9492 +       AAC_UINT32  fsMaxExtendSize;
9493 +       AAC_UINT32  fsSpaceUnits;
9494 +       AAC_UINT32  fsMaxNumFiles;
9495 +       AAC_UINT32  fsNumFreeFiles;
9496 +       AAC_UINT32  fsInodeDensity;
9497 +};     // valid iff ObjType == FT_FILESYS && !(ContentState & FSCS_NOTCLEAN)
9498 +
9499 +union ContentManagerInfo {
9500 +       struct FileSysInfo FileSys;     // valid iff ObjType == FT_FILESYS && !(ContentState & FSCS_NOTCLEAN)
9501 +};
9502 +
9503 +//
9504 +// Query for "mountable" objects, ie, objects that are typically
9505 +// associated with a drive letter on the client (host) side.
9506 +//
9507 +
9508 +typedef struct _MNTOBJ {
9509 +
9510 +   AAC_UINT32    ObjectId;
9511 +   FSASTRING  FileSystemName;   // if applicable
9512 +   ContainerCreationInfo   CreateInfo; // if applicable
9513 +   AAC_UINT32    Capacity;
9514 +   FSAVOLTYPE VolType;          // substrate structure
9515 +   FTYPE      ObjType;          // FT_FILESYS, FT_DATABASE, etc.
9516 +   AAC_UINT32     ContentState;     // unready for mounting, readonly, etc.
9517 +
9518 +   union ContentManagerInfo
9519 +              ObjExtension;     // Info specific to content manager (eg, filesystem)
9520 +
9521 +   AAC_UINT32    AlterEgoId;       // != ObjectId <==> snapshot or broken mirror exists
9522 +
9523 +} MNTOBJ;
9524 +
9525 +
9526 +#define FSCS_READONLY  0x0002  // possible result of broken mirror
9527 +
9528 +
9529 +
9530 +typedef struct _MNTINFO {
9531 +
9532 +   VMCOMMAND  Command;
9533 +   FTYPE      MntType;
9534 +   AAC_UINT32     MntCount;
9535 +
9536 +} MNTINFO;
9537 +typedef MNTINFO *PMNTINFO;
9538 +
9539 +typedef struct _MNTINFORESPONSE {
9540 +
9541 +   FSASTATUS Status;
9542 +   FTYPE     MntType;           // should be same as that requested
9543 +   AAC_UINT32    MntRespCount;
9544 +   MNTOBJ    MntTable[1];
9545 +
9546 +} MNTINFORESPONSE;
9547 +typedef MNTINFORESPONSE *PMNTINFORESPONSE;
9548 +
9549 +
9550 +//
9551 +// The following command is sent to shut down each container.
9552 +//
9553 +
9554 +typedef struct _CLOSECOMMAND {
9555 +
9556 +   VMCOMMAND  Command;
9557 +   AAC_UINT32    ContainerId;
9558 +
9559 +} CLOSECOMMAND;
9560 +typedef CLOSECOMMAND *PCLOSECOMMAND;
9561 +
9562 +
9563 +#endif /* _FSACT_H_ */
9564 +
9565 +
9566 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/fsafs.h linux/drivers/scsi/aacraid/include/fsafs.h
9567 --- linux-2.4.9/drivers/scsi/aacraid/include/fsafs.h    Wed Dec 31 18:00:00 1969
9568 +++ linux/drivers/scsi/aacraid/include/fsafs.h  Thu Aug 16 13:41:30 2001
9569 @@ -0,0 +1,78 @@
9570 +/*++
9571 + * Adaptec aacraid device driver for Linux.
9572 + *
9573 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9574 + *
9575 + * This program is free software; you can redistribute it and/or modify
9576 + * it under the terms of the GNU General Public License as published by
9577 + * the Free Software Foundation; either version 2, or (at your option)
9578 + * any later version.
9579 + *
9580 + * This program is distributed in the hope that it will be useful,
9581 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9582 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9583 + * GNU General Public License for more details.
9584 + *
9585 + * You should have received a copy of the GNU General Public License
9586 + * along with this program; see the file COPYING.  If not, write to
9587 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9588 + *
9589 + * Module Name:
9590 + *   fsafs.h
9591 + *
9592 + * Abstract: Common file system structures that are required to be
9593 + *           known on both the host and adapter
9594 + *
9595 + *
9596 + *
9597 + --*/
9598 +
9599 +#ifndef _FSAFS_H_
9600 +#define        _FSAFS_H_ 1
9601 +
9602 +static char *ident_fsafs = "aacraid_ident fsafs.h 1.0.6 2000/10/09 Adaptec, Inc.";
9603 +
9604 +#include <fsatypes.h>   // core types, shared by client and server, eg, u_long
9605 +
9606 +/*
9607 + *  Maximum number of filesystems.
9608 + */
9609 +#define NFILESYS   24
9610 +
9611 +/*
9612 + * File identifier.
9613 + * These are unique and self validating within a filesystem
9614 + * on a single machine and can persist across reboots.
9615 + * The hint field may be volatile and is not guaranteed to persist
9616 + * across reboots but is used to speed up the FID to file object translation
9617 + * if possible. The opaque f1 and f2 fields are guaranteed to uniquely identify
9618 + * the file object (assuming a filesystem context, i.e. driveno).
9619 + */
9620 +typedef struct {
9621 +                               AAC_UINT32  hint; // last used hint for fast reclaim
9622 +                               AAC_UINT32  f1;   // opaque
9623 +                               AAC_UINT32  f2;   // opaque
9624 +                       } fileid_t;             /* intra-filesystem file ID type */
9625 +
9626 +       
9627 +/*
9628 + * Generic file handle
9629 + */
9630 +struct fhandle {
9631 +       fsid_t   fh_fsid;       /* File system id of mount point */
9632 +       fileid_t fh_fid;        /* File sys specific file id */
9633 +};
9634 +typedef struct fhandle fhandle_t;
9635 +
9636 +#define        FIDSIZE         sizeof(fhandle_t)
9637 +
9638 +typedef struct {
9639 +       union {
9640 +               AAC_INT8        fid_data[FIDSIZE];
9641 +               struct  fhandle fsafid;
9642 +       } fidu;
9643 +} FSAFID;                                      /* FSA File ID type */
9644 +
9645 +                                                               
9646 +#endif /* _FSAFS_H_ */
9647 +
9648 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/fsaioctl.h linux/drivers/scsi/aacraid/include/fsaioctl.h
9649 --- linux-2.4.9/drivers/scsi/aacraid/include/fsaioctl.h Wed Dec 31 18:00:00 1969
9650 +++ linux/drivers/scsi/aacraid/include/fsaioctl.h       Thu Aug 16 13:41:30 2001
9651 @@ -0,0 +1,159 @@
9652 +/*++
9653 + * Adaptec aacraid device driver for Linux.
9654 + *
9655 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9656 + *
9657 + * This program is free software; you can redistribute it and/or modify
9658 + * it under the terms of the GNU General Public License as published by
9659 + * the Free Software Foundation; either version 2, or (at your option)
9660 + * any later version.
9661 + *
9662 + * This program is distributed in the hope that it will be useful,
9663 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9664 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9665 + * GNU General Public License for more details.
9666 + *
9667 + * You should have received a copy of the GNU General Public License
9668 + * along with this program; see the file COPYING.  If not, write to
9669 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9670 + *
9671 + * Module Name:
9672 + *   fsaioctl.h
9673 + *
9674 + * Abstract: Defines the interface structures between user mode applications
9675 + *           and the fsa driver.  This structures are used in 
9676 + *           DeviceIoControl() calls.
9677 + *
9678 + *
9679 + *
9680 + --*/
9681 +#ifndef _FSAIOCTL_H_
9682 +#define _FSAIOCTL_H_
9683 +
9684 +static char *ident_fsaioctl = "aacraid_ident fsaioctl.h 1.0.6 2000/10/09 Adaptec, Inc.";
9685 +
9686 +#ifndef IOTRACEUSER
9687 +
9688 +#ifndef CTL_CODE
9689 +
9690 +
9691 +#define FILE_DEVICE_CONTROLLER          0x00000004
9692 +
9693 +//
9694 +// Macro definition for defining IOCTL and FSCTL function control codes.  Note
9695 +// that function codes 0-2047 are reserved for Microsoft Corporation, and
9696 +// 2048-4095 are reserved for customers.
9697 +//
9698 +
9699 +#define CTL_CODE( DeviceType, Function, Method, Access ) (                 \
9700 +    ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
9701 +)
9702 +
9703 +//
9704 +// Define the method codes for how buffers are passed for I/O and FS controls
9705 +//
9706 +
9707 +#define METHOD_BUFFERED                 0
9708 +
9709 +
9710 +#define METHOD_NEITHER                  3
9711 +
9712 +//
9713 +// Define the access check value for any access
9714 +//
9715 +//
9716 +// The FILE_READ_ACCESS and FILE_WRITE_ACCESS constants are also defined in
9717 +// ntioapi.h as FILE_READ_DATA and FILE_WRITE_DATA. The values for these
9718 +// constants *MUST* always be in sync.
9719 +//
9720 +#define FILE_ANY_ACCESS                 0
9721 +
9722 +
9723 +
9724 +#endif
9725 +
9726 +
9727 +
9728 +typedef struct _UNIX_QUERY_DISK {
9729 +       AAC_INT32       ContainerNumber;
9730 +       AAC_INT32       Bus;
9731 +       AAC_INT32       Target;
9732 +       AAC_INT32       Lun;
9733 +       AAC_BOOLEAN     Valid;
9734 +       AAC_BOOLEAN     Locked;
9735 +       AAC_BOOLEAN     Deleted;
9736 +       AAC_INT32       Instance;
9737 +       AAC_INT8        diskDeviceName[10];
9738 +       AAC_BOOLEAN UnMapped;
9739 +} UNIX_QUERY_DISK;
9740 +typedef UNIX_QUERY_DISK *PUNIX_QUERY_DISK;
9741 +
9742 +
9743 +typedef struct _DELETE_DISK {
9744 +       AAC_UINT32      NtDiskNumber;
9745 +       AAC_UINT32      ContainerNumber;
9746 +} DELETE_DISK;
9747 +typedef DELETE_DISK *PDELETE_DISK;
9748 +
9749 +
9750 +#endif /*IOTRACEUSER*/
9751 +
9752 +#define FSACTL_NULL_IO_TEST             0x43    // CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 2048, METHOD_NEITHER, FILE_ANY_ACCESS)
9753 +#define FSACTL_SIM_IO_TEST              0x53    // CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 2049, METHOD_NEITHER, FILE_ANY_ACCESS)
9754 +
9755 +
9756 +#define FSACTL_SENDFIB                  CTL_CODE(FILE_DEVICE_CONTROLLER, 2050, METHOD_BUFFERED, FILE_ANY_ACCESS)
9757 +
9758 +
9759 +#define FSACTL_GET_VAR                                 0x93
9760 +#define FSACTL_SET_VAR                                 0xa3
9761 +#define FSACTL_GET_FIBTIMES                            0xb3
9762 +#define FSACTL_ZERO_FIBTIMES                   0xc3
9763 +
9764 +
9765 +#define FSACTL_DELETE_DISK                             0x163
9766 +#define FSACTL_QUERY_DISK                              0x173
9767 +
9768 +
9769 +// AfaComm perfmon ioctls
9770 +#define FSACTL_GET_COMM_PERF_DATA              CTL_CODE(FILE_DEVICE_CONTROLLER, 2084, METHOD_BUFFERED, FILE_ANY_ACCESS)
9771 +
9772 +
9773 +#define FSACTL_OPENCLS_COMM_PERF_DATA  CTL_CODE(FILE_DEVICE_CONTROLLER, 2085, METHOD_BUFFERED, FILE_ANY_ACCESS)
9774 +
9775 +
9776 +typedef struct _GET_ADAPTER_FIB_IOCTL {
9777 +       char    *AdapterFibContext;
9778 +       int             Wait;
9779 +       char    *AifFib;
9780 +} GET_ADAPTER_FIB_IOCTL, *PGET_ADAPTER_FIB_IOCTL;
9781 +
9782 +//
9783 +// filesystem ioctls
9784 +//
9785 +#define FSACTL_OPEN_GET_ADAPTER_FIB            CTL_CODE(FILE_DEVICE_CONTROLLER, 2100, METHOD_BUFFERED, FILE_ANY_ACCESS)
9786 +
9787 +#define FSACTL_GET_NEXT_ADAPTER_FIB            CTL_CODE(FILE_DEVICE_CONTROLLER, 2101, METHOD_BUFFERED, FILE_ANY_ACCESS)
9788 +
9789 +#define FSACTL_CLOSE_GET_ADAPTER_FIB   CTL_CODE(FILE_DEVICE_CONTROLLER, 2102, METHOD_BUFFERED, FILE_ANY_ACCESS)
9790 +
9791 +#define FSACTL_OPEN_ADAPTER_CONFIG             CTL_CODE(FILE_DEVICE_CONTROLLER, 2103, METHOD_NEITHER, FILE_ANY_ACCESS)
9792 +
9793 +#define FSACTL_CLOSE_ADAPTER_CONFIG            CTL_CODE(FILE_DEVICE_CONTROLLER, 2104, METHOD_NEITHER, FILE_ANY_ACCESS)
9794 +
9795 +
9796 +#define FSACTL_MINIPORT_REV_CHECK              CTL_CODE(FILE_DEVICE_CONTROLLER, 2107, METHOD_BUFFERED, FILE_ANY_ACCESS)
9797 +
9798 +
9799 +#define FSACTL_QUERY_ADAPTER_CONFIG            CTL_CODE(FILE_DEVICE_CONTROLLER, 2113, METHOD_BUFFERED, FILE_ANY_ACCESS)
9800 +
9801 +
9802 +#define FSACTL_FORCE_DELETE_DISK               CTL_CODE(FILE_DEVICE_CONTROLLER, 2120, METHOD_NEITHER, FILE_ANY_ACCESS)
9803 +
9804 +
9805 +#define FSACTL_AIF_THREAD                              CTL_CODE(FILE_DEVICE_CONTROLLER, 2127, METHOD_NEITHER, FILE_ANY_ACCESS)
9806 +
9807 +
9808 +#endif // _FSAIOCTL_H_
9809 +
9810 +
9811 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/fsaport.h linux/drivers/scsi/aacraid/include/fsaport.h
9812 --- linux-2.4.9/drivers/scsi/aacraid/include/fsaport.h  Wed Dec 31 18:00:00 1969
9813 +++ linux/drivers/scsi/aacraid/include/fsaport.h        Thu Aug 16 13:41:30 2001
9814 @@ -0,0 +1,223 @@
9815 +/*++
9816 + * Adaptec aacraid device driver for Linux.
9817 + *
9818 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9819 + *
9820 + * This program is free software; you can redistribute it and/or modify
9821 + * it under the terms of the GNU General Public License as published by
9822 + * the Free Software Foundation; either version 2, or (at your option)
9823 + * any later version.
9824 + *
9825 + * This program is distributed in the hope that it will be useful,
9826 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9827 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9828 + * GNU General Public License for more details.
9829 + *
9830 + * You should have received a copy of the GNU General Public License
9831 + * along with this program; see the file COPYING.  If not, write to
9832 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9833 + *
9834 + * Module Name:
9835 + *   fsaport.h
9836 + *
9837 + * Abstract: This module defines all of the globally used procedures in the FSA
9838 + *           file system.
9839 + *
9840 + *
9841 + *
9842 + --*/
9843 +#ifndef _FSAPORT_
9844 +#define _FSAPORT_
9845 +
9846 +static char *ident_fsaport = "aacraid_ident fsaport.h 1.0.6 2000/10/09 Adaptec, Inc.";
9847 +
9848 +//
9849 +// The scatter/gather map context is the information we 
9850 +// we need to keep the map and transfer data to and from the
9851 +// adapter.
9852 +//
9853 +
9854 +typedef struct _SGMAP_CONTEXT {
9855 +       
9856 +       caddr_t         BaseAddress;
9857 +    PVOID              MapRegBase;
9858 +    ULONG              NumberMapRegs;
9859 +       PSGMAP          SgMapPtr;
9860 +       ULONG           ByteCount;              // Used to check the Mdl length.
9861 +       BOOLEAN         WriteToDevice;
9862 +
9863 +       struct buf      *bp;
9864 +
9865 +
9866 +} SGMAP_CONTEXT;
9867 +typedef SGMAP_CONTEXT *PSGMAP_CONTEXT;
9868 +
9869 +typedef struct _MAPFIB_CONTEXT {
9870 +       PMDL            Mdl;    
9871 +    PVOID              MapRegBase;
9872 +    ULONG              NumberMapRegs;
9873 +       PVOID           FibVirtualAddress;
9874 +       ULONG           Size;
9875 +       PVOID       FibPhysicalAddress;
9876 +
9877 +
9878 +} MAPFIB_CONTEXT;
9879 +typedef MAPFIB_CONTEXT *PMAPFIB_CONTEXT;
9880 +
9881 +typedef BOOLEAN
9882 +(*PFSA_ALLOCATE_ADAPTER_COMM_AREA)(
9883 +       PVOID AdapterExtension,
9884 +       IN OUT PVOID    *BaseAddress,
9885 +       IN ULONG                Size,
9886 +       IN ULONG                Alignment
9887 +       );
9888 +
9889 +typedef BOOLEAN
9890 +(*PFSA_FREE_ADAPTER_COMM_AREA)(
9891 +       PVOID   AdapterExtension
9892 +       );
9893 +
9894 +typedef VOID
9895 +(*PFSA_FREE_DMA_RESOURCES)(     
9896 +       IN PVOID AdapterExtension,
9897 +    IN PSGMAP_CONTEXT SgMapContext
9898 +    );
9899 +
9900 +typedef BOOLEAN
9901 +(*PFSA_ALLOCATE_AND_MAP_FIB_SPACE)(
9902 +       IN PVOID AdapterExtension, 
9903 +       IN PMAPFIB_CONTEXT MapFibContext
9904 +    );
9905 +
9906 +typedef BOOLEAN
9907 +(*PFSA_UNMAP_AND_FREE_FIB_SPACE)(
9908 +       IN PVOID AdapterExtension, 
9909 +       IN PMAPFIB_CONTEXT MapFibContext
9910 +    );
9911 +
9912 +typedef VOID
9913 +(*PFSA_INTERRUPT_ADAPTER)(
9914 +       IN PVOID AdapterExtension
9915 +       );
9916 +
9917 +typedef VOID
9918 +(*PFSA_NOTIFY_ADAPTER)(
9919 +       IN PVOID AdapterExtension,
9920 +    IN HOST_2_ADAP_EVENT AdapterEvent
9921 +    );
9922 +
9923 +typedef VOID
9924 +(*PFSA_RESET_DEVICE)(
9925 +       PVOID AdapterExtension
9926 +       );
9927 +
9928 +typedef AAC_STATUS
9929 +(*PFSA_BUILD_SGMAP)(  
9930 +       IN PVOID AdapterExtension,
9931 +       IN PSGMAP_CONTEXT SgMapContext
9932 +       );
9933 +
9934 +typedef PVOID
9935 +(*PFSA_ADAPTER_ADDR_TO_SYSTEM_ADDR)(  
9936 +       IN PVOID AdapterExtension,
9937 +       IN PVOID AdapterAddress
9938 +       );
9939 +
9940 +typedef VOID
9941 +(*PFSA_INTERRUPT_HOST)(
9942 +       PVOID                   Adapter,
9943 +       ADAPTER_EVENT   AdapterEvent
9944 +       );
9945 +
9946 +typedef VOID
9947 +(*PFSA_ENABLE_INTERRUPT)(
9948 +       PVOID                   Adapter,
9949 +       ADAPTER_EVENT   AdapterEvent,
9950 +       BOOLEAN                 AtDeviceIrq
9951 +       );
9952 +
9953 +
9954 +typedef VOID
9955 +(*PFSA_DISABLE_INTERRUPT)(
9956 +       PVOID                   Adapter,
9957 +       ADAPTER_EVENT   AdapterEvent,
9958 +       BOOLEAN                 AtDeviceIrq
9959 +       );
9960 +
9961 +typedef AAC_STATUS
9962 +(*PFSA_OPEN_ADAPTER) (
9963 +       IN PVOID Adapter
9964 +       );
9965 +
9966 +typedef int
9967 +(*PFSA_DEVICE_CONTROL) (
9968 +       IN PVOID Adapter,
9969 +       IN PAFA_IOCTL_CMD IoctlCmdPtr
9970 +       );
9971 +
9972 +typedef AAC_STATUS
9973 +(*PFSA_CLOSE_ADAPTER) (
9974 +       IN PVOID Adapter
9975 +       );
9976 +
9977 +typedef BOOLEAN
9978 +(*PFSA_SEND_SYNCH_FIB) (
9979 +       IN PVOID Adapter,
9980 +       IN ULONG FibPhysicalAddress
9981 +       );
9982 +
9983 +typedef struct _FSAPORT_FUNCS {
9984 +       ULONG                                                           SizeOfFsaPortFuncs;
9985 +
9986 +       PFSA_ALLOCATE_ADAPTER_COMM_AREA         AllocateAdapterCommArea;
9987 +       PFSA_FREE_ADAPTER_COMM_AREA                     FreeAdapterCommArea;
9988 +       PFSA_FREE_DMA_RESOURCES                         FreeDmaResources;
9989 +       PFSA_ALLOCATE_AND_MAP_FIB_SPACE         AllocateAndMapFibSpace;
9990 +       PFSA_UNMAP_AND_FREE_FIB_SPACE           UnmapAndFreeFibSpace;
9991 +       PFSA_INTERRUPT_ADAPTER                          InterruptAdapter;
9992 +       PFSA_NOTIFY_ADAPTER                                     NotifyAdapter;
9993 +       PFSA_ENABLE_INTERRUPT                           EnableInterrupt;
9994 +       PFSA_DISABLE_INTERRUPT                          DisableInterrupt;
9995 +       PFSA_RESET_DEVICE                                       ResetDevice;
9996 +       PFSA_BUILD_SGMAP                                        BuildSgMap;
9997 +       PFSA_ADAPTER_ADDR_TO_SYSTEM_ADDR        AdapterAddressToSystemAddress;
9998 +
9999 +       PFSA_INTERRUPT_HOST                                     InterruptHost;
10000 +       PFSA_OPEN_ADAPTER                                       OpenAdapter;
10001 +       PFSA_DEVICE_CONTROL                                     DeviceControl;
10002 +       PFSA_CLOSE_ADAPTER                                      CloseAdapter;
10003 +
10004 +       PFSA_SEND_SYNCH_FIB                                     SendSynchFib;
10005 +
10006 +} FSAPORT_FUNCS;
10007 +typedef FSAPORT_FUNCS *PFSAPORT_FUNCS;
10008 +
10009 +typedef AAC_STATUS
10010 +(*PFSA_SETVAR_CALLBACK) (
10011 +       IN PVOID Adapter,
10012 +       IN ULONG NewValue
10013 +       );
10014 +
10015 +typedef struct _FSA_USER_VAR {
10016 +       char                                    Name[32];
10017 +       ULONG                                   *Address;
10018 +       PFSA_SETVAR_CALLBACK    SetVarCallback;
10019 +} FSA_USER_VAR;
10020 +
10021 +typedef FSA_USER_VAR *PFSA_USER_VAR;
10022 +
10023 +typedef struct _FSA_NEW_ADAPTER {
10024 +       PVOID                           AdapterExtension;
10025 +       PFSAPORT_FUNCS          AdapterFuncs;
10026 +       PVOID                           Adapter;
10027 +       BOOLEAN                         AdapterInterruptsBelowDpc;
10028 +       PFSA_USER_VAR           AdapterUserVars;
10029 +       ULONG                           AdapterUserVarsSize;
10030 +       void                            *Dip;
10031 +} FSA_NEW_ADAPTER;
10032 +typedef FSA_NEW_ADAPTER *PFSA_NEW_ADAPTER;
10033 +
10034 +#define        FSAFS_GET_NEXT_ADAPTER                  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 2048, METHOD_NEITHER, FILE_ANY_ACCESS)
10035 +#define        FSAFS_INIT_NEW_ADAPTER                  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 2049, METHOD_NEITHER, FILE_ANY_ACCESS)
10036 +
10037 +#endif
10038 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/fsatypes.h linux/drivers/scsi/aacraid/include/fsatypes.h
10039 --- linux-2.4.9/drivers/scsi/aacraid/include/fsatypes.h Wed Dec 31 18:00:00 1969
10040 +++ linux/drivers/scsi/aacraid/include/fsatypes.h       Thu Aug 16 13:41:30 2001
10041 @@ -0,0 +1,214 @@
10042 +/*++
10043 + * Adaptec aacraid device driver for Linux.
10044 + *
10045 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10046 + *
10047 + * This program is free software; you can redistribute it and/or modify
10048 + * it under the terms of the GNU General Public License as published by
10049 + * the Free Software Foundation; either version 2, or (at your option)
10050 + * any later version.
10051 + *
10052 + * This program is distributed in the hope that it will be useful,
10053 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10054 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10055 + * GNU General Public License for more details.
10056 + *
10057 + * You should have received a copy of the GNU General Public License
10058 + * along with this program; see the file COPYING.  If not, write to
10059 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10060 + *
10061 + * Module Name:
10062 + *   fsatypes.h
10063 + *
10064 + * Abstract: Define all shared data types here, ie, those
10065 + *           types shared among several components, such
10066 + *           as host (driver + apps), adapter, and BIOS.
10067 + *
10068 + *
10069 + --*/
10070 +#ifndef _FSATYPES_H
10071 +#define _FSATYPES_H
10072 +
10073 +static char *ident_fsatype = "aacraid_ident fsatypes.h 1.0.6 2000/10/09 Adaptec, Inc.";
10074 +
10075 +typedef        AAC_UINT32              AAC_BOOLEAN;
10076 +
10077 +//
10078 +// Define a 64-bit address structure for use on
10079 +// a 32-bit processor architecture.
10080 +//
10081 +typedef struct {
10082 +       AAC_UINT32              lo32;
10083 +       AAC_UINT32              hi32;
10084 +} AAC_UINT64S, *PAAC_UINT64S;
10085 +
10086 +
10087 +
10088 +//
10089 +// Container Types
10090 +//
10091 +typedef struct {
10092 +   AAC_UINT32 data[2];  // RMA FIX, make this a real serial number when we
10093 +                           // know what it looks like.  Note, BIOS sees this
10094 +                           // definition and it must be coded in such a way
10095 +                           // that it appears to be 64 bits.  ints are 16 bits
10096 +                           // in BIOS land; fortunately, longs are 32 bits.
10097 +} SerialNumberT;
10098 +
10099 +
10100 +
10101 +//
10102 +//     ***********************
10103 +//     DON'T CHANGE THE ORDER, ctdevsw use this order to map the drivers
10104 +//     ***********************
10105 +//     drivers for CT_NONE to CT_PASSTHRU
10106 +//
10107 +typedef enum _FSAVOLTYPE {
10108 +       CT_NONE = 0,                            
10109 +       CT_VOLUME,                                      
10110 +       CT_MIRROR,
10111 +       CT_STRIPE,
10112 +       CT_RAID5,
10113 +       CT_SSRW,
10114 +       CT_SSRO,
10115 +       CT_MORPH,
10116 +       CT_PASSTHRU,
10117 +       CT_RAID4,
10118 +       CT_RAID10,                                      // stripe of mirror
10119 +       CT_RAID00,                                      // stripe of stripe
10120 +       CT_VOLUME_OF_MIRRORS,           // volume of mirror
10121 +       CT_PSEUDO_RAID3,                        // really raid4
10122 +
10123 +       CT_LAST_VOLUME_TYPE
10124 +
10125 +} _E_FSAVOLTYPE;
10126 +
10127 +#ifdef AAC_32BIT_ENUMS
10128 +typedef        _E_FSAVOLTYPE   FSAVOLTYPE;
10129 +#else
10130 +typedef        AAC_UINT32              FSAVOLTYPE;
10131 +#endif
10132 +
10133 +
10134 +//
10135 +// Types of objects addressable in some fashion by the client.
10136 +// This is a superset of those objects handled just by the filesystem
10137 +// and includes "raw" objects that an administrator would use to
10138 +// configure containers and filesystems.
10139 +//
10140 +typedef enum _FTYPE {
10141 +    FT_REG = 1,     // regular file
10142 +    FT_DIR,         // directory
10143 +    FT_BLK,         // "block" device - reserved
10144 +    FT_CHR,         // "character special" device - reserved
10145 +    FT_LNK,         // symbolic link
10146 +    FT_SOCK,        // socket
10147 +    FT_FIFO,        // fifo
10148 +    FT_FILESYS,     // ADAPTEC's "FSA"(tm) filesystem
10149 +    FT_DRIVE,       // physical disk - addressable in scsi by bus/target/lun
10150 +    FT_SLICE,       // virtual disk - raw volume - slice
10151 +    FT_PARTITION,   // FSA partition - carved out of a slice - building block for containers
10152 +    FT_VOLUME,      // Container - Volume Set
10153 +    FT_STRIPE,      // Container - Stripe Set
10154 +    FT_MIRROR,      // Container - Mirror Set
10155 +    FT_RAID5,       // Container - Raid 5 Set
10156 +    FT_DATABASE     // Storage object with "foreign" content manager
10157 +} _E_FTYPE;
10158 +
10159 +#ifdef AAC_32BIT_ENUMS
10160 +typedef        _E_FTYPE        FTYPE;
10161 +#else
10162 +typedef        AAC_UINT32      FTYPE;
10163 +#endif
10164 +
10165 +
10166 +
10167 +//
10168 +// Host side memory scatter gather list
10169 +// Used by the adapter for read, write, and readdirplus operations
10170 +//
10171 +typedef  PAAC_UINT8 HOSTADDRESS;
10172 +
10173 +typedef struct _SGENTRY {
10174 +       HOSTADDRESS             SgAddress;              /* 32-bit Base address. */
10175 +       AAC_UINT32                      SgByteCount;    /* Length. */
10176 +} SGENTRY;
10177 +typedef SGENTRY *PSGENTRY;
10178 +
10179 +
10180 +
10181 +//
10182 +// SGMAP
10183 +//
10184 +// This is the SGMAP structure for all commands that use
10185 +// 32-bit addressing.
10186 +//
10187 +// Note that the upper 16 bits of SgCount are used as flags.
10188 +// Only the lower 16 bits of SgCount are actually used as the
10189 +// SG element count.
10190 +//
10191 +typedef struct _SGMAP {
10192 +       AAC_UINT32              SgCount;
10193 +       SGENTRY                 SgEntry[1];
10194 +} SGMAP;
10195 +typedef SGMAP *PSGMAP;
10196 +
10197 +
10198 +
10199 +//
10200 +// SGMAP64
10201 +//
10202 +// This is the SGMAP structure for 64-bit container commands.
10203 +//
10204 +typedef struct _SGMAP64 {
10205 +       AAC_UINT8       SgCount;
10206 +       AAC_UINT8       SgSectorsPerPage;
10207 +       AAC_UINT16      SgByteOffset; // For the first page 
10208 +       AAC_UINT64S     SgEntry[1];     // Must be last entry
10209 +} SGMAP64;
10210 +typedef SGMAP64 *PSGMAP64;
10211 +
10212 +
10213 +
10214 +
10215 +//
10216 +// attempt at common time structure across host and adapter
10217 +//
10218 +typedef struct __TIME_T {
10219 +
10220 +       AAC_UINT32      tv_sec;         /* seconds (maybe, depends upon host) */
10221 +       AAC_UINT32      tv_usec;        /* and nanoseconds (maybe, depends upon host)*/
10222 +
10223 +} TIME_T;
10224 +typedef TIME_T *PTIME_T;
10225 +
10226 +#ifndef _TIME_T
10227 +#define timespec __TIME_T
10228 +#define ts_sec tv_sec
10229 +#define ts_nsec        tv_usec
10230 +#endif
10231 +
10232 +
10233 +
10234 +
10235 +typedef struct _ContainerCreationInfo
10236 +{
10237 +
10238 +       AAC_UINT8               ViaBuildNumber;         // e.g., 588
10239 +       AAC_UINT8               MicroSecond;            // e.g., 588
10240 +       AAC_UINT8               Via;                            // e.g.,        1 = FSU,
10241 +                                                                               //                      2 = API,
10242 +       AAC_UINT8               YearsSince1900;         // e.g., 1997 = 97
10243 +       AAC_UINT32              Date;                   //
10244 +                                                                               // unsigned     Month           :4;             // 1 - 12
10245 +                                                                               // unsigned     Day                     :6;             // 1 - 32
10246 +                                                                               // unsigned     Hour            :6;             // 0 - 23
10247 +                                                                               // unsigned     Minute          :6;             // 0 - 60
10248 +                                                                               // unsigned     Second          :6;             // 0 - 60
10249 +       SerialNumberT   ViaAdapterSerialNumber; // e.g., 0x1DEADB0BFAFAF001
10250 +} ContainerCreationInfo;
10251 +
10252 +
10253 +#endif // _FSATYPES_H
10254 +
10255 +
10256 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/linit.h linux/drivers/scsi/aacraid/include/linit.h
10257 --- linux-2.4.9/drivers/scsi/aacraid/include/linit.h    Wed Dec 31 18:00:00 1969
10258 +++ linux/drivers/scsi/aacraid/include/linit.h  Thu Aug 16 13:41:30 2001
10259 @@ -0,0 +1,107 @@
10260 +/*++
10261 + * Adaptec aacraid device driver for Linux.
10262 + *
10263 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10264 + *
10265 + * This program is free software; you can redistribute it and/or modify
10266 + * it under the terms of the GNU General Public License as published by
10267 + * the Free Software Foundation; either version 2, or (at your option)
10268 + * any later version.
10269 + *
10270 + * This program is distributed in the hope that it will be useful,
10271 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10272 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10273 + * GNU General Public License for more details.
10274 + *
10275 + * You should have received a copy of the GNU General Public License
10276 + * along with this program; see the file COPYING.  If not, write to
10277 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10278 + *
10279 + * Module Name:
10280 + *   linit.h
10281 + *
10282 + * Abstract: Header file for Linux Driver for Adaptec RAID Array Controller
10283 + *
10284 + --*/
10285 +/*------------------------------------------------------------------------------
10286 + *              I N C L U D E S
10287 + *----------------------------------------------------------------------------*/
10288 +
10289 +#ifndef _LINIT_H_
10290 +#define _LINIT_H_
10291 +
10292 +static char *ident_linith = "aacraid_ident linit.h 1.0.6 2000/10/09 Adaptec, Inc.";
10293 +
10294 +#include <linux/config.h>
10295 +
10296 +/*------------------------------------------------------------------------------
10297 + *              D E F I N E S
10298 + *----------------------------------------------------------------------------*/
10299 +/* Define the AAC SCSI Host Template structure. */
10300 +#define AAC_HOST_TEMPLATE_ENTRY        \
10301 +  { name:           "AAC",                   /* Driver Name            */ \
10302 +    proc_info:      AAC_ProcDirectoryInfo,   /* ProcFS Info Func       */ \
10303 +    detect:         AAC_DetectHostAdapter,   /* Detect Host Adapter    */ \
10304 +    release:        AAC_ReleaseHostAdapter,  /* Release Host Adapter   */ \
10305 +    info:           AAC_DriverInfo,          /* Driver Info Function   */ \
10306 +    ioctl:          AAC_Ioctl,               /* ioctl Interface        */ \
10307 +    command:        AAC_Command,             /* unqueued command       */ \
10308 +    queuecommand:   AAC_QueueCommand,        /* Queue Command Function */ \
10309 +    abort:          AAC_AbortCommand,        /* Abort Command Function */ \
10310 +    reset:          AAC_ResetCommand,        /* Reset Command Function */ \
10311 +    bios_param:     AAC_BIOSDiskParameters,  /* BIOS Disk Parameters   */ \
10312 +    can_queue:      1,                       /* Default initial value  */ \
10313 +    this_id:        0,                       /* Default initial value  */ \
10314 +    sg_tablesize:   0,                       /* Default initial value  */ \
10315 +    max_sectors:    128,                     /* max xfer size of 64k   */ \
10316 +    cmd_per_lun:    0,                       /* Default initial value  */ \
10317 +    present:        0,                       /* Default initial value  */ \
10318 +    unchecked_isa_dma: 0,                    /* Default Initial Value  */ \
10319 +    use_new_eh_code:         0,                  /* Default initial value      */ \
10320 +    eh_abort_handler:        AAC_AbortCommand,   /* New Abort Command func     */ \
10321 +    eh_strategy_handler:     NULL,               /* New Strategy Error Handler */ \
10322 +    eh_device_reset_handler: NULL,               /* New Device Reset Handler   */ \
10323 +    eh_bus_reset_handler:    NULL,               /* New Bus Reset Handler      */ \
10324 +    eh_host_reset_handler:   NULL,               /* New Host reset Handler     */ \
10325 +    use_clustering: ENABLE_CLUSTERING        /* Disable Clustering      */ \
10326 +  }
10327 +
10328 +
10329 +/*------------------------------------------------------------------------------
10330 + *              T Y P E D E F S / S T R U C T S
10331 + *----------------------------------------------------------------------------*/
10332 +typedef struct AAC_BIOS_DiskParameters
10333 +{
10334 +       int heads;
10335 +       int sectors;
10336 +       int cylinders;
10337 +} AAC_BIOS_DiskParameters_T;
10338 +
10339 +
10340 +/*------------------------------------------------------------------------------
10341 + *              P R O G R A M   G L O B A L S
10342 + *----------------------------------------------------------------------------*/
10343 +
10344 +const char *AAC_DriverInfo( struct Scsi_Host * );
10345 +
10346 +
10347 +/*------------------------------------------------------------------------------
10348 + *              F U N C T I O N   P R O T O T Y P E S
10349 + *----------------------------------------------------------------------------*/
10350 +/* Define prototypes for the AAC Driver Interface Functions. */
10351 +int AAC_DetectHostAdapter( Scsi_Host_Template * );
10352 +int AAC_ReleaseHostAdapter( struct Scsi_Host * );
10353 +int AAC_QueueCommand( Scsi_Cmnd *, void ( *CompletionRoutine )( Scsi_Cmnd * ) );
10354 +int AAC_Command( Scsi_Cmnd * );
10355 +int AAC_ResetCommand( Scsi_Cmnd *, unsigned int );
10356 +int AAC_BIOSDiskParameters( Disk *, kdev_t, int * );
10357 +int AAC_ProcDirectoryInfo( char *, char **, off_t, int, int, int );
10358 +int AAC_Ioctl( Scsi_Device *, int, void * );
10359 +
10360 +
10361 +void AAC_SelectQueueDepths(    struct Scsi_Host *, Scsi_Device * );
10362 +
10363 +
10364 +int AAC_AbortCommand( Scsi_Cmnd *scsi_cmnd_ptr );
10365 +
10366 +#endif /* _LINIT_H_ */
10367 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/monkerapi.h linux/drivers/scsi/aacraid/include/monkerapi.h
10368 --- linux-2.4.9/drivers/scsi/aacraid/include/monkerapi.h        Wed Dec 31 18:00:00 1969
10369 +++ linux/drivers/scsi/aacraid/include/monkerapi.h      Thu Aug 16 13:41:30 2001
10370 @@ -0,0 +1,98 @@
10371 +/*++
10372 + * Adaptec aacraid device driver for Linux.
10373 + *
10374 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10375 + *
10376 + * This program is free software; you can redistribute it and/or modify
10377 + * it under the terms of the GNU General Public License as published by
10378 + * the Free Software Foundation; either version 2, or (at your option)
10379 + * any later version.
10380 + *
10381 + * This program is distributed in the hope that it will be useful,
10382 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10383 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10384 + * GNU General Public License for more details.
10385 + *
10386 + * You should have received a copy of the GNU General Public License
10387 + * along with this program; see the file COPYING.  If not, write to
10388 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10389 + *
10390 + * Module Name:
10391 + *   monkerapi.h
10392 + *
10393 + * Abstract: This module contains the definitions used by the Host Adapter
10394 + *      Communications interface.
10395 + *      This is the interface used for by host programs and the Adapter 
10396 + *      to communicate via synchronous commands via a shared set of registers
10397 + *      on a platform (typically doorbells and mailboxes).
10398 + *
10399 + --*/
10400 +//**********************************************************************
10401 +//
10402 +//     Monitor / Kernel API
10403 +//
10404 +//     03/24/1998 Bob Peret    Initial creation
10405 +//
10406 +//**********************************************************************
10407 +
10408 +#ifndef MONKER_H
10409 +#define MONKER_H
10410 +
10411 +static char *ident_monk = "aacraid_ident monkerapi.h 1.0.6 2000/10/09 Adaptec, Inc.";
10412 +
10413 +#define        BREAKPOINT_REQUEST                                      0x00000004
10414 +#define        INIT_STRUCT_BASE_ADDRESS                        0x00000005
10415 +
10416 +
10417 +#define        SEND_SYNCHRONOUS_FIB                            0x0000000c
10418 +
10419 +
10420 +
10421 +//
10422 +//     Adapter Status Register
10423 +//
10424 +//  Phase Staus mailbox is 32bits:
10425 +//     <31:16> = Phase Status
10426 +//     <15:0>  = Phase
10427 +//
10428 +//  The adapter reports is present state through the phase.  Only
10429 +//  a single phase should be ever be set.  Each phase can have multiple
10430 +//     phase status bits to provide more detailed information about the 
10431 +//     state of the board.  Care should be taken to ensure that any phase status 
10432 +//  bits that are set when changing the phase are also valid for the new phase
10433 +//  or be cleared out.  Adapter software (monitor, iflash, kernel) is responsible
10434 +//  for properly maintining the phase status mailbox when it is running.
10435 +
10436 +//                                                                                     
10437 +// MONKER_API Phases                                                   
10438 +//
10439 +// Phases are bit oriented.  It is NOT valid 
10440 +// to have multiple bits set                                           
10441 +//                                     
10442 +
10443 +
10444 +#define        SELF_TEST_FAILED                                        0x00000004
10445 +
10446 +
10447 +#define        KERNEL_UP_AND_RUNNING                           0x00000080
10448 +#define        KERNEL_PANIC                                            0x00000100
10449 +
10450 +
10451 +
10452 +//
10453 +// Doorbell bit defines
10454 +//
10455 +
10456 +
10457 +#define DoorBellPrintfDone                             (1<<5)  // Host -> Adapter
10458 +
10459 +
10460 +#define DoorBellAdapterNormCmdReady            (1<<1)  // Adapter -> Host
10461 +#define DoorBellAdapterNormRespReady   (1<<2)  // Adapter -> Host
10462 +#define DoorBellAdapterNormCmdNotFull  (1<<3)  // Adapter -> Host
10463 +#define DoorBellAdapterNormRespNotFull (1<<4)  // Adapter -> Host
10464 +#define DoorBellPrintfReady                            (1<<5)  // Adapter -> Host
10465 +
10466 +
10467 +#endif // MONKER_H
10468 +
10469 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/nodetype.h linux/drivers/scsi/aacraid/include/nodetype.h
10470 --- linux-2.4.9/drivers/scsi/aacraid/include/nodetype.h Wed Dec 31 18:00:00 1969
10471 +++ linux/drivers/scsi/aacraid/include/nodetype.h       Thu Aug 16 13:41:30 2001
10472 @@ -0,0 +1,67 @@
10473 +/*++
10474 + * Adaptec aacraid device driver for Linux.
10475 + *
10476 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10477 + *
10478 + * This program is free software; you can redistribute it and/or modify
10479 + * it under the terms of the GNU General Public License as published by
10480 + * the Free Software Foundation; either version 2, or (at your option)
10481 + * any later version.
10482 + *
10483 + * This program is distributed in the hope that it will be useful,
10484 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10485 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10486 + * GNU General Public License for more details.
10487 + *
10488 + * You should have received a copy of the GNU General Public License
10489 + * along with this program; see the file COPYING.  If not, write to
10490 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10491 + *
10492 + * Module Name:
10493 + *   nodetype.h
10494 + *
10495 + * Abstract:     This module defines all of the node type codes used in this development
10496 + *  shell.  Every major data structure in the file system is assigned a node
10497 + *  type code that is.  This code is the first CSHORT in the structure and is
10498 + *  followed by a CSHORT containing the size, in bytes, of the structure.
10499 + *
10500 + --*/
10501 +#ifndef _NODETYPE_
10502 +#define _NODETYPE_
10503 +
10504 +static char *ident_node = "aacraid_ident nodetype.h 1.0.6 2000/10/09 Adaptec, Inc.";
10505 +
10506 +typedef CSHORT NODE_TYPE_CODE;
10507 +
10508 +
10509 +#define FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT ((NODE_TYPE_CODE)0x030b)
10510 +#define FSAFS_NTC_FIB_CONTEXT            ((NODE_TYPE_CODE)0x030c)
10511 +
10512 +
10513 +typedef CSHORT NODE_BYTE_SIZE;
10514 +
10515 +
10516 +//
10517 +//  The following definitions are used to generate meaningful blue bugcheck
10518 +//  screens.  On a bugcheck the file system can output 4 ulongs of useful
10519 +//  information.  The first ulong will have encoded in it a source file id
10520 +//  (in the high word) and the line number of the bugcheck (in the low word).
10521 +//  The other values can be whatever the caller of the bugcheck routine deems
10522 +//  necessary.
10523 +//
10524 +//  Each individual file that calls bugcheck needs to have defined at the
10525 +//  start of the file a constant called BugCheckFileId with one of the
10526 +//  FSAFS_BUG_CHECK_ values defined below and then use FsaBugCheck to bugcheck
10527 +//  the system.
10528 +//
10529 +
10530 +
10531 +#define FSAFS_BUG_CHECK_COMMSUP           (0X001e0000)
10532 +#define FSAFS_BUG_CHECK_DPCSUP            (0X001f0000)
10533 +
10534 +
10535 +#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); }
10536 +
10537 +
10538 +#endif // _NODETYPE_
10539 +
10540 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/nvramioctl.h linux/drivers/scsi/aacraid/include/nvramioctl.h
10541 --- linux-2.4.9/drivers/scsi/aacraid/include/nvramioctl.h       Wed Dec 31 18:00:00 1969
10542 +++ linux/drivers/scsi/aacraid/include/nvramioctl.h     Thu Aug 16 13:41:30 2001
10543 @@ -0,0 +1,112 @@
10544 +/*++
10545 + * Adaptec aacraid device driver for Linux.
10546 + *
10547 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10548 + *
10549 + * This program is free software; you can redistribute it and/or modify
10550 + * it under the terms of the GNU General Public License as published by
10551 + * the Free Software Foundation; either version 2, or (at your option)
10552 + * any later version.
10553 + *
10554 + * This program is distributed in the hope that it will be useful,
10555 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10556 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10557 + * GNU General Public License for more details.
10558 + *
10559 + * You should have received a copy of the GNU General Public License
10560 + * along with this program; see the file COPYING.  If not, write to
10561 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10562 + *
10563 + * Module Name:
10564 + *   nvramioctl.h
10565 + *
10566 + * Abstract: This file defines the data structures related to querying
10567 + *    and controlling the FSA NVRAM/WriteCache subsystem via the NVRAMIOCTL FIB.
10568 + *
10569 + --*/
10570 +#ifndef _NVRAMIOCTL_H_
10571 +#define _NVRAMIOCTL_H_ 1
10572 +
10573 +static char *ident_nvram = "aacraid_ident nvramioctl.h 1.0.6 2000/10/09 Adaptec, Inc.";
10574 +
10575 +/*
10576 + * NVRAM/Write Cache subsystem states
10577 + */
10578 +typedef enum _NVSTATUS {
10579 +       NVSTATUS_DISABLED = 0,  // present, clean, not being used
10580 +       NVSTATUS_ENABLED,               // present, possibly dirty, ready for use
10581 +       NVSTATUS_ERROR,                 // present, dirty, contains dirty data
10582 +                                                       // for bad/missing device
10583 +       NVSTATUS_BATTERY,               // present, bad or low battery, may contain dirty data
10584 +                                                       // for bad/missing device
10585 +       NVSTATUS_UNKNOWN                // present?????
10586 +} _E_NVSTATUS;
10587 +
10588 +#ifdef AAC_32BIT_ENUMS
10589 +typedef _E_NVSTATUS    NVSTATUS;
10590 +#else
10591 +typedef AAC_UINT32     NVSTATUS;
10592 +#endif
10593 +
10594 +/*
10595 + * NVRAM/Write Cache subsystem battery component states
10596 + *
10597 + */
10598 +//NB: this enum should be identical to battery_status in nvram.h
10599 +//       or else collapsed into one enum someday
10600 +typedef enum _NVBATTSTATUS {
10601 +       NVBATTSTATUS_NONE = 0,  // battery has no power or is not present
10602 +       NVBATTSTATUS_LOW,               // battery is low on power
10603 +       NVBATTSTATUS_OK,                        // battery is okay - normal operation possible only in this state
10604 +       NVBATTSTATUS_RECONDITIONING     // no battery present - reconditioning in process
10605 +} _E_NVBATTSTATUS;
10606 +
10607 +#ifdef AAC_32BIT_ENUMS
10608 +typedef        _E_NVBATTSTATUS NVBATTSTATUS;
10609 +#else
10610 +typedef AAC_UINT32             NVBATTSTATUS;
10611 +#endif
10612 +
10613 +/*
10614 + * battery transition type
10615 + */
10616 +typedef enum _NVBATT_TRANSITION {
10617 +       NVBATT_TRANSITION_NONE = 0,     // battery now has no power or is not present
10618 +       NVBATT_TRANSITION_LOW,          // battery is now low on power
10619 +       NVBATT_TRANSITION_OK            // battery is now okay - normal operation possible only in this state
10620 +} _E_NVBATT_TRANSITION;
10621 +
10622 +#ifdef AAC_32BIT_ENUMS
10623 +typedef _E_NVBATT_TRANSITION   NVBATT_TRANSITION;
10624 +#else
10625 +typedef        AAC_UINT32                              NVBATT_TRANSITION;
10626 +#endif
10627 +
10628 +/*
10629 + * NVRAM Info structure returned for NVRAM_GetInfo call
10630 + */
10631 +typedef struct _NVRAMDEVINFO {
10632 +       AAC_UINT32              NV_Enabled;             /* write caching enabled */
10633 +       AAC_UINT32              NV_Error;               /* device in error state */
10634 +       AAC_UINT32              NV_NDirty;              /* count of dirty NVRAM buffers */
10635 +       AAC_UINT32              NV_NActive;             /* count of NVRAM buffers being written */
10636 +} NVRAMDEVINFO, *PNVRAMDEVINFO;
10637 +
10638 +typedef struct _NVRAMINFO {
10639 +       NVSTATUS                NV_Status;                              /* nvram subsystem status */
10640 +       NVBATTSTATUS    NV_BattStatus;                  /* battery status */
10641 +       AAC_UINT32              NV_Size;                                /* size of WriteCache NVRAM in bytes */
10642 +       AAC_UINT32              NV_BufSize;                             /* size of NVRAM buffers in bytes */
10643 +       AAC_UINT32              NV_NBufs;                               /* number of NVRAM buffers */
10644 +       AAC_UINT32              NV_NDirty;                              /* count of dirty NVRAM buffers */
10645 +       AAC_UINT32              NV_NClean;                              /* count of clean NVRAM buffers */
10646 +       AAC_UINT32              NV_NActive;                             /* count of NVRAM buffers being written */
10647 +       AAC_UINT32              NV_NBrokered;                   /* count of brokered NVRAM buffers */
10648 +       NVRAMDEVINFO    NV_DevInfo[NFILESYS];   /* per device info */
10649 +       AAC_UINT32              NV_BattNeedsReconditioning;     /* boolean */
10650 +       AAC_UINT32              NV_TotalSize;                   /* total size of all non-volatile memories in bytes */
10651 +} NVRAMINFO, *PNVRAMINFO;
10652 +
10653 +#endif /* !_NVRAMIOCTL_H_ */
10654 +
10655 +
10656 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/osheaders.h linux/drivers/scsi/aacraid/include/osheaders.h
10657 --- linux-2.4.9/drivers/scsi/aacraid/include/osheaders.h        Wed Dec 31 18:00:00 1969
10658 +++ linux/drivers/scsi/aacraid/include/osheaders.h      Thu Aug 16 18:12:22 2001
10659 @@ -0,0 +1,127 @@
10660 +/*++
10661 + * Adaptec aacraid device driver for Linux.
10662 + *
10663 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10664 + *
10665 + * This program is free software; you can redistribute it and/or modify
10666 + * it under the terms of the GNU General Public License as published by
10667 + * the Free Software Foundation; either version 2, or (at your option)
10668 + * any later version.
10669 + *
10670 + * This program is distributed in the hope that it will be useful,
10671 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10672 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10673 + * GNU General Public License for more details.
10674 + *
10675 + * You should have received a copy of the GNU General Public License
10676 + * along with this program; see the file COPYING.  If not, write to
10677 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10678 + *
10679 + * Module Name:
10680 + *   osheaders.h
10681 + *
10682 + * Abstract: Holds all of the header file includes for a particular O/S flavor.
10683 + *
10684 + --*/
10685 +#ifndef _OSHEADERS_H_
10686 +#define _OSHEADERS_H_
10687 +
10688 +static char *ident_oshead = "aacraid_ident osheaders.h 1.0.6 2000/10/09 Adaptec, Inc.";
10689 +
10690 +
10691 +#include <linux/version.h>
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/slab.h>
10713 +#include <linux/tqueue.h>
10714 +#include "ostypes.h"
10715 +#include "scsi.h"
10716 +#include "hosts.h"
10717 +
10718 +#ifndef intptr_t
10719 +#define intptr_t void *
10720 +#endif
10721 +
10722 +#ifndef cred_t
10723 +#define cred_t void
10724 +#endif
10725 +
10726 +#ifndef paddr32_t
10727 +#define paddr32_t unsigned
10728 +#endif
10729 +
10730 +#ifndef bzero 
10731 +#define bzero(b,len) memset(b,0,len)
10732 +#endif
10733 +
10734 +#ifndef bcopy
10735 +#define bcopy(src,dst,len) memcpy(dst,src,len )
10736 +#endif
10737 +
10738 +#ifndef DEVICE_NR
10739 +#define DEVICE_NR(device) ( ( ( MAJOR( device ) & 7 ) << 4 ) + ( MINOR( device ) >> 4 ) )
10740 +#endif
10741 +
10742 +typedef unsigned uint_t;
10743 +
10744 +typedef enum
10745 +{
10746 +       CE_PANIC = 0,
10747 +       CE_WARN,
10748 +       CE_NOTE, 
10749 +       CE_CONT, 
10750 +       CE_DEBUG,
10751 +       CE_DEBUG2,
10752 +       CE_TAIL
10753 +} CE_ENUM_T;
10754 +
10755 +#define CMN_ERR_LEVEL CE_NOTE
10756 +
10757 +#ifndef IN
10758 +#define IN
10759 +#endif
10760 +
10761 +// usage of READ & WRITE as a typedefs in protocol.h
10762 +// conflicts with <linux/fs.h> definition.
10763 +#ifdef READ
10764 +#undef READ
10765 +#endif
10766 +
10767 +#ifdef WRITE
10768 +#undef WRITE
10769 +#endif
10770 +
10771 +typedef struct aac_options
10772 +{
10773 +       int message_level;
10774 +       int reverse_scan; 
10775 +} aac_options_t;
10776 +
10777 +#endif // _OSHEADERS_H_
10778 +
10779 +
10780 +
10781 +
10782 +
10783 +
10784 +
10785 +
10786 +
10787 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/ostypes.h linux/drivers/scsi/aacraid/include/ostypes.h
10788 --- linux-2.4.9/drivers/scsi/aacraid/include/ostypes.h  Wed Dec 31 18:00:00 1969
10789 +++ linux/drivers/scsi/aacraid/include/ostypes.h        Thu Aug 16 13:41:30 2001
10790 @@ -0,0 +1,149 @@
10791 +/*++
10792 + * Adaptec aacraid device driver for Linux.
10793 + *
10794 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10795 + *
10796 + * This program is free software; you can redistribute it and/or modify
10797 + * it under the terms of the GNU General Public License as published by
10798 + * the Free Software Foundation; either version 2, or (at your option)
10799 + * any later version.
10800 + *
10801 + * This program is distributed in the hope that it will be useful,
10802 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10803 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10804 + * GNU General Public License for more details.
10805 + *
10806 + * You should have received a copy of the GNU General Public License
10807 + * along with this program; see the file COPYING.  If not, write to
10808 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10809 + *
10810 + * Module Name:
10811 + *   ostypes.h
10812 + *
10813 + * Abstract: Holds all of the O/S specific types.
10814 + *
10815 + --*/
10816 +/*------------------------------------------------------------------------------
10817 + *              D E F I N E S
10818 + *----------------------------------------------------------------------------*/
10819 +#ifndef _OSTYPES_H_
10820 +#define _OSTYPES_H_
10821 +
10822 +static char *ident_ostypes = "aacraid_ident ostypes.h 1.0.7 2000/10/11 Adaptec, Inc.";
10823 +
10824 +#include <linux/types.h>
10825 +
10826 +#define MAXIMUM_NUM_CONTAINERS 64              // 4 Luns * 16 Targets
10827 +#define MAXIMUM_NUM_ADAPTERS   8
10828 +
10829 +#define OS_ALLOC_MEM_SLEEP             GFP_KERNEL
10830 +
10831 +#define Os_remove_softintr OsSoftInterruptRemove
10832 +#define OsPrintf printk
10833 +#define FsaCommPrint
10834 +
10835 +// the return values for copy_from_user & copy_to_user is the 
10836 +// number of bytes not transferred. Thus if an internal error 
10837 +// occurs, the return value is greater than zero.
10838 +#define COPYIN(SRC,DST,COUNT,FLAGS)  copy_from_user(DST,SRC,COUNT)
10839 +#define COPYOUT(SRC,DST,COUNT,FLAGS) copy_to_user(DST,SRC,COUNT)
10840 +
10841 +#define copyin(SRC,DST,COUNT) copy_from_user(DST,SRC,COUNT)
10842 +#define copyout(SRC,DST,COUNT) copy_to_user(DST,SRC,COUNT)
10843 +
10844 +/*------------------------------------------------------------------------------
10845 + *              S T R U C T S / T Y P E D E F S
10846 + *----------------------------------------------------------------------------*/
10847 +typedef struct OS_MUTEX
10848 +{
10849 +       unsigned long lock_var;
10850 +       wait_queue_head_t wq;
10851 +       unsigned owner;
10852 +} OS_MUTEX;
10853 +
10854 +typedef        struct OS_SPINLOCK
10855 +{
10856 +       spinlock_t      spin_lock;
10857 +       unsigned cpu_lock_count[NR_CPUS];
10858 +       unsigned long cpu_flags[NR_CPUS];
10859 +       long lockout_count;
10860 +} OS_SPINLOCK;
10861 +
10862 +#ifdef CVLOCK_USE_SPINLOCK
10863 +       typedef OS_SPINLOCK OS_CVLOCK;
10864 +#else
10865 +       typedef OS_MUTEX OS_CVLOCK;
10866 +#endif
10867 +
10868 +typedef size_t         OS_SIZE_T;
10869 +
10870 +typedef        struct OS_CV_T
10871 +{
10872 +       unsigned long lock_var;
10873 +       unsigned long type;
10874 +       wait_queue_head_t wq;   
10875 +} OS_CV_T;
10876 +
10877 +struct fsa_scsi_hba {
10878 +       void                            *CommonExtension;
10879 +       unsigned long           ContainerSize[MAXIMUM_NUM_CONTAINERS];
10880 +       unsigned long           ContainerType[MAXIMUM_NUM_CONTAINERS];
10881 +       unsigned char           ContainerValid[MAXIMUM_NUM_CONTAINERS];
10882 +       unsigned char           ContainerReadOnly[MAXIMUM_NUM_CONTAINERS];
10883 +       unsigned char           ContainerLocked[MAXIMUM_NUM_CONTAINERS];
10884 +       unsigned char           ContainerDeleted[MAXIMUM_NUM_CONTAINERS];
10885 +       long                            ContainerDevNo[MAXIMUM_NUM_CONTAINERS];
10886 +};
10887 +
10888 +typedef struct fsa_scsi_hba fsadev_t;
10889 +
10890 +typedef struct OsKI
10891 +{
10892 +       struct Scsi_Host *scsi_host_ptr;
10893 +       void * dip;     // #REVISIT#
10894 +       fsadev_t fsa_dev;
10895 +       int thread_pid;
10896 +  int    MiniPortIndex;
10897 +} OsKI_t;
10898 +
10899 +#define dev_info_t     fsadev_t
10900 +
10901 +typedef int    OS_SPINLOCK_COOKIE;
10902 +
10903 +typedef unsigned int   OS_STATUS;
10904 +
10905 +typedef struct tq_struct OS_SOFTINTR;
10906 +
10907 +typedef        OS_SOFTINTR     *ddi_softintr_t;
10908 +
10909 +
10910 +
10911 +//-----------------------------------------------------------------------------
10912 +// Conditional variable functions
10913 +
10914 +void OsCv_init ( 
10915 +       OS_CV_T *cv_ptr );
10916 +
10917 +
10918 +//-----------------------------------------------------------------------------
10919 +// Printing functions
10920 +void printk_err(int flag, char *fmt, ...);
10921 +
10922 +#define cmn_err printk_err
10923 +
10924 +
10925 +//
10926 +// just ignore these solaris ddi functions in the code
10927 +//
10928 +#define DDI_SUCCESS                                            0
10929 +
10930 +#define ddi_add_softintr(A,B,C,D,E,F,G)                OsSoftInterruptAdd(C,F,G)
10931 +
10932 +//#REVIEW#
10933 +#define ddi_remove_softintr(A)                         0
10934 +#define ddi_get_soft_iblock_cookie(A, B, C)    0
10935 +
10936 +#define ASSERT(expr) ((void) 0)
10937 +#define drv_usecwait udelay
10938 +
10939 +#endif // _OSTYPES_H_
10940 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/pcisup.h linux/drivers/scsi/aacraid/include/pcisup.h
10941 --- linux-2.4.9/drivers/scsi/aacraid/include/pcisup.h   Wed Dec 31 18:00:00 1969
10942 +++ linux/drivers/scsi/aacraid/include/pcisup.h Thu Aug 16 13:41:30 2001
10943 @@ -0,0 +1,97 @@
10944 +/*++
10945 + * Adaptec aacraid device driver for Linux.
10946 + *
10947 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10948 + *
10949 + * This program is free software; you can redistribute it and/or modify
10950 + * it under the terms of the GNU General Public License as published by
10951 + * the Free Software Foundation; either version 2, or (at your option)
10952 + * any later version.
10953 + *
10954 + * This program is distributed in the hope that it will be useful,
10955 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10956 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10957 + * GNU General Public License for more details.
10958 + *
10959 + * You should have received a copy of the GNU General Public License
10960 + * along with this program; see the file COPYING.  If not, write to
10961 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10962 + *
10963 + * Module Name:
10964 + *   pcisup.h
10965 + *
10966 + * Abstract: This module defines functions that are defined in PciSup.c
10967 + *
10968 + --*/
10969 +#ifndef _PCISUP_
10970 +#define _PCISUP_
10971 +
10972 +static char *ident_pcisup = "aacraid_ident pcisup.h 1.0.6 2000/10/09 Adaptec, Inc.";
10973 +
10974 +       
10975 +/*
10976 + * define which interrupt handler needs to be installed
10977 + */
10978 +
10979 +#define SaISR  1
10980 +#define RxISR  2
10981 +
10982 +typedef struct _PCI_MINIPORT_COMMON_EXTENSION {
10983 +       ULONG                                   AdapterNumber;                  // Which FSA# this miniport is
10984 +       
10985 +       ULONG                                   PciBusNumber;                   // Which PCI bus we are located on
10986 +       ULONG                                   PciSlotNumber;                  // Whiat PCI slot we are in
10987 +       
10988 +       PVOID                                   Adapter;                                // Back pointer to Fsa adapter object
10989 +       ULONG                                   AdapterIndex;                   // Index into PlxAdapterTypes array
10990 +       PDEVICE_OBJECT                  DeviceObject;                   // Pointer to our device object
10991 +       
10992 +       FSAPORT_FUNCS                   AdapterFuncs;
10993 +       ULONG                                   FilesystemRevision;     // Main driver's revision number
10994 +       
10995 +       
10996 +       PADAPTER_INIT_STRUCT    InitStruct;                             // Holds initialization info to communicate with adapter
10997 +       PVOID                                   PhysicalInitStruct;     // Holds physical address of the init struct
10998 +       
10999 +       
11000 +       PVOID                                   PrintfBufferAddress;    // pointer to buffer used for printf's from the adapter
11001 +       
11002 +       BOOLEAN                                 AdapterPrintfsToScreen;                 
11003 +       BOOLEAN                                 AdapterConfigured;              // set to true when we know adapter can take FIBs
11004 +       
11005 +       void *                                  MiniPort;
11006 +       
11007 +       caddr_t                                 CommAddress;    // Base address of Comm area
11008 +       paddr32_t                               CommPhysAddr;   // Physical Address of Comm area
11009 +       size_t                                  CommSize;
11010 +
11011 +       OsKI_t                                  OsDep;                  // OS dependent kernel interfaces
11012 +
11013 +       
11014 +} PCI_MINIPORT_COMMON_EXTENSION;
11015 +
11016 +typedef PCI_MINIPORT_COMMON_EXTENSION *PPCI_MINIPORT_COMMON_EXTENSION;
11017 +
11018 +typedef int
11019 +(*PFSA_MINIPORT_INIT) (
11020 +       IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
11021 +       IN ULONG AdapterNumber,
11022 +       IN ULONG PciBus,
11023 +       IN ULONG PciSlot
11024 +       );
11025 +
11026 +typedef struct _FSA_MINIPORT {
11027 +       USHORT                          VendorId;
11028 +       USHORT                          DeviceId;
11029 +       USHORT                          SubVendorId;
11030 +       USHORT                          SubSystemId;
11031 +       PCHAR                           DevicePrefix;
11032 +  PFSA_MINIPORT_INIT   InitRoutine;
11033 +  PCHAR               DeviceName;
11034 +  PCHAR               Vendor;
11035 +  PCHAR               Model;
11036 +} FSA_MINIPORT;
11037 +typedef FSA_MINIPORT *PFSA_MINIPORT;
11038 +
11039 +
11040 +#endif // _PCISUP_
11041 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/perfpack.h linux/drivers/scsi/aacraid/include/perfpack.h
11042 --- linux-2.4.9/drivers/scsi/aacraid/include/perfpack.h Wed Dec 31 18:00:00 1969
11043 +++ linux/drivers/scsi/aacraid/include/perfpack.h       Thu Aug 16 13:41:30 2001
11044 @@ -0,0 +1,110 @@
11045 +/*++
11046 + * Adaptec aacraid device driver for Linux.
11047 + *
11048 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11049 + *
11050 + * This program is free software; you can redistribute it and/or modify
11051 + * it under the terms of the GNU General Public License as published by
11052 + * the Free Software Foundation; either version 2, or (at your option)
11053 + * any later version.
11054 + *
11055 + * This program is distributed in the hope that it will be useful,
11056 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11057 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11058 + * GNU General Public License for more details.
11059 + *
11060 + * You should have received a copy of the GNU General Public License
11061 + * along with this program; see the file COPYING.  If not, write to
11062 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11063 + *
11064 + * Module Name:
11065 + *   perfpack.h
11066 + *
11067 + * Abstract: This file defines the layout of the performance data that is passed
11068 + *           back from the FSA filesystem driver.
11069 + *
11070 + *     
11071 + --*/
11072 +
11073 +#ifndef _FSA_PERFPACK_H_
11074 +#define _FSA_PERFPACK_H_       1
11075 +
11076 +static char *ident_perf = "aacraid_ident perfpack.h 1.0.6 2000/10/09 Adaptec, Inc.";
11077 +
11078 +//#define FSA_DO_PERF          1               /* enable the engineering counters */
11079 +
11080 +#ifdef FSA_DO_PERF
11081 +//
11082 +// engineering counters
11083 +//
11084 +typedef struct _FSA_PERF_DATA {
11085 +                       ULONG FibsSent;
11086 +                       ULONG ReadDirs;
11087 +                       ULONG GetAttrs;
11088 +                       ULONG SetAttrs;
11089 +                       ULONG Lookups;
11090 +                       ULONG ReadFibs;
11091 +                       ULONG WriteFibs;
11092 +                       ULONG CreateFibs;
11093 +                       ULONG MakeDirs;
11094 +                       ULONG RemoveFibs;
11095 +                       ULONG RemoveDirs;
11096 +                       ULONG RenameFibs;
11097 +                       ULONG ReadDirPlus;
11098 +                       ULONG FsStat;
11099 +                       ULONG WriteBytes;
11100 +                       ULONG ReadBytes;
11101 +// NT FSA entry points
11102 +                       ULONG FsaFsdCreateCount;
11103 +                       ULONG FsaFsdCloseCount;
11104 +                       ULONG FsaFsdReadCount;
11105 +                       ULONG FsaFsdWriteCount;
11106 +                       ULONG FsaFsdQueryInformationCount;
11107 +
11108 +                       struct _FsaFsdSetInfomation{
11109 +                               ULONG FsaSetAllocationInfoCount;
11110 +                               ULONG FsaSetBasicInfoCount;
11111 +                               ULONG FsaSetDispositionInfoCount;
11112 +                               ULONG FsaSetEndOfFileInfoCount;
11113 +                               ULONG FsaSetPositionInfoCount;
11114 +                               ULONG FsaSetRenameInfoCount;
11115 +                               ULONG FsaClearArchiveBitCount;
11116 +                       };
11117 +
11118 +                       ULONG FsaFsdFlushBuffersCount;
11119 +                       ULONG FsaFsdQueryVolumeInfoCount;
11120 +                       ULONG FsaFsdSetVolumeInfoCount;
11121 +                       ULONG FsaFsdCleanupCount;
11122 +                       ULONG FsaFsdDirectoryControlCount;
11123 +                       ULONG FsaFsdFileSystemControlCount;
11124 +                       ULONG FsaFsdLockControlCount;
11125 +                       ULONG FsaFsdDeviceControlCount;
11126 +                       ULONG FsaFsdShutdownCount;
11127 +                       ULONG FsaFsdQuerySecurityInfo;
11128 +                       ULONG FsaFsdSetSecurityInfo;
11129 +                       ULONG FastIoCheckIfPossibleCount;
11130 +                       ULONG FastIoReadCount;
11131 +                       ULONG FastIoWriteCount;
11132 +                       ULONG FastIoQueryBasicInfoCount;
11133 +                       ULONG FastIoQueryStandardInfoCount;
11134 +                       ULONG FastIoLockCount;
11135 +                       ULONG FastIoUnlockSingleCount;
11136 +                       ULONG FastIoUnlockAllCount;
11137 +                       ULONG FastIoUnlockAllByKeyCount;
11138 +                       ULONG FastIoDeviceControlCount;
11139 + } FSA_PERF_DATA;
11140 +
11141 +typedef FSA_PERF_DATA *PFSA_PERF_DATA;
11142 +
11143 +
11144 +#else /* FSA_DO_PERF */
11145 +
11146 +//
11147 +// engineering performance counters are disabled
11148 +//
11149 +#define FSA_DO_PERF_INC(Counter)               /* */
11150 +#define FSA_DO_FSP_PERF_INC(Counter)   /* */
11151 +
11152 +#endif /* FSA_DO_PERF */
11153 +
11154 +#endif // _FSA_PERFPACK_H_
11155 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/port.h linux/drivers/scsi/aacraid/include/port.h
11156 --- linux-2.4.9/drivers/scsi/aacraid/include/port.h     Wed Dec 31 18:00:00 1969
11157 +++ linux/drivers/scsi/aacraid/include/port.h   Thu Aug 16 18:16:55 2001
11158 @@ -0,0 +1,87 @@
11159 +/*++
11160 + * Adaptec aacraid device driver for Linux.
11161 + *
11162 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11163 + *
11164 + * This program is free software; you can redistribute it and/or modify
11165 + * it under the terms of the GNU General Public License as published by
11166 + * the Free Software Foundation; either version 2, or (at your option)
11167 + * any later version.
11168 + *
11169 + * This program is distributed in the hope that it will be useful,
11170 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11171 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11172 + * GNU General Public License for more details.
11173 + *
11174 + * You should have received a copy of the GNU General Public License
11175 + * along with this program; see the file COPYING.  If not, write to
11176 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11177 + *
11178 + * Module Name:
11179 + *   port.h
11180 + *
11181 + * Abstract: This module defines functions and structures that are in common among all miniports
11182 + *
11183 + *     
11184 + --*/
11185 +
11186 +#ifndef _PORT_
11187 +#define _PORT_
11188 +
11189 +static char *ident_porth = "aacraid_ident port.h 1.0.6 2000/10/09 Adaptec, Inc.";
11190 +
11191 +#ifdef DBG
11192 +#define AfaPortPrint if (AfaPortPrinting) DbgPrint
11193 +extern int AfaPortPrinting;
11194 +#else
11195 +#define AfaPortPrint 
11196 +#endif /* DBG */
11197 +
11198 +extern int AfaPortPrinting;
11199 +
11200 +
11201 +BOOLEAN
11202 +AfaPortAllocateAdapterCommArea(
11203 +       IN PVOID                Arg1,
11204 +       IN OUT PVOID    *CommHeaderAddress,
11205 +       IN ULONG                CommAreaSize,
11206 +       IN ULONG                CommAreaAlignment
11207 +       );
11208 +
11209 +
11210 +BOOLEAN
11211 +AfaPortFreeAdapterCommArea(
11212 +       IN PVOID                Arg1
11213 +       );
11214 +
11215 +
11216 +AAC_STATUS
11217 +AfaPortBuildSgMap(
11218 +       PVOID Arg1,
11219 +       IN PSGMAP_CONTEXT SgMapContext
11220 +       );
11221 +
11222 +
11223 +VOID
11224 +AfaPortFreeDmaResources(
11225 +       PVOID Arg1,
11226 +    IN PSGMAP_CONTEXT SgMapContext
11227 +    );
11228 +
11229 +
11230 +BOOLEAN
11231 +AfaPortAllocateAndMapFibSpace(
11232 +       PVOID Arg1,
11233 +    IN PMAPFIB_CONTEXT MapFibContext
11234 +    );
11235 +
11236 +
11237 +BOOLEAN
11238 +AfaPortUnmapAndFreeFibSpace(
11239 +       PVOID Arg1,
11240 +    IN PMAPFIB_CONTEXT MapFibContext
11241 +    );
11242 +
11243 +
11244 +#endif // _PORT_
11245 +
11246 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/protocol.h linux/drivers/scsi/aacraid/include/protocol.h
11247 --- linux-2.4.9/drivers/scsi/aacraid/include/protocol.h Wed Dec 31 18:00:00 1969
11248 +++ linux/drivers/scsi/aacraid/include/protocol.h       Thu Aug 16 13:41:30 2001
11249 @@ -0,0 +1,249 @@
11250 +/*++
11251 + * Adaptec aacraid device driver for Linux.
11252 + *
11253 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11254 + *
11255 + * This program is free software; you can redistribute it and/or modify
11256 + * it under the terms of the GNU General Public License as published by
11257 + * the Free Software Foundation; either version 2, or (at your option)
11258 + * any later version.
11259 + *
11260 + * This program is distributed in the hope that it will be useful,
11261 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11262 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11263 + * GNU General Public License for more details.
11264 + *
11265 + * You should have received a copy of the GNU General Public License
11266 + * along with this program; see the file COPYING.  If not, write to
11267 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11268 + *
11269 + * Module Name:
11270 + *   protocol.h
11271 + *
11272 + * Abstract: Defines the commands and command data which enables the nt
11273 + *    filesystem driver to be the client of the fsa adapter
11274 + *    filesystem. This protocol is largely modeled after the NFS
11275 + *    V3 protocol with modifications allowed due to the unique
11276 + *    client/server model FSA works under.
11277 + *
11278 + *
11279 + *     
11280 + --*/
11281 +
11282 +#ifndef _PROTOCOL_H_
11283 +#define _PROTOCOL_H_
11284 +
11285 +static char *ident_protocol = "aacraid_ident protocol.h 1.0.6 2000/10/09 Adaptec, Inc.";
11286 +
11287 +#include <fsafs.h>      // definition of FSAFID; includes fsatypes.h
11288 +#include <nvramioctl.h> // for NVRAMINFO definition
11289 +
11290 +// #define MDL_READ_WRITE
11291 +
11292 +//
11293 +// Define the command values
11294 +//
11295 +typedef enum _FSA_COMMANDS {
11296 +        Null = 0,
11297 +        GetAttributes,
11298 +        SetAttributes,
11299 +        Lookup,
11300 +        ReadLink,
11301 +        Read,
11302 +        Write,
11303 +        Create,
11304 +        MakeDirectory,
11305 +        SymbolicLink,
11306 +        MakeNode,
11307 +        Removex,
11308 +        RemoveDirectoryx, // bkpfix added x to this because already defined in nt
11309 +        Rename,
11310 +        Link,
11311 +        ReadDirectory,
11312 +        ReadDirectoryPlus,
11313 +        FileSystemStatus,
11314 +        FileSystemInfo,
11315 +        PathConfigure,
11316 +        Commit,
11317 +        Mount,
11318 +        UnMount,
11319 +        Newfs,
11320 +        FsCheck,
11321 +        FsSync,
11322 +               SimReadWrite,
11323 +               SetFileSystemStatus,
11324 +               BlockRead,
11325 +               BlockWrite,
11326 +               NvramIoctl,
11327 +               FsSyncWait,
11328 +               ClearArchiveBit,
11329 +#ifdef MDL_READ_WRITE
11330 +               MdlReadComplete,
11331 +               MdlWriteComplete,
11332 +               MdlRead,                        // these are used solely for stats, Mdl really controlled by 
11333 +               MdlWrite,                       // flags field in Fib.
11334 +#endif
11335 +               SetAcl,
11336 +               GetAcl,
11337 +               AssignAcl,
11338 +               FaultInsertion,         // Fault Insertion Command
11339 +               CrazyCache,                     // crazycache
11340 +               MAX_FSACOMMAND_NUM      //CJ: used for sizing stats array - leave last
11341 +} _E_FSACOMMAND;
11342 +
11343 +#ifdef AAC_32BIT_ENUMS
11344 +typedef        _E_FSACOMMAND   FSACOMMAND;
11345 +#else
11346 +typedef AAC_UINT32             FSACOMMAND;
11347 +#endif
11348 +
11349 +
11350 +
11351 +//
11352 +// Define the status returns
11353 +//
11354 +// See include\comm\errno.h for adapter kernel errno's
11355 +typedef enum _FSASTATUS {
11356 +       ST_OK = 0,
11357 +       ST_PERM = 1,
11358 +       ST_NOENT = 2,
11359 +       ST_IO = 5,
11360 +       ST_NXIO = 6,
11361 +       ST_E2BIG = 7,
11362 +       ST_ACCES = 13,
11363 +       ST_EXIST = 17,
11364 +       ST_XDEV = 18,
11365 +       ST_NODEV = 19,
11366 +       ST_NOTDIR = 20,
11367 +       ST_ISDIR = 21,
11368 +       ST_INVAL = 22,
11369 +       ST_FBIG = 27,
11370 +       ST_NOSPC = 28,
11371 +       ST_ROFS = 30,
11372 +       ST_MLINK = 31,
11373 +       ST_WOULDBLOCK = 35,
11374 +       ST_NAMETOOLONG = 63,
11375 +       ST_NOTEMPTY = 66,
11376 +       ST_DQUOT = 69,
11377 +       ST_STALE = 70,
11378 +       ST_REMOTE = 71,
11379 +       ST_BADHANDLE = 10001,
11380 +       ST_NOT_SYNC = 10002,
11381 +       ST_BAD_COOKIE = 10003,
11382 +       ST_NOTSUPP = 10004,
11383 +       ST_TOOSMALL = 10005,
11384 +       ST_SERVERFAULT = 10006,
11385 +       ST_BADTYPE = 10007,
11386 +       ST_JUKEBOX = 10008,
11387 +       ST_NOTMOUNTED = 10009,
11388 +       ST_MAINTMODE = 10010,
11389 +       ST_STALEACL = 10011
11390 +} _E_FSASTATUS;
11391 +
11392 +#ifdef AAC_32BIT_ENUMS
11393 +typedef _E_FSASTATUS   FSASTATUS;
11394 +#else
11395 +typedef        AAC_UINT32              FSASTATUS;
11396 +#endif
11397 +
11398 +//
11399 +// On writes how does the client want the data written.
11400 +//
11401 +
11402 +typedef enum _CACHELEVEL {
11403 +       CSTABLE = 1,
11404 +    CUNSTABLE
11405 +} _E_CACHELEVEL;
11406 +
11407 +#ifdef AAC_32BIT_ENUMS
11408 +typedef _E_CACHELEVEL  CACHELEVEL;
11409 +#else
11410 +typedef        AAC_UINT32              CACHELEVEL;
11411 +#endif
11412 +
11413 +//
11414 +// Lets the client know at which level the data was commited on a write request
11415 +//
11416 +
11417 +typedef enum _COMMITLEVEL {
11418 +    CMFILE_SYNCH_NVRAM = 1,
11419 +    CMDATA_SYNCH_NVRAM,
11420 +    CMFILE_SYNCH,
11421 +    CMDATA_SYNCH,
11422 +    CMUNSTABLE
11423 +} _E_COMMITLEVEL;
11424 +
11425 +#ifdef AAC_32BIT_ENUMS
11426 +typedef _E_COMMITLEVEL COMMITLEVEL;
11427 +#else
11428 +typedef AAC_UINT32             COMMITLEVEL;
11429 +#endif
11430 +
11431 +
11432 +
11433 +//
11434 +// The following are all the different commands or FIBs which can be sent to the
11435 +// FSA filesystem. We will define a required subset which cannot return STATUS_NOT_IMPLEMENTED,
11436 +// but others outside that subset are allowed to return not implemented. The client is then
11437 +// responsible for dealing with the fact it is not implemented.
11438 +//
11439 +typedef AAC_INT8 FSASTRING[16];
11440 +
11441 +
11442 +typedef AAC_UINT32     BYTECOUNT;      // only 32 bit-ism
11443 +
11444 +
11445 +
11446 +//
11447 +// BlockRead
11448 +//
11449 +
11450 +typedef struct _BLOCKREAD { // variable size struct
11451 +
11452 +    FSACOMMAND                 Command;
11453 +    AAC_UINT32                 ContainerId;
11454 +    BYTECOUNT          BlockNumber;
11455 +    BYTECOUNT          ByteCount;
11456 +       SGMAP                   SgMap;  // Must be last in struct because it is variable
11457 +
11458 +} BLOCKREAD;
11459 +typedef BLOCKREAD *PBLOCKREAD;
11460 +
11461 +typedef struct _BLOCKREADRESPONSE {
11462 +
11463 +    FSASTATUS          Status;
11464 +    BYTECOUNT          ByteCount;
11465 +
11466 +} BLOCKREADRESPONSE;
11467 +typedef BLOCKREADRESPONSE *PBLOCKREADRESPONSE;
11468 +
11469 +//
11470 +// BlockWrite
11471 +//
11472 +
11473 +typedef struct _BLOCKWRITE {   // variable size struct
11474 +
11475 +    FSACOMMAND                 Command;
11476 +    AAC_UINT32                 ContainerId;
11477 +    BYTECOUNT          BlockNumber;
11478 +    BYTECOUNT          ByteCount;
11479 +    CACHELEVEL                 Stable;
11480 +       SGMAP                   SgMap;  // Must be last in struct because it is variable
11481 +
11482 +} BLOCKWRITE;
11483 +typedef BLOCKWRITE *PBLOCKWRITE;
11484 +
11485 +
11486 +typedef struct _BLOCKWRITERESPONSE {
11487 +
11488 +    FSASTATUS          Status;
11489 +    BYTECOUNT          ByteCount;
11490 +    COMMITLEVEL        Committed;
11491 +
11492 +} BLOCKWRITERESPONSE;
11493 +typedef BLOCKWRITERESPONSE *PBLOCKWRITERESPONSE;
11494 +
11495 +
11496 +
11497 +#endif // _PROTOCOL_H_
11498 +
11499 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/revision.h linux/drivers/scsi/aacraid/include/revision.h
11500 --- linux-2.4.9/drivers/scsi/aacraid/include/revision.h Wed Dec 31 18:00:00 1969
11501 +++ linux/drivers/scsi/aacraid/include/revision.h       Thu Aug 16 13:41:30 2001
11502 @@ -0,0 +1,350 @@
11503 +/*++
11504 + * Adaptec aacraid device driver for Linux.
11505 + *
11506 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11507 + *
11508 + * This program is free software; you can redistribute it and/or modify
11509 + * it under the terms of the GNU General Public License as published by
11510 + * the Free Software Foundation; either version 2, or (at your option)
11511 + * any later version.
11512 + *
11513 + * This program is distributed in the hope that it will be useful,
11514 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11515 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11516 + * GNU General Public License for more details.
11517 + *
11518 + * You should have received a copy of the GNU General Public License
11519 + * along with this program; see the file COPYING.  If not, write to
11520 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11521 + *
11522 + * Module Name:
11523 + *   revision.h
11524 + *
11525 + * Abstract: This module contains all of the revision information for
11526 + *     the FSA product, as well as the support routines for
11527 + *     checking module compatibility.
11528 + *
11529 + *     Before editing anything in this module, make sure that
11530 + *     you read the comments. Some lines are changed automatically
11531 + *     as part of the build, and should never be changed by hand.
11532 + *
11533 + * Routines (all inlines):
11534 + *
11535 + *     RevGetBuildNumber - Retrieve current build number
11536 + *     RevGetExternalRev - Retrieve revision for external use
11537 + *     RevGetFullRevision - Retrieve full revision structure
11538 + *
11539 + *     RevCheckCompatibility - Checks compatibility base on internal table
11540 + *
11541 + *     RevCheckCompatibilityFullInfo - Check for static component
11542 + *     RevGetCompInfoTableSize - Get size for static component table
11543 + *     RevGetCompInfoTable - Get actual table to place on static component
11544 + *     RevGetBuildNumberFromInfo - Get build number for static component.
11545 + *
11546 + *
11547 + *     
11548 + --*/
11549 +
11550 +#ifndef _REVISION_H
11551 +#define _REVISION_H
11552 +
11553 +static char *ident_revision = "aacraid_ident revision.h 1.0.6 2000/10/09 Adaptec, Inc.";
11554 +
11555 +#include "version.h" // revision numbers kept separate so they can be used by resource compiler as well
11556 +
11557 +typedef int REV_BOOL;
11558 +
11559 +#define REV_TRUE 1
11560 +#define REV_FALSE 0
11561 +
11562 +//
11563 +//     Define Revision Levels for this product
11564 +//
11565 +//  IMPORTANT: Do NOT modify BUILD_NUMBER define, this is modified
11566 +//                        automatically by the build.
11567 +//
11568 +//  Version is VMAJOR.MINOR-DASH TYPE (Build BUILD_NUMBER)
11569 +//
11570 +//     IMPORTANT: Don't access these revisions directly. They can be
11571 +//                        accessed via, the RevGetXxxxx rouines.
11572 +//
11573 +
11574 +
11575 +#define REV_AS_LONGWORD \
11576 +       ((REV_MAJOR << 24) | (REV_MINOR << 16) | (REV_TYPE << 8) | (REV_DASH))
11577 +
11578 +
11579 +
11580 +#ifndef BIOS
11581 +
11582 +//
11583 +//     Enumerate the types of product levels we can have
11584 +//
11585 +enum {
11586 +       RevType_Devo=1,         // Development mode, testing all of latest
11587 +       RevType_Alpha,          // Alpha - Internal field test
11588 +       RevType_Beta,           // Beta - External field test
11589 +       RevType_Release         // Release - Retail version
11590 +};
11591 +
11592 +//
11593 +//     Define the basic structure for all revision information. Note
11594 +//     that the ordering of the components is such that they should
11595 +//     always increase. dash will be updated the most, then the version
11596 +//     type, then minor and major.
11597 +//
11598 +typedef struct {
11599 +       union {
11600 +               struct {
11601 +                       unsigned char dash;     // Dash version number
11602 +                       unsigned char type;     // Type, 1=Devo, 2=Alpha, 3=Beta, 4=Release
11603 +                       unsigned char minor;// Minor version minor
11604 +                       unsigned char major;// Major version number
11605 +               } comp;                         // Components to external viewed rev number
11606 +               unsigned long ul;       // External revision as single 32-bit value
11607 +       } external;                     // External revision number (union)
11608 +       unsigned long buildNumber; // Automatically generated build number
11609 +} FsaRevision;
11610 +
11611 +
11612 +//
11613 +//     Define simple routines to get basic revision information. The
11614 +//     definitions should never be accessed directly. These routines
11615 +//     are meant to be used to access all relevant information no matter
11616 +//     how simple.
11617 +//
11618 +static inline unsigned long RevGetBuildNumber() {return REV_BUILD_NUMBER;}
11619 +
11620 +static inline unsigned long RevGetExternalRev() {return REV_AS_LONGWORD;}
11621 +
11622 +
11623 +//
11624 +//     Enumerate different components that may have to check
11625 +//     compatibility. This list of components can be changed
11626 +//     at any time.
11627 +//
11628 +//     IMPORTANT: ONLY add to the END of this enum structure. Otherwise,
11629 +//                        incompatibilities between component rev checking will
11630 +//                        cause wrong checking results.
11631 +//
11632 +typedef enum {
11633 +       RevApplication = 1,     // Any user End application
11634 +       RevDkiCli,                      // ADAPTEC proprietary interface (knows FIBs)
11635 +       RevNetService,          // Network Service Revision (under API)
11636 +       RevApi,                         // ADAPTEC User mode API
11637 +       RevFileSysDriver,       // FSA File System Driver
11638 +       RevMiniportDriver,      // FSA File System Miniport Driver
11639 +       RevAdapterSW,           // Adapter Software (or NT Simulator)
11640 +       RevMonitor,                     // Monitor for adapter hardware (MON960 for now)
11641 +       RevRemoteApi            // The remote API.
11642 +       // ALWAYS ADD NEW COMPONENTS HERE - AT END
11643 +} RevComponent;
11644 +
11645 +//
11646 +//     Define a structure so that we can create a compatibility table.
11647 +//
11648 +typedef struct {
11649 +       RevComponent A,B;
11650 +       unsigned long BuildNumOfB_RequiredByA;
11651 +       unsigned long BuildNumOfA_RequiredByB;
11652 +} RevCompareElement;
11653 +
11654 +//
11655 +//     Now, define the table. This table should only be included once,
11656 +//     in one program. If it is linked from 2 modules, there will likely
11657 +//     be a multiply defined symbol error from the linker.
11658 +//
11659 +//     To fix this problem, REV_REFERENCE_ONLY can be defined. This will
11660 +//     allow access to the revision information table without a redefinition
11661 +//     of the tables.
11662 +//
11663 +extern const int                          RevCompareTableLength;
11664 +
11665 +extern const RevCompareElement RevCompareTable[];
11666 +
11667 +/********************************************************************\
11668 +* Routine: RevCheckCompatibility(callerComp,compB,compB_BuildNumber)
11669 +*
11670 +*      The following routine is used to check compatibility between
11671 +*      the calling component and a component that has some dependencies
11672 +*      on it. If this routine returns REV_FALSE, it is expected that the caller
11673 +*      will send an appropriate incompatibility message and stop.
11674 +*
11675 +*      This routine is only meant to check for compatibility in the
11676 +*      absolute sense. If code wishes to execute a different path based
11677 +*      on the CompB_BuildNumber, then this routine is not useful. The
11678 +*      routine RevGetBuildNumber can be used to get the calling module's
11679 +*      current build number for a comparison check.
11680 +*
11681 +*      The return value is REV_TRUE, if compatibility is possible, and REV_FALSE
11682 +*      if the components are definitely not compatible, or there is an
11683 +*      error when trying to figure it out. To be more specific:
11684 +*
11685 +*              1) REV_TRUE if component B is newer than calling component. (In this
11686 +*                 case, the revision check done by component B with respect to
11687 +*                 this component will give the real compatibility information.
11688 +*                 It is the only one with the knowledge, since this component
11689 +*                 could not look into the future.)
11690 +*              2) REV_TRUE if calling component is more recent and table shows okay
11691 +*              3) REV_FALSE if calling component more recent and table show not okay
11692 +*              4) REV_FALSE if calling component is more recent and table entry to
11693 +*                 check does not exist.
11694 +*
11695 +*      Note that the CompB_BuildNumber must be attained by the calling
11696 +*      routine through some mechanism done by the caller.
11697 +*
11698 +* Input:
11699 +*
11700 +*      callerComp - Name of component making this call
11701 +*      compB - Name of component to check compatibility with
11702 +*      compB_BuildNumber - Build number to component B
11703 +*
11704 +* Output:
11705 +*
11706 +*      None
11707 +*
11708 +* Return Value:
11709 +*
11710 +*      REV_TRUE - Component compatibility is possible, continue as usual. compB
11711 +*                 must give true compatibility information.
11712 +*      REV_FALSE - Incompatible components, notify and end
11713 +*
11714 +\********************************************************************/
11715 +static inline REV_BOOL RevCheckCompatibility(
11716 +               RevComponent callerComp,
11717 +               RevComponent compB,
11718 +               unsigned long compB_BuildNumber)
11719 +{
11720 +       int i;
11721 +       unsigned long RevForB;
11722 +
11723 +       //
11724 +       //      Compatibility check is possible, so we should continue. When
11725 +       //      compB makes this call in its own component, it will get the
11726 +       //      true compatibility information, since only it can know.
11727 +       //
11728 +       if (RevGetBuildNumber() < compB_BuildNumber) return REV_TRUE;
11729 +
11730 +       //
11731 +       //      Go through rev table. When the components are found in the
11732 +       //      same table entry, return the approprate number.
11733 +       //
11734 +       for (i=0; i<RevCompareTableLength; i++) {
11735 +               if (RevCompareTable[i].A == callerComp) {
11736 +                       if (RevCompareTable[i].B == compB) {
11737 +                               RevForB = RevCompareTable[i].BuildNumOfB_RequiredByA;
11738 +                               return (compB_BuildNumber >= RevForB);
11739 +                       }
11740 +               } else if (RevCompareTable[i].B == callerComp) {
11741 +                       if (RevCompareTable[i].A == compB) {
11742 +                               RevForB = RevCompareTable[i].BuildNumOfA_RequiredByB;
11743 +                               return (compB_BuildNumber >= RevForB);
11744 +                       }
11745 +               }
11746 +       }
11747 +
11748 +       //
11749 +       //      Uh oh! No relevant table entry was found (this should never
11750 +       //      happen).
11751 +       //
11752 +       return REV_FALSE;
11753 +}
11754 +
11755 +
11756 +//
11757 +//     Now create a structure that can be used by a FIB to check
11758 +//     compatibility.
11759 +//
11760 +typedef struct _RevCheck {
11761 +       RevComponent callingComponent;
11762 +       FsaRevision callingRevision;
11763 +} RevCheck;
11764 +
11765 +typedef struct _RevCheckResp {
11766 +       REV_BOOL possiblyCompatible;
11767 +       FsaRevision adapterSWRevision;
11768 +} RevCheckResp;
11769 +
11770 +#endif /* bios */
11771 +#endif /* _REVISION_H */
11772 +
11773 +//
11774 +//     The following allows for inclusion of revision.h in other h
11775 +//     files. when you include this file in another h file, simply
11776 +//     define REV_REFERENCE_ONLY. This will be undefined later, so that
11777 +//     the single C file inclusion in the module will be used to
11778 +//     implement the global structures.
11779 +//
11780 +#ifndef REV_REFERENCE_ONLY
11781 +#ifndef _REVISION_H_GLOBAL
11782 +#define _REVISION_H_GLOBAL
11783 +
11784 +
11785 +
11786 +//
11787 +//     The following array is the table of compatibility. This table
11788 +//     can be modified in two ways:
11789 +//
11790 +//             1) A component which has an incompatible change done to
11791 +//                it, can get a new build number.
11792 +//
11793 +//             2) A new component can be added, requiring more entries
11794 +//                to be place into this table.
11795 +//
11796 +//
11797 +//     In case (1), you must change the revision number in the appropriate
11798 +//     column, based on which component absolutely requires an upgrade.
11799 +//
11800 +//     Example: A new FIB used by the API, in build number 105
11801 +//             {RevApi,        RevAdapterSW,           100,  100}
11802 +//                     ---> would be changed to <---
11803 +//             {RevApi,        RevAdapterSW,           105,  100}
11804 +//
11805 +//     Example: A structure is changed for a FIB that only the API uses
11806 +//             {RevApi,        RevAdapterSW,           100,  100}
11807 +//                     ---> would be changed to <---
11808 +//             {RevApi,        RevAdapterSW,           105,  105}
11809 +//
11810 +//
11811 +//     In case (2), the less common case, the enumerated list of
11812 +//     components must be changed to include the new component. Then
11813 +//     entries need to be placed into this table.
11814 +//
11815 +//     Since the revisions must be communicated between the two
11816 +//     components, it is likely that you would need to put in the
11817 +//     current build number for both columns. That is the recommended
11818 +//     way to start revision test.
11819 +//
11820 +const RevCompareElement RevCompareTable[] = {
11821 +       // Component A          Component B                     MinBForA        MinAForB
11822 +       // -----------          -----------                     --------        --------
11823 +       {RevApplication,        RevApi,                         2120,           2120    },
11824 +       {RevDkiCli,             RevApi,                         2120,           2120    },
11825 +       {RevDkiCli,             RevFileSysDriver,               257,            257     },
11826 +       {RevDkiCli,             RevMiniportDriver,              257,            257     },
11827 +       {RevDkiCli,             RevAdapterSW,                   257,            257     },
11828 +       {RevApi,                RevFileSysDriver,               2120,           2120    },
11829 +       {RevApi,                RevMiniportDriver,              2120,           2120    },
11830 +       {RevApi,                RevAdapterSW,                   2120,           2120    },
11831 +       {RevApi,                RevNetService,                  2120,           2120    },
11832 +       {RevFileSysDriver,      RevMiniportDriver,              100,            100     },
11833 +       {RevFileSysDriver,      RevAdapterSW,                   257,            257     },
11834 +       {RevMiniportDriver,     RevAdapterSW,                   257,            257     },
11835 +       {RevMiniportDriver,     RevMonitor,                     100,            100     },
11836 +       {RevApi,                RevNetService,                  2120,           2120    },
11837 +       {RevApi,                RevRemoteApi,                   2120,           2120    },
11838 +       {RevNetService,         RevRemoteApi,                   2120,           2120    }
11839 +};
11840 +
11841 +const int RevCompareTableLength = sizeof(RevCompareTable)/sizeof(RevCompareElement);
11842 +
11843 +#endif /* _REVISION_H_GLOBAL */
11844 +#endif /* REV_REFERENCE_ONLY */
11845 +#undef REV_REFERENCE_ONLY
11846 +
11847 +
11848 +
11849 +
11850 +
11851 +
11852 +
11853 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/rx.h linux/drivers/scsi/aacraid/include/rx.h
11854 --- linux-2.4.9/drivers/scsi/aacraid/include/rx.h       Wed Dec 31 18:00:00 1969
11855 +++ linux/drivers/scsi/aacraid/include/rx.h     Thu Aug 16 13:41:30 2001
11856 @@ -0,0 +1,81 @@
11857 +/*++
11858 + * Adaptec aacraid device driver for Linux.
11859 + *
11860 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11861 + *
11862 + * This program is free software; you can redistribute it and/or modify
11863 + * it under the terms of the GNU General Public License as published by
11864 + * the Free Software Foundation; either version 2, or (at your option)
11865 + * any later version.
11866 + *
11867 + * This program is distributed in the hope that it will be useful,
11868 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11869 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11870 + * GNU General Public License for more details.
11871 + *
11872 + * You should have received a copy of the GNU General Public License
11873 + * along with this program; see the file COPYING.  If not, write to
11874 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11875 + *
11876 + * Module Name:
11877 + *   rx.h
11878 + *
11879 + * Abstract: Prototypes and data structures unique to the Rx based controller board.
11880 + *
11881 + *     
11882 + --*/
11883 +
11884 +static char *ident_rxh = "aacraid_ident rx.h 1.0.6 2000/10/09 Adaptec, Inc.";
11885 +
11886 +typedef struct _Rx_ADAPTER_EXTENSION {
11887 +
11888 +       //
11889 +       // The following must be first.
11890 +       //
11891 +       PPCI_MINIPORT_COMMON_EXTENSION  Common;
11892 +       struct _Rx_ADAPTER_EXTENSION    *Next;                          // Next adapter miniport structure
11893 +    USHORT                                                     LocalMaskInterruptControl;
11894 +       PRx_DEVICE_REGISTERS                    Device;
11895 +
11896 +} Rx_ADAPTER_EXTENSION;
11897 +
11898 +    
11899 +typedef Rx_ADAPTER_EXTENSION *PRx_ADAPTER_EXTENSION;
11900 +
11901 +
11902 +
11903 +#ifdef LINUX
11904 +/*
11905 + * 
11906 + */
11907 +
11908 +#define Rx_READ_UCHAR(AEP,  CSR)                       *(volatile unsigned char *)  &((AEP)->Device->CSR)
11909 +    
11910 +
11911 +
11912 +#define Rx_READ_ULONG(AEP,  CSR)                       *(volatile unsigned int *)   &((AEP)->Device->CSR)
11913 +#define Rx_WRITE_UCHAR(AEP,  CSR, Value)       *(volatile unsigned char *)  &((AEP)->Device->CSR) = (Value)
11914 +
11915 +
11916 +#define Rx_WRITE_ULONG(AEP, CSR, Value)                *(volatile unsigned int *)   &((AEP)->Device->CSR) = (Value)
11917 +
11918 +#endif /* LINUX */
11919 +
11920 +
11921 +VOID
11922 +RxInterruptAdapter(
11923 +       PVOID Arg1
11924 +       );
11925 +
11926 +VOID
11927 +RxNotifyAdapter(
11928 +       PVOID Arg1,
11929 +    IN HOST_2_ADAP_EVENT AdapterEvent
11930 +    );
11931 +
11932 +VOID
11933 +RxResetDevice(
11934 +       PVOID Arg1
11935 +       );
11936 +
11937 +
11938 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/rxcommon.h linux/drivers/scsi/aacraid/include/rxcommon.h
11939 --- linux-2.4.9/drivers/scsi/aacraid/include/rxcommon.h Wed Dec 31 18:00:00 1969
11940 +++ linux/drivers/scsi/aacraid/include/rxcommon.h       Thu Aug 16 13:41:30 2001
11941 @@ -0,0 +1,105 @@
11942 +/*++
11943 + * Adaptec aacraid device driver for Linux.
11944 + *
11945 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11946 + *
11947 + * This program is free software; you can redistribute it and/or modify
11948 + * it under the terms of the GNU General Public License as published by
11949 + * the Free Software Foundation; either version 2, or (at your option)
11950 + * any later version.
11951 + *
11952 + * This program is distributed in the hope that it will be useful,
11953 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11954 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11955 + * GNU General Public License for more details.
11956 + *
11957 + * You should have received a copy of the GNU General Public License
11958 + * along with this program; see the file COPYING.  If not, write to
11959 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11960 + *
11961 + * Module Name:
11962 + *   rxcommon.h
11963 + *
11964 + * Abstract: Structures and defines for the i960 Rx chip.
11965 + *
11966 + *     
11967 + --*/
11968 +
11969 +#ifndef _Rx_COMMON_H_
11970 +#define _Rx_COMMON_H_
11971 +
11972 +static char *ident_rxcommon = "aacraid_ident rxcommon.h 1.0.6 2000/10/09 Adaptec, Inc.";
11973 +
11974 +//
11975 +// Rx Message Unit Registers
11976 +//
11977 +
11978 +typedef volatile struct _StructRxMURegisters {
11979 +                                                                               //       Local  |   PCI*        |       Name
11980 +                                                                               //                      |               |
11981 +       unsigned        ARSR;                                   //      1300h   |       00h     |       APIC Register Select Register
11982 +       unsigned        reserved0;                              //      1304h   |       04h     |       Reserved
11983 +       unsigned        AWR;                                    //      1308h   |       08h     |       APIC Window Register
11984 +       unsigned        reserved1;                              //      130Ch   |       0Ch     |       Reserved
11985 +       unsigned        IMRx[2];                                //      1310h   |       10h     |       Inbound Message Registers
11986 +       unsigned        OMRx[2];                                //      1318h   |       18h     |       Outbound Message Registers
11987 +       unsigned        IDR;                                    //      1320h   |       20h     |       Inbound Doorbell Register
11988 +       unsigned        IISR;                                   //      1324h   |       24h     |       Inbound Interrupt Status Register
11989 +       unsigned        IIMR;                                   //      1328h   |       28h     |       Inbound Interrupt Mask Register
11990 +       unsigned        ODR;                                    //      132Ch   |       2Ch     |       Outbound Doorbell Register
11991 +       unsigned        OISR;                                   //      1330h   |       30h     |       Outbound Interrupt Status Register
11992 +       unsigned        OIMR;                                   //      1334h   |       34h     |       Outbound Interrupt Mask Register
11993 +                                                                               // * Must access trhough ATU Inbound Translation Window
11994 +
11995 +}Rx_MU_CONFIG;
11996 +typedef Rx_MU_CONFIG *PRx_MU_CONFIG;
11997 +
11998 +typedef volatile struct _Rx_Inbound {
11999 +
12000 +       unsigned        Mailbox[8];
12001 +
12002 +}Rx_Inbound;
12003 +
12004 +typedef Rx_Inbound *PRx_Inbound;
12005 +
12006 +#define        InboundMailbox0         IndexRegs.Mailbox[0]
12007 +#define        InboundMailbox1         IndexRegs.Mailbox[1]
12008 +#define        InboundMailbox2         IndexRegs.Mailbox[2]
12009 +#define        InboundMailbox3         IndexRegs.Mailbox[3]
12010 +#define        InboundMailbox4         IndexRegs.Mailbox[4]
12011 +
12012 +
12013 +
12014 +#define        INBOUNDDOORBELL_0       0x00000001
12015 +#define INBOUNDDOORBELL_1      0x00000002
12016 +#define INBOUNDDOORBELL_2      0x00000004
12017 +#define INBOUNDDOORBELL_3      0x00000008
12018 +#define INBOUNDDOORBELL_4      0x00000010
12019 +#define INBOUNDDOORBELL_5      0x00000020
12020 +#define INBOUNDDOORBELL_6      0x00000040
12021 +
12022 +
12023 +#define        OUTBOUNDDOORBELL_0      0x00000001
12024 +#define OUTBOUNDDOORBELL_1     0x00000002
12025 +#define OUTBOUNDDOORBELL_2     0x00000004
12026 +#define OUTBOUNDDOORBELL_3     0x00000008
12027 +#define OUTBOUNDDOORBELL_4     0x00000010
12028 +
12029 +
12030 +#define InboundDoorbellReg     MUnit.IDR
12031 +
12032 +#define OutboundDoorbellReg    MUnit.ODR
12033 +
12034 +
12035 +typedef struct _Rx_DEVICE_REGISTERS {
12036 +       Rx_MU_CONFIG                    MUnit;                  // 1300h - 1334h
12037 +       unsigned                                reserved1[6];   // 1338h - 134ch
12038 +       Rx_Inbound                              IndexRegs;
12039 +} Rx_DEVICE_REGISTERS;
12040 +
12041 +typedef Rx_DEVICE_REGISTERS *PRx_DEVICE_REGISTERS;
12042 +
12043 +
12044 +#endif // _Rx_COMMON_H_
12045 +
12046 +
12047 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/sap1.h linux/drivers/scsi/aacraid/include/sap1.h
12048 --- linux-2.4.9/drivers/scsi/aacraid/include/sap1.h     Wed Dec 31 18:00:00 1969
12049 +++ linux/drivers/scsi/aacraid/include/sap1.h   Thu Aug 16 13:41:30 2001
12050 @@ -0,0 +1,85 @@
12051 +/*++
12052 + * Adaptec aacraid device driver for Linux.
12053 + *
12054 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
12055 + *
12056 + * This program is free software; you can redistribute it and/or modify
12057 + * it under the terms of the GNU General Public License as published by
12058 + * the Free Software Foundation; either version 2, or (at your option)
12059 + * any later version.
12060 + *
12061 + * This program is distributed in the hope that it will be useful,
12062 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
12063 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12064 + * GNU General Public License for more details.
12065 + *
12066 + * You should have received a copy of the GNU General Public License
12067 + * along with this program; see the file COPYING.  If not, write to
12068 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
12069 + *
12070 + * Module Name:
12071 + *   sap1.h
12072 + *
12073 + * Abstract: Prototypes and data structures unique to the Strong Arm based controller board.
12074 + *
12075 + *     
12076 + --*/
12077 +#ifndef _SAP1_H_
12078 +#define _SAP1_H_
12079 +
12080 +static char *ident_sap1h = "aacraid_ident sap1.h 1.0.6 2000/10/09 Adaptec, Inc.";
12081 +
12082 +#define Sa_MINIPORT_REVISION                   1
12083 +
12084 +typedef struct _Sa_ADAPTER_EXTENSION {
12085 +
12086 +       //
12087 +       // The following must be first.
12088 +       //
12089 +       PPCI_MINIPORT_COMMON_EXTENSION  Common;
12090 +       struct _Sa_ADAPTER_EXTENSION    *Next;                  // Next adapter miniport structure
12091 +       USHORT                                                  LocalMaskInterruptControl;
12092 +       PSa_DEVICE_REGISTERS                    Device;
12093 +
12094 +} Sa_ADAPTER_EXTENSION;
12095 +
12096 +typedef Sa_ADAPTER_EXTENSION *PSa_ADAPTER_EXTENSION;
12097 +
12098
12099 +
12100 +#ifdef LINUX
12101 +/*
12102 + * 
12103 + */
12104 +
12105
12106 +#define Sa_READ_USHORT(AEP, CSR)                       *(volatile unsigned short *) &((AEP)->Device->CSR)
12107 +#define Sa_READ_ULONG(AEP,  CSR)                       *(volatile unsigned int *)   &((AEP)->Device->CSR)
12108 +
12109
12110 +#define Sa_WRITE_USHORT(AEP, CSR, Value)       *(volatile unsigned short *) &((AEP)->Device->CSR) = (Value)
12111 +#define Sa_WRITE_ULONG(AEP, CSR, Value)                *(volatile unsigned int *)   &((AEP)->Device->CSR) = (Value)
12112 +
12113 +#endif /* LINUX */
12114 +
12115
12116 +VOID
12117 +SaInterruptAdapter(
12118 +       PVOID Arg1
12119 +       );
12120 +
12121 +VOID
12122 +SaNotifyAdapter(
12123 +       PVOID Arg1,
12124 +    IN HOST_2_ADAP_EVENT AdapterEvent
12125 +    );
12126 +
12127 +VOID
12128 +SaResetDevice(
12129 +       PVOID Arg1
12130 +       );
12131 +
12132
12133 +#endif /* _SAP1_H_ */
12134 +
12135 +
12136 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/sap1common.h linux/drivers/scsi/aacraid/include/sap1common.h
12137 --- linux-2.4.9/drivers/scsi/aacraid/include/sap1common.h       Wed Dec 31 18:00:00 1969
12138 +++ linux/drivers/scsi/aacraid/include/sap1common.h     Thu Aug 16 13:41:30 2001
12139 @@ -0,0 +1,111 @@
12140 +/*++
12141 + * Adaptec aacraid device driver for Linux.
12142 + *
12143 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
12144 + *
12145 + * This program is free software; you can redistribute it and/or modify
12146 + * it under the terms of the GNU General Public License as published by
12147 + * the Free Software Foundation; either version 2, or (at your option)
12148 + * any later version.
12149 + *
12150 + * This program is distributed in the hope that it will be useful,
12151 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
12152 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12153 + * GNU General Public License for more details.
12154 + *
12155 + * You should have received a copy of the GNU General Public License
12156 + * along with this program; see the file COPYING.  If not, write to
12157 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
12158 + *
12159 + * Module Name:
12160 + *   sap1common.h
12161 + *
12162 + * Abstract: Structures and defines for the Drawbridge and StrongArm110 chip.
12163 + *     
12164 + --*/
12165 +
12166 +#ifndef _Sa_COMMON_H_
12167 +#define _Sa_COMMON_H_
12168 +
12169 +static char *ident_sap1common = "aacraid_ident sap1common.h 1.0.6 2000/10/09 Adaptec, Inc.";
12170 +
12171 +//
12172 +// SaP1 Message Unit Registers
12173 +//
12174 +
12175 +typedef volatile struct _StructSaDrawbridge_CSR_RegisterMap {
12176 +                                                                                               //       Offset |       Name
12177 +       unsigned                        reserved[10];                   //      00h-27h |   Reserved
12178 +       unsigned char           LUT_Offset;                             //              28h     |       Looup Table Offset
12179 +       unsigned char           reserved1[3];                   //      29h-2bh |       Reserved
12180 +       unsigned                        LUT_Data;                               //              2ch     |       Looup Table Data        
12181 +       unsigned                        reserved2[26];                  //      30h-97h |       Reserved
12182 +       unsigned short          PRICLEARIRQ;                    //              98h     |       Primary Clear Irq
12183 +       unsigned short          SECCLEARIRQ;                    //              9ah     |       Secondary Clear Irq
12184 +       unsigned short          PRISETIRQ;                              //              9ch     |       Primary Set Irq
12185 +       unsigned short          SECSETIRQ;                              //              9eh     |       Secondary Set Irq
12186 +       unsigned short          PRICLEARIRQMASK;                //              a0h     |       Primary Clear Irq Mask
12187 +       unsigned short          SECCLEARIRQMASK;                //              a2h     |       Secondary Clear Irq Mask
12188 +       unsigned short          PRISETIRQMASK;                  //              a4h     |       Primary Set Irq Mask
12189 +       unsigned short          SECSETIRQMASK;                  //              a6h     |       Secondary Set Irq Mask
12190 +       unsigned                        MAILBOX0;                               //              a8h     |       Scratchpad 0
12191 +       unsigned                        MAILBOX1;                               //              ach     |       Scratchpad 1
12192 +       unsigned                        MAILBOX2;                               //              b0h     |       Scratchpad 2
12193 +       unsigned                        MAILBOX3;                               //              b4h     |       Scratchpad 3
12194 +       unsigned                        MAILBOX4;                               //              b8h     |       Scratchpad 4
12195 +       unsigned                        MAILBOX5;                               //              bch     |       Scratchpad 5
12196 +       unsigned                        MAILBOX6;                               //              c0h     |       Scratchpad 6
12197 +       unsigned                        MAILBOX7;                               //              c4h     |       Scratchpad 7
12198 +
12199 +       unsigned                        ROM_Setup_Data;                 //              c8h |   Rom Setup and Data
12200 +       unsigned                        ROM_Control_Addr;               //              cch |   Rom Control and Address
12201 +
12202 +       unsigned                        reserved3[12];                  //      d0h-ffh |       reserved
12203 +       unsigned                        LUT[64];                                // 100h-1ffh|   Lookup Table Entries
12204 +
12205 +       //
12206 +       //  TO DO
12207 +       //      need to add DMA, I2O, UART, etc registers form 80h to 364h
12208 +       //
12209 +
12210 +}Sa_Drawbridge_CSR;
12211 +
12212 +typedef Sa_Drawbridge_CSR *PSa_Drawbridge_CSR;
12213 +
12214 +
12215 +#define Mailbox0       SaDbCSR.MAILBOX0
12216 +#define Mailbox1       SaDbCSR.MAILBOX1
12217 +#define Mailbox2       SaDbCSR.MAILBOX2
12218 +#define Mailbox3       SaDbCSR.MAILBOX3
12219 +#define Mailbox4       SaDbCSR.MAILBOX4
12220 +
12221 +       
12222 +#define Mailbox7       SaDbCSR.MAILBOX7
12223 +       
12224 +#define DoorbellReg_p SaDbCSR.PRISETIRQ
12225 +#define DoorbellReg_s SaDbCSR.SECSETIRQ
12226 +#define DoorbellClrReg_p SaDbCSR.PRICLEARIRQ
12227 +
12228 +
12229 +#define        DOORBELL_0      0x00000001
12230 +#define DOORBELL_1     0x00000002
12231 +#define DOORBELL_2     0x00000004
12232 +#define DOORBELL_3     0x00000008
12233 +#define DOORBELL_4     0x00000010
12234 +#define DOORBELL_5     0x00000020
12235 +#define DOORBELL_6     0x00000040
12236 +
12237 +       
12238 +#define PrintfReady                    DOORBELL_5
12239 +#define PrintfDone                     DOORBELL_5
12240 +       
12241 +typedef struct _Sa_DEVICE_REGISTERS {
12242 +       Sa_Drawbridge_CSR       SaDbCSR;                        // 98h - c4h
12243 +} Sa_DEVICE_REGISTERS;
12244 +       
12245 +typedef Sa_DEVICE_REGISTERS *PSa_DEVICE_REGISTERS;
12246 +
12247 +       
12248 +#endif // _Sa_COMMON_H_
12249 +
12250 +
12251 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/version.h linux/drivers/scsi/aacraid/include/version.h
12252 --- linux-2.4.9/drivers/scsi/aacraid/include/version.h  Wed Dec 31 18:00:00 1969
12253 +++ linux/drivers/scsi/aacraid/include/version.h        Thu Aug 16 18:16:55 2001
12254 @@ -0,0 +1,40 @@
12255 +/*++
12256 + * Adaptec aacraid device driver for Linux.
12257 + *
12258 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
12259 + *
12260 + * This program is free software; you can redistribute it and/or modify
12261 + * it under the terms of the GNU General Public License as published by
12262 + * the Free Software Foundation; either version 2, or (at your option)
12263 + * any later version.
12264 + *
12265 + * This program is distributed in the hope that it will be useful,
12266 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
12267 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12268 + * GNU General Public License for more details.
12269 + *
12270 + * You should have received a copy of the GNU General Public License
12271 + * along with this program; see the file COPYING.  If not, write to
12272 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
12273 + *
12274 + * Module Name:
12275 + *   version.h
12276 + *
12277 + * Abstract: Keeps track of build number for development purposes.
12278 + *     
12279 + --*/
12280 +#ifndef _VERSION_H_
12281 +#define _VERSION_H_
12282 +
12283 +static char *ident_version = "aacraid_ident version.h 1.0.7 2000/8/10 Adaptec, Inc.";
12284 +
12285 +#include "build_number.h"
12286 +
12287 +#define REV_MAJOR 3
12288 +#define REV_MINOR 0
12289 +#define REV_TYPE RevType_Release
12290 +#define REV_DASH 0
12291 +
12292 +#define FSA_VERSION_STRING "3.0.0.5125\0"
12293 +
12294 +#endif /* _VERSION_H_ */
12295 diff -burN linux-2.4.9/drivers/scsi/aacraid/linit.c linux/drivers/scsi/aacraid/linit.c
12296 --- linux-2.4.9/drivers/scsi/aacraid/linit.c    Wed Dec 31 18:00:00 1969
12297 +++ linux/drivers/scsi/aacraid/linit.c  Thu Aug 16 13:41:30 2001
12298 @@ -0,0 +1,1086 @@
12299 +/*++
12300 + * Adaptec aacraid device driver for Linux.
12301 + *
12302 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
12303 + *
12304 + * This program is free software; you can redistribute it and/or modify
12305 + * it under the terms of the GNU General Public License as published by
12306 + * the Free Software Foundation; either version 2, or (at your option)
12307 + * any later version.
12308 + *
12309 + * This program is distributed in the hope that it will be useful,
12310 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
12311 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12312 + * GNU General Public License for more details.
12313 + *
12314 + * You should have received a copy of the GNU General Public License
12315 + * along with this program; see the file COPYING.  If not, write to
12316 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
12317 + *
12318 + * Module Name:
12319 + *   linit.c
12320 + *
12321 + * Abstract: Linux Driver entry module for Adaptec RAID Array Controller
12322 + *                             
12323 + *     Provides the following driver entry points:
12324 + *             AAC_DetectHostAdapter()
12325 + *             AAC_ReleaseHostAdapter()
12326 + *             AAC_QueueCommand()
12327 + *             AAC_ResetCommand()
12328 + *             AAC_BIOSDiskParameters()
12329 + *     
12330 + --*/
12331 +
12332 +static char *ident_linit = "aacraid_ident linit.c 1.0.6 2000/10/09 Adaptec, Inc.";
12333 +
12334 +/*------------------------------------------------------------------------------
12335 + *              D E F I N E S
12336 + *----------------------------------------------------------------------------*/
12337 +#define AAC_DRIVER_VERSION                             "0.1.1"
12338 +#define AAC_DRIVER_BUILD_DATE                  __DATE__
12339 +#define MAX_DRIVER_QUEUE_DEPTH                 500
12340 +
12341 +/*------------------------------------------------------------------------------
12342 + *              I N C L U D E S
12343 + *----------------------------------------------------------------------------*/
12344 +#include "osheaders.h"
12345 +
12346 +#include "AacGenericTypes.h"
12347 +
12348 +#include <linux/module.h>
12349 +#include "sd.h"
12350 +#include "linit.h"
12351 +#include "aac_unix_defs.h"
12352 +#include "fsatypes.h"
12353 +#include "comstruc.h"
12354 +#include "fsaport.h"
12355 +#include "pcisup.h"
12356 +#include "port.h"
12357 +#include "afacomm.h"
12358 +#include "nodetype.h"
12359 +#include "comsup.h"
12360 +#include "adapter.h"
12361 +
12362 +/*------------------------------------------------------------------------------
12363 + *              G L O B A L S
12364 + *----------------------------------------------------------------------------*/
12365 +extern FSA_MINIPORT MiniPorts[];
12366 +extern int CommPrinting;
12367 +extern char DescriptionString[];
12368 +extern char devicestr[];
12369 +
12370 +/*------------------------------------------------------------------------------
12371 + *              M O D U L E   G L O B A L S
12372 + *----------------------------------------------------------------------------*/
12373 +aac_options_t g_options = { CMN_ERR_LEVEL, 0 };        // default message_level
12374 +
12375 +char g_DriverName[] = { "aacraid" };
12376 +
12377 +/*
12378 +       The Loadable Kernel Module Installation Facility may pass us
12379 +       a pointer to a driver specific options string to be parsed, 
12380 +       we assign this to options string. 
12381 +*/
12382 +
12383 +static char * aacraid_options = NULL;
12384 +MODULE_PARM      ( aacraid_options, "s" );
12385 +MODULE_PARM_DESC ( aacraid_options, "message_level:(int)  reverse_scan:1 (default 0)");
12386 +
12387 +
12388 +static unsigned short perc_pciid[4] = { 0, 0, 0, 0 };
12389 +MODULE_PARM      ( perc_pciid, "4h");
12390 +MODULE_PARM_DESC ( perc_pciid, "PCI vendor,device,subsystem vendor,subsystem device, for non-auto-recognized Dell PERC controllers.");
12391 +
12392 +static unsigned short rx_pciid[4] = { 0, 0, 0, 0 };
12393 +MODULE_PARM      ( rx_pciid, "4h");
12394 +MODULE_PARM_DESC ( rx_pciid, "PCI vendor,device,subsystem vendor,subsystem device, for non-auto-recognized Adaptec Rx controllers.");
12395 +
12396 +static unsigned short sa_pciid[4] = { 0, 0, 0, 0 };
12397 +MODULE_PARM      ( sa_pciid, "4h");
12398 +MODULE_PARM_DESC ( sa_pciid, "PCI vendor,device,subsystem vendor,subsystem device, for non-auto-recognized Adaptec Sa controllers.");
12399 +
12400 +MODULE_AUTHOR ("Adaptec OEM RAID Solutions");
12401 +
12402 +
12403 +
12404 +PCI_MINIPORT_COMMON_EXTENSION *g_CommonExtensionPtrArray[ MAXIMUM_NUM_ADAPTERS ];
12405 +unsigned g_HostAdapterCount = 0;
12406 +unsigned g_chardev_major = 0;
12407 +
12408 +int g_single_command_done = FALSE;
12409 +
12410 +/*------------------------------------------------------------------------------
12411 + *              F U N C T I O N   P R O T O T Y P E S
12412 + *----------------------------------------------------------------------------*/
12413 +int AacHba_Ioctl(
12414 +       PCI_MINIPORT_COMMON_EXTENSION *CommonExtension,
12415 +       int cmd,
12416 +       void * arg );
12417 +
12418 +int AacHba_ProbeContainers( 
12419 +       PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr );
12420 +
12421 +int AacHba_DoScsiCmd(
12422 +       Scsi_Cmnd *scsi_cmnd_ptr,
12423 +       int wait );
12424 +
12425 +void AacHba_DetachAdapter(
12426 +       IN PVOID AdapterArg );
12427 +
12428 +int AacHba_ClassDriverInit(
12429 +       PCI_MINIPORT_COMMON_EXTENSION * CommonExtensionPtr);
12430 +
12431 +void AacHba_AbortScsiCommand(
12432 +       Scsi_Cmnd *scsi_cmnd_ptr );
12433 +
12434 +
12435 +/*------------------------------------------------------------------------------
12436 + *              L O C A L   F U N C T I O N   P R O T O T Y P E S
12437 + *----------------------------------------------------------------------------*/
12438 +static int parse_keyword(
12439 +       char ** str_ptr, 
12440 +       char * keyword );
12441 +
12442 +static void AAC_ParseDriverOptions( 
12443 +       char * cmnd_line_options_str );
12444 +
12445 +static void AAC_AnnounceDriver( void );
12446 +
12447 +int AAC_ChardevIoctl(
12448 +       struct inode * inode_ptr, 
12449 +       struct file * file_ptr,
12450 +       unsigned int cmd,
12451 +       unsigned long arg );
12452 +
12453 +int AAC_ChardevOpen(
12454 +       struct inode * inode_ptr,
12455 +       struct file * file_ptr );
12456 +
12457 +int AAC_ChardevRelease(
12458 +       struct inode * inode_ptr,
12459 +       struct file * file_ptr );
12460 +
12461 +struct file_operations AAC_fops = {
12462 +       NULL,               // module name
12463 +       NULL,                           // lseek
12464 +       NULL,                           // read
12465 +       NULL,                           // write
12466 +       NULL,                           // readdir
12467 +       NULL,                           // poll
12468 +       AAC_ChardevIoctl,       // ioctl
12469 +       NULL,                           // mmap
12470 +       AAC_ChardevOpen,        // open
12471 +       NULL,                           // flush
12472 +       AAC_ChardevRelease,     // release
12473 +       NULL,                           // fsync
12474 +       NULL,                           // fasync
12475 +       NULL,                           // check media change
12476 +       NULL,                           // revalidate
12477 +       NULL                            // lock
12478 +};
12479 +
12480 +/*------------------------------------------------------------------------------
12481 + *              F U N C T I O N S
12482 + *----------------------------------------------------------------------------*/
12483 +/*------------------------------------------------------------------------------
12484 +       AAC_AnnounceDriver()
12485 +
12486 +               Announce the driver name, version and date.
12487 + *----------------------------------------------------------------------------*/
12488 +static void AAC_AnnounceDriver( void ){
12489 +  printk(KERN_ALERT "%s, %s\n", 
12490 +                "aacraid raid driver version", AAC_DRIVER_BUILD_DATE );   
12491 +  schedule();
12492 +}
12493 +
12494 +
12495 +/*------------------------------------------------------------------------------
12496 +       AAC_DetectHostAdapter()
12497 +
12498 +               Probe for AAC Host Adapters initialize, register, and report the 
12499 +               configuration of each AAC Host Adapter found.
12500 +
12501 +       Preconditions:
12502 +       Postconditions:
12503 +               - Returns the number of adapters successfully initialized and 
12504 +               registered.
12505 +               - Initialize all data necessary for this particular SCSI driver.
12506 +       Notes:
12507 +               The detect routine must not call any of the mid level functions 
12508 +               to queue commands because things are not guaranteed to be set 
12509 +               up yet. The detect routine can send commands to the host adapter 
12510 +               as long as the program control will not be passed to scsi.c in 
12511 +               the processing of the command. Note especially that 
12512 +               scsi_malloc/scsi_free must not be called.
12513 + *----------------------------------------------------------------------------*/
12514 +int AAC_DetectHostAdapter (Scsi_Host_Template *HostTemplate)
12515 +{
12516 +               int index;
12517 +               int ContainerId;
12518 +               uint16_t vendor_id, device_id, sub_vendor_id, sub_system_id;
12519 +               struct Scsi_Host *host_ptr;
12520 +               PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
12521 +               struct pci_dev *dev = NULL;
12522 +               extern int NumMiniPorts;
12523 +               fsadev_t *fsa_dev_ptr;
12524 +               char *DeviceName;
12525 +
12526 +               struct pci_dev *devp;
12527 +
12528 +               int     first_index, last_index, increment;
12529 +
12530 +               CommPrinting = TRUE;
12531 +
12532 +               EXPORT_NO_SYMBOLS;
12533 +
12534 +               AAC_AnnounceDriver();
12535 +
12536 +               /* setting up the proc directory structure */
12537 +               HostTemplate->proc_name = "aacraid";
12538 +
12539 +               if( aacraid_options != NULL ) AAC_ParseDriverOptions( aacraid_options );
12540 +
12541 +               /* If we were passed a PCI device ID, handle that first. */
12542 +               if ( perc_pciid[0] != 0 ) {
12543 +                       MiniPorts[0].VendorId    = perc_pciid[0];
12544 +                       MiniPorts[0].DeviceId    = perc_pciid[1];
12545 +                       MiniPorts[0].SubVendorId = perc_pciid[2];
12546 +                       MiniPorts[0].SubSystemId = perc_pciid[3];
12547 +               }
12548 +               if ( rx_pciid[0] != 0 ) {
12549 +                       MiniPorts[1].VendorId    = rx_pciid[0];
12550 +                       MiniPorts[1].DeviceId    = rx_pciid[1];
12551 +                       MiniPorts[1].SubVendorId = rx_pciid[2];
12552 +                       MiniPorts[1].SubSystemId = rx_pciid[3];
12553 +               }
12554 +               if ( sa_pciid[0] != 0 ) {
12555 +                       MiniPorts[2].VendorId    = sa_pciid[0];
12556 +                       MiniPorts[2].DeviceId    = sa_pciid[1];
12557 +                       MiniPorts[2].SubVendorId = sa_pciid[2];
12558 +                       MiniPorts[2].SubSystemId = sa_pciid[3];
12559 +               }
12560 +
12561 +               // NumMiniPorts & MiniPorts[] defined in aacid.c
12562 +               if (g_options.reverse_scan == 0) {
12563 +                               first_index = 0;
12564 +                               last_index  = NumMiniPorts;
12565 +                               increment   = 1;
12566 +               } else {
12567 +                               first_index = NumMiniPorts -1;
12568 +                               last_index  = -1;
12569 +                               increment   = -1;
12570 +               }
12571 +
12572 +               for( index = first_index; index != last_index; index += increment )
12573 +               {
12574 +                               device_id = MiniPorts[index].DeviceId;
12575 +                               vendor_id = MiniPorts[index].VendorId;
12576 +                               DeviceName = MiniPorts[index].DeviceName;
12577 +                               cmn_err(CE_DEBUG, "Checking %s %x/%x/%x/%x", 
12578 +                                               DeviceName,     vendor_id, device_id,
12579 +                                               MiniPorts[index].SubVendorId,
12580 +                                               MiniPorts[index].SubSystemId);
12581 +
12582 +                               /* If vendor and device ID are 0, this is an unused entry, so skip! */
12583 +                               if ( vendor_id == 0 && device_id == 0 ) continue;
12584 +
12585 +                               // pci_find_device traverses the pci_devices linked list for devices
12586 +                               // with matching vendor and device ids.
12587 +
12588 +                               dev = NULL;     // start from beginning of list
12589 +                               while( ( dev = pci_find_device( vendor_id, device_id, dev ) ) )
12590 +                               {
12591 +                                               if (pci_enable_device(dev)) continue;
12592 +                 
12593 +                                               if( pci_read_config_word( dev, PCI_SUBSYSTEM_VENDOR_ID, &sub_vendor_id ) ){
12594 +                                                               cmn_err(CE_WARN, "pci_read_config_word SUBSYS_VENDOR_ID failed");
12595 +                                                               break;
12596 +                                               }
12597 +                                               if( pci_read_config_word( dev, PCI_SUBSYSTEM_ID, &sub_system_id ) ){
12598 +                                                               cmn_err(CE_WARN, "pci_read_config_work SUBSYSTEM_ID failed");
12599 +                                                               break;
12600 +                                               }
12601 +
12602 +                                               cmn_err(CE_DEBUG, "     found: %x/%x/%x/%x", vendor_id, device_id, sub_vendor_id, sub_system_id);
12603 +                                               if( ( sub_vendor_id != MiniPorts[index].SubVendorId ) || 
12604 +                                                       ( sub_system_id != MiniPorts[index].SubSystemId ) ){
12605 +                                                               continue;
12606 +                                               }
12607 +                       
12608 +
12609 +                                               printk(KERN_ALERT "%s device detected\n", DeviceName );
12610 +                                               cmn_err(CE_DEBUG, "%x/%x/%x/%x", vendor_id, device_id, sub_vendor_id, sub_system_id);
12611 +
12612 +                                               // Increment the host adapter count
12613 +                                               g_HostAdapterCount++;
12614 +
12615 +                                               // scsi_register() allocates memory for a Scsi_Hosts structure and
12616 +                                               // links it into the linked list of host adapters. This linked list
12617 +                                               // contains the data for all possible <supported> scsi hosts.
12618 +                                               // This is similar to the Scsi_Host_Template, except that we have
12619 +                                               // one entry for each actual physical host adapter on the system,
12620 +                                               // stored as a linked list. If there are two AAC boards, then we
12621 +                                               // will need to make two Scsi_Host entries, but there will be only
12622 +                                               // one Scsi_Host_Template entry. The second argument to scsi_register()
12623 +                                               // specifies the size of the extra memory we want to hold any device 
12624 +                                               // specific information.
12625 +                                               host_ptr = scsi_register( HostTemplate, sizeof( PCI_MINIPORT_COMMON_EXTENSION ) );
12626 +
12627 +                                               // These three parameters can be used to allow for wide SCSI 
12628 +                                               // and for host adapters that support multiple buses.
12629 +                                               host_ptr->max_id = 17;
12630 +                                               host_ptr->max_lun = 8;
12631 +                                               host_ptr->max_channel = 1;
12632 +
12633 +
12634 +                                               host_ptr->irq = dev->irq;               // Adapter IRQ number
12635 +                                               /* host_ptr->base = ( char * )(dev->resource[0].start & ~0xff); */
12636 +                                               host_ptr->base = ( char * )(dev->resource[0].start);
12637 +                                               scsi_set_pci_device(host_ptr, dev);
12638 +
12639 +                                               cmn_err( CE_DEBUG, "Device base address = 0x%lx [0x%lx]", host_ptr->base, dev->resource[0].start );
12640 +                                               cmn_err( CE_DEBUG, "Device irq = 0x%lx", dev->irq );
12641 +
12642 +                                               // The unique_id field is a unique identifier that must be assigned
12643 +                                               // so that we have some way of identifying each host adapter properly
12644 +                                               // and uniquely. For hosts that do not support more than one card in the
12645 +                                               // system, this does not need to be set. It is initialized to zero in
12646 +                                               // scsi_register(). This is the value returned from OsGetDeviceInstance().
12647 +
12648 +                                               host_ptr->unique_id = g_HostAdapterCount - 1;
12649 +                                               host_ptr->this_id = 16;                 // SCSI Id for the adapter itself
12650 +
12651 +                                               // Set the maximum number of simultaneous commands supported by the driver.
12652 +                                               host_ptr->can_queue = MAX_DRIVER_QUEUE_DEPTH;
12653 +
12654 +                                               // Define the maximum number of scatter/gather elements supported by 
12655 +                                               // the driver. 
12656 +
12657 +                                               host_ptr->sg_tablesize = 16;
12658 +                                               host_ptr->max_sectors = 128;
12659 +                                               host_ptr->cmd_per_lun = 1;              // untagged queue depth
12660 +
12661 +                                               // This function is called after the device list has been built to find
12662 +                                               // tagged queueing depth supported for each device.
12663 +
12664 +                                               host_ptr->select_queue_depths = AAC_SelectQueueDepths;
12665 +                                               CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )host_ptr->hostdata;
12666 +                       
12667 +                                               // attach a pointer back to Scsi_Host
12668 +                                               CommonExtensionPtr->OsDep.scsi_host_ptr = host_ptr;     
12669 +                                               CommonExtensionPtr->OsDep.MiniPortIndex =  index;
12670 +
12671 +                                               // Initialize the ordinal number of the device to -1
12672 +                                               fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
12673 +                                               for( ContainerId = 0; ContainerId < MAXIMUM_NUM_CONTAINERS; ContainerId++ )
12674 +                                                               fsa_dev_ptr->ContainerDevNo[ContainerId] = -1;
12675 +
12676 +                                               // Call initialization routine
12677 +                                               cmn_err (CE_DEBUG, "Initializing Hardware...\n");
12678 +                                               if( ( *MiniPorts[index].InitRoutine )
12679 +                                                       ( CommonExtensionPtr, host_ptr->unique_id, dev->bus->number, 0 ) != 0 )
12680 +                                               {
12681 +                                                               // device initialization failed
12682 +                                                               cmn_err( CE_WARN, "%s:%d device initialization failed", DeviceName, host_ptr->unique_id );
12683 +                                                               scsi_unregister( host_ptr );
12684 +                                                               g_HostAdapterCount--;
12685 +                                               } /* end if */
12686 +                                               else
12687 +                                               {
12688 +                                                       cmn_err( CE_NOTE, "%s:%d device initialization successful", DeviceName, host_ptr->unique_id  );
12689 +                                                       AacHba_ClassDriverInit( CommonExtensionPtr );
12690 +                                                       cmn_err(CE_NOTE, "%s:%d AacHba_ClassDriverInit complete", DeviceName, host_ptr->unique_id);
12691 +                                                       AacHba_ProbeContainers( CommonExtensionPtr );
12692 +                                                       g_CommonExtensionPtrArray[ g_HostAdapterCount - 1 ] = CommonExtensionPtr;
12693 +
12694 +                                               } /* end else */
12695 +
12696 +                               } /* end while */
12697 +
12698 +               } /* end for */
12699 +
12700 +               if( g_HostAdapterCount ){
12701 +                       if( !( g_chardev_major = register_chrdev( 0, devicestr, &AAC_fops ) ) )
12702 +                               cmn_err( CE_WARN, "%s: unable to register %s device", DeviceName, devicestr);
12703 +               }
12704 +
12705 +               HostTemplate->present = g_HostAdapterCount; // # of cards of this type found
12706 +
12707 +               return( g_HostAdapterCount ); 
12708 +}
12709 +
12710 +
12711 +/*------------------------------------------------------------------------------
12712 +       AAC_ReleaseHostAdapter()
12713 +
12714 +               Release all resources previously acquired to support a specific Host 
12715 +               Adapter and unregister the AAC Host Adapter.
12716 + *----------------------------------------------------------------------------*/
12717 +int AAC_ReleaseHostAdapter( 
12718 +       struct Scsi_Host *host_ptr )
12719 +/*----------------------------------------------------------------------------*/
12720 +{
12721 +       PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
12722 +
12723 +       cmn_err( CE_DEBUG, "AAC_ReleaseHostAdapter" );
12724 +
12725 +       CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )host_ptr->hostdata;
12726 +
12727 +       // kill any threads we started
12728 +       kill_proc( CommonExtensionPtr->OsDep.thread_pid, SIGKILL, 0 );
12729 +
12730 +       // Call the comm layer to detach from this adapter
12731 +       AacHba_DetachAdapter( CommonExtensionPtr->Adapter );
12732 +
12733 +       // remove interrupt binding
12734 +       OsDetachInterrupt( CommonExtensionPtr->MiniPort );
12735 +
12736 +       SaDetachDevice( CommonExtensionPtr );
12737 +
12738 +       // unregister adapter
12739 +       scsi_unregister( host_ptr );
12740 +
12741 +       if( g_chardev_major )
12742 +       {
12743 +               unregister_chrdev( g_chardev_major, devicestr );
12744 +               g_chardev_major = 0;
12745 +       }
12746 +
12747 +       return( 0 ); // #REVISIT# return code
12748 +}
12749 +
12750 +
12751 +/*------------------------------------------------------------------------------
12752 +       AAC_QueueCommand()
12753 +
12754 +               Queues a command for execution by the associated Host Adapter.
12755 + *----------------------------------------------------------------------------*/
12756 +int AAC_QueueCommand(
12757 +       Scsi_Cmnd *scsi_cmnd_ptr,
12758 +       void ( *CompletionRoutine )( Scsi_Cmnd * ) )
12759 +/*----------------------------------------------------------------------------*/
12760 +{
12761 +       int ret;
12762 +       scsi_cmnd_ptr->scsi_done = CompletionRoutine;
12763 +
12764 +       // AacHba_DoScsiCmd() handles command processing, setting the 
12765 +       // result code and calling completion routine. 
12766 +       #ifdef SYNC_FIB
12767 +       if( (ret = AacHba_DoScsiCmd( scsi_cmnd_ptr, 1 )) != 0 ) // call with wait = TRUE
12768 +       #else
12769 +       if( (ret = AacHba_DoScsiCmd( scsi_cmnd_ptr, 0 )) != 0 ) // call with wait = FALSE
12770 +       #endif
12771 +               cmn_err( CE_DEBUG, "AacHba_DoScsiCmd failed" );
12772 +       return ret;
12773 +} 
12774 +
12775 +
12776 +/*------------------------------------------------------------------------------
12777 +       AAC_Done()
12778 +
12779 +               Callback function for a non-queued command.
12780 +
12781 +       Postconditions
12782 +               Sets g_single_command done to TRUE
12783 + *----------------------------------------------------------------------------*/
12784 +void AAC_Done( 
12785 +       Scsi_Cmnd * scsi_cmnd_ptr ) 
12786 +/*----------------------------------------------------------------------------*/
12787 +{
12788 +       g_single_command_done = TRUE;
12789 +}
12790 +
12791 +
12792 +/*------------------------------------------------------------------------------
12793 +       AAC_Command()
12794 +       
12795 +               Accepts a single command for execution by the associated Host Adapter.
12796 +
12797 +       Postconditions
12798 +               Returns an int where:
12799 +               Byte 0 = SCSI status code
12800 +               Byte 1 = SCSI 1 byte message
12801 +               Byte 2 = host error return
12802 +               Byte 3 = mid level error return
12803 + *----------------------------------------------------------------------------*/
12804 +int AAC_Command(
12805 +       Scsi_Cmnd *scsi_cmnd_ptr )
12806 +/*----------------------------------------------------------------------------*/
12807 +{
12808 +       scsi_cmnd_ptr->scsi_done = AAC_Done;
12809 +
12810 +       cmn_err( CE_DEBUG, "AAC_Command" );
12811 +
12812 +       // AacHba_DoScsiCmd() handles command processing, setting the 
12813 +       // result code and calling completion routine.
12814 +       g_single_command_done = FALSE;
12815 +       
12816 +       AacHba_DoScsiCmd( scsi_cmnd_ptr, 0 );
12817 +       while( !g_single_command_done );
12818 +       return( scsi_cmnd_ptr->result );
12819 +} 
12820 +
12821 +
12822 +/*------------------------------------------------------------------------------
12823 +       AAC_AbortCommand()
12824 +
12825 +               Abort command if possible.
12826 + *----------------------------------------------------------------------------*/
12827 +int AAC_AbortCommand( 
12828 +       Scsi_Cmnd *scsi_cmnd_ptr )
12829 +/*----------------------------------------------------------------------------*/
12830 +{
12831 +       int target = scsi_cmnd_ptr->target;
12832 +       int hba = scsi_cmnd_ptr->host->unique_id;
12833 +       int result = 0;
12834 +       u_short interrupt_status;
12835 +       PCI_MINIPORT_COMMON_EXTENSION *cep;
12836 +       char   *DeviceName;
12837 +
12838 +       cmn_err( CE_WARN, "%s:%d ABORT", g_DriverName, hba, target );
12839 +       AacHba_AbortScsiCommand( scsi_cmnd_ptr );
12840 +
12841 +       cep = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
12842 +       DeviceName = MiniPorts[cep->OsDep.MiniPortIndex].DeviceName; 
12843 +
12844 +               /*
12845 +               cmn_err( CE_WARN, "%s:%d Unable to abort command to target %d - "
12846 +                 "command already completed", DeviceName, hba, target);
12847 +               result = SCSI_ABORT_NOT_RUNNING;
12848 +
12849 +               cmn_err(CE_WARN, "%s:%d Unable to abort command to target %d - "
12850 +                  "no command found\n", DeviceName, hba, target);
12851 +               result = SCSI_ABORT_NOT_RUNNING;
12852 +
12853 +               cmn_err(CE_WARN, "%s:%d Unable to abort command to target %d - "
12854 +                  "command reset\n", DeviceName, hba, target);
12855 +               result = SCSI_ABORT_PENDING;
12856 +
12857 +               cmn_err(CE_WARN, "%s:%d Unable to abort command to target %d - "
12858 +                  "abort tag not supported\n", DeviceName, hba, target);
12859 +               result = SCSI_ABORT_SNOOZE;
12860 +
12861 +               cmn_err(CE_WARN, "%s:%d Aborting command to target %d - pending",
12862 +                  DeviceName, hba, target);
12863 +               result = SCSI_ABORT_PENDING;
12864 +
12865 +               cmn_err(CE_WARN, "%s:%d Unable to abort command to target %d",
12866 +                  DeviceName, hba, target);
12867 +               result = SCSI_ABORT_BUSY;
12868 +
12869 +               cmn_err(CE_WARN, "%s:%d Aborted command to target %d\n",
12870 +                  DeviceName, hba, target);
12871 +               result = SCSI_ABORT_SUCCESS;
12872 +               */
12873 +
12874 +       // Abort not supported yet
12875 +       result = SCSI_ABORT_BUSY;
12876 +       return result;
12877 +}
12878 +
12879 +
12880 +/*------------------------------------------------------------------------------
12881 +       AAC_ResetCommand()
12882 +
12883 +               Reset command handling.
12884 + *----------------------------------------------------------------------------*/
12885 +int AAC_ResetCommand( 
12886 +       struct scsi_cmnd *scsi_cmnd_ptr, 
12887 +       unsigned int reset_flags )
12888 +/*----------------------------------------------------------------------------*/
12889 +{
12890 +       int target = scsi_cmnd_ptr->target;
12891 +       int hba = scsi_cmnd_ptr->host->unique_id;
12892 +       PCI_MINIPORT_COMMON_EXTENSION *cep;
12893 +       char    *DeviceName;
12894 +
12895 +       cep = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
12896 +       DeviceName = MiniPorts[cep->OsDep.MiniPortIndex].DeviceName;
12897 +
12898 +       cmn_err( CE_WARN, "%s:%d RESET", DeviceName, hba, target );
12899 +
12900 +       return SCSI_RESET_PUNT;
12901 +}
12902 +
12903 +
12904 +/*------------------------------------------------------------------------------
12905 +       AAC_DriverInfo()
12906 +
12907 +               Returns the host adapter name
12908 + *----------------------------------------------------------------------------*/
12909 +const char *AAC_DriverInfo( 
12910 +       struct Scsi_Host *host_ptr )
12911 +/*----------------------------------------------------------------------------*/
12912 +{
12913 +  PCI_MINIPORT_COMMON_EXTENSION *cep;
12914 +  char *DeviceName;
12915 +
12916 +  cep = ( PCI_MINIPORT_COMMON_EXTENSION * )( host_ptr->hostdata );
12917 +  DeviceName = MiniPorts[cep->OsDep.MiniPortIndex].DeviceName;
12918 +
12919 +  cmn_err( CE_DEBUG, "AAC_DriverInfo" );
12920 +  return (DeviceName);
12921 +}
12922 +
12923 +
12924 +/*------------------------------------------------------------------------------
12925 +       AAC_BIOSDiskParameters()
12926 +
12927 +               Return the Heads/Sectors/Cylinders BIOS Disk Parameters for Disk.  
12928 +               The default disk geometry is 64 heads, 32 sectors, and the appropriate 
12929 +               number of cylinders so as not to exceed drive capacity.  In order for 
12930 +               disks equal to or larger than 1 GB to be addressable by the BIOS
12931 +               without exceeding the BIOS limitation of 1024 cylinders, Extended 
12932 +               Translation should be enabled.   With Extended Translation enabled, 
12933 +               drives between 1 GB inclusive and 2 GB exclusive are given a disk 
12934 +               geometry of 128 heads and 32 sectors, and drives above 2 GB inclusive 
12935 +               are given a disk geometry of 255 heads and 63 sectors.  However, if 
12936 +               the BIOS detects that the Extended Translation setting does not match 
12937 +               the geometry in the partition table, then the translation inferred 
12938 +               from the partition table will be used by the BIOS, and a warning may 
12939 +               be displayed.
12940 + *----------------------------------------------------------------------------*/
12941 +int AAC_BIOSDiskParameters(
12942 +       Scsi_Disk *scsi_disk_ptr, 
12943 +       kdev_t device,
12944 +       int *parameter_ptr )
12945 +/*----------------------------------------------------------------------------*/
12946 +{
12947 +       AAC_BIOS_DiskParameters_T *disk_parameters = 
12948 +               ( AAC_BIOS_DiskParameters_T *)parameter_ptr;
12949 +       struct buffer_head * buffer_head_ptr;
12950 +
12951 +       cmn_err( CE_DEBUG, "AAC_BIOSDiskParameters" );
12952 +
12953 +       // Assuming extended translation is enabled - #REVISIT#
12954 +       if( scsi_disk_ptr->capacity >= 2 * 1024 * 1024 ) // 1 GB in 512 byte sectors
12955 +       {
12956 +               if( scsi_disk_ptr->capacity >= 4 * 1024 * 1024 ) // 2 GB in 512 byte sectors
12957 +               {
12958 +                       disk_parameters->heads = 255;
12959 +                       disk_parameters->sectors = 63;
12960 +               }
12961 +               else
12962 +               {
12963 +                       disk_parameters->heads = 128;
12964 +                       disk_parameters->sectors = 32;
12965 +               }
12966 +       }
12967 +       else
12968 +       {
12969 +               disk_parameters->heads = 64;
12970 +               disk_parameters->sectors = 32;
12971 +       }
12972 +
12973 +       disk_parameters->cylinders = scsi_disk_ptr->capacity
12974 +               /( disk_parameters->heads * disk_parameters->sectors );
12975 +
12976 +       // Read the first 1024 bytes from the disk device
12977 +       buffer_head_ptr = bread( 
12978 +                                               MKDEV( MAJOR( device ), 
12979 +                                               MINOR( device ) & ~0x0F ), 
12980 +                                               0, 1024 );
12981 +
12982 +       if( buffer_head_ptr == NULL )
12983 +               return( 0 );
12984 +       /* 
12985 +               If the boot sector partition table is valid, search for a partition 
12986 +               table entry whose end_head matches one of the standard geometry 
12987 +               translations ( 64/32, 128/32, 255/63 ).
12988 +       */
12989 +       if( *( unsigned short * )( buffer_head_ptr->b_data + 0x1fe ) == 0xaa55 )
12990 +       {
12991 +               struct partition *first_partition_entry =
12992 +                       ( struct partition * )( buffer_head_ptr->b_data + 0x1be );
12993 +               struct partition *partition_entry = first_partition_entry;
12994 +               int saved_cylinders = disk_parameters->cylinders;
12995 +               int partition_number;
12996 +               unsigned char partition_entry_end_head, partition_entry_end_sector;
12997 +
12998 +               for( partition_number = 0; partition_number < 4; partition_number++ )
12999 +               {
13000 +                       partition_entry_end_head   = partition_entry->end_head;
13001 +                       partition_entry_end_sector = partition_entry->end_sector & 0x3f;
13002 +
13003 +                       if( partition_entry_end_head == ( 64 - 1 ) )
13004 +                       {
13005 +                               disk_parameters->heads = 64;
13006 +                               disk_parameters->sectors = 32;
13007 +                               break;
13008 +                       }
13009 +                       else if( partition_entry_end_head == ( 128 - 1 ) )
13010 +                       {
13011 +                               disk_parameters->heads = 128;
13012 +                               disk_parameters->sectors = 32;
13013 +                               break;
13014 +                       }
13015 +                       else if( partition_entry_end_head == ( 255 - 1 ) ) 
13016 +                       {
13017 +                               disk_parameters->heads = 255;
13018 +                               disk_parameters->sectors = 63;
13019 +                               break;
13020 +                       }
13021 +                       partition_entry++;
13022 +               }
13023 +
13024 +               if( partition_number == 4 )
13025 +               {
13026 +                       partition_entry_end_head   = first_partition_entry->end_head;
13027 +                       partition_entry_end_sector = first_partition_entry->end_sector & 0x3f;
13028 +               }
13029 +
13030 +               disk_parameters->cylinders = scsi_disk_ptr->capacity
13031 +                       /( disk_parameters->heads * disk_parameters->sectors );
13032 +
13033 +               if( ( partition_number < 4 )  && ( partition_entry_end_sector == disk_parameters->sectors ) )
13034 +               {
13035 +                       if( disk_parameters->cylinders != saved_cylinders )
13036 +                               cmn_err( CE_DEBUG, "Adopting geometry: heads=%d, sectors=%d from partition table %d",
13037 +                                       disk_parameters->heads, disk_parameters->sectors, partition_number );
13038 +               }
13039 +               else if( ( partition_entry_end_head > 0 ) || ( partition_entry_end_sector > 0 ) )
13040 +               {
13041 +                       cmn_err( CE_DEBUG, "Strange geometry: heads=%d, sectors=%d in partition table %d",
13042 +                               partition_entry_end_head + 1, partition_entry_end_sector, partition_number );
13043 +                       cmn_err( CE_DEBUG, "Using geometry: heads=%d, sectors=%d",
13044 +                                       disk_parameters->heads, disk_parameters->sectors );
13045 +               }
13046 +       }
13047 +       
13048 +       brelse( buffer_head_ptr );
13049 +
13050 +       return( 0 );
13051 +}
13052 +
13053 +
13054 +/*------------------------------------------------------------------------------
13055 +       AAC_SelectQueueDepths()
13056 +
13057 +               Selects queue depths for each target device based on the host adapter's
13058 +               total capacity and the queue depth supported by the target device.
13059 +               A queue depth of one automatically disables tagged queueing.
13060 + *----------------------------------------------------------------------------*/
13061 +void AAC_SelectQueueDepths(
13062 +       struct Scsi_Host * host_ptr,
13063 +       Scsi_Device * scsi_device_ptr )
13064 +/*----------------------------------------------------------------------------*/
13065 +{
13066 +       Scsi_Device * device_ptr;
13067 +
13068 +       cmn_err( CE_DEBUG, "AAC_SelectQueueDepths" );
13069 +       cmn_err( CE_DEBUG, "Device #   Q Depth   Online" );
13070 +       cmn_err( CE_DEBUG, "---------------------------" );
13071 +       for( device_ptr = scsi_device_ptr; device_ptr != NULL; device_ptr = device_ptr->next )
13072 +               if( device_ptr->host == host_ptr )
13073 +               {
13074 +                       device_ptr->queue_depth = 10;           
13075 +                       cmn_err( CE_DEBUG, "  %2d         %d        %d", 
13076 +                               device_ptr->id, device_ptr->queue_depth, device_ptr->online );
13077 +               }
13078 +}
13079 +
13080 +
13081 +/*------------------------------------------------------------------------------
13082 +       AAC_SearchBiosSignature()
13083 +
13084 +               Locate adapter signature in BIOS
13085 + *----------------------------------------------------------------------------*/
13086 +int AAC_SearchBiosSignature( void )
13087 +/*----------------------------------------------------------------------------*/
13088 +{
13089 +       unsigned base;
13090 +       unsigned namep;
13091 +       int index;
13092 +       int val;
13093 +       char name_buf[32];
13094 +       int result = FALSE;
13095 +
13096 +       for( base = 0xc8000; base < 0xdffff; base += 0x4000 )
13097 +       {
13098 +               val = readb( base );
13099 +               if( val != 0x55 ) 
13100 +                       continue;
13101 +
13102 +               result = TRUE;
13103 +               namep = base + 0x1e;
13104 +               memcpy_fromio( name_buf, namep, 32 );
13105 +               name_buf[31] = '\0';
13106 +       }
13107 +       return( result );
13108 +}
13109 +
13110 +
13111 +/*------------------------------------------------------------------------------
13112 +       AAC_Ioctl()
13113 +
13114 +               Handle SCSI ioctls
13115 + *----------------------------------------------------------------------------*/
13116 +int AAC_Ioctl(
13117 +       Scsi_Device * scsi_dev_ptr,
13118 +       int cmd,
13119 +       void * arg )
13120 +/*----------------------------------------------------------------------------*/
13121 +{
13122 +       PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
13123 +
13124 +       cmn_err( CE_DEBUG, "AAC_Ioctl" );
13125 +       CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )scsi_dev_ptr->host->hostdata;
13126 +       return( AacHba_Ioctl( CommonExtensionPtr, cmd, arg ) );
13127 +}
13128 +
13129 +
13130 +
13131 +/*------------------------------------------------------------------------------
13132 +       AAC_ChardevOpen()
13133 +       
13134 +               Handle character device open
13135 +       
13136 +       Preconditions:
13137 +       Postconditions:
13138 +               Returns 0 if successful, -ENODEV or -EINVAL otherwise
13139 + *----------------------------------------------------------------------------*/
13140 +int AAC_ChardevOpen(
13141 +       struct inode * inode_ptr,
13142 +       struct file * file_ptr )
13143 +/*----------------------------------------------------------------------------*/
13144 +{
13145 +       unsigned minor_number;
13146 +
13147 +       cmn_err( CE_DEBUG, "AAC_ChardevOpen" );
13148 +
13149 +       // check device permissions in file_ptr->f_mode ??
13150 +
13151 +       // extract & check the minor number
13152 +       minor_number = MINOR( inode_ptr->i_rdev );
13153 +       if( minor_number > ( g_HostAdapterCount - 1 ) )
13154 +       {
13155 +               cmn_err( CE_WARN, "AAC_ChardevOpen: Minor number %d not supported", minor_number );
13156 +               return( -ENODEV );
13157 +       }
13158 +
13159 +       MOD_INC_USE_COUNT;
13160 +
13161 +       return( 0 );
13162 +}
13163 +
13164 +
13165 +/*------------------------------------------------------------------------------
13166 +       AAC_ChardevRelease()
13167 +       
13168 +               Handle character device release.
13169 +       
13170 +       Preconditions:
13171 +       Postconditions:
13172 +               Returns 0 if successful, -ENODEV or -EINVAL otherwise
13173 + *----------------------------------------------------------------------------*/
13174 +int AAC_ChardevRelease(
13175 +       struct inode * inode_ptr,
13176 +       struct file * file_ptr )
13177 +/*----------------------------------------------------------------------------*/
13178 +{
13179 +       cmn_err( CE_DEBUG, "AAC_ChardevRelease" );
13180 +
13181 +       MOD_DEC_USE_COUNT;
13182 +
13183 +       return( 0 );
13184 +}
13185 +
13186 +
13187 +/*------------------------------------------------------------------------------
13188 +       AAC_ChardevIoctl()
13189 +       
13190 +               Handle character device interface ioctls
13191 +       
13192 +       Preconditions:
13193 +       Postconditions:
13194 +               Returns 0 if successful, -ENODEV or -EINVAL otherwise
13195 + *----------------------------------------------------------------------------*/
13196 +int AAC_ChardevIoctl(
13197 +       struct inode * inode_ptr, 
13198 +       struct file * file_ptr,
13199 +       unsigned int cmd,
13200 +       unsigned long arg )
13201 +{
13202 +       unsigned minor_number;
13203 +       PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
13204 +
13205 +       cmn_err( CE_DEBUG, "AAC_ChardevIoctl" );
13206 +
13207 +       // check device permissions in file_ptr->f_mode ??
13208 +
13209 +       // extract & check the minor number
13210 +       minor_number = MINOR( inode_ptr->i_rdev );
13211 +       if( minor_number > ( g_HostAdapterCount - 1 ) )
13212 +       {
13213 +               cmn_err( CE_WARN, "AAC_ChardevIoctl: Minor number %d not supported", minor_number );
13214 +               return( -ENODEV );
13215 +       }
13216 +
13217 +       // get device pointer
13218 +       CommonExtensionPtr = g_CommonExtensionPtrArray[ minor_number ];
13219 +
13220 +       // dispatch ioctl - AacHba_Ioctl() returns zero on success
13221 +       if( AacHba_Ioctl( CommonExtensionPtr, cmd, ( void * )arg ) )
13222 +               return( -EINVAL );
13223 +
13224 +       return( 0 );
13225 +}
13226 +
13227 +
13228 +/*------------------------------------------------------------------------------
13229 +       parse_keyword()
13230 +
13231 +               Look for the keyword in str_ptr
13232 +
13233 +       Preconditions:
13234 +       Postconditions:
13235 +               If keyword found
13236 +                       - return true and update the pointer str_ptr.
13237 +               otherwise
13238 +                       - return false
13239 + *----------------------------------------------------------------------------*/
13240 +static int parse_keyword(
13241 +       char ** str_ptr, 
13242 +       char * keyword )
13243 +/*----------------------------------------------------------------------------*/
13244 +{
13245 +       char * ptr = *str_ptr;
13246 +       
13247 +       while( *keyword != '\0' )
13248 +       {
13249 +               char string_char = *ptr++;
13250 +               char keyword_char = *keyword++;
13251 +
13252 +               if ( ( string_char >= 'A' ) && ( string_char <= 'Z' ) )
13253 +                       string_char += 'a' - 'Z';
13254 +               if( ( keyword_char >= 'A' ) && ( keyword_char <= 'Z' ) ) 
13255 +                       keyword_char += 'a' - 'Z';
13256 +               if( string_char != keyword_char )
13257 +                       return FALSE;
13258 +       }
13259 +       *str_ptr = ptr;
13260 +       return TRUE;
13261 +}
13262 +
13263 +
13264 +/*------------------------------------------------------------------------------
13265 +       AAC_ParseDriverOptions()
13266 +
13267 +       For modules the usage is:
13268 +               insmod -f aacraid.o 'aacraid_options="<option_name:argument>"'
13269 + *----------------------------------------------------------------------------*/
13270 +static void AAC_ParseDriverOptions( 
13271 +       char * cmnd_line_options_str )
13272 +/*----------------------------------------------------------------------------*/
13273 +{
13274 +       int message_level;
13275 +       int reverse_scan;
13276 +       char *cp;
13277 +       char *endp;
13278 +
13279 +       cp = cmnd_line_options_str;
13280 +
13281 +       cmn_err(CE_DEBUG, "AAC_ParseDriverOptions: <%s>", cp);
13282 +
13283 +       while( *cp ) {
13284 +               if( parse_keyword( &cp, "message_level:" ) ) {
13285 +                       message_level = simple_strtoul( cp, 0, 0 );
13286 +                       if( ( message_level < CE_TAIL ) && ( message_level >= 0 ) ) {
13287 +                               g_options.message_level = message_level;
13288 +                               cmn_err( CE_WARN, "%s: new message level = %d", g_DriverName, g_options.message_level );
13289 +                       }
13290 +                       else {
13291 +                               cmn_err( CE_WARN, "%s: invalid message level = %d", g_DriverName, message_level );
13292 +                       }
13293 +               } else if (parse_keyword( &cp, "reverse_scan:" ) ) {
13294 +                       reverse_scan = simple_strtoul( cp, 0, 0 );
13295 +                       if (reverse_scan) {
13296 +                               g_options.reverse_scan = 1;
13297 +                               cmn_err( CE_WARN, "%s: reversing device discovery order", g_DriverName, g_options.message_level );
13298 +                       }
13299 +               }
13300 +               else {
13301 +                       cmn_err( CE_WARN, "%s: unknown command line option <%s>", g_DriverName, cp );
13302 +               }
13303 +
13304 +               /*
13305 +                * skip to next option,  accept " ", ";", and "," as delimiters
13306 +                */
13307 +               while ( *cp && (*cp != ' ')  && (*cp != ';')  && (*cp != ','))
13308 +                       cp++;
13309 +
13310 +               if (*cp)                                 /* skip over the delimiter */
13311 +                       cp++;
13312 +       }
13313 +
13314 +}
13315 +
13316 +
13317 +/*------------------------------------------------------------------------------
13318 +       To use the low level SCSI driver support using the linux kernel loadable 
13319 +       module interface we should initialize the global variable driver_interface  
13320 +       (datatype Scsi_Host_Template) and then include the file scsi_module.c.
13321 + *----------------------------------------------------------------------------*/
13322 +
13323 +Scsi_Host_Template driver_template = AAC_HOST_TEMPLATE_ENTRY;
13324 +
13325 +#include "scsi_module.c"
13326 +
13327 +
13328 +/*********************************************************************
13329 +       AAC_ProcDirectoryInfo()
13330 +
13331 +               Implement /proc/scsi/<drivername>/<n>.
13332 +               Used to export driver statistics and other infos to the world outside 
13333 +               the kernel using the proc file system. Also provides an interface to
13334 +               feed the driver with information.
13335 +
13336 +       Postconditions
13337 +               For reads
13338 +                       - if offset > 0 return 0
13339 +                       - if offset == 0 write data to proc_buffer and set the start_ptr to
13340 +                       beginning of proc_buffer, return the number of characters written.
13341 +               For writes
13342 +                       - writes currently not supported, return 0
13343 +************************************************************/
13344 +int AAC_ProcDirectoryInfo(
13345 +       char *proc_buffer,              // read/write buffer
13346 +       char **start_ptr,               // start of valid data in the buffer
13347 +       off_t offset,                   // offset from the beginning of the imaginary file 
13348 +       int bytes_available,    // bytes available
13349 +       int host_no,                    // SCSI host number 
13350 +       int write )                             // direction of dataflow: TRUE for writes, FALSE for reads      
13351 +{
13352 +       int length = 0;
13353 +       cmn_err( CE_WARN, "AAC_ProcDirectoryInfo" );
13354 +
13355 +       if( ( write ) || ( offset > 0 ) )
13356 +               return( 0 );
13357 +
13358 +       *start_ptr = proc_buffer;
13359 +
13360 +       return( sprintf(&proc_buffer[length], "%s  %d\n", "Raid Controller, scsi hba number", host_no ) );
13361 +}
13362 +
13363 +void aac_allocate_SyncFibs (PCI_MINIPORT_COMMON_EXTENSION *CommonExtension)
13364 +{
13365 +  void         *BaseAddress;
13366 +  ULONG                PhysAddress;
13367 +  int          size;
13368 +  int          npages;
13369 +  int          i;
13370 +
13371 +  AFA_COMM_ADAPTER             *Adapter;
13372 +  Adapter = CommonExtension->Adapter;
13373 +
13374 +
13375 +  // Allocate 1 fib for synch fibs
13376 +  // Allocate 1 page.
13377 +  BaseAddress = OsAllocMemory ( PAGE_SIZE, OS_ALLOC_MEM_SLEEP);
13378 +  bzero(BaseAddress, PAGE_SIZE);
13379 +  PhysAddress = virt_to_phys (BaseAddress);
13380 +  Adapter->SyncFib = BaseAddress;
13381 +  Adapter->SyncFibPhysicalAddress = PhysAddress;
13382 +  cmn_err(CE_DEBUG,"aac_allocate_SyncFibs: syncFib: vaddr: 0x%x paddr: 0x%x ", BaseAddress, PhysAddress);
13383 +
13384 +}
13385 diff -burN linux-2.4.9/drivers/scsi/aacraid/osddi.c linux/drivers/scsi/aacraid/osddi.c
13386 --- linux-2.4.9/drivers/scsi/aacraid/osddi.c    Wed Dec 31 18:00:00 1969
13387 +++ linux/drivers/scsi/aacraid/osddi.c  Thu Aug 16 13:41:30 2001
13388 @@ -0,0 +1,508 @@
13389 +/*++
13390 + * Adaptec aacraid device driver for Linux.
13391 + *
13392 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
13393 + *
13394 + * This program is free software; you can redistribute it and/or modify
13395 + * it under the terms of the GNU General Public License as published by
13396 + * the Free Software Foundation; either version 2, or (at your option)
13397 + * any later version.
13398 + *
13399 + * This program is distributed in the hope that it will be useful,
13400 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
13401 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13402 + * GNU General Public License for more details.
13403 + *
13404 + * You should have received a copy of the GNU General Public License
13405 + * along with this program; see the file COPYING.  If not, write to
13406 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
13407 + *
13408 + * Module Name:
13409 + *   osddi.c
13410 + *
13411 + * Abstract: This file contains all the proceedures which use LINUX specific Device 
13412 + *             Driver Interfaces.
13413 + *     
13414 + --*/
13415 +
13416 +static char *ident_osddi = "aacraid_ident osddi.c 1.0.6 2000/10/09 Adaptec, Inc.";
13417 +
13418 +#include "osheaders.h"
13419 +
13420 +#include <linux/smp_lock.h>
13421 +
13422 +#ifdef fsid_t
13423 +#undef fsid_t
13424 +#endif
13425 +#include "AacGenericTypes.h"
13426 +#include "aac_unix_defs.h"
13427 +#include "comstruc.h"
13428 +#include "monkerapi.h"
13429 +#include "protocol.h"
13430 +#include "fsafs.h"
13431 +
13432 +#include "sap1common.h"
13433 +#include "fsaport.h"
13434 +#include "pcisup.h"
13435 +#include "sap1.h"
13436 +#include "nodetype.h"
13437 +#include "comsup.h"
13438 +#include "afacomm.h"
13439 +#include "adapter.h"
13440 +
13441 +
13442 +void AacSaPciIsr( 
13443 +       int irq,
13444 +       void * irq_data,
13445 +       struct pt_regs *regs);
13446 +
13447 +void AacRxPciIsr( 
13448 +       int irq,
13449 +       void * irq_data,
13450 +       struct pt_regs *regs);
13451 +
13452 +unsigned SaPciIsr (
13453 +    IN PSa_ADAPTER_EXTENSION AdapterExtension );
13454 +
13455 +unsigned RxPciIsr (
13456 +    IN PSa_ADAPTER_EXTENSION AdapterExtension );
13457 +
13458 +
13459 +/*----------------------------------------------------------------------------*/
13460 +VOID AfaCommInterruptHost(
13461 +       PVOID                   AdapterArg,
13462 +       ADAPTER_EVENT   AdapterEvent )
13463 +/*----------------------------------------------------------------------------*/
13464 +{
13465 +       PAFA_COMM_ADAPTER       Adapter = ( PAFA_COMM_ADAPTER ) AdapterArg;
13466 +       PCOMM_REGION CommRegion = Adapter->CommRegion;
13467 +
13468 +       switch (AdapterEvent) {
13469 +
13470 +         case HostNormRespQue:
13471 +               OsSoftInterruptTrigger( CommRegion->HostNormRespQue.ConsumerRoutine );
13472 +       
13473 +       // #REVIEW# - what do we do with this
13474 +       // if (FsaCommData.HardInterruptModeration)
13475 +       //                      DisableInterrupt( Adapter, HostNormRespQue, TRUE );
13476 +
13477 +                       break;
13478 +
13479 +      case AdapNormCmdNotFull:
13480 +               OsSoftInterruptTrigger( CommRegion->QueueNotFullDpc );
13481 +                       break;
13482 +
13483 +         case HostNormCmdQue:
13484 +               OsSoftInterruptTrigger( CommRegion->HostNormCmdQue.ConsumerRoutine );
13485 +                       break;
13486 +
13487 +      case AdapNormRespNotFull:
13488 +               OsSoftInterruptTrigger( CommRegion->QueueNotFullDpc );
13489 +                       break;
13490 +
13491 +       // #REVIEW# - what do we do with these
13492 +         case HostHighCmdQue:
13493 +         case HostHighRespQue:
13494 +         case AdapHighCmdNotFull:
13495 +         case AdapHighRespNotFull:
13496 +         case SynchCommandComplete:
13497 +         case AdapInternalError:
13498 +                 break;
13499 +       }
13500 +}
13501 +
13502 +
13503 +// get the device name associated with this instance of the device
13504 +/*----------------------------------------------------------------------------*/
13505 +char *OsGetDeviceName( 
13506 +       void *AdapterExtension )
13507 +/*----------------------------------------------------------------------------*/
13508 +{
13509 +       return( ( ( Sa_ADAPTER_EXTENSION * )AdapterExtension )->Common->
13510 +               OsDep.scsi_host_ptr->hostt->name );
13511 +}
13512 +
13513 +
13514 +/*----------------------------------------------------------------------------*/
13515 +int OsGetDeviceInstance( 
13516 +       void *AdapterExtension )
13517 +/*----------------------------------------------------------------------------*/
13518 +{
13519 +       return( ( int )( ( Sa_ADAPTER_EXTENSION * )AdapterExtension )->Common->
13520 +               OsDep.scsi_host_ptr->unique_id );
13521 +}
13522 +
13523 +
13524 +/*------------------------------------------------------------------------------
13525 +       OsMapDeviceRegisters()
13526 +
13527 +       Postconditions:
13528 +               Return zero on success non-zero otherwise.
13529 + *----------------------------------------------------------------------------*/
13530 +int OsMapDeviceRegisters( 
13531 +       Sa_ADAPTER_EXTENSION *AdapterExtension )
13532 +/*----------------------------------------------------------------------------*/
13533 +{
13534 +       PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
13535 +
13536 +       CommonExtension = AdapterExtension->Common;
13537 +
13538 +       if( AdapterExtension->Device = ( Sa_DEVICE_REGISTERS * )
13539 +                       ioremap( ( unsigned long )CommonExtension->OsDep.scsi_host_ptr->base, 8192 ) )
13540 +       {
13541 +               cmn_err( CE_WARN, "Device mapped to virtual address 0x%x", AdapterExtension->Device ); 
13542 +               return( 0 );
13543 +       }
13544 +       else
13545 +       {       
13546 +               cmn_err( CE_WARN, "OsMapDeviceRegisters: ioremap() failed" );
13547 +               return( 1 );
13548 +       }
13549 +}
13550 +
13551 +
13552 +/*------------------------------------------------------------------------------
13553 +       OsUnMapDeviceRegisters()
13554 +
13555 +       Postconditions:
13556 + *----------------------------------------------------------------------------*/
13557 +void OsUnMapDeviceRegisters( 
13558 +       Sa_ADAPTER_EXTENSION *AdapterExtension )
13559 +/*----------------------------------------------------------------------------*/
13560 +{
13561 +       iounmap( ( void * )AdapterExtension->Device );
13562 +}
13563 +
13564 +
13565 +/*----------------------------------------------------------------------------*/
13566 +int OsAttachInterrupt( 
13567 +       Sa_ADAPTER_EXTENSION *AdapterExtension ,
13568 +       int     WhichIsr )
13569 +/*----------------------------------------------------------------------------*/
13570 +{
13571 +       PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
13572 +       void *irq_data;
13573 +       void (*Isr)();
13574 +
13575 +       CommonExtension = AdapterExtension->Common;
13576 +       irq_data = ( void * )AdapterExtension;
13577 +
13578 +       switch (WhichIsr) {
13579 +               case SaISR:
13580 +                       Isr = AacSaPciIsr;
13581 +                       break;
13582 +               case RxISR:
13583 +                       Isr = AacRxPciIsr;
13584 +                       break;
13585 +               default:
13586 +                       cmn_err(CE_WARN, "OsAttachInterrupt: invalid ISR case: 0x%x", WhichIsr);
13587 +                       return( FAILURE );
13588 +                       break;
13589 +       }
13590 +
13591 +       
13592 +       if      ( OsRegisterInterrupt (
13593 +                               CommonExtension->OsDep.scsi_host_ptr->irq,      // interrupt number
13594 +                               Isr,                                                                            // handler function
13595 +                               irq_data )
13596 +               ) 
13597 +       {
13598 +               cmn_err( CE_WARN, "OsAttachInterrupt: Failed for IRQ: 0x%x", 
13599 +                       CommonExtension->OsDep.scsi_host_ptr->irq );
13600 +               return( FAILURE );
13601 +       }
13602 +
13603 +       return ( 0 );
13604 +}
13605 +
13606 +
13607 +/*----------------------------------------------------------------------------*/
13608 +void AacSaPciIsr( 
13609 +       int irq,
13610 +       void * irq_data,
13611 +       struct pt_regs *regs)
13612 +/*----------------------------------------------------------------------------*/
13613 +{
13614 +       // call the actual interrupt handler
13615 +       SaPciIsr( ( Sa_ADAPTER_EXTENSION * )irq_data );
13616 +}
13617 +
13618 +/*----------------------------------------------------------------------------*/
13619 +void AacRxPciIsr( 
13620 +       int irq,
13621 +       void * irq_data,
13622 +       struct pt_regs *regs)
13623 +/*----------------------------------------------------------------------------*/
13624 +{
13625 +       // call the actual interrupt handler
13626 +       RxPciIsr( ( Sa_ADAPTER_EXTENSION * )irq_data );
13627 +}
13628 +
13629 +
13630 +/*----------------------------------------------------------------------------*/
13631 +void OsDetachInterrupt( 
13632 +       Sa_ADAPTER_EXTENSION *AdapterExtension )
13633 +/*----------------------------------------------------------------------------*/
13634 +{
13635 +       PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
13636 +       void *irq_data;
13637 +
13638 +       CommonExtension = AdapterExtension->Common;
13639 +       irq_data = ( void * )AdapterExtension;
13640 +
13641 +       OsUnregisterInterrupt (
13642 +               CommonExtension->OsDep.scsi_host_ptr->irq,      // interrupt number
13643 +               irq_data );
13644 +}
13645 +
13646 +
13647 +/*----------------------------------------------------------------------------*/
13648 +int OsAttachDMA( 
13649 +       Sa_ADAPTER_EXTENSION *AdapterExtension )
13650 +/*----------------------------------------------------------------------------*/
13651 +{
13652 +       return( 0 );
13653 +}
13654 +
13655 +/*----------------------------------------------------------------------------*/
13656 +int OsAttachHBA( 
13657 +       Sa_ADAPTER_EXTENSION *AdapterExtension )
13658 +/*----------------------------------------------------------------------------*/
13659 +{
13660 +       return( 0 );
13661 +}
13662 +
13663 +/*----------------------------------------------------------------------------*/
13664 +void OsDetachDevice( 
13665 +       Sa_ADAPTER_EXTENSION *AdapterExtension )
13666 +/*----------------------------------------------------------------------------*/
13667 +{
13668 +       OsUnMapDeviceRegisters( AdapterExtension );
13669 +       return( 0 );
13670 +}
13671 +
13672 +/*----------------------------------------------------------------------------*/
13673 +ULONG *OsAllocCommPhysMem(
13674 +       Sa_ADAPTER_EXTENSION    *AdapterExtension, 
13675 +       ULONG                                   size,
13676 +       ULONG                                   **virt_addr_pptr,
13677 +       ULONG                                   *phys_addr_ptr )
13678 +/*----------------------------------------------------------------------------*/
13679 +{
13680 +       if( ( *virt_addr_pptr = ( ULONG * )OsAllocMemory( size, GFP_KERNEL ) ) )
13681 +       {
13682 +               *phys_addr_ptr = OsVirtToPhys( ( volatile void * )*virt_addr_pptr );
13683 +               if( !*phys_addr_ptr )
13684 +               {
13685 +                       cmn_err( CE_WARN, "OsAllocCommPhysMem: OsVirtToPhys failed" );
13686 +               }
13687 +                               
13688 +               return( *virt_addr_pptr );
13689 +       }
13690 +       else
13691 +               return( NULL );
13692 +}
13693 +
13694 +OsAifKernelThread(
13695 +       Sa_ADAPTER_EXTENSION    *AdapterExtension )
13696 +{
13697 +
13698 +       struct fs_struct *fs;
13699 +       int i;
13700 +       struct task_struct *tsk;
13701 +
13702 +       tsk = current;
13703 +
13704 +
13705 +       /*
13706 +        * set up the name that will appear in 'ps'
13707 +        * stored in  task_struct.comm[16].
13708 +        */
13709 +
13710 +       sprintf(tsk->comm, "AIFd");
13711 +
13712 +
13713 +       // use_init_fs_context();  only exists in 2.2.13 onward.
13714 +
13715 +       lock_kernel();
13716 +
13717 +       /*
13718 +        * we were started as a result of loading the  module.
13719 +        * free all of user space pages
13720 +        */
13721 +
13722 +       exit_mm(tsk);
13723 +
13724 +       exit_files(tsk);
13725 +
13726 +       exit_fs(tsk);
13727 +
13728 +       fs = init_task.fs;
13729 +       tsk->fs = fs;
13730 +
13731 +       tsk->session = 1;
13732 +       tsk->pgrp = 1;
13733 +
13734 +       if (fs)
13735 +               atomic_inc(&fs->count);
13736 +
13737 +       unlock_kernel();
13738 +
13739 +
13740 +
13741 +
13742 +       NormCommandThread(AdapterExtension);
13743 +       /* NOT REACHED */
13744 +}
13745 +
13746 +/*----------------------------------------------------------------------------*/
13747 +void OsStartKernelThreads(
13748 +       Sa_ADAPTER_EXTENSION    *AdapterExtension )
13749 +/*----------------------------------------------------------------------------*/
13750 +{
13751 +       PCI_MINIPORT_COMMON_EXTENSION   *CommonExtension;
13752 +       AFA_COMM_ADAPTER                                *Adapter;
13753 +       extern void                                     NormCommandThread(void *Adapter);
13754 +
13755 +       CommonExtension = AdapterExtension->Common;
13756 +       Adapter = (AFA_COMM_ADAPTER *)CommonExtension->Adapter;
13757 +
13758 +       // 
13759 +       // Start thread which will handle interrupts for this adapter
13760 +       //
13761 +       //kthread_spawn(FsaCommIntrHandler, AdapterExtension, "fsaintr",0);
13762 +
13763 +       //
13764 +       // Start thread which will handle AdapterInititatedFibs from this adapter
13765 +       //
13766 +       CommonExtension->OsDep.thread_pid = 
13767 +               kernel_thread( ( int ( * )( void * ) )OsAifKernelThread, Adapter, 0 );
13768 +//             kernel_thread( ( int ( * )( void * ) )NormCommandThread, Adapter, 0 );
13769 +}
13770 +
13771 +/*----------------------------------------------------------------------------*/
13772 +BOOLEAN AfaPortAllocateAndMapFibSpace(
13773 +       PVOID Arg1,
13774 +    IN PMAPFIB_CONTEXT MapFibContext )
13775 +/*----------------------------------------------------------------------------*/
13776 +{
13777 +       PVOID           BaseAddress;
13778 +       ULONG           PhysAddress;
13779 +
13780 +       if( !( BaseAddress = (ULONG *)OsAllocMemory( MapFibContext->Size, GFP_KERNEL ) ) )
13781 +       {
13782 +               cmn_err( CE_WARN, "AfaPortAllocateAndMapFibSpace: OsAllocMemory failed" );
13783 +               return( FALSE );
13784 +       }
13785 +
13786 +       PhysAddress = OsVirtToPhys( BaseAddress );
13787 +       
13788 +       MapFibContext->FibVirtualAddress = BaseAddress;
13789 +       MapFibContext->FibPhysicalAddress = (PVOID) PhysAddress;
13790 +
13791 +       return (TRUE);
13792 +}
13793 +
13794 +/*----------------------------------------------------------------------------*/
13795 +BOOLEAN AfaPortUnmapAndFreeFibSpace(
13796 +       PVOID Arg1,
13797 +    IN PMAPFIB_CONTEXT MapFibContext )
13798 +/*----------------------------------------------------------------------------*/
13799 +{
13800 +       PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
13801 +
13802 +       OsFreeMemory( MapFibContext->FibVirtualAddress, 0 );
13803 +
13804 +       return (TRUE);
13805 +}
13806 +
13807 +/*----------------------------------------------------------------------------*/
13808 +BOOLEAN AfaPortFreeAdapterCommArea(
13809 +       IN PVOID Arg1 )
13810 +/*----------------------------------------------------------------------------*/
13811 +{
13812 +       PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
13813 +
13814 +       OsFreeMemory( CommonExtension->CommAddress, 0 );
13815 +
13816 +       return (TRUE);
13817 +}
13818 +
13819 +
13820 +/* ================================================================================ */
13821 +/*
13822 + * Not sure if the functions below here ever get called in the current code
13823 + * These probably should be a different file.
13824 + */
13825 +/*
13826 +ddi_dma_attr_t AfaPortDmaAttributes = {
13827 +       //rpbfix : we may want something different for I/O
13828 +       DMA_ATTR_V0,
13829 +       0,
13830 +       0xffffffff,
13831 +       0x0000ffff,
13832 +       1,
13833 +       1,
13834 +       1,
13835 +       0x0000ffff,
13836 +       0x0000ffff,
13837 +       17,
13838 +       512,
13839 +       0
13840 +};
13841 +*/
13842 +
13843 +AAC_STATUS
13844 +AfaPortBuildSgMap(
13845 +       PVOID Arg1,
13846 +       IN PSGMAP_CONTEXT SgMapContext
13847 +       )
13848 +
13849 +/*++
13850 +
13851 +Routine Description:
13852 +
13853 +       This routine build a scatter gather map using the information
13854 +       in the SgMapContext.
13855 +
13856 +Arguments:
13857 +
13858 +       AdapterExtension - Pointer to adapter extension structure.
13859 +    SgMapContext - Pointer to the SgMapContext for the request.
13860 +
13861 +
13862 +Return Value:
13863 +
13864 +       AAC_STATUS      
13865 +--*/
13866 +{
13867 +       printk( KERN_ALERT "AfaPortBuildSgMap: unimplemented function called" );
13868 +       return (STATUS_UNSUCCESSFUL);
13869 +}
13870 +
13871 +VOID
13872 +AfaPortFreeDmaResources(
13873 +       PVOID Arg1,
13874 +    IN PSGMAP_CONTEXT SgMapContext
13875 +    )
13876 +
13877 +/*++
13878 +
13879 +Routine Description:
13880 +
13881 +    Given a pointer to the IRP context will free all reserved DMA resources allocated for
13882 +    the completed IO operation.
13883 +
13884 +Arguments:
13885 +
13886 +    Fib - Pointer to the Fib the caller wishes to have transfered over to the adapter.
13887 +    Context - Pointer to the Irp Context we use to store the dma mapping information
13888 +        we need to do and complete the IO.
13889 +
13890 +Return Value:
13891 +
13892 +    Nothing
13893 +
13894 +--*/
13895 +{
13896 +}
13897 diff -burN linux-2.4.9/drivers/scsi/aacraid/osfuncs.c linux/drivers/scsi/aacraid/osfuncs.c
13898 --- linux-2.4.9/drivers/scsi/aacraid/osfuncs.c  Wed Dec 31 18:00:00 1969
13899 +++ linux/drivers/scsi/aacraid/osfuncs.c        Thu Aug 16 18:15:01 2001
13900 @@ -0,0 +1,594 @@
13901 +/*++
13902 + * Adaptec aacraid device driver for Linux.
13903 + *
13904 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
13905 + *
13906 + * This program is free software; you can redistribute it and/or modify
13907 + * it under the terms of the GNU General Public License as published by
13908 + * the Free Software Foundation; either version 2, or (at your option)
13909 + * any later version.
13910 + *
13911 + * This program is distributed in the hope that it will be useful,
13912 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
13913 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13914 + * GNU General Public License for more details.
13915 + *
13916 + * You should have received a copy of the GNU General Public License
13917 + * along with this program; see the file COPYING.  If not, write to
13918 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
13919 + *
13920 + * Module Name:
13921 + *  osfuncs.c
13922 + *
13923 + * Abstract: Holds all of the O/S specific interface functions.
13924 + *     
13925 + --*/
13926 +
13927 +static char *ident_osfuncs = "aacraid_ident osfuncs.c 1.0.6 2000/10/09 Adaptec, Inc.";
13928 +
13929 +#include "osheaders.h"
13930 +
13931 +//static LKINFO_DECL(fsa_locks, "fsa_locks",0);
13932 +
13933 +extern aac_options_t g_options;
13934 +
13935 +OS_SOFTINTR g_idle_task = { 0, 0, 0, 0 };
13936 +wait_queue_t * g_wait_queue_ptr = NULL;
13937 +wait_queue_t g_wait;
13938 +
13939 +void OsTimeoutHandler( 
13940 +       struct semaphore * sem );
13941 +
13942 +int * OsIdleTask( void * data );
13943 +
13944 +//-----------------------------------------------------------------------------
13945 +// Memory Allocation functions
13946 +
13947 +/*----------------------------------------------------------------------------*/
13948 +void * OsAllocMemory(
13949 +       OS_SIZE_T Size,
13950 +       unsigned int Flags )
13951 +/*----------------------------------------------------------------------------*/
13952 +{
13953 +       void *mem_ptr;
13954 +
13955 +       if( !( mem_ptr = kmalloc( Size, GFP_KERNEL ) ) )
13956 +               cmn_err( CE_WARN, "OsAllocMemory: FAILED\n" );
13957 +       return( mem_ptr );
13958 +}
13959 +
13960 +
13961 +/*----------------------------------------------------------------------------*/
13962 +void OsFreeMemory(
13963 +       void * Buffer,
13964 +       OS_SIZE_T Size )
13965 +/*----------------------------------------------------------------------------*/
13966 +{
13967 +       kfree( Buffer );
13968 +}
13969 +
13970 +
13971 +/*----------------------------------------------------------------------------*/
13972 +int OsRegisterInterrupt(
13973 +       unsigned int irq,               // interrupt number
13974 +       void ( *handler )( int, void*, struct pt_regs * ),      // handler function
13975 +       void *irq_data )                // argument to handler function
13976 +/*----------------------------------------------------------------------------*/
13977 +{
13978 +  return( request_irq (irq, handler, SA_INTERRUPT | SA_SHIRQ,  "aacraid", irq_data ) );
13979 +}
13980 +
13981 +
13982 +/*----------------------------------------------------------------------------*/
13983 +void OsUnregisterInterrupt(
13984 +       unsigned int irq,               // interrupt number
13985 +       void *irq_data)
13986 +/*----------------------------------------------------------------------------*/
13987 +{
13988 +       free_irq (
13989 +               irq,                                                                            // interrupt number
13990 +               irq_data );
13991 +}
13992 +
13993 +
13994 +/*----------------------------------------------------------------------------*/
13995 +unsigned long OsVirtToPhys( 
13996 +       void * virtual_address )
13997 +/*----------------------------------------------------------------------------*/
13998 +{
13999 +       return( virt_to_phys( virtual_address ) );
14000 +}
14001 +
14002 +
14003 +//-----------------------------------------------------------------------------
14004 +// MUTEX functions
14005 +
14006 +/*----------------------------------------------------------------------------*/
14007 +OS_STATUS OsMutexInit( 
14008 +       OS_MUTEX *Mutex,
14009 +       OS_SPINLOCK_COOKIE Cookie )
14010 +/*----------------------------------------------------------------------------*/
14011 +{
14012 +       Mutex->lock_var = 0;
14013 +       //      bzero (&Mutex->wq, sizeof (Mutex->wq));
14014 +       init_waitqueue_head (&Mutex->wq);
14015 +       return ( 0 );
14016 +}
14017 +
14018 +
14019 +/*----------------------------------------------------------------------------*/
14020 +void OsMutexDestroy( 
14021 +       OS_MUTEX *Mutex )
14022 +/*----------------------------------------------------------------------------*/
14023 +{
14024 +}
14025 +
14026 +
14027 +/*----------------------------------------------------------------------------*/
14028 +void OsMutexAcquire( 
14029 +       OS_MUTEX *Mutex )
14030 +/*----------------------------------------------------------------------------*/
14031 +{
14032 +  //   wait_queue_t wait = { current, NULL };
14033 +       unsigned long time_stamp;
14034 +
14035 +       DECLARE_WAITQUEUE (wait, current);
14036 +
14037 +       time_stamp = jiffies;
14038 +
14039 +       if( test_and_set_bit( 0, &( Mutex->lock_var ) ) != 0 )
14040 +       {
14041 +               if( in_interrupt() )
14042 +                       panic( "OsMutexAcquire going to sleep at interrupt time\n" );
14043 +               current->state = TASK_INTERRUPTIBLE;
14044 +               add_wait_queue( &( Mutex->wq ), &wait );
14045 +               while( test_and_set_bit( 0, &( Mutex->lock_var ) ) != 0 )
14046 +                       schedule();
14047 +               remove_wait_queue( &( Mutex->wq ), &wait );
14048 +       }
14049 +
14050 +       if( ( jiffies - 1 ) > time_stamp )
14051 +               cmn_err( CE_WARN, "Mutex %ld locked out for %ld ticks", 
14052 +                       Mutex, jiffies - time_stamp );
14053 +}
14054 +
14055 +
14056 +/*----------------------------------------------------------------------------*/
14057 +void OsMutexRelease( 
14058 +       OS_MUTEX *Mutex )
14059 +/*----------------------------------------------------------------------------*/
14060 +{
14061 +       if( test_and_clear_bit( 0, &( Mutex->lock_var ) ) == 0 )
14062 +               cmn_err( CE_WARN, "OsMutexRelease: mutex not locked" );
14063 +       wake_up_interruptible( &( Mutex->wq ) );
14064 +}
14065 +
14066 +// see man hierarchy(D5)
14067 +#define FSA_LOCK 1
14068 +
14069 +//-----------------------------------------------------------------------------
14070 +// Spinlock functions
14071 +
14072 +/*----------------------------------------------------------------------------*/
14073 +OS_SPINLOCK * OsSpinLockAlloc( void ) 
14074 +/*----------------------------------------------------------------------------*/
14075 +{
14076 +       OS_SPINLOCK *SpinLock;
14077 +       int i;
14078 +
14079 +
14080 +       SpinLock = ( OS_SPINLOCK * )kmalloc( sizeof( OS_SPINLOCK ), GFP_KERNEL );
14081 +
14082 +       if (SpinLock == NULL)
14083 +               cmn_err (CE_WARN, "WARNING: OsSpinLockAlloc Failed!!!");
14084 +       
14085 +       SpinLock->spin_lock = SPIN_LOCK_UNLOCKED;
14086 +       for( i = 0; i < NR_CPUS; i++ )
14087 +               SpinLock->cpu_lock_count[ i ] = 0;
14088 +       return( SpinLock );
14089 +}
14090 +
14091 +
14092 +/*----------------------------------------------------------------------------*/
14093 +OS_STATUS OsSpinLockInit( 
14094 +       OS_SPINLOCK *SpinLock,
14095 +       OS_SPINLOCK_COOKIE Cookie )
14096 +/*----------------------------------------------------------------------------*/
14097 +{
14098 +       return( 0 );
14099 +}
14100 +
14101 +
14102 +/*----------------------------------------------------------------------------*/
14103 +void OsSpinLockDestroy( 
14104 +       OS_SPINLOCK *SpinLock )
14105 +/*----------------------------------------------------------------------------*/
14106 +{
14107 +       kfree( SpinLock );
14108 +       SpinLock = NULL;
14109 +}
14110 +
14111 +
14112 +/*----------------------------------------------------------------------------*/
14113 +void OsSpinLockAcquire( 
14114 +       OS_SPINLOCK *SpinLock )
14115 +/*----------------------------------------------------------------------------*/
14116 +{
14117 +       unsigned cpu_id;
14118 +
14119 +       if( SpinLock )
14120 +       {
14121 +               cpu_id = smp_processor_id();
14122 +               if( SpinLock->cpu_lock_count[ cpu_id ] ){
14123 +                       cmn_err (CE_PANIC, "CPU %d trying to acquire lock again: lock count = %d\n",
14124 +                                cpu_id, SpinLock->cpu_lock_count[ cpu_id ]);
14125 +               }                 
14126 +               
14127 +               spin_lock_irqsave( &( SpinLock->spin_lock ), SpinLock->cpu_flags[ cpu_id ] );
14128 +               SpinLock->cpu_lock_count[ cpu_id ]++;
14129 +          
14130 +       } else {
14131 +               cmn_err( CE_WARN, "OsSpinLockAcquire: lock does not exist" );
14132 +       }
14133 +}
14134 +
14135 +
14136 +/*----------------------------------------------------------------------------*/
14137 +void OsSpinLockRelease( 
14138 +       OS_SPINLOCK *SpinLock )
14139 +/*----------------------------------------------------------------------------*/
14140 +{
14141 +       unsigned cpu_id;
14142 +
14143 +       if( SpinLock )
14144 +       {
14145 +               cpu_id = smp_processor_id();
14146 +               SpinLock->cpu_lock_count[ cpu_id ]--;
14147 +               spin_unlock_irqrestore( &( SpinLock->spin_lock ), SpinLock->cpu_flags[ cpu_id ] );
14148 +       }
14149 +       else
14150 +               cmn_err( CE_WARN, "OsSpinLockRelease: lock does not exist" );
14151 +}
14152 +
14153 +
14154 +/*----------------------------------------------------------------------------*/
14155 +inline int OsSpinLockOwned(
14156 +       OS_SPINLOCK *SpinLock )
14157 +/*----------------------------------------------------------------------------*/
14158 +{
14159 +       return spin_is_locked (&SpinLock->spin_lock);
14160 +}
14161 +
14162 +
14163 +//-----------------------------------------------------------------------------
14164 +// CvLock functions
14165 +
14166 +/*----------------------------------------------------------------------------*/
14167 +OS_CVLOCK *OsCvLockAlloc( void ) 
14168 +{
14169 +       OS_CVLOCK *cv_lock;
14170 +
14171 +
14172 +#ifdef CVLOCK_USE_SPINLOCK
14173 +       cv_lock = OsSpinLockAlloc(); 
14174 +#else
14175 +       cv_lock = ( OS_CVLOCK * )kmalloc( sizeof( OS_CVLOCK ), GFP_KERNEL );
14176 +       cv_lock->wq = NULL;
14177 +       cv_lock->lock_var = 0;
14178 +#endif
14179 +
14180 +       return( cv_lock );
14181 +}
14182 +
14183 +
14184 +/*----------------------------------------------------------------------------*/
14185 +OS_STATUS OsCvLockInit( 
14186 +       OS_CVLOCK *cv_lock,
14187 +       OS_SPINLOCK_COOKIE Cookie )
14188 +/*----------------------------------------------------------------------------*/
14189 +{
14190 +       return ( 0 );
14191 +}
14192 +
14193 +
14194 +/*----------------------------------------------------------------------------*/
14195 +void OsCvLockDestroy( 
14196 +       OS_CVLOCK *cv_lock )
14197 +/*----------------------------------------------------------------------------*/
14198 +{
14199 +       if( cv_lock )
14200 +               kfree( cv_lock );
14201 +       cv_lock = NULL;
14202 +}
14203 +
14204 +
14205 +/*----------------------------------------------------------------------------*/
14206 +void OsCvLockAcquire (OS_CVLOCK *cv_lock)
14207 +{
14208 +#ifdef CVLOCK_USE_SPINLOCK
14209 +               OsSpinLockAcquire( cv_lock );
14210 +#else
14211 +               OsMutexAcquire( cv_lock );
14212 +#endif
14213 +}
14214 +
14215 +
14216 +/*----------------------------------------------------------------------------*/
14217 +void OsCvLockRelease( 
14218 +       OS_CVLOCK *cv_lock )
14219 +/*----------------------------------------------------------------------------*/
14220 +{
14221 +#ifdef CVLOCK_USE_SPINLOCK
14222 +               OsSpinLockRelease( cv_lock );
14223 +#else
14224 +               OsMutexRelease( cv_lock );
14225 +#endif
14226 +}
14227 +
14228 +
14229 +/*----------------------------------------------------------------------------*/
14230 +int OsCvLockOwned(
14231 +       OS_CVLOCK *cv_lock )
14232 +/*----------------------------------------------------------------------------*/
14233 +{
14234 +       return( 1 );
14235 +}
14236 +
14237 +
14238 +//-----------------------------------------------------------------------------
14239 +// Conditional variable functions
14240 +
14241 +/*----------------------------------------------------------------------------*/
14242 +void OsCv_init ( 
14243 +       OS_CV_T *cv_ptr )
14244 +/*----------------------------------------------------------------------------*/
14245 +{
14246 +       cv_ptr->lock_var = 1;
14247 +       init_waitqueue_head (&cv_ptr->wq);
14248 +}
14249 +
14250 +
14251 +/*----------------------------------------------------------------------------*/
14252 +void OsCv_destroy( 
14253 +       OS_CV_T  *cv_ptr )
14254 +/*----------------------------------------------------------------------------*/
14255 +{
14256 +}
14257 +
14258 +
14259 +/*______________________________________________________________________________
14260 + -
14261 + -
14262 + -----------------------------------------------------------------------------*/
14263 +OsCv_wait (OS_CV_T *cv_ptr, OS_CVLOCK *cv_lock_ptr)
14264 +{
14265 +       unsigned long flags;
14266 +
14267 +       DECLARE_WAITQUEUE (wait, current);
14268 +       
14269 +       if( in_interrupt() )
14270 +               panic( "OsCv_wait going to sleep at interrupt time\n" );
14271 +
14272 +       cv_ptr->type = TASK_UNINTERRUPTIBLE;
14273 +       current->state = TASK_UNINTERRUPTIBLE;
14274 +
14275 +       add_wait_queue( &cv_ptr->wq, &wait );
14276 +
14277 +       OsCvLockRelease( cv_lock_ptr );
14278 +       schedule();
14279 +
14280 +       while( test_and_set_bit( 0, &( cv_ptr->lock_var ) ) != 0 )
14281 +       {
14282 +               if( in_interrupt() )
14283 +                       panic( "OsCv_wait going to sleep at interrupt time\n" );
14284 +               schedule();
14285 +       }
14286 +
14287 +       remove_wait_queue( &( cv_ptr->wq ), &wait );
14288 +
14289 +       OsCvLockAcquire( cv_lock_ptr );
14290 +}
14291 +
14292 +
14293 +/*----------------------------------------------------------------------------*/
14294 +int OsCv_wait_sig( 
14295 +       OS_CV_T *cv_ptr,
14296 +       OS_CVLOCK *cv_lock_ptr ) 
14297 +/*----------------------------------------------------------------------------*/
14298 +{
14299 +       unsigned long flags;
14300 +       int signal_state = 1;
14301 +
14302 +       DECLARE_WAITQUEUE (wait, current);
14303 +       
14304 +       if( in_interrupt() )
14305 +               panic( "OsCv_wait_sig going to sleep at interrupt time\n" );
14306 +
14307 +       cv_ptr->type = TASK_INTERRUPTIBLE;
14308 +       current->state = TASK_INTERRUPTIBLE;
14309 +
14310 +       add_wait_queue( &( cv_ptr->wq ), &wait );
14311 +
14312 +       OsCvLockRelease( cv_lock_ptr );
14313 +       schedule();
14314 +
14315 +       while( ( test_and_set_bit( 0, &( cv_ptr->lock_var ) ) != 0 ) && 
14316 +                       ( !signal_pending( current ) ) )
14317 +       {
14318 +               if( in_interrupt() )
14319 +                       panic( "OsCv_wait_sig going to sleep at interrupt time\n" );
14320 +               schedule();
14321 +       }
14322 +
14323 +       if( signal_pending( current ) )
14324 +               signal_state = 0;
14325 +       
14326 +       remove_wait_queue( &( cv_ptr->wq ), &wait );
14327 +       
14328 +       OsCvLockAcquire( cv_lock_ptr );
14329 +       return( signal_state );
14330 +}
14331 +
14332 +
14333 +/*----------------------------------------------------------------------------*/
14334 +void OsCv_signal( 
14335 +       OS_CV_T *cv_ptr )
14336 +/*----------------------------------------------------------------------------*/
14337 +{
14338 +
14339 +       clear_bit( 0, &( cv_ptr->lock_var ) );
14340 +       if( cv_ptr->type == TASK_INTERRUPTIBLE )
14341 +                       wake_up_interruptible( &( cv_ptr->wq ) );
14342 +       else{
14343 +                       wake_up( &( cv_ptr->wq ) );
14344 +       }
14345 +}
14346 +
14347 +
14348 +// return time in seconds
14349 +/*----------------------------------------------------------------------------*/
14350 +unsigned long OsGetSeconds( void )
14351 +/*----------------------------------------------------------------------------*/
14352 +{
14353 +       return( jiffies/HZ );
14354 +}
14355 +
14356 +
14357 +//-----------------------------------------------------------------------------
14358 +// Deferred procedure call functions
14359 +
14360 +// create a soft interrupt object
14361 +/*----------------------------------------------------------------------------*/
14362 +int OsSoftInterruptAdd( 
14363 +       OS_SOFTINTR **ptr,
14364 +       void * handler,
14365 +       void * data )
14366 +/*----------------------------------------------------------------------------*/
14367 +{
14368 +       OS_SOFTINTR *tmp_ptr;
14369 +
14370 +       if( !( tmp_ptr = ( OS_SOFTINTR * )kmalloc( sizeof( OS_SOFTINTR ), GFP_KERNEL ) ) )
14371 +               return( -1 );
14372 +       tmp_ptr->routine = handler;
14373 +       tmp_ptr->data = data;
14374 +       tmp_ptr->sync = 0;
14375 +       INIT_LIST_HEAD(&tmp_ptr->list);
14376 +
14377 +       *ptr = tmp_ptr; 
14378 +
14379 +       return( 0 );
14380 +}
14381 +
14382 +/*
14383 +       Use kernel_thread( ( int ( * )( void * ) )OsIdleTask, NULL, 0 ); to start
14384 +*/
14385 +/*----------------------------------------------------------------------------*/
14386 +int * OsIdleTask( void * data )
14387 +/*----------------------------------------------------------------------------*/
14388 +{
14389 +       DECLARE_WAITQUEUE (wait, current);
14390 +
14391 +       while( 1 )
14392 +       {
14393 +               current->state = TASK_INTERRUPTIBLE;
14394 +               add_wait_queue( &g_wait_queue_ptr, &wait );
14395 +               schedule();
14396 +               remove_wait_queue( &g_wait_queue_ptr, &wait );
14397 +               wait.task =  current;
14398 +               wait.task_list.next = NULL;
14399 +       }
14400 +       return( NULL );
14401 +}
14402 +
14403 +
14404 +// dispatch a soft interrupt 
14405 +/*----------------------------------------------------------------------------*/
14406 +void OsSoftInterruptTrigger( 
14407 +       OS_SOFTINTR *soft_intr_ptr )
14408 +/*----------------------------------------------------------------------------*/
14409 +{
14410 +       // call the completion routine directly
14411 +       soft_intr_ptr->routine( soft_intr_ptr->data );
14412 +}
14413 +
14414 +
14415 +// delete a soft interrupt object
14416 +/*----------------------------------------------------------------------------*/
14417 +void OsSoftInterruptRemove( 
14418 +       OS_SOFTINTR *arg )
14419 +/*----------------------------------------------------------------------------*/
14420 +{
14421 +       if( arg )
14422 +               kfree( arg );
14423 +       arg = NULL;
14424 +}
14425 +
14426 +
14427 +/*----------------------------------------------------------------------------*/
14428 +void OsSleep( 
14429 +       unsigned time )         // in seconds
14430 +/*----------------------------------------------------------------------------*/
14431 +{
14432 +       struct semaphore sem;
14433 +       struct timer_list timer_var;
14434 +       
14435 +       init_MUTEX_LOCKED (&sem);
14436 +
14437 +       //      if( in_interrupt() )
14438 +       //              panic( "OsSleep going to sleep at interrupt time\n" );
14439 +
14440 +       init_timer( &timer_var );
14441 +       timer_var.function = ( void ( * )( unsigned long ) )OsTimeoutHandler;
14442 +       timer_var.data = ( unsigned long )&sem;
14443 +       timer_var.expires = jiffies + time * HZ;
14444 +
14445 +       add_timer( &timer_var );
14446 +       down( &sem );
14447 +
14448 +       del_timer( &timer_var );
14449 +}
14450 +
14451 +
14452 +/*----------------------------------------------------------------------------*/
14453 +void OsTimeoutHandler( 
14454 +       struct semaphore * sem )
14455 +/*----------------------------------------------------------------------------*/
14456 +{
14457 +       if( sem != NULL )
14458 +               up( sem );
14459 +}
14460 +
14461 +
14462 +/*----------------------------------------------------------------------------*/
14463 +void printk_err(
14464 +       int flag, 
14465 +       char *fmt, 
14466 +       ...)
14467 +/*----------------------------------------------------------------------------*/
14468 +{
14469 +       char    buf[256];
14470 +       va_list ap;
14471 +
14472 +       va_start(ap, fmt);
14473 +       (void) vsprintf(buf, fmt, ap);
14474 +       va_end(ap);
14475 +       
14476 +       if( flag <= g_options.message_level )
14477 +               printk(KERN_ALERT "%s\n", buf);
14478 +}
14479 +
14480 +/*  void aac_show_tasks (struct list_head *our_tasks){ */
14481
14482 +/*             cmn_err (CE_DEBUG, "Entering aac_show_tasks"); */
14483 +
14484 +/*             if (our_tasks->next == NULL || our_tasks->next == 0) */
14485 +/*                             cmn_err (CE_DEBUG, "list_head->next is NULL or 0"); */
14486 +/*             else */
14487 +/*                             cmn_err (CE_DEBUG, "list_head->next: 0x%x", our_tasks->next); */
14488 +
14489 +/*             if (our_tasks->prev == NULL || our_tasks->prev == 0) */
14490 +/*                             cmn_err (CE_DEBUG, "list_head->prev is NULL or 0"); */
14491 +/*             else */
14492 +/*                             cmn_err (CE_DEBUG, "list_head->prev: 0x%x", our_tasks->prev); */
14493 +
14494 +/*  } */
14495 diff -burN linux-2.4.9/drivers/scsi/aacraid/ossup.c linux/drivers/scsi/aacraid/ossup.c
14496 --- linux-2.4.9/drivers/scsi/aacraid/ossup.c    Wed Dec 31 18:00:00 1969
14497 +++ linux/drivers/scsi/aacraid/ossup.c  Thu Aug 16 13:41:30 2001
14498 @@ -0,0 +1,199 @@
14499 +/*++
14500 + * Adaptec aacraid device driver for Linux.
14501 + *
14502 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
14503 + *
14504 + * This program is free software; you can redistribute it and/or modify
14505 + * it under the terms of the GNU General Public License as published by
14506 + * the Free Software Foundation; either version 2, or (at your option)
14507 + * any later version.
14508 + *
14509 + * This program is distributed in the hope that it will be useful,
14510 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
14511 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14512 + * GNU General Public License for more details.
14513 + *
14514 + * You should have received a copy of the GNU General Public License
14515 + * along with this program; see the file COPYING.  If not, write to
14516 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
14517 + *
14518 + * Module Name:
14519 + *  ossup.c
14520 + *
14521 + * 
14522 + *
14523 + --*/
14524 +
14525 +static char *ident_ossup = "aacraid_ident ossup.c 1.0.6 2000/10/09 Adaptec, Inc.";
14526 +
14527 +#include "osheaders.h"
14528 +
14529 +#include "aac_unix_defs.h"
14530 +
14531 +
14532 +AAC_STATUS
14533 +ExInitializeZone(
14534 +    IN PZONE_HEADER Zone,
14535 +    IN ULONG BlockSize,
14536 +    IN PVOID InitialSegment,
14537 +    IN ULONG InitialSegmentSize
14538 +    )
14539 +
14540 +/*++
14541 +
14542 +Routine Description:
14543 +
14544 +    This function initializes a zone header.  Once successfully
14545 +    initialized, blocks can be allocated and freed from the zone, and
14546 +    the zone can be extended.
14547 +
14548 +Arguments:
14549 +
14550 +    Zone - Supplies the address of a zone header to be initialized.
14551 +
14552 +    BlockSize - Supplies the block size of the allocatable unit within
14553 +                the zone.  The size must be larger that the size of the
14554 +                initial segment, and must be 64-bit aligned.
14555 +
14556 +    InitialSegment - Supplies the address of a segment of storage.  The
14557 +                     first ZONE_SEGMENT_HEADER-sized portion of the segment
14558 +                     is used by the zone allocator.  The remainder of
14559 +                     the segment is carved up into fixed size
14560 +                     (BlockSize) blocks and is made available for
14561 +                     allocation and deallocation from the zone.  The
14562 +                     address of the segment must be aligned on a 64-bit
14563 +                     boundary.
14564 +
14565 +    InitialSegmentSize - Supplies the size in bytes of the InitialSegment.
14566 +
14567 +Return Value:
14568 +
14569 +    STATUS_UNSUCCESSFUL - BlockSize or InitialSegment was not aligned on
14570 +                          64-bit boundaries, or BlockSize was larger than
14571 +                          the initial segment size.
14572 +
14573 +    STATUS_SUCCESS - The zone was successfully initialized.
14574 +
14575 +--*/
14576 +
14577 +{
14578 +    ULONG i;
14579 +    PCHAR p;
14580 +
14581 +
14582 +    Zone->BlockSize = BlockSize;
14583 +
14584 +    Zone->SegmentList.Next = &((PZONE_SEGMENT_HEADER) InitialSegment)->SegmentList;
14585 +    ((PZONE_SEGMENT_HEADER) InitialSegment)->SegmentList.Next = NULL;
14586 +    ((PZONE_SEGMENT_HEADER) InitialSegment)->Reserved = NULL;
14587 +
14588 +    Zone->FreeList.Next = NULL;
14589 +
14590 +    p = (PCHAR)InitialSegment + sizeof(ZONE_SEGMENT_HEADER);
14591 +
14592 +    for (i = sizeof(ZONE_SEGMENT_HEADER);
14593 +         i <= InitialSegmentSize - BlockSize;
14594 +         i += BlockSize
14595 +        ) {
14596 +        ((PSINGLE_LIST_ENTRY)p)->Next = Zone->FreeList.Next;
14597 +        Zone->FreeList.Next = (PSINGLE_LIST_ENTRY)p;
14598 +        p += BlockSize;
14599 +    }
14600 +    Zone->TotalSegmentSize = i;
14601 +
14602 +#if 0
14603 +    DbgPrint( "EX: ExInitializeZone( %lx, %lx, %lu, %lu, %lx )\n",
14604 +              Zone, InitialSegment, InitialSegmentSize,
14605 +              BlockSize, p
14606 +            );
14607 +#endif
14608 +
14609 +    return STATUS_SUCCESS;
14610 +}
14611 +
14612 +AAC_STATUS
14613 +ExExtendZone(
14614 +    IN PZONE_HEADER Zone,
14615 +    IN PVOID Segment,
14616 +    IN ULONG SegmentSize
14617 +    )
14618 +
14619 +/*++
14620 +
14621 +Routine Description:
14622 +
14623 +    This function extends a zone by adding another segment's worth of
14624 +    blocks to the zone.
14625 +
14626 +Arguments:
14627 +
14628 +    Zone - Supplies the address of a zone header to be extended.
14629 +
14630 +    Segment - Supplies the address of a segment of storage.  The first
14631 +              ZONE_SEGMENT_HEADER-sized portion of the segment is used by the
14632 +              zone allocator.  The remainder of the segment is carved up
14633 +              into fixed-size (BlockSize) blocks and is added to the
14634 +              zone.  The address of the segment must be aligned on a 64-
14635 +              bit boundary.
14636 +
14637 +    SegmentSize - Supplies the size in bytes of Segment.
14638 +
14639 +Return Value:
14640 +
14641 +    STATUS_UNSUCCESSFUL - BlockSize or Segment was not aligned on
14642 +                          64-bit boundaries, or BlockSize was larger than
14643 +                          the segment size.
14644 +
14645 +    STATUS_SUCCESS - The zone was successfully extended.
14646 +
14647 +--*/
14648 +
14649 +{
14650 +    ULONG i;
14651 +    PCHAR p;
14652 +
14653 +
14654 +    ((PZONE_SEGMENT_HEADER) Segment)->SegmentList.Next = Zone->SegmentList.Next;
14655 +    Zone->SegmentList.Next = &((PZONE_SEGMENT_HEADER) Segment)->SegmentList;
14656 +
14657 +    p = (PCHAR)Segment + sizeof(ZONE_SEGMENT_HEADER);
14658 +
14659 +    for (i = sizeof(ZONE_SEGMENT_HEADER);
14660 +         i <= SegmentSize - Zone->BlockSize;
14661 +         i += Zone->BlockSize
14662 +        ) {
14663 +
14664 +        ((PSINGLE_LIST_ENTRY)p)->Next = Zone->FreeList.Next;
14665 +        Zone->FreeList.Next = (PSINGLE_LIST_ENTRY)p;
14666 +        p += Zone->BlockSize;
14667 +    }
14668 +    Zone->TotalSegmentSize += i;
14669 +
14670 +#if 0
14671 +    DbgPrint( "EX: ExExtendZone( %lx, %lx, %lu, %lu, %lx )\n",
14672 +              Zone, Segment, SegmentSize, Zone->BlockSize, p
14673 +            );
14674 +#endif
14675 +
14676 +    return STATUS_SUCCESS;
14677 +}
14678 +
14679 +DbgPrint()
14680 +{
14681 +}
14682 +
14683 +/* Function: InqStrCopy()
14684 + *
14685 + * Arguments: [2] pointer to char
14686 + *
14687 + * Purpose: Copy a String from one location to another
14688 + * without copying \0
14689 + */
14690 +void
14691 +InqStrCopy(char *a, char *b)
14692 +{
14693 +
14694 +       while(*a != (char)0) 
14695 +               *b++ = *a++;
14696 +}
14697 +
14698 diff -burN linux-2.4.9/drivers/scsi/aacraid/port.c linux/drivers/scsi/aacraid/port.c
14699 --- linux-2.4.9/drivers/scsi/aacraid/port.c     Wed Dec 31 18:00:00 1969
14700 +++ linux/drivers/scsi/aacraid/port.c   Thu Aug 16 13:41:30 2001
14701 @@ -0,0 +1,287 @@
14702 +/*++
14703 + * Adaptec aacraid device driver for Linux.
14704 + *
14705 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
14706 + *
14707 + * This program is free software; you can redistribute it and/or modify
14708 + * it under the terms of the GNU General Public License as published by
14709 + * the Free Software Foundation; either version 2, or (at your option)
14710 + * any later version.
14711 + *
14712 + * This program is distributed in the hope that it will be useful,
14713 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
14714 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14715 + * GNU General Public License for more details.
14716 + *
14717 + * You should have received a copy of the GNU General Public License
14718 + * along with this program; see the file COPYING.  If not, write to
14719 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
14720 + *
14721 + * Module Name:
14722 + *  port.c
14723 + *
14724 + * Abstract: All support routines for FSA communication which are miniport specific.
14725 + *
14726 + --*/
14727 +
14728 +static char *ident_port = "aacraid_ident port.c 1.0.7 2000/10/11 Adaptec, Inc.";
14729 +
14730 +#include "osheaders.h"
14731 +
14732 +
14733 +#include "AacGenericTypes.h"
14734 +
14735 +#include "aac_unix_defs.h"
14736 +
14737 +#include "fsatypes.h"
14738 +#include "comstruc.h"
14739 +#include "protocol.h"
14740 +
14741 +#include "fsaport.h"
14742 +#include "fsaioctl.h"
14743 +
14744 +#include "pcisup.h"
14745 +#include "port.h"
14746 +
14747 +int AfaPortPrinting = 1;
14748 +
14749 +extern AAC_STATUS AfaPort_Err_Adapter_Printf;
14750 +extern AAC_STATUS AfaPort_Warn_Adapter_Printf;
14751 +extern AAC_STATUS AfaPort_Info_Adapter_Printf;
14752 +extern AAC_STATUS AfaPort_Err_FastAfa_Load_Driver;
14753 +
14754 +
14755 +
14756 +VOID
14757 +AfaPortLogError(
14758 +       IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
14759 +       IN AAC_STATUS ErrorCode,
14760 +       IN PUCHAR StringBuffer,
14761 +       IN ULONG StringLength
14762 +       )
14763 +/*++
14764 +
14765 +Routine Description:
14766 +
14767 +       Does all of the work to log an error log entry
14768 +Arguments:
14769 +
14770 +       CommonExtension - Pointer to the adapter that caused the error.
14771 +
14772 +       ErrorCode - Which error is being logged.
14773 +
14774 +       StringBuffer - Pointer to optional String for error log entry.
14775 +
14776 +       StringLength - Length of StringBuffer.
14777 +
14778 +Return Value:
14779 +
14780 +    Nothing
14781 +
14782 +--*/
14783 +
14784 +{
14785 +
14786 +}
14787 +
14788 +BOOLEAN
14789 +AfaPortGetNextAdapterNumber(
14790 +    IN  PDRIVER_OBJECT  DriverObject,
14791 +       OUT PDEVICE_OBJECT      *FsaDeviceObject,
14792 +       OUT PFILE_OBJECT        *FileObject,
14793 +       OUT PULONG                      AdapterNumber
14794 +       )
14795 +{
14796 +}
14797 +BOOLEAN
14798 +AfaPortAllocateAdapterCommArea(
14799 +       IN PVOID                Arg1,
14800 +       IN OUT PVOID    *CommHeaderAddress,
14801 +       IN ULONG                CommAreaSize,
14802 +       IN ULONG                CommAreaAlignment
14803 +       )
14804 +{
14805 +       PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
14806 +       PVOID BaseAddress;
14807 +       PHYSICAL_ADDRESS PhysicalBaseAddress;
14808 +       ULONG TotalSize, BytesToAlign;
14809 +       size_t          RealLength;
14810 +       uint_t          Count;
14811 +//     ULONG SizeOfFastIoComm = sizeof(FASTIO_STRUCT);
14812 +//     ULONG AdapterFibsSize = PAGE_SIZE;
14813 +       ULONG AdapterFibsSize = 4096;
14814 +       ULONG PrintfBufferSize = 256;
14815 +       PADAPTER_INIT_STRUCT InitStruct;
14816 +       extern int MiniPortRevision;
14817 +       ULONG   PhysAddress;
14818 +
14819 +//     TotalSize = AdapterFibsSize + sizeof(ADAPTER_INIT_STRUCT) + CommAreaSize + CommAreaAlignment +
14820 +//              SizeOfFastIoComm + PrintfBufferSize;
14821 +       TotalSize = AdapterFibsSize + sizeof(ADAPTER_INIT_STRUCT) + CommAreaSize + CommAreaAlignment +
14822 +                PrintfBufferSize;
14823 +
14824 +
14825 +       OsAllocCommPhysMem(CommonExtension->MiniPort, TotalSize, &BaseAddress, &PhysAddress);
14826 +
14827 +       CommonExtension->CommAddress  = BaseAddress;
14828 +       CommonExtension->CommPhysAddr = PhysAddress;
14829 +       CommonExtension->CommSize         = TotalSize;
14830 +
14831 +       PhysicalBaseAddress.HighPart = 0;
14832 +       PhysicalBaseAddress.LowPart = PhysAddress;
14833 +
14834 +       CommonExtension->InitStruct = (PADAPTER_INIT_STRUCT)((PUCHAR)(BaseAddress) + AdapterFibsSize);
14835 +       CommonExtension->PhysicalInitStruct = (PADAPTER_INIT_STRUCT)((PUCHAR)(PhysicalBaseAddress.LowPart) + AdapterFibsSize);
14836 +
14837 +       InitStruct = CommonExtension->InitStruct;
14838 +
14839 +       InitStruct->InitStructRevision = ADAPTER_INIT_STRUCT_REVISION;
14840 +       InitStruct->MiniPortRevision = MiniPortRevision;
14841 +       InitStruct->FilesystemRevision = CommonExtension->FilesystemRevision;
14842 +
14843 +       //
14844 +       // Adapter Fibs are the first thing allocated so that they start page aligned
14845 +       //
14846 +       InitStruct->AdapterFibsVirtualAddress = BaseAddress;
14847 +       InitStruct->AdapterFibsPhysicalAddress = (PVOID) PhysicalBaseAddress.LowPart;
14848 +       InitStruct->AdapterFibsSize = AdapterFibsSize;
14849 +       InitStruct->AdapterFibAlign = sizeof(FIB);
14850 +
14851 +       //
14852 +       // Increment the base address by the amount already used
14853 +       //
14854 +       BaseAddress = (PVOID)((PUCHAR)(BaseAddress) + AdapterFibsSize + sizeof(ADAPTER_INIT_STRUCT));
14855 +       PhysicalBaseAddress.LowPart = (ULONG)((PUCHAR)(PhysicalBaseAddress.LowPart) + AdapterFibsSize + sizeof(ADAPTER_INIT_STRUCT));
14856 +
14857 +       //
14858 +       // Align the beginning of Headers to CommAreaAlignment
14859 +       //
14860 +       BytesToAlign = (CommAreaAlignment - ((ULONG)(BaseAddress) & (CommAreaAlignment - 1)));
14861 +       BaseAddress = (PVOID)((PUCHAR)(BaseAddress) + BytesToAlign);
14862 +       PhysicalBaseAddress.LowPart = (ULONG)((PUCHAR)(PhysicalBaseAddress.LowPart) + BytesToAlign);
14863 +
14864 +       //
14865 +       // Fill in addresses of the Comm Area Headers and Queues
14866 +       //
14867 +       *CommHeaderAddress = BaseAddress;
14868 +       InitStruct->CommHeaderAddress = (PVOID)PhysicalBaseAddress.LowPart;
14869 +
14870 +       //
14871 +       //      Increment the base address by the size of the CommArea
14872 +       //
14873 +       BaseAddress = (PVOID)((PUCHAR)(BaseAddress) + CommAreaSize);
14874 +       PhysicalBaseAddress.LowPart = (ULONG)((PUCHAR)(PhysicalBaseAddress.LowPart) + CommAreaSize);
14875 +
14876 +
14877 +       //
14878 +       // Place the Printf buffer area after the Fast I/O comm area.
14879 +       //
14880 +       CommonExtension->PrintfBufferAddress = (PVOID)(BaseAddress);
14881 +       InitStruct->PrintfBufferAddress = (PVOID)PhysicalBaseAddress.LowPart;
14882 +       InitStruct->PrintfBufferSize = PrintfBufferSize;
14883 +       bzero (BaseAddress, PrintfBufferSize);
14884 +
14885 +       AfaPortPrint("FsaAllocateAdapterCommArea: allocated a common buffer of 0x%x bytes from address 0x%x to address 0x%x\n",
14886 +                        TotalSize, InitStruct->AdapterFibsVirtualAddress,
14887 +                        (PUCHAR)(InitStruct->AdapterFibsVirtualAddress) + TotalSize);
14888 +
14889 +       AfaPortPrint("Mapped on to PCI address 0x%x\n", InitStruct->AdapterFibsPhysicalAddress);
14890 +
14891 +       return (TRUE);
14892 +}
14893 +
14894 +AAC_STATUS
14895 +AfaPortCreate (
14896 +    IN PDEVICE_OBJECT DeviceObject,
14897 +    IN PIRP Irp
14898 +    )
14899 +/*++
14900 +
14901 +Routine Description:
14902 +
14903 +       The routine will get called each time a user issues a CreateFile on the DeviceObject
14904 +       for the adapter.
14905 +
14906 +       The main purpose of this routine is to set up any data structures that may be needed
14907 +       to handle any requests made on this DeviceObject.
14908 +
14909 +Arguments:
14910 +
14911 +       DeviceObject - Pointer to device object representing adapter
14912 +
14913 +       Irp - Pointer to Irp that caused this open
14914 +
14915 +
14916 +Return Value:
14917 +
14918 +       Status value returned from File system driver AdapterOpen
14919 +
14920 +--*/
14921 +
14922 +{
14923 +}
14924 +
14925 +AAC_STATUS
14926 +AfaPortClose (
14927 +    IN PDEVICE_OBJECT DeviceObject,
14928 +    IN PIRP Irp
14929 +    )
14930 +/*++
14931 +
14932 +Routine Description:
14933 +
14934 +       This routine will get called each time a user issues a CloseHandle on the DeviceObject
14935 +       for the adapter.
14936 +
14937 +       The main purpose of this routine is to cleanup any data structures that have been set up
14938 +       while this FileObject has been opened.
14939 +
14940 +Arguments:
14941 +
14942 +       DeviceObject - Pointer to device object representing adapter
14943 +
14944 +       Irp - Pointer to Irp that caused this close
14945 +
14946 +Return Value:
14947 +
14948 +       Status value returned from File system driver AdapterClose
14949 +
14950 +--*/
14951 +
14952 +{
14953 +
14954 +}
14955 +
14956 +AAC_STATUS
14957 +AfaPortDeviceControl (
14958 +    IN PDEVICE_OBJECT DeviceObject,
14959 +    IN PIRP Irp
14960 +    )
14961 +{
14962 +
14963 +}
14964 +
14965 +ULONG
14966 +AfaPortGetMaxPhysicalPage(
14967 +       IN PPCI_MINIPORT_COMMON_EXTENSION       CommonExtension
14968 +       )
14969 +/*++
14970 +
14971 +Routine Description:
14972 +
14973 +       This routine determines the max physical page in host memory.
14974 +
14975 +Arguments:
14976 +
14977 +       AdapterExtension
14978 +
14979 +Return Value:
14980 +
14981 +       Max physical page in host memory.
14982 +
14983 +--*/
14984 +{
14985 +
14986 +}
14987 +
14988 +
14989 diff -burN linux-2.4.9/drivers/scsi/aacraid/rx.c linux/drivers/scsi/aacraid/rx.c
14990 --- linux-2.4.9/drivers/scsi/aacraid/rx.c       Wed Dec 31 18:00:00 1969
14991 +++ linux/drivers/scsi/aacraid/rx.c     Thu Aug 16 13:41:30 2001
14992 @@ -0,0 +1,917 @@
14993 +/*++
14994 + * Adaptec aacraid device driver for Linux.
14995 + *
14996 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
14997 + *
14998 + * This program is free software; you can redistribute it and/or modify
14999 + * it under the terms of the GNU General Public License as published by
15000 + * the Free Software Foundation; either version 2, or (at your option)
15001 + * any later version.
15002 + *
15003 + * This program is distributed in the hope that it will be useful,
15004 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
15005 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15006 + * GNU General Public License for more details.
15007 + *
15008 + * You should have received a copy of the GNU General Public License
15009 + * along with this program; see the file COPYING.  If not, write to
15010 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
15011 + *
15012 + * Module Name:
15013 + *  rx.c
15014 + *
15015 + * Abstract: Hardware miniport for Drawbridge specific hardware functions.
15016 + *
15017 + --*/
15018 +
15019 +static char *ident_rx = "aacraid_ident rx.c 1.0.7 2000/10/11 Adaptec, Inc.";
15020 +
15021 +#include "osheaders.h"
15022 +
15023 +
15024 +#include "AacGenericTypes.h"
15025 +
15026 +#include "aac_unix_defs.h"
15027 +
15028 +#include "fsatypes.h"
15029 +#include "comstruc.h"
15030 +#include "fsact.h"
15031 +#include "protocol.h"
15032 +
15033 +#define DEFINE_PCI_IDS
15034 +#include "rxcommon.h"
15035 +#include "monkerapi.h"
15036 +
15037 +#include "fsaport.h"
15038 +#include "fsaioctl.h"
15039 +
15040 +#include "pcisup.h"
15041 +#include "rx.h"
15042 +
15043 +#include "port.h"
15044 +
15045 +#define BugCheckFileId                   (FSAFS_BUG_CHECK_CYCLONESUP)
15046 +
15047 +// #define RxBugCheck(A,B,C) { KeBugCheckEx(0x00000AFA, __LINE__, (ULONG)A, (ULONG)B,(ULONG)C ); }
15048 +
15049 +#define RxBugCheck(A, B, C) {  cmn_err(CE_PANIC, "aacdisk : line %s, 0x%x, 0x%x, 0x%x ", __LINE__, A, B, C);  }
15050 +
15051 +#define NUM_TICKS_PER_SECOND (1000 * 1000 * 10) /* time is in 100 nanoseconds */
15052 +
15053 +
15054 +//
15055 +// The list of all the Rx adapter structures
15056 +//
15057 +
15058 +PRx_ADAPTER_EXTENSION  RxAdapterList;
15059 +
15060 +int
15061 +RxInitDevice(
15062 +       IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
15063 +       IN ULONG AdapterNumber,
15064 +       IN ULONG PciBus,
15065 +       IN ULONG PciSlot
15066 +);
15067 +
15068 +BOOLEAN
15069 +RxSendSynchFib(
15070 +       PVOID Arg1,
15071 +       ULONG FibPhysicalAddress
15072 +       );
15073 +
15074 +FSA_USER_VAR   RxUserVars[] = {
15075 +       { "AfaPortPrinting", (PULONG)&AfaPortPrinting, NULL },
15076 +};
15077 +
15078 +
15079 +//
15080 +// Declare private use routines for this modual
15081 +//
15082 +
15083 +u_int
15084 +RxPciIsr (
15085 +    IN PRx_ADAPTER_EXTENSION AdapterExtension
15086 +    )
15087 +
15088 +/*++
15089 +
15090 +Routine Description:
15091 +
15092 +    The Isr routine for fsa Rx based adapter boards.
15093 +
15094 +Arguments:
15095 +
15096 +
15097 +Return Value:
15098 +
15099 +       TRUE - if the interrupt was handled by this isr
15100 +       FALSE - if the interrupt was not handled by this isr
15101 +
15102 +--*/
15103 +
15104 +{
15105 +       ULONG   DoorbellBits;
15106 +       UCHAR   InterruptStatus, Mask;
15107 +       u_int OurInterrupt = INTR_UNCLAIMED;
15108 +
15109 +       //cmn_err(CE_WARN, "RxPciIsr entered\n");
15110 +
15111 +       InterruptStatus = Rx_READ_UCHAR(AdapterExtension, MUnit.OISR);
15112 +
15113 +       //
15114 +       // Read mask and invert because drawbridge is reversed.
15115 +       //
15116 +       // This allows us to only service interrupts that have been enabled.
15117 +       //
15118 +
15119 +       Mask = ~(Rx_READ_UCHAR(AdapterExtension, MUnit.OIMR));
15120 +
15121 +       // Check to see if this is our interrupt.  If it isn't just return FALSE.
15122 +
15123 +
15124 +       if (InterruptStatus & Mask) {
15125 +
15126 +               DoorbellBits = Rx_READ_ULONG(AdapterExtension, OutboundDoorbellReg);
15127 +
15128 +               OurInterrupt = INTR_CLAIMED;
15129 +
15130 +               if (DoorbellBits & DoorBellPrintfReady) {
15131 +
15132 +                       ULONG Length, Level;
15133 +                       unsigned char *cp;
15134 +
15135 +                       cp = AdapterExtension->Common->PrintfBufferAddress;
15136 +
15137 +                       //
15138 +                       // The size of the Printfbuffer is set in port.c
15139 +                       // There is no variable or define for it
15140 +                       //
15141 +                       if (Length > 255)
15142 +                               Length = 255;
15143 +
15144 +                       if (cp[Length] != 0) {
15145 +                               // cmn_err (CE_NOTE, "byte %d is 0x%x, should be 0", Length, cp[Length]);
15146 +                               cp[Length] = 0;
15147 +                       }
15148 +
15149 +                       if (Level == LOG_HIGH_ERROR)
15150 +                               cmn_err (CE_WARN, "%s:%s", OsGetDeviceName(AdapterExtension), AdapterExtension->Common->PrintfBufferAddress);
15151 +                       else
15152 +                               cmn_err (CE_NOTE, "%s:%s", OsGetDeviceName(AdapterExtension), AdapterExtension->Common->PrintfBufferAddress);
15153 +
15154 +                       bzero (AdapterExtension->Common->PrintfBufferAddress, 256);
15155 +
15156 +                       Rx_WRITE_ULONG(AdapterExtension, MUnit.ODR,DoorBellPrintfReady); //clear PrintfReady
15157 +
15158 +                       Rx_WRITE_ULONG(AdapterExtension, InboundDoorbellReg,DoorBellPrintfDone);
15159 +
15160 +
15161 +               } else if (DoorbellBits & DoorBellAdapterNormCmdReady) {        // Adapter -> Host Normal Command Ready
15162 +
15163 +                       AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, HostNormCmdQue);
15164 +                       Rx_WRITE_ULONG(AdapterExtension, MUnit.ODR, DoorBellAdapterNormCmdReady);
15165 +
15166 +               } else if (DoorbellBits & DoorBellAdapterNormRespReady) {       // Adapter -> Host Normal Response Ready
15167 +
15168 +                       AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, HostNormRespQue);
15169 +                       Rx_WRITE_ULONG(AdapterExtension, MUnit.ODR,DoorBellAdapterNormRespReady);
15170 +
15171 +               } else if (DoorbellBits & DoorBellAdapterNormCmdNotFull) {      // Adapter -> Host Normal Command Not Full
15172 +
15173 +                       AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, AdapNormCmdNotFull);
15174 +                       Rx_WRITE_ULONG(AdapterExtension, MUnit.ODR, DoorBellAdapterNormCmdNotFull);
15175 +
15176 +               } else if (DoorbellBits & DoorBellAdapterNormRespNotFull) {     // Adapter -> Host Normal Response Not Full
15177 +
15178 +                       AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, AdapNormRespNotFull);
15179 +                       Rx_WRITE_ULONG(AdapterExtension, MUnit.ODR, DoorBellAdapterNormRespNotFull);
15180 +
15181 +               }
15182 +
15183 +       }
15184 +       return(OurInterrupt);
15185 +}
15186 +
15187 +VOID
15188 +RxEnableInterrupt(
15189 +       PVOID                                           Arg1,
15190 +       ADAPTER_EVENT                           AdapterEvent,
15191 +       BOOLEAN                                         AtDeviceIrq
15192 +       )
15193 +/*++
15194 +
15195 +Routine Description:
15196 +
15197 +       This routine will enable the corresponding adapter event to cause an interrupt on 
15198 +       the host.
15199 +
15200 +Arguments:
15201 +
15202 +       AdapterExtension - Which adapter to enable.
15203 +
15204 +       AdapterEvent - Which adapter event.
15205 +
15206 +       AtDeviceIrq - Whether the system is in DEVICE irql
15207 +
15208 +Return Value:
15209 +
15210 +    Nothing.
15211 +
15212 +--*/
15213 +{
15214 +       PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
15215 +       PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) CommonExtension->MiniPort;
15216 +
15217 +       //cmn_err(CE_WARN, "RxEnableInterrupt");
15218 +       switch (AdapterEvent) {
15219 +
15220 +         case HostNormCmdQue:
15221 +
15222 +               AdapterExtension->LocalMaskInterruptControl &= ~(OUTBOUNDDOORBELL_1);
15223 +
15224 +               break;
15225 +
15226 +         case HostNormRespQue:
15227 +
15228 +               AdapterExtension->LocalMaskInterruptControl &= ~(OUTBOUNDDOORBELL_2);
15229 +
15230 +               break;
15231 +
15232 +      case AdapNormCmdNotFull:
15233 +
15234 +               AdapterExtension->LocalMaskInterruptControl &= ~(OUTBOUNDDOORBELL_3);
15235 +
15236 +               break;
15237 +
15238 +      case AdapNormRespNotFull:
15239 +
15240 +               AdapterExtension->LocalMaskInterruptControl &= ~(OUTBOUNDDOORBELL_4);
15241 +
15242 +               break;
15243 +
15244 +       }
15245 +
15246 +}
15247 +
15248 +VOID
15249 +RxDisableInterrupt(
15250 +       PVOID                                           Arg1,
15251 +       ADAPTER_EVENT                           AdapterEvent,
15252 +       BOOLEAN                                         AtDeviceIrq
15253 +       )
15254 +/*++
15255 +
15256 +Routine Description:
15257 +
15258 +       This routine will disable the corresponding adapter event to cause an interrupt on 
15259 +       the host.
15260 +
15261 +Arguments:
15262 +
15263 +       AdapterExtension - Which adapter to enable.
15264 +
15265 +       AdapterEvent - Which adapter event.
15266 +
15267 +       AtDeviceIrq - Whether the system is in DEVICE irql
15268 +
15269 +Return Value:
15270 +
15271 +    Nothing.
15272 +
15273 +--*/
15274 +{
15275 +       PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
15276 +       PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) CommonExtension->MiniPort;
15277 +
15278 +       //cmn_err(CE_WARN, "RxEnableInterrupt");
15279 +
15280 +       switch (AdapterEvent) {
15281 +
15282 +
15283 +         case HostNormCmdQue:
15284 +
15285 +               AdapterExtension->LocalMaskInterruptControl |= (OUTBOUNDDOORBELL_1);
15286 +
15287 +               break;
15288 +
15289 +         case HostNormRespQue:
15290 +
15291 +               AdapterExtension->LocalMaskInterruptControl |= (OUTBOUNDDOORBELL_2);
15292 +
15293 +               break;
15294 +
15295 +      case AdapNormCmdNotFull:
15296 +
15297 +               AdapterExtension->LocalMaskInterruptControl |= (OUTBOUNDDOORBELL_3);
15298 +
15299 +               break;
15300 +
15301 +
15302 +      case AdapNormRespNotFull:
15303 +
15304 +               AdapterExtension->LocalMaskInterruptControl |= (OUTBOUNDDOORBELL_4);
15305 +
15306 +               break;
15307 +
15308 +       }
15309 +
15310 +}
15311 +
15312 +
15313 +
15314 +RxDetachDevice(
15315 +       IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension
15316 +       )
15317 +{
15318 +       PRx_ADAPTER_EXTENSION AdapterExtension = CommonExtension->MiniPort;
15319 +
15320 +       //
15321 +       // Free the register mapping.
15322 +       //
15323 +
15324 +       OsDetachDevice( AdapterExtension);
15325 +
15326 +       OsFreeMemory( AdapterExtension, sizeof(Rx_ADAPTER_EXTENSION) );
15327 +
15328 +}
15329 +
15330 +int
15331 +RxInitDevice(
15332 +       IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
15333 +       IN ULONG AdapterNumber,
15334 +       IN ULONG PciBus,
15335 +       IN ULONG PciSlot
15336 +)
15337 +
15338 +/*++
15339 +
15340 +Routine Description:
15341 +
15342 +       Scans the PCI bus looking for the Rx card. When found all resources for the
15343 +       device will be allocated and the interrupt vectors and csrs will be allocated and
15344 +       mapped.
15345 +
15346 +       The device_interface in the commregion will be allocated and linked to the comm region.
15347 +
15348 +Arguments:
15349 +
15350 +
15351 +Return Value:
15352 +
15353 +    TRUE - if the device was setup with not problems
15354 +    FALSE - if the device could not be mapped and init successfully
15355 +
15356 +--*/
15357 +
15358 +{
15359 +       AAC_STATUS Status;
15360 +       PRx_ADAPTER_EXTENSION AdapterExtension = NULL;
15361 +       FSA_NEW_ADAPTER NewAdapter;
15362 +       ULONG StartTime, EndTime, WaitTime;
15363 +       ULONG InitStatus;
15364 +       int instance;
15365 +       int nIntrs;
15366 +       char * name;
15367 +
15368 +    AfaPortPrint("In init device.\n");
15369 +
15370 +       //cmn_err(CE_WARN, "In RxInitDevice");
15371 +
15372 +//     AdapterExtension->Common->AdapterIndex = AdapterIndex;
15373 +       CommonExtension->AdapterNumber = AdapterNumber;
15374 +
15375 +
15376 +       CommonExtension->PciBusNumber = PciBus;
15377 +       CommonExtension->PciSlotNumber = PciSlot;
15378 +
15379 +
15380 +       AdapterExtension = OsAllocMemory( sizeof(Rx_ADAPTER_EXTENSION), OS_ALLOC_MEM_SLEEP );
15381 +       AdapterExtension->Common = CommonExtension;
15382 +       CommonExtension->MiniPort = AdapterExtension;
15383 +
15384 +       instance = OsGetDeviceInstance(AdapterExtension);
15385 +       name     = OsGetDeviceName(AdapterExtension);
15386 +       //
15387 +       // Map in the registers from the adapter, register space 0 is config space,
15388 +       // register space 1 is the memery space.
15389 +       //
15390 +
15391 +       if (OsMapDeviceRegisters(AdapterExtension)) {
15392 +
15393 +               cmn_err(CE_CONT, "%s%d: can't map device registers\n",
15394 +                               OsGetDeviceName(AdapterExtension), instance);
15395 +               return(FAILURE);
15396 +       }
15397 +
15398 +       //
15399 +       // Check to see if the board failed any self tests.
15400 +       //
15401 +
15402 +       if (Rx_READ_ULONG( AdapterExtension, IndexRegs.Mailbox[7]) & SELF_TEST_FAILED) {
15403 +
15404 +               cmn_err(CE_CONT, "%s%d: adapter self-test failed\n",
15405 +                               OsGetDeviceName(AdapterExtension), instance);
15406 +               return(FAILURE);
15407 +
15408 +       }
15409 +       //cmn_err(CE_WARN, "RxInitDevice: %s%d: adapter passwd self-test\n",
15410 +       //                      OsGetDeviceName(AdapterExtension), instance);
15411 +
15412 +       //
15413 +       // Check to see if the board panic'd while booting.
15414 +       //
15415 +
15416 +       if (Rx_READ_ULONG( AdapterExtension, IndexRegs.Mailbox[7]) & KERNEL_PANIC) {
15417 +
15418 +               cmn_err(CE_CONT, "%s%d: adapter kernel panic'd\n",
15419 +                               OsGetDeviceName(AdapterExtension), instance);
15420 +               return(FAILURE);
15421 +
15422 +       }
15423 +
15424 +       StartTime = OsGetSeconds();
15425 +       WaitTime = 0;
15426 +
15427 +
15428 +       //
15429 +       //  Wait for the adapter to be up and running. Wait up until 3 minutes.
15430 +       //
15431 +
15432 +       while (!(Rx_READ_ULONG( AdapterExtension, IndexRegs.Mailbox[7]) & KERNEL_UP_AND_RUNNING)) {
15433 +       
15434 +               EndTime = OsGetSeconds();
15435 +
15436 +               WaitTime = EndTime - StartTime;
15437 +
15438 +               if ( WaitTime > (3 * 10) ) {
15439 +
15440 +                       InitStatus = Rx_READ_ULONG( AdapterExtension, IndexRegs.Mailbox[7]) >> 16;
15441 +
15442 +                       cmn_err(CE_CONT, "%s%d: adapter kernel failed to start, init status = %d\n",
15443 +                                       OsGetDeviceName(AdapterExtension), instance, InitStatus);
15444 +                       return(FAILURE);
15445 +
15446 +               }
15447 +       }
15448 +
15449 +       if (OsAttachInterrupt(AdapterExtension,RxISR)) {
15450 +               cmn_err(CE_WARN, "%s%d RxInitDevice: failed OsAttachIntterupt", name, instance);
15451 +               return(FAILURE);
15452 +       }
15453 +
15454 +
15455 +       if (OsAttachDMA(AdapterExtension)) {
15456 +               cmn_err(CE_WARN, "%s%d SaInitDevice: failed OsAttachDMA", name, instance);
15457 +               return(FAILURE);
15458 +       }
15459 +
15460 +       //
15461 +       // Fill in the function dispatch table.
15462 +       //
15463 +
15464 +       AdapterExtension->Common->AdapterFuncs.SizeOfFsaPortFuncs = sizeof(FSAPORT_FUNCS);
15465 +       AdapterExtension->Common->AdapterFuncs.AllocateAdapterCommArea = AfaPortAllocateAdapterCommArea;
15466 +       AdapterExtension->Common->AdapterFuncs.FreeAdapterCommArea = AfaPortFreeAdapterCommArea;
15467 +       AdapterExtension->Common->AdapterFuncs.BuildSgMap = AfaPortBuildSgMap;
15468 +       AdapterExtension->Common->AdapterFuncs.FreeDmaResources = AfaPortFreeDmaResources;
15469 +       AdapterExtension->Common->AdapterFuncs.AllocateAndMapFibSpace = AfaPortAllocateAndMapFibSpace;
15470 +       AdapterExtension->Common->AdapterFuncs.UnmapAndFreeFibSpace = AfaPortUnmapAndFreeFibSpace;
15471 +       AdapterExtension->Common->AdapterFuncs.InterruptAdapter = RxInterruptAdapter;
15472 +       AdapterExtension->Common->AdapterFuncs.EnableInterrupt = RxEnableInterrupt;
15473 +       AdapterExtension->Common->AdapterFuncs.DisableInterrupt = RxDisableInterrupt;
15474 +       AdapterExtension->Common->AdapterFuncs.NotifyAdapter = RxNotifyAdapter;
15475 +       AdapterExtension->Common->AdapterFuncs.ResetDevice = RxResetDevice;
15476 +       AdapterExtension->Common->AdapterFuncs.InterruptHost = NULL;
15477 +
15478 +       AdapterExtension->Common->AdapterFuncs.SendSynchFib = RxSendSynchFib;
15479 +
15480 +       NewAdapter.AdapterExtension = CommonExtension;
15481 +       NewAdapter.AdapterFuncs = &AdapterExtension->Common->AdapterFuncs;
15482 +       NewAdapter.AdapterInterruptsBelowDpc = FALSE;
15483 +       NewAdapter.AdapterUserVars = RxUserVars;
15484 +       NewAdapter.AdapterUserVarsSize = sizeof(RxUserVars) / sizeof(FSA_USER_VAR);
15485 +
15486 +       NewAdapter.Dip = CommonExtension->OsDep.dip;
15487 +
15488 +       
15489 +       if (AfaCommInitNewAdapter( &NewAdapter ) == NULL) {
15490 +               
15491 +               cmn_err(CE_WARN, "AfaCommInitNewAdapter failed\n");
15492 +               return (FAILURE);
15493 +       }
15494 +
15495 +
15496 +       AdapterExtension->Common->Adapter = NewAdapter.Adapter;
15497 +
15498 +       if (AdapterExtension->Common->Adapter == NULL) {
15499 +
15500 +               AfaPortLogError(AdapterExtension->Common, FAILURE, NULL, 0);
15501 +               cmn_err(CE_WARN, "%s%d RxInitDevice: No Adapter pointer", name, instance);
15502 +
15503 +
15504 +               return (FAILURE);
15505 +       }
15506 +
15507 +
15508 +       //
15509 +       // Start any kernel threads needed
15510 +       //
15511 +       OsStartKernelThreads(AdapterExtension);
15512 +
15513 +       //
15514 +       // Tell the adapter that all is configure, and it can start accepting requests
15515 +       //
15516 +
15517 +       RxStartAdapter(AdapterExtension);
15518 +
15519 +
15520 +#ifdef AACDISK
15521 +#endif
15522 +
15523 +
15524 +       //
15525 +       // Put this adapter into the list of Rx adapters
15526 +       //
15527 +
15528 +       AdapterExtension->Next = RxAdapterList;
15529 +       RxAdapterList = AdapterExtension;
15530 +
15531 +       AdapterExtension->Common->AdapterConfigured = TRUE;
15532 +
15533 +
15534 +#ifdef AACDISK
15535 +       //
15536 +       // Call the disk layer to initialize itself.
15537 +       //
15538 +
15539 +       AfaDiskInitNewAdapter( AdapterExtension->Common->AdapterNumber, AdapterExtension->Common->Adapter );
15540 +#endif
15541 +
15542 +
15543 +init_done:
15544 +
15545 +       AdapterExtension->Common->AdapterPrintfsToScreen = FALSE;
15546 +
15547 +
15548 +
15549 +       OsAttachHBA(AdapterExtension);
15550 +
15551 +    return(0);
15552 +}
15553 +
15554 +VOID
15555 +RxStartAdapter(
15556 +       PRx_ADAPTER_EXTENSION AdapterExtension
15557 +       )
15558 +{
15559 +       ULONG ReturnStatus;
15560 +       LARGE_INTEGER HostTime;
15561 +       ULONG ElapsedSeconds;
15562 +       PADAPTER_INIT_STRUCT InitStruct;
15563 +
15564 +       //cmn_err(CE_WARN, "RxStartAdapter");
15565 +       //
15566 +       // Fill in the remaining pieces of the InitStruct.
15567 +       //
15568 +
15569 +       InitStruct = AdapterExtension->Common->InitStruct;
15570 +
15571 +       InitStruct->HostPhysMemPages = AfaPortGetMaxPhysicalPage(AdapterExtension->Common);
15572 +
15573 +       ElapsedSeconds = OsGetSeconds();
15574 +
15575 +       InitStruct->HostElapsedSeconds = ElapsedSeconds;
15576 +
15577 +       //
15578 +       // Tell the adapter we are back and up and running so it will scan its command
15579 +       // queues and enable our interrupts
15580 +       //
15581 +
15582 +       AdapterExtension->LocalMaskInterruptControl =
15583 +               (DoorBellPrintfReady | OUTBOUNDDOORBELL_1 | OUTBOUNDDOORBELL_2 | OUTBOUNDDOORBELL_3 | OUTBOUNDDOORBELL_4);
15584 +
15585 +       //
15586 +       // First clear out all interrupts.  Then enable the one's that we can handle.
15587 +       //
15588 +
15589 +       Rx_WRITE_UCHAR( AdapterExtension, MUnit.OIMR, 0xff);
15590 +       Rx_WRITE_ULONG( AdapterExtension, MUnit.ODR, 0xffffffff);
15591 +//     Rx_WRITE_UCHAR(AdapterExtension, MUnit.OIMR, ~(UCHAR)OUTBOUND_DOORBELL_INTERRUPT_MASK);
15592 +       Rx_WRITE_UCHAR( AdapterExtension, MUnit.OIMR, 0xfb);
15593 +
15594 +       RxSendSynchCommand(AdapterExtension, 
15595 +                                        INIT_STRUCT_BASE_ADDRESS, 
15596 +                                        (ULONG) AdapterExtension->Common->PhysicalInitStruct,
15597 +                                        0,
15598 +                                        0,
15599 +                                        0,
15600 +                                        &ReturnStatus);
15601 +
15602 +}
15603 +
15604 +
15605 +VOID
15606 +RxResetDevice(
15607 +       PVOID Arg1
15608 +    )
15609 +
15610 +{
15611 +}
15612 +
15613 +VOID
15614 +RxInterruptAdapter(
15615 +       PVOID Arg1
15616 +       )
15617 +/*++
15618 +
15619 +Routine Description:
15620 +
15621 +       The will cause the adapter to take a break point.
15622 +
15623 +Arguments:
15624 +
15625 +       None
15626 +
15627 +Return Value:
15628 +
15629 +    Nothing
15630 +
15631 +--*/
15632 +{
15633 +       PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
15634 +       PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) CommonExtension->MiniPort;
15635 +
15636 +       ULONG ReturnStatus;
15637 +
15638 +       RxSendSynchCommand(AdapterExtension, 
15639 +                                          BREAKPOINT_REQUEST,
15640 +                                          0,
15641 +                                          0,
15642 +                                          0,
15643 +                                          0,
15644 +                                          &ReturnStatus);
15645 +
15646 +}
15647 +
15648 +VOID
15649 +RxNotifyAdapter(
15650 +       PVOID Arg1,
15651 +    IN HOST_2_ADAP_EVENT AdapterEvent
15652 +    )
15653 +/*++
15654 +
15655 +Routine Description:
15656 +
15657 +    Will read the adapter CSRs to find the reason the adapter has
15658 +    interrupted us.
15659 +
15660 +Arguments:
15661 +
15662 +    AdapterEvent - Enumerated type the returns the reason why we were interrutped.
15663 +
15664 +Return Value:
15665 +
15666 +    Nothing
15667 +
15668 +--*/
15669 +{
15670 +       PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
15671 +       PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) CommonExtension->MiniPort;
15672 +       ULONG ReturnStatus;
15673 +
15674 +       //cmn_err(CE_WARN, "RxNotifyAdapter %d", AdapterEvent);
15675 +
15676 +    switch (AdapterEvent) {
15677 +        case AdapNormCmdQue:
15678 +
15679 +                       Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_1);
15680 +            break;
15681 +
15682 +        case HostNormRespNotFull:
15683 +
15684 +                       Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_4);
15685 +            break;
15686 +
15687 +        case AdapNormRespQue:
15688 +
15689 +                       Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_2);
15690 +            break;
15691 +
15692 +        case HostNormCmdNotFull:
15693 +
15694 +                       Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_3);
15695 +            break;
15696 +
15697 +        case HostShutdown:
15698 +
15699 +//                     RxSendSynchCommand(AdapterExtension, HOST_CRASHING, 0, 0, 0, 0, &ReturnStatus);
15700 +
15701 +            break;
15702 +
15703 +               case FastIo:
15704 +                       Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_6);
15705 +                       break;
15706 +
15707 +               case AdapPrintfDone:
15708 +                       Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_5);
15709 +                       break;
15710 +
15711 +        default:
15712 +
15713 +                       RxBugCheck(0,0,0);
15714 +            AfaPortPrint("Notify requested with an invalid request 0x%x.\n",AdapterEvent);
15715 +            break;
15716 +    }
15717 +}
15718 +
15719 +AAC_STATUS
15720 +RxSendSynchCommand(
15721 +       PVOID Arg1,
15722 +       ULONG Command,
15723 +       ULONG Parameter1,
15724 +       ULONG Parameter2,
15725 +       ULONG Parameter3,
15726 +       ULONG Parameter4,
15727 +       PULONG  ReturnStatus
15728 +       )
15729 +/*++
15730 +
15731 +Routine Description:
15732 +
15733 +       This routine will send a synchronous comamnd to the adapter and wait for its
15734 +       completion.
15735 +
15736 +Arguments:
15737 +
15738 +       AdapterExtension - Pointer to adapter extension structure.
15739 +       Command - Which command to send
15740 +       Parameter1 - 4  - Parameters for command
15741 +       ReturnStatus - return status from adapter after completion of command
15742 +
15743 +
15744 +Return Value:
15745 +
15746 +       AAC_STATUS
15747 +
15748 +--*/
15749 +{
15750 +       PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) Arg1;
15751 +       ULONG StartTime,EndTime,WaitTime;
15752 +       BOOLEAN CommandSucceeded;
15753 +
15754 +       //cmn_err(CE_WARN, "RxSendSyncCommand");
15755 +       //
15756 +       // Write the Command into Mailbox 0
15757 +       //
15758 +
15759 +       Rx_WRITE_ULONG( AdapterExtension, InboundMailbox0, Command);
15760 +
15761 +       //
15762 +       // Write the parameters into Mailboxes 1 - 4
15763 +       //
15764 +
15765 +       Rx_WRITE_ULONG( AdapterExtension, InboundMailbox1, Parameter1);
15766 +       Rx_WRITE_ULONG( AdapterExtension, InboundMailbox2, Parameter2);
15767 +       Rx_WRITE_ULONG( AdapterExtension, InboundMailbox3, Parameter3);
15768 +       Rx_WRITE_ULONG( AdapterExtension, InboundMailbox4, Parameter4);
15769 +
15770 +       //
15771 +       // Clear the synch command doorbell to start on a clean slate.
15772 +       //
15773 +               
15774 +       Rx_WRITE_ULONG( AdapterExtension, OutboundDoorbellReg, OUTBOUNDDOORBELL_0);
15775 +
15776 +       //
15777 +       // disable doorbell interrupts
15778 +       //
15779 +
15780 +       Rx_WRITE_UCHAR( AdapterExtension, MUnit.OIMR, 
15781 +                                       Rx_READ_UCHAR(AdapterExtension, MUnit.OIMR) | 0x04);
15782 +
15783 +       //
15784 +       // force the completion of the mask register write before issuing the interrupt.
15785 +       //
15786 +
15787 +       Rx_READ_UCHAR ( AdapterExtension, MUnit.OIMR);
15788 +
15789 +       //
15790 +       // Signal that there is a new synch command
15791 +       //
15792 +
15793 +       Rx_WRITE_ULONG( AdapterExtension, InboundDoorbellReg, INBOUNDDOORBELL_0);
15794 +
15795 +       CommandSucceeded = FALSE;
15796 +
15797 +       StartTime = OsGetSeconds();
15798 +       WaitTime = 0;
15799 +
15800 +       while (WaitTime < 30) { // wait up to 30 seconds
15801 +
15802 +               drv_usecwait(5);                                // delay 5 microseconds to let Mon960 get info.
15803 +
15804 +               //
15805 +               // Mon110 will set doorbell0 bit when it has completed the command.
15806 +               //
15807 +
15808 +               if (Rx_READ_ULONG(AdapterExtension, OutboundDoorbellReg) & OUTBOUNDDOORBELL_0) {
15809 +
15810 +                       //
15811 +                       // clear the doorbell.
15812 +                       //
15813 +
15814 +                       Rx_WRITE_ULONG(AdapterExtension, OutboundDoorbellReg, OUTBOUNDDOORBELL_0);
15815 +
15816 +                       CommandSucceeded = TRUE;
15817 +                       break;
15818 +               }
15819 +
15820 +               EndTime = OsGetSeconds();
15821 +               WaitTime = EndTime - StartTime;
15822 +
15823 +       }
15824 +
15825 +       if (CommandSucceeded != TRUE) {
15826 +
15827 +               //
15828 +               // restore interrupt mask even though we timed out
15829 +               //
15830 +
15831 +               Rx_WRITE_UCHAR(AdapterExtension, MUnit.OIMR, 
15832 +                                          Rx_READ_ULONG(AdapterExtension, MUnit.OIMR) & 0xfb);
15833 +
15834 +               return (STATUS_IO_TIMEOUT);
15835 +
15836 +       }
15837 +
15838 +       //
15839 +       // Pull the synch status from Mailbox 0.
15840 +       //
15841 +
15842 +       *ReturnStatus = Rx_READ_ULONG(AdapterExtension, IndexRegs.Mailbox[0]);
15843 +
15844 +       //
15845 +       // Clear the synch command doorbell.
15846 +       //
15847 +               
15848 +       Rx_WRITE_ULONG(AdapterExtension, OutboundDoorbellReg, OUTBOUNDDOORBELL_0);
15849 +
15850 +       //
15851 +       // restore interrupt mask
15852 +       //
15853 +
15854 +       Rx_WRITE_UCHAR(AdapterExtension, MUnit.OIMR, 
15855 +                                  Rx_READ_ULONG(AdapterExtension, MUnit.OIMR) & 0xfb);
15856 +
15857 +       //
15858 +       // Return SUCCESS
15859 +       //
15860 +
15861 +       return (STATUS_SUCCESS);
15862 +
15863 +}
15864 +
15865 +BOOLEAN
15866 +RxSendSynchFib(
15867 +       PVOID Arg1,
15868 +       ULONG FibPhysicalAddress
15869 +       )
15870 +/*++
15871 +
15872 +Routine Description:
15873 +
15874 +       This routine will send a synchronous fib to the adapter and wait for its
15875 +       completion.
15876 +
15877 +Arguments:
15878 +
15879 +       AdapterExtension - Pointer to adapter extension structure.
15880 +       FibPhysicalAddress - Physical address of fib to send.
15881 +
15882 +
15883 +Return Value:
15884 +
15885 +       BOOLEAN
15886 +
15887 +--*/
15888 +{
15889 +       PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
15890 +       PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) CommonExtension->MiniPort;
15891 +       ULONG returnStatus;
15892 +
15893 +       if (RxSendSynchCommand( AdapterExtension,
15894 +                                                   SEND_SYNCHRONOUS_FIB,
15895 +                                                   FibPhysicalAddress,
15896 +                                                   0,
15897 +                                                   0,
15898 +                                                   0,
15899 +                                                   &returnStatus ) != STATUS_SUCCESS ) {
15900 +
15901 +               return (FALSE);
15902 +               
15903 +       }
15904 +       
15905 +       return (TRUE);
15906 +                                                                               
15907 +}
15908 +
15909 +
15910 diff -burN linux-2.4.9/drivers/scsi/aacraid/sap1sup.c linux/drivers/scsi/aacraid/sap1sup.c
15911 --- linux-2.4.9/drivers/scsi/aacraid/sap1sup.c  Wed Dec 31 18:00:00 1969
15912 +++ linux/drivers/scsi/aacraid/sap1sup.c        Thu Aug 16 13:41:30 2001
15913 @@ -0,0 +1,859 @@
15914 +/*++
15915 + * Adaptec aacraid device driver for Linux.
15916 + *
15917 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
15918 + *
15919 + * This program is free software; you can redistribute it and/or modify
15920 + * it under the terms of the GNU General Public License as published by
15921 + * the Free Software Foundation; either version 2, or (at your option)
15922 + * any later version.
15923 + *
15924 + * This program is distributed in the hope that it will be useful,
15925 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
15926 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15927 + * GNU General Public License for more details.
15928 + *
15929 + * You should have received a copy of the GNU General Public License
15930 + * along with this program; see the file COPYING.  If not, write to
15931 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
15932 + *
15933 + * Module Name:
15934 + *  sap1sup.c
15935 + *
15936 + * Abstract: Drawbridge specific support functions
15937 + *
15938 + --*/
15939 +
15940 +static char *ident_sap1 = "aacraid_ident sap1sup.c 1.0.7 2000/10/11 Adaptec, Inc.";
15941 +
15942 +#include "osheaders.h"
15943 +
15944 +
15945 +#include "AacGenericTypes.h"
15946 +
15947 +#include "aac_unix_defs.h"
15948 +
15949 +#include "fsatypes.h"
15950 +#include "comstruc.h"
15951 +#include "fsact.h"
15952 +#include "protocol.h"
15953 +
15954 +#define DEFINE_PCI_IDS
15955 +#include "sap1common.h"
15956 +#include "monkerapi.h"
15957 +
15958 +#include "fsaport.h"
15959 +#include "fsaioctl.h"
15960 +
15961 +
15962 +#include "pcisup.h"
15963 +#include "sap1.h"
15964 +
15965 +#include "port.h"
15966 +
15967 +#include "nodetype.h"
15968 +#include "comsup.h"
15969 +#include "afacomm.h"
15970 +#include "adapter.h"
15971 +
15972 +#define BugCheckFileId                   (FSAFS_BUG_CHECK_CYCLONESUP)
15973 +
15974 +// #define SaBugCheck(A,B,C) { KeBugCheckEx(0x00000AFA, __LINE__, (ULONG)A, (ULONG)B,(ULONG)C ); }
15975 +
15976 +#define SaBugCheck(A, B, C) {  cmn_err(CE_PANIC, "aacdisk : line %s, 0x%x, 0x%x, 0x%x ", __LINE__, A, B, C);  }
15977 +
15978 +#define NUM_TICKS_PER_SECOND (1000 * 1000 * 10) /* time is in 100 nanoseconds */
15979 +
15980 +int MiniPortRevision = Sa_MINIPORT_REVISION;
15981 +
15982 +
15983 +//
15984 +// The list of all the Sa adapter structures
15985 +//
15986 +
15987 +PSa_ADAPTER_EXTENSION  SaAdapterList;
15988 +
15989 +int
15990 +SaInitDevice(
15991 +       IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
15992 +       IN ULONG AdapterNumber,
15993 +       IN ULONG PciBus,
15994 +       IN ULONG PciSlot
15995 +);
15996 +
15997 +BOOLEAN
15998 +SaSendSynchFib(
15999 +       PVOID Arg1,
16000 +       ULONG FibPhysicalAddress
16001 +       );
16002 +
16003 +FSA_USER_VAR   SaUserVars[] = {
16004 +       { "AfaPortPrinting", (PULONG)&AfaPortPrinting, NULL },
16005 +};
16006 +
16007 +
16008 +//
16009 +// Declare private use routines for this modual
16010 +//
16011 +
16012 +
16013 +/*++
16014 +
16015 +Routine Description:
16016 +
16017 +    The Isr routine for fsa Sa based adapter boards.
16018 +
16019 +Arguments:
16020 +
16021 +
16022 +Return Value:
16023 +
16024 +       TRUE - if the interrupt was handled by this isr
16025 +       FALSE - if the interrupt was not handled by this isr
16026 +
16027 +--*/
16028 +u_int
16029 +SaPciIsr (IN PSa_ADAPTER_EXTENSION AdapterExtension)
16030 +{
16031 +               USHORT InterruptStatus, Mask;
16032 +               u_int OurInterrupt = INTR_UNCLAIMED;
16033 +
16034 +       InterruptStatus = Sa_READ_USHORT( AdapterExtension, DoorbellReg_p);
16035 +
16036 +       //
16037 +       // Read mask and invert because drawbridge is reversed.
16038 +       //
16039 +       // This allows us to only service interrupts that have been enabled.
16040 +       //
16041 +
16042 +       Mask = ~(Sa_READ_USHORT( AdapterExtension, SaDbCSR.PRISETIRQMASK));
16043 +
16044 +       // Check to see if this is our interrupt.  If it isn't just return FALSE.
16045 +
16046 +
16047 +       if (InterruptStatus & Mask) {
16048 +
16049 +               OurInterrupt = INTR_CLAIMED;
16050 +
16051 +               if (InterruptStatus & PrintfReady) {
16052 +
16053 +                       ULONG Length, Level;
16054 +                       unsigned char *cp;
16055 +
16056 +                       cp = AdapterExtension->Common->PrintfBufferAddress;
16057 +
16058 +                       //
16059 +                       // The size of the Printbuffer is set in port.c
16060 +                       // There is no variable or define for it
16061 +                       //
16062 +                       if (Length > 255)
16063 +                               Length = 255;
16064 +
16065 +                       if (cp[Length] != 0) {
16066 +                               // cmn_err (CE_NOTE, "byte %d is 0x%x, should be 0", Length, cp[Length]);
16067 +                               cp[Length] = 0;
16068 +                       }
16069 +
16070 +                       if (Level == LOG_HIGH_ERROR)
16071 +                               cmn_err (CE_WARN, "%s:%s", OsGetDeviceName(AdapterExtension), AdapterExtension->Common->PrintfBufferAddress);
16072 +                       else
16073 +                               cmn_err (CE_NOTE, "%s:%s", OsGetDeviceName(AdapterExtension), AdapterExtension->Common->PrintfBufferAddress);
16074 +
16075 +                       bzero (AdapterExtension->Common->PrintfBufferAddress, 256);
16076 +
16077 +                       Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p,PrintfReady); //clear PrintfReady
16078 +
16079 +                       Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,PrintfDone);
16080 +
16081 +               } else if (InterruptStatus & DOORBELL_1) {      // Adapter -> Host Normal Command Ready
16082 +
16083 +                       AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, HostNormCmdQue);
16084 +                       Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p, DOORBELL_1);
16085 +
16086 +               } else if (InterruptStatus & DOORBELL_2) {      // Adapter -> Host Normal Response Ready
16087 +
16088 +                               AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, HostNormRespQue);
16089 +                               Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p,DOORBELL_2);
16090 +
16091 +               } else if (InterruptStatus & DOORBELL_3) {      // Adapter -> Host Normal Command Not Full
16092 +
16093 +                       AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, AdapNormCmdNotFull);
16094 +                       Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p, DOORBELL_3);
16095 +
16096 +               } else if (InterruptStatus & DOORBELL_4) {      // Adapter -> Host Normal Response Not Full
16097 +
16098 +                       AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, AdapNormRespNotFull);
16099 +                       Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p, DOORBELL_4);
16100 +
16101 +               }
16102 +
16103 +       }
16104 +       return(OurInterrupt);
16105 +}
16106 +
16107 +
16108 +/*++
16109 +
16110 +Routine Description:
16111 +
16112 +       This routine will enable the corresponding adapter event to cause an interrupt on 
16113 +       the host.
16114 +
16115 +Arguments:
16116 +
16117 +       AdapterExtension - Which adapter to enable.
16118 +
16119 +       AdapterEvent - Which adapter event.
16120 +
16121 +       AtDeviceIrq - Whether the system is in DEVICE irql
16122 +
16123 +Return Value:
16124 +
16125 +    Nothing.
16126 +
16127 +--*/
16128 +VOID
16129 +SaEnableInterrupt (PVOID Arg1, ADAPTER_EVENT AdapterEvent, BOOLEAN AtDeviceIrq)
16130 +{
16131 +       PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
16132 +       PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) CommonExtension->MiniPort;
16133 +
16134 +       switch (AdapterEvent) {
16135 +
16136 +         case HostNormCmdQue:
16137 +
16138 +               Sa_WRITE_USHORT( AdapterExtension,  SaDbCSR.PRICLEARIRQMASK, DOORBELL_1 );
16139 +
16140 +               break;
16141 +
16142 +         case HostNormRespQue:
16143 +
16144 +               Sa_WRITE_USHORT( AdapterExtension,  SaDbCSR.PRICLEARIRQMASK, DOORBELL_2 );
16145 +
16146 +               break;
16147 +
16148 +      case AdapNormCmdNotFull:
16149 +
16150 +               Sa_WRITE_USHORT( AdapterExtension,  SaDbCSR.PRICLEARIRQMASK, DOORBELL_3 );
16151 +
16152 +               break;
16153 +
16154 +      case AdapNormRespNotFull:
16155 +
16156 +               Sa_WRITE_USHORT( AdapterExtension,  SaDbCSR.PRICLEARIRQMASK, DOORBELL_4 );
16157 +
16158 +               break;
16159 +
16160 +       }
16161 +
16162 +}
16163 +
16164 +
16165 +
16166 +/*++
16167 +
16168 +Routine Description:
16169 +
16170 +       This routine will disable the corresponding adapter event to cause an interrupt on 
16171 +       the host.
16172 +
16173 +Arguments:
16174 +
16175 +       AdapterExtension - Which adapter to enable.
16176 +
16177 +       AdapterEvent - Which adapter event.
16178 +
16179 +       AtDeviceIrq - Whether the system is in DEVICE irql
16180 +
16181 +Return Value:
16182 +
16183 +    Nothing.
16184 +
16185 +--*/
16186 +VOID
16187 +SaDisableInterrupt (PVOID Arg1,        ADAPTER_EVENT AdapterEvent, BOOLEAN AtDeviceIrq)
16188 +{
16189 +       PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
16190 +       PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) CommonExtension->MiniPort;
16191 +
16192 +       switch (AdapterEvent) {
16193 +
16194 +
16195 +         case HostNormCmdQue:
16196 +
16197 +               Sa_WRITE_USHORT( AdapterExtension,  SaDbCSR.PRISETIRQMASK, DOORBELL_1 );
16198 +
16199 +               break;
16200 +
16201 +         case HostNormRespQue:
16202 +
16203 +               Sa_WRITE_USHORT( AdapterExtension,  SaDbCSR.PRISETIRQMASK, DOORBELL_2 );
16204 +
16205 +               break;
16206 +
16207 +      case AdapNormCmdNotFull:
16208 +
16209 +               Sa_WRITE_USHORT( AdapterExtension,  SaDbCSR.PRISETIRQMASK, DOORBELL_3 );
16210 +
16211 +               break;
16212 +
16213 +
16214 +      case AdapNormRespNotFull:
16215 +
16216 +               Sa_WRITE_USHORT( AdapterExtension,  SaDbCSR.PRISETIRQMASK, DOORBELL_4 );
16217 +
16218 +               break;
16219 +
16220 +       }
16221 +
16222 +}
16223 +
16224 +
16225 +SaDetachDevice (IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension)
16226 +{
16227 +       PSa_ADAPTER_EXTENSION AdapterExtension = CommonExtension->MiniPort;
16228 +
16229 +       //
16230 +       // Free the register mapping.
16231 +       //
16232 +
16233 +       OsDetachDevice(AdapterExtension);
16234 +
16235 +       OsFreeMemory( AdapterExtension, sizeof(Sa_ADAPTER_EXTENSION) );
16236 +
16237 +}
16238 +
16239 +
16240 +/*++
16241 +
16242 +Routine Description:
16243 +
16244 +       Scans the PCI bus looking for the Sa card. When found all resources for the
16245 +       device will be allocated and the interrupt vectors and csrs will be allocated and
16246 +       mapped.
16247 +
16248 +       The device_interface in the commregion will be allocated and linked to the comm region.
16249 +
16250 +Arguments:
16251 +
16252 +
16253 +Return Value:
16254 +
16255 +    TRUE - if the device was setup with not problems
16256 +    FALSE - if the device could not be mapped and init successfully
16257 +
16258 +--*/
16259 +int
16260 +SaInitDevice (IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
16261 +                         IN ULONG AdapterNumber, IN ULONG PciBus,
16262 +                         IN ULONG PciSlot)
16263 +{
16264 +       AAC_STATUS Status;
16265 +       PSa_ADAPTER_EXTENSION AdapterExtension = NULL;
16266 +       FSA_NEW_ADAPTER NewAdapter;
16267 +       ULONG StartTime, EndTime, WaitTime;
16268 +       ULONG InitStatus;
16269 +       int instance;
16270 +       char *name;
16271 +
16272 +    AfaPortPrint("In init device.\n");
16273 +
16274 +       CommonExtension->AdapterNumber = AdapterNumber;
16275 +
16276 +       CommonExtension->PciBusNumber = PciBus;
16277 +       CommonExtension->PciSlotNumber = PciSlot;
16278 +
16279 +       AdapterExtension = OsAllocMemory( sizeof(Sa_ADAPTER_EXTENSION), OS_ALLOC_MEM_SLEEP );
16280 +       AdapterExtension->Common = CommonExtension;
16281 +       CommonExtension->MiniPort = AdapterExtension;
16282 +
16283 +       instance = OsGetDeviceInstance(AdapterExtension);
16284 +       name     = OsGetDeviceName(AdapterExtension);
16285 +
16286 +       //
16287 +       // Map in the registers from the adapter, register space 0 is config space,
16288 +       // register space 1 is the memery space.
16289 +       //
16290 +
16291 +       if (OsMapDeviceRegisters(AdapterExtension)){
16292 +               cmn_err(CE_WARN, "%s%d SaInitDevice: failed OsMapDeviceRegisters", name, instance);
16293 +               return(FAILURE);
16294 +       }
16295 +
16296 +
16297 +       //
16298 +       // Check to see if the board failed any self tests.
16299 +       //
16300 +
16301 +       if (Sa_READ_ULONG( AdapterExtension, Mailbox7) & SELF_TEST_FAILED) {
16302 +
16303 +               cmn_err(CE_WARN, "%s%d: adapter self-test failed\n",
16304 +                               name, instance);
16305 +               return(FAILURE);
16306 +       }
16307 +
16308 +       //
16309 +       // Check to see if the board panic'd while booting.
16310 +       //
16311 +
16312 +       if (Sa_READ_ULONG( AdapterExtension, Mailbox7) & KERNEL_PANIC) {
16313 +
16314 +               cmn_err(CE_WARN, "%s%d: adapter kernel panic'd\n",
16315 +                               name, instance);
16316 +               return(FAILURE);
16317 +       }
16318 +
16319 +
16320 +       StartTime = OsGetSeconds();
16321 +       WaitTime = 0;
16322 +
16323 +
16324 +       //
16325 +       //  Wait for the adapter to be up and running. Wait up until 3 minutes.
16326 +       //
16327 +
16328 +       while (!(Sa_READ_ULONG( AdapterExtension, Mailbox7) & KERNEL_UP_AND_RUNNING)) {
16329 +       
16330 +               EndTime = OsGetSeconds();
16331 +
16332 +               WaitTime = EndTime - StartTime;
16333 +
16334 +               if ( WaitTime > (3 * 60) ) {
16335 +
16336 +                       InitStatus = Sa_READ_ULONG( AdapterExtension, Mailbox7) >> 16;
16337 +
16338 +                       cmn_err(CE_WARN, "%s%d: adapter kernel failed to start, init status = %d\n",
16339 +                                       name, instance, InitStatus);
16340 +                       return(FAILURE);
16341 +
16342 +               }
16343 +       }
16344 +
16345 +       if (OsAttachInterrupt(AdapterExtension, SaISR)) {
16346 +               cmn_err(CE_WARN, "%s%d SaInitDevice: failed OsAttachIntterupt", name, instance);
16347 +               return(FAILURE);
16348 +       }
16349 +
16350 +       if (OsAttachDMA(AdapterExtension)) {
16351 +               cmn_err(CE_WARN, "%s%d SaInitDevice: failed OsAttachDMA", name, instance);
16352 +               return(FAILURE);
16353 +       }
16354 +
16355 +
16356 +       //
16357 +       // Fill in the function dispatch table.
16358 +       //
16359 +
16360 +       AdapterExtension->Common->AdapterFuncs.SizeOfFsaPortFuncs = sizeof(FSAPORT_FUNCS);
16361 +       AdapterExtension->Common->AdapterFuncs.AllocateAdapterCommArea = AfaPortAllocateAdapterCommArea;
16362 +       AdapterExtension->Common->AdapterFuncs.FreeAdapterCommArea = AfaPortFreeAdapterCommArea;
16363 +       AdapterExtension->Common->AdapterFuncs.BuildSgMap = AfaPortBuildSgMap;
16364 +       AdapterExtension->Common->AdapterFuncs.FreeDmaResources = AfaPortFreeDmaResources;
16365 +       AdapterExtension->Common->AdapterFuncs.AllocateAndMapFibSpace = AfaPortAllocateAndMapFibSpace;
16366 +       AdapterExtension->Common->AdapterFuncs.UnmapAndFreeFibSpace = AfaPortUnmapAndFreeFibSpace;
16367 +       AdapterExtension->Common->AdapterFuncs.InterruptAdapter = SaInterruptAdapter;
16368 +       AdapterExtension->Common->AdapterFuncs.EnableInterrupt = SaEnableInterrupt;
16369 +       AdapterExtension->Common->AdapterFuncs.DisableInterrupt = SaDisableInterrupt;
16370 +       AdapterExtension->Common->AdapterFuncs.NotifyAdapter = SaNotifyAdapter;
16371 +       AdapterExtension->Common->AdapterFuncs.ResetDevice = SaResetDevice;
16372 +       AdapterExtension->Common->AdapterFuncs.InterruptHost = NULL;
16373 +
16374 +       AdapterExtension->Common->AdapterFuncs.SendSynchFib = SaSendSynchFib;
16375 +
16376 +       NewAdapter.AdapterExtension = CommonExtension;
16377 +       NewAdapter.AdapterFuncs = &AdapterExtension->Common->AdapterFuncs;
16378 +       NewAdapter.AdapterInterruptsBelowDpc = FALSE;
16379 +       NewAdapter.AdapterUserVars = SaUserVars;
16380 +       NewAdapter.AdapterUserVarsSize = sizeof(SaUserVars) / sizeof(FSA_USER_VAR);
16381 +
16382 +       NewAdapter.Dip = CommonExtension->OsDep.dip;
16383 +
16384 +       
16385 +       if ( AfaCommInitNewAdapter( &NewAdapter ) == NULL) {
16386 +                       cmn_err(CE_WARN, "SaInitDevice: AfaCommInitNewAdapter failed\n");
16387 +                       return (FAILURE);
16388 +       };
16389 +
16390 +
16391 +       AdapterExtension->Common->Adapter = NewAdapter.Adapter;
16392 +
16393 +       if (AdapterExtension->Common->Adapter == NULL) {
16394 +
16395 +               AfaPortLogError(AdapterExtension->Common, FAILURE, NULL, 0);
16396 +               cmn_err(CE_WARN, "%s%d SaInitDevice: No Adapter pointer", name, instance);
16397 +
16398 +               return (FAILURE); 
16399 +       }
16400 +
16401 +
16402 +    //
16403 +       // Start any kernel threads needed
16404 +       OsStartKernelThreads(AdapterExtension);
16405 +
16406 +       //
16407 +       // Tell the adapter that all is configure, and it can start accepting requests
16408 +       //
16409 +
16410 +       SaStartAdapter(AdapterExtension);
16411 +
16412 +
16413 +
16414 +       //
16415 +       // Put this adapter into the list of Sa adapters
16416 +       //
16417 +
16418 +       AdapterExtension->Next = SaAdapterList;
16419 +       SaAdapterList = AdapterExtension;
16420 +
16421 +       AdapterExtension->Common->AdapterConfigured = TRUE;
16422 +
16423 +
16424 +#ifdef AACDISK
16425 +       //
16426 +       // Call the disk layer to initialize itself.
16427 +       //
16428 +
16429 +       AfaDiskInitNewAdapter( AdapterExtension->Common->AdapterNumber, AdapterExtension->Common->Adapter );
16430 +#endif
16431 +
16432 +
16433 +init_done:
16434 +
16435 +       AdapterExtension->Common->AdapterPrintfsToScreen = FALSE;
16436 +
16437 +       OsAttachHBA(AdapterExtension);
16438 +
16439 +       return (0);
16440 +
16441 +init_error:
16442 +
16443 +       return (FAILURE);
16444 +}
16445 +
16446 +
16447 +
16448 +VOID
16449 +SaStartAdapter (PSa_ADAPTER_EXTENSION AdapterExtension)
16450 +{
16451 +       ULONG ReturnStatus;
16452 +       LARGE_INTEGER HostTime;
16453 +       ULONG ElapsedSeconds;
16454 +       PADAPTER_INIT_STRUCT InitStruct;
16455 +
16456 +       //
16457 +       // Fill in the remaining pieces of the InitStruct.
16458 +       //
16459 +
16460 +       InitStruct = AdapterExtension->Common->InitStruct;
16461 +
16462 +       InitStruct->HostPhysMemPages = AfaPortGetMaxPhysicalPage(AdapterExtension->Common);
16463 +
16464 +       ElapsedSeconds = OsGetSeconds();
16465 +
16466 +       InitStruct->HostElapsedSeconds = ElapsedSeconds;
16467 +
16468 +       //
16469 +       // Tell the adapter we are back and up and running so it will scan its command
16470 +       // queues and enable our interrupts
16471 +       //
16472 +
16473 +       AdapterExtension->LocalMaskInterruptControl =
16474 +               (PrintfReady | DOORBELL_1 | DOORBELL_2 | DOORBELL_3 | DOORBELL_4);
16475 +
16476 +
16477 +       //
16478 +       // First clear out all interrupts.  Then enable the one's that we can handle.
16479 +       //
16480 +
16481 +       Sa_WRITE_USHORT( AdapterExtension,  SaDbCSR.PRISETIRQMASK, (USHORT) 0xffff );
16482 +       Sa_WRITE_USHORT( AdapterExtension,  SaDbCSR.PRICLEARIRQMASK,
16483 +                                       (PrintfReady | DOORBELL_1 | DOORBELL_2 | DOORBELL_3 | DOORBELL_4) );
16484 +
16485 +       SaSendSynchCommand(AdapterExtension, 
16486 +                          INIT_STRUCT_BASE_ADDRESS, 
16487 +                          (ULONG) AdapterExtension->Common->PhysicalInitStruct,
16488 +                          0,
16489 +                          0,
16490 +                          0,
16491 +                          &ReturnStatus);
16492 +
16493 +}
16494 +
16495 +
16496 +VOID
16497 +SaResetDevice (PVOID Arg1){
16498 +
16499 +}
16500 +
16501 +
16502 +/*++
16503 +
16504 +Routine Description:
16505 +
16506 +       The will cause the adapter to take a break point.
16507 +
16508 +Arguments:
16509 +
16510 +       None
16511 +
16512 +Return Value:
16513 +
16514 +    Nothing
16515 +
16516 +--*/
16517 +VOID
16518 +SaInterruptAdapter (PVOID Arg1)
16519 +{
16520 +       PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
16521 +       PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) CommonExtension->MiniPort;
16522 +
16523 +       ULONG ReturnStatus;
16524 +
16525 +       SaSendSynchCommand(AdapterExtension, 
16526 +                          BREAKPOINT_REQUEST,
16527 +                          0,
16528 +                          0,
16529 +                          0,
16530 +                          0,
16531 +                          &ReturnStatus);
16532 +
16533 +}
16534 +
16535 +
16536 +/*++
16537 +
16538 +Routine Description:
16539 +
16540 +    Will read the adapter CSRs to find the reason the adapter has
16541 +    interrupted us.
16542 +
16543 +Arguments:
16544 +
16545 +    AdapterEvent - Enumerated type the returns the reason why we were interrutped.
16546 +
16547 +Return Value:
16548 +
16549 +    Nothing
16550 +
16551 +--*/
16552 +VOID
16553 +SaNotifyAdapter (PVOID Arg1, IN HOST_2_ADAP_EVENT AdapterEvent)
16554 +{
16555 +       PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
16556 +       PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) CommonExtension->MiniPort;
16557 +       ULONG ReturnStatus;
16558 +
16559 +    switch (AdapterEvent) {
16560 +        case AdapNormCmdQue:
16561 +
16562 +                       Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_1);
16563 +            break;
16564 +
16565 +        case HostNormRespNotFull:
16566 +
16567 +                       Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_4);
16568 +            break;
16569 +
16570 +        case AdapNormRespQue:
16571 +
16572 +                       Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_2);
16573 +            break;
16574 +
16575 +        case HostNormCmdNotFull:
16576 +
16577 +                       Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_3);
16578 +            break;
16579 +
16580 +        case HostShutdown:
16581 +
16582 +//                     SaSendSynchCommand(AdapterExtension, HOST_CRASHING, 0, 0, 0, 0, &ReturnStatus);
16583 +
16584 +            break;
16585 +
16586 +               case FastIo:
16587 +                       Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_6);
16588 +                       break;
16589 +
16590 +               case AdapPrintfDone:
16591 +                       Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_5);
16592 +                       break;
16593 +
16594 +        default:
16595 +
16596 +                       SaBugCheck(0,0,0);
16597 +            AfaPortPrint("Notify requested with an invalid request 0x%x.\n",AdapterEvent);
16598 +            break;
16599 +    }
16600 +}
16601 +
16602 +
16603 +/*++
16604 +
16605 +Routine Description:
16606 +
16607 +       This routine will send a synchronous comamnd to the adapter and wait for its
16608 +       completion.
16609 +
16610 +Arguments:
16611 +
16612 +       AdapterExtension - Pointer to adapter extension structure.
16613 +       Command - Which command to send
16614 +       Parameter1 - 4  - Parameters for command
16615 +       ReturnStatus - return status from adapter after completion of command
16616 +
16617 +
16618 +Return Value:
16619 +
16620 +       AAC_STATUS
16621 +
16622 +--*/
16623 +AAC_STATUS
16624 +SaSendSynchCommand(
16625 +                  PVOID Arg1,
16626 +                  ULONG Command,
16627 +                  ULONG Parameter1,
16628 +                  ULONG Parameter2,
16629 +                  ULONG Parameter3,
16630 +                  ULONG Parameter4,
16631 +                  PULONG       ReturnStatus
16632 +       )
16633 +{
16634 +       PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) Arg1;
16635 +       ULONG StartTime,EndTime,WaitTime;
16636 +       BOOLEAN CommandSucceeded;
16637 +
16638 +       //
16639 +       // Write the Command into Mailbox 0
16640 +       //
16641 +
16642 +       Sa_WRITE_ULONG( AdapterExtension, Mailbox0, Command);
16643 +
16644 +       //
16645 +       // Write the parameters into Mailboxes 1 - 4
16646 +       //
16647 +
16648 +       Sa_WRITE_ULONG( AdapterExtension, Mailbox1, Parameter1);
16649 +       Sa_WRITE_ULONG( AdapterExtension, Mailbox2, Parameter2);
16650 +       Sa_WRITE_ULONG( AdapterExtension, Mailbox3, Parameter3);
16651 +       Sa_WRITE_ULONG( AdapterExtension, Mailbox4, Parameter4);
16652 +
16653 +       //
16654 +       // Clear the synch command doorbell to start on a clean slate.
16655 +       //
16656 +               
16657 +       Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p, DOORBELL_0);
16658 +
16659 +       //
16660 +       // Signal that there is a new synch command
16661 +       //
16662 +
16663 +       Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s, DOORBELL_0);
16664 +
16665 +       CommandSucceeded = FALSE;
16666 +
16667 +       StartTime = OsGetSeconds();
16668 +       WaitTime = 0;
16669 +
16670 +       while (WaitTime < 30) { // wait up to 30 seconds
16671 +
16672 +               drv_usecwait(5);                                // delay 5 microseconds to let Mon960 get info.
16673 +
16674 +               //
16675 +               // Mon110 will set doorbell0 bit when it has completed the command.
16676 +               //
16677 +
16678 +               if( Sa_READ_USHORT( AdapterExtension, DoorbellReg_p) & DOORBELL_0 )  {
16679 +
16680 +                       CommandSucceeded = TRUE;
16681 +                       break;
16682 +               }
16683 +
16684 +               EndTime = OsGetSeconds();
16685 +               WaitTime = EndTime - StartTime;
16686 +
16687 +       }
16688 +
16689 +       if (CommandSucceeded != TRUE) {
16690 +
16691 +               return (STATUS_IO_TIMEOUT);
16692 +
16693 +       }
16694 +
16695 +       //
16696 +       // Clear the synch command doorbell.
16697 +       //
16698 +               
16699 +       Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p, DOORBELL_0);
16700 +
16701 +       //
16702 +       // Pull the synch status from Mailbox 0.
16703 +       //
16704 +
16705 +       *ReturnStatus = Sa_READ_ULONG( AdapterExtension, Mailbox0);
16706 +
16707 +       //
16708 +       // Return SUCCESS
16709 +       //
16710 +
16711 +       return (STATUS_SUCCESS);
16712 +
16713 +}
16714 +
16715 +
16716 +/*++
16717 +
16718 +Routine Description:
16719 +
16720 +       This routine will send a synchronous fib to the adapter and wait for its
16721 +       completion.
16722 +
16723 +Arguments:
16724 +
16725 +       AdapterExtension - Pointer to adapter extension structure.
16726 +       FibPhysicalAddress - Physical address of fib to send.
16727 +
16728 +
16729 +Return Value:
16730 +
16731 +       BOOLEAN
16732 +
16733 +--*/
16734 +BOOLEAN
16735 +SaSendSynchFib (PVOID Arg1, ULONG FibPhysicalAddress)
16736 +{
16737 +       PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
16738 +       PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) CommonExtension->MiniPort;
16739 +       ULONG returnStatus;
16740 +
16741 +       if (SaSendSynchCommand( AdapterExtension,
16742 +                                                   SEND_SYNCHRONOUS_FIB,
16743 +                                                   FibPhysicalAddress,
16744 +                                                   0,
16745 +                                                   0,
16746 +                                                   0,
16747 +                                                   &returnStatus ) != STATUS_SUCCESS ) {
16748 +
16749 +               return (FALSE);
16750 +               
16751 +       }
16752 +       
16753 +       return (TRUE);
16754 +                                                                               
16755 +}
16756 +
16757 +BOOLEAN
16758 +WriteFlash(
16759 +       PVOID AdapterExtension,
16760 +       ULONG *MappedBuffer)
16761 +{
16762 +       return (FALSE);
16763 +}
16764 +
16765 +BOOLEAN
16766 +ReadFlash(
16767 +       PVOID AdapterExtension,
16768 +       ULONG *MappedBuffer)
16769 +{
16770 +       return (FALSE);
16771 +}
16772 +
16773 diff -burN linux-2.4.9/drivers/scsi/scsi_scan.c linux/drivers/scsi/scsi_scan.c
16774 --- linux-2.4.9/drivers/scsi/scsi_scan.c        Thu Aug 16 13:40:31 2001
16775 +++ linux/drivers/scsi/scsi_scan.c      Thu Aug 16 18:10:10 2001
16776 @@ -160,6 +160,8 @@
16777         {"SONY", "TSL",       "*", BLIST_FORCELUN},  // DDS3 & DDS4 autoloaders
16778         {"DELL", "PERCRAID", "*", BLIST_FORCELUN},
16779         {"HP", "NetRAID-4M", "*", BLIST_FORCELUN},
16780 +       {"ADAPTEC", "AACRAID", "*", BLIST_FORCELUN},
16781 +       {"ADAPTEC", "Adaptec 5400S", "*", BLIST_FORCELUN},
16782  
16783         /*
16784          * Must be at end of list...
This page took 1.761138 seconds and 3 git commands to generate.