]> git.pld-linux.org Git - packages/kernel.git/blob - aacraid-2.4.1-1.0.6.patch
- obsolete
[packages/kernel.git] / aacraid-2.4.1-1.0.6.patch
1 diff -urN linux/arch/i386/defconfig linux/arch/i386/defconfig
2 --- linux/arch/i386/defconfig   Thu Nov 16 21:20:29 2000
3 +++ linux/arch/i386/defconfig   Thu Dec 21 13:27:04 2000
4 @@ -276,6 +276,7 @@
5  # CONFIG_SCSI_AHA152X is not set
6  # CONFIG_SCSI_AHA1542 is not set
7  # CONFIG_SCSI_AHA1740 is not set
8 +# CONFIG_SCSI_AACRAID is not set
9  # CONFIG_SCSI_AIC7XXX is not set
10  # CONFIG_SCSI_ADVANSYS is not set
11  # CONFIG_SCSI_IN2000 is not set
12 diff -urN linux/drivers/scsi/Config.in linux/drivers/scsi/Config.in
13 --- linux/drivers/scsi/Config.in        Thu Dec 21 12:07:01 2000
14 +++ linux/drivers/scsi/Config.in        Thu Dec 21 13:28:36 2000
15 @@ -48,6 +48,7 @@
16  dep_tristate 'Adaptec AHA152X/2825 support' CONFIG_SCSI_AHA152X $CONFIG_SCSI
17  dep_tristate 'Adaptec AHA1542 support' CONFIG_SCSI_AHA1542 $CONFIG_SCSI
18  dep_tristate 'Adaptec AHA1740 support' CONFIG_SCSI_AHA1740 $CONFIG_SCSI
19 +dep_tristate 'Adaptec AACRAID support EXPERIMENTAL' CONFIG_SCSI_AACRAID $CONFIG_SCSI
20  dep_tristate 'Adaptec AIC7xxx support' CONFIG_SCSI_AIC7XXX $CONFIG_SCSI
21  if [ "$CONFIG_SCSI_AIC7XXX" != "n" ]; then
22     bool '  Enable Tagged Command Queueing (TCQ) by default' CONFIG_AIC7XXX_TCQ_ON_BY_DEFAULT
23 diff -urN linux/drivers/scsi/Makefile linux/drivers/scsi/Makefile
24 --- linux/drivers/scsi/Makefile Thu Dec 21 12:07:01 2000
25 +++ linux/drivers/scsi/Makefile Thu Dec 21 14:20:35 2000
26 @@ -62,6 +62,7 @@
27  obj-$(CONFIG_SCSI_AHA152X)     += aha152x.o
28  obj-$(CONFIG_SCSI_AHA1542)     += aha1542.o
29  obj-$(CONFIG_SCSI_AHA1740)     += aha1740.o
30 +obj-$(CONFIG_SCSI_AACRAID)     += aacraid.o
31  obj-$(CONFIG_SCSI_AIC7XXX)     += aic7xxx.o
32  obj-$(CONFIG_SCSI_IPS)         += ips.o
33  obj-$(CONFIG_SCSI_FD_MCS)      += fd_mcs.o
34 @@ -195,3 +196,7 @@
35  sim710_u.h: sim710_d.h
36  
37  sim710.o : sim710_d.h
38 +
39 +aacraid.o:
40 +       cd aacraid; make
41 +
42 diff -urN linux/drivers/scsi/aacraid/Makefile linux/drivers/scsi/aacraid/Makefile
43 --- linux/drivers/scsi/aacraid/Makefile Wed Dec 31 19:00:00 1969
44 +++ linux/drivers/scsi/aacraid/Makefile Thu Dec 21 13:14:30 2000
45 @@ -0,0 +1,171 @@
46 +#
47 +# Makefile aacraid Raid Controller
48 +#
49 +
50 +###############################################################################
51 +### SOURCE FILES DEFINES
52 +###############################################################################
53 +
54 +CFILES_DRIVER=\
55 +       ./aachba.c \
56 +       ./aacid.c \
57 +       ./commctrl.c \
58 +       ./comminit.c \
59 +       ./commsup.c \
60 +       ./dpcsup.c \
61 +       ./linit.c \
62 +       ./osddi.c \
63 +       ./osfuncs.c \
64 +       ./ossup.c \
65 +       ./port.c \
66 +       ./rx.c \
67 +       ./sap1sup.c
68 +
69 +IFILES_DRIVER=\
70 +       ./include/AacGenericTypes.h \
71 +       ./include/aac_unix_defs.h \
72 +       ./include/adapter.h \
73 +       ./include/afacomm.h \
74 +       ./include/aifstruc.h \
75 +       ./include/build_number.h \
76 +       ./include/commdata.h \
77 +       ./include/commerr.h \
78 +       ./include/commfibcontext.h \
79 +       ./include/comprocs.h \
80 +       ./include/comproto.h \
81 +       ./include/comstruc.h \
82 +       ./include/comsup.h \
83 +       ./include/fsact.h \
84 +       ./include/fsafs.h  \
85 +       ./include/fsaioctl.h \
86 +       ./include/fsaport.h \
87 +       ./include/fsatypes.h \
88 +       ./include/linit.h \
89 +       ./include/monkerapi.h \
90 +       ./include/nodetype.h \
91 +       ./include/nvramioctl.h \
92 +       ./include/osheaders.h \
93 +       ./include/ostypes.h \
94 +       ./include/pcisup.h \
95 +       ./include/perfpack.h \
96 +       ./include/port.h \
97 +       ./include/protocol.h \
98 +       ./include/revision.h \
99 +       ./include/rxcommon.h \
100 +       ./include/rx.h \
101 +       ./include/sap1common.h \
102 +       ./include/sap1.h \
103 +       ./include/version.h
104 +
105 +ALL_SOURCE=\
106 +       ${CFILES_DRIVER} \
107 +       ${IFILES_DRIVER} 
108 +
109 +###############################################################################
110 +### OBJECT FILES DEFINES
111 +###############################################################################
112 +
113 +
114 +OFILES_DRIVER=\
115 +       linit.o \
116 +       osfuncs.o \
117 +       osddi.o \
118 +       aachba.o \
119 +       commctrl.o \
120 +       comminit.o \
121 +       commsup.o \
122 +       dpcsup.o \
123 +       ossup.o \
124 +       port.o \
125 +       rx.o \
126 +       sap1sup.o
127 +
128 +TARGET_OFILES= ${OFILES_DRIVER} aacid.o
129 +
130 +###############################################################################
131 +### GENERAL DEFINES
132 +###############################################################################
133 +
134 +#  Remember that we're doing a chdir one level lower, so we need an extra ../
135 +INCS= \
136 +       -I./include \
137 +       -I../../../include -I..
138 +
139 +WARNINGS= -w -Wall -Wno-unused -Wno-switch -Wno-missing-prototypes -Wno-implicit
140 +
141 +
142 +COMMON_FLAGS=\
143 +       -D__KERNEL__=1 -DUNIX -DCVLOCK_USE_SPINLOCK -DLINUX \
144 +       -Wall -Wstrict-prototypes \
145 +       ${INCS} \
146 +       ${WARNINGS} \
147 +       -O1 -g
148 +
149 +AACFLAGS=${CFLAGS} ${COMMON_FLAGS} ${EXTRA_FLAGS}
150 +
151 +###############################################################################
152 +### DO GENERAL STUFF
153 +###############################################################################
154 +
155 +.SUFFIXES:
156 +.SUFFIXES: .c .o .h .a
157 +
158 +all: source ${TARGET_OFILES} aacraid.o
159 +
160 +source: ${ALL_SOURCE}
161 +
162 +clean:
163 +       rm *.o
164 +
165 +###############################################################################
166 +### DRIVER LINKS
167 +###############################################################################
168 +
169 +aacraid.o: source ${TARGET_OFILES}
170 +       ld -r -o $@ $(TARGET_OFILES)
171 +       cp -r aacraid.o ../
172 +
173 +###############################################################################
174 +### SIMPLE COMPILES
175 +###############################################################################
176 +
177 +linit.o: ./linit.c
178 +       $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o linit.o ./linit.c
179 +
180 +aachba.o: ./aachba.c
181 +       $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o aachba.o ./aachba.c
182 +
183 +osddi.o: ./osddi.c
184 +       $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o osddi.o ./osddi.c
185 +
186 +osfuncs.o: ./osfuncs.c
187 +       $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o osfuncs.o ./osfuncs.c
188 +
189 +commctrl.o:  ./commctrl.c
190 +       $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o commctrl.o ./commctrl.c
191 +
192 +comminit.o:  ./comminit.c
193 +       $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o comminit.o ./comminit.c
194 +
195 +commsup.o:  ./commsup.c
196 +       $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o commsup.o ./commsup.c
197 +
198 +dpcsup.o:  ./dpcsup.c
199 +       $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o dpcsup.o ./dpcsup.c
200 +
201 +aacid.o:  ./aacid.c
202 +       $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o aacid.o ./aacid.c
203 +
204 +port.o:  ./port.c
205 +       $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o port.o ./port.c
206 +
207 +ossup.o:  ./ossup.c
208 +       $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o ossup.o ./ossup.c
209 +
210 +rx.o:  ./rx.c
211 +       $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o rx.o ./rx.c
212 +
213 +sap1sup.o: ./sap1sup.c
214 +       $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o sap1sup.o ./sap1sup.c
215 +
216 +
217 diff -urN linux/drivers/scsi/aacraid/README linux/drivers/scsi/aacraid/README
218 --- linux/drivers/scsi/aacraid/README   Wed Dec 31 19:00:00 1969
219 +++ linux/drivers/scsi/aacraid/README   Thu Dec 21 13:14:30 2000
220 @@ -0,0 +1,30 @@
221 +                               AACRAID Driver for Linux
222 +
223 +Introduction
224 +-------------------------
225 +The aacraid driver adds support for Adaptec (http://www.adaptec.com)
226 +OEM based RAID controllers.
227 +
228 +Supported Cards/Chipsets
229 +-------------------------
230 +       Dell Computer Corporation PERC 2 Quad Channel
231 +       Dell Computer Corporation PERC 3/Di
232 +       Dell Computer Corporation PERC 3/Si
233 +       HP NetRAID-4M
234 +
235 +Not Supported Devices
236 +-------------------------
237 +       Any and All Adaptec branded raid controllers.
238 +
239 +People
240 +-------------------------
241 +       Brian M. Boerner
242 +
243 +Mailing List
244 +-------------------------
245 +There is currently a mailing list being created for aacraid. This
246 +will all be straitened out before the driver is submitted for
247 +inclusion in the standard kernel distribution.
248 +
249 +$Revision$
250 +Modified by Brian Boerner 2000
251 \ No newline at end of file
252 diff -urN linux/drivers/scsi/aacraid/aachba.c linux/drivers/scsi/aacraid/aachba.c
253 --- linux/drivers/scsi/aacraid/aachba.c Wed Dec 31 19:00:00 1969
254 +++ linux/drivers/scsi/aacraid/aachba.c Thu Dec 21 13:14:30 2000
255 @@ -0,0 +1,1874 @@
256 +/*++
257 + * Adaptec aacraid device driver for Linux.
258 + *
259 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
260 + *
261 + * This program is free software; you can redistribute it and/or modify
262 + * it under the terms of the GNU General Public License as published by
263 + * the Free Software Foundation; either version 2, or (at your option)
264 + * any later version.
265 + *
266 + * This program is distributed in the hope that it will be useful,
267 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
268 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
269 + * GNU General Public License for more details.
270 + *
271 + * You should have received a copy of the GNU General Public License
272 + * along with this program; see the file COPYING.  If not, write to
273 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
274 + *
275 + * Module Name:
276 + *   aachba.c
277 + *
278 + * Abstract: driver...
279 + *
280 +--*/
281 +
282 +static char *ident_aachba = "aacraid_ident aachba.c 1.0.6 2000/10/09 Adaptec, Inc.";
283 +
284 +/*------------------------------------------------------------------------------
285 + *              I N C L U D E S
286 + *----------------------------------------------------------------------------*/
287 +#include "osheaders.h"
288 +#include "AacGenericTypes.h"
289 +#include "aac_unix_defs.h"
290 +#include "comstruc.h"
291 +#include "monkerapi.h"
292 +#include "protocol.h"
293 +#include "fsafs.h"
294 +#include "fsact.h"
295 +#include "fsaioctl.h"
296 +
297 +#include "sap1common.h"
298 +#include "fsaport.h"
299 +#include "pcisup.h"
300 +#include "sap1.h"
301 +#include "nodetype.h"
302 +#include "comsup.h"
303 +#include "afacomm.h"
304 +#include "adapter.h"
305 +
306 +/*------------------------------------------------------------------------------
307 + *              D E F I N E S
308 + *----------------------------------------------------------------------------*/
309 +/*     SCSI Commands */
310 +#define        SS_TEST                 0x00    /* Test unit ready */
311 +#define SS_REZERO              0x01    /* Rezero unit */
312 +#define        SS_REQSEN               0x03    /* Request Sense */
313 +#define SS_REASGN              0x07    /* Reassign blocks */
314 +#define        SS_READ                 0x08    /* Read 6   */
315 +#define        SS_WRITE                0x0A    /* Write 6  */
316 +#define        SS_INQUIR               0x12    /* inquiry */
317 +#define        SS_ST_SP                0x1B    /* Start/Stop unit */
318 +#define        SS_LOCK                 0x1E    /* prevent/allow medium removal */
319 +#define SS_RESERV              0x16    /* Reserve */
320 +#define SS_RELES               0x17    /* Release */
321 +#define SS_MODESEN             0x1A    /* Mode Sense 6 */
322 +#define        SS_RDCAP                0x25    /* Read Capacity */
323 +#define        SM_READ                 0x28    /* Read 10  */
324 +#define        SM_WRITE                0x2A    /* Write 10 */
325 +#define SS_SEEK                        0x2B    /* Seek */
326 +
327 +/* values for inqd_pdt: Peripheral device type in plain English */
328 +#define        INQD_PDT_DA     0x00    /* Direct-access (DISK) device */
329 +#define        INQD_PDT_PROC   0x03    /* Processor device */
330 +#define        INQD_PDT_CHNGR  0x08    /* Changer (jukebox, scsi2) */
331 +#define        INQD_PDT_COMM   0x09    /* Communication device (scsi2) */
332 +#define        INQD_PDT_NOLUN2 0x1f    /* Unknown Device (scsi2) */
333 +#define        INQD_PDT_NOLUN  0x7f    /* Logical Unit Not Present */
334 +
335 +#define        INQD_PDT_DMASK  0x1F    /* Peripheral Device Type Mask */
336 +#define        INQD_PDT_QMASK  0xE0    /* Peripheral Device Qualifer Mask */
337 +
338 +#define        TARGET_LUN_TO_CONTAINER(Target, Lun)    (((Lun) << 4) | Target)
339 +#define CONTAINER_TO_TARGET(Container)          ((Container) & 0xf)
340 +#define CONTAINER_TO_LUN(Container)             ((Container) >> 4)
341 +
342 +#define MAX_FIB_DATA (sizeof(FIB) - sizeof(FIB_HEADER))
343 +
344 +#define MAX_DRIVER_SG_SEGMENT_COUNT 17
345 +
346 +// ------------------------------------------------------
347 +// Sense keys
348 +//
349 +#define SENKEY_NO_SENSE      0x00 //
350 +#define SENKEY_UNDEFINED     0x01 //
351 +#define SENKEY_NOT_READY     0x02 //
352 +#define SENKEY_MEDIUM_ERR    0x03 //
353 +#define SENKEY_HW_ERR        0x04 //
354 +#define SENKEY_ILLEGAL       0x05 //
355 +#define SENKEY_ATTENTION     0x06 //
356 +#define SENKEY_PROTECTED     0x07 //
357 +#define SENKEY_BLANK         0x08 //
358 +#define SENKEY_V_UNIQUE      0x09 //
359 +#define SENKEY_CPY_ABORT     0x0A //
360 +#define SENKEY_ABORT         0x0B //
361 +#define SENKEY_EQUAL         0x0C //
362 +#define SENKEY_VOL_OVERFLOW  0x0D //
363 +#define SENKEY_MISCOMP       0x0E //
364 +#define SENKEY_RESERVED      0x0F //
365 +
366 +// ------------------------------------------------------
367 +// Sense codes
368 +//
369 +#define SENCODE_NO_SENSE                        0x00
370 +#define SENCODE_END_OF_DATA                     0x00
371 +#define SENCODE_BECOMING_READY                  0x04
372 +#define SENCODE_INIT_CMD_REQUIRED               0x04
373 +#define SENCODE_PARAM_LIST_LENGTH_ERROR         0x1A
374 +#define SENCODE_INVALID_COMMAND                 0x20
375 +#define SENCODE_LBA_OUT_OF_RANGE                0x21
376 +#define SENCODE_INVALID_CDB_FIELD               0x24
377 +#define SENCODE_LUN_NOT_SUPPORTED               0x25
378 +#define SENCODE_INVALID_PARAM_FIELD             0x26
379 +#define SENCODE_PARAM_NOT_SUPPORTED             0x26
380 +#define SENCODE_PARAM_VALUE_INVALID             0x26
381 +#define SENCODE_RESET_OCCURRED                  0x29
382 +#define SENCODE_LUN_NOT_SELF_CONFIGURED_YET     0x3E
383 +#define SENCODE_INQUIRY_DATA_CHANGED            0x3F
384 +#define SENCODE_SAVING_PARAMS_NOT_SUPPORTED     0x39
385 +#define SENCODE_DIAGNOSTIC_FAILURE              0x40
386 +#define SENCODE_INTERNAL_TARGET_FAILURE         0x44
387 +#define SENCODE_INVALID_MESSAGE_ERROR           0x49
388 +#define SENCODE_LUN_FAILED_SELF_CONFIG          0x4c
389 +#define SENCODE_OVERLAPPED_COMMAND              0x4E
390 +
391 +// ------------------------------------------------------
392 +// Additional sense codes
393 +//
394 +#define ASENCODE_NO_SENSE                       0x00
395 +#define ASENCODE_END_OF_DATA                    0x05
396 +#define ASENCODE_BECOMING_READY                 0x01
397 +#define ASENCODE_INIT_CMD_REQUIRED              0x02
398 +#define ASENCODE_PARAM_LIST_LENGTH_ERROR        0x00
399 +#define ASENCODE_INVALID_COMMAND                0x00
400 +#define ASENCODE_LBA_OUT_OF_RANGE               0x00
401 +#define ASENCODE_INVALID_CDB_FIELD              0x00
402 +#define ASENCODE_LUN_NOT_SUPPORTED              0x00
403 +#define ASENCODE_INVALID_PARAM_FIELD            0x00
404 +#define ASENCODE_PARAM_NOT_SUPPORTED            0x01
405 +#define ASENCODE_PARAM_VALUE_INVALID            0x02
406 +#define ASENCODE_RESET_OCCURRED                 0x00
407 +#define ASENCODE_LUN_NOT_SELF_CONFIGURED_YET    0x00
408 +#define ASENCODE_INQUIRY_DATA_CHANGED           0x03
409 +#define ASENCODE_SAVING_PARAMS_NOT_SUPPORTED    0x00
410 +#define ASENCODE_DIAGNOSTIC_FAILURE             0x80
411 +#define ASENCODE_INTERNAL_TARGET_FAILURE        0x00
412 +#define ASENCODE_INVALID_MESSAGE_ERROR          0x00
413 +#define ASENCODE_LUN_FAILED_SELF_CONFIG         0x00
414 +#define ASENCODE_OVERLAPPED_COMMAND             0x00
415 +
416 +#define BYTE0( x ) ( unsigned char )( x )
417 +#define BYTE1( x ) ( unsigned char )( x >> 8  )
418 +#define BYTE2( x ) ( unsigned char )( x >> 16 )
419 +#define BYTE3( x ) ( unsigned char )( x >> 24 )
420 +
421 +/*------------------------------------------------------------------------------
422 + *              S T R U C T S / T Y P E D E F S
423 + *----------------------------------------------------------------------------*/
424 +/* SCSI inquiry data */
425 +struct inquiry_data {
426 +       unchar inqd_pdt;     /* Peripheral qualifier | Peripheral Device Type  */
427 +       unchar inqd_dtq;     /* RMB | Device Type Qualifier  */
428 +       unchar inqd_ver;     /* ISO version | ECMA version | ANSI-approved version */
429 +       unchar inqd_rdf;     /* AENC | TrmIOP | Response data format */
430 +       unchar inqd_len;     /* Additional length (n-4) */
431 +       unchar inqd_pad1[2]; /* Reserved - must be zero */
432 +       unchar inqd_pad2;    /* RelAdr | WBus32 | WBus16 |  Sync  | Linked |Reserved| CmdQue | SftRe */
433 +       unchar inqd_vid[8];  /* Vendor ID */
434 +       unchar inqd_pid[16]; /* Product ID */
435 +       unchar inqd_prl[4];  /* Product Revision Level */
436 +};
437 +
438 +struct sense_data {
439 +       unchar error_code;              // 70h (current errors), 71h(deferred errors)
440 +       unchar valid:1;                 // A valid bit of one indicates that the information 
441 +                                       // field contains valid information as defined in the
442 +                                       // SCSI-2 Standard.
443 +       
444 +       unchar segment_number;  // Only used for COPY, COMPARE, or COPY AND VERIFY 
445 +                               // commands
446 +       
447 +       unchar sense_key:4;             // Sense Key
448 +       unchar reserved:1;
449 +       unchar ILI:1;                   // Incorrect Length Indicator
450 +       unchar EOM:1;                   // End Of Medium - reserved for random access devices
451 +       unchar filemark:1;              // Filemark - reserved for random access devices
452 +       
453 +       unchar information[4];  // for direct-access devices, contains the unsigned 
454 +                               // logical block address or residue associated with 
455 +                               // the sense key 
456 +       unchar add_sense_len;   // number of additional sense bytes to follow this field
457 +       unchar cmnd_info[4];    // not used
458 +       unchar ASC;             // Additional Sense Code
459 +       unchar ASCQ;            // Additional Sense Code Qualifier
460 +       unchar FRUC;            // Field Replaceable Unit Code - not used
461 +       
462 +       unchar bit_ptr:3;       // indicates which byte of the CDB or parameter data
463 +                               // was in error
464 +       unchar BPV:1;           // bit pointer valid (BPV): 1- indicates that 
465 +                               // the bit_ptr field has valid value
466 +       unchar reserved2:2;
467 +       unchar CD:1;            // command data bit: 1- illegal parameter in CDB.
468 +                               //                   0- illegal parameter in data.
469 +       unchar SKSV:1;
470 +       
471 +       unchar field_ptr[2];    // byte of the CDB or parameter data in error
472 +};
473 +
474 +/*------------------------------------------------------------------------------
475 + *              G L O B A L S
476 + *----------------------------------------------------------------------------*/
477 +/*------------------------------------------------------------------------------
478 + *              M O D U L E   G L O B A L S
479 + *----------------------------------------------------------------------------*/
480 +static fsadev_t *g_fsa_dev_array[8];   // SCSI Device Instance Pointers
481 +static struct sense_data g_sense_data[MAXIMUM_NUM_CONTAINERS];
482 +
483 +/*------------------------------------------------------------------------------
484 + *              F U N C T I O N   P R O T O T Y P E S
485 + *----------------------------------------------------------------------------*/
486 +AAC_STATUS AacHba_OpenAdapter( PVOID AdapterArg);
487 +AAC_STATUS AacHba_CloseAdapter( PVOID AdapterArg);
488 +BOOLEAN AacHba_HandleAif( PVOID AdapterArg, PFIB_CONTEXT FibContext);
489 +BOOLEAN AacHba_AdapterDeviceControl ( PVOID AdapterArg, 
490 +       PAFA_IOCTL_CMD IoctlCmdPtr, int * ReturnStatus);
491 +
492 +void AacHba_CompleteScsi( 
493 +       Scsi_Cmnd *scsi_cmnd_ptr );
494 +
495 +void AacHba_CompleteScsiNoLock( 
496 +       Scsi_Cmnd *scsi_cmnd_ptr );
497 +
498 +static void AacHba_ReadCallback( 
499 +       void *Context, 
500 +       PFIB_CONTEXT FibContext, 
501 +       int FibStatus );
502 +
503 +static void AacHba_WriteCallback( 
504 +       void *Context, 
505 +       PFIB_CONTEXT FibContext, 
506 +       int FibStatus );
507 +
508 +int AacHba_DoScsiRead(
509 +       Scsi_Cmnd *scsi_cmnd_ptr,
510 +       int ContainerId,
511 +       int wait );
512 +
513 +int AacHba_DoScsiWrite(
514 +       Scsi_Cmnd *scsi_cmnd_ptr,
515 +       int ContainerId,
516 +       int wait );
517 +
518 +int AacHba_QueryDisk(
519 +       PVOID AdapterArg,               // CommonExtensionPtr
520 +       IN PAFA_IOCTL_CMD IoctlCmdPtr );
521 +
522 +int AacHba_ForceDeleteDisk(
523 +       PVOID AdapterArg,               // CommonExtensionPtr
524 +       IN PAFA_IOCTL_CMD IoctlCmdPtr );
525 +
526 +int AacHba_DeleteDisk(
527 +       PVOID AdapterArg,
528 +       IN PAFA_IOCTL_CMD IoctlCmdPtr );
529 +
530 +void AacHba_DetachAdapter(
531 +       IN PVOID AdapterArg );
532 +
533 +BOOLEAN AacCommDetachAdapter(
534 +       IN PAFA_COMM_ADAPTER Adapter );
535 +
536 +void AacHba_SetSenseData(
537 +       char * sense_buf,
538 +       unchar sense_key,
539 +       unchar sense_code,
540 +       unchar a_sense_code,
541 +       unchar incorrect_length,
542 +       unchar bit_pointer,
543 +       unsigned field_pointer,
544 +       unsigned long residue );
545 +
546 +static void get_sd_devname(
547 +       long disknum, 
548 +       char * buffer);
549 +
550 +// Keep these here for the time being - #REVIEW#
551 +int
552 +AfaCommAdapterDeviceControl (
553 +       IN PVOID AdapterArg,
554 +       IN PAFA_IOCTL_CMD       IoctlCmdPtr
555 +       );
556 +
557 +AAC_STATUS
558 +AfaCommRegisterNewClassDriver(
559 +       IN PAFA_COMM_ADAPTER    Adapter,
560 +       IN PAFA_NEW_CLASS_DRIVER        NewClassDriver,
561 +       OUT PAFA_NEW_CLASS_DRIVER_RESPONSE NewClassDriverResponse
562 +       );
563 +
564 +void
565 +SetInqDataStr (int, void *, int);
566 +/*------------------------------------------------------------------------------
567 + *              F U N C T I O N S
568 + *----------------------------------------------------------------------------*/
569 +
570 +/*------------------------------------------------------------------------------
571 +       AacHba_ClassDriverInit()
572 +
573 +               Setup 'core' class driver to answer ioctl's
574 + *----------------------------------------------------------------------------*/
575 +int AacHba_ClassDriverInit(
576 +       PCI_MINIPORT_COMMON_EXTENSION * CommonExtensionPtr)
577 +/*----------------------------------------------------------------------------*/
578 +{
579 +    AFA_NEW_CLASS_DRIVER                               NewClassDriver;
580 +       AFA_NEW_CLASS_DRIVER_RESPONSE           NewClassDriverResponse;
581 +       PAFA_COMM_ADAPTER                                       Adapter;
582 +
583 +       Adapter = (AFA_COMM_ADAPTER *)CommonExtensionPtr->Adapter;
584 +
585 +       RtlZeroMemory( &NewClassDriver, sizeof( AFA_NEW_CLASS_DRIVER ) );
586 +       
587 +       // ClassDriverExtension is the first argument passed to class driver functions below
588 +       NewClassDriver.ClassDriverExtension = CommonExtensionPtr;
589 +       
590 +       NewClassDriver.OpenAdapter = AacHba_OpenAdapter;
591 +       NewClassDriver.CloseAdapter = AacHba_CloseAdapter;
592 +       NewClassDriver.DeviceControl = AacHba_AdapterDeviceControl;
593 +       NewClassDriver.HandleAif = AacHba_HandleAif;
594 +       AfaCommRegisterNewClassDriver( Adapter, &NewClassDriver, &NewClassDriverResponse );
595 +
596 +       return(0);
597 +}
598 +
599 +
600 +/*------------------------------------------------------------------------------
601 +       AacHba_ProbeContainers()
602 +
603 +               Make a list of all containers in the system.
604 +------------------------------------------------------------------------------*/
605 +int AacHba_ProbeContainers (PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr)
606 +{
607 +       fsadev_t                                                *fsa_dev_ptr;
608 +       int                                                             Index, Status;
609 +       PMNTINFO                                                DiskInfo;
610 +       PMNTINFORESPONSE                                DiskInfoResponse;
611 +       PFIB_CONTEXT                                    FibContext;
612 +       AFA_COMM_ADAPTER                                *Adapter;
613 +       unsigned                                                instance;
614 +       char                            *bufp;
615 +       int                             size;
616 +
617 +
618 +       Adapter = ( AFA_COMM_ADAPTER * )CommonExtensionPtr->Adapter;
619 +       fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
620 +       instance = CommonExtensionPtr->OsDep.scsi_host_ptr->unique_id;
621 +
622 +       if( !( FibContext = Adapter->CommFuncs.AllocateFib( Adapter ) ) )
623 +       {
624 +               cmn_err( CE_WARN, "AacHba_ProbeContainers: AllocateFib failed" );
625 +               return( STATUS_UNSUCCESSFUL );
626 +       }
627 +
628 +    for ( Index = 0; Index < MAXIMUM_NUM_CONTAINERS; Index++ ) 
629 +       {
630 +               Adapter->CommFuncs.InitializeFib( FibContext );
631 +
632 +               DiskInfo = ( PMNTINFO )Adapter->CommFuncs.GetFibData( FibContext );
633 +
634 +               DiskInfo->Command  = VM_NameServe;
635 +               DiskInfo->MntCount = Index;
636 +               DiskInfo->MntType  = FT_FILESYS;
637 +               
638 +               Status =  Adapter->CommFuncs.SendFib(   ContainerCommand,
639 +                                                       FibContext,
640 +                                                       sizeof(MNTINFO),
641 +                                                       FsaNormal,
642 +                                                       TRUE,
643 +                                                       NULL,
644 +                                                       TRUE,
645 +                                                       NULL,
646 +                                                       NULL );
647 +               if ( Status ) 
648 +               {
649 +                       cmn_err( CE_WARN, "ProbeContainers: SendFIb Failed" );
650 +                       break;
651 +               }
652 +
653 +               DiskInfoResponse = ( PMNTINFORESPONSE )Adapter->CommFuncs.GetFibData( FibContext );
654 +               
655 +
656 +               if ( ( DiskInfoResponse->Status == ST_OK ) &&
657 +                       ( DiskInfoResponse->MntTable[0].VolType != CT_NONE ) ) 
658 +               {
659 +
660 +
661 +                       fsa_dev_ptr->ContainerValid[Index] = TRUE;
662 +                       fsa_dev_ptr->ContainerType[Index]  = DiskInfoResponse->MntTable[0].VolType;
663 +                       fsa_dev_ptr->ContainerSize[Index]  = DiskInfoResponse->MntTable[0].Capacity;
664 +
665 +                       if (DiskInfoResponse->MntTable[0].ContentState & FSCS_READONLY)
666 +                               fsa_dev_ptr->ContainerReadOnly[Index] = TRUE;
667 +               }
668 +               
669 +               Adapter->CommFuncs.CompleteFib( FibContext );
670 +
671 +               // If there are no more containers, then stop asking.
672 +               if ((Index + 1) >= DiskInfoResponse->MntRespCount)
673 +                       break;
674 +    } // end for()
675 +
676 +       Adapter->CommFuncs.FreeFib( FibContext );
677 +
678 +       g_fsa_dev_array[instance] = fsa_dev_ptr;
679 +       return( Status );
680 +}
681 +
682 +
683 +/*------------------------------------------------------------------------------
684 +       AacHba_ProbeContainer()
685 +
686 +               Probe a single container.
687 + *----------------------------------------------------------------------------*/
688 +int AacHba_ProbeContainer( 
689 +       PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr,
690 +       int ContainerId )
691 +/*----------------------------------------------------------------------------*/
692 +{
693 +       fsadev_t                                                *fsa_dev_ptr;
694 +    int                                                                Status;
695 +    PMNTINFO                                           DiskInfo;
696 +    PMNTINFORESPONSE                           DiskInfoResponse;
697 +       PFIB_CONTEXT                                    FibContext;
698 +       AFA_COMM_ADAPTER                                *Adapter;
699 +       unsigned                                                instance;
700 +       
701 +       Adapter = ( AFA_COMM_ADAPTER * )CommonExtensionPtr->Adapter;
702 +       fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
703 +       instance = CommonExtensionPtr->OsDep.scsi_host_ptr->unique_id;
704 +
705 +       if( !( FibContext = Adapter->CommFuncs.AllocateFib( Adapter ) ) )
706 +       {
707 +               cmn_err( CE_WARN, "AacHba_ProbeContainers: AllocateFib failed" );
708 +               return( STATUS_UNSUCCESSFUL );
709 +       }
710 +
711 +       Adapter->CommFuncs.InitializeFib( FibContext );
712 +
713 +       DiskInfo = ( PMNTINFO )Adapter->CommFuncs.GetFibData( FibContext );
714 +
715 +       DiskInfo->Command  = VM_NameServe;
716 +       DiskInfo->MntCount = ContainerId;
717 +       DiskInfo->MntType  = FT_FILESYS;
718 +               
719 +       Status =  Adapter->CommFuncs.SendFib (ContainerCommand,
720 +                                             FibContext,
721 +                                             sizeof(MNTINFO),
722 +                                             FsaNormal,
723 +                                             TRUE,
724 +                                             NULL,
725 +                                             TRUE,
726 +                                             NULL,
727 +                                             NULL );
728 +       if ( Status ) 
729 +       {
730 +               cmn_err( CE_WARN, "ProbeContainers: SendFIb Failed" );
731 +               Adapter->CommFuncs.CompleteFib( FibContext );
732 +               Adapter->CommFuncs.FreeFib( FibContext );
733 +               return( Status );
734 +       }
735 +
736 +       DiskInfoResponse = ( PMNTINFORESPONSE )Adapter->CommFuncs.GetFibData( FibContext );
737 +               
738 +
739 +       if ( ( DiskInfoResponse->Status == ST_OK ) &&
740 +               ( DiskInfoResponse->MntTable[0].VolType != CT_NONE ) ) 
741 +       {
742 +
743 +               fsa_dev_ptr->ContainerValid[ContainerId] = TRUE;
744 +               fsa_dev_ptr->ContainerType[ContainerId]  = DiskInfoResponse->MntTable[0].VolType;
745 +               fsa_dev_ptr->ContainerSize[ContainerId]  = DiskInfoResponse->MntTable[0].Capacity;
746 +               if (DiskInfoResponse->MntTable[0].ContentState & FSCS_READONLY)
747 +                       fsa_dev_ptr->ContainerReadOnly[ContainerId] = TRUE;
748 +       }
749 +               
750 +       Adapter->CommFuncs.CompleteFib( FibContext );
751 +       Adapter->CommFuncs.FreeFib( FibContext );
752 +
753 +       return( Status );
754 +}
755 +
756 +
757 +/*------------------------------------------------------------------------------
758 +       AacHba_CompleteScsi()
759 +
760 +               Call SCSI completion routine after acquiring io_request_lock
761 +
762 +       Preconditions:
763 +       Postconditions:
764 + *----------------------------------------------------------------------------*/
765 +void AacHba_CompleteScsi( 
766 +       Scsi_Cmnd *scsi_cmnd_ptr )
767 +{
768 +       unsigned long cpu_flags;
769 +
770 +       spin_lock_irqsave( &io_request_lock, cpu_flags );
771 +       scsi_cmnd_ptr->scsi_done( scsi_cmnd_ptr );
772 +       spin_unlock_irqrestore( &io_request_lock, cpu_flags );
773 +}
774 +
775 +
776 +/*------------------------------------------------------------------------------
777 +       AacHba_CompleteScsiNoLock()
778 +
779 +               Call SCSI completion routine
780 +
781 +       Preconditions:
782 +       Postconditions:
783 + *----------------------------------------------------------------------------*/
784 +void AacHba_CompleteScsiNoLock( 
785 +       Scsi_Cmnd *scsi_cmnd_ptr )
786 +{
787 +       scsi_cmnd_ptr->scsi_done( scsi_cmnd_ptr );
788 +}
789 +
790 +/*------------------------------------------------------------------------------
791 +       AacHba_DoScsiCmd()
792 +
793 +               Process SCSI command
794 +
795 +       Preconditions:
796 +       Postconditions:
797 +               Returns 0 on success, -1 on failure
798 + *----------------------------------------------------------------------------*/
799 +int AacHba_DoScsiCmd(
800 +       Scsi_Cmnd *scsi_cmnd_ptr,
801 +       int wait )
802 +{
803 +       int                     ContainerId = 0;
804 +       fsadev_t        *fsa_dev_ptr;
805 +       PCI_MINIPORT_COMMON_EXTENSION   *CommonExtensionPtr;
806 +       int MiniPortIndex;
807 +
808 +       CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
809 +       MiniPortIndex = CommonExtensionPtr->OsDep.MiniPortIndex;
810 +
811 +       fsa_dev_ptr = g_fsa_dev_array[ scsi_cmnd_ptr->host->unique_id ];
812 +
813 +       // If the bus, target or lun is out of range, return fail
814 +       // Test does not apply to ID 16, the pseudo id for the controller itself.
815 +       if ( scsi_cmnd_ptr->target != scsi_cmnd_ptr->host->this_id ) 
816 +       {
817 +               if( ( scsi_cmnd_ptr->channel > 0 ) ||
818 +                       ( scsi_cmnd_ptr->target > 15 ) || 
819 +                       ( scsi_cmnd_ptr->lun > 7 ) )
820 +               {
821 +                       cmn_err( CE_DEBUG, "The bus, target or lun is out of range = %d, %d, %d",
822 +                               scsi_cmnd_ptr->channel,
823 +                               scsi_cmnd_ptr->target, 
824 +                               scsi_cmnd_ptr->lun );
825 +                       scsi_cmnd_ptr->result = DID_BAD_TARGET << 16;
826 +
827 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
828 +
829 +                       return ( -1 );
830 +               }
831 +
832 +               ContainerId = TARGET_LUN_TO_CONTAINER( scsi_cmnd_ptr->target, scsi_cmnd_ptr->lun );
833 +
834 +
835 +               // If the target container doesn't exist, it may have been newly created
836 +               if( fsa_dev_ptr->ContainerValid[ContainerId] == 0 )
837 +               {       
838 +                       switch( scsi_cmnd_ptr->cmnd[0] )
839 +                       {
840 +                               case SS_INQUIR:
841 +                               case SS_RDCAP:
842 +                               case SS_TEST:
843 +                                       spin_unlock_irq( &io_request_lock );
844 +                                       AacHba_ProbeContainer( CommonExtensionPtr, ContainerId );               
845 +                                       spin_lock_irq( &io_request_lock );
846 +                               default:
847 +                                       break;
848 +                       }
849 +               }
850 +
851 +               // If the target container still doesn't exist, return failure
852 +               if( fsa_dev_ptr->ContainerValid[ContainerId] == 0 )
853 +               {       
854 +
855 +                       scsi_cmnd_ptr->result = DID_BAD_TARGET << 16;
856 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
857 +
858 +                       return ( -1 );
859 +               }
860 +       }
861 +       else    // the command is for the controller itself
862 +               if( ( scsi_cmnd_ptr->cmnd[0] != SS_INQUIR )     && // only INQUIRY & TUR cmnd supported for controller 
863 +                       ( scsi_cmnd_ptr->cmnd[0] != SS_TEST ) )
864 +               {
865 +                       cmn_err( CE_WARN, "Only INQUIRY & TUR command supported for controller, rcvd = 0x%x", 
866 +                               scsi_cmnd_ptr->cmnd[0] );
867 +
868 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
869 +                       
870 +                       AacHba_SetSenseData( (char *)&g_sense_data[ ContainerId ],
871 +                               SENKEY_ILLEGAL, SENCODE_INVALID_COMMAND, ASENCODE_INVALID_COMMAND, 
872 +                               0, 0, 0, 0 );
873 +
874 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
875 +
876 +                       return ( -1 );
877 +               }
878 +
879 +       // Handle commands here that don't really require going out to the adapter
880 +       switch ( scsi_cmnd_ptr->cmnd[0] ) 
881 +       {
882 +               case SS_INQUIR:
883 +               {
884 +                       struct inquiry_data *inq_data_ptr;
885 +               
886 +                       cmn_err( CE_DEBUG, "INQUIRY command, ID: %d", scsi_cmnd_ptr->target );
887 +                       inq_data_ptr = ( struct inquiry_data * )scsi_cmnd_ptr->request_buffer;
888 +                       bzero( inq_data_ptr, sizeof( struct inquiry_data ) );
889 +
890 +                       inq_data_ptr->inqd_ver = 2;             // claim compliance to SCSI-2
891 +
892 +                       inq_data_ptr->inqd_dtq = 0x80;  // set RMB bit to one indicating 
893 +                                                                                       // that the medium is removable
894 +                       inq_data_ptr->inqd_rdf = 2;             // A response data format value of
895 +                                                                                       // two indicates that the data shall 
896 +                                                                                       // be in the format specified in SCSI-2
897 +                       inq_data_ptr->inqd_len = 31;
898 +
899 +                       // Set the Vendor, Product, and Revision Level see: <vendor>.c i.e. aac.c
900 +                       SetInqDataStr(  MiniPortIndex, 
901 +                                                       (void *)(inq_data_ptr->inqd_vid),
902 +                                                       fsa_dev_ptr->ContainerType[ContainerId]);
903 +
904 +                       if ( scsi_cmnd_ptr->target == scsi_cmnd_ptr->host->this_id )
905 +                               inq_data_ptr->inqd_pdt = INQD_PDT_PROC; // Processor device
906 +                       else
907 +                               inq_data_ptr->inqd_pdt = INQD_PDT_DA;   // Direct/random access device
908 +
909 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
910 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
911 +
912 +                       return ( 0 );
913 +               }
914 +
915 +               case SS_RDCAP:
916 +               {
917 +                       int capacity;
918 +                       char *cp;
919 +
920 +                       cmn_err( CE_DEBUG, "READ CAPACITY command" );
921 +                       capacity = fsa_dev_ptr->ContainerSize[ContainerId];
922 +                       cp = scsi_cmnd_ptr->request_buffer;
923 +                       cp[0] = ( capacity >> 24 ) & 0xff;
924 +                       cp[1] = ( capacity >> 16 ) & 0xff;
925 +                       cp[2] = ( capacity >>  8 ) & 0xff;
926 +                       cp[3] = ( capacity >>  0 ) & 0xff;
927 +                       cp[4] = 0;
928 +                       cp[5] = 0;
929 +                       cp[6] = 2;
930 +                       cp[7] = 0;
931 +       
932 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
933 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
934 +
935 +                       return ( 0 );
936 +               }
937 +
938 +               case SS_MODESEN:
939 +               {
940 +                       char *mode_buf;
941 +
942 +                       cmn_err( CE_DEBUG, "MODE SENSE command" );
943 +                       mode_buf = scsi_cmnd_ptr->request_buffer;
944 +                       mode_buf[0] = 0;        // Mode data length (MSB)
945 +                       mode_buf[1] = 6;        // Mode data length (LSB)
946 +                       mode_buf[2] = 0;        // Medium type - default
947 +                       mode_buf[3] = 0;        // Device-specific param, bit 8: 0/1 = write enabled/protected
948 +                       mode_buf[4] = 0;        // reserved
949 +                       mode_buf[5] = 0;        // reserved
950 +                       mode_buf[6] = 0;        // Block descriptor length (MSB)
951 +                       mode_buf[7] = 0;        // Block descriptor length (LSB)
952 +       
953 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
954 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
955 +
956 +                       return ( 0 );
957 +               }
958 +
959 +
960 +               // These commands are all No-Ops
961 +               case SS_TEST:
962 +                       cmn_err( CE_DEBUG, "TEST UNIT READY command" );
963 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
964 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
965 +                       return ( 0 );
966 +
967 +               case SS_REQSEN:
968 +                       cmn_err( CE_DEBUG, "REQUEST SENSE command" );
969 +
970 +                       memcpy( scsi_cmnd_ptr->sense_buffer, &g_sense_data[ContainerId],
971 +                               sizeof( struct sense_data ) );
972 +                       bzero( &g_sense_data[ContainerId], sizeof( struct sense_data ) );
973 +
974 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
975 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
976 +                       return ( 0 );
977 +
978 +               case SS_LOCK:
979 +                       cmn_err(CE_DEBUG, "LOCK command");
980 +
981 +                       if( scsi_cmnd_ptr->cmnd[4] )
982 +                               fsa_dev_ptr->ContainerLocked[ContainerId] = 1;
983 +                       else
984 +                               fsa_dev_ptr->ContainerLocked[ContainerId] = 0;
985 +
986 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
987 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
988 +                       return ( 0 );
989 +
990 +               case SS_RESERV:
991 +                       cmn_err( CE_DEBUG, "RESERVE command" );
992 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
993 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
994 +                       return ( 0 );
995 +
996 +               case SS_RELES:
997 +                       cmn_err( CE_DEBUG, "RELEASE command" );
998 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
999 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1000 +                       return ( 0 );
1001 +
1002 +               case SS_REZERO:
1003 +                       cmn_err( CE_DEBUG, "REZERO command" );
1004 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1005 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1006 +                       return ( 0 );
1007 +
1008 +               case SS_REASGN:
1009 +                       cmn_err( CE_DEBUG, "REASSIGN command" );
1010 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1011 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1012 +                       return ( 0 );
1013 +
1014 +               case SS_SEEK:
1015 +                       cmn_err( CE_DEBUG, "SEEK command" );
1016 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1017 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1018 +                       return ( 0 );
1019 +
1020 +               case SS_ST_SP:
1021 +                       cmn_err( CE_DEBUG, "START/STOP command" );
1022 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1023 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1024 +                       return ( 0 );
1025 +       }
1026 +
1027 +       switch ( scsi_cmnd_ptr->cmnd[0] ) 
1028 +       {
1029 +               case SS_READ:
1030 +               case SM_READ:
1031 +                       // Hack to keep track of ordinal number of the device that corresponds
1032 +                       // to a container. Needed to convert containers to /dev/sd device names
1033 +                       fsa_dev_ptr->ContainerDevNo[ContainerId] = 
1034 +                               DEVICE_NR( scsi_cmnd_ptr->request.rq_dev );
1035 +
1036 +                       return( AacHba_DoScsiRead( scsi_cmnd_ptr, ContainerId,  wait ) );
1037 +                       break;
1038 +
1039 +               case SS_WRITE:
1040 +               case SM_WRITE:
1041 +
1042 +                       return( AacHba_DoScsiWrite( scsi_cmnd_ptr, ContainerId,  wait ) );
1043 +                       break;
1044 +       }
1045 +       //
1046 +       // Unhandled commands
1047 +       //
1048 +       cmn_err( CE_WARN, "Unhandled SCSI Command: 0x%x", scsi_cmnd_ptr->cmnd[0] );
1049 +       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1050 +
1051 +       AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1052 +               SENKEY_ILLEGAL, SENCODE_INVALID_COMMAND, ASENCODE_INVALID_COMMAND, 
1053 +               0, 0, 0, 0 );
1054 +
1055 +       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1056 +       return ( -1 );
1057 +}
1058 +
1059 +
1060 +/*------------------------------------------------------------------------------
1061 +       AacHba_DoScsiRead()
1062 +               
1063 +               Handles SCSI READ requests
1064 +
1065 +       Preconditions:
1066 +       Postconditions:
1067 +               Returns 0 on success, -1 on failure
1068 + *----------------------------------------------------------------------------*/
1069 +int AacHba_DoScsiRead(
1070 +       Scsi_Cmnd *scsi_cmnd_ptr,
1071 +       int ContainerId,
1072 +       int wait )
1073 +/*----------------------------------------------------------------------------*/
1074 +{
1075 +       u_long                          lba;
1076 +       u_long                          count;
1077 +       u_long                          byte_count;
1078 +       int                                     Status;
1079 +
1080 +       PBLOCKREAD                      BlockReadDisk;
1081 +       PBLOCKREADRESPONSE      BlockReadResponse;
1082 +       uint16_t                        FibSize;
1083 +       PCI_MINIPORT_COMMON_EXTENSION   *CommonExtension;
1084 +       AFA_COMM_ADAPTER                                *Adapter;
1085 +       PFIB_CONTEXT                                    cmd_fibcontext;
1086 +
1087 +       CommonExtension = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
1088 +       Adapter         = ( AFA_COMM_ADAPTER * )CommonExtension->Adapter;
1089 +
1090 +       // Get block address and transfer length
1091 +       if ( scsi_cmnd_ptr->cmnd[0] == SS_READ ) // 6 byte command
1092 +       {
1093 +               cmn_err( CE_DEBUG, "aachba: received a read(6) command on target %d", ContainerId );
1094 +
1095 +               lba = ( ( scsi_cmnd_ptr->cmnd[1] & 0x1F ) << 16 ) | 
1096 +                       ( scsi_cmnd_ptr->cmnd[2] << 8 ) |
1097 +                       scsi_cmnd_ptr->cmnd[3];
1098 +               count = scsi_cmnd_ptr->cmnd[4];
1099 +
1100 +               if ( count == 0 )
1101 +                       count = 256;
1102 +       } 
1103 +       else 
1104 +       {               
1105 +               cmn_err( CE_DEBUG, "aachba: received a read(10) command on target %d", ContainerId );
1106 +               
1107 +               lba = ( scsi_cmnd_ptr->cmnd[2] << 24 ) | ( scsi_cmnd_ptr->cmnd[3] << 16 ) | 
1108 +                       ( scsi_cmnd_ptr->cmnd[4] << 8 ) | scsi_cmnd_ptr->cmnd[5];
1109 +
1110 +               count = ( scsi_cmnd_ptr->cmnd[7] << 8 ) | scsi_cmnd_ptr->cmnd[8];
1111 +       }       
1112 +       cmn_err( CE_DEBUG, "AacHba_DoScsiRead[cpu %d]: lba = %lu, t = %ld", smp_processor_id(), lba, jiffies );
1113 +
1114 +       //-------------------------------------------------------------------------
1115 +       // Alocate and initialize a Fib
1116 +       //  Setup BlockRead command
1117 +       if( !( cmd_fibcontext = Adapter->CommFuncs.AllocateFib( Adapter ) ) )
1118 +       {
1119 +               cmn_err( CE_WARN, "AacHba_DoScsiRead: AllocateFib failed\n" );
1120 +               scsi_cmnd_ptr->result = DID_ERROR << 16;
1121 +               AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1122 +               return ( -1 );
1123 +       }
1124 +
1125 +    Adapter->CommFuncs.InitializeFib( cmd_fibcontext );
1126 +
1127 +       BlockReadDisk = ( PBLOCKREAD )Adapter->CommFuncs.GetFibData( cmd_fibcontext );
1128 +       BlockReadDisk->Command     = VM_CtBlockRead;
1129 +       BlockReadDisk->ContainerId = ContainerId;
1130 +       BlockReadDisk->BlockNumber = lba;
1131 +       BlockReadDisk->ByteCount   = count * 512;
1132 +       BlockReadDisk->SgMap.SgCount = 1;
1133 +
1134 +       if( BlockReadDisk->ByteCount > ( 64 * 1024 ) )
1135 +       {
1136 +               cmn_err( CE_WARN, "AacHba_DoScsiRead: READ request is larger than 64K" );
1137 +               scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1138 +
1139 +               AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1140 +                               SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD, 
1141 +                               0, 0, 7, 0 );
1142 +
1143 +               goto err_return;
1144 +       }
1145 +
1146 +       //-------------------------------------------------------------------------
1147 +       // Build Scatter/Gather list
1148 +       //
1149 +       if ( scsi_cmnd_ptr->use_sg )    // use scatter/gather list
1150 +       {
1151 +               struct scatterlist *scatterlist_ptr;
1152 +               int segment;
1153 +               
1154 +               scatterlist_ptr = ( struct scatterlist * )scsi_cmnd_ptr->request_buffer;
1155 +
1156 +               byte_count = 0;
1157 +               for( segment = 0; segment< scsi_cmnd_ptr->use_sg; segment++ ) 
1158 +               {
1159 +                       BlockReadDisk->SgMap.SgEntry[segment].SgAddress = 
1160 +                               ( void * )OsVirtToPhys( scatterlist_ptr[segment].address );
1161 +                       BlockReadDisk->SgMap.SgEntry[segment].SgByteCount = 
1162 +                               scatterlist_ptr[segment].length;
1163 +
1164 +#ifdef DEBUG_SGBUFFER
1165 +                       memset( scatterlist_ptr[segment].address, 0xa5, 
1166 +                               scatterlist_ptr[segment].length );
1167 +#endif
1168 +
1169 +                       byte_count += scatterlist_ptr[segment].length;
1170 +                       
1171 +                       if( BlockReadDisk->SgMap.SgEntry[segment].SgByteCount > ( 64 * 1024 ) )
1172 +                       {
1173 +                               cmn_err( CE_WARN, "AacHba_DoScsiRead: Segment byte count is larger than 64K" );
1174 +                               scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1175 +
1176 +                               AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1177 +                                       SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD, 
1178 +                                       0, 0, 7, 0 );
1179 +
1180 +                               goto err_return;
1181 +                       }
1182 +                       /*
1183 +                       cmn_err(CE_DEBUG, "SgEntry[%d].SgAddress = 0x%x, Byte count = 0x%x", 
1184 +                                       segment,
1185 +                                       BlockReadDisk->SgMap.SgEntry[segment].SgAddress,
1186 +                                       BlockReadDisk->SgMap.SgEntry[segment].SgByteCount);
1187 +                       */
1188 +               }
1189 +               BlockReadDisk->SgMap.SgCount = scsi_cmnd_ptr->use_sg;
1190 +
1191 +               if( BlockReadDisk->SgMap.SgCount > MAX_DRIVER_SG_SEGMENT_COUNT ) 
1192 +               {
1193 +                       cmn_err( CE_WARN, "AacHba_DoScsiRead: READ request with SgCount > %d", 
1194 +                               MAX_DRIVER_SG_SEGMENT_COUNT );
1195 +                       scsi_cmnd_ptr->result = DID_ERROR << 16;
1196 +                       goto err_return;
1197 +               }
1198 +       }       
1199 +       else            // one piece of contiguous phys mem
1200 +       {
1201 +               BlockReadDisk->SgMap.SgEntry[0].SgAddress = 
1202 +                       ( void * )OsVirtToPhys( scsi_cmnd_ptr->request_buffer );
1203 +               BlockReadDisk->SgMap.SgEntry[0].SgByteCount = scsi_cmnd_ptr->request_bufflen;
1204 +
1205 +               byte_count = scsi_cmnd_ptr->request_bufflen;
1206 +
1207 +               if( BlockReadDisk->SgMap.SgEntry[0].SgByteCount > ( 64 * 1024 ) )
1208 +               {
1209 +                       cmn_err( CE_WARN, "AacHba_DoScsiRead: Single segment byte count is larger than 64K" );
1210 +                       cmn_err( CE_WARN, "AacHba_DoScsiRead: ByteCount: %d", BlockReadDisk->ByteCount);
1211 +                       cmn_err( CE_WARN, "AacHba_DoScsiRead: SG ELEMENTS: %d", scsi_cmnd_ptr->use_sg);
1212 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1213 +
1214 +                       AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1215 +                               SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD, 
1216 +                               0, 0, 7, 0 );
1217 +
1218 +                       goto err_return;
1219 +               }
1220 +       }
1221 +
1222 +       if( byte_count != BlockReadDisk->ByteCount )
1223 +               cmn_err( CE_WARN, "AacHba_DoScsiRead: byte_count != BlockReadDisk->ByteCount" );
1224 +
1225 +       //-------------------------------------------------------------------------
1226 +       // Now send the Fib to the adapter
1227 +       //
1228 +       FibSize = sizeof( BLOCKREAD ) + ( ( BlockReadDisk->SgMap.SgCount - 1 ) * sizeof( SGENTRY ) );
1229 +
1230 +       if( wait ) 
1231 +       {
1232 +               Status = Adapter->CommFuncs.SendFib( ContainerCommand,
1233 +                                                                                        cmd_fibcontext,
1234 +                                                                                        FibSize,
1235 +                                                                                        FsaNormal,
1236 +                                                                                        TRUE,
1237 +                                                                                        NULL,
1238 +                                                                                        TRUE,
1239 +                                                                                        NULL,
1240 +                                                                                        NULL);
1241 +
1242 +               BlockReadResponse = ( PBLOCKREADRESPONSE )
1243 +                       Adapter->CommFuncs.GetFibData( cmd_fibcontext );        
1244 +
1245 +               Adapter->CommFuncs.CompleteFib( cmd_fibcontext );
1246 +               Adapter->CommFuncs.FreeFib( cmd_fibcontext );
1247 +               
1248 +               if( BlockReadResponse->Status != ST_OK )
1249 +               {
1250 +                       cmn_err( CE_WARN, "AacHba_DoScsiRead: BlockReadCommand failed with status: %d", 
1251 +                               BlockReadResponse->Status );
1252 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1253 +
1254 +                       AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1255 +                               SENKEY_HW_ERR, SENCODE_INTERNAL_TARGET_FAILURE, ASENCODE_INTERNAL_TARGET_FAILURE, 
1256 +                               0, 0, 0, 0 );
1257 +
1258 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1259 +                       return ( -1 );
1260 +               }
1261 +               else
1262 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1263 +
1264 +               AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1265 +               return ( 0 );
1266 +       } 
1267 +       else 
1268 +       {
1269 +               Status = Adapter->CommFuncs.SendFib( ContainerCommand,
1270 +                                                                                        cmd_fibcontext,
1271 +                                                                                        FibSize,
1272 +                                                                                        FsaNormal,
1273 +                                                                                        FALSE,
1274 +                                                                                        NULL,
1275 +                                                                                        TRUE,
1276 +                                                                                        ( PFIB_CALLBACK )AacHba_ReadCallback,
1277 +                                                                                        ( void *)scsi_cmnd_ptr );
1278 +               // don't call done func here
1279 +               return ( 0 );
1280 +       }
1281 +
1282 +err_return:
1283 +       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1284 +
1285 +       Adapter->CommFuncs.CompleteFib( cmd_fibcontext );
1286 +       Adapter->CommFuncs.FreeFib( cmd_fibcontext );
1287 +
1288 +       return ( -1 );
1289 +}
1290 +
1291 +
1292 +/*------------------------------------------------------------------------------
1293 +       AacHba_DoScsiWrite()
1294 +
1295 +               Handles SCSI WRITE requests
1296 +       
1297 +       Preconditions:
1298 +       Postconditions:
1299 +               Returns 0 on success, -1 on failure
1300 + *----------------------------------------------------------------------------*/
1301 +int AacHba_DoScsiWrite(
1302 +       Scsi_Cmnd *scsi_cmnd_ptr,
1303 +       int ContainerId,
1304 +       int wait )
1305 +/*----------------------------------------------------------------------------*/
1306 +{
1307 +       u_long                          lba;
1308 +       u_long                          count;
1309 +       u_long                          byte_count;
1310 +       int                                     Status;
1311 +
1312 +       PBLOCKWRITE                                             BlockWriteDisk;
1313 +       PBLOCKWRITERESPONSE                             BlockWriteResponse;
1314 +       uint16_t                                                FibSize;
1315 +       PCI_MINIPORT_COMMON_EXTENSION   *CommonExtension;
1316 +       AFA_COMM_ADAPTER                                *Adapter;
1317 +       PFIB_CONTEXT                                    cmd_fibcontext;
1318 +
1319 +       CommonExtension = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
1320 +       Adapter         = ( AFA_COMM_ADAPTER * )CommonExtension->Adapter;
1321 +
1322 +       // Get block address and transfer length
1323 +       if ( scsi_cmnd_ptr->cmnd[0] == SS_WRITE ) // 6 byte command
1324 +       {
1325 +               lba = ( ( scsi_cmnd_ptr->cmnd[1] & 0x1F ) << 16 ) | 
1326 +                       ( scsi_cmnd_ptr->cmnd[2] << 8 ) |
1327 +                       scsi_cmnd_ptr->cmnd[3];
1328 +               count = scsi_cmnd_ptr->cmnd[4];
1329 +
1330 +               if ( count == 0 )
1331 +                       count = 256;
1332 +       } 
1333 +       else 
1334 +       {               
1335 +               cmn_err( CE_DEBUG, "aachba: received a write(10) command on target %d", ContainerId );
1336 +               
1337 +               lba = ( scsi_cmnd_ptr->cmnd[2] << 24 ) | ( scsi_cmnd_ptr->cmnd[3] << 16 ) | 
1338 +                       ( scsi_cmnd_ptr->cmnd[4] << 8 ) | scsi_cmnd_ptr->cmnd[5];
1339 +
1340 +               count = ( scsi_cmnd_ptr->cmnd[7] << 8 ) | scsi_cmnd_ptr->cmnd[8];
1341 +
1342 +       }       
1343 +       cmn_err( CE_DEBUG, "AacHba_DoScsiWrite[cpu %d]: lba = %lu, t = %ld", smp_processor_id(), lba, jiffies );
1344 +
1345 +       //-------------------------------------------------------------------------
1346 +       // Alocate and initialize a Fib
1347 +       //  Setup BlockWrite command
1348 +       if( !( cmd_fibcontext = Adapter->CommFuncs.AllocateFib( Adapter ) ) ) 
1349 +       {
1350 +               cmn_err( CE_WARN, "AacHba_DoScsiWrite: AllocateFib failed\n" );
1351 +               scsi_cmnd_ptr->result = DID_ERROR << 16;
1352 +               AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1353 +               return ( -1 );
1354 +       }
1355 +
1356 +    Adapter->CommFuncs.InitializeFib( cmd_fibcontext );
1357 +
1358 +       BlockWriteDisk = (PBLOCKWRITE) Adapter->CommFuncs.GetFibData( cmd_fibcontext );
1359 +       BlockWriteDisk->Command     = VM_CtBlockWrite;
1360 +       BlockWriteDisk->ContainerId = ContainerId;
1361 +       BlockWriteDisk->BlockNumber = lba;
1362 +       BlockWriteDisk->ByteCount   = count * 512;
1363 +       BlockWriteDisk->SgMap.SgCount = 1;
1364 +
1365 +
1366 +       if ( BlockWriteDisk->ByteCount > ( 64 * 1024 ) )
1367 +         {
1368 +                 struct scatterlist *scatterlist_ptr;
1369 +                 int segment;
1370 +                 scatterlist_ptr = (struct scatterlist *)scsi_cmnd_ptr->request_buffer;
1371 +
1372 +                 cmn_err( CE_WARN, "\n");
1373 +                 cmn_err( CE_WARN, "AacHba_`DoScsiWrite: WRITE request is larger than 64K");
1374 +                 cmn_err( CE_WARN, "AacHba_DoScsiWrite: ByteCount: %d", BlockWriteDisk->ByteCount);
1375 +                 cmn_err( CE_WARN, "AacHba_DoScsiWrite: SG ELEMENTS: %d", scsi_cmnd_ptr->use_sg);
1376 +                 cmn_err( CE_WARN, "Dump SG Element Size...");
1377 +                 for( segment = 0; segment < scsi_cmnd_ptr->use_sg; segment++ ) 
1378 +                 {
1379 +                         cmn_err (CE_WARN, "SG Segment %d: %d", segment, scatterlist_ptr[segment].length);
1380 +                 }
1381 +                 cmn_err (CE_WARN, "\n");
1382 +
1383 +               scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1384 +
1385 +               AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1386 +                               SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD, 
1387 +                               0, 0, 7, 0 );
1388 +
1389 +               goto err_return;
1390 +       }
1391 +
1392 +       //-------------------------------------------------------------------------
1393 +       // Build Scatter/Gather list
1394 +       //
1395 +       if ( scsi_cmnd_ptr->use_sg )    // use scatter/gather list
1396 +       {
1397 +               struct scatterlist *scatterlist_ptr;
1398 +               int segment;
1399 +               
1400 +               scatterlist_ptr = ( struct scatterlist * )scsi_cmnd_ptr->request_buffer;
1401 +
1402 +               byte_count = 0;
1403 +               for( segment = 0; segment< scsi_cmnd_ptr->use_sg; segment++ ) 
1404 +               {
1405 +                       BlockWriteDisk->SgMap.SgEntry[segment].SgAddress = 
1406 +                               ( HOSTADDRESS )OsVirtToPhys( scatterlist_ptr[segment].address );
1407 +                       BlockWriteDisk->SgMap.SgEntry[segment].SgByteCount = 
1408 +                               scatterlist_ptr[segment].length;
1409 +                       
1410 +                       byte_count += scatterlist_ptr[segment].length;
1411 +
1412 +                       if ( BlockWriteDisk->SgMap.SgEntry[segment].SgByteCount > ( 64 * 1024 ) )
1413 +                       {
1414 +                               cmn_err( CE_WARN, "AacHba_DoScsiWrite: Segment byte count is larger than 64K" );
1415 +                               scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1416 +
1417 +                               AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1418 +                                       SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD, 
1419 +                                       0, 0, 7, 0 );
1420 +
1421 +                               goto err_return;
1422 +                       }
1423 +
1424 +                       /*
1425 +                       cmn_err(CE_DEBUG, "SgEntry[%d].SgAddress = 0x%x, Byte count = 0x%x", 
1426 +                                       segment,
1427 +                                       BlockWriteDisk->SgMap.SgEntry[segment].SgAddress,
1428 +                                       BlockWriteDisk->SgMap.SgEntry[segment].SgByteCount); 
1429 +                       */
1430 +               }
1431 +               BlockWriteDisk->SgMap.SgCount = scsi_cmnd_ptr->use_sg;
1432 +
1433 +               if( BlockWriteDisk->SgMap.SgCount > MAX_DRIVER_SG_SEGMENT_COUNT ) 
1434 +               {
1435 +                       cmn_err( CE_WARN, "AacHba_DoScsiWrite: WRITE request with SgCount > %d", 
1436 +                               MAX_DRIVER_SG_SEGMENT_COUNT );
1437 +                       scsi_cmnd_ptr->result = DID_ERROR << 16;
1438 +                       goto err_return;
1439 +               }
1440 +       } 
1441 +       else            // one piece of contiguous phys mem
1442 +       {
1443 +               BlockWriteDisk->SgMap.SgEntry[0].SgAddress = 
1444 +                       ( HOSTADDRESS )OsVirtToPhys( scsi_cmnd_ptr->request_buffer );
1445 +               BlockWriteDisk->SgMap.SgEntry[0].SgByteCount = scsi_cmnd_ptr->request_bufflen;
1446 +
1447 +               byte_count = scsi_cmnd_ptr->request_bufflen;
1448 +
1449 +               if ( BlockWriteDisk->SgMap.SgEntry[0].SgByteCount > ( 64 * 1024 ) )
1450 +               {
1451 +                       cmn_err( CE_WARN, "AacHba_DoScsiWrite: Single segment byte count is larger than 64K" );
1452 +
1453 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1454 +                       AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1455 +                               SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD, 
1456 +                               0, 0, 7, 0 );
1457 +
1458 +                       goto err_return;
1459 +               }
1460 +       }
1461 +
1462 +       if( byte_count != BlockWriteDisk->ByteCount )
1463 +         cmn_err( CE_WARN, "AacHba_DoScsiWrite: byte_count != BlockReadDisk->ByteCount" );
1464 +
1465 +       //-------------------------------------------------------------------------
1466 +       // Now send the Fib to the adapter
1467 +       //
1468 +       FibSize = sizeof( BLOCKWRITE ) + ( ( BlockWriteDisk->SgMap.SgCount - 1 ) * sizeof( SGENTRY ) );
1469 +
1470 +       if( wait ) 
1471 +       {
1472 +               Status = Adapter->CommFuncs.SendFib( ContainerCommand,
1473 +                                                                                        cmd_fibcontext,
1474 +                                                                                        FibSize,
1475 +                                                                                        FsaNormal,
1476 +                                                                                        TRUE,
1477 +                                                                                        NULL,
1478 +                                                                                        TRUE,
1479 +                                                                                        NULL,
1480 +                                                                                        NULL );
1481 +
1482 +               BlockWriteResponse = ( PBLOCKWRITERESPONSE ) 
1483 +                       Adapter->CommFuncs.GetFibData( cmd_fibcontext );        
1484 +
1485 +               Adapter->CommFuncs.CompleteFib(  cmd_fibcontext );
1486 +               Adapter->CommFuncs.FreeFib(  cmd_fibcontext );
1487 +
1488 +               if( BlockWriteResponse->Status != ST_OK )
1489 +               {
1490 +                       cmn_err( CE_WARN, "AacHba_DoScsiWrite: BlockWriteCommand failed with status: %d\n", 
1491 +                               BlockWriteResponse->Status );
1492 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;;
1493 +                       AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1494 +                               SENKEY_HW_ERR, SENCODE_INTERNAL_TARGET_FAILURE, ASENCODE_INTERNAL_TARGET_FAILURE, 
1495 +                               0, 0, 0, 0 );
1496 +                       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1497 +                       return ( -1 );
1498 +               }
1499 +               else
1500 +                       scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1501 +
1502 +               AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1503 +               return ( 0 );
1504 +       } 
1505 +       else 
1506 +       {
1507 +               Status = Adapter->CommFuncs.SendFib( ContainerCommand,
1508 +                                                                                        cmd_fibcontext,
1509 +                                                                                        FibSize,
1510 +                                                                                        FsaNormal,
1511 +                                                                                        FALSE,
1512 +                                                                                        NULL,
1513 +                                                                                        TRUE,
1514 +                                                                                        ( PFIB_CALLBACK )AacHba_WriteCallback,
1515 +                                                                                        ( void * )scsi_cmnd_ptr );
1516 +
1517 +               // don't call done func here - it should be called by the WriteCallback
1518 +               return ( 0 );
1519 +       }
1520 +
1521 +err_return:
1522 +       AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1523 +
1524 +       Adapter->CommFuncs.CompleteFib( cmd_fibcontext );
1525 +       Adapter->CommFuncs.FreeFib( cmd_fibcontext );
1526 +
1527 +       return ( -1 );
1528 +}
1529 +
1530 +
1531 +/*------------------------------------------------------------------------------
1532 +       AacHba_ReadCallback()
1533 + *----------------------------------------------------------------------------*/
1534 +void AacHba_ReadCallback(  
1535 +       VOID                    *Context,
1536 +       PFIB_CONTEXT    FibContext,
1537 +       int                             FibStatus )
1538 +/*----------------------------------------------------------------------------*/
1539 +{
1540 +       PCI_MINIPORT_COMMON_EXTENSION   *CommonExtension;
1541 +       AFA_COMM_ADAPTER                                *Adapter;
1542 +       BLOCKREADRESPONSE                               *BlockReadResponse;
1543 +       Scsi_Cmnd * scsi_cmnd_ptr;
1544 +       u_long                                                  lba;
1545 +       int                     ContainerId;
1546 +
1547 +       scsi_cmnd_ptr = ( Scsi_Cmnd * )Context;
1548 +
1549 +       CommonExtension = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
1550 +       Adapter         = ( AFA_COMM_ADAPTER * )CommonExtension->Adapter;
1551 +
1552 +       ContainerId = TARGET_LUN_TO_CONTAINER( scsi_cmnd_ptr->target, scsi_cmnd_ptr->lun );
1553 +       
1554 +       lba = ( ( scsi_cmnd_ptr->cmnd[1] & 0x1F ) << 16 ) | 
1555 +                       ( scsi_cmnd_ptr->cmnd[2] << 8 ) |
1556 +                       scsi_cmnd_ptr->cmnd[3];
1557 +       cmn_err( CE_DEBUG, "AacHba_ReadCallback[cpu %d]: lba = %ld, t = %ld", smp_processor_id(), lba, jiffies );
1558 +
1559 +       if( FibContext == 0 ) 
1560 +       {
1561 +               cmn_err( CE_WARN, "AacHba_ReadCallback: no fib context" );
1562 +               scsi_cmnd_ptr->result = DID_ERROR << 16;
1563 +               AacHba_CompleteScsi( scsi_cmnd_ptr );
1564 +               return;
1565 +       }
1566 +
1567 +    BlockReadResponse = ( PBLOCKREADRESPONSE )Adapter->CommFuncs.GetFibData( FibContext );
1568 +
1569 +       if ( BlockReadResponse->Status == ST_OK ) 
1570 +               scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1571 +       else 
1572 +       {
1573 +               cmn_err( CE_WARN, "AacHba_ReadCallback: read failed, status = %d\n", 
1574 +                       BlockReadResponse->Status );
1575 +               scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1576 +               AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1577 +                       SENKEY_HW_ERR, SENCODE_INTERNAL_TARGET_FAILURE, ASENCODE_INTERNAL_TARGET_FAILURE, 
1578 +                       0, 0, 0, 0 );
1579 +       }
1580 +
1581 +#ifdef DEBUG_SGBUFFER
1582 +       if ( scsi_cmnd_ptr->use_sg )    // use scatter/gather list
1583 +       {
1584 +               struct scatterlist *scatterlist_ptr;
1585 +               int i, segment, count;
1586 +               char *ptr;
1587 +               
1588 +               scatterlist_ptr = ( struct scatterlist * )scsi_cmnd_ptr->request_buffer;
1589 +
1590 +               for( segment = 0; segment < scsi_cmnd_ptr->use_sg; segment++ ) 
1591 +               {
1592 +                       count = 0;
1593 +                       ptr = scatterlist_ptr[segment].address;
1594 +                       for( i = 0; i < scatterlist_ptr[segment].length; i++ )
1595 +                       {
1596 +                               if( *( ptr++ ) == 0xa5 )
1597 +                                       count++;
1598 +                       }
1599 +                       if( count == scatterlist_ptr[segment].length )
1600 +                               cmn_err( CE_WARN, "AacHba_ReadCallback: segment %d not filled", segment );
1601 +
1602 +               }
1603 +       }
1604 +#endif
1605 +
1606 +       Adapter->CommFuncs.CompleteFib( FibContext );
1607 +       Adapter->CommFuncs.FreeFib( FibContext );
1608 +
1609 +       AacHba_CompleteScsi( scsi_cmnd_ptr );
1610 +}
1611 +
1612 +/*------------------------------------------------------------------------------
1613 +       AacHba_WriteCallback()
1614 + *----------------------------------------------------------------------------*/
1615 +void AacHba_WriteCallback(  
1616 +       VOID                    *Context,
1617 +       PFIB_CONTEXT    FibContext,
1618 +       int                             FibStatus )
1619 +/*----------------------------------------------------------------------------*/
1620 +{
1621 +       PCI_MINIPORT_COMMON_EXTENSION   *CommonExtension;
1622 +       AFA_COMM_ADAPTER                                *Adapter;
1623 +       BLOCKWRITERESPONSE                              *BlockWriteResponse;
1624 +       Scsi_Cmnd                                               *scsi_cmnd_ptr;
1625 +       u_long                                                  lba;
1626 +       int                     ContainerId;
1627 +
1628 +       scsi_cmnd_ptr = ( Scsi_Cmnd * )Context;
1629 +
1630 +       CommonExtension = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
1631 +       Adapter         = ( AFA_COMM_ADAPTER * )CommonExtension->Adapter;
1632 +       
1633 +       ContainerId = TARGET_LUN_TO_CONTAINER( scsi_cmnd_ptr->target, scsi_cmnd_ptr->lun );
1634 +
1635 +       lba = ( ( scsi_cmnd_ptr->cmnd[1] & 0x1F ) << 16 ) | 
1636 +                       ( scsi_cmnd_ptr->cmnd[2] << 8 ) |
1637 +                       scsi_cmnd_ptr->cmnd[3];
1638 +       cmn_err( CE_DEBUG, "AacHba_WriteCallback[cpu %d]: lba = %ld, t = %ld", smp_processor_id(), lba, jiffies );
1639 +       if( FibContext == 0 ) 
1640 +       {
1641 +               cmn_err( CE_WARN, "AacHba_WriteCallback: no fib context" );
1642 +               scsi_cmnd_ptr->result = DID_ERROR << 16;
1643 +               AacHba_CompleteScsi( scsi_cmnd_ptr );
1644 +               return;
1645 +       }
1646 +
1647 +    BlockWriteResponse = (PBLOCKWRITERESPONSE) Adapter->CommFuncs.GetFibData( FibContext );
1648 +       if (BlockWriteResponse->Status == ST_OK) 
1649 +               scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1650 +       else 
1651 +       {
1652 +               cmn_err( CE_WARN, "AacHba_WriteCallback: write failed, status = %d\n", 
1653 +                       BlockWriteResponse->Status );
1654 +               scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1655 +               AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1656 +                       SENKEY_HW_ERR, SENCODE_INTERNAL_TARGET_FAILURE, ASENCODE_INTERNAL_TARGET_FAILURE, 
1657 +                       0, 0, 0, 0 );
1658 +       }
1659 +
1660 +       Adapter->CommFuncs.CompleteFib( FibContext );
1661 +       Adapter->CommFuncs.FreeFib( FibContext );
1662 +
1663 +       AacHba_CompleteScsi( scsi_cmnd_ptr );
1664 +}
1665 +
1666 +
1667 +/*------------------------------------------------------------------------------
1668 +       AacHba_Ioctl()
1669 +
1670 +               Handle IOCTL requests
1671 +
1672 +       Preconditions:
1673 +       Postconditions:
1674 + *----------------------------------------------------------------------------*/
1675 +int AacHba_Ioctl(
1676 +       PCI_MINIPORT_COMMON_EXTENSION *CommonExtension,
1677 +       int cmd,
1678 +       void * arg )
1679 +/*----------------------------------------------------------------------------*/
1680 +{
1681 +       Sa_ADAPTER_EXTENSION              *AdapterExtension;
1682 +       AFA_IOCTL_CMD IoctlCmd;
1683 +       int status;
1684 +       
1685 +       AdapterExtension = ( Sa_ADAPTER_EXTENSION * )CommonExtension->MiniPort;
1686 +
1687 +       cmn_err( CE_DEBUG, "AacHba_Ioctl, type = %d", cmd );
1688 +       switch( cmd )
1689 +       {
1690 +         case FSACTL_SENDFIB:
1691 +                 cmn_err( CE_DEBUG, "FSACTL_SENDFIB" );
1692 +               break;
1693 +
1694 +         case FSACTL_AIF_THREAD:
1695 +                 cmn_err( CE_DEBUG, "FSACTL_AIF_THREAD" );
1696 +               break;
1697 +
1698 +         case FSACTL_NULL_IO_TEST:
1699 +                 cmn_err( CE_DEBUG, "FSACTL_NULL_IO_TEST" );
1700 +               break;
1701 +
1702 +         case FSACTL_SIM_IO_TEST:
1703 +                 cmn_err( CE_DEBUG, "FSACTL_SIM_IO_TEST" );
1704 +               break;
1705 +
1706 +         case FSACTL_GET_FIBTIMES:
1707 +                 cmn_err( CE_DEBUG, "FSACTL_GET_FIBTIMES" );
1708 +               break;
1709 +
1710 +         case FSACTL_ZERO_FIBTIMES:
1711 +                 cmn_err( CE_DEBUG, "FSACTL_ZERO_FIBTIMES");
1712 +               break;
1713 +
1714 +         case FSACTL_GET_VAR:
1715 +                 cmn_err( CE_DEBUG, "FSACTL_GET_VAR" );
1716 +               break;
1717 +
1718 +         case FSACTL_SET_VAR:
1719 +                 cmn_err( CE_DEBUG, "FSACTL_SET_VAR" );
1720 +               break;
1721 +
1722 +         case FSACTL_OPEN_ADAPTER_CONFIG:
1723 +                 cmn_err( CE_DEBUG, "FSACTL_OPEN_ADAPTER_CONFIG" );
1724 +               break;  
1725 +
1726 +         case FSACTL_CLOSE_ADAPTER_CONFIG:
1727 +                 cmn_err( CE_DEBUG, "FSACTL_CLOSE_ADAPTER_CONFIG" );
1728 +               break;
1729 +
1730 +         case FSACTL_QUERY_ADAPTER_CONFIG:
1731 +                 cmn_err( CE_DEBUG, "FSACTL_QUERY_ADAPTER_CONFIG" );
1732 +               break;
1733 +
1734 +         case FSACTL_OPEN_GET_ADAPTER_FIB:
1735 +                 cmn_err( CE_DEBUG, "FSACTL_OPEN_GET_ADAPTER_FIB" );
1736 +               break;
1737 +
1738 +         case FSACTL_GET_NEXT_ADAPTER_FIB:
1739 +                 cmn_err( CE_DEBUG, "FSACTL_GET_NEXT_ADAPTER_FIB" );
1740 +               break;
1741 +
1742 +         case FSACTL_CLOSE_GET_ADAPTER_FIB:
1743 +                 cmn_err( CE_DEBUG, "FSACTL_CLOSE_GET_ADAPTER_FIB" );
1744 +               break;
1745 +
1746 +         case FSACTL_MINIPORT_REV_CHECK:
1747 +                 cmn_err( CE_DEBUG, "FSACTL_MINIPORT_REV_CHECK" );
1748 +               break;
1749 +
1750 +         case FSACTL_OPENCLS_COMM_PERF_DATA:
1751 +                 cmn_err( CE_DEBUG, "FSACTL_OPENCLS_COMM_PERF_DATA" );
1752 +               break;
1753 +       
1754 +         case FSACTL_GET_COMM_PERF_DATA:
1755 +                 cmn_err( CE_DEBUG, "FSACTL_GET_COMM_PERF_DATA" );
1756 +               break;
1757 +
1758 +         case FSACTL_QUERY_DISK:
1759 +                 cmn_err( CE_DEBUG, "FSACTL_QUERY_DISK" );
1760 +               break;
1761 +               
1762 +         case FSACTL_DELETE_DISK:
1763 +                 cmn_err( CE_DEBUG, "FSACTL_DELETE_DISK" );
1764 +               break;
1765 +
1766 +         default:
1767 +                 cmn_err( CE_DEBUG, "Unknown ioctl: 0x%x", cmd );
1768 +       }
1769 +
1770 +       IoctlCmd.cmd = cmd;
1771 +       IoctlCmd.arg = ( intptr_t )arg;
1772 +       IoctlCmd.flag = 0;
1773 +       IoctlCmd.cred_p = 0;
1774 +       IoctlCmd.rval_p = 0;
1775 +
1776 +       status = AfaCommAdapterDeviceControl( CommonExtension->Adapter, &IoctlCmd );
1777 +       cmn_err( CE_DEBUG, "AAC_Ioctl, completion status = %d", status );
1778 +       return( status );
1779 +}
1780 +
1781 +
1782 +/*------------------------------------------------------------------------------
1783 +       AacHba_AdapterDeviceControl()
1784 +
1785 +       Preconditions:
1786 +       Postconditions:
1787 +               Returns TRUE if ioctl handled, FALSE otherwise
1788 +               *ReturnStatus set to completion status
1789 + *----------------------------------------------------------------------------*/
1790 +BOOLEAN AacHba_AdapterDeviceControl (
1791 +       PVOID AdapterArg,               // CommonExtensionPtr
1792 +       IN PAFA_IOCTL_CMD IoctlCmdPtr,
1793 +       OUT int * ReturnStatus )
1794 +/*----------------------------------------------------------------------------*/
1795 +{
1796 +       BOOLEAN Handled = TRUE; // start out handling it.
1797 +       int Status = EFAULT;
1798 +
1799 +       switch( IoctlCmdPtr->cmd )
1800 +       {
1801 +               case FSACTL_QUERY_DISK:
1802 +                       Status = AacHba_QueryDisk( AdapterArg, IoctlCmdPtr );
1803 +                       break;
1804 +
1805 +               case FSACTL_DELETE_DISK:
1806 +                       Status = AacHba_DeleteDisk( AdapterArg, IoctlCmdPtr );
1807 +                       break;
1808 +
1809 +               case FSACTL_FORCE_DELETE_DISK:
1810 +                       Status = AacHba_ForceDeleteDisk( AdapterArg, IoctlCmdPtr );
1811 +                       break;
1812 +
1813 +               case 2131:
1814 +                       if( AacHba_ProbeContainers( ( PCI_MINIPORT_COMMON_EXTENSION * )AdapterArg ) )
1815 +                               Status = -EFAULT;
1816 +                       break;
1817 +
1818 +               default:
1819 +                       Handled = FALSE;
1820 +                       break;
1821 +       }
1822 +
1823 +       *ReturnStatus = Status;
1824 +
1825 +       return( Handled );
1826 +}
1827 +
1828 +
1829 +/*------------------------------------------------------------------------------
1830 +       AacHba_QueryDisk()
1831 +
1832 +       Postconditions:
1833 +               Return values
1834 +               0       = OK
1835 +               -EFAULT = Bad address
1836 +               -EINVAL = Bad container number
1837 + *----------------------------------------------------------------------------*/
1838 +int AacHba_QueryDisk(
1839 +       PVOID AdapterArg,               // CommonExtensionPtr
1840 +       IN PAFA_IOCTL_CMD IoctlCmdPtr )
1841 +/*----------------------------------------------------------------------------*/
1842 +{
1843 +       UNIX_QUERY_DISK QueryDisk;
1844 +       PCI_MINIPORT_COMMON_EXTENSION   *CommonExtensionPtr;
1845 +       fsadev_t                                                *fsa_dev_ptr;
1846 +
1847 +       CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )AdapterArg;
1848 +       fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
1849 +
1850 +       if( copyin( IoctlCmdPtr->arg, &QueryDisk, sizeof( UNIX_QUERY_DISK ) ) )
1851 +               return( -EFAULT );
1852 +
1853 +       if (QueryDisk.ContainerNumber == -1)
1854 +               QueryDisk.ContainerNumber = TARGET_LUN_TO_CONTAINER( QueryDisk.Target, QueryDisk.Lun );
1855 +       else 
1856 +               if( ( QueryDisk.Bus == -1 ) && ( QueryDisk.Target == -1 ) && ( QueryDisk.Lun == -1 ) )
1857 +               {
1858 +                       if( QueryDisk.ContainerNumber > MAXIMUM_NUM_CONTAINERS )
1859 +                               return( -EINVAL );
1860 +
1861 +                       QueryDisk.Instance = CommonExtensionPtr->OsDep.scsi_host_ptr->host_no;
1862 +                       QueryDisk.Bus = 0;
1863 +                       QueryDisk.Target = CONTAINER_TO_TARGET( QueryDisk.ContainerNumber );
1864 +                       QueryDisk.Lun = CONTAINER_TO_LUN( QueryDisk.ContainerNumber );
1865 +               }
1866 +               else 
1867 +                       return( -EINVAL );
1868 +
1869 +       QueryDisk.Valid = fsa_dev_ptr->ContainerValid[QueryDisk.ContainerNumber];
1870 +       QueryDisk.Locked = fsa_dev_ptr->ContainerLocked[QueryDisk.ContainerNumber];
1871 +       QueryDisk.Deleted = fsa_dev_ptr->ContainerDeleted[QueryDisk.ContainerNumber];
1872 +
1873 +       if( fsa_dev_ptr->ContainerDevNo[QueryDisk.ContainerNumber] == -1 )
1874 +               QueryDisk.UnMapped = TRUE;
1875 +       else
1876 +               QueryDisk.UnMapped = FALSE;
1877 +
1878 +       get_sd_devname( fsa_dev_ptr->ContainerDevNo[QueryDisk.ContainerNumber], 
1879 +               QueryDisk.diskDeviceName );
1880 +
1881 +       if( copyout( &QueryDisk, IoctlCmdPtr->arg, sizeof( UNIX_QUERY_DISK ) ) )
1882 +               return( -EFAULT );
1883 +
1884 +       return( 0 );
1885 +}
1886 +
1887 +
1888 +/*------------------------------------------------------------------------------
1889 +       get_sd_devname()
1890 + *----------------------------------------------------------------------------*/
1891 +static void get_sd_devname(
1892 +       long disknum, 
1893 +       char * buffer)
1894 +/*----------------------------------------------------------------------------*/
1895 +{
1896 +       if( disknum < 0 )
1897 +       {
1898 +        sprintf(buffer, "%s", "");
1899 +               return;
1900 +       }
1901 +
1902 +   if( disknum < 26 )
1903 +        sprintf(buffer, "sd%c", 'a' + disknum);
1904 +    else {
1905 +        unsigned int min1;
1906 +        unsigned int min2;
1907 +        /*
1908 +         * For larger numbers of disks, we need to go to a new
1909 +         * naming scheme.
1910 +         */
1911 +        min1 = disknum / 26;
1912 +        min2 = disknum % 26;
1913 +        sprintf(buffer, "sd%c%c", 'a' + min1 - 1, 'a' + min2);
1914 +    }
1915 +}
1916 +
1917 +
1918 +/*------------------------------------------------------------------------------
1919 +       AacHba_ForceDeleteDisk()
1920 +
1921 +       Postconditions:
1922 +               Return values
1923 +               0       = OK
1924 +               -EFAULT = Bad address
1925 +               -EINVAL = Bad container number
1926 + *----------------------------------------------------------------------------*/
1927 +int AacHba_ForceDeleteDisk(
1928 +       PVOID AdapterArg,               // CommonExtensionPtr
1929 +       IN PAFA_IOCTL_CMD IoctlCmdPtr )
1930 +/*----------------------------------------------------------------------------*/
1931 +{
1932 +       DELETE_DISK      DeleteDisk;
1933 +       PCI_MINIPORT_COMMON_EXTENSION   *CommonExtensionPtr;
1934 +       fsadev_t                                                *fsa_dev_ptr;
1935 +
1936 +       CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )AdapterArg;
1937 +       fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
1938 +
1939 +       if ( copyin( IoctlCmdPtr->arg,  &DeleteDisk, sizeof( DELETE_DISK ) ) )
1940 +               return( -EFAULT );
1941 +
1942 +       if ( DeleteDisk.ContainerNumber > MAXIMUM_NUM_CONTAINERS ) 
1943 +               return( -EINVAL );
1944 +       
1945 +       // Mark this container as being deleted.
1946 +       fsa_dev_ptr->ContainerDeleted[DeleteDisk.ContainerNumber] = TRUE;
1947 +
1948 +       // Mark the container as no longer valid
1949 +       fsa_dev_ptr->ContainerValid[DeleteDisk.ContainerNumber] = 0;
1950 +
1951 +       return( 0 );
1952 +}
1953 +
1954 +
1955 +/*------------------------------------------------------------------------------
1956 +       AacHba_DeleteDisk()
1957 +
1958 +       Postconditions:
1959 +               Return values
1960 +               0       = OK
1961 +               -EFAULT = Bad address
1962 +               -EINVAL = Bad container number
1963 +               -EBUSY  = Device locked
1964 + *----------------------------------------------------------------------------*/
1965 +int AacHba_DeleteDisk(
1966 +       PVOID AdapterArg,
1967 +       IN PAFA_IOCTL_CMD IoctlCmdPtr )
1968 +/*----------------------------------------------------------------------------*/
1969 +{
1970 +       DELETE_DISK DeleteDisk;
1971 +       PCI_MINIPORT_COMMON_EXTENSION   *CommonExtensionPtr;
1972 +       fsadev_t                                                *fsa_dev_ptr;
1973 +
1974 +       CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )AdapterArg;
1975 +       fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
1976 +
1977 +       if( copyin( IoctlCmdPtr->arg, &DeleteDisk, sizeof( DELETE_DISK ) ) ) 
1978 +               return( -EFAULT );
1979 +
1980 +       if( DeleteDisk.ContainerNumber > MAXIMUM_NUM_CONTAINERS )
1981 +               return( -EINVAL );
1982 +       
1983 +       // If the container is locked, it can not be deleted by the API.
1984 +       if( fsa_dev_ptr->ContainerLocked[DeleteDisk.ContainerNumber] )
1985 +               return( -EBUSY );
1986 +       else 
1987 +       {       
1988 +               // Mark the container as no longer being valid.
1989 +               fsa_dev_ptr->ContainerValid[DeleteDisk.ContainerNumber] = 0;
1990 +               fsa_dev_ptr->ContainerDevNo[DeleteDisk.ContainerNumber] = -1;
1991 +               return(0);
1992 +       }       
1993 +}
1994 +
1995 +
1996 +/*------------------------------------------------------------------------------
1997 +       AacHba_OpenAdapter()
1998 + *----------------------------------------------------------------------------*/
1999 +AAC_STATUS AacHba_OpenAdapter(
2000 +       IN PVOID AdapterArg )
2001 +/*----------------------------------------------------------------------------*/
2002 +{
2003 +       return( STATUS_SUCCESS );
2004 +}
2005 +
2006 +
2007 +/*------------------------------------------------------------------------------
2008 +       AacHba_CloseAdapter()
2009 + *----------------------------------------------------------------------------*/
2010 +AAC_STATUS AacHba_CloseAdapter(
2011 +       IN PVOID AdapterArg )
2012 +/*----------------------------------------------------------------------------*/
2013 +{
2014 +       return( STATUS_SUCCESS );
2015 +}
2016 +
2017 +
2018 +/*------------------------------------------------------------------------------
2019 +       AacHba_DetachAdapter()
2020 + *----------------------------------------------------------------------------*/
2021 +void AacHba_DetachAdapter(
2022 +       IN PVOID AdapterArg )
2023 +/*----------------------------------------------------------------------------*/
2024 +{
2025 +       AacCommDetachAdapter( AdapterArg );
2026 +}
2027 +
2028 +
2029 +/*------------------------------------------------------------------------------
2030 +       AacHba_AbortScsiCommand()
2031 + *----------------------------------------------------------------------------*/
2032 +void AacHba_AbortScsiCommand(
2033 +       Scsi_Cmnd *scsi_cmnd_ptr )
2034 +/*----------------------------------------------------------------------------*/
2035 +{
2036 +       u_short interrupt_status;
2037 +       PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
2038 +
2039 +       CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
2040 +       interrupt_status = Sa_READ_USHORT( ( PSa_ADAPTER_EXTENSION )( CommonExtensionPtr->MiniPort ),
2041 +               DoorbellReg_p );
2042 +       cmn_err( CE_WARN, "interrupt_status = %d", interrupt_status );
2043 +       
2044 +       if( interrupt_status & DOORBELL_1) {    // Adapter -> Host Normal Command Ready
2045 +               cmn_err( CE_WARN, "DOORBELL_1: Adapter -> Host Normal Command Ready" );
2046 +       } 
2047 +
2048 +       if( interrupt_status & DOORBELL_2) {    // Adapter -> Host Normal Response Ready
2049 +               cmn_err( CE_WARN, "DOORBELL_2: Adapter -> Host Normal Response Ready" );
2050 +       }
2051 +
2052 +       if ( interrupt_status & DOORBELL_3) {   // Adapter -> Host Normal Command Not Full
2053 +               cmn_err( CE_WARN, "DOORBELL_3: Adapter -> Host Normal Command Not Full" );
2054 +       }
2055 +
2056 +       if ( interrupt_status & DOORBELL_4) {   // Adapter -> Host Normal Response Not Full
2057 +               cmn_err( CE_WARN, "DOORBELL_4: Adapter -> Host Normal Response Not Full" );
2058 +       }
2059 +
2060 +}
2061 +
2062 +
2063 +/*------------------------------------------------------------------------------
2064 +       AacHba_HandleAif()
2065 + *----------------------------------------------------------------------------*/
2066 +BOOLEAN AacHba_HandleAif(
2067 +       IN PVOID AdapterArg,
2068 +       IN PFIB_CONTEXT FibContext )
2069 +/*----------------------------------------------------------------------------*/
2070 +{
2071 +       return( FALSE );
2072 +}
2073 +
2074 +
2075 +/*------------------------------------------------------------------------------
2076 +       AacHba_SetSenseData()
2077 +               Fill in the sense data.
2078 +       Preconditions:
2079 +       Postconditions:
2080 + *----------------------------------------------------------------------------*/
2081 +void AacHba_SetSenseData(
2082 +       char * sense_buf,
2083 +       unchar sense_key,
2084 +       unchar sense_code,
2085 +       unchar a_sense_code,
2086 +       unchar incorrect_length,
2087 +       unchar bit_pointer,
2088 +       unsigned field_pointer,
2089 +       unsigned long residue )
2090 +/*----------------------------------------------------------------------------*/
2091 +{
2092 +       sense_buf[0] = 0xF0;                    // Sense data valid, err code 70h (current error)
2093 +       sense_buf[1] = 0;                                                               // Segment number, always zero
2094 +
2095 +       if( incorrect_length )
2096 +       {
2097 +               sense_buf[2] = sense_key | 0x20;                // Set the ILI bit | sense key
2098 +               sense_buf[3] = BYTE3(residue);
2099 +               sense_buf[4] = BYTE2(residue);
2100 +               sense_buf[5] = BYTE1(residue);
2101 +               sense_buf[6] = BYTE0(residue);
2102 +       }
2103 +       else
2104 +               sense_buf[2] = sense_key;                               // Sense key
2105 +
2106 +       if( sense_key == SENKEY_ILLEGAL )
2107 +               sense_buf[7] = 10;                                              // Additional sense length
2108 +       else
2109 +               sense_buf[7] = 6;                                               // Additional sense length
2110 +
2111 +       sense_buf[12] = sense_code;                             // Additional sense code
2112 +       sense_buf[13] = a_sense_code;                           // Additional sense code qualifier
2113 +       if( sense_key == SENKEY_ILLEGAL )
2114 +       {
2115 +               sense_buf[15] = 0;
2116 +
2117 +               if( sense_code == SENCODE_INVALID_PARAM_FIELD )
2118 +                       sense_buf[15] = 0x80;                           // Std sense key specific field
2119 +                                                                                               // Illegal parameter is in the parameter block
2120 +
2121 +               if( sense_code == SENCODE_INVALID_CDB_FIELD )
2122 +                       sense_buf[15] = 0xc0;                           // Std sense key specific field
2123 +                                                                                               // Illegal parameter is in the CDB block
2124 +               sense_buf[15] |= bit_pointer;
2125 +               sense_buf[16] = field_pointer >> 8;     // MSB
2126 +               sense_buf[17] = field_pointer;          // LSB
2127 +       }
2128 +}
2129 +
2130 diff -urN linux/drivers/scsi/aacraid/aacid.c linux/drivers/scsi/aacraid/aacid.c
2131 --- linux/drivers/scsi/aacraid/aacid.c  Wed Dec 31 19:00:00 1969
2132 +++ linux/drivers/scsi/aacraid/aacid.c  Thu Dec 21 13:14:30 2000
2133 @@ -0,0 +1,153 @@
2134 +/*++
2135 + * Adaptec aacraid device driver for Linux.
2136 + *
2137 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
2138 + *
2139 + * This program is free software; you can redistribute it and/or modify
2140 + * it under the terms of the GNU General Public License as published by
2141 + * the Free Software Foundation; either version 2, or (at your option)
2142 + * any later version.
2143 + *
2144 + * This program is distributed in the hope that it will be useful,
2145 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2146 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
2147 + * GNU General Public License for more details.
2148 + *
2149 + * You should have received a copy of the GNU General Public License
2150 + * along with this program; see the file COPYING.  If not, write to
2151 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
2152 + *
2153 + * Module Name:
2154 + *  aac.c
2155 + *
2156 + * Abstract: Data structures for controller specific info.
2157 + *
2158 +--*/
2159 +
2160 +static char *ident_aacid = "aacraid_ident aacid.c 1.0.6 2000/10/09 Adaptec, Inc.";
2161 +
2162 +#include "osheaders.h"
2163 +
2164 +#include "AacGenericTypes.h"
2165 +
2166 +#include "aac_unix_defs.h"
2167 +
2168 +#include "fsatypes.h"
2169 +#include "comstruc.h"
2170 +#include "fsaport.h"
2171 +#include "pcisup.h"
2172 +
2173 +#include "version.h"
2174 +
2175 +
2176 +/* Function Prototypes */
2177 +void InqStrCopy(char *a, char *b); /* ossup.c */
2178 +
2179 +/* Device name used to register and unregister
2180 +   the device in linit.c */
2181 +char devicestr[]="aac";
2182 +
2183 +char *container_types[] = {
2184 +        "None",
2185 +        "Volume",
2186 +        "Mirror",
2187 +        "Stripe",
2188 +        "RAID5",
2189 +        "SSRW",
2190 +        "SSRO",
2191 +        "Morph",
2192 +        "Legacy",
2193 +        "RAID4",
2194 +        "RAID10",             
2195 +        "RAID00",             
2196 +        "V-MIRRORS",          
2197 +        "PSEUDO R4",          
2198 +       "RAID50",
2199 +        "Unknown"
2200 +};
2201 +
2202 +/* Local Structure to set SCSI inquiry data strings */
2203 +typedef struct _INQSTR {
2204 +  char vid[8];         /* Vendor ID */
2205 +  char pid[16];        /* Product ID */
2206 +  char prl[4];         /* Product Revision Level */
2207 +} INQSTR, *INQSTRP;
2208 +
2209 +FSA_MINIPORT MiniPorts[];
2210 +
2211 +/* Function: SetInqDataStr
2212 + *
2213 + * Arguments: [1] pointer to void [1] int
2214 + *
2215 + * Purpose: Sets SCSI inquiry data strings for vendor, product
2216 + * and revision level. Allows strings to be set in platform dependant
2217 + * files instead of in OS dependant driver source.
2218 + */
2219 +void
2220 +SetInqDataStr (
2221 +  int MiniPortIndex,
2222 +  void *dataPtr,
2223 +  int tindex)
2224 +{
2225 +  INQSTRP InqStrPtr;
2226 +   char *findit;
2227 +   FSA_MINIPORT   *mp;
2228 +
2229 +   mp = &MiniPorts[MiniPortIndex];
2230 +   
2231 +    InqStrPtr = (INQSTRP)(dataPtr); /* cast dataPtr to type INQSTRP */
2232 +
2233 +    InqStrCopy (mp->Vendor, InqStrPtr->vid); 
2234 +    InqStrCopy (mp->Model,  InqStrPtr->pid); /* last six chars reserved for vol type */
2235 +
2236 +    findit = InqStrPtr->pid;
2237 +
2238 +    for ( ; *findit != ' '; findit++); /* walk till we find a space then incr by 1 */
2239 +        findit++;
2240 +       
2241 +    if (tindex < (sizeof(container_types)/sizeof(char *))){
2242 +      InqStrCopy (container_types[tindex], findit);
2243 +    }
2244 +   InqStrCopy ("0001", InqStrPtr->prl);
2245 +}
2246 +
2247 +int
2248 +SaInitDevice(
2249 +       IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
2250 +       IN ULONG AdapterNumber,
2251 +       IN ULONG PciBus,
2252 +       IN ULONG PciSlot
2253 +);
2254 +
2255 +int
2256 +RxInitDevice(
2257 +       IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
2258 +       IN ULONG AdapterNumber,
2259 +       IN ULONG PciBus,
2260 +       IN ULONG PciSlot
2261 +);
2262 +
2263 +
2264 +/*
2265 + * Because of the way Linux names scsi devices, the order in this table has
2266 + * become important.  Check for on-board Raid first, add-in cards second.
2267 + */
2268 +
2269 +FSA_MINIPORT MiniPorts[] = {
2270 +       { 0x1028, 0x0001, 0x1028, 0x0001, "afa", RxInitDevice, "percraid", "DELL    ", "PERCRAID        " }, /* PERC 3/Si */
2271 +       { 0x1028, 0x0002, 0x1028, 0x0002, "afa", RxInitDevice, "percraid", "DELL    ", "PERCRAID        " }, /* PERC 3/Di */
2272 +       { 0x1028, 0x0003, 0x1028, 0x0003, "afa", RxInitDevice, "percraid", "DELL    ", "PERCRAID        " }, /* PERC 3/Si */
2273 +       { 0x1028, 0x0004, 0x1028, 0x00d0, "afa", RxInitDevice, "percraid", "DELL    ", "PERCRAID        " }, /* PERC 3/Si */
2274 +       { 0x1028, 0x0002, 0x1028, 0x00d1, "afa", RxInitDevice, "percraid", "DELL    ", "PERCRAID        " }, /* PERC 3/Di */
2275 +       { 0x1028, 0x0002, 0x1028, 0x00d9, "afa", RxInitDevice, "percraid", "DELL    ", "PERCRAID        " }, /* PERC 3/Di */
2276 +       { 0x1028, 0x0008, 0x1028, 0x00cf, "afa", RxInitDevice, "percraid", "DELL    ", "PERCRAID        " }, /* PERC 3/Di */
2277 +       { 0x1011, 0x0046, 0x9005, 0x1364, "afa", SaInitDevice, "percraid", "DELL    ", "PERCRAID        " }, /* Dell PERC2 "Quad Channel */
2278 +       { 0x1011, 0x0046, 0x103c, 0x10c2, "hpn", SaInitDevice, "hpnraid",  "HP      ", "NetRAID-4M      " }  /* HP NetRAID-4M */
2279 +};
2280 +
2281 +
2282 +#define NUM_MINIPORTS  (sizeof(MiniPorts) / sizeof(FSA_MINIPORT))
2283 +
2284 +int NumMiniPorts = NUM_MINIPORTS;
2285 +
2286 +char DescriptionString[] =     "AACxxx Raid Controller" FSA_VERSION_STRING ;
2287 diff -urN linux/drivers/scsi/aacraid/commctrl.c linux/drivers/scsi/aacraid/commctrl.c
2288 --- linux/drivers/scsi/aacraid/commctrl.c       Wed Dec 31 19:00:00 1969
2289 +++ linux/drivers/scsi/aacraid/commctrl.c       Thu Dec 21 13:14:30 2000
2290 @@ -0,0 +1,1098 @@
2291 +/*++
2292 + * Adaptec aacraid device driver for Linux.
2293 + *
2294 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
2295 + *
2296 + * This program is free software; you can redistribute it and/or modify
2297 + * it under the terms of the GNU General Public License as published by
2298 + * the Free Software Foundation; either version 2, or (at your option)
2299 + * any later version.
2300 + *
2301 + * This program is distributed in the hope that it will be useful,
2302 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2303 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
2304 + * GNU General Public License for more details.
2305 + *
2306 + * You should have received a copy of the GNU General Public License
2307 + * along with this program; see the file COPYING.  If not, write to
2308 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
2309 + *
2310 + * Module Name:
2311 + *  commctrl.c
2312 + *
2313 + * Abstract: Contains all routines for control of the AFA comm layer
2314 + *
2315 +--*/
2316 +
2317 +static char *ident_commctrl = "aacraid_ident commctrl.c 1.0.7 2000/10/11 Adaptec, Inc.";
2318 +
2319 +#include "comprocs.h"
2320 +#include "osheaders.h"
2321 +#include "ostypes.h"
2322 +
2323 +
2324 +
2325 +
2326 +
2327 +typedef BOOLEAN BOOL;
2328 +#define inline /* _inline */
2329 +
2330 +#include <revision.h>
2331 +AAC_STATUS
2332 +FsaCtlCheckRevision(
2333 +       IN PAFA_COMM_ADAPTER    Adapter,
2334 +       IN PAFA_IOCTL_CMD               IoctlCmdPtr
2335 +       )
2336 +/*++
2337 +
2338 +Routine Description:
2339 +
2340 +       This routine validates the revision of the caller with the current revision
2341 +       of the filesystem.
2342 +
2343 +Arguments:
2344 +
2345 +       Adapter - Supplies which adapter is being processed.
2346 +
2347 +    Irp - Supplies the Irp being processed.
2348 +
2349 +       IrpContext - Supplies the IrpContext.
2350 +
2351 +Return Value:
2352 +
2353 +       AAC_STATUS
2354 +
2355 +--*/
2356 +
2357 +{
2358 +       RevCheck APIRevCheck;
2359 +       RevCheckResp APIRevCheckResp;
2360 +       RevComponent APICallingComponent;
2361 +       ULONG APIBuildNumber;
2362 +
2363 +       if (COPYIN( (caddr_t) IoctlCmdPtr->arg, (caddr_t) &APIRevCheck, sizeof(RevCheck), IoctlCmdPtr->flag )) {
2364 +               return (EFAULT);
2365 +       }
2366 +
2367 +       APICallingComponent = APIRevCheck.callingComponent;
2368 +       APIBuildNumber = APIRevCheck.callingRevision.buildNumber;
2369 +
2370 +       APIRevCheckResp.possiblyCompatible = RevCheckCompatibility( RevMiniportDriver , APICallingComponent, APIBuildNumber );
2371 +
2372 +       APIRevCheckResp.adapterSWRevision.external.ul = RevGetExternalRev();
2373 +       APIRevCheckResp.adapterSWRevision.buildNumber = RevGetBuildNumber();
2374 +
2375 +       if (COPYOUT( (caddr_t) &APIRevCheckResp, (caddr_t) IoctlCmdPtr->arg, sizeof(RevCheckResp), IoctlCmdPtr->flag )) {
2376 +               return (EFAULT);
2377 +       }
2378 +
2379 +       return (0);
2380 +}
2381 +
2382 +
2383 +int
2384 +AfaCommAdapterDeviceControl(
2385 +       IN PVOID AdapterArg,
2386 +       IN PAFA_IOCTL_CMD IoctlCmdPtr
2387 +       )
2388 +{
2389 +       PAFA_COMM_ADAPTER Adapter = (PAFA_COMM_ADAPTER) AdapterArg;
2390 +    int Status = ENOTTY;
2391 +//    PIO_STACK_LOCATION IrpSp;
2392 +       PAFA_CLASS_DRIVER ClassDriver;
2393 +
2394 +       //
2395 +       // First loop through all of the class drivers to give them a chance to handle
2396 +       // the Device control first.
2397 +       //
2398 +
2399 +       ClassDriver = Adapter->ClassDriverList;
2400 +
2401 +       while (ClassDriver) {
2402 +
2403 +               if (ClassDriver->DeviceControl) {
2404 +
2405 +                       if (ClassDriver->DeviceControl( ClassDriver->ClassDriverExtension, IoctlCmdPtr, &Status ) ) {
2406 +
2407 +                               return (Status);
2408 +
2409 +                       }
2410 +               }
2411 +
2412 +               ClassDriver = ClassDriver->Next;
2413 +       }
2414 +
2415 +    switch (IoctlCmdPtr->cmd) {
2416 +
2417 +
2418 +         case FSACTL_SENDFIB:
2419 +
2420 +               Status = AfaCommCtlSendFib( Adapter, IoctlCmdPtr );
2421 +               break;
2422 +
2423 +         case FSACTL_AIF_THREAD:
2424 +
2425 +               Status = AfaCommCtlAifThread( Adapter, IoctlCmdPtr );   
2426 +               break;
2427 +
2428 +
2429 +         case FSACTL_OPEN_GET_ADAPTER_FIB:
2430 +
2431 +               Status = FsaCtlOpenGetAdapterFib( Adapter, IoctlCmdPtr );
2432 +               break;
2433 +
2434 +         case FSACTL_GET_NEXT_ADAPTER_FIB:
2435 +
2436 +               Status = FsaCtlGetNextAdapterFib( Adapter, IoctlCmdPtr );
2437 +               break;
2438 +
2439 +         case FSACTL_CLOSE_GET_ADAPTER_FIB:
2440 +
2441 +               Status = FsaCtlCloseGetAdapterFib( Adapter, IoctlCmdPtr );
2442 +               break;
2443 +
2444 +         case FSACTL_MINIPORT_REV_CHECK:
2445 +        
2446 +               Status = FsaCtlCheckRevision( Adapter , IoctlCmdPtr );
2447 +               break;
2448 +
2449 +
2450 +      default:
2451 +         
2452 +               Status = ENOTTY;
2453 +               break;  
2454 +
2455 +       }
2456 +
2457 +
2458 +       return (Status);
2459 +}
2460 +
2461 +AAC_STATUS
2462 +AfaCommRegisterNewClassDriver(
2463 +       IN PAFA_COMM_ADAPTER    Adapter,
2464 +       IN PAFA_NEW_CLASS_DRIVER        NewClassDriver,
2465 +       OUT PAFA_NEW_CLASS_DRIVER_RESPONSE NewClassDriverResponse
2466 +       )
2467 +/*++
2468 +
2469 +Routine Description:
2470 +
2471 +       This routine registers a new class driver for the comm layer.
2472 +
2473 +       It will return a pointer to the communication functions for the class driver
2474 +       to use.
2475 +
2476 +Arguments:
2477 +
2478 +       Adapter - Supplies which adapter is being processed.
2479 +
2480 +    Irp - Supplies the Irp being processed.
2481 +
2482 +Return Value:
2483 +
2484 +       STATUS_SUCCESS           - Everything OK.
2485 +
2486 +--*/
2487 +{
2488 +       AAC_STATUS Status;
2489 +       PAFA_CLASS_DRIVER ClassDriver;
2490 +
2491 +
2492 +       ClassDriver = (PAFA_CLASS_DRIVER) OsAllocMemory( sizeof(AFA_CLASS_DRIVER), OS_ALLOC_MEM_SLEEP );
2493 +
2494 +       if (ClassDriver == NULL) {
2495 +
2496 +               Status = STATUS_INSUFFICIENT_RESOURCES;
2497 +
2498 +               return Status;
2499 +       }
2500 +
2501 +       //
2502 +       // If the class driver has sent in user Vars, then copy them into the global
2503 +       // area.
2504 +       //
2505 +
2506 +       if (NewClassDriver->NumUserVars) {
2507 +
2508 +               PFSA_USER_VAR   NewUserVars;
2509 +
2510 +               NewUserVars = OsAllocMemory( (FsaCommData.NumUserVars +
2511 +                                                                  NewClassDriver->NumUserVars) * sizeof(FSA_USER_VAR), OS_ALLOC_MEM_SLEEP );
2512 +
2513 +               //
2514 +               // First copy the existing into the new area.
2515 +               //
2516 +
2517 +               RtlCopyMemory( NewUserVars, FsaCommData.UserVars, FsaCommData.NumUserVars * sizeof(FSA_USER_VAR) );
2518 +
2519 +               //
2520 +               // Next copy the new vars passed in from class driver.
2521 +               //
2522 +
2523 +               RtlCopyMemory( (NewUserVars + FsaCommData.NumUserVars),
2524 +                                          NewClassDriver->UserVars,
2525 +                                          NewClassDriver->NumUserVars * sizeof(FSA_USER_VAR) );
2526 +
2527 +               //
2528 +               // Free up the old user vars.
2529 +               //
2530 +
2531 +               OsFreeMemory( FsaCommData.UserVars, FsaCommData.NumUserVars * sizeof(FSA_USER_VAR) );
2532 +
2533 +               //
2534 +               // Point the global to the new area.
2535 +               //
2536 +
2537 +               FsaCommData.UserVars = NewUserVars;
2538 +
2539 +               //
2540 +               // Update the total count.
2541 +               //
2542 +
2543 +               FsaCommData.NumUserVars += NewClassDriver->NumUserVars;
2544 +
2545 +       }
2546 +
2547 +       ClassDriver->OpenAdapter = NewClassDriver->OpenAdapter;
2548 +       ClassDriver->CloseAdapter = NewClassDriver->CloseAdapter;
2549 +       ClassDriver->DeviceControl = NewClassDriver->DeviceControl;
2550 +       ClassDriver->HandleAif = NewClassDriver->HandleAif;
2551 +       ClassDriver->ClassDriverExtension = NewClassDriver->ClassDriverExtension;
2552 +
2553 +       ClassDriver->Next = Adapter->ClassDriverList;
2554 +       Adapter->ClassDriverList = ClassDriver;
2555 +
2556 +       //
2557 +       // Now return the information needed by the class driver to communicate to us.
2558 +       //
2559 +
2560 +       NewClassDriverResponse->CommFuncs = &Adapter->CommFuncs;
2561 +       NewClassDriverResponse->CommPortExtension = Adapter;
2562 +       NewClassDriverResponse->MiniPortExtension = Adapter->AdapterExtension;
2563 +       NewClassDriverResponse->SpinLockCookie = Adapter->SpinLockCookie;
2564 +       NewClassDriverResponse->Dip = Adapter->Dip;
2565 +
2566 +       return (STATUS_SUCCESS);
2567 +
2568 +
2569 +}
2570 +
2571 +int
2572 +AfaCommCtlSendFib(
2573 +       IN PAFA_COMM_ADAPTER    Adapter,
2574 +       IN PAFA_IOCTL_CMD               IoctlCmdPtr
2575 +)
2576 +/*++
2577 +
2578 +Routine Description:
2579 +
2580 +       This routine sends a fib to the adapter on behalf of a user level
2581 +       program.
2582 +
2583 +Arguments:
2584 +
2585 +       Adapter - Supplies which adapter is being processed.
2586 +
2587 +       IoctlCmdPtr - Pointer to the arguments to the IOCTL call
2588 +
2589 +Return Value:
2590 +
2591 +       STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2592 +
2593 +       STATUS_INSUFFICIENT_RESOURCES - If a memory allocation failed.
2594 +
2595 +       STATUS_SUCCESS           - Everything OK.
2596 +
2597 +--*/
2598 +{
2599 +    PFIB KFib;
2600 +//    PMDL DmaMdl = NULL;
2601 +       PCOMM_FIB_CONTEXT FibContext;
2602 +       PSGMAP_CONTEXT SgMapContext;
2603 +       SGMAP_CONTEXT _SgMapContext;
2604 +    QUEUE_TYPES WhichQueue;
2605 +    PVOID UsersAddress;
2606 +       AAC_STATUS Status;
2607 +
2608 +       FibContext = AllocateFib( Adapter );
2609 +
2610 +    KFib = FibContext->Fib;
2611 +
2612 +       //
2613 +       // First copy in the header so that we can check the size field.
2614 +       //
2615 +
2616 +       if (COPYIN( (caddr_t) IoctlCmdPtr->arg, (caddr_t) KFib, sizeof(FIB_HEADER), IoctlCmdPtr->flag )) {
2617 +               FreeFib( FibContext );
2618 +               Status = EFAULT;
2619 +               return (Status);
2620 +       }
2621 +
2622 +       //
2623 +       //      Since we copy based on the fib header size, make sure that we
2624 +       //      will not overrun the buffer when we copy the memory. Return
2625 +       //      an error if we would.
2626 +       //
2627 +
2628 +       if (KFib->Header.Size > sizeof(FIB) - sizeof(FIB_HEADER)) {
2629 +               FreeFib( FibContext );
2630 +               Status = EINVAL;
2631 +               return Status;
2632 +
2633 +       }
2634 +
2635 +       if (COPYIN( (caddr_t) IoctlCmdPtr->arg, (caddr_t) KFib, KFib->Header.Size + sizeof(FIB_HEADER), IoctlCmdPtr->flag )) {
2636 +               FreeFib( FibContext );
2637 +               Status = EFAULT;
2638 +               return (Status);
2639 +       }
2640 +
2641 +    WhichQueue = AdapNormCmdQueue;
2642 +
2643 +
2644 +       if (KFib->Header.Command == TakeABreakPt) {
2645 +
2646 +               InterruptAdapter(Adapter);
2647 +
2648 +               //
2649 +               // Since we didn't really send a fib, zero out the state to allow 
2650 +               // cleanup code not to assert.
2651 +               //
2652 +
2653 +               KFib->Header.XferState = 0;
2654 +
2655 +
2656 +       } else {
2657 +       
2658 +               if (SendFib(KFib->Header.Command, FibContext, KFib->Header.Size , FsaNormal,
2659 +                                       TRUE, NULL, TRUE, NULL, NULL) != FSA_SUCCESS) {
2660 +               FsaCommPrint("User SendFib failed!.\n");
2661 +
2662 +
2663 +                       FreeFib( FibContext );
2664 +                       return (ENXIO);
2665 +               }
2666 +
2667 +           if (CompleteFib(FibContext) != FSA_SUCCESS) {
2668 +               FsaCommPrint("User Complete FIB failed.\n");
2669 +
2670 +                       FreeFib( FibContext );
2671 +                       return (ENXIO);
2672 +               }
2673 +
2674 +
2675 +    }
2676 +
2677 +
2678 +       //
2679 +       //      Make sure that the size returned by the adapter (which includes
2680 +       //      the header) is less than or equal to the size of a fib, so we
2681 +       //      don't corrupt application data. Then copy that size to the user
2682 +       //      buffer. (Don't try to add the header information again, since it
2683 +       //      was already included by the adapter.)
2684 +       //
2685 +    ASSERT(KFib->Header.Size <= sizeof(FIB));
2686 +
2687 +       if (COPYOUT( (caddr_t) KFib, (caddr_t) IoctlCmdPtr->arg, KFib->Header.Size, IoctlCmdPtr->flag )) {
2688 +               FreeFib( FibContext );
2689 +               Status = EFAULT;
2690 +               return (Status);
2691 +       }
2692 +
2693 +       FreeFib( FibContext );
2694 +
2695 +    return (0);
2696 +
2697 +}
2698 +
2699 +int
2700 +AfaCommCtlAifThread(
2701 +       IN PAFA_COMM_ADAPTER    Adapter,
2702 +       IN PAFA_IOCTL_CMD               IoctlCmdPtr
2703 +)
2704 +/*++
2705 +
2706 +Routine Description:
2707 +
2708 +       This routine will act as the AIF thread for this adapter.
2709 +
2710 +Arguments:
2711 +
2712 +       Adapter - Supplies which adapter is being processed.
2713 +
2714 +       IoctlCmdPtr - Pointer to the arguments to the IOCTL call
2715 +
2716 +Return Value:
2717 +
2718 +       STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2719 +
2720 +       STATUS_INSUFFICIENT_RESOURCES - If a memory allocation failed.
2721 +
2722 +       STATUS_SUCCESS           - Everything OK.
2723 +
2724 +--*/
2725 +{
2726 +       return (NormCommandThread(Adapter));
2727 +}
2728 +
2729 +
2730 +
2731 +#ifdef GATHER_FIB_TIMES
2732 +AAC_STATUS
2733 +AfaCommGetFibTimes(
2734 +       IN PAFA_COMM_ADAPTER    Adapter,
2735 +       IN PIRP                                 Irp
2736 +       )
2737 +/*++
2738 +
2739 +Routine Description:
2740 +
2741 +       This routine returns the gathered fibtimes to the user.
2742 +
2743 +Arguments:
2744 +
2745 +       Adapter - Supplies which adapter is being processed.
2746 +
2747 +    Irp - Supplies the Irp being processed.
2748 +
2749 +Return Value:
2750 +
2751 +       STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2752 +
2753 +       STATUS_INSUFFICIENT_RESOURCES - If a memory allocation failed.
2754 +
2755 +       STATUS_SUCCESS           - Everything OK.
2756 +
2757 +--*/
2758 +{
2759 +       PALL_FIB_TIMES AllFibTimes;
2760 +       PLARGE_INTEGER FreqPtr;
2761 +    PIO_STACK_LOCATION IrpSp;
2762 +
2763 +    //
2764 +    //  Get a pointer to the current Irp stack location
2765 +    //
2766 +
2767 +    IrpSp = IoGetCurrentIrpStackLocation( Irp );
2768 +
2769 +       FreqPtr = (PLARGE_INTEGER)IrpSp->Parameters.FileSystemControl.Type3InputBuffer;
2770 +
2771 +       *FreqPtr = Adapter->FibTimesFrequency;
2772 +
2773 +       AllFibTimes = (PALL_FIB_TIMES)((PUCHAR)FreqPtr + sizeof(LARGE_INTEGER));
2774 +
2775 +       RtlCopyMemory(AllFibTimes, Adapter->FibTimes, sizeof(ALL_FIB_TIMES));
2776 +
2777 +       Irp->IoStatus.Information = 0;
2778 +
2779 +       return (STATUS_SUCCESS);
2780 +
2781 +}
2782 +
2783 +AAC_STATUS
2784 +AfaCommZeroFibTimes(
2785 +       IN PAFA_COMM_ADAPTER    Adapter,
2786 +       IN PIRP                                 Irp
2787 +       )
2788 +/*++
2789 +
2790 +Routine Description:
2791 +
2792 +       This routine zero's the FibTimes structure within the adapter structure.
2793 +
2794 +Arguments:
2795 +
2796 +       Adapter - Supplies which adapter is being processed.
2797 +
2798 +    Irp - Supplies the Irp being processed.
2799 +
2800 +Return Value:
2801 +
2802 +       STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2803 +
2804 +       STATUS_INSUFFICIENT_RESOURCES - If a memory allocation failed.
2805 +
2806 +       STATUS_SUCCESS           - Everything OK.
2807 +
2808 +--*/
2809 +{
2810 +       PFIB_TIMES FibTimesPtr;
2811 +       int i;
2812 +    PIO_STACK_LOCATION IrpSp;
2813 +
2814 +    //
2815 +    //  Get a pointer to the current Irp stack location
2816 +    //
2817 +
2818 +    IrpSp = IoGetCurrentIrpStackLocation( Irp );
2819 +
2820 +       //
2821 +       // Initialize the Fib timing data structures
2822 +       //
2823 +       RtlZeroMemory(Adapter->FibTimes, sizeof(ALL_FIB_TIMES));
2824 +
2825 +       for (i = 0; i < MAX_FSACOMMAND_NUM; i++) {
2826 +
2827 +               FibTimesPtr = &Adapter->FibTimes->FileSys[i];
2828 +
2829 +               FibTimesPtr->Minimum.LowPart = 0xffffffff;
2830 +               FibTimesPtr->Minimum.HighPart = 0x7fffffff;
2831 +               FibTimesPtr->AdapterMinimum.LowPart = 0xffffffff;
2832 +               FibTimesPtr->AdapterMinimum.HighPart = 0x7fffffff;
2833 +       }
2834 +       for (i = 0; i < MAX_RW_FIB_TIMES; i++) {
2835 +
2836 +               FibTimesPtr = &Adapter->FibTimes->Read[i];
2837 +
2838 +               FibTimesPtr->Minimum.LowPart = 0xffffffff;
2839 +               FibTimesPtr->Minimum.HighPart = 0x7fffffff;
2840 +               FibTimesPtr->AdapterMinimum.LowPart = 0xffffffff;
2841 +               FibTimesPtr->AdapterMinimum.HighPart = 0x7fffffff;
2842 +       }
2843 +       for (i = 0; i < MAX_RW_FIB_TIMES; i++) {
2844 +
2845 +               FibTimesPtr = &Adapter->FibTimes->Write[i];
2846 +
2847 +               FibTimesPtr->Minimum.LowPart = 0xffffffff;
2848 +               FibTimesPtr->Minimum.HighPart = 0x7fffffff;
2849 +               FibTimesPtr->AdapterMinimum.LowPart = 0xffffffff;
2850 +               FibTimesPtr->AdapterMinimum.HighPart = 0x7fffffff;
2851 +       }
2852 +
2853 +       FibTimesPtr = &Adapter->FibTimes->Other;
2854 +
2855 +       FibTimesPtr->Minimum.LowPart = 0xffffffff;
2856 +       FibTimesPtr->Minimum.HighPart = 0x7fffffff;
2857 +       FibTimesPtr->AdapterMinimum.LowPart = 0xffffffff;
2858 +       FibTimesPtr->AdapterMinimum.HighPart = 0x7fffffff;
2859 +
2860 +       Irp->IoStatus.Information = 0;
2861 +
2862 +       return (STATUS_SUCCESS);
2863 +
2864 +}
2865 +#endif // GATHER_FIB_TIMES
2866 +
2867 +#ifndef unix_aif
2868 +int
2869 +FsaCtlOpenGetAdapterFib(
2870 +       IN PAFA_COMM_ADAPTER    Adapter,
2871 +       IN PAFA_IOCTL_CMD               IoctlCmdPtr
2872 +       )
2873 +/*++
2874 +
2875 +Routine Description:
2876 +
2877 +    This routine will get the next Fib, if available, from the AdapterFibContext
2878 +       passed in from the user.
2879 +
2880 +Arguments:
2881 +
2882 +       Adapter - Supplies which adapter is being processed.
2883 +
2884 +    Irp - Supplies the Irp being processed.
2885 +
2886 +Return Value:
2887 +
2888 +       STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2889 +
2890 +       STATUS_INSUFFICIENT_RESOURCES - If a memory allocation failed.
2891 +
2892 +       STATUS_SUCCESS           - Everything OK.
2893 +
2894 +--*/
2895 +{
2896 +       PGET_ADAPTER_FIB_CONTEXT AdapterFibContext;
2897 +//     HANDLE Event;
2898 +//    PKEVENT eventObject = (PKEVENT) NULL;
2899 +       int Status;
2900 +
2901 +       //
2902 +       // The context must be allocated from NonPagedPool because we need to use MmIsAddressValid.
2903 +       //
2904 +
2905 +       AdapterFibContext = OsAllocMemory(sizeof(GET_ADAPTER_FIB_CONTEXT), OS_ALLOC_MEM_SLEEP);
2906 +
2907 +       if (AdapterFibContext == NULL) {
2908 +
2909 +               Status = ENOMEM;
2910 +
2911 +       } else {
2912 +
2913 +               AdapterFibContext->NodeTypeCode = FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT;
2914 +               AdapterFibContext->NodeByteSize = sizeof(GET_ADAPTER_FIB_CONTEXT);
2915 +
2916 +
2917 +               //
2918 +               // Initialize the conditional variable use to wait for the next AIF.
2919 +               //
2920 +
2921 +               OsCv_init( &AdapterFibContext->UserEvent);
2922 +
2923 +               //
2924 +               // Set WaitingForFib to FALSE to indicate we are not in a WaitForSingleObject
2925 +               //
2926 +
2927 +               AdapterFibContext->WaitingForFib = FALSE;
2928 +
2929 +               //
2930 +               // Initialize the FibList and set the count of fibs on the list to 0.
2931 +               //
2932 +
2933 +               AdapterFibContext->FibCount = 0;
2934 +               InitializeListHead(&AdapterFibContext->FibList);
2935 +
2936 +               //
2937 +               // Overload FileObject with a time stamp.
2938 +               //
2939 +               AdapterFibContext->FileObject = (void *)OsGetSeconds();
2940 +
2941 +               //
2942 +               // Now add this context onto the adapter's AdapterFibContext list.
2943 +               //
2944 +
2945 +               OsCvLockAcquire(Adapter->AdapterFibMutex);
2946 +
2947 +               InsertTailList(&Adapter->AdapterFibContextList, &AdapterFibContext->NextContext);
2948 +
2949 +               OsCvLockRelease(Adapter->AdapterFibMutex);
2950 +
2951 +               if (COPYOUT( &AdapterFibContext, (caddr_t) IoctlCmdPtr->arg, sizeof(PGET_ADAPTER_FIB_CONTEXT), 
2952 +                                                IoctlCmdPtr->flag )) {
2953 +
2954 +                       Status = EFAULT;
2955 +                       
2956 +               } else {
2957 +               
2958 +                       Status = 0;
2959 +
2960 +               }       
2961 +
2962 +       }
2963 +
2964 +       return (Status);
2965 +}
2966 +
2967 +int
2968 +FsaCtlGetNextAdapterFib(
2969 +       IN PAFA_COMM_ADAPTER    Adapter,
2970 +       IN PAFA_IOCTL_CMD               IoctlCmdPtr
2971 +       )
2972 +/*++
2973 +
2974 +Routine Description:
2975 +
2976 +    This routine will get the next Fib, if available, from the AdapterFibContext
2977 +       passed in from the user.
2978 +
2979 +Arguments:
2980 +
2981 +       Adapter - Supplies which adapter is being processed.
2982 +
2983 +    Irp - Supplies the Irp being processed.
2984 +
2985 +Return Value:
2986 +
2987 +       STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2988 +
2989 +       STATUS_NO_MORE_ENTRIES - There are no more Fibs for this AdapterFibContext.
2990 +
2991 +       STATUS_SUCCESS           - Everything OK.
2992 +
2993 +--*/
2994 +{
2995 +       GET_ADAPTER_FIB_IOCTL AdapterFibIoctl;
2996 +       PGET_ADAPTER_FIB_CONTEXT AdapterFibContext, aifcp;
2997 +       PFIB Fib;
2998 +       int Status;
2999 +       PLIST_ENTRY Entry;
3000 +       int found;
3001 +
3002 +       if (COPYIN( (caddr_t) IoctlCmdPtr->arg, (caddr_t) &AdapterFibIoctl,
3003 +                                       sizeof(GET_ADAPTER_FIB_IOCTL), IoctlCmdPtr->flag )) {
3004 +               return (EFAULT);
3005 +       }
3006 +
3007 +       //
3008 +       // Extract the AdapterFibContext from the Input parameters.
3009 +       //
3010 +
3011 +       AdapterFibContext = (PGET_ADAPTER_FIB_CONTEXT) AdapterFibIoctl.AdapterFibContext;
3012 +
3013 +       //
3014 +       // Verify that the HANDLE passed in was a valid AdapterFibContext
3015 +       //
3016 +       // Search the list of AdapterFibContext addresses on the adapter to be sure
3017 +       // this is a valid address
3018 +
3019 +       found = 0;
3020 +       Entry = Adapter->AdapterFibContextList.Flink;
3021 +
3022 +       while ( Entry != &Adapter->AdapterFibContextList ) {
3023 +                       aifcp = CONTAINING_RECORD ( Entry, GET_ADAPTER_FIB_CONTEXT, NextContext );
3024 +                       if ( AdapterFibContext == aifcp ) {   // We found a winner
3025 +                                       found = 1;
3026 +                                       break;
3027 +                       }
3028 +                       Entry = Entry->Flink;
3029 +       }
3030 +
3031 +       if ( found == 0 ) {
3032 +                       return ( EINVAL );;
3033 +       }
3034 +
3035 +       if ( (AdapterFibContext->NodeTypeCode != FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT) ||
3036 +                (AdapterFibContext->NodeByteSize != sizeof(GET_ADAPTER_FIB_CONTEXT)) ) {
3037 +
3038 +               return ( EINVAL );
3039 +
3040 +       }
3041 +
3042 +       Status = STATUS_SUCCESS;
3043 +
3044 +       OsCvLockAcquire(Adapter->AdapterFibMutex);
3045 +
3046 +       //
3047 +       // If there are no fibs to send back, then either wait or return EAGAIN
3048 +       //
3049 +return_fib:
3050 +
3051 +       if (!IsListEmpty(&AdapterFibContext->FibList)) {
3052 +
3053 +               PLIST_ENTRY Entry;
3054 +
3055 +               //
3056 +               // Pull the next fib from the FibList
3057 +               //
3058 +               Entry = RemoveHeadList(&AdapterFibContext->FibList);
3059 +
3060 +               Fib = CONTAINING_RECORD( Entry, FIB, Header.FibLinks );
3061 +
3062 +               AdapterFibContext->FibCount--;
3063 +
3064 +               if (COPYOUT( Fib, AdapterFibIoctl.AifFib, sizeof(FIB), IoctlCmdPtr->flag )) {
3065 +
3066 +                       OsCvLockRelease( Adapter->AdapterFibMutex );
3067 +                       OsFreeMemory( Fib, sizeof(Fib) );
3068 +                       return (EFAULT);
3069 +
3070 +               }       
3071 +
3072 +               //
3073 +               // Free the space occupied by this copy of the fib.
3074 +               //
3075 +
3076 +               OsFreeMemory(Fib, sizeof(FIB));
3077 +
3078 +        Status = 0;
3079 +
3080 +               //
3081 +               // Overload FileObject with a time stamp
3082 +               // 
3083 +               AdapterFibContext->FileObject = ( void * )OsGetSeconds();
3084 +
3085 +       } else {
3086 +
3087 +               if (AdapterFibIoctl.Wait) {
3088 +                       
3089 +                       if (OsCv_wait_sig( &AdapterFibContext->UserEvent, Adapter->AdapterFibMutex ) == 0) {
3090 +
3091 +                               Status = EINTR;
3092 +
3093 +                       } else {
3094 +                       
3095 +                               goto return_fib;
3096 +                               
3097 +                       }
3098 +               } else {
3099 +                                       
3100 +                       Status = EAGAIN;
3101 +
3102 +               }       
3103 +
3104 +       }
3105 +       OsCvLockRelease( Adapter->AdapterFibMutex );
3106 +
3107 +       return (Status);
3108 +}
3109 +
3110 +int
3111 +FsaCtlCloseGetAdapterFib(
3112 +       IN PAFA_COMM_ADAPTER    Adapter,
3113 +       IN PAFA_IOCTL_CMD               IoctlCmdPtr
3114 +       )
3115 +/*++
3116 +
3117 +Routine Description:
3118 +
3119 +    This routine will close down the AdapterFibContext passed in from the user.
3120 +
3121 +Arguments:
3122 +
3123 +       Adapter - Supplies which adapter is being processed.
3124 +
3125 +    Irp - Supplies the Irp being processed.
3126 +
3127 +Return Value:
3128 +
3129 +       STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
3130 +
3131 +       STATUS_SUCCESS           - Everything OK.
3132 +
3133 +--*/
3134 +{
3135 +       PGET_ADAPTER_FIB_CONTEXT AdapterFibContext, aifcp;
3136 +       AAC_STATUS Status;
3137 +
3138 +       PLIST_ENTRY Entry;
3139 +       int found;
3140 +
3141 +       //
3142 +       // Extract the AdapterFibContext from the Input parameters
3143 +       //
3144 +
3145 +       AdapterFibContext = (PGET_ADAPTER_FIB_CONTEXT) IoctlCmdPtr->arg;
3146 +
3147 +       if (AdapterFibContext == 0) {
3148 +               cmn_err(CE_WARN, "FsaCtlCloseGetAdapterFib: AdapterFibContext is NULL");
3149 +               return(EINVAL);
3150 +       }
3151 +
3152 +       //
3153 +       // Verify that the HANDLE passed in was a valid AdapterFibContext
3154 +       //
3155 +       // Search the list of AdapterFibContext addresses on the adapter to be sure
3156 +       // this is a valid address
3157 +
3158 +       found = 0;
3159 +       Entry = Adapter->AdapterFibContextList.Flink;
3160 +
3161 +       while ( Entry != &Adapter->AdapterFibContextList ) {
3162 +                       aifcp = CONTAINING_RECORD ( Entry, GET_ADAPTER_FIB_CONTEXT, NextContext );
3163 +                       if ( AdapterFibContext == aifcp ) {   // We found a winner
3164 +                                       found = 1;
3165 +                                       break;
3166 +                       }
3167 +                       Entry = Entry->Flink;
3168 +       }
3169 +
3170 +       if ( found == 0 ) {
3171 +               return ( 0 ); // Already Gone
3172 +       }
3173 +
3174 +       if ( (AdapterFibContext->NodeTypeCode != FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT) ||
3175 +                (AdapterFibContext->NodeByteSize != sizeof(GET_ADAPTER_FIB_CONTEXT)) ) {
3176 +
3177 +               return (EINVAL);
3178 +
3179 +       }
3180 +
3181 +       OsCvLockAcquire(Adapter->AdapterFibMutex);
3182 +
3183 +       Status = FsaCloseAdapterFibContext(Adapter, AdapterFibContext);
3184 +
3185 +       OsCvLockRelease(Adapter->AdapterFibMutex);
3186 +
3187 +       return (Status);
3188 +}
3189 +
3190 +int
3191 +FsaCloseAdapterFibContext(
3192 +       IN PAFA_COMM_ADAPTER                    Adapter,
3193 +       IN PGET_ADAPTER_FIB_CONTEXT             AdapterFibContext
3194 +       )
3195 +{
3196 +       int Status;
3197 +       PFIB Fib;
3198 +
3199 +       //
3200 +       // First free any FIBs that have not been consumed yet.
3201 +       //
3202 +
3203 +       while (!IsListEmpty(&AdapterFibContext->FibList)) {
3204 +
3205 +               PLIST_ENTRY Entry;
3206 +
3207 +               //
3208 +               // Pull the next fib from the FibList
3209 +               //
3210 +
3211 +               Entry = RemoveHeadList(&AdapterFibContext->FibList);
3212 +
3213 +               Fib = CONTAINING_RECORD( Entry, FIB, Header.FibLinks );
3214 +
3215 +               AdapterFibContext->FibCount--;
3216 +
3217 +               //
3218 +               // Free the space occupied by this copy of the fib.
3219 +               //
3220 +
3221 +               OsFreeMemory(Fib, sizeof(FIB));
3222 +       }
3223 +
3224 +       //
3225 +       // Remove the Context from the AdapterFibContext List
3226 +       //
3227 +
3228 +       RemoveEntryList(&AdapterFibContext->NextContext);
3229 +
3230 +       OsCv_destroy( &AdapterFibContext->UserEvent );
3231 +
3232 +       //
3233 +       // Invalidate context
3234 +       //
3235 +
3236 +       AdapterFibContext->NodeTypeCode = 0;
3237 +
3238 +       //
3239 +       // Free the space occupied by the Context
3240 +       //
3241 +
3242 +       OsFreeMemory(AdapterFibContext, sizeof(GET_ADAPTER_FIB_CONTEXT));
3243 +
3244 +       Status = STATUS_SUCCESS;
3245 +
3246 +    return Status;
3247 +}
3248 +#endif 
3249 +
3250 +AAC_STATUS
3251 +AfaCommOpenAdapter(
3252 +       IN PVOID Arg
3253 +       )
3254 +/*++
3255 +
3256 +Routine Description:
3257 +
3258 +       The routine will get called by the miniport each time a user issues a CreateFile on the DeviceObject
3259 +       for the adapter.
3260 +
3261 +       The main purpose of this routine is to set up any data structures that may be needed
3262 +       to handle any requests made on this DeviceObject.
3263 +
3264 +Arguments:
3265 +
3266 +       Adapter - Pointer to which adapter miniport was opened.
3267 +
3268 +
3269 +Return Value:
3270 +
3271 +       STATUS_SUCCESS
3272 +
3273 +--*/
3274 +
3275 +{
3276 +       PAFA_COMM_ADAPTER       Adapter = (PAFA_COMM_ADAPTER) Arg;
3277 +       AAC_STATUS Status = STATUS_SUCCESS;
3278 +       PAFA_CLASS_DRIVER ClassDriver;
3279 +
3280 +       ClassDriver = Adapter->ClassDriverList;
3281 +
3282 +       while (ClassDriver) {
3283 +
3284 +               if (ClassDriver->OpenAdapter) {
3285 +
3286 +                       Status = ClassDriver->OpenAdapter( ClassDriver->ClassDriverExtension );
3287 +
3288 +                       if (Status != STATUS_SUCCESS)
3289 +                               break;
3290 +               }
3291 +
3292 +               ClassDriver = ClassDriver->Next;
3293 +       }
3294 +
3295 +       return ( Status );
3296 +}
3297 +
3298 +AAC_STATUS
3299 +AfaCommCloseAdapter(
3300 +       IN PVOID Arg
3301 +       )
3302 +/*++
3303 +
3304 +Routine Description:
3305 +
3306 +       This routine will get called by the miniport each time a user issues a CloseHandle on the DeviceObject
3307 +       for the adapter.
3308 +
3309 +       The main purpose of this routine is to cleanup any data structures that have been set up
3310 +       while this FileObject has been opened.
3311 +
3312 +       This routine loops through all of the AdapterFibContext structures to determine if any need
3313 +       to be deleted for this FileObject.
3314 +
3315 +Arguments:
3316 +
3317 +       Adapter - Pointer to adapter miniport
3318 +
3319 +       Irp - Pointer to Irp that caused this close
3320 +
3321 +Return Value:
3322 +
3323 +       Status value returned from File system driver AdapterClose
3324 +
3325 +--*/
3326 +{
3327 +       PAFA_COMM_ADAPTER       Adapter = (PAFA_COMM_ADAPTER) Arg;
3328 +       PLIST_ENTRY Entry, NextEntry;
3329 +       PGET_ADAPTER_FIB_CONTEXT AdapterFibContext;
3330 +       AAC_STATUS Status = STATUS_SUCCESS;
3331 +       PAFA_CLASS_DRIVER ClassDriver;
3332 +
3333 +       OsCvLockAcquire(Adapter->AdapterFibMutex);
3334 +
3335 +       Entry = Adapter->AdapterFibContextList.Flink;
3336 +
3337 +       //
3338 +       // Loop through all of the AdapterFibContext, looking for any that
3339 +       // were created with the FileObject that is being closed.
3340 +       //
3341 +       while (Entry != &Adapter->AdapterFibContextList) {
3342 +
3343 +               //
3344 +               // Extract the AdapterFibContext
3345 +               //
3346 +               AdapterFibContext = CONTAINING_RECORD( Entry, GET_ADAPTER_FIB_CONTEXT, NextContext );
3347 +
3348 +               // 
3349 +               // Save the next entry because CloseAdapterFibContext will delete the AdapterFibContext
3350 +               //
3351 +               NextEntry = Entry->Flink;
3352 +
3353 +               Entry = NextEntry;
3354 +
3355 +       }
3356 +
3357 +#ifdef unix_config_file
3358 +       //
3359 +       // If this FileObject had the adapter open for configuration, then release it.
3360 +       //
3361 +       if ( Adapter->AdapterConfigFileObject == IrpSp->FileObject ) {
3362 +
3363 +               Adapter->AdapterConfigFileObject = NULL;
3364 +
3365 +       }
3366 +#endif
3367 +
3368 +       OsCvLockRelease(Adapter->AdapterFibMutex);
3369 +
3370 +       ClassDriver = Adapter->ClassDriverList;
3371 +
3372 +       while (ClassDriver) {
3373 +
3374 +               if (ClassDriver->CloseAdapter) {
3375 +
3376 +                       Status = ClassDriver->CloseAdapter( ClassDriver->ClassDriverExtension );
3377 +
3378 +                       if (Status != STATUS_SUCCESS)
3379 +                               break;
3380 +               }
3381 +
3382 +               ClassDriver = ClassDriver->Next;
3383 +       }
3384 +
3385 +       return ( Status );
3386 +
3387 +}
3388 +
3389 diff -urN linux/drivers/scsi/aacraid/comminit.c linux/drivers/scsi/aacraid/comminit.c
3390 --- linux/drivers/scsi/aacraid/comminit.c       Wed Dec 31 19:00:00 1969
3391 +++ linux/drivers/scsi/aacraid/comminit.c       Thu Dec 21 13:14:30 2000
3392 @@ -0,0 +1,986 @@
3393 +/*++
3394 + * Adaptec aacraid device driver for Linux.
3395 + *
3396 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
3397 + *
3398 + * This program is free software; you can redistribute it and/or modify
3399 + * it under the terms of the GNU General Public License as published by
3400 + * the Free Software Foundation; either version 2, or (at your option)
3401 + * any later version.
3402 + *
3403 + * This program is distributed in the hope that it will be useful,
3404 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
3405 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
3406 + * GNU General Public License for more details.
3407 + *
3408 + * You should have received a copy of the GNU General Public License
3409 + * along with this program; see the file COPYING.  If not, write to
3410 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
3411 + *
3412 + * Module Name:
3413 + *  comminit.c
3414 + *
3415 + * Abstract: This supports the initialization of the host adapter commuication interface.
3416 + *    This is a platform dependent module for the pci cyclone board.
3417 + *
3418 + --*/
3419 +
3420 +static char *ident_comminit = "aacraid_ident comminit.c 1.0.6 2000/10/09 Adaptec, Inc.";
3421 +
3422 +#include "comprocs.h"
3423 +
3424 +#define BugCheckFileId                   (FSAFS_BUG_CHECK_COMMINIT)
3425 +
3426 +VOID
3427 +AfaCommBugcheckHandler(
3428 +               IN PVOID Buffer,
3429 +               IN ULONG Length
3430 +               );
3431 +
3432 +VOID
3433 +ThrottlePeriodEndDpcRtn(
3434 +       IN PKDPC Dpc,
3435 +       IN PVOID DeferredContext,
3436 +       IN PVOID SystemArgument1,
3437 +       IN PVOID SystemArgument2);
3438 +
3439 +FSA_COMM_DATA FsaCommData;
3440 +
3441 +AAC_STATUS
3442 +HardInterruptModeration1Changed(
3443 +       IN PVOID AdapterContext,
3444 +       IN ULONG NewValue
3445 +       )
3446 +{
3447 +       PAFA_COMM_ADAPTER Adapter = AdapterContext;
3448 +
3449 +       //
3450 +       // If we are using interrupt moderation, then disable the interrupt
3451 +       // until we need to use it.
3452 +       //
3453 +       if (FsaCommData.HardInterruptModeration1)
3454 +               DisableInterrupt( Adapter, AdapNormCmdNotFull, FALSE );
3455 +       else
3456 +               EnableInterrupt( Adapter, AdapNormCmdNotFull, FALSE );
3457 +
3458 +       return (STATUS_SUCCESS);
3459 +}
3460 +
3461 +AAC_STATUS
3462 +FsaFibTimeoutChanged(
3463 +       IN PVOID AdapterContext,
3464 +       IN ULONG NewValue
3465 +       )
3466 +{
3467 +       //
3468 +       // scale the new timeout from seconds to 100 nsec units
3469 +       //
3470 +//     FsaCommData.AdapterTimeout = RtlConvertLongToLargeInteger(-10*1000*1000*NewValue);
3471 +
3472 +       return (STATUS_SUCCESS);
3473 +}
3474 +
3475 +#ifdef GATHER_FIB_TIMES
3476 +extern int GatherFibTimes;
3477 +#endif
3478 +
3479 +FSA_USER_VAR FsaCommUserVars[] = {
3480 +#ifdef FIB_CHECKSUMS
3481 +    { "do_fib_checksums", (PULONG)&FsaCommData.do_fib_checksums, NULL },
3482 +#endif
3483 +#ifdef GATHER_FIB_TIMES
3484 +       { "GatherFibTimes", (PULONG)&GatherFibTimes, NULL },
3485 +#endif
3486 +       { "EnableAdapterTimeouts", (PULONG)&FsaCommData.EnableAdapterTimeouts, NULL},
3487 +       { "EnableInterruptModeration", (PULONG)&FsaCommData.EnableInterruptModeration, NULL },
3488 +       { "FsaDataFibsSent", (PULONG) &FsaCommData.FibsSent, NULL },
3489 +       { "FsaDataFibRecved", (PULONG) &FsaCommData.FibRecved, NULL },
3490 +       { "HardInterruptModeration", (PULONG)&FsaCommData.HardInterruptModeration, NULL},
3491 +       { "HardInterruptModeration1", (PULONG)&FsaCommData.HardInterruptModeration1, HardInterruptModeration1Changed},
3492 +       { "EnableFibTimeoutBreak", (PULONG)&FsaCommData.EnableFibTimeoutBreak, NULL},
3493 +       { "PeakFibsConsumed", (PULONG)&FsaCommData.PeakFibsConsumed, NULL },
3494 +       { "ZeroFibsConsumed", (PULONG)&FsaCommData.ZeroFibsConsumed, NULL },
3495 +       { "FibTimeoutSeconds", (PULONG) &FsaCommData.FibTimeoutSeconds, FsaFibTimeoutChanged },
3496 +};
3497 +
3498 +#define NUM_COMM_USER_VARS     (sizeof(FsaCommUserVars) / sizeof(FSA_USER_VAR) )
3499 +
3500 +\f
3501 +AAC_STATUS
3502 +AacCommDriverEntry(
3503 +    )
3504 +
3505 +/*++
3506 +
3507 +Routine Description:
3508 +
3509 +    This is the initialization routine for the FileArray Comm layer device driver.
3510 +
3511 +Arguments:
3512 +
3513 +    DriverObject - Pointer to driver object created by the system.
3514 +
3515 +Return Value:
3516 +
3517 +    AAC_STATUS - The function value is the final status from the initialization
3518 +        operation.
3519 +
3520 +--*/
3521 +
3522 +{
3523 +    AAC_STATUS Status;
3524 +       PVOID BugCheckBuffer;
3525 +
3526 +       RtlZeroMemory( &FsaCommData, sizeof(FSA_COMM_DATA) );
3527 +
3528 +
3529 +    //
3530 +    // Load the global timeout value for the adapter timeout
3531 +    // Also init the global that enables or disables adapter timeouts
3532 +    //
3533 +
3534 +//     FsaCommData.AdapterTimeout = RtlConvertLongToLargeInteger(-10*1000*1000*180);
3535 +
3536 +       FsaCommData.FibTimeoutSeconds = 180;
3537 +
3538 +       FsaCommData.EnableAdapterTimeouts = TRUE; 
3539 +
3540 +//     FsaCommData.QueueFreeTimeout = RtlConvertLongToLargeInteger(QUEUE_ENTRY_FREE_TIMEOUT);
3541 +
3542 +#ifdef unix_fib_timeout
3543 +       FsaCommData.FibTimeoutIncrement = (180 * 1000 * 1000 * 10) / KeQueryTimeIncrement();
3544 +#endif
3545 +
3546 +       FsaCommData.EnableInterruptModeration = FALSE;
3547 +
3548 +       //
3549 +       // Preload UserVars with all variables from the comm layer.  The class layers will
3550 +       // include theirs when they register.
3551 +       //
3552 +
3553 +       FsaCommData.UserVars = OsAllocMemory(NUM_COMM_USER_VARS * sizeof(FSA_USER_VAR), OS_ALLOC_MEM_SLEEP );
3554 +       FsaCommData.NumUserVars = NUM_COMM_USER_VARS;
3555 +
3556 +       RtlCopyMemory( FsaCommData.UserVars, &FsaCommUserVars, NUM_COMM_USER_VARS * sizeof(FSA_USER_VAR) );
3557 +
3558 +
3559 +#ifdef AACDISK
3560 +       //
3561 +       // Call the disk driver to initialize itself.
3562 +       //
3563 +
3564 +       AacDiskDriverEntry();
3565 +
3566 +#endif
3567 +
3568 +
3569 +
3570 +       return (STATUS_SUCCESS);
3571 +}
3572 +
3573 +
3574 +VOID
3575 +DetachNTQueue(
3576 +       IN PAFA_COMM_ADAPTER Adapter,
3577 +    IN OUT PCOMM_QUE Queue,
3578 +    IN QUEUE_TYPES WhichQueue
3579 +    )
3580 +/*++
3581 +
3582 +Routine Description:
3583 +
3584 +       This routine will release all of the resources used by a given queue.
3585 +
3586 +Arguments:
3587 +
3588 +       Adapter - Which adapter the queue belongs to
3589 +       Queue - Pointer to the queue itself
3590 +       WhichQueue - Identifies which of the host queues this is.
3591 +
3592 +Return Value:
3593 +
3594 +       NONE.
3595 +
3596 +--*/
3597 +{
3598 +    switch (WhichQueue) {
3599 +
3600 +        case HostNormCmdQueue:
3601 +
3602 +                       Os_remove_softintr( Queue->ConsumerRoutine );
3603 +                       OsSpinLockDestroy( Queue->QueueLock );
3604 +                       OsCv_destroy( &Queue->CommandReady );
3605 +                               
3606 +            break;
3607 +
3608 +        case HostHighCmdQueue:
3609 +
3610 +                       Os_remove_softintr( Queue->ConsumerRoutine );
3611 +                       OsSpinLockDestroy( Queue->QueueLock );
3612 +                       OsCv_destroy( &Queue->CommandReady );
3613 +                               
3614 +            break;
3615 +
3616 +        case HostNormRespQueue:
3617 +
3618 +                       Os_remove_softintr( Queue->ConsumerRoutine );
3619 +                       OsSpinLockDestroy( Queue->QueueLock );
3620 +            break;
3621 +
3622 +        case HostHighRespQueue:
3623 +
3624 +                       Os_remove_softintr( Queue->ConsumerRoutine );
3625 +                       OsSpinLockDestroy( Queue->QueueLock );
3626 +            break;
3627 +
3628 +        case AdapNormCmdQueue:
3629 +        case AdapHighCmdQueue:
3630 +        case AdapNormRespQueue:
3631 +        case AdapHighRespQueue:
3632 +                       OsCv_destroy( &Queue->QueueFull );
3633 +            break;
3634 +    }
3635 +}
3636 +    
3637 +VOID
3638 +InitializeNTQueue(
3639 +       IN PAFA_COMM_ADAPTER Adapter,
3640 +    IN OUT PCOMM_QUE Queue,
3641 +    IN QUEUE_TYPES WhichQueue
3642 +    )
3643 +/*++
3644 +
3645 +Routine Description:
3646 +
3647 +    Will initialize all entries in the queue that is NT specific.
3648 +
3649 +Arguments:
3650 +
3651 +Return Value:
3652 +
3653 +    Nothing there is nothing to allocate so nothing should fail
3654 +
3655 +--*/
3656 +{
3657 +    
3658 +       Queue->NumOutstandingIos = 0;
3659 +
3660 +       //
3661 +       // Store a pointer to the adapter structure.
3662 +       //
3663 +
3664 +       Queue->Adapter = Adapter;
3665 +
3666 +       InitializeListHead( &Queue->OutstandingIoQueue );
3667 +           
3668 +    switch (WhichQueue) {
3669 +
3670 +        case HostNormCmdQueue:
3671 +
3672 +                       OsCv_init( &Queue->CommandReady);
3673 +                       OsSpinLockInit( Queue->QueueLock, Adapter->SpinLockCookie);
3674 +                       if (ddi_add_softintr( Adapter->Dip, DDI_SOFTINT_HIGH, &Queue->ConsumerRoutine, NULL,
3675 +                                                                 NULL, (PUNIX_INTR_HANDLER)HostCommandNormDpc,
3676 +                                                                 (caddr_t)Queue ) != DDI_SUCCESS) {
3677 +
3678 +                               cmn_err(CE_CONT, "OS_addr_intr failed\n");                                      
3679 +                       }                                       
3680 +
3681 +            InitializeListHead(&Queue->CommandQueue);
3682 +
3683 +            break;
3684 +
3685 +        case HostHighCmdQueue:
3686 +
3687 +                       OsCv_init( &Queue->CommandReady);
3688 +                       OsSpinLockInit( Queue->QueueLock, Adapter->SpinLockCookie);
3689 +                       if (ddi_add_softintr( Adapter->Dip, DDI_SOFTINT_HIGH, &Queue->ConsumerRoutine, NULL,
3690 +                                                                 NULL, (PUNIX_INTR_HANDLER)HostCommandHighDpc,
3691 +                                                                 (caddr_t) Queue ) != DDI_SUCCESS) {
3692 +
3693 +                               cmn_err(CE_CONT, "OS_addr_intr failed\n");                                      
3694 +                       }                                       
3695 +
3696 +            InitializeListHead(&Queue->CommandQueue);
3697 +            break;
3698 +
3699 +        case HostNormRespQueue:
3700 +
3701 +                       OsSpinLockInit( Queue->QueueLock, Adapter->SpinLockCookie);
3702 +                       if (ddi_add_softintr( Adapter->Dip, DDI_SOFTINT_HIGH, &Queue->ConsumerRoutine, NULL,
3703 +                                                                 NULL, (PUNIX_INTR_HANDLER)HostResponseNormalDpc, 
3704 +                                                                 (caddr_t) Queue ) != DDI_SUCCESS) {
3705 +
3706 +                               cmn_err(CE_CONT, "OS_addr_intr failed\n");                                      
3707 +                       }                                       
3708 +            break;
3709 +
3710 +        case HostHighRespQueue:
3711 +
3712 +
3713 +                       OsSpinLockInit( Queue->QueueLock, Adapter->SpinLockCookie);
3714 +                       if (ddi_add_softintr( Adapter->Dip, DDI_SOFTINT_HIGH, &Queue->ConsumerRoutine, NULL,
3715 +                                                                 NULL, (PUNIX_INTR_HANDLER)HostResponseHighDpc, 
3716 +                                                                 (caddr_t) Queue ) != DDI_SUCCESS) {
3717 +
3718 +                               cmn_err(CE_CONT, "OS_addr_intr failed\n");                                      
3719 +                       }                                       
3720 +            break;
3721 +
3722 +        case AdapNormCmdQueue:
3723 +        case AdapHighCmdQueue:
3724 +        case AdapNormRespQueue:
3725 +        case AdapHighRespQueue:
3726 +
3727 +                       OsCv_init( &Queue->QueueFull);
3728 +            break;
3729 +    }
3730 +}
3731 +
3732 +BOOLEAN
3733 +StartFsaCommandThreads(PAFA_COMM_ADAPTER Adapter)
3734 +/*++
3735 +
3736 +Routine Description:
3737 +
3738 +    Create and start the command receiver threads.
3739 +
3740 +Arguments:
3741 +
3742 +
3743 +Return Value:
3744 +
3745 +    Nothing
3746 +
3747 +--*/
3748 +
3749 +{
3750 +    return(TRUE);
3751 +}
3752 +
3753 +
3754 +
3755 +/*++
3756 +
3757 +Routine Description:
3758 +
3759 +       This routine gets called to detach all resources that have been allocated for 
3760 +       this adapter.
3761 +
3762 +Arguments:
3763 +
3764 +       Adapter - Pointer to the adapter structure to detach.
3765 +
3766 +Return Value:
3767 +
3768 +    TRUE - All resources have been properly released.
3769 +    FALSE - An error occured while trying to release resources.
3770 +--*/
3771 +BOOLEAN
3772 +AacCommDetachAdapter (IN PAFA_COMM_ADAPTER     Adapter)
3773 +{
3774 +       PAFA_CLASS_DRIVER ClassDriver;
3775 +       //
3776 +       // First remove this adapter from the list of adapters.
3777 +       //
3778 +
3779 +       if (FsaCommData.AdapterList == Adapter) {
3780 +               
3781 +               FsaCommData.AdapterList = Adapter->NextAdapter;
3782 +
3783 +       } else {
3784 +
3785 +               PAFA_COMM_ADAPTER CurrentAdapter, NextAdapter;
3786 +       
3787 +               CurrentAdapter = FsaCommData.AdapterList;
3788 +               NextAdapter = CurrentAdapter->NextAdapter;
3789 +
3790 +               while (NextAdapter) {
3791 +                               
3792 +                       if (NextAdapter == Adapter) {
3793 +
3794 +                               CurrentAdapter->NextAdapter = NextAdapter->NextAdapter;
3795 +                               break;
3796 +                        
3797 +                       }
3798 +                       
3799 +                       CurrentAdapter = NextAdapter;
3800 +                       NextAdapter = CurrentAdapter->NextAdapter;
3801 +               }
3802 +       }                       
3803 +               
3804 +       //
3805 +       // First send a shutdown to the adapter.
3806 +       //
3807 +
3808 +       AfaCommShutdown( Adapter );
3809 +
3810 +       //
3811 +       // Destroy the FibContextZone for this adapter.  This will free up all
3812 +       // of the fib space used by this adapter.
3813 +       //
3814 +       
3815 +       FsaFreeFibContextZone( Adapter );
3816 +
3817 +       //
3818 +       // Destroy the mutex used for synch'ing adapter fibs.
3819 +       //
3820 +
3821 +       OsCvLockDestroy( Adapter->AdapterFibMutex );
3822 +
3823 +       //
3824 +       // Detach all of the host queues.
3825 +       //
3826 +
3827 +    DetachNTQueue( Adapter, &Adapter->CommRegion->AdapHighRespQue, AdapHighRespQueue );
3828 +    DetachNTQueue( Adapter, &Adapter->CommRegion->AdapNormRespQue, AdapNormRespQueue );
3829 +    DetachNTQueue( Adapter, &Adapter->CommRegion->HostHighRespQue, HostHighRespQueue );
3830 +    DetachNTQueue( Adapter, &Adapter->CommRegion->HostNormRespQue, HostNormRespQueue );
3831 +    DetachNTQueue( Adapter, &Adapter->CommRegion->AdapHighCmdQue, AdapHighCmdQueue );
3832 +    DetachNTQueue( Adapter, &Adapter->CommRegion->AdapNormCmdQue, AdapNormCmdQueue );
3833 +    DetachNTQueue( Adapter, &Adapter->CommRegion->HostHighCmdQue, HostHighCmdQueue );
3834 +       DetachNTQueue( Adapter, &Adapter->CommRegion->HostNormCmdQue, HostNormCmdQueue );
3835 +
3836 +       //
3837 +       // Destroy the mutex used to protect the FibContextZone
3838 +       //
3839 +
3840 +       OsSpinLockDestroy( Adapter->FibContextZoneSpinLock );
3841 +
3842 +       //
3843 +       // Call the miniport to free the space allocated for the shared comm queues
3844 +       // between the host and the adapter.
3845 +       //
3846 +
3847 +       FsaFreeAdapterCommArea( Adapter );
3848 +
3849 +       //
3850 +       // Free the memory used by the comm region for this adapter
3851 +       //
3852 +
3853 +       OsFreeMemory( Adapter->CommRegion, sizeof(COMM_REGION) );
3854 +
3855 +       //
3856 +       // Free the memory used by the adapter structure.
3857 +       //
3858 +       ClassDriver = Adapter->ClassDriverList;
3859 +       Adapter->ClassDriverList = Adapter->ClassDriverList->Next;
3860 +       OsFreeMemory( ClassDriver, sizeof(AFA_CLASS_DRIVER) );
3861 +       
3862 +       OsFreeMemory( Adapter, sizeof(AFA_COMM_ADAPTER) );
3863 +
3864 +       return (TRUE);
3865 +}
3866 +
3867 +PVOID
3868 +AfaCommInitNewAdapter (IN PFSA_NEW_ADAPTER NewAdapter)
3869 +{
3870 +       PVOID BugCheckBuffer;
3871 +       PAFA_COMM_ADAPTER Adapter;
3872 +       MAPFIB_CONTEXT MapFibContext;
3873 +       LARGE_INTEGER Time;
3874 +       char ErrorBuffer[60];
3875 +
3876 +       Adapter = (PAFA_COMM_ADAPTER) OsAllocMemory( sizeof(AFA_COMM_ADAPTER) , OS_ALLOC_MEM_SLEEP );
3877 +
3878 +       if (Adapter == NULL)
3879 +               return (NULL);
3880 +
3881 +       RtlZeroMemory(Adapter, sizeof(AFA_COMM_ADAPTER));
3882 +
3883 +
3884 +       //
3885 +       // Save the current adapter number and increment the total number.
3886 +       //
3887 +
3888 +       Adapter->AdapterNumber = FsaCommData.TotalAdapters++;
3889 +
3890 +
3891 +       //
3892 +       // Fill in the pointer back to the device specific structures.
3893 +       // The device specific driver has also passed a pointer for us to 
3894 +       // fill in with the Adapter object that we have created.
3895 +       //
3896 +
3897 +       Adapter->AdapterExtension = NewAdapter->AdapterExtension;
3898 +       Adapter->AdapterFuncs = NewAdapter->AdapterFuncs;
3899 +       Adapter->InterruptsBelowDpc = NewAdapter->AdapterInterruptsBelowDpc;
3900 +       Adapter->AdapterUserVars = NewAdapter->AdapterUserVars;
3901 +       Adapter->AdapterUserVarsSize = NewAdapter->AdapterUserVarsSize;
3902 +
3903 +       Adapter->Dip = NewAdapter->Dip;
3904 +
3905 +       //
3906 +       // Fill in Our address into the function dispatch table
3907 +       //
3908 +
3909 +       NewAdapter->AdapterFuncs->InterruptHost = AfaCommInterruptHost;
3910 +       NewAdapter->AdapterFuncs->OpenAdapter = AfaCommOpenAdapter;
3911 +       NewAdapter->AdapterFuncs->CloseAdapter = AfaCommCloseAdapter;
3912 +       NewAdapter->AdapterFuncs->DeviceControl = AfaCommAdapterDeviceControl;
3913 +
3914 +       //
3915 +       // Ok now init the communication subsystem
3916 +       //
3917 +
3918 +       Adapter->CommRegion = (PCOMM_REGION) OsAllocMemory(sizeof(COMM_REGION), OS_ALLOC_MEM_SLEEP);
3919 +       if (Adapter->CommRegion == NULL) {
3920 +               cmn_err(CE_WARN, "Error could not allocate comm region.\n");
3921 +               return (NULL);
3922 +       }
3923 +       RtlZeroMemory(Adapter->CommRegion, sizeof(COMM_REGION));
3924 +
3925 +       //
3926 +       // Get a pointer to the iblock_cookie
3927 +       //
3928 +
3929 +       ddi_get_soft_iblock_cookie( Adapter->Dip, DDI_SOFTINT_HIGH, &Adapter->SpinLockCookie );
3930 +
3931 +       if (!CommInit(Adapter)) {
3932 +               FsaCommPrint("Failed to init the commuication subsystem.\n");
3933 +               return(NULL);
3934 +       }
3935 +
3936 +
3937 +       //
3938 +       // Initialize the list of AdapterFibContext's.
3939 +       //
3940 +
3941 +       InitializeListHead(&Adapter->AdapterFibContextList);
3942 +
3943 +       //
3944 +       // Initialize the fast mutex used for synchronization of the adapter fibs
3945 +       //
3946 +
3947 +       Adapter->AdapterFibMutex = OsCvLockAlloc();
3948 +       OsCvLockInit(Adapter->AdapterFibMutex, NULL);
3949 +
3950 +    //
3951 +    // Allocate and start the FSA command threads. These threads will handle
3952 +    // command requests from the adapter. They will wait on an event then pull
3953 +    // all CDBs off the thread's queue. Each CDB will be given to a worker thread
3954 +    // upto a defined limit. When that limit is reached wait a event will be waited
3955 +    // on till a worker thread is finished.
3956 +    //
3957 +
3958 +    if (!StartFsaCommandThreads(Adapter)) {
3959 +           FsaCommPrint("Fsainit could not initilize the command receiver threads.\n");
3960 +               return (NULL);
3961 +    }
3962 +
3963 +#ifdef unix_crash_dump
3964 +       //
3965 +       // Allocate and map a fib for use by the synch path, which is used for crash
3966 +       // dumps.
3967 +       //
3968 +       // Allocate an entire page so that alignment is correct.
3969 +       //
3970 +
3971 +       Adapter->SyncFib = OsAllocMemory( PAGE_SIZE, OS_ALLOC_MEM_SLEEP );
3972 +       MapFibContext.Fib = Adapter->SyncFib;
3973 +       MapFibContext.Size = sizeof(FIB);
3974 +       MapFib( Adapter, &MapFibContext );
3975 +       Adapter->SyncFibPhysicalAddress = MapFibContext.LogicalFibAddress.LowPart;
3976 +#endif
3977 +
3978 +       Adapter->CommFuncs.SizeOfAfaCommFuncs = sizeof(AFACOMM_FUNCS);
3979 +
3980 +       Adapter->CommFuncs.AllocateFib = AllocateFib;
3981 +
3982 +       Adapter->CommFuncs.FreeFib = FreeFib;
3983 +       Adapter->CommFuncs.FreeFibFromDpc = FreeFibFromDpc;
3984 +       Adapter->CommFuncs.DeallocateFib = DeallocateFib;
3985 +
3986 +       Adapter->CommFuncs.InitializeFib = InitializeFib;
3987 +       Adapter->CommFuncs.GetFibData = FsaGetFibData;
3988 +       Adapter->CommFuncs.SendFib = SendFib;
3989 +       Adapter->CommFuncs.CompleteFib = CompleteFib;
3990 +       Adapter->CommFuncs.CompleteAdapterFib = CompleteAdapterFib;
3991 +
3992 +       Adapter->CommFuncs.SendSynchFib = SendSynchFib;
3993 +
3994 +       Adapter->CommFuncs.FreeDmaResources = Adapter->AdapterFuncs->FreeDmaResources;
3995 +       Adapter->CommFuncs.BuildSgMap = Adapter->AdapterFuncs->BuildSgMap;
3996 +
3997 +       //
3998 +       // Add this adapter in to our Adapter List.
3999 +       //
4000 +
4001 +       Adapter->NextAdapter = FsaCommData.AdapterList;
4002 +       FsaCommData.AdapterList = Adapter;
4003 +
4004 +       NewAdapter->Adapter = Adapter;
4005 +
4006 +//     AfaDiskInitNewAdapter( Adapter->AdapterNumber, Adapter );
4007 +
4008 +       return (Adapter);
4009 +}
4010 +
4011 +AAC_STATUS
4012 +CommInitialize(
4013 +       PAFA_COMM_ADAPTER Adapter
4014 +       )
4015 +{
4016 +    //
4017 +    //  Now allocate and initialize the zone structures used as our pool
4018 +    //  of FIB context records.  The size of the zone is based on the
4019 +    //  system memory size.  We also initialize the mutex used to protect
4020 +    //  the zone.
4021 +    //
4022 +       Adapter->FibContextZoneSpinLock = OsSpinLockAlloc();
4023 +       OsSpinLockInit( Adapter->FibContextZoneSpinLock, Adapter->SpinLockCookie );
4024 +
4025 +       Adapter->FibContextZoneExtendSize = 64;
4026 +
4027 +       return (STATUS_SUCCESS);
4028 +}
4029 +
4030 +
4031 +    
4032 +/*++
4033 +
4034 +Routine Description:
4035 +
4036 +    Initializes the data structures that are required for the FSA commuication
4037 +    interface to operate.
4038 +
4039 +Arguments:
4040 +
4041 +    None - all global or allocated data.
4042 +
4043 +Return Value:
4044 +
4045 +    TRUE - if we were able to init the commuication interface.
4046 +    FALSE - If there were errors initing. This is a fatal error.
4047 +--*/
4048 +BOOLEAN
4049 +CommInit(PAFA_COMM_ADAPTER Adapter)
4050 +{
4051 +    
4052 +    ULONG SizeOfHeaders = (sizeof(QUEUE_INDEX) * NUMBER_OF_COMM_QUEUES) * 2;
4053 +    ULONG SizeOfQueues = sizeof(QUEUE_ENTRY) * TOTAL_QUEUE_ENTRIES;
4054 +    PQUEUE_INDEX Headers;
4055 +    PQUEUE_ENTRY Queues;
4056 +       ULONG TotalSize;
4057 +       PCOMM_REGION CommRegion = Adapter->CommRegion;
4058 +
4059 +        CommInitialize( Adapter );
4060 +
4061 +       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",
4062 +                         sizeof(QUEUE_ENTRY), sizeof(QUEUE_INDEX), TOTAL_QUEUE_ENTRIES, NUMBER_OF_COMM_QUEUES);
4063 +       //
4064 +       //
4065 +       // Allocate the physically contigous space for the commuication queue
4066 +       // headers. 
4067 +       //
4068 +
4069 +       TotalSize = SizeOfHeaders + SizeOfQueues;
4070 +
4071 +       if (!FsaAllocateAdapterCommArea(Adapter, (PVOID *)&Headers, TotalSize, QUEUE_ALIGNMENT))
4072 +               return (FALSE);
4073 +
4074 +       Queues = (PQUEUE_ENTRY)((PUCHAR)Headers + SizeOfHeaders);
4075 +
4076 +       if (ddi_add_softintr( Adapter->Dip, DDI_SOFTINT_HIGH, &CommRegion->QueueNotFullDpc, NULL,
4077 +                                                 NULL, (PUNIX_INTR_HANDLER)CommonNotFullDpc,
4078 +                                                 (caddr_t)CommRegion ) != DDI_SUCCESS) {
4079 +
4080 +         cmn_err(CE_CONT, "Os_addr_intr failed\n");                                    
4081 +       }                                       
4082 +
4083 +
4084 +    // Adapter to Host normal priority Command queue
4085 +
4086 +
4087 +    CommRegion->HostNormCmdQue.Headers.ProducerIndex = Headers++;
4088 +    CommRegion->HostNormCmdQue.Headers.ConsumerIndex = Headers++;
4089 +    *CommRegion->HostNormCmdQue.Headers.ProducerIndex = HOST_NORM_CMD_ENTRIES;
4090 +    *CommRegion->HostNormCmdQue.Headers.ConsumerIndex = HOST_NORM_CMD_ENTRIES;
4091 +
4092 +    CommRegion->HostNormCmdQue.SavedIrql = 0;
4093 +    CommRegion->HostNormCmdQue.BaseAddress = Queues;
4094 +    CommRegion->HostNormCmdQue.QueueEntries = HOST_NORM_CMD_ENTRIES;
4095 +
4096 +       CommRegion->HostNormCmdQue.QueueLock = OsSpinLockAlloc();
4097 +       if (CommRegion->HostNormCmdQue.QueueLock == NULL) {
4098 +               return (FALSE);
4099 +       }
4100 +    InitializeNTQueue(Adapter, &CommRegion->HostNormCmdQue, HostNormCmdQueue);
4101 +
4102 +    
4103 +    Queues += HOST_NORM_CMD_ENTRIES;
4104 +
4105 +    // Adapter to Host high priority command queue
4106 +    
4107 +    CommRegion->HostHighCmdQue.Headers.ProducerIndex = Headers++;
4108 +    CommRegion->HostHighCmdQue.Headers.ConsumerIndex = Headers++;
4109 +    *CommRegion->HostHighCmdQue.Headers.ProducerIndex = HOST_HIGH_CMD_ENTRIES;
4110 +    *CommRegion->HostHighCmdQue.Headers.ConsumerIndex = HOST_HIGH_CMD_ENTRIES;
4111 +
4112 +    CommRegion->HostHighCmdQue.SavedIrql = 0;
4113 +    CommRegion->HostHighCmdQue.BaseAddress = Queues;
4114 +    CommRegion->HostHighCmdQue.QueueEntries = HOST_HIGH_CMD_ENTRIES;
4115 +//     CommRegion->HostHighCmdQue.QueueLock = (PKSPIN_LOCK) ExAllocatePool(NonPagedPool, sizeof(KSPIN_LOCK));
4116 +       CommRegion->HostHighCmdQue.QueueLock = OsSpinLockAlloc();
4117 +       if (CommRegion->HostHighCmdQue.QueueLock == NULL) {
4118 +               return (FALSE);
4119 +       }
4120 +    InitializeNTQueue(Adapter, &CommRegion->HostHighCmdQue, HostHighCmdQueue);
4121 +    
4122 +    Queues += HOST_HIGH_CMD_ENTRIES;
4123 +
4124 +    // Host to adapter normal priority command queue
4125 +    
4126 +    CommRegion->AdapNormCmdQue.Headers.ProducerIndex = Headers++;
4127 +    CommRegion->AdapNormCmdQue.Headers.ConsumerIndex = Headers++;
4128 +    *CommRegion->AdapNormCmdQue.Headers.ProducerIndex = ADAP_NORM_CMD_ENTRIES;
4129 +    *CommRegion->AdapNormCmdQue.Headers.ConsumerIndex = ADAP_NORM_CMD_ENTRIES;
4130 +
4131 +    CommRegion->AdapNormCmdQue.SavedIrql = 0;    
4132 +    CommRegion->AdapNormCmdQue.BaseAddress = Queues;
4133 +    CommRegion->AdapNormCmdQue.QueueEntries = ADAP_NORM_CMD_ENTRIES;
4134 +    InitializeNTQueue(Adapter, &CommRegion->AdapNormCmdQue, AdapNormCmdQueue);
4135 +    
4136 +    Queues += ADAP_NORM_CMD_ENTRIES;
4137 +
4138 +    // host to adapter high priority command queue
4139 +    
4140 +    CommRegion->AdapHighCmdQue.Headers.ProducerIndex = Headers++;
4141 +    CommRegion->AdapHighCmdQue.Headers.ConsumerIndex = Headers++;
4142 +    *CommRegion->AdapHighCmdQue.Headers.ProducerIndex = ADAP_HIGH_CMD_ENTRIES;
4143 +    *CommRegion->AdapHighCmdQue.Headers.ConsumerIndex = ADAP_HIGH_CMD_ENTRIES;
4144 +
4145 +    CommRegion->AdapHighCmdQue.SavedIrql = 0;    
4146 +    CommRegion->AdapHighCmdQue.BaseAddress = Queues;
4147 +    CommRegion->AdapHighCmdQue.QueueEntries = ADAP_HIGH_CMD_ENTRIES;
4148 +    InitializeNTQueue(Adapter, &CommRegion->AdapHighCmdQue, AdapHighCmdQueue);
4149 +    
4150 +    Queues += ADAP_HIGH_CMD_ENTRIES;
4151 +
4152 +    // adapter to host normal priority response queue
4153 +    
4154 +    CommRegion->HostNormRespQue.Headers.ProducerIndex = Headers++;
4155 +    CommRegion->HostNormRespQue.Headers.ConsumerIndex = Headers++;
4156 +    *CommRegion->HostNormRespQue.Headers.ProducerIndex = HOST_NORM_RESP_ENTRIES;
4157 +    *CommRegion->HostNormRespQue.Headers.ConsumerIndex = HOST_NORM_RESP_ENTRIES;
4158 +
4159 +    CommRegion->HostNormRespQue.SavedIrql = 0;    
4160 +    CommRegion->HostNormRespQue.BaseAddress = Queues;
4161 +    CommRegion->HostNormRespQue.QueueEntries = HOST_NORM_RESP_ENTRIES;
4162 +//     CommRegion->HostNormRespQue.QueueLock = (PKSPIN_LOCK) ExAllocatePool(NonPagedPool, sizeof(KSPIN_LOCK));
4163 +       CommRegion->HostNormRespQue.QueueLock = OsSpinLockAlloc();
4164 +       if (CommRegion->HostNormRespQue.QueueLock == NULL) {
4165 +               return (FALSE);
4166 +       }
4167 +    InitializeNTQueue(Adapter, &CommRegion->HostNormRespQue, HostNormRespQueue);
4168 +    
4169 +    Queues += HOST_NORM_RESP_ENTRIES;
4170 +
4171 +    // adapter to host high priority response queue
4172 +    
4173 +    CommRegion->HostHighRespQue.Headers.ProducerIndex = Headers++;
4174 +    CommRegion->HostHighRespQue.Headers.ConsumerIndex = Headers++;
4175 +    *CommRegion->HostHighRespQue.Headers.ProducerIndex = HOST_HIGH_RESP_ENTRIES;
4176 +    *CommRegion->HostHighRespQue.Headers.ConsumerIndex = HOST_HIGH_RESP_ENTRIES;
4177 +
4178 +    CommRegion->HostHighRespQue.SavedIrql = 0;    
4179 +    CommRegion->HostHighRespQue.BaseAddress = Queues;
4180 +    CommRegion->HostHighRespQue.QueueEntries = HOST_HIGH_RESP_ENTRIES;
4181 +//     CommRegion->HostHighRespQue.QueueLock = (PKSPIN_LOCK) ExAllocatePool(NonPagedPool, sizeof(KSPIN_LOCK));
4182 +       CommRegion->HostHighRespQue.QueueLock = OsSpinLockAlloc();
4183 +       if (CommRegion->HostHighRespQue.QueueLock == NULL) {
4184 +               return (FALSE);
4185 +       }
4186 +    InitializeNTQueue(Adapter, &CommRegion->HostHighRespQue, HostHighRespQueue);
4187 +    
4188 +    Queues += HOST_HIGH_RESP_ENTRIES;
4189 +
4190 +    // host to adapter normal priority response queue
4191 +    
4192 +    CommRegion->AdapNormRespQue.Headers.ProducerIndex = Headers++;
4193 +    CommRegion->AdapNormRespQue.Headers.ConsumerIndex = Headers++;
4194 +    *CommRegion->AdapNormRespQue.Headers.ProducerIndex = ADAP_NORM_RESP_ENTRIES;
4195 +    *CommRegion->AdapNormRespQue.Headers.ConsumerIndex = ADAP_NORM_RESP_ENTRIES;
4196 +
4197 +    CommRegion->AdapNormRespQue.SavedIrql = 0;    
4198 +    CommRegion->AdapNormRespQue.BaseAddress = Queues;
4199 +    CommRegion->AdapNormRespQue.QueueEntries = ADAP_NORM_RESP_ENTRIES;
4200 +    InitializeNTQueue(Adapter, &CommRegion->AdapNormRespQue, AdapNormRespQueue);
4201 +    
4202 +    Queues += ADAP_NORM_RESP_ENTRIES;
4203 +
4204 +    // host to adapter high priority response queue
4205 +    
4206 +    CommRegion->AdapHighRespQue.Headers.ProducerIndex = Headers++;
4207 +    CommRegion->AdapHighRespQue.Headers.ConsumerIndex = Headers++;
4208 +    *CommRegion->AdapHighRespQue.Headers.ProducerIndex = ADAP_HIGH_RESP_ENTRIES;
4209 +    *CommRegion->AdapHighRespQue.Headers.ConsumerIndex = ADAP_HIGH_RESP_ENTRIES;
4210 +
4211 +    CommRegion->AdapHighRespQue.SavedIrql = 0;    
4212 +    CommRegion->AdapHighRespQue.BaseAddress = Queues;
4213 +    CommRegion->AdapHighRespQue.QueueEntries = ADAP_HIGH_RESP_ENTRIES;
4214 +    InitializeNTQueue(Adapter, &CommRegion->AdapHighRespQue, AdapHighRespQueue);
4215 +
4216 +       CommRegion->AdapNormCmdQue.QueueLock = CommRegion->HostNormRespQue.QueueLock;
4217 +       CommRegion->AdapHighCmdQue.QueueLock = CommRegion->HostHighRespQue.QueueLock;
4218 +       CommRegion->AdapNormRespQue.QueueLock = CommRegion->HostNormCmdQue.QueueLock;
4219 +       CommRegion->AdapHighRespQue.QueueLock = CommRegion->HostHighCmdQue.QueueLock;
4220 +
4221 +    return(TRUE);
4222 +}
4223 +
4224 +AAC_STATUS
4225 +AfaCommShutdown(
4226 +       PAFA_COMM_ADAPTER Adapter
4227 +       )
4228 +/*++
4229 +
4230 +Routine Description:
4231 +
4232 +       This routine will send a shutdown request to each adapter.
4233 +
4234 +Arguments:
4235 +
4236 +       Adapter - which adapter to send the shutdown to.
4237 +
4238 +Return Value:
4239 +
4240 +    NT Status success.
4241 +
4242 +--*/
4243 +
4244 +{
4245 +       PFIB_CONTEXT FibContext;
4246 +       PCLOSECOMMAND CloseCommand;
4247 +       AAC_STATUS Status;
4248 +
4249 +       FibContext = AllocateFib( Adapter );
4250 +
4251 +       InitializeFib( FibContext );
4252 +
4253 +       CloseCommand = (PCLOSECOMMAND) FsaGetFibData( FibContext );
4254 +
4255 +       CloseCommand->Command = VM_CloseAll;
4256 +       CloseCommand->ContainerId = 0xffffffff;
4257 +
4258 +       Status = SendFib( ContainerCommand, FibContext, sizeof(CLOSECOMMAND), FsaNormal, TRUE, NULL, TRUE, NULL, NULL );
4259 +
4260 +       if (Status != STATUS_SUCCESS) {
4261 +
4262 +               FreeFib( FibContext );
4263 +
4264 +               goto ret;
4265 +
4266 +       }
4267 +
4268 +       CompleteFib( FibContext );
4269 +
4270 +       FreeFib( FibContext );
4271 +
4272 +
4273 +       Status = STATUS_SUCCESS;
4274 +
4275 +ret:
4276 +
4277 +       return (Status);
4278 +
4279 +}
4280 +
4281 +VOID
4282 +AfaCommBugcheckHandler(
4283 +               IN PVOID Buffer,
4284 +               IN ULONG Length
4285 +               )
4286 +/*++
4287 +
4288 +Routine Description:
4289 +
4290 +       This routine will shutdown the adapter if there is a bugcheck and
4291 +       copy the shutdown data from the adapter response into the buffer
4292 +       so it will show up in the host dump file.
4293 +p
4294 +Arguments:
4295 +
4296 +       Buffer - This buffer will be written to the host dump by nt for us.
4297 +
4298 +       Length - The size of the buffer.
4299 +
4300 +Return Value:
4301 +
4302 +       N/A
4303 +
4304 +--*/
4305 +{
4306 +       PAFA_COMM_ADAPTER Adapter = FsaCommData.AdapterList;
4307 +
4308 +       while (Adapter) {
4309 +
4310 +               NotifyAdapter(Adapter, HostShutdown);
4311 +
4312 +               Adapter = Adapter->NextAdapter;
4313 +
4314 +       }
4315 +
4316 +}      
4317 +
4318 +VOID
4319 +FsaCommLogEvent(
4320 +       PFIB_CONTEXT FibContext, 
4321 +       PDEVICE_OBJECT DeviceObject,
4322 +       AAC_STATUS FsaStatus,
4323 +       AAC_STATUS AacStatus,
4324 +       ULONG LocationCode,
4325 +       USHORT Category,
4326 +       PUCHAR String,
4327 +       BOOLEAN DumpFib
4328 +)
4329 +{
4330 +}
4331 +
4332 +AfaCommProbeDisks(
4333 +       PAFA_COMM_ADAPTER       Adapter
4334 +       )
4335 +{
4336 +    PMNTINFO DiskInfo;
4337 +    PMNTINFORESPONSE DiskInfoResponse;
4338 +       AAC_STATUS Status;
4339 +       PCOMM_FIB_CONTEXT FibContext;
4340 +    
4341 +       FibContext = AllocateFib( Adapter );
4342 +
4343 +       InitializeFib( FibContext );
4344 +
4345 +       DiskInfo = (PMNTINFO) FibContext->Fib->data;
4346 +       DiskInfo->Command = VM_NameServe;
4347 +       DiskInfo->MntCount = 0;
4348 +       DiskInfo->MntType = FT_FILESYS;
4349 +
4350 +    Status = SendFib(ContainerCommand,
4351 +                            FibContext,
4352 +                        sizeof(MNTINFO),
4353 +                        FsaNormal,
4354 +                        TRUE,
4355 +                        NULL,
4356 +                        TRUE,
4357 +                        NULL,
4358 +                        NULL);
4359 +
4360 +       DiskInfoResponse = (PMNTINFORESPONSE) FibContext->Fib->data;
4361 +
4362 +       if (DiskInfoResponse->MntRespCount) {
4363 +
4364 +               cmn_err(CE_CONT, "container found on adapter, size = 0x%x blocks\n", 
4365 +                               DiskInfoResponse->MntTable[0].Capacity);
4366 +                               
4367 +       } else {
4368 +       
4369 +               cmn_err(CE_CONT, "no containers found on adapter\n");
4370 +               
4371 +       }
4372 +                                       
4373 +       CompleteFib( FibContext );
4374 +       
4375 +       FreeFib( FibContext );                           
4376 +}
4377 +
4378 +
4379 diff -urN linux/drivers/scsi/aacraid/commsup.c linux/drivers/scsi/aacraid/commsup.c
4380 --- linux/drivers/scsi/aacraid/commsup.c        Wed Dec 31 19:00:00 1969
4381 +++ linux/drivers/scsi/aacraid/commsup.c        Thu Dec 21 13:14:30 2000
4382 @@ -0,0 +1,2180 @@
4383 +/*++
4384 + * Adaptec aacraid device driver for Linux.
4385 + *
4386 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
4387 + *
4388 + * This program is free software; you can redistribute it and/or modify
4389 + * it under the terms of the GNU General Public License as published by
4390 + * the Free Software Foundation; either version 2, or (at your option)
4391 + * any later version.
4392 + *
4393 + * This program is distributed in the hope that it will be useful,
4394 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
4395 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
4396 + * GNU General Public License for more details.
4397 + *
4398 + * You should have received a copy of the GNU General Public License
4399 + * along with this program; see the file COPYING.  If not, write to
4400 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
4401 + *
4402 + * Module Name:
4403 + *  commsup.c
4404 + *
4405 + * Abstract: Contain all routines that are required for FSA host/adapter
4406 + *    commuication.
4407 + *
4408 + *
4409 + --*/
4410 +
4411 +static char *ident_commsup = "aacraid_ident commsup.c 1.0.7 2000/10/11 Adaptec, Inc.";
4412 +
4413 +#include "comprocs.h"
4414 +
4415 +#define BugCheckFileId                   (FSAFS_BUG_CHECK_COMMSUP)
4416 +
4417 +int CommPrinting;
4418 +
4419 +void
4420 +ThrottleExceptionHandler(
4421 +       IN PCOMM_REGION CommRegion,
4422 +       AAC_STATUS              Status
4423 +       );
4424 +
4425 +void ThrottlePeriodEndDpcRtn(
4426 +    IN PKDPC Dpc,
4427 +    IN PVOID DeferredContext,
4428 +    IN PVOID SystemArgument1,
4429 +    IN PVOID SystemArgument2
4430 +    );
4431 +
4432 +
4433 +/*++
4434 +
4435 +Routine Description:
4436 +
4437 +       This routine will free all resources used by a given FibContextSegment.
4438 +
4439 +Arguments:
4440 +
4441 +       Adapter - The adapter that this COMM_FIB_CONTEXT will communicate with.
4442 +       ZoneSegment - The segment to release resources from.
4443 +
4444 +Return Value:
4445 +
4446 +       TRUE - All resources were properly freed.
4447 +       FALSE - An Error occured while freeing resources.
4448 +
4449 +--*/
4450 +BOOLEAN
4451 +FsaFreeFibContextSegment (PAFA_COMM_ADAPTER Adapter,
4452 +                                                 PFIB_CONTEXT_ZONE_SEGMENT     ZoneSegment)
4453 +{
4454 +       PCOMM_FIB_CONTEXT FibContext;
4455 +       int i;
4456 +       
4457 +       // Account for the ZONE_SEGMENT_HEADER before the first actual FibContext.
4458 +
4459 +       for (i = 0, FibContext = (PCOMM_FIB_CONTEXT)((PUCHAR)ZoneSegment->FibContextSegment + sizeof(ZONE_SEGMENT_HEADER));
4460 +                i < ZoneSegment->ExtendSize; i++, FibContext++) {
4461 +
4462 +               OsCvLockDestroy( FibContext->FsaEventMutex );
4463 +               OsCv_destroy( &FibContext->FsaEvent );
4464 +
4465 +       }
4466 +
4467 +       UnmapAndFreeFibSpace( Adapter, &ZoneSegment->MapFibContext );
4468 +
4469 +       OsFreeMemory( ZoneSegment->FibContextSegment, ZoneSegment->FibContextSegmentSize );
4470 +
4471 +       OsFreeMemory( ZoneSegment, sizeof( FIB_CONTEXT_ZONE_SEGMENT ) );
4472 +
4473 +       return (TRUE);
4474 +}
4475 +
4476 +BOOLEAN
4477 +FsaFreeFibContextZone(
4478 +       PAFA_COMM_ADAPTER Adapter
4479 +       )
4480 +/*++
4481 +
4482 +Routine Description:
4483 +
4484 +       This routine will walk through the FibContextSegmentList and free up all
4485 +       resources used by the FibContextZone.
4486 +
4487 +Arguments:
4488 +
4489 +       Adapter - The adapter that this COMM_FIB_CONTEXT will communicate with.
4490 +
4491 +Return Value:
4492 +
4493 +       TRUE - All resources were properly freed.
4494 +       FALSE - An Error occured while freeing resources.
4495 +
4496 +--*/
4497 +
4498 +{
4499 +       PFIB_CONTEXT_ZONE_SEGMENT ZoneSegment, NextZoneSegment;
4500 +
4501 +       ZoneSegment = Adapter->FibContextSegmentList;
4502 +
4503 +       while (ZoneSegment) {
4504 +
4505 +               NextZoneSegment = ZoneSegment->Next;
4506 +
4507 +               FsaFreeFibContextSegment( Adapter, ZoneSegment );
4508 +
4509 +               ZoneSegment = NextZoneSegment;
4510 +       }
4511 +
4512 +       return (TRUE);
4513 +}
4514 +
4515 +       
4516 +
4517 +BOOLEAN
4518 +FsaExtendFibContextZone (IN PAFA_COMM_ADAPTER Adapter)
4519 +{
4520 +    int ExtendSize;
4521 +    KIRQL SavedIrql;
4522 +       ULONG ZoneSegmentAllocSize, FibAllocSize;
4523 +       PVOID FibContextSegment;
4524 +       PCOMM_FIB_CONTEXT FibContext;
4525 +       PFIB Fib;
4526 +       PVOID FibPhysicalAddress;
4527 +       int i;
4528 +       PFIB_CONTEXT_ZONE_SEGMENT ZoneSegment;
4529 +       
4530 +       //
4531 +       // Allocate space to describe this zone segment.
4532 +       //
4533 +
4534 +       cmn_err (CE_DEBUG, "Entered FsaExtendFibConextZone");
4535 +       ZoneSegment = OsAllocMemory( sizeof( FIB_CONTEXT_ZONE_SEGMENT ), OS_ALLOC_MEM_SLEEP );
4536 +
4537 +       ExtendSize = Adapter->FibContextZoneExtendSize;
4538 +       ZoneSegmentAllocSize = (ExtendSize * sizeof(COMM_FIB_CONTEXT)) + sizeof(ZONE_SEGMENT_HEADER);
4539 +
4540 +       FibContextSegment = OsAllocMemory( ZoneSegmentAllocSize, OS_ALLOC_MEM_SLEEP );
4541 +
4542 +       if (FibContextSegment == NULL) {
4543 +               return (FALSE);
4544 +       }       
4545 +
4546 +       RtlZeroMemory( FibContextSegment, ZoneSegmentAllocSize );
4547 +
4548 +       ZoneSegment->FibContextSegment = FibContextSegment;
4549 +       ZoneSegment->FibContextSegmentSize = ZoneSegmentAllocSize;
4550 +       ZoneSegment->ExtendSize = ExtendSize;
4551 +
4552 +       FibAllocSize = ExtendSize * sizeof(FIB);
4553 +
4554 +
4555 +       ZoneSegment->MapFibContext.Size = FibAllocSize;
4556 +
4557 +       AllocateAndMapFibSpace( Adapter, &ZoneSegment->MapFibContext );
4558 +
4559 +       Fib = ZoneSegment->MapFibContext.FibVirtualAddress;
4560 +       FibPhysicalAddress = ZoneSegment->MapFibContext.FibPhysicalAddress;
4561 +
4562 +       RtlZeroMemory( Fib, FibAllocSize );
4563 +
4564 +       // Account for the ZONE_SEGMENT_HEADER before the first actual FibContext.
4565 +
4566 +       for (i = 0, FibContext = (PCOMM_FIB_CONTEXT)((PUCHAR)FibContextSegment + sizeof(ZONE_SEGMENT_HEADER));
4567 +                i < ExtendSize; i++, FibContext++) {
4568 +
4569 +               FibContext->Adapter = Adapter;
4570 +
4571 +               FibContext->Fib = Fib;
4572 +               FibContext->FibData = (PVOID) FibContext->Fib->data;
4573 +
4574 +               OsCv_init( &FibContext->FsaEvent);
4575 +               FibContext->FsaEventMutex = OsCvLockAlloc();
4576 +               OsCvLockInit( FibContext->FsaEventMutex, Adapter->SpinLockCookie );
4577 +
4578 +               Fib->Header.XferState = 0xffffffff;
4579 +               Fib->Header.SenderSize = sizeof(FIB);
4580 +
4581 +               FibContext->LogicalFibAddress.LowPart = (ULONG) FibPhysicalAddress;
4582 +
4583 +               Fib = (PFIB)((PUCHAR)Fib + sizeof(FIB));
4584 +               FibPhysicalAddress = (PVOID)((PUCHAR)FibPhysicalAddress + sizeof(FIB));
4585 +       }
4586 +
4587 +       //
4588 +       // If FibContextZone.TotalSegmentSize is non-zero, then a zone has already been
4589 +       // initialized, we just need to extend it.
4590 +       //
4591 +
4592 +       if (Adapter->FibContextZone.TotalSegmentSize) {
4593 +
4594 +               OsSpinLockAcquire( Adapter->FibContextZoneSpinLock );
4595 +
4596 +               ExExtendZone( &Adapter->FibContextZone,
4597 +                                         FibContextSegment,
4598 +                                         ZoneSegmentAllocSize );
4599 +
4600 +               OsSpinLockRelease( Adapter->FibContextZoneSpinLock );
4601 +
4602 +       } else {
4603 +
4604 +           if (ExInitializeZone( &Adapter->FibContextZone,
4605 +                                                         sizeof(COMM_FIB_CONTEXT),
4606 +                             FibContextSegment,
4607 +                                 ZoneSegmentAllocSize ) != STATUS_SUCCESS)
4608 +                       FsaBugCheck(0,0,0);
4609 +
4610 +       }
4611 +
4612 +       //
4613 +       // Add this segment to the adapter's list of segments
4614 +       //
4615 +
4616 +       ZoneSegment->Next = Adapter->FibContextSegmentList;
4617 +       Adapter->FibContextSegmentList = ZoneSegment;
4618 +
4619 +       return (TRUE);
4620 +}
4621 +
4622 +
4623 +
4624 +/*++
4625 +
4626 +Routine Description:
4627 +
4628 +    This routine creates a new COMM_FIB_CONTEXT record
4629 +
4630 +Arguments:
4631 +
4632 +       Adapter - The adapter that this COMM_FIB_CONTEXT will communicate with.
4633 +
4634 +Return Value:
4635 +
4636 +    PCOMM_FIB_CONTEXT - returns a pointer to the newly allocate COMM_FIB_CONTEXT Record
4637 +
4638 +--*/
4639 +PFIB_CONTEXT
4640 +AllocateFib (IN PVOID AdapterArg)
4641 +{
4642 +       PAFA_COMM_ADAPTER Adapter = (PAFA_COMM_ADAPTER) AdapterArg;
4643 +    KIRQL SavedIrql;
4644 +    PCOMM_FIB_CONTEXT FibContext;
4645 +       int FullZoneLoopCounter = 0;
4646 +        
4647 +
4648 +        //
4649 +       // Acquire the zone spin lock, and check to see if the zone is full.
4650 +       // If it is, then release the spin lock and allocate more fibs for the 
4651 +       // zone.  The ExtendFibZone routine will re-acquire the spin lock to add
4652 +       // the new fibs onto the zone.
4653 +        //
4654 +
4655 +    OsSpinLockAcquire( Adapter->FibContextZoneSpinLock );
4656 +
4657 +    while (ExIsFullZone( &Adapter->FibContextZone )) {
4658 +
4659 +               if (++FullZoneLoopCounter >  10)
4660 +                       FsaBugCheck(0,0,0);
4661 +
4662 +               OsSpinLockRelease( Adapter->FibContextZoneSpinLock );
4663 +
4664 +                // bmb debug
4665 +                cmn_err (CE_DEBUG, "Extending FibContextZone");
4666 +               if (FsaExtendFibContextZone(Adapter) == FALSE) {
4667 +                       return (NULL);
4668 +               }
4669 +
4670 +                OsSpinLockAcquire( Adapter->FibContextZoneSpinLock );
4671 +
4672 +       }
4673 +
4674 +    //
4675 +       //  At this point we now know that the zone has at least one more
4676 +    //  IRP context record available.  So allocate from the zone and
4677 +    //  then release the mutex.
4678 +    //
4679 +
4680 +    FibContext = (PCOMM_FIB_CONTEXT) ExAllocateFromZone( &Adapter->FibContextZone );
4681 +
4682 +       OsSpinLockRelease( Adapter->FibContextZoneSpinLock );
4683 +
4684 +    //
4685 +    //  Set the proper node type code and node byte size
4686 +    //
4687 +
4688 +    FibContext->NodeTypeCode = FSAFS_NTC_FIB_CONTEXT;
4689 +    FibContext->NodeByteSize = sizeof( COMM_FIB_CONTEXT );
4690 +
4691 +       // 
4692 +       // Null out fields that depend on being zero at the start of each I/O
4693 +       //
4694 +
4695 +       FibContext->Fib->Header.XferState = 0;
4696 +       FibContext->FibCallback = NULL;
4697 +       FibContext->FibCallbackContext = NULL;
4698 +
4699 +
4700 +    //
4701 +    //  return and tell the caller
4702 +    //
4703 +
4704 +    return ((PFIB_CONTEXT) FibContext);
4705 +}
4706 +
4707 +
4708 +/*++
4709 +
4710 +Routine Description:
4711 +
4712 +    This routine deallocates and removes the specified COMM_FIB_CONTEXT record
4713 +    from the Fsafs in memory data structures.  It should only be called
4714 +    by FsaCompleteRequest.
4715 +
4716 +Arguments:
4717 +
4718 +       FibContext - Supplies the COMM_FIB_CONTEXT to remove
4719 +
4720 +Return Value:
4721 +
4722 +    None
4723 +
4724 +--*/
4725 +VOID
4726 +FreeFib (IN PFIB_CONTEXT Context)
4727 +{
4728 +    KIRQL SavedIrql;
4729 +       PCOMM_FIB_CONTEXT FibContext = Context;
4730 +
4731 +    ASSERT(FibContext->NodeTypeCode == FSAFS_NTC_FIB_CONTEXT);
4732 +
4733 +    OsSpinLockAcquire( FibContext->Adapter->FibContextZoneSpinLock );
4734 +
4735 +       if (FibContext->Flags & FIB_CONTEXT_FLAG_TIMED_OUT) {
4736 +
4737 +               FsaCommData.TimedOutFibs++;
4738 +
4739 +               FibContext->Next = FibContext->Adapter->FibContextTimedOutList;
4740 +               FibContext->Adapter->FibContextTimedOutList = FibContext;
4741 +
4742 +       } else {
4743 +
4744 +           ASSERT(FibContext->Fib->Header.XferState == 0);
4745 +
4746 +               if (FibContext->Fib->Header.XferState != 0) {
4747 +                               cmn_err(CE_WARN, "FreeFib, XferState != 0, FibContext = 0x%x, XferState = 0x%x\n", 
4748 +                                        FibContext, FibContext->Fib->Header.XferState);
4749 +               }
4750 +
4751 +           ExFreeToZone( &FibContext->Adapter->FibContextZone, FibContext );
4752 +
4753 +       }       
4754 +
4755 +       OsSpinLockRelease( FibContext->Adapter->FibContextZoneSpinLock );
4756 +
4757 +    //
4758 +    //  return and tell the caller
4759 +    //
4760 +
4761 +    return;
4762 +}
4763 +
4764 +
4765 +/*++
4766 +
4767 +Routine Description:
4768 +
4769 +    This routine deallocates and removes the specified COMM_FIB_CONTEXT record
4770 +    from the Fsafs in memory data structures.  It should only be called
4771 +    from the dpc routines to from dpc to free an FibContext from an async or
4772 +       no response io
4773 +
4774 +Arguments:
4775 +
4776 +    FibContext - Supplies the COMM_FIB_CONTEXT to remove
4777 +
4778 +Return Value:
4779 +
4780 +    None
4781 +
4782 +--*/
4783 +VOID
4784 +FreeFibFromDpc (IN PFIB_CONTEXT Context)
4785 +{
4786 +    PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
4787 +
4788 +    ASSERT(FibContext->NodeTypeCode == FSAFS_NTC_FIB_CONTEXT);
4789 +
4790 +    OsSpinLockAcquire(FibContext->Adapter->FibContextZoneSpinLock);
4791 +
4792 +       if (FibContext->Flags & FIB_CONTEXT_FLAG_TIMED_OUT) {
4793 +
4794 +               FsaCommData.TimedOutFibs++;
4795 +
4796 +               FibContext->Next = FibContext->Adapter->FibContextTimedOutList;
4797 +               FibContext->Adapter->FibContextTimedOutList = FibContext;
4798 +
4799 +       } else {
4800 +
4801 +           ASSERT(FibContext->Fib->Header.XferState == 0);
4802 +
4803 +               if (FibContext->Fib->Header.XferState != 0) {
4804 +                               cmn_err(CE_WARN, "FreeFibFromDpc, XferState != 0, FibContext = 0x%x, XferState = 0x%x\n", 
4805 +                                        FibContext, FibContext->Fib->Header.XferState);
4806 +               }
4807 +
4808 +
4809 +           ExFreeToZone( &FibContext->Adapter->FibContextZone, FibContext );
4810 +
4811 +       }
4812 +               
4813 +       OsSpinLockRelease(FibContext->Adapter->FibContextZoneSpinLock);
4814 +
4815 +    //
4816 +    //  return and tell the caller
4817 +    //
4818 +
4819 +    return;
4820 +}
4821 +
4822 +
4823 +/*++
4824 +
4825 +Routine Description:
4826 +
4827 +    Will initialize a FIB of the requested size.
4828 +    
4829 +Arguments:
4830 +
4831 +    Fib is a pointer to a location which will receive the address of the allocated
4832 +        FIB.
4833 +
4834 +    Size is the size of the Fib to allocate.
4835 +
4836 +Return Value:
4837 +
4838 +    NT_SUCCESS if a Fib was returned to the caller.
4839 +    NT_ERROR if event was an invalid event. 
4840 +
4841 +--*/
4842 +AAC_STATUS
4843 +InitializeFib (IN PFIB_CONTEXT Context)
4844 +{
4845 +    PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
4846 +       PFIB Fib = FibContext->Fib;
4847 +
4848 +    Fib->Header.StructType = TFib;
4849 +    Fib->Header.Size = sizeof(FIB);
4850 +//    if (Fib->Header.XferState & AllocatedFromPool)
4851 +//        Fib->Header.XferState = HostOwned | FibInitialized | FibEmpty | AllocatedFromPool;
4852 +//    else
4853 +        Fib->Header.XferState = HostOwned | FibInitialized | FibEmpty | FastResponseCapable;
4854 +    Fib->Header.SenderFibAddress = 0;
4855 +    Fib->Header.ReceiverFibAddress = 0;
4856 +    Fib->Header.SenderSize = sizeof(FIB);
4857 +
4858 +    return(STATUS_SUCCESS);
4859 +}
4860 +    
4861 +
4862 +/*++
4863 +
4864 +Routine Description:
4865 +
4866 +    Will allocate and initialize a FIB of the requested size and return a
4867 +    pointer to the structure. The size allocated may be larger than the size
4868 +    requested due to allocation performace optimizations.
4869 +    
4870 +Arguments:
4871 +
4872 +    Fib is a pointer to a location which will receive the address of the allocated
4873 +        FIB.
4874 +
4875 +    Size is the size of the Fib to allocate.
4876 +
4877 +    JustInitialize is a boolean which indicates a Fib has been allocated most likly in an
4878 +        imbedded structure the FS always allocates. So just initiaize it and return.
4879 +    
4880 +Return Value:
4881 +
4882 +    NT_SUCCESS if a Fib was returned to the caller.
4883 +    NT_ERROR if event was an invalid event. 
4884 +
4885 +--*/
4886 +AAC_STATUS
4887 +AllocatePoolFib (OUT PFIB *Fib, IN USHORT Size)
4888 +{}
4889 +    
4890 +
4891 +/*++
4892 +
4893 +Routine Description:
4894 +
4895 +    Will deallocate and return to the free pool the FIB pointed to by the
4896 +    caller. Upon return accessing locations pointed to by the FIB parameter
4897 +    could cause system access faults.
4898 +
4899 +Arguments:
4900 +
4901 +    Fib is a pointer to the FIB that caller wishes to deallocate.
4902 +    
4903 +Return Value:
4904 +
4905 +    NT_SUCCESS if a Fib was returned to the caller.
4906 +    NT_ERROR if event was an invalid event. 
4907 +
4908 +--*/
4909 +AAC_STATUS
4910 +DeallocateFib (PFIB_CONTEXT Context)
4911 +{
4912 +    PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
4913 +       PFIB Fib = FibContext->Fib;
4914 +
4915 +    if ( Fib->Header.StructType != TFib ) {
4916 +        FsaCommPrint("Error CompleteFib called with a non Fib structure.\n");
4917 +        return(STATUS_UNSUCCESSFUL);
4918 +    }
4919 +
4920 +
4921 +    Fib->Header.XferState = 0;        
4922 +        
4923 +    return(STATUS_SUCCESS);
4924 +
4925 +}
4926 +
4927 +
4928 +AAC_STATUS
4929 +GetResponse(
4930 +    IN PCOMM_QUE ResponseQueue,
4931 +    OUT PFIB Fib
4932 +    )
4933 +/*++
4934 +
4935 +Routine Description:
4936 +
4937 +    Gets a QE off the requested response queue and gets the response FIB into
4938 +    host memory. The FIB may already be in host memory depending on the bus
4939 +    interface, or may require the host to DMA it over from the adapter. The routine
4940 +    will return the FIB to the caller.
4941 +
4942 +Arguments:
4943 +
4944 +    ResponseQueue - Is the queue the caller wishes to have the response gotten from.
4945 +    Fib - Is the Fib which was the response from the adapter
4946 +
4947 +Return Value:
4948 +
4949 +    NT_SUCCESS if a Fib was returned to the caller.
4950 +    NT_ERROR if there was no Fib to return to the caller.
4951 +    bkpfix - add in all the other possible errors ect
4952 +
4953 +--*/
4954 +{
4955 +return(STATUS_UNSUCCESSFUL);
4956 +}
4957 +
4958 +//
4959 +// Commuication primitives define and support the queuing method we use to
4960 +// support host to adapter commuication. All queue accesses happen through
4961 +// these routines and are the only routines which have a knowledge of the
4962 +// how these queues are implemented.
4963 +//
4964 +
4965 +
4966 +/*++
4967 +
4968 +Routine Description:
4969 +
4970 +    With a priority the routine returns a queue entry if the queue has free entries. If the queue
4971 +    is full(no free entries) than no entry is returned and the function returns FALSE otherwise TRUE is
4972 +    returned.
4973 +
4974 +Arguments:
4975 +
4976 +    Priority is an enumerated type which determines which priority level
4977 +        command queue the QE is going to be queued on.
4978 +
4979 +    Entry is a pointer to the address of where to return the address of
4980 +        the queue entry from the requested command queue.
4981 +
4982 +    Index is a pointer to the address of where to store the index of the new
4983 +        queue entry returned.
4984 +
4985 +       DontInterrupt - We set this true if the queue state is such that we don't
4986 +               need to interrupt the adapter for this queue entry.
4987 +
4988 +Return Value:
4989 +
4990 +    TRUE - If a queue entry is returned
4991 +    FALSE - If there are no free queue entries on the requested command queue.
4992 +
4993 +--*/
4994 +BOOLEAN
4995 +GetEntry (IN PAFA_COMM_ADAPTER Adapter, IN QUEUE_TYPES WhichQueue,
4996 +                 OUT PQUEUE_ENTRY *Entry, OUT PQUEUE_INDEX Index,
4997 +                 OUT ULONG *DontInterrupt)
4998 +{
4999 +    ULONG QueueOffset;
5000 +       BOOLEAN status;
5001 +       PCOMM_REGION CommRegion;
5002 +
5003 +       CommRegion = Adapter->CommRegion;
5004 +
5005 +    //
5006 +    // All of the queues wrap when they reach the end, so we check to see if they
5007 +    // have reached the end and if they have we just set the index back to zero.
5008 +    // This is a wrap. You could or off the high bits in all updates but this is
5009 +    // a bit faster I think.
5010 +    //
5011 +
5012 +    if (WhichQueue == AdapHighCmdQueue) {
5013 +        *Index = *(CommRegion->AdapHighCmdQue.Headers.ProducerIndex);
5014 +
5015 +               if (*Index - 2 == *(CommRegion->AdapHighCmdQue.Headers.ConsumerIndex))
5016 +                       *DontInterrupt = TRUE; 
5017 +
5018 +        if (*Index >= ADAP_HIGH_CMD_ENTRIES)
5019 +            *Index = 0;
5020 +
5021 +        if (*Index + 1 == *(CommRegion->AdapHighCmdQue.Headers.ConsumerIndex)) { // Queue is full
5022 +                       status = FALSE;
5023 +                       cmn_err(CE_WARN, "Adapter High Command Queue full, %d outstanding",
5024 +                                       CommRegion->AdapHighCmdQue.NumOutstandingIos);
5025 +               } else {
5026 +               QueueOffset = sizeof(QUEUE_ENTRY) * (*Index);
5027 +               *Entry = QueueOffset + CommRegion->AdapHighCmdQue.BaseAddress;
5028 +
5029 +                       status = TRUE;
5030 +               }
5031 +    } else if (WhichQueue == AdapNormCmdQueue) {
5032 +
5033 +        *Index = *(CommRegion->AdapNormCmdQue.Headers.ProducerIndex);
5034 +
5035 +               if (*Index - 2 == *(CommRegion->AdapNormCmdQue.Headers.ConsumerIndex))
5036 +                       *DontInterrupt = TRUE; 
5037 +
5038 +               //
5039 +               // If we are at the end of the QUEUE then wrap back to 
5040 +               // the beginning.
5041 +        //
5042 +
5043 +        if (*Index >= ADAP_NORM_CMD_ENTRIES) 
5044 +            *Index = 0; // Wrap to front of the Producer Queue.
5045 +
5046 +               //
5047 +        // The IEEE spec says that it the producer is one behind the consumer then
5048 +        // the queue is full.
5049 +        //       
5050 +
5051 +               ASSERT(*(CommRegion->AdapNormCmdQue.Headers.ConsumerIndex) != 0);
5052 +
5053 +        if (*Index + 1 == *(CommRegion->AdapNormCmdQue.Headers.ConsumerIndex)) { // Queue is full
5054 +                       cmn_err(CE_WARN, "Adapter Norm Command Queue full, %d outstanding",
5055 +                                       CommRegion->AdapNormCmdQue.NumOutstandingIos);
5056 +                       status = FALSE;
5057 +               } else {        
5058 +               //
5059 +                       // The success case just falls through and returns the a valid queue entry.
5060 +                       //
5061 +
5062 +#ifdef commdebug
5063 +               FsaCommPrint("queue entry = %x.\n",CommRegion->AdapNormCmdQue.BaseAddress + *Index);
5064 +               FsaCommPrint("GetEntry: Index = %d, QueueOffset = %x, Entry = %x, *Entry = %x.\n",
5065 +                            *Index, QueueOffset, Entry, *Entry);
5066 +#endif
5067 +               *Entry = CommRegion->AdapNormCmdQue.BaseAddress + *Index;
5068 +
5069 +                       status = TRUE;
5070 +               }
5071 +    } else if (WhichQueue == AdapHighRespQueue) {
5072 +
5073 +        *Index = *(CommRegion->AdapHighRespQue.Headers.ProducerIndex);
5074 +
5075 +               if (*Index - 2 == *(CommRegion->AdapHighRespQue.Headers.ConsumerIndex))
5076 +                       *DontInterrupt = TRUE; 
5077 +
5078 +        if (*Index >= ADAP_HIGH_RESP_ENTRIES)
5079 +            *Index = 0;
5080 +
5081 +        if (*Index + 1 == *(CommRegion->AdapHighRespQue.Headers.ConsumerIndex)) { // Queue is full
5082 +                       status = FALSE;
5083 +                       cmn_err(CE_WARN, "Adapter High Resp Queue full, %d outstanding",
5084 +                                       CommRegion->AdapHighRespQue.NumOutstandingIos);
5085 +               } else {                                                        
5086 +               *Entry = CommRegion->AdapHighRespQue.BaseAddress + *Index;
5087 +               status = TRUE;
5088 +               } 
5089 +    } else if (WhichQueue == AdapNormRespQueue) {
5090 +
5091 +        *Index = *(CommRegion->AdapNormRespQue.Headers.ProducerIndex);
5092 +
5093 +               if (*Index - 2 == *(CommRegion->AdapNormRespQue.Headers.ConsumerIndex))
5094 +                       *DontInterrupt = TRUE; 
5095 +
5096 +               //
5097 +               // If we are at the end of the QUEUE then wrap back to 
5098 +               // the beginning.
5099 +        //
5100 +
5101 +        if (*Index >= ADAP_NORM_RESP_ENTRIES) 
5102 +            *Index = 0; // Wrap to front of the Producer Queue.
5103 +
5104 +               //
5105 +        // The IEEE spec says that it the producer is one behind the consumer then
5106 +        // the queue is full.
5107 +        //       
5108 +
5109 +        if (*Index + 1 == *(CommRegion->AdapNormRespQue.Headers.ConsumerIndex)) { // Queue is full
5110 +                       status = FALSE; 
5111 +                       cmn_err(CE_WARN, "Adapter Norm Resp Queue full, %d outstanding",
5112 +                                       CommRegion->AdapNormRespQue.NumOutstandingIos);
5113 +               } else {        
5114 +               //
5115 +                       // The success case just falls through and returns the a valid queue entry.
5116 +                       //
5117 +
5118 +               *Entry = CommRegion->AdapNormRespQue.BaseAddress + *Index;
5119 +
5120 +#ifdef commdebug
5121 +               FsaCommPrint("queue entry = %x.\n",CommRegion->AdapNormRespQue.BaseAddress + *Index);
5122 +               FsaCommPrint("GetEntry: Index = %d, Entry = %x, *Entry = %x.\n",*Index, Entry, *Entry);
5123 +#endif
5124 +                       status = TRUE;
5125 +               }     
5126 +    } else {
5127 +               cmn_err(CE_PANIC, "GetEntry: invalid queue %d", WhichQueue);
5128 +       }
5129 +
5130 +
5131 +       return (status);
5132 +}
5133 +   
5134 +
5135 +
5136 +#ifdef API_THROTTLE
5137 +
5138 +void ThrottleCheck(
5139 +       IN PAFA_COMM_ADAPTER Adapter,
5140 +       IN PFIB Fib
5141 +       )
5142 +/*++
5143 +
5144 +Routine Description:
5145 +
5146 +    This routine implements data I/O throttling. Throttling occurs when
5147 +       a CLI FIB is detected. To ensure the CLI responds quickly (the user
5148 +       is waiting for the response), this mechanism restricts the queue
5149 +       depth of data IOs at the adapter for a period of time (called the
5150 +       Throttle Period, default 5 seconds).
5151 +
5152 +    The mechanism uses a counted semaphore to place threads into a wait
5153 +       state should there be too many data I/Os outstanding.
5154 +
5155 +       At the start of a throttle period (indicated by the first CLI FIB)
5156 +       a timer is started. When the timer expires, new requests can go to
5157 +       the adapter freely. Throttled requests gradually drain to the
5158 +       adapter as each outstanding throttle I/O completes.
5159 +
5160 +    To avoid hurting regular I/O performance, we use a flag in the FIB
5161 +       header to mark FIBs involved in throttling. This means we only need
5162 +       take the extra spinlock in the response DPC routine for FIBs who
5163 +       were subject to throttling. If no throttling is occurring, the cost
5164 +       to the regular code paths is a handful of instructions.
5165 +
5166 +Arguments:
5167 +
5168 +       Adapter - Pointer to per-adapter context. This is used to locate the
5169 +                         throttle information for this adapter.
5170 +       
5171 +       Fib             - Pointer to the header for the fib being sent.
5172 +
5173 +Return Value:
5174 +
5175 +       None.
5176 +
5177 +--*/
5178 +{
5179 +       PCOMM_REGION CommRegion = Adapter->CommRegion;
5180 +       AAC_STATUS       Status;
5181 +
5182 +       //
5183 +       // This routine is called under protection of the queue spinlock.
5184 +       // As such we are allowed to check and change the counts for the
5185 +       // throttle.
5186 +       // Check the FIB. If its not a data operation, send it on without
5187 +       // throttle check. If it is a data operation, check for throttle.
5188 +       //
5189 +
5190 +       CommRegion->TotalFibs++;                                                        // Keep statistics
5191 +
5192 +       if ((Fib->Header.XferState & ApiFib) != 0) {
5193 +
5194 +               CommRegion->ApiFibs++;                                                  // Keep statistics
5195 +
5196 +               //
5197 +               // Its an API fib. If the throttle is not already active,
5198 +               // make it so. This will prevent new data Fibs being sent
5199 +               // if they exceed the throttle check.
5200 +               //
5201 +
5202 +               if (!CommRegion->ThrottleActive) {
5203 +                       BOOLEAN          InQue;
5204 +
5205 +                       CommRegion->ThrottleActive = TRUE;                      // This causes new data I/Os to be throttled
5206 +
5207 +                       //
5208 +                       // Schedule a timer for the throttle active period. When
5209 +                       // it expires, we'll be called back at routine ThrottleDpcRoutine
5210 +                       // above. This will signify the throttle active period ended
5211 +                       // and any waiting threads will be signalled to restart.
5212 +                       //
5213 +
5214 +                       FsaCommPrint("Throttle Period Start - CommRegion: %x\n", CommRegion);
5215 +                       CommRegion->ThrottleTimerSets++;
5216 +                       InQue = KeSetTimer( &CommRegion->ThrottleTimer,
5217 +                                                               CommRegion->ThrottleTimeout,
5218 +                                                               &CommRegion->ThrottleDpc);
5219 +                       ASSERT(InQue == FALSE);
5220 +               }
5221 +
5222 +               return;
5223 +       }
5224 +
5225 +       //
5226 +       // Its a non-API fib, so subject to throttle checks.
5227 +       // The following are exempt from throttling:
5228 +       //              o FIBs marked as "throttle exempt" by upper layers.
5229 +       //              o I/Os issued from a raised IRQL. We can't suspend
5230 +       //                a thread when at raised IRQL so throttling is exempt.
5231 +       //
5232 +
5233 +       if (CommRegion->AdapNormCmdQue.SavedIrql != PASSIVE_LEVEL) {
5234 +
5235 +               CommRegion->NonPassiveFibs++;
5236 +               FsaCommPrint("ThrottleCheck: Non-Passive level FIB bypasses throttle: %x\n", Fib);
5237 +               return;
5238 +
5239 +       }
5240 +
5241 +       if (CommRegion->ThrottleActive) {
5242 +
5243 +               //
5244 +               // Throttle is active.
5245 +               // Check if the FIB is a read or write. If so, and its to the
5246 +               // file system information area, let it through without throttling.
5247 +               //
5248 +
5249 +               if (Fib->Header.Command == ContainerCommand) {
5250 +                       PBLOCKREAD BlockDisk = (PBLOCKREAD) &Fib->data;
5251 +
5252 +                       //
5253 +                       // *** Note *** We are using read and write command formats
5254 +                       // interchangably here. This is ok for this purpose as the
5255 +                       // command is in the same place for both. Read and write command
5256 +                       // formats are different at higher offsets though.
5257 +                       //
5258 +
5259 +                       if ( ((BlockDisk->Command == VM_CtBlockRead) ||
5260 +                                 (BlockDisk->Command == VM_CtBlockWrite)) &&
5261 +                                 (BlockDisk->BlockNumber <= FILESYSTEM_INFO_MAX_BLKNO)) {
5262 +
5263 +                               CommRegion->FSInfoFibs++;                                                       // Keep statistics
5264 +                               return;
5265 +
5266 +                       }
5267 +
5268 +               }
5269 +
5270 +               //
5271 +               // Throttle the FIB.
5272 +               // Mark it as throttle active so that it can signal a waiter
5273 +               // when it completes.
5274 +
5275 +               CommRegion->ThrottledFibs++;
5276 +               Fib->Header.Flags |= ThrottledFib;
5277 +               
5278 +               //
5279 +               // Release the spinlock so we can wait the thread if necessary.
5280 +               // Since we specify a timeout, check the caller is at passive level.
5281 +               //
5282 +
5283 +               OsSpinLockRelease((CommRegion->AdapNormCmdQue.QueueLock), CommRegion->AdapNormCmdQue.SavedIrql);
5284 +
5285 +               FsaCommPrint("ThrottleCheck - Thread Suspension - FIB: %x\n", Fib);
5286 +
5287 +               Status = KeWaitForSingleObject(&CommRegion->ThrottleReleaseSema,
5288 +                                                                               Executive,                                                      // Don't allow user APCs to wake us
5289 +                                                                               KernelMode,                                                     // Wait in kernel mode
5290 +                                                                               FALSE,                                                          // Not alertable
5291 +                                                                               &CommRegion->ThrottleWaitTimeout);      // Timeout after this time
5292 +
5293 +               //
5294 +               // Check the signal status. If we've timed out, clear the throttle
5295 +               // flag on the FIB to avoid us signalling the semaphore on completion.
5296 +               // We never acquired the semaphore.
5297 +               //
5298 +               if (Status == STATUS_TIMEOUT) {
5299 +
5300 +                       CommRegion->ThrottleTimedoutFibs++;
5301 +                       FsaCommPrint("ThrottledFib Timed Out - FIB: %x\n", Fib);
5302 +                       Fib->Header.Flags &= ~ThrottledFib;                                             // Clear the throttledfib flag
5303 +
5304 +               } else {
5305 +
5306 +                       ASSERT(Status == STATUS_SUCCESS);                                               // No other return is possible
5307 +
5308 +               }
5309 +
5310 +               //
5311 +               // We've been woken up and can now send the FIB to the adapter.
5312 +               // Acquire the spinlock again so we can get a queue entry. This
5313 +               // returns to GetQueueEntry.
5314 +               //
5315 +
5316 +               FsaCommPrint("ThrottleCheck - Thread Resume - FIB: %x\n", Fib);
5317 +               KeAcquireSpinLock((CommRegion->AdapNormCmdQue.QueueLock), &(CommRegion->AdapNormCmdQue.SavedIrql));
5318 +               CommRegion->ThrottleOutstandingFibs++;          // There's another throttle controlled FIB going.
5319 +               return;
5320 +
5321 +       }
5322 +}
5323 +
5324 +#endif //#ifdef API_THROTTLE
5325 +
5326 +int GetQueueEntryTimeouts = 0;
5327 +
5328 +
5329 +/*++
5330 +
5331 +Routine Description:
5332 +
5333 +    Gets the next free QE off the requested priorty adapter command queue and
5334 +    associates the Fib with the QE. The QE represented by index is ready to
5335 +     insert on the queue when this routine returns success.
5336 +
5337 +Arguments:
5338 +
5339 +    Index is the returned value which represents the QE which is ready to
5340 +        insert on the adapter's command queue.
5341 +
5342 +    Priority is an enumerated type which determines which priority level
5343 +        command queue the QE is going to be queued on.
5344 +
5345 +    Fib is a pointer to the FIB the caller wishes to have associated with the
5346 +        QE.
5347 +
5348 +    Wait is a boolean which determines if the routine will wait if there are
5349 +        no free QEs on the requested priority command queue.
5350 +
5351 +    FibContext is where the driver stores all system resources required to execute the
5352 +        command requested from the calling thread. This includes mapping resources for
5353 +        the FIB and the 'users' buffer.
5354 +
5355 +       DontInterrupt - We set this true if the queue state is such that we don't
5356 +               need to interrupt the adapter for this queue entry.
5357 +
5358 +Return Value:
5359 +
5360 +    NT_SUCCESS if a Fib was returned to the caller.
5361 +    NT_ERROR if event was an invalid event. 
5362 +
5363 +--*/
5364 +AAC_STATUS
5365 +GetQueueEntry (IN PAFA_COMM_ADAPTER Adapter, OUT PQUEUE_INDEX Index,
5366 +                          IN QUEUE_TYPES WhichQueue, IN PFIB Fib, IN BOOLEAN Wait,
5367 +                          IN PCOMM_FIB_CONTEXT FibContext, OUT ULONG *DontInterrupt)
5368 +{
5369 +    PQUEUE_ENTRY QueueEntry = NULL;
5370 +    BOOLEAN MapAddress = FALSE;
5371 +       int timeouts = 0;
5372 +       AAC_STATUS Status;
5373 +       PCOMM_REGION CommRegion;
5374 +
5375 +       CommRegion = Adapter->CommRegion;
5376 +
5377 +    //
5378 +    // Get the spinlock for the queue we are putting a command on
5379 +    //
5380 +
5381 +    if (WhichQueue == AdapHighCmdQueue) 
5382 +        OsSpinLockAcquire(CommRegion->AdapHighCmdQue.QueueLock);
5383 +    else if (WhichQueue == AdapNormCmdQueue)
5384 +        OsSpinLockAcquire(CommRegion->AdapNormCmdQue.QueueLock);
5385 +    else if (WhichQueue == AdapHighRespQueue)
5386 +        OsSpinLockAcquire(CommRegion->AdapHighRespQue.QueueLock);
5387 +    else if (WhichQueue == AdapNormRespQueue)
5388 +        OsSpinLockAcquire(CommRegion->AdapNormRespQue.QueueLock);
5389 +    else {
5390 +        FsaCommPrint("Invalid queue priority passed to GetQueueEntry.\n");
5391 +        return(FSA_INVALID_QUEUE);
5392 +    }
5393 +    
5394 +    //
5395 +    // Get the pointers to a queue entry on the queue the caller wishes to queue
5396 +    // a command request on. If there are no entries then wait if that is what the
5397 +    // caller requested. 
5398 +    //
5399 +
5400 +    if (WhichQueue == AdapHighCmdQueue) {
5401 +         // if no entries wait for some if caller wants to
5402 +        while ( !GetEntry(Adapter, AdapHighCmdQueue, &QueueEntry, Index, DontInterrupt) ) { 
5403 +                       cmn_err(CE_PANIC, "GetEntries failed (1)\n");
5404 +               }
5405 +
5406 +        //
5407 +        // Setup queue entry with a command, status and Fib mapped
5408 +        //
5409 +
5410 +        QueueEntry->Size = Fib->Header.Size;
5411 +        MapAddress = TRUE;
5412 +       
5413 +    } else if (WhichQueue == AdapNormCmdQueue) {
5414 +         // if no entries wait for some if caller wants to
5415 +        while ( !GetEntry(Adapter, AdapNormCmdQueue, &QueueEntry, Index, DontInterrupt) ) { 
5416 +                       cmn_err(CE_PANIC, "GetEntries failed (2)\n");
5417 +               }
5418
5419 +        //
5420 +        // Setup queue entry with command, status and Fib mapped
5421 +        //
5422 +
5423 +        QueueEntry->Size = Fib->Header.Size;
5424 +        MapAddress = TRUE;
5425 +        
5426 +     } else if (WhichQueue == AdapHighRespQueue) {
5427 +
5428 +        while ( !GetEntry(Adapter, AdapHighRespQueue, &QueueEntry, Index, DontInterrupt) ) { // if no entries wait for some if caller wants to
5429 +               }
5430 +
5431 +        //
5432 +        // Setup queue entry with command, status and Fib mapped
5433 +        //
5434 +
5435 +        QueueEntry->Size = Fib->Header.Size;
5436 +        QueueEntry->FibAddress = Fib->Header.SenderFibAddress;                         // Restore adapters pointer to the FIB
5437 +               Fib->Header.ReceiverFibAddress = Fib->Header.SenderFibAddress;          // Let the adapter now where to find its data
5438 +        MapAddress = FALSE;
5439 +        
5440 +     } else if (WhichQueue == AdapNormRespQueue) {
5441 +        while ( !GetEntry(Adapter, AdapNormRespQueue, &QueueEntry, Index, DontInterrupt) ) { // if no entries wait for some if caller wants to
5442 +               }
5443 +
5444 +               //
5445 +               // Setup queue entry with command, status, adapter's pointer to the Fib it sent
5446 +               //
5447 +       
5448 +        QueueEntry->Size = Fib->Header.Size;
5449 +        QueueEntry->FibAddress = Fib->Header.SenderFibAddress;                         // Restore adapters pointer to the FIB
5450 +               Fib->Header.ReceiverFibAddress = Fib->Header.SenderFibAddress;          // Let the adapter now where to find its data
5451 +        MapAddress = FALSE;
5452 +     }
5453 +                
5454 +    //
5455 +    // If MapFib is true than we need to map the Fib and put pointers in the queue entry.
5456 +    //
5457 +
5458 +    if (MapAddress) {
5459 +               QueueEntry->FibAddress = (ULONG)(FibContext->LogicalFibAddress.LowPart);
5460 +    }
5461 +    
5462 +    //
5463 +    // Return
5464 +    //
5465 +#ifdef commdebug    
5466 +    FsaCommPrint("Queue Entry contents:.\n");
5467 +    FsaCommPrint("  Command =               %d.\n", QueueEntry->Command);
5468 +    FsaCommPrint("  Status  =               %x.\n", QueueEntry->Status);
5469 +    FsaCommPrint("  Rec Fib address low =   %x.\n", QueueEntry->FibAddressLow);        
5470 +    FsaCommPrint("  Fib size in bytes =     %d.\n", QueueEntry->Size);
5471 +#endif
5472 +
5473 +    return(FSA_SUCCESS);
5474 +}
5475 +
5476 +
5477 +/*++
5478 +
5479 +Routine Description:
5480 +
5481 +    Gets the next free QE off the requested priorty adapter command queue and
5482 +      associates the Fib with the QE. The QE represented by index is ready to
5483 +    insert on the queue when this routine returns success.
5484 +
5485 +Arguments:
5486 +
5487 +    Index is the returned value which represents the QE which is ready to
5488 +        insert on the adapter's command queue.
5489 +
5490 +    WhichQueue tells us which queue the caller wishes to have the entry put.
5491 +        
5492 +Return Value:
5493 +
5494 +    NT_SUCCESS if a Fib was returned to the caller.
5495 +    NT_ERROR if event was an invalid event. 
5496 +
5497 +--*/
5498 +AAC_STATUS
5499 +InsertQueueEntry(
5500 +                 IN PAFA_COMM_ADAPTER Adapter,
5501 +                 IN QUEUE_INDEX Index,
5502 +                 IN QUEUE_TYPES WhichQueue,
5503 +                 IN ULONG DontInterrupt
5504 +                 )
5505 +{
5506 +       PCOMM_REGION CommRegion;
5507 +    
5508 +       CommRegion = Adapter->CommRegion;
5509 +
5510 +    //
5511 +    // We have already verified the queue in getentry, but we still have to make
5512 +    // sure we don't wrap here too.
5513 +    //
5514 +
5515 +    if (WhichQueue == AdapHighCmdQueue) {
5516 +
5517 +        *(CommRegion->AdapHighCmdQue.Headers.ProducerIndex) = Index + 1;
5518 +            
5519 +        OsSpinLockRelease(CommRegion->AdapHighCmdQue.QueueLock);
5520 +
5521 +               if (!DontInterrupt)
5522 +               NotifyAdapter(Adapter, AdapHighCmdQue);
5523 +        
5524 +    } else if (WhichQueue == AdapNormCmdQueue) {
5525 +
5526 +#ifdef commdebug
5527 +        FsaCommPrint("InsertQueueEntry: Inerting with an index of %d.\n",Index);
5528 +#endif
5529 +        *(CommRegion->AdapNormCmdQue.Headers.ProducerIndex) = Index + 1;
5530 +       
5531 +        OsSpinLockRelease(CommRegion->AdapNormCmdQue.QueueLock);
5532 +
5533 +               if (!DontInterrupt)
5534 +               NotifyAdapter(Adapter, AdapNormCmdQue);
5535 +
5536 +    } else if (WhichQueue == AdapHighRespQueue) {
5537 +
5538 +        *(CommRegion->AdapHighRespQue.Headers.ProducerIndex) = Index + 1;
5539 +
5540 +        OsSpinLockRelease(CommRegion->AdapHighRespQue.QueueLock);
5541 +
5542 +               if (!DontInterrupt)
5543 +               NotifyAdapter(Adapter, AdapHighRespQue);
5544 +
5545 +    } else if (WhichQueue == AdapNormRespQueue) {
5546 +
5547 +           *(CommRegion->AdapNormRespQue.Headers.ProducerIndex) = Index + 1;
5548 +           
5549 +           OsSpinLockRelease(CommRegion->AdapNormRespQue.QueueLock);
5550 +
5551 +           if (!DontInterrupt)
5552 +                   NotifyAdapter(Adapter, AdapNormRespQue);
5553 +
5554 +    } else {        
5555 +        FsaCommPrint("Invalid queue priority passed to InsertQueueEntry.\n");
5556 +        return(FSA_INVALID_QUEUE_PRIORITY);
5557 +    }
5558 +
5559 +    return(FSA_SUCCESS);                
5560 +}
5561 +
5562 +extern int GatherFibTimes;
5563 +
5564 +BOOLEAN
5565 +SendSynchFib(
5566 +       PVOID                   Arg,
5567 +       FIB_COMMAND     Command,
5568 +       PVOID                   Data,
5569 +       USHORT                  Size,
5570 +       PVOID                   Response,
5571 +       USHORT                  *ResponseSize
5572 +       )
5573 +/*++
5574 +
5575 +Routine Description:
5576 +
5577 +       This routine will send a synchronous FIB to the adapter and wait for its
5578 +       completion.
5579 +
5580 +Arguments:
5581 +
5582 +       DeviceExtension - Pointer to adapter extension structure.
5583 +
5584 +
5585 +Return Value:
5586 +
5587 +       BOOLEAN
5588 +
5589 +--*/
5590 +{
5591 +       PAFA_COMM_ADAPTER Adapter = Arg;
5592 +       FIB *Fib;
5593 +       ULONG returnStatus;
5594 +
5595 +       Fib = Adapter->SyncFib;
5596 +
5597 +    Fib->Header.StructType = TFib;
5598 +    Fib->Header.Size = sizeof(FIB);
5599 +    Fib->Header.XferState = HostOwned | FibInitialized | FibEmpty;
5600 +    Fib->Header.ReceiverFibAddress = 0;
5601 +    Fib->Header.SenderSize = sizeof(FIB);
5602 +    Fib->Header.SenderFibAddress = (ULONG)Fib;
5603 +    Fib->Header.Command = Command;
5604 +
5605 +       //
5606 +       // Copy the Data portion into the Fib.
5607 +       //
5608 +
5609 +       RtlCopyMemory( Fib->data, Data, Size );
5610 +
5611 +
5612 +    Fib->Header.XferState |= (SentFromHost | NormalPriority);
5613 +    
5614 +       //
5615 +    // Set the size of the Fib we want to send to the adapter
5616 +       //
5617 +
5618 +    Fib->Header.Size = sizeof(FIB_HEADER) + Size;
5619 +
5620 +       if (!Adapter->AdapterFuncs->SendSynchFib( Adapter->AdapterExtension,
5621 +                                                                                         Adapter->SyncFibPhysicalAddress )) {
5622 +
5623 +                       return (FALSE);
5624 +
5625 +       }
5626 +
5627 +       //
5628 +       // Copy the response back to the caller's buffer.
5629 +       //
5630 +
5631 +       RtlCopyMemory( Response, Fib->data, Fib->Header.Size - sizeof(FIB_HEADER) );
5632 +
5633 +       *ResponseSize = Fib->Header.Size - sizeof(FIB_HEADER);
5634 +
5635 +       //
5636 +       // Indicate success
5637 +       //
5638 +
5639 +       return (TRUE);
5640 +}
5641 +
5642 +//
5643 +// Define the highest level of host to adapter communication routines. These
5644 +// routines will support host to adapter FS commuication. These routines have
5645 +// no knowledge of the commuication method used. This level sends and receives
5646 +// FIBs. This level has no knowledge of how these FIBs get passed back and forth.
5647 +//
5648 +
5649 +
5650 +
5651 +/*++
5652 +
5653 +Routine Description:
5654 +
5655 +    Sends the requested FIB to the adapter and optionally will wait for a
5656 +     response FIB. If the caller does not wish to wait for a response than
5657 +    an event to wait on must be supplied. This event will be set when a
5658 +    response FIB is received from the adapter.
5659 +
5660 +Arguments:
5661 +
5662 +    Fib is a pointer to the FIB the caller wishes to send to the adapter.
5663 +    
5664 +    Size - Size of the data portion of the Fib.
5665 +    
5666 +    Priority is an enumerated type which determines which priority level
5667 +        the caller wishes to send this command at. 
5668 +
5669 +    Wait is a boolean which determines if the routine will wait for the
5670 +        completion Fib to be returned(TRUE), or return when the Fib has been
5671 +        successfully received by the adapter(FALSE).
5672 +
5673 +    WaitOn is only vaild when Wait is FALSE. The Event will be set when the response
5674 +        FIB has been returned by the adapter.
5675 +
5676 +    ReturnFib is an optional pointer to a FIB that if present the response FIB will
5677 +        copied to.     
5678 +        
5679 +Return Value:
5680 +
5681 +    NT_SUCCESS if a Fib was returned to the caller.
5682 +    NT_ERROR if event was an invalid event. 
5683 +
5684 +       --*/
5685 +AAC_STATUS
5686 +SendFib (IN FIB_COMMAND Command,
5687 +         IN PFIB_CONTEXT Context,
5688 +         IN ULONG Size, 
5689 +         IN COMM_PRIORITIES Priority,
5690 +         IN BOOLEAN Wait,
5691 +         IN PVOID WaitOn,
5692 +         IN BOOLEAN ResponseExpected,
5693 +         IN PFIB_CALLBACK FibCallback,
5694 +         IN PVOID FibCallbackContext)
5695 +{
5696 +               PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
5697 +               QUEUE_INDEX Index;
5698 +               QUEUE_TYPES WhichQueue;
5699 +               LARGE_INTEGER Timeout;
5700 +               AAC_STATUS Status;
5701 +               PAFA_COMM_ADAPTER Adapter = FibContext->Adapter;
5702 +               ULONG DontInterrupt = FALSE;
5703 +               PFIB Fib = FibContext->Fib;
5704 +               IN PCOMM_QUE OurQueue;
5705 +
5706 +               Timeout = FsaCommData.AdapterTimeout;
5707 +
5708 +               if (!(Fib->Header.XferState & HostOwned)) {
5709 +                               FsaCommPrint("SendFib was called with a xfer state not set to HostOwned!\n");
5710 +                               FsaCommLogEvent(FibContext,
5711 +                                                               FsaCommData.DeviceObject, 
5712 +                                                               FSAFS_FIB_INVALID, 
5713 +                                                               STATUS_UNSUCCESSFUL, 
5714 +                                                               BugCheckFileId | __LINE__,
5715 +                                                               FACILITY_FSAFS_ERROR_CODE,
5716 +                                                               NULL,
5717 +                                                               TRUE);                  
5718 +
5719 +                               return(STATUS_UNSUCCESSFUL);
5720 +
5721 +               }
5722 +    
5723 +               //
5724 +               // There are 5 cases with the wait and reponse requested flags. The only invalid cases
5725 +               // are if the caller requests to wait and  does not request a response and if the
5726 +               // caller does not want a response and the Fib is not allocated from pool. If a response
5727 +               // is not requesed the Fib will just be deallocaed by the DPC routine when the response
5728 +               // comes back from the adapter. No further processing will be done besides deleting the
5729 +               // Fib. We will have a debug mode where the adapter can notify the host it had a problem
5730 +               // and the host can log that fact.
5731 +
5732 +               if (Wait && !ResponseExpected) {
5733 +
5734 +                               FsaCommLogEvent(FibContext,
5735 +                                                FsaCommData.DeviceObject, 
5736 +                                                FSAFS_FIB_INVALID, 
5737 +                                                STATUS_UNSUCCESSFUL, 
5738 +                                                BugCheckFileId | __LINE__,
5739 +                                                FACILITY_FSAFS_ERROR_CODE,
5740 +                                                NULL,
5741 +                                                TRUE);                 
5742 +
5743 +                               return(STATUS_UNSUCCESSFUL);
5744 +
5745 +               } else if (!Wait && ResponseExpected) {
5746 +                               Fib->Header.XferState |= (Async | ResponseExpected);
5747 +                               FIB_COUNTER_INCREMENT(FsaCommData.AsyncSent);
5748 +               } else if (!Wait && !ResponseExpected) {
5749 +                               Fib->Header.XferState |= NoResponseExpected;
5750 +                               FIB_COUNTER_INCREMENT(FsaCommData.NoResponseSent);
5751 +               } else if (Wait && ResponseExpected) {
5752 +                  Fib->Header.XferState |= ResponseExpected;
5753 +                  FIB_COUNTER_INCREMENT(FsaCommData.NormalSent);
5754 +               } 
5755 +
5756 +               Fib->Header.SenderData = (ULONG)FibContext; // so we can complete the io in the dpc routine
5757 +
5758 +               //
5759 +               // Set FIB state to indicate where it came from and if we want a response from the
5760 +               // adapter. Also load the command from the caller.
5761 +               //
5762 +
5763 +               Fib->Header.SenderFibAddress = (ULONG)Fib;
5764 +               Fib->Header.Command = Command;
5765 +               Fib->Header.XferState |= SentFromHost;
5766 +               FibContext->Fib->Header.Flags = 0;                              // Zero the flags field - its internal only...
5767 +    
5768 +               //
5769 +               // Set the size of the Fib we want to send to the adapter
5770 +               //
5771 +
5772 +               Fib->Header.Size = sizeof(FIB_HEADER) + Size;
5773 +               if (Fib->Header.Size > Fib->Header.SenderSize) {
5774 +                               return(STATUS_BUFFER_OVERFLOW);
5775 +               }                
5776 +
5777 +               //
5778 +               // Get a queue entry connect the FIB to it and send an notify the adapter a command is ready.
5779 +               //
5780 +            
5781 +               if (Priority == FsaHigh) {
5782 +                               Fib->Header.XferState |= HighPriority;
5783 +                               WhichQueue = AdapHighCmdQueue;
5784 +                               OurQueue = &Adapter->CommRegion->AdapHighCmdQue;
5785 +               } else {
5786 +                               Fib->Header.XferState |= NormalPriority;
5787 +                               WhichQueue = AdapNormCmdQueue;
5788 +                               OurQueue = &Adapter->CommRegion->AdapNormCmdQue;
5789 +               }
5790 +
5791 +               if (Wait) {
5792 +                               OsCvLockAcquire( FibContext->FsaEventMutex );
5793 +               }
5794 +
5795 +               if ( GetQueueEntry( Adapter, &Index, WhichQueue, Fib, TRUE, FibContext, &DontInterrupt) != FSA_SUCCESS )
5796 +                               return(STATUS_UNSUCCESSFUL);
5797 +
5798 +               // bmb debug
5799 +
5800 +               cmn_err (CE_DEBUG,"SendFib: inserting a queue entry at index %d.\n",Index);
5801 +               cmn_err (CE_DEBUG,"Fib contents:.\n");
5802 +               cmn_err (CE_DEBUG,"  Command =               %d.\n", Fib->Header.Command);
5803 +               cmn_err (CE_DEBUG,"  XferState  =            %x.\n", Fib->Header.XferState );
5804 +
5805 +               //
5806 +               // Fill in the Callback and CallbackContext if we are not going to wait.
5807 +               //
5808 +
5809 +               if (!Wait) {
5810 +
5811 +                               FibContext->FibCallback = FibCallback;
5812 +                               FibContext->FibCallbackContext = FibCallbackContext;
5813 +
5814 +               }
5815 +
5816 +               FIB_COUNTER_INCREMENT(FsaCommData.FibsSent);
5817 +
5818 +               InsertTailList( &OurQueue->OutstandingIoQueue, &FibContext->QueueEntry );
5819 +               OurQueue->NumOutstandingIos++;
5820 +
5821 +               FibContext->FibComplete = 0;
5822 +
5823 +
5824 +
5825 +               if ( InsertQueueEntry( Adapter, Index, WhichQueue, (DontInterrupt & FsaCommData.EnableInterruptModeration)) != FSA_SUCCESS )
5826 +                        return(STATUS_UNSUCCESSFUL);
5827 +
5828 +               //
5829 +               // If the caller wanted us to wait for response wait now. 
5830 +               // If Timeouts are enabled than set the timeout otherwise wait forever.
5831 +               //
5832 +    
5833 +               if (Wait) {
5834 +                        while (FibContext->FibComplete == 0) {
5835 +                                OsCv_wait( &FibContext->FsaEvent, FibContext->FsaEventMutex );
5836 +                        }      
5837 +                        
5838 +                        OsCvLockRelease( FibContext->FsaEventMutex );
5839 +                                       
5840 +                        if ( (FibContext->Flags & FIB_CONTEXT_FLAG_TIMED_OUT) ) {
5841 +                                return(STATUS_IO_TIMEOUT);
5842 +                        } else {
5843 +                                return(STATUS_SUCCESS);
5844 +                        }
5845 +               }
5846 +
5847 +               //
5848 +               // If the user does not want a response than return success otherwise return pending
5849 +               // 
5850 +
5851 +               ASSERT( FibCallback );
5852 +
5853 +               if (ResponseExpected)
5854 +                               return(STATUS_PENDING);
5855 +               else
5856 +                               return(STATUS_SUCCESS);
5857 +}
5858 +
5859 +BOOLEAN
5860 +GetConsumerEntry(
5861 +       IN PAFA_COMM_ADAPTER Adapter,
5862 +    PCOMM_QUE OurQueue,
5863 +    OUT PQUEUE_ENTRY *Entry
5864 +    )
5865 +/*++
5866 +
5867 +Routine Description:
5868 +
5869 +    Will return a pointer to the entry on the top of the queue requested that we are a consumer
5870 +    of, and return the address of the queue entry. It does not change the state of the queue. 
5871 +
5872 +Arguments:
5873 +
5874 +    OurQueue - is the queue the queue entry should be removed from.
5875 +
5876 +    Entry - is a pointer where the address  of the queue entry should be returned.    
5877 +    
5878 +Return Value:
5879 +
5880 +    TRUE if there was a queue entry on the response queue for the host to consume.
5881 +    FALSE if there were no queue entries to consume.
5882 +    
5883 +--*/
5884 +
5885 +{
5886 +    QUEUE_INDEX Index;
5887 +       BOOLEAN status;
5888 +
5889 +    if (*OurQueue->Headers.ProducerIndex == *OurQueue->Headers.ConsumerIndex) {
5890 +               status = FALSE;
5891 +       } else {
5892 +
5893 +           //
5894 +           // The consumer index must be wrapped if we have reached the end of
5895 +           // the queue. 
5896 +           // Else we just use the entry pointed to by the header index
5897 +           //
5898 +           
5899 +           if (*OurQueue->Headers.ConsumerIndex >= OurQueue->QueueEntries) 
5900 +                       Index = 0;              
5901 +           else
5902 +               Index = *OurQueue->Headers.ConsumerIndex;
5903 +           
5904 +           *Entry = OurQueue->BaseAddress + Index;
5905 +
5906 +#ifdef commdebug
5907 +           FsaCommPrint("Got a QE at Index %d, QE Addrss of %x.\n",Index,*Entry);
5908 +#endif
5909 +               status = TRUE;
5910 +       }
5911 +
5912 +    return(status);
5913 +}
5914 +
5915 +BOOLEAN
5916 +ConsumerEntryAvailable(
5917 +       IN PAFA_COMM_ADAPTER Adapter,
5918 +    PCOMM_QUE OurQueue
5919 +       )
5920 +{
5921 +    return (*OurQueue->Headers.ProducerIndex != *OurQueue->Headers.ConsumerIndex);
5922 +}
5923 +
5924 +VOID
5925 +FreeConsumerEntry(
5926 +       IN PAFA_COMM_ADAPTER Adapter,
5927 +    PCOMM_QUE OurQueue,
5928 +    QUEUE_TYPES WhichQueue
5929 +    )
5930 +/*++
5931 +
5932 +Routine Description:
5933 +
5934 +    Frees up the current top of the queue we are a consumer of. If the queue was full
5935 +    notify the producer that the queue is no longer full.
5936 +
5937 +Arguments:
5938 +
5939 +    OurQueue - is the queue we will free the current consumer entry on.
5940 +
5941 +Return Value:
5942 +
5943 +    TRUE if there was a queue entry on the response queue for the host to consume.
5944 +    FALSE if there were no queue entries to consume.
5945 +    
5946 +--*/
5947 +
5948 +{
5949 +    BOOLEAN WasFull = FALSE;
5950 +    HOST_2_ADAP_EVENT Notify;
5951 +
5952 +    if (*OurQueue->Headers.ProducerIndex+1 == *OurQueue->Headers.ConsumerIndex)
5953 +        WasFull = TRUE;
5954 +        
5955 +    if (*OurQueue->Headers.ConsumerIndex >= OurQueue->QueueEntries)
5956 +        *OurQueue->Headers.ConsumerIndex = 1;
5957 +    else
5958 +        *OurQueue->Headers.ConsumerIndex += 1;
5959 +        
5960 +    if (WasFull) {
5961 +        switch (WhichQueue) {
5962 +
5963 +            case HostNormCmdQueue:
5964 +                Notify = HostNormCmdNotFull;
5965 +                break;
5966 +            case HostHighCmdQueue:
5967 +                Notify = HostHighCmdNotFull;
5968 +                break;
5969 +
5970 +            case HostNormRespQueue:
5971 +                Notify = HostNormRespNotFull;
5972 +                break;
5973 +
5974 +            case HostHighRespQueue:
5975 +                Notify = HostHighRespNotFull;
5976 +                break;
5977 +
5978 +        }
5979 +        NotifyAdapter(Adapter, Notify);
5980 +    }
5981 +
5982 +}        
5983 +
5984 +AAC_STATUS
5985 +CompleteAdapterFib(
5986 +       IN PFIB_CONTEXT Context,
5987 +    IN USHORT Size
5988 +    )
5989 +/*++
5990 +
5991 +Routine Description:
5992 +
5993 +    Will do all necessary work to complete a FIB that was sent from the adapter.
5994 +
5995 +Arguments:
5996 +
5997 +    Fib is a pointer to the FIB that caller wishes to complete processing on. 
5998 +
5999 +    Size - Size of the completion Packet(Opitional). If not present than the current
6000 +           largest size in the Fib will be used
6001 +    
6002 +       Adapter - Pointer to which adapter sent this FIB
6003 +
6004 +Return Value:
6005 +
6006 +    NT_SUCCESS if a Fib was returned to the caller.
6007 +    NT_ERROR if event was an invalid event. 
6008 +
6009 +--*/
6010 +{
6011 +       PCOMM_FIB_CONTEXT FibContext = Context;
6012 +    PFIB Fib = FibContext->Fib;
6013 +       PAFA_COMM_ADAPTER Adapter = FibContext->Adapter;
6014 +    ULONG DontInterrupt = FALSE;
6015 +
6016 +    if (Fib->Header.XferState == 0)
6017 +        return(STATUS_SUCCESS);
6018 +
6019 +    //
6020 +    // If we plan to do anything check the structure type first.
6021 +    // 
6022 +
6023 +    if ( Fib->Header.StructType != TFib ) {
6024 +        FsaCommPrint("Error CompleteFib called with a non Fib structure.\n");
6025 +        return(STATUS_UNSUCCESSFUL);
6026 +    }
6027 +
6028 +    //
6029 +    // This block handles the case where the adapter had sent us a command and we
6030 +    // have finished processing the command. We call completeFib when we are done
6031 +    // processing the command and want to send a response back to the adapter. This
6032 +    // will send the completed cdb to the adapter.
6033 +    //
6034 +
6035 +    if (Fib->Header.XferState & SentFromAdapter) {
6036 +        Fib->Header.XferState |= HostProcessed;
6037 +        if (Fib->Header.XferState & HighPriority) {
6038 +            QUEUE_INDEX Index;
6039 +            
6040 +            if (Size) {
6041 +                Size += sizeof(FIB_HEADER);
6042 +                if (Size > Fib->Header.SenderSize) 
6043 +                    return(STATUS_BUFFER_OVERFLOW);
6044 +                Fib->Header.Size = Size;
6045 +            }
6046 +
6047 +            if (GetQueueEntry(Adapter, &Index, AdapHighRespQueue, Fib, TRUE, NULL, &DontInterrupt) != STATUS_SUCCESS) {
6048 +                FsaCommPrint("CompleteFib got an error geting a queue entry for a response.\n");
6049 +                return(FSA_FATAL);
6050 +            }
6051 +            if (InsertQueueEntry(Adapter, 
6052 +                                               Index, 
6053 +                                               AdapHighRespQueue, 
6054 +                                               (DontInterrupt & (BOOLEAN)FsaCommData.EnableInterruptModeration)) != STATUS_SUCCESS) {
6055 +                FsaCommPrint("CompleteFib failed while inserting entry on the queue.\n");
6056 +            }
6057 +        } else if (Fib->Header.XferState & NormalPriority) {
6058 +            QUEUE_INDEX Index;
6059 +
6060 +            if (Size) {
6061 +                Size += sizeof(FIB_HEADER);
6062 +                if (Size > Fib->Header.SenderSize) 
6063 +                    return(STATUS_BUFFER_OVERFLOW);
6064 +                Fib->Header.Size = Size;
6065 +            }
6066 +            
6067 +            if (GetQueueEntry(Adapter, &Index, AdapNormRespQueue, Fib, TRUE, NULL, &DontInterrupt) != STATUS_SUCCESS) {
6068 +                FsaCommPrint("CompleteFib got an error geting a queue entry for a response.\n");
6069 +                return(FSA_FATAL);
6070 +            }
6071 +            if (InsertQueueEntry(Adapter, 
6072 +                                               Index, 
6073 +                                               AdapNormRespQueue, 
6074 +                                               (DontInterrupt & (BOOLEAN)FsaCommData.EnableInterruptModeration)) != STATUS_SUCCESS) {
6075 +                FsaCommPrint("CompleteFib failed while inserting entry on the queue.\n");
6076 +            }
6077 +               }
6078 +    } else {
6079 +        cmn_err(CE_WARN, "CompleteFib: Unknown xferstate detected.\n");
6080 +               FsaBugCheck(0,0,0);
6081 +    }   
6082 +    return(STATUS_SUCCESS);
6083 +}
6084 +
6085 +AAC_STATUS
6086 +CompleteFib(
6087 +       IN PFIB_CONTEXT Context
6088 +    )
6089 +/*++
6090 +
6091 +Routine Description:
6092 +
6093 +    Will do all necessary work to complete a FIB. If the caller wishes to
6094 +    reuse the FIB after post processing has been completed Reinitialize
6095 +    should be called set to TRUE, otherwise the FIB will be returned to the
6096 +    free FIB pool. If Reinitialize is set to TRUE then the FIB header is
6097 +    reinitialzied and is ready for reuse on return from this routine.
6098 +
6099 +Arguments:
6100 +
6101 +    Fib is a pointer to the FIB that caller wishes to complete processing on. 
6102 +
6103 +    Size - Size of the completion Packet(Opitional). If not present than the current
6104 +           largest size in the Fib will be used
6105 +    
6106 +    Reinitialize is a boolean which determines if the routine will ready the
6107 +        completed FIB for reuse(TRUE) or not(FALSE).
6108 +
6109 +Return Value:
6110 +
6111 +    NT_SUCCESS if a Fib was returned to the caller.
6112 +    NT_ERROR if event was an invalid event. 
6113 +
6114 +--*/
6115 +{
6116 +    PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
6117 +       PAFA_COMM_ADAPTER Adapter = FibContext->Adapter;
6118 +       PFIB Fib = FibContext->Fib;
6119 +
6120 +    //
6121 +    // Check for a fib which has already been completed
6122 +    //
6123 +
6124 +//     ASSERT(Fib->Header.XferState & AdapterProcessed);
6125 +    if (Fib->Header.XferState == 0)
6126 +        return(STATUS_SUCCESS);
6127 +
6128 +    //
6129 +    // If we plan to do anything check the structure type first.
6130 +    // 
6131 +
6132 +    if ( Fib->Header.StructType != TFib ) {
6133 +        FsaCommPrint("Error CompleteFib called with a non Fib structure.\n");
6134 +        return(STATUS_UNSUCCESSFUL);
6135 +    }
6136 +
6137 +#if 0
6138 +//#if FSA_ADAPTER_METER
6139 +       //
6140 +       // Meter the completion
6141 +       //
6142 +       fsaMeterEnd(                                            // meter the end of an operation
6143 +               &(Adapter->FibMeter),                   // .. the meter
6144 +               IrpContext->FibMeterType,               // .. type of operation
6145 +               &(IrpContext->FibStartTime),    // .. ptr to operation start timestamp
6146 +               FibGetMeterSize(Fib,                    // .. number of bytes in operation
6147 +                               IrpContext->FibMeterType, 
6148 +                               IrpContext->FibSubCommand));
6149 +#endif // FSA_ADAPTER_METER
6150 +       
6151 +    //
6152 +    // This block completes a cdb which orginated on the host and we just need
6153 +    // to deallocate the cdb or reinit it. At this point the command is complete
6154 +    // that we had sent to the adapter and this cdb could be reused.
6155 +    //
6156 +       
6157 +    if ( (Fib->Header.XferState & SentFromHost) &&
6158 +         (Fib->Header.XferState & AdapterProcessed)) {
6159 +        
6160 +        ASSERT(FibContext->LogicalFibAddress.LowPart != 0);
6161 +
6162 +        return( DeallocateFib(FibContext) ); 
6163 +       
6164 +    //
6165 +    // This handles the case when the host has aborted the I/O to the
6166 +    // adapter because the adapter is not responding
6167 +    //
6168 +
6169 +    } else if (Fib->Header.XferState & SentFromHost) {
6170 +
6171 +        ASSERT(FibContext->LogicalFibAddress.LowPart != 0);
6172 +
6173 +
6174 +        return( DeallocateFib(FibContext) ); 
6175 +
6176 +    } else if (Fib->Header.XferState & HostOwned) {
6177 +
6178 +        return(DeallocateFib(FibContext));
6179 +
6180 +    } else {
6181 +        cmn_err(CE_WARN, "CompleteFib: Unknown xferstate detected.\n");
6182 +               FsaBugCheck(0,0,0);
6183 +    }   
6184 +    return(STATUS_SUCCESS);
6185 +}
6186 +
6187 +VOID
6188 +HandleDriverAif(
6189 +    IN PAFA_COMM_ADAPTER Adapter,
6190 +       IN PCOMM_FIB_CONTEXT FibContext
6191 +    )
6192 +/*++
6193 +
6194 +Routine Description:
6195 +
6196 +       This routine handles a driver notify fib from the adapter and dispatches it to 
6197 +       the appropriate routine for handling.
6198 +
6199 +Arguments:
6200 +
6201 +       Adapter - Which adapter this fib is from
6202 +       FibContext - Pointer to FibContext from adapter.
6203 +    
6204 +Return Value:
6205 +
6206 +    Nothing.
6207 +    
6208 +--*/
6209 +{
6210 +       PFIB Fib = FibContext->Fib;
6211 +       PAFA_CLASS_DRIVER ClassDriver;
6212 +       BOOLEAN Handled = FALSE;
6213 +
6214 +
6215 +       //
6216 +       // First loop through all of the class drivers to give them a chance to handle
6217 +       // the Fib.
6218 +       //
6219 +
6220 +       ClassDriver = Adapter->ClassDriverList;
6221 +
6222 +       while (ClassDriver) {
6223 +
6224 +               if (ClassDriver->HandleAif) {
6225 +
6226 +                       if (ClassDriver->HandleAif( ClassDriver->ClassDriverExtension, FibContext ) ) {
6227 +
6228 +                               Handled = TRUE;
6229 +                               break;
6230 +
6231 +                       }
6232 +               }
6233 +
6234 +               ClassDriver = ClassDriver->Next;
6235 +       }
6236 +
6237 +       if (!Handled) {
6238 +
6239 +               //
6240 +               // Set the status of this FIB to be Invalid parameter.
6241 +               //
6242 +
6243 +//             *(FSASTATUS *)Fib->data = ST_INVAL;
6244 +               *(FSASTATUS *)Fib->data = ST_OK;
6245 +
6246 +
6247 +               CompleteAdapterFib(FibContext, sizeof(FSASTATUS));
6248 +
6249 +       }
6250 +}
6251 +
6252 +int
6253 +NormCommandThread(
6254 +    IN PAFA_COMM_ADAPTER Adapter
6255 +    )
6256 +/*++
6257 +
6258 +Routine Description:
6259 +
6260 +    Waits on the commandready event in it's queue. When the event gets set it will
6261 +    pull FIBs off it's queue. It will continue to pull FIBs off till the queue is empty.
6262 +    When the queue is empty it will wait for more FIBs.
6263 +
6264 +Arguments:
6265 +
6266 +    Context is used. All data os global
6267 +    
6268 +Return Value:
6269 +    Nothing.
6270 +    
6271 +--*/
6272 +{
6273 +    PFIB Fib, NewFib;
6274 +       COMM_FIB_CONTEXT FibContext; // for error logging
6275 +    KIRQL SavedIrql;
6276 +       PCOMM_REGION CommRegion = Adapter->CommRegion;
6277 +       PLIST_ENTRY Entry;
6278 +       PGET_ADAPTER_FIB_CONTEXT AdapterFibContext;
6279 +
6280 +       //
6281 +       // We can only have one thread per adapter for AIF's.
6282 +       //
6283 +
6284 +       if (Adapter->AifThreadStarted) {
6285 +               return (EINVAL);
6286 +       }
6287 +
6288 +// cmn_err(CE_DEBUG, "AIF thread started");
6289 +
6290 +       //
6291 +       // Let the DPC know it has a place to send the AIF's to.
6292 +       //
6293 +
6294 +       Adapter->AifThreadStarted = TRUE;
6295 +
6296 +       RtlZeroMemory(&FibContext, sizeof(COMM_FIB_CONTEXT));
6297 +
6298 +       OsSpinLockAcquire(CommRegion->HostNormCmdQue.QueueLock);
6299 +
6300 +    while (TRUE) {
6301 +
6302 +               //
6303 +               // NOTE : the QueueLock is held at the top of each loop.
6304 +               //
6305 +
6306 +               ASSERT(OsSpinLockOwned(CommRegion->HostNormCmdQue.QueueLock));
6307 +
6308 +               while (!IsListEmpty(&(CommRegion->HostNormCmdQue.CommandQueue))) {
6309 +                       PLIST_ENTRY Entry;
6310 +                       PAIFCOMMANDTOHOST AifCommandToHost;
6311 +
6312 +                       Entry = RemoveHeadList(&(CommRegion->HostNormCmdQue.CommandQueue));
6313 +
6314 +                       OsSpinLockRelease(CommRegion->HostNormCmdQue.QueueLock);
6315 +
6316 +                       Fib = CONTAINING_RECORD( Entry, FIB, Header.FibLinks );
6317 +                                               
6318 +                       //
6319 +                       // We will process the FIB here or pass it to a worker thread that is TBD. We Really
6320 +                       // can't do anything at this point since we don't have anything defined for this thread to
6321 +                       // do.
6322 +                       //
6323 +                       
6324 +                       // cmn_err(CE_DEBUG, "Got Fib from the adapter with a NORMAL priority, command 0x%x.\n", Fib->Header.Command);
6325 +
6326 +                       RtlZeroMemory( &FibContext, sizeof(COMM_FIB_CONTEXT) );
6327 +
6328 +
6329 +                   FibContext.NodeTypeCode = FSAFS_NTC_FIB_CONTEXT;
6330 +                   FibContext.NodeByteSize = sizeof( COMM_FIB_CONTEXT );
6331 +                       FibContext.Fib = Fib;
6332 +                       FibContext.FibData = Fib->data;
6333 +                       FibContext.Adapter = Adapter;
6334 +
6335 +                       
6336 +                       //
6337 +                       // We only handle AifRequest fibs from the adapter.
6338 +                       //
6339 +
6340 +                       ASSERT(Fib->Header.Command == AifRequest);
6341 +
6342 +
6343 +                       AifCommandToHost = (PAIFCOMMANDTOHOST) Fib->data;
6344 +
6345 +                       if (AifCommandToHost->command == AifCmdDriverNotify) {
6346 +
6347 +
6348 +
6349 +                               HandleDriverAif( Adapter, &FibContext );
6350 +
6351 +                       } else {
6352 +                                       AAC_UINT32 time_now, time_last;
6353 +                                       time_now = (AAC_UINT32)OsGetSeconds();
6354 +                       
6355 +
6356 +                               OsCvLockAcquire(Adapter->AdapterFibMutex);
6357 +
6358 +                               Entry = Adapter->AdapterFibContextList.Flink;
6359 +
6360 +                               //
6361 +                               // For each Context that is on the AdapterFibContextList, make a copy of the
6362 +                               // fib, and then set the event to wake up the thread that is waiting for it.
6363 +                               //
6364 +
6365 +                               while (Entry != &Adapter->AdapterFibContextList) {
6366 +
6367 +                                       //
6368 +                                       // Extract the AdapterFibContext
6369 +                                       //
6370 +
6371 +                                       AdapterFibContext = CONTAINING_RECORD( Entry, GET_ADAPTER_FIB_CONTEXT, NextContext );
6372 +
6373 +                                       //
6374 +                                       // Check if the queue is getting backlogged
6375 +                                       //
6376 +                                       if ( AdapterFibContext->FibCount > 20 ) {
6377 +                                               time_last = (AAC_UINT32)(AdapterFibContext->FileObject);
6378 +
6379 +                                               //
6380 +                                               // has it been > 2 minutes since the last read off the queue?
6381 +                                               //
6382 +                                               if ((time_now - time_last) > 120) {
6383 +                                                       Entry = Entry->Flink;
6384 +                                                       // cmn_err (CE_WARN, "aifd: Flushing orphaned AdapterFibContext: idle %d seconds, %d fibs",
6385 +                                                       //               time_now - time_last,
6386 +                                                       //               AdapterFibContext->FibCount);
6387 +                                                       FsaCloseAdapterFibContext ( Adapter, AdapterFibContext );
6388 +                                                       continue;
6389 +                                               }
6390 +                                       }
6391 +                                                                       
6392 +//  Warning: sleep possible while holding spinlock
6393 +                                       NewFib = OsAllocMemory(sizeof(FIB), OS_ALLOC_MEM_SLEEP);
6394 +
6395 +                                       if (NewFib) {
6396 +
6397 +                                               //
6398 +                                               // Make the copy of the FIB
6399 +                                               //
6400 +
6401 +                                               RtlCopyMemory(NewFib, Fib, sizeof(FIB));
6402 +
6403 +                                               //
6404 +                                               // Put the FIB onto the AdapterFibContext's FibList
6405 +                                               //
6406 +
6407 +                                               InsertTailList(&AdapterFibContext->FibList, &NewFib->Header.FibLinks);
6408 +                                               AdapterFibContext->FibCount++;
6409 +
6410 +                                               // 
6411 +                                               // Set the event to wake up the thread that will waiting.
6412 +                                               //
6413 +
6414 +                                               OsCv_signal(&AdapterFibContext->UserEvent);
6415 +
6416 +                                       } else {
6417 +
6418 +
6419 +                                       }
6420 +
6421 +                                       Entry = Entry->Flink;
6422 +                               }
6423 +
6424 +                               //
6425 +                               // Set the status of this FIB
6426 +                               //
6427 +
6428 +                               *(FSASTATUS *)Fib->data = ST_OK;
6429 +                               
6430 +                               CompleteAdapterFib( &FibContext, sizeof(FSASTATUS) );
6431 +
6432 +                               OsCvLockRelease(Adapter->AdapterFibMutex);
6433 +
6434 +                       }
6435 +
6436 +                       OsSpinLockAcquire(CommRegion->HostNormCmdQue.QueueLock);
6437 +
6438 +               }
6439 +
6440 +               //
6441 +               // There are no more AIF's,  call cv_wait_sig to wait for more
6442 +               // to process.
6443 +               //
6444 +
6445 +               // cmn_err(CE_DEBUG, "no more AIF's going to sleep\n");
6446 +
6447 +               if (OsCv_wait_sig( &(CommRegion->HostNormCmdQue.CommandReady), 
6448 +                                                CommRegion->HostNormCmdQue.QueueLock ) == 0) {
6449 +
6450 +                       OsSpinLockRelease(CommRegion->HostNormCmdQue.QueueLock);
6451 +
6452 +                       Adapter->AifThreadStarted = FALSE;
6453 +
6454 +                       // cmn_err(CE_DEBUG, "AifThread awoken by a signal\n");
6455 +                       
6456 +                       return (EINTR);
6457 +                       
6458 +               }                                
6459 +
6460 +               // cmn_err(CE_DEBUG, "Aif thread awake, going to look for more AIF's\n");
6461 +
6462 +       }
6463 +}
6464 +    
6465 +
6466 +PVOID
6467 +FsaGetFibData(
6468 +       IN PFIB_CONTEXT Context
6469 +       )
6470 +{
6471 +    PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
6472 +
6473 +       return ((PVOID)FibContext->Fib->data);
6474 +}          
6475 +                              
6476 +
6477 +#ifdef API_THROTTLE
6478 +
6479 +void ThrottlePeriodEndDpcRtn(
6480 +    IN PKDPC Dpc,
6481 +    IN PVOID DeferredContext,
6482 +    IN PVOID SystemArgument1,
6483 +    IN PVOID SystemArgument2
6484 +    )
6485 +/*++
6486 +
6487 +Routine Description:
6488 +
6489 +    This routine is called as a DPC when a throttle period expires. It
6490 +       restarts all threads suspended due to the throttling flow control.
6491 +       
6492 +       The throttling counted semaphore is signalled for all waiting threads
6493 +       and the indicator of throttling active is cleared.
6494 +
6495 +Arguments:
6496 +
6497 +    Dpc                                - Pointer to Dpc structure. Not used.
6498 +       DefferedContext - Pointer to per-adapter context. This is used to locate the
6499 +                                         throttle information for this adapter.
6500 +    SystemArgument1    - Not used
6501 +       SystemArgument2 - Not used
6502 +       
6503 +Return Value:
6504 +
6505 +       None.
6506 +
6507 +--*/
6508 +{
6509 +       PCOMM_REGION CommRegion;
6510 +       PAFA_COMM_ADAPTER Adapter = (PAFA_COMM_ADAPTER) DeferredContext;
6511 +
6512 +       CommRegion = Adapter->CommRegion;
6513 +
6514 +       //
6515 +       // Acquire the spinlock protecting the throttle status.
6516 +       //
6517 +       OsSpinLockAcquire(CommRegion->AdapNormCmdQue.QueueLock);
6518 +
6519 +       FsaCommPrint("ThrottlePeriodEndDpc\n");
6520 +
6521 +       //
6522 +       // Check that the timer has fired as many times as it was set !
6523 +       //
6524 +
6525 +       CommRegion->ThrottleTimerFires++;
6526 +       ASSERT(CommRegion->ThrottleTimerFires == CommRegion->ThrottleTimerSets);
6527 +
6528 +       //
6529 +       // The throttle period is now over. Restart all threads waiting
6530 +       // on the throttle being released.
6531 +       // Clear the throttle active indicator. This will allow new FIBs
6532 +       // to be sent to the adapter once we release the spinlock on exiting
6533 +       // the DPC. This means all restarted threads will be runnable
6534 +       // threads by then.
6535 +       //
6536 +
6537 +       ASSERT(CommRegion->ThrottleActive == TRUE);             // The throttle had better be on !
6538 +       CommRegion->ThrottleActive = FALSE;                             // This allows new data FIBs to go to the adapter on dpc exit
6539 +
6540 +       OsSpinLockRelease(CommRegion->AdapNormCmdQue.QueueLock);
6541 +}
6542 +
6543 +#endif // #ifdef API_THROTTLE
6544 +
6545 +/*
6546 + * Overrides for Emacs so that we almost follow Linus's tabbing style.
6547 + * Emacs will notice this stuff at the end of the file and automatically
6548 + * adjust the settings for this buffer only.  This must remain at the end
6549 + * of the file.
6550 + * ---------------------------------------------------------------------------
6551 + * Local variables:
6552 + * c-indent-level: 4
6553 + * c-brace-imaginary-offset: 0
6554 + * c-brace-offset: -4
6555 + * c-argdecl-indent: 4
6556 + * c-label-offset: -4
6557 + * c-continued-statement-offset: 4
6558 + * c-continued-brace-offset: 0
6559 + * indent-tabs-mode: nil
6560 + * tab-width: 8
6561 + * End:
6562 + */
6563 diff -urN linux/drivers/scsi/aacraid/dpcsup.c linux/drivers/scsi/aacraid/dpcsup.c
6564 --- linux/drivers/scsi/aacraid/dpcsup.c Wed Dec 31 19:00:00 1969
6565 +++ linux/drivers/scsi/aacraid/dpcsup.c Thu Dec 21 13:14:30 2000
6566 @@ -0,0 +1,443 @@
6567 +/*++
6568 + * Adaptec aacraid device driver for Linux.
6569 + *
6570 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
6571 + *
6572 + * This program is free software; you can redistribute it and/or modify
6573 + * it under the terms of the GNU General Public License as published by
6574 + * the Free Software Foundation; either version 2, or (at your option)
6575 + * any later version.
6576 + *
6577 + * This program is distributed in the hope that it will be useful,
6578 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
6579 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
6580 + * GNU General Public License for more details.
6581 + *
6582 + * You should have received a copy of the GNU General Public License
6583 + * along with this program; see the file COPYING.  If not, write to
6584 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
6585 + *
6586 + * Module Name:
6587 + *  dpcsup.c
6588 + *
6589 + * Abstract: All DPC processing routines for the cyclone board occur here.
6590 + *
6591 + *
6592 + --*/
6593 +
6594 +static char *ident_dpcsup = "aacraid_ident dpcsup.c 1.0.6 2000/10/09 Adaptec, Inc.";
6595 +
6596 +#include "comprocs.h"
6597 +
6598 +
6599 +//
6600 +//  The Bug check file id for this module
6601 +//
6602 +
6603 +#define BugCheckFileId                   (FSAFS_BUG_CHECK_DPCSUP)
6604 +
6605 +#define Dbg                              (DEBUG_TRACE_DPCSUP)
6606 +
6607 +u_int
6608 +CommonNotFullDpc(
6609 +       IN PCOMM_REGION CommRegion
6610 +    )
6611 +/*++
6612 +
6613 +Routine Description:
6614 +
6615 +    This DPC routine will be queued when the adapter interrupts us to let us know the queue is
6616 +    no longer full. The Isr will pass the queue that we will set the not full event.
6617 +
6618 +Arguments:
6619 +
6620 +    Dpc - Pointer to this routine.
6621 +
6622 +    Dummy - is a pointer to the comm region which is global so we don't need it anyway
6623 +
6624 +    Queue is a pointer to the queue structure we will operate on.
6625 +
6626 +    MoreData2 are DPC parameters we don't need for this function. Maybe we can add some accounting
6627 +        stuff in here.
6628 +
6629 +Return Value:
6630 +    Nothing.
6631 +
6632 +--*/
6633 +{
6634 +
6635 +#ifdef unix_queue_full
6636 +    KeSetEvent(&Queue->QueueFull, 0, FALSE);
6637 +#endif
6638 +
6639 +}
6640 +
6641 +int GatherFibTimes = 0;
6642 +
6643 +// XXX - hack this in until I figure out which header file should contain it. <smb>
6644 +extern ULONG
6645 +FibGetMeterSize(
6646 +    PFIB pFib,
6647 +       ULONG MeterType,
6648 +       char SubCommand
6649 +       );
6650 +
6651 +
6652 +/*++
6653 +
6654 +Routine Description:
6655 +
6656 +    This DPC routine will be queued when the adapter interrupts us to let us know there
6657 +    is a response on our normal priority queue. We will pull off all QE there are and wake
6658 +    up all the waiters before exiting. We will take a spinlock out on the queue before operating
6659 +    on it.
6660 +
6661 +Arguments:
6662 +
6663 +    Dpc - Pointer to this routine.
6664 +
6665 +    OurQueue is a pointer to the queue structure we will operate on.
6666 +
6667 +    MoreData1&2 are DPC parameters we don't need for this function. Maybe we can add some accounting
6668 +        stuff in here.
6669 +
6670 +Return Value:
6671 +    Nothing.
6672 +
6673 +--*/
6674 +u_int
6675 +HostResponseNormalDpc (IN PCOMM_QUE OurQueue)
6676 +{
6677 +    PAFA_COMM_ADAPTER Adapter = OurQueue->Adapter;
6678 +    PQUEUE_ENTRY QueueEntry;
6679 +    PFIB Fib;
6680 +       PCOMM_FIB_CONTEXT FibContext;
6681 +    int Consumed = 0;
6682 +       KIRQL OldIrql;
6683 +
6684 +       LARGE_INTEGER ResponseAllocSize;
6685 +
6686 +#ifdef commdebug
6687 +    FsaCommPrint("entering the host normal reponse dpc routine.\n");
6688 +#endif
6689 +
6690 +       OsSpinLockAcquire( OurQueue->QueueLock );       
6691 +
6692 +    //
6693 +    // Keep pulling response QEs off the response queue and waking
6694 +    // up the waiters until there are no more QEs. We then return
6695 +    // back to the system. If no response was requesed we just
6696 +    // deallocate the Fib here and continue.
6697 +    //
6698 +
6699 + loop:
6700 +    while ( GetConsumerEntry( Adapter, OurQueue, &QueueEntry) ) {
6701 +
6702 +               int IsFastResponse;
6703 +
6704 +               IsFastResponse = (int) (QueueEntry->FibAddress & 0x01);
6705 +               Fib = (PFIB) (QueueEntry->FibAddress & ~0x01);
6706 +
6707 +               FreeConsumerEntry(Adapter, OurQueue, HostNormRespQueue);
6708 +
6709 +               FibContext = (PCOMM_FIB_CONTEXT)Fib->Header.SenderData;
6710 +
6711 +               ASSERT(FibContext->Fib == Fib);
6712 +
6713 +               //
6714 +               // Remove this FibContext from the Outstanding I/O queue.
6715 +               // But only if it has not already been timed out.
6716 +               //
6717 +               // If the fib has been timed out already, then just continue.
6718 +               // The caller has already been notified that the fib timed out.
6719 +               //
6720 +
6721 +               if (!(FibContext->Flags & FIB_CONTEXT_FLAG_TIMED_OUT)) {
6722 +
6723 +                       RemoveEntryList( &FibContext->QueueEntry );
6724 +                       Adapter->CommRegion->AdapNormCmdQue.NumOutstandingIos--;
6725 +
6726 +               } else {
6727 +
6728 +                       FsaCommLogEvent(FibContext,
6729 +                                                       FsaCommData.DeviceObject, 
6730 +                                                       FSAFS_TIMED_OUT_FIB_COMPLETED,
6731 +                                                       STATUS_UNSUCCESSFUL, 
6732 +                                                       BugCheckFileId | __LINE__,
6733 +                                                       FACILITY_FSAFS_ERROR_CODE,
6734 +                                                       NULL,
6735 +                                                       TRUE);                  
6736 +
6737 +                       continue;
6738 +
6739 +               }
6740 +
6741 +               OsSpinLockRelease( OurQueue->QueueLock );
6742 +
6743 +               if (IsFastResponse) {
6744 +
6745 +                       //
6746 +                       // doctor the fib
6747 +                       //
6748 +
6749 +                       *(FSASTATUS *)Fib->data = ST_OK;
6750 +
6751 +                       Fib->Header.XferState |= AdapterProcessed;
6752 +
6753 +               }
6754 +
6755 +               ASSERT((Fib->Header.XferState & (AdapterProcessed | HostOwned | SentFromHost)) == (AdapterProcessed | HostOwned | SentFromHost));
6756 +
6757 +               FIB_COUNTER_INCREMENT(FsaCommData.FibRecved);
6758 +
6759 +               ASSERT(FsaCommData.FibsSent >= FsaCommData.FibRecved);
6760 +
6761 +
6762 +               if (Fib->Header.Command == NuFileSystem) {
6763 +
6764 +                       FSASTATUS *pStatus = (FSASTATUS *)Fib->data;
6765 +
6766 +                       if (*pStatus & 0xffff0000) {
6767 +
6768 +                               ULONG Hint = *pStatus;
6769 +
6770 +                               *pStatus = ST_OK;
6771 +
6772 +/*
6773 +                               DbgPrint("Replacing hint in fid (drive = %d, f1 = 0x%x, f2 = 0x%x, hint = 0x%x, new_hint = 0x%x)\n", 
6774 +                                                IrpContext->NonPaged->FileId.fid_driveno,
6775 +                                                IrpContext->NonPaged->FileId.fid_f1,
6776 +                                                IrpContext->NonPaged->FileId.fid_f2,
6777 +                                                IrpContext->NonPaged->FileId.fid_hint,
6778 +                                                Hint);
6779 +*/
6780 +
6781 +                       }
6782 +
6783 +               }
6784 +
6785 +               if (Fib->Header.XferState & (NoResponseExpected | Async) ) {
6786 +
6787 +                       ASSERT(FibContext->FibCallback);
6788 +
6789 +               if (Fib->Header.XferState & NoResponseExpected)
6790 +                               FIB_COUNTER_INCREMENT(FsaCommData.NoResponseRecved);
6791 +                       else 
6792 +                               FIB_COUNTER_INCREMENT(FsaCommData.AsyncRecved);
6793 +
6794 +                       //
6795 +                       // NOTE:  we can not touch the FibContext after this call, because it may have been
6796 +                       // deallocated.
6797 +                       //
6798 +
6799 +                       FibContext->FibCallback(FibContext->FibCallbackContext, FibContext, STATUS_SUCCESS);
6800 +
6801 +               } else {
6802 +
6803 +                       OsCvLockAcquire( FibContext->FsaEventMutex);
6804 +
6805 +                       FibContext->FibComplete = 1;
6806 +
6807 +                       OsCv_signal( &FibContext->FsaEvent );
6808 +
6809 +                       OsCvLockRelease( FibContext->FsaEventMutex );
6810 +
6811 +                       FIB_COUNTER_INCREMENT(FsaCommData.NormalRecved);
6812 +                       
6813 +               }
6814 +
6815 +
6816 +               Consumed++;
6817 +
6818 +               OsSpinLockAcquire( OurQueue->QueueLock );
6819 +               
6820 +    }
6821 +
6822 +       if (Consumed > FsaCommData.PeakFibsConsumed)
6823 +               FsaCommData.PeakFibsConsumed = Consumed;
6824 +
6825 +       if (Consumed == 0) 
6826 +               FsaCommData.ZeroFibsConsumed++;
6827 +
6828 +       if (FsaCommData.HardInterruptModeration) {
6829 +
6830 +               //
6831 +               // Re-Enable the interrupt from the adapter, then recheck to see if anything has 
6832 +               // been put on the queue.  This removes the race condition that exists between the
6833 +               // last time we checked the queue, and when we re-enabled the interrupt.
6834 +               //
6835 +               // If there is something on the queue, then go handle it.
6836 +               //
6837 +
6838 +               EnableInterrupt( Adapter, HostNormRespQue, FALSE );
6839 +
6840 +               if (ConsumerEntryAvailable( Adapter, OurQueue ) ) {
6841 +
6842 +                       DisableInterrupt( Adapter, HostNormRespQue, FALSE );
6843 +
6844 +                       goto loop;
6845 +
6846 +               }
6847 +       }
6848 +
6849 +#ifdef commdebug
6850 +    FsaCommPrint("Exiting host normal reponse dpc routine after consuming %d QE(s).\n",Consumed);
6851 +#endif
6852 +
6853 +       OsSpinLockRelease( OurQueue->QueueLock );
6854 +
6855 +}
6856 +
6857 +/*++
6858 +
6859 +Routine Description:
6860 +
6861 +    This DPC routine wiol be queued when the adapter interrupts us to let us know there
6862 +    is a response on our high priority queue. We will pull off all QE there are and wake
6863 +    up all the waiters before exiting. We will take a spinlock out on the queue before operating
6864 +    on it.
6865 +
6866 +Arguments:
6867 +
6868 +    Dpc - Pointer to this routine.
6869 +
6870 +    OurQueue is a pointer to the queue structure we will operate on.
6871 +
6872 +    MoreData1&2 are DPC parameters we don't need for this function. Maybe we can add some accounting
6873 +        stuff in here.
6874 +
6875 +Return Value:
6876 +    Nothing.
6877 +
6878 +--*/
6879 +u_int
6880 +HostResponseHighDpc (IN PCOMM_QUE OurQueue)
6881 +{}
6882 +
6883 +
6884 +/*++
6885 +
6886 +Routine Description:
6887 +
6888 +    This DPC routine will be queued when the adapter interrupts us to let us know there
6889 +    is a command on our high priority queue. We will pull off all QE there are and wake
6890 +    up all the waiters before exiting. We will take a spinlock out on the queue before operating
6891 +    on it.
6892 +
6893 +Arguments:
6894 +
6895 +    Dpc - Pointer to this routine.
6896 +
6897 +    OurQueue is a pointer to the queue structure we will operate on.
6898 +
6899 +    MoreData1&2 are DPC parameters we don't need for this function. Maybe we can add some accounting
6900 +        stuff in here.
6901 +
6902 +Return Value:
6903 +    Nothing.
6904 +
6905 +--*/
6906 +u_int
6907 +HostCommandHighDpc (IN PCOMM_QUE OurQueue)
6908 +{}
6909 +
6910 +
6911 +/*++
6912 +
6913 +Routine Description:
6914 +
6915 +    This DPC routine will be queued when the adapter interrupts us to let us know there
6916 +    is a command on our normal priority queue. We will pull off all QE there are and wake
6917 +    up all the waiters before exiting. We will take a spinlock out on the queue before operating
6918 +    on it.
6919 +
6920 +Arguments:
6921 +
6922 +    Dpc - Pointer to this routine.
6923 +
6924 +    OurQueue is a pointer to the queue structure we will operate on.
6925 +
6926 +    MoreData1&2 are DPC parameters we don't need for this function. Maybe we can add some accounting
6927 +        stuff in here.
6928 +
6929 +Return Value:
6930 +    Nothing.
6931 +
6932 +--*/
6933 +u_int
6934 +HostCommandNormDpc (IN PCOMM_QUE OurQueue)
6935 +{
6936 +    PAFA_COMM_ADAPTER Adapter = OurQueue->Adapter;
6937 +    PQUEUE_ENTRY QueueEntry;
6938 +
6939 +       OsSpinLockAcquire( OurQueue->QueueLock );
6940 +
6941 +    //
6942 +    // Keep pulling response QEs off the response queue and waking
6943 +    // up the waiters until there are no more QEs. We then return
6944 +    // back to the system.
6945 +    //
6946 +
6947 +    while ( GetConsumerEntry( Adapter, OurQueue, &QueueEntry) ) {
6948 +
6949 +               PFIB Fib;
6950 +
6951 +               Fib = (PFIB)QueueEntry->FibAddress;
6952 +
6953 +
6954 +               if (Adapter->AifThreadStarted) {
6955 +
6956 +
6957 +//                     cmn_err(CE_CONT, "^Received AIF, putting onto command queue\n");
6958 +
6959 +
6960 +               InsertTailList(&OurQueue->CommandQueue, &Fib->Header.FibLinks);
6961 +               FreeConsumerEntry(Adapter, OurQueue, HostNormCmdQueue);
6962 +               OsCv_signal(&OurQueue->CommandReady);
6963 +
6964 +
6965 +
6966 +               } else {
6967 +
6968 +
6969 +
6970 +                       COMM_FIB_CONTEXT FibContext;
6971 +
6972 +               
6973 +
6974 +               FreeConsumerEntry(Adapter, OurQueue, HostNormCmdQueue);
6975 +
6976 +
6977 +
6978 +                       OsSpinLockRelease( OurQueue->QueueLock );
6979 +
6980 +
6981 +
6982 +//                     cmn_err(CE_CONT, "^Received AIF, thread not started\n");
6983 +
6984 +
6985 +                       RtlZeroMemory( &FibContext, sizeof(COMM_FIB_CONTEXT) );
6986 +
6987 +                   FibContext.NodeTypeCode = FSAFS_NTC_FIB_CONTEXT;
6988 +                   FibContext.NodeByteSize = sizeof( COMM_FIB_CONTEXT );
6989 +                       FibContext.Fib = Fib;
6990 +                       FibContext.FibData = Fib->data;
6991 +                       FibContext.Adapter = Adapter;
6992 +
6993 +                       //
6994 +                       // Set the status of this FIB
6995 +                       //
6996 +
6997 +                       *(FSASTATUS *)Fib->data = ST_OK;
6998 +                               
6999 +                       CompleteAdapterFib( &FibContext, sizeof(FSASTATUS) );
7000 +
7001 +
7002 +
7003 +                       OsSpinLockAcquire( OurQueue->QueueLock );
7004 +               }               
7005 +    }
7006 +
7007 +       OsSpinLockRelease( OurQueue->QueueLock );
7008 +
7009 +}
7010 diff -urN linux/drivers/scsi/aacraid/include/AacGenericTypes.h linux/drivers/scsi/aacraid/include/AacGenericTypes.h
7011 --- linux/drivers/scsi/aacraid/include/AacGenericTypes.h        Wed Dec 31 19:00:00 1969
7012 +++ linux/drivers/scsi/aacraid/include/AacGenericTypes.h        Thu Dec 21 13:14:30 2000
7013 @@ -0,0 +1,57 @@
7014 +/*++
7015 + * Adaptec aacraid device driver for Linux.
7016 + *
7017 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
7018 + *
7019 + * This program is free software; you can redistribute it and/or modify
7020 + * it under the terms of the GNU General Public License as published by
7021 + * the Free Software Foundation; either version 2, or (at your option)
7022 + * any later version.
7023 + *
7024 + * This program is distributed in the hope that it will be useful,
7025 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7026 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
7027 + * GNU General Public License for more details.
7028 + *
7029 + * You should have received a copy of the GNU General Public License
7030 + * along with this program; see the file COPYING.  If not, write to
7031 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
7032 + *
7033 + * Module Name:
7034 + *
7035 + *  AacGenericTypes.h
7036 + *
7037 + * Abstract:
7038 + *
7039 + *     The module defines the generic data types that all of the other header files
7040 + *     depend upon.
7041 + --*/
7042 +
7043 +#ifndef _AAC_GENERIC_TYPES
7044 +#define _AAC_GENERIC_TYPES
7045 +
7046 +static char *ident_AacGeneric = "aacraid_ident AacGenericTypes.h 1.0.6 2000/10/09 Adaptec, Inc.";
7047 +
7048 +typedef        char                    AAC_INT8, *PAAC_INT8;
7049 +typedef short                  AAC_INT16, *PAAC_INT16;
7050 +typedef int                    AAC_INT32, *PAAC_INT32;
7051 +typedef long long              AAC_INT64, *PAAC_INT64;
7052 +
7053 +typedef unsigned char  AAC_UINT8, *PAAC_UINT8;
7054 +typedef unsigned short AAC_UINT16, *PAAC_UINT16;
7055 +typedef unsigned int   AAC_UINT32, *PAAC_UINT32;
7056 +typedef unsigned long long     AAC_UINT64, *PAAC_UINT64;
7057 +
7058 +typedef void                   AAC_VOID, *PAAC_VOID;
7059 +
7060 +//
7061 +// this compiler uses 32 bit enum data types
7062 +//
7063 +
7064 +#define        AAC_32BIT_ENUMS 1
7065 +#define FAILURE 1
7066 +#define INTR_UNCLAIMED 1
7067 +#define INTR_CLAIMED 0
7068 +
7069 +#endif // _AAC_GENERIC_TYPES
7070 +
7071 diff -urN linux/drivers/scsi/aacraid/include/aac_unix_defs.h linux/drivers/scsi/aacraid/include/aac_unix_defs.h
7072 --- linux/drivers/scsi/aacraid/include/aac_unix_defs.h  Wed Dec 31 19:00:00 1969
7073 +++ linux/drivers/scsi/aacraid/include/aac_unix_defs.h  Thu Dec 21 13:14:30 2000
7074 @@ -0,0 +1,300 @@
7075 +/*++
7076 + * Adaptec aacraid device driver for Linux.
7077 + *
7078 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
7079 + *
7080 + * This program is free software; you can redistribute it and/or modify
7081 + * it under the terms of the GNU General Public License as published by
7082 + * the Free Software Foundation; either version 2, or (at your option)
7083 + * any later version.
7084 + *
7085 + * This program is distributed in the hope that it will be useful,
7086 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7087 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
7088 + * GNU General Public License for more details.
7089 + *
7090 + * You should have received a copy of the GNU General Public License
7091 + * along with this program; see the file COPYING.  If not, write to
7092 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
7093 + *
7094 + * Module Name:
7095 + *
7096 + *  aac_unix_defs.h
7097 + *
7098 + * Abstract:
7099 + *
7100 + *     Macro definition and typedefs
7101 + *
7102 + --*/
7103 +
7104 +#ifndef _AAC_UNIX_DEFS
7105 +#define _AAC_UNIX_DEFS
7106 +
7107 +static char *ident_aac_unix = "aacraid_ident aac_unix_defs.h 1.0.6 2000/10/09 Adaptec, Inc.";
7108 +
7109 +#define        AAC_MAX_ADAPTERS        64
7110 +
7111 +#ifndef        TRUE
7112 +#define TRUE   1
7113 +#define FALSE  0
7114 +#endif
7115 +
7116 +#define PAGE_SIZE      4096
7117 +
7118 +typedef        void    VOID;
7119 +typedef VOID   *PVOID;
7120 +
7121 +typedef char           CHAR, *PCHAR;
7122 +typedef unsigned char  UCHAR, *PUCHAR;
7123 +typedef short          SHORT, *PSHORT;
7124 +typedef short          CSHORT, *PCSHORT;
7125 +typedef unsigned short         USHORT, *PUSHORT;
7126 +typedef unsigned long  ULONG, *PULONG;
7127 +typedef long           LONG, *PLONG;
7128 +
7129 +typedef unsigned long  BOOLEAN;
7130 +
7131 +typedef unsigned long  AAC_STATUS, *PNT_STATUS;
7132 +
7133 +typedef struct {
7134 +       unsigned long   LowPart;
7135 +       unsigned long   HighPart;
7136 +} LARGE_INTEGER;
7137 +
7138 +typedef LARGE_INTEGER  PHYSICAL_ADDRESS;
7139 +
7140 +
7141 +typedef struct _AFA_IOCTL_CMD {
7142 +       int             cmd;
7143 +       intptr_t        arg;
7144 +       int             flag;
7145 +       cred_t          *cred_p;
7146 +       int             *rval_p;
7147 +} AFA_IOCTL_CMD, *PAFA_IOCTL_CMD;
7148 +
7149 +
7150 +//
7151 +//  Singly linked list structure. Can be used as either a list head, or
7152 +//  as link words.
7153 +//
7154 +
7155 +typedef struct _SINGLE_LIST_ENTRY {
7156 +    struct _SINGLE_LIST_ENTRY *Next;
7157 +} SINGLE_LIST_ENTRY, *PSINGLE_LIST_ENTRY;
7158 +
7159 +
7160 +//
7161 +// Calculate the address of the base of the structure given its type, and an
7162 +// address of a field within the structure.
7163 +//
7164 +
7165 +#define CONTAINING_RECORD(address, type, field) ((type *)( \
7166 +                                                  (PCHAR)(address) - \
7167 +                                                  (PCHAR)(&((type *)0)->field)))
7168 +
7169 +typedef        PVOID   PMDL;
7170 +typedef PVOID  PDEVICE_OBJECT;
7171 +typedef PVOID  PADAPTER_OBJECT;
7172 +typedef ULONG  KIRQL;
7173 +typedef PVOID  HANDLE;
7174 +typedef PVOID  KDPC, *PKDPC;
7175 +typedef PVOID  PFILE_OBJECT;
7176 +typedef PVOID  PIRP;
7177 +typedef PVOID  PDRIVER_OBJECT;
7178 +typedef ULONG  KTIMER;
7179 +
7180 +
7181 +#define        STATUS_SUCCESS          0x00000000
7182 +#define STATUS_PENDING         0x40000001
7183 +#define STATUS_IO_TIMEOUT                      0xc0000001
7184 +#define STATUS_UNSUCCESSFUL                    0xc0000002
7185 +#define STATUS_INSUFFICIENT_RESOURCES  0xc0000005
7186 +#define STATUS_BUFFER_OVERFLOW         0xc0000003
7187 +
7188 +
7189 +#define OUT
7190 +
7191 +
7192 +
7193 +typedef u_int
7194 +(*PUNIX_INTR_HANDLER)(caddr_t Arg);
7195 +
7196 +//
7197 +// Zone Allocation
7198 +//
7199 +
7200 +typedef struct _ZONE_SEGMENT_HEADER {
7201 +    SINGLE_LIST_ENTRY SegmentList;
7202 +    PVOID Reserved;
7203 +} ZONE_SEGMENT_HEADER, *PZONE_SEGMENT_HEADER;
7204 +
7205 +typedef struct _ZONE_HEADER {
7206 +    SINGLE_LIST_ENTRY FreeList;
7207 +    SINGLE_LIST_ENTRY SegmentList;
7208 +    ULONG BlockSize;
7209 +    ULONG TotalSegmentSize;
7210 +} ZONE_HEADER, *PZONE_HEADER;
7211 +
7212 +
7213 +//++
7214 +//
7215 +// PVOID
7216 +// ExAllocateFromZone(
7217 +//     IN PZONE_HEADER Zone
7218 +//     )
7219 +//
7220 +// Routine Description:
7221 +//
7222 +//     This routine removes an entry from the zone and returns a pointer to it.
7223 +//
7224 +// Arguments:
7225 +//
7226 +//     Zone - Pointer to the zone header controlling the storage from which the
7227 +//         entry is to be allocated.
7228 +//
7229 +// Return Value:
7230 +//
7231 +//     The function value is a pointer to the storage allocated from the zone.
7232 +//
7233 +//--
7234 +
7235 +#define ExAllocateFromZone(Zone) \
7236 +    (PVOID)((Zone)->FreeList.Next); \
7237 +    if ( (Zone)->FreeList.Next ) (Zone)->FreeList.Next = (Zone)->FreeList.Next->Next
7238 +
7239 +//++
7240 +//
7241 +// PVOID
7242 +// ExFreeToZone(
7243 +//     IN PZONE_HEADER Zone,
7244 +//     IN PVOID Block
7245 +//     )
7246 +//
7247 +// Routine Description:
7248 +//
7249 +//     This routine places the specified block of storage back onto the free
7250 +//     list in the specified zone.
7251 +//
7252 +// Arguments:
7253 +//
7254 +//     Zone - Pointer to the zone header controlling the storage to which the
7255 +//         entry is to be inserted.
7256 +//
7257 +//     Block - Pointer to the block of storage to be freed back to the zone.
7258 +//
7259 +// Return Value:
7260 +//
7261 +//     Pointer to previous block of storage that was at the head of the free
7262 +//         list.  NULL implies the zone went from no available free blocks to
7263 +//         at least one free block.
7264 +//
7265 +//--
7266 +
7267 +#define ExFreeToZone(Zone,Block)                                    \
7268 +    ( ((PSINGLE_LIST_ENTRY)(Block))->Next = (Zone)->FreeList.Next,  \
7269 +      (Zone)->FreeList.Next = ((PSINGLE_LIST_ENTRY)(Block)),        \
7270 +      ((PSINGLE_LIST_ENTRY)(Block))->Next                           \
7271 +    )
7272 +
7273 +//++
7274 +//
7275 +// BOOLEAN
7276 +// ExIsFullZone(
7277 +//     IN PZONE_HEADER Zone
7278 +//     )
7279 +//
7280 +// Routine Description:
7281 +//
7282 +//     This routine determines if the specified zone is full or not.  A zone
7283 +//     is considered full if the free list is empty.
7284 +//
7285 +// Arguments:
7286 +//
7287 +//     Zone - Pointer to the zone header to be tested.
7288 +//
7289 +// Return Value:
7290 +//
7291 +//     TRUE if the zone is full and FALSE otherwise.
7292 +//
7293 +//--
7294 +
7295 +#define ExIsFullZone(Zone) \
7296 +    ( (Zone)->FreeList.Next == (PSINGLE_LIST_ENTRY)NULL )
7297 +
7298 +
7299 +#define RtlCopyMemory( Destination, Source, Size )     bcopy( (Source), (Destination), (Size) )
7300 +#define RtlZeroMemory( Destination, Size )                     bzero( (Destination), (Size) )
7301 +
7302 +//
7303 +//  Doubly-linked list manipulation routines.  Implemented as macros
7304 +//  but logically these are procedures.
7305 +//
7306 +
7307 +//
7308 +//  VOID
7309 +//  InitializeListHead(
7310 +//      PLIST_ENTRY ListHead
7311 +//      );
7312 +//
7313 +
7314 +#define InitializeListHead(ListHead) (\
7315 +    (ListHead)->Flink = (ListHead)->Blink = (ListHead))
7316 +
7317 +//
7318 +//  BOOLEAN
7319 +//  IsListEmpty(
7320 +//      PLIST_ENTRY ListHead
7321 +//      );
7322 +//
7323 +
7324 +#define IsListEmpty(ListHead) \
7325 +    ((ListHead)->Flink == (ListHead))
7326 +
7327 +//
7328 +//  PLIST_ENTRY
7329 +//  RemoveHeadList(
7330 +//      PLIST_ENTRY ListHead
7331 +//      );
7332 +//
7333 +
7334 +#define RemoveHeadList(ListHead) \
7335 +    (ListHead)->Flink;\
7336 +    {RemoveEntryList((ListHead)->Flink)}
7337 +
7338 +
7339 +//
7340 +//  VOID
7341 +//  RemoveEntryList(
7342 +//      PLIST_ENTRY Entry
7343 +//      );
7344 +//
7345 +
7346 +#define RemoveEntryList(Entry) {\
7347 +    PLIST_ENTRY _EX_Blink;\
7348 +    PLIST_ENTRY _EX_Flink;\
7349 +    _EX_Flink = (Entry)->Flink;\
7350 +    _EX_Blink = (Entry)->Blink;\
7351 +    _EX_Blink->Flink = _EX_Flink;\
7352 +    _EX_Flink->Blink = _EX_Blink;\
7353 +    }
7354 +
7355 +//
7356 +//  VOID
7357 +//  InsertTailList(
7358 +//      PLIST_ENTRY ListHead,
7359 +//      PLIST_ENTRY Entry
7360 +//      );
7361 +//
7362 +
7363 +#define InsertTailList(ListHead,Entry) {\
7364 +    PLIST_ENTRY _EX_Blink;\
7365 +    PLIST_ENTRY _EX_ListHead;\
7366 +    _EX_ListHead = (ListHead);\
7367 +    _EX_Blink = _EX_ListHead->Blink;\
7368 +    (Entry)->Flink = _EX_ListHead;\
7369 +    (Entry)->Blink = _EX_Blink;\
7370 +    _EX_Blink->Flink = (Entry);\
7371 +    _EX_ListHead->Blink = (Entry);\
7372 +    }
7373 +
7374 +#endif /* AAC_UNIX_DEFS */
7375 diff -urN linux/drivers/scsi/aacraid/include/adapter.h linux/drivers/scsi/aacraid/include/adapter.h
7376 --- linux/drivers/scsi/aacraid/include/adapter.h        Wed Dec 31 19:00:00 1969
7377 +++ linux/drivers/scsi/aacraid/include/adapter.h        Thu Dec 21 13:14:30 2000
7378 @@ -0,0 +1,164 @@
7379 +/*++
7380 + * Adaptec aacraid device driver for Linux.
7381 + *
7382 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
7383 + *
7384 + * This program is free software; you can redistribute it and/or modify
7385 + * it under the terms of the GNU General Public License as published by
7386 + * the Free Software Foundation; either version 2, or (at your option)
7387 + * any later version.
7388 + *
7389 + * This program is distributed in the hope that it will be useful,
7390 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7391 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
7392 + * GNU General Public License for more details.
7393 + *
7394 + * You should have received a copy of the GNU General Public License
7395 + * along with this program; see the file COPYING.  If not, write to
7396 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
7397 + *
7398 + * Module Name:
7399 + *
7400 + *   Adapter.h
7401 + *
7402 + * Abstract:
7403 + *   The module contains the definitions for a comm layer view of the adapter.
7404 + *
7405 + *
7406 + *
7407 + --*/
7408 +
7409 +#ifndef _ADAPTER_
7410 +#define _ADAPTER_
7411 +
7412 +static char *ident_adapter = "aacraid_ident adapter.h 1.0.6 2000/10/09 Adaptec, Inc.";
7413 +
7414 +typedef struct _GET_ADAPTER_FIB_CONTEXT {
7415 +
7416 +       NODE_TYPE_CODE          NodeTypeCode;   // used for verification of structure   
7417 +       NODE_BYTE_SIZE          NodeByteSize;
7418 +       PFILE_OBJECT            FileObject;     // used for cleanup
7419 +       LIST_ENTRY              NextContext;    // used to link context's into a linked list
7420 +       OS_CV_T                 UserEvent;      // this is used to wait for the next fib to arrive.
7421 +       BOOLEAN                 WaitingForFib;  // Set to true when thread is in WaitForSingleObject
7422 +       ULONG                   FibCount;       // total number of FIBs on FibList
7423 +       LIST_ENTRY              FibList;
7424 +} GET_ADAPTER_FIB_CONTEXT;
7425 +typedef GET_ADAPTER_FIB_CONTEXT *PGET_ADAPTER_FIB_CONTEXT;
7426 +
7427 +
7428 +typedef struct _FIB_CONTEXT_ZONE_SEGMENT {
7429 +
7430 +       struct _FIB_CONTEXT_ZONE_SEGMENT        *Next;
7431 +       ULONG                                   FibContextSegmentSize;
7432 +       PVOID                                   FibContextSegment;
7433 +       ULONG                                   ExtendSize;
7434 +       MAPFIB_CONTEXT                          MapFibContext;
7435 +
7436 +} FIB_CONTEXT_ZONE_SEGMENT;
7437 +typedef FIB_CONTEXT_ZONE_SEGMENT *PFIB_CONTEXT_ZONE_SEGMENT;
7438 +
7439 +typedef struct _AFA_COMM_ADAPTER {
7440 +
7441 +       struct _AFA_COMM_ADAPTER        *NextAdapter;
7442 +
7443 +    //
7444 +    //  The following fields are used to allocate FIB context structures
7445 +    //  using the zone allocator, and other fixed sized structures from a
7446 +    //  small cache.  The mutex protects access to the zone/lists
7447 +    //
7448 +
7449 +    ZONE_HEADER                FibContextZone;
7450 +       OS_SPINLOCK                     *FibContextZoneSpinLock;
7451 +       int                             FibContextZoneExtendSize;
7452 +
7453 +       PFIB_CONTEXT_ZONE_SEGMENT       FibContextSegmentList;
7454 +
7455 +       PVOID                           FibContextTimedOutList;
7456 +
7457 +       PFIB                            SyncFib;
7458 +       ULONG                           SyncFibPhysicalAddress;
7459 +
7460 +       PCOMM_REGION            CommRegion;
7461 +
7462 +       OS_SPINLOCK_COOKIE      SpinLockCookie;
7463 +
7464 +       //
7465 +       // The user API will use an IOCTL to register itself to receive FIBs
7466 +       // from the adapter.  The following list is used to keep track of all
7467 +       // the threads that have requested these FIBs.  The mutex is used to 
7468 +       // synchronize access to all data associated with the adapter fibs.
7469 +       //
7470 +       LIST_ENTRY                      AdapterFibContextList;
7471 +       OS_CVLOCK                       *AdapterFibMutex;
7472 +
7473 +       //
7474 +       // The following holds which FileObject is allow to send configuration
7475 +       // commands to the adapter that would modify the configuration.
7476 +       //
7477 +       // This is controlled by the FSACTL_OPEN_ADAPTER_CONFIG and FSACTL_CLOSE_ADAPTER_CONFIG
7478 +       // ioctls.
7479 +       //
7480 +       PFILE_OBJECT            AdapterConfigFileObject;
7481 +
7482 +       //
7483 +       // The following is really here because of the simulator
7484 +       //
7485 +       BOOLEAN                         InterruptsBelowDpc;
7486 +
7487 +       //
7488 +       // The following is the device specific extension.
7489 +       //
7490 +       PVOID                   AdapterExtension;       
7491 +       PFSAPORT_FUNCS          AdapterFuncs;
7492 +       void                    *Dip;
7493 +
7494 +       //
7495 +       // The following are user variables that are specific to the mini port.
7496 +       //
7497 +       PFSA_USER_VAR           AdapterUserVars;
7498 +       ULONG                   AdapterUserVarsSize;
7499 +
7500 +       //
7501 +       // The following is the number of the individual adapter..i.e. \Device\Afa0
7502 +       //
7503 +       LONG                    AdapterNumber;
7504 +
7505 +       AFACOMM_FUNCS           CommFuncs;
7506 +
7507 +       PAFA_CLASS_DRIVER       ClassDriverList;
7508 +
7509 +       BOOLEAN                 AifThreadStarted;
7510 +
7511 +} AFA_COMM_ADAPTER;
7512 +
7513 +typedef AFA_COMM_ADAPTER *PAFA_COMM_ADAPTER;
7514 +
7515 +
7516 +#define FsaAllocateAdapterCommArea(Adapter, BaseAddress, Size, Alignment) \
7517 +       Adapter->AdapterFuncs->AllocateAdapterCommArea(Adapter->AdapterExtension, BaseAddress, Size, Alignment)
7518 +
7519 +#define FsaFreeAdapterCommArea(Adapter) \
7520 +       Adapter->AdapterFuncs->FreeAdapterCommArea(Adapter->AdapterExtension)
7521 +
7522 +
7523 +#define AllocateAndMapFibSpace(Adapter, MapFibContext) \
7524 +       Adapter->AdapterFuncs->AllocateAndMapFibSpace(Adapter->AdapterExtension, MapFibContext)
7525 +
7526 +#define UnmapAndFreeFibSpace(Adapter, MapFibContext) \
7527 +       Adapter->AdapterFuncs->UnmapAndFreeFibSpace(Adapter->AdapterExtension, MapFibContext)
7528 +
7529 +#define InterruptAdapter(Adapter) \
7530 +       Adapter->AdapterFuncs->InterruptAdapter(Adapter->AdapterExtension)
7531 +
7532 +#define NotifyAdapter(Adapter, AdapterEvent) \
7533 +       Adapter->AdapterFuncs->NotifyAdapter(Adapter->AdapterExtension, AdapterEvent)
7534 +
7535 +#define EnableInterrupt(Adapter, AdapterEvent, AtDeviceIrq) \
7536 +       Adapter->AdapterFuncs->EnableInterrupt(Adapter->AdapterExtension, AdapterEvent, AtDeviceIrq)
7537 +
7538 +#define DisableInterrupt(Adapter, AdapterEvent, AtDeviceIrq) \
7539 +       Adapter->AdapterFuncs->DisableInterrupt(Adapter->AdapterExtension, AdapterEvent, AtDeviceIrq)
7540 +
7541 +
7542 +#endif // _ADAPTER_
7543 diff -urN linux/drivers/scsi/aacraid/include/afacomm.h linux/drivers/scsi/aacraid/include/afacomm.h
7544 --- linux/drivers/scsi/aacraid/include/afacomm.h        Wed Dec 31 19:00:00 1969
7545 +++ linux/drivers/scsi/aacraid/include/afacomm.h        Thu Dec 21 13:14:30 2000
7546 @@ -0,0 +1,191 @@
7547 +/*++
7548 + * Adaptec aacraid device driver for Linux.
7549 + *
7550 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
7551 + *
7552 + * This program is free software; you can redistribute it and/or modify
7553 + * it under the terms of the GNU General Public License as published by
7554 + * the Free Software Foundation; either version 2, or (at your option)
7555 + * any later version.
7556 + *
7557 + * This program is distributed in the hope that it will be useful,
7558 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7559 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
7560 + * GNU General Public License for more details.
7561 + *
7562 + * You should have received a copy of the GNU General Public License
7563 + * along with this program; see the file COPYING.  If not, write to
7564 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
7565 + *
7566 + * Module Name:
7567 + *   AfaComm.h
7568 + *
7569 + * Abstract:
7570 + *   This module defines all of the external interfaces to the AFA comm layer.
7571 + *
7572 + *
7573 + *
7574 + --*/
7575 +#ifndef _AFACOMM_
7576 +#define _AFACOMM_
7577 +
7578 +static char *ident_afacomm = "aacraid_ident afacomm.h 1.0.6 2000/10/09 Adaptec, Inc.";
7579 +
7580 +#include "fsaport.h"
7581 +
7582 +typedef void   *PFIB_CONTEXT;
7583 +
7584 +typedef VOID
7585 +(*PFIB_CALLBACK)(
7586 +       PVOID           FibCallbackContext,
7587 +       PFIB_CONTEXT    FibContext,
7588 +       AAC_STATUS      Status
7589 +       );
7590 +
7591 +
7592 +typedef PFIB_CONTEXT
7593 +(*PAFA_COMM_ALLOCATE_FIB) (
7594 +       IN PVOID AdapterExtension
7595 +    );
7596 +
7597 +typedef VOID
7598 +(*PAFA_COMM_FREE_FIB) (
7599 +    IN PFIB_CONTEXT FibContext
7600 +    );
7601 +
7602 +
7603 +typedef AAC_STATUS
7604 +(*PAFA_COMM_DEALLOCATE_FIB) (
7605 +    IN PFIB_CONTEXT FibContext
7606 +    );
7607 +
7608 +
7609 +typedef VOID
7610 +(*PAFA_COMM_FREE_FIB_FROM_DPC) (
7611 +    IN PFIB_CONTEXT FibContext
7612 +    );
7613 +
7614 +typedef AAC_STATUS
7615 +(*PAFA_COMM_INITIALIZE_FIB) (
7616 +       IN PFIB_CONTEXT FibContext
7617 +    );
7618 +
7619 +typedef PVOID
7620 +(*PAFA_COMM_GET_FIB_DATA) (
7621 +       IN PFIB_CONTEXT FibContext
7622 +       );
7623 +
7624 +typedef AAC_STATUS
7625 +(*PAFA_COMM_SEND_FIB) (
7626 +    IN FIB_COMMAND Command, 
7627 +       IN PFIB_CONTEXT FibContext,
7628 +    IN ULONG Size,
7629 +    IN COMM_PRIORITIES Priority,
7630 +    IN BOOLEAN Wait,
7631 +    IN PVOID WaitOn,
7632 +    IN BOOLEAN ResponseExpected,
7633 +       IN PFIB_CALLBACK FibCallback,
7634 +       IN PVOID FibCallbackContext
7635 +    );
7636 +
7637 +typedef AAC_STATUS
7638 +(*PAFA_COMM_COMPLETE_FIB) (
7639 +       IN PFIB_CONTEXT FibContext
7640 +    );
7641 +
7642 +typedef AAC_STATUS
7643 +(*PAFA_COMM_COMPLETE_ADAPTER_FIB) (
7644 +       IN PFIB_CONTEXT FibContext,
7645 +       IN USHORT Size
7646 +    );
7647 +
7648 +typedef BOOLEAN
7649 +(*PAFA_COMM_SEND_SYNCH_FIB) (
7650 +       PVOID                   AdapterExtension,
7651 +       FIB_COMMAND     Command,
7652 +       PVOID                   Data,
7653 +       USHORT                  Size,
7654 +       PVOID                   Response,
7655 +       USHORT                  *ResponseSize
7656 +       );
7657 +
7658 +
7659 +typedef struct _AFACOMM_FUNCS {
7660 +       ULONG                                   SizeOfAfaCommFuncs;
7661 +       PAFA_COMM_ALLOCATE_FIB                  AllocateFib;
7662 +       PAFA_COMM_FREE_FIB                      FreeFib;
7663 +       PAFA_COMM_FREE_FIB_FROM_DPC             FreeFibFromDpc;
7664 +       PAFA_COMM_DEALLOCATE_FIB                DeallocateFib;
7665 +       PAFA_COMM_INITIALIZE_FIB                InitializeFib;
7666 +       PAFA_COMM_GET_FIB_DATA                  GetFibData;
7667 +       PAFA_COMM_SEND_FIB                      SendFib;
7668 +       PAFA_COMM_COMPLETE_FIB                  CompleteFib;
7669 +       PAFA_COMM_COMPLETE_ADAPTER_FIB          CompleteAdapterFib;
7670 +       PAFA_COMM_SEND_SYNCH_FIB                SendSynchFib;
7671 +       PFSA_FREE_DMA_RESOURCES                 FreeDmaResources;
7672 +       PFSA_BUILD_SGMAP                        BuildSgMap;
7673 +       PFSA_ADAPTER_ADDR_TO_SYSTEM_ADDR        AdapterAddressToSystemAddress;
7674 +} AFACOMM_FUNCS;
7675 +typedef AFACOMM_FUNCS *PAFACOMM_FUNCS;
7676 +
7677 +
7678 +typedef AAC_STATUS
7679 +(*PAFA_CLASS_OPEN_ADAPTER) (
7680 +       IN PVOID Adapter
7681 +       );
7682 +
7683 +
7684 +typedef AAC_STATUS
7685 +(*PAFA_CLASS_CLOSE_ADAPTER) (
7686 +       IN PVOID Adapter
7687 +       );
7688 +
7689 +
7690 +typedef BOOLEAN
7691 +(*PAFA_CLASS_DEV_CONTROL) (
7692 +       IN PVOID Adapter,
7693 +       IN PAFA_IOCTL_CMD       IoctlCmdPtr,
7694 +       OUT int * Status
7695 +       );
7696 +
7697 +typedef BOOLEAN
7698 +(*PAFA_CLASS_HANDLE_AIF) (
7699 +       IN PVOID Adapter,
7700 +       IN PFIB_CONTEXT FibContext
7701 +       );
7702 +
7703 +
7704 +typedef struct _AFA_NEW_CLASS_DRIVER {
7705 +       PVOID                           ClassDriverExtension;
7706 +       PAFA_CLASS_OPEN_ADAPTER         OpenAdapter;
7707 +        PAFA_CLASS_CLOSE_ADAPTER       CloseAdapter;
7708 +        PAFA_CLASS_DEV_CONTROL                 DeviceControl;
7709 +       PAFA_CLASS_HANDLE_AIF           HandleAif;
7710 +       PFSA_USER_VAR                   UserVars;
7711 +       ULONG                           NumUserVars;
7712 +} AFA_NEW_CLASS_DRIVER;
7713 +typedef AFA_NEW_CLASS_DRIVER *PAFA_NEW_CLASS_DRIVER;
7714 +
7715 +
7716 +typedef struct _AFA_NEW_CLASS_DRIVER_RESPONSE {
7717 +       PAFACOMM_FUNCS          CommFuncs;
7718 +       PVOID                   CommPortExtension;
7719 +       PVOID                   MiniPortExtension;
7720 +       OS_SPINLOCK_COOKIE      SpinLockCookie;
7721 +       void                    *Dip;
7722 +} AFA_NEW_CLASS_DRIVER_RESPONSE;
7723 +typedef AFA_NEW_CLASS_DRIVER_RESPONSE *PAFA_NEW_CLASS_DRIVER_RESPONSE;
7724 +
7725 +
7726 +typedef struct _AFA_CLASS_DRIVER {
7727 +       struct _AFA_CLASS_DRIVER        *Next;
7728 +       PVOID                           ClassDriverExtension;
7729 +       PAFA_CLASS_OPEN_ADAPTER         OpenAdapter;
7730 +       PAFA_CLASS_CLOSE_ADAPTER        CloseAdapter;
7731 +       PAFA_CLASS_DEV_CONTROL          DeviceControl;
7732 +       PAFA_CLASS_HANDLE_AIF           HandleAif;
7733 +} AFA_CLASS_DRIVER;
7734 +typedef AFA_CLASS_DRIVER *PAFA_CLASS_DRIVER;
7735 +
7736 +
7737 +#endif // _AFACOMM_
7738 diff -urN linux/drivers/scsi/aacraid/include/aifstruc.h linux/drivers/scsi/aacraid/include/aifstruc.h
7739 --- linux/drivers/scsi/aacraid/include/aifstruc.h       Wed Dec 31 19:00:00 1969
7740 +++ linux/drivers/scsi/aacraid/include/aifstruc.h       Thu Dec 21 13:14:30 2000
7741 @@ -0,0 +1,319 @@
7742 +/*++
7743 + * Adaptec aacraid device driver for Linux.
7744 + *
7745 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
7746 + *
7747 + * This program is free software; you can redistribute it and/or modify
7748 + * it under the terms of the GNU General Public License as published by
7749 + * the Free Software Foundation; either version 2, or (at your option)
7750 + * any later version.
7751 + *
7752 + * This program is distributed in the hope that it will be useful,
7753 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7754 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
7755 + * GNU General Public License for more details.
7756 + *
7757 + * You should have received a copy of the GNU General Public License
7758 + * along with this program; see the file COPYING.  If not, write to
7759 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
7760 + *
7761 + * Module Name:
7762 + *   Aifstruc.h
7763 + *
7764 + * Abstract:
7765 + *   Define all shared data types relating to
7766 + *   the set of features utilizing Adapter
7767 + *   Initiated Fibs.
7768 + *
7769 + *
7770 + *
7771 + --*/
7772 +#ifndef _AIFSTRUC_H
7773 +#define _AIFSTRUC_H
7774 +
7775 +static char *ident_aifstruc = "aacraid_ident aifstruc.h 1.0.6 2000/10/09 Adaptec, Inc.";
7776 +
7777 +#include <protocol.h>
7778 +
7779 +//
7780 +//     Progress report structure definitions
7781 +//
7782 +typedef enum {
7783 +       AifJobStsSuccess = 1,
7784 +       AifJobStsFinished,
7785 +       AifJobStsAborted,
7786 +       AifJobStsFailed,
7787 +       AifJobStsLastReportMarker = 100, // All before mean last report
7788 +       AifJobStsSuspended,
7789 +       AifJobStsRunning
7790 +} _E_AifJobStatus;
7791 +
7792 +#ifdef AAC_32BIT_ENUMS
7793 +typedef        _E_AifJobStatus AifJobStatus;
7794 +#else
7795 +typedef        AAC_UINT32              AifJobStatus;
7796 +#endif
7797 +
7798 +
7799 +typedef enum {
7800 +       AifJobScsiMin = 1,              // Minimum value for Scsi operation
7801 +       AifJobScsiZero,                 // SCSI device clear operation
7802 +       AifJobScsiVerify,               // SCSI device Verify operation NO REPAIR
7803 +       AifJobScsiExercise,             // SCSI device Exercise operation
7804 +       AifJobScsiVerifyRepair, // SCSI device Verify operation WITH repair
7805 +       // Add new SCSI task types above this line
7806 +       AifJobScsiMax = 99,             // Max Scsi value
7807 +       AifJobCtrMin,                   // Min Ctr op value
7808 +       AifJobCtrZero,                  // Container clear operation
7809 +       AifJobCtrCopy,                  // Container copy operation
7810 +       AifJobCtrCreateMirror,  // Container Create Mirror operation
7811 +       AifJobCtrMergeMirror,   // Container Merge Mirror operation
7812 +       AifJobCtrScrubMirror,   // Container Scrub Mirror operation
7813 +       AifJobCtrRebuildRaid5,  // Container Rebuild Raid5 operation
7814 +       AifJobCtrScrubRaid5,    // Container Scrub Raid5 operation
7815 +       AifJobCtrMorph,                 // Container morph operation
7816 +       AifJobCtrPartCopy,              // Container Partition copy operation
7817 +       AifJobCtrRebuildMirror, // Container Rebuild Mirror operation
7818 +       AifJobCtrCrazyCache,            // crazy cache
7819 +       // Add new container task types above this line
7820 +       AifJobCtrMax = 199,             // Max Ctr type operation
7821 +       AifJobFsMin,                    // Min Fs type operation
7822 +       AifJobFsCreate,                 // File System Create operation
7823 +       AifJobFsVerify,                 // File System Verify operation
7824 +       AifJobFsExtend,                 // File System Extend operation
7825 +       // Add new file system task types above this line
7826 +       AifJobFsMax = 299,              // Max Fs type operation
7827 +       // Add new API task types here
7828 +       AifJobApiFormatNTFS,    // Format a drive to NTFS
7829 +       AifJobApiFormatFAT,             // Format a drive to FAT
7830 +       AifJobApiUpdateSnapshot, // update the read/write half of a snapshot
7831 +       AifJobApiFormatFAT32,   // Format a drive to FAT32
7832 +       AifJobApiMax = 399,             // Max API type operation
7833 +       AifJobCtlContinuousCtrVerify,   // Controller operation
7834 +       AifJobCtlMax = 499              // Max Controller type operation
7835 +
7836 +} _E_AifJobType;
7837 +
7838 +#ifdef AAC_32BIT_ENUMS
7839 +typedef        _E_AifJobType   AifJobType;
7840 +#else
7841 +typedef        AAC_UINT32              AifJobType;
7842 +#endif
7843 +
7844 +union SrcContainer {
7845 +       AAC_UINT32 from;
7846 +       AAC_UINT32 master;
7847 +       AAC_UINT32 container;
7848 +};
7849 +
7850 +union DstContainer {
7851 +       AAC_UINT32 to;
7852 +       AAC_UINT32 slave;
7853 +       AAC_UINT32 container;
7854 +};
7855 +
7856 +
7857 +struct AifContainers {
7858 +       union SrcContainer src;
7859 +       union DstContainer dst;
7860 +};
7861 +
7862 +union AifJobClient {
7863 +       
7864 +       struct AifContainers container; // For Container nd file system progress ops;
7865 +       AAC_INT32 scsi_dh;                      // For SCSI progress ops
7866 +};
7867 +
7868 +struct AifJobDesc {
7869 +       AAC_UINT32 jobID;                       // DO NOT FILL IN! Will be filled in by AIF
7870 +       AifJobType type;                // Operation that is being performed
7871 +       union AifJobClient client; // Details
7872 +};
7873 +
7874 +struct AifJobProgressReport {
7875 +       struct AifJobDesc jd;
7876 +       AifJobStatus status;
7877 +       AAC_UINT32 finalTick;
7878 +       AAC_UINT32 currentTick;
7879 +       AAC_UINT32 jobSpecificData1;
7880 +       AAC_UINT32 jobSpecificData2;
7881 +};
7882 +
7883 +//
7884 +//     Notification of events structure definition starts here
7885 +//
7886 +typedef enum {
7887 +       // General application notifies start here
7888 +       AifEnGeneric = 1,                       // Generic notification
7889 +       AifEnTaskComplete,                      // Task has completed
7890 +       AifEnConfigChange,                      // Adapter configuration change occurred
7891 +       AifEnContainerChange,           // Adapter specific container configuration change
7892 +       AifEnDeviceFailure,                     // SCSI device failed
7893 +       AifEnMirrorFailover,            // Mirror failover started
7894 +       AifEnContainerEvent,            // Significant container event
7895 +       AifEnFileSystemChange,          // File system changed
7896 +       AifEnConfigPause,                       // Container pause event
7897 +       AifEnConfigResume,                      // Container resume event
7898 +       AifEnFailoverChange,            // Failover space assignment changed
7899 +       AifEnRAID5RebuildDone,          // RAID5 rebuild finished
7900 +       AifEnEnclosureManagement,       // Enclosure management event
7901 +       AifEnBatteryEvent,                      // Significant NV battery event
7902 +       AifEnAddContainer,                      // A new container was created.
7903 +       AifEnDeleteContainer,           // A container was deleted.
7904 +       AifEnSMARTEvent,            // SMART Event
7905 +       AifEnBatteryNeedsRecond,        // The battery needs reconditioning
7906 +       AifEnClusterEvent,                      // Some cluster event
7907 +       AifEnDiskSetEvent,                      // A disk set event occured.
7908 +       // Add general application notifies above this comment
7909 +       AifDriverNotifyStart=199,       // Notifies for host driver go here
7910 +       // Host driver notifications start here
7911 +       AifDenMorphComplete,            // A morph operation completed
7912 +       AifDenVolumeExtendComplete      // A volume expand operation completed
7913 +       // Add host driver notifications above this comment
7914 +} _E_AifEventNotifyType;
7915 +
7916 +#ifdef AAC_32BIT_ENUMS
7917 +typedef _E_AifEventNotifyType  AifEventNotifyType;
7918 +#else
7919 +typedef        AAC_UINT32                              AifEventNotifyType;
7920 +#endif
7921 +
7922 +struct AifEnsGeneric {
7923 +       AAC_INT8 text[132];                             // Generic text
7924 +};
7925 +
7926 +struct AifEnsDeviceFailure {
7927 +       AAC_INT32 deviceHandle; // SCSI device handle
7928 +};
7929 +
7930 +struct AifEnsMirrorFailover {
7931 +       AAC_UINT32 container;           // Container with failed element
7932 +       AAC_UINT32 failedSlice;         // Old slice which failed
7933 +       AAC_UINT32 creatingSlice;       // New slice used for auto-create
7934 +};
7935 +
7936 +struct AifEnsContainerChange {
7937 +       AAC_UINT32 container[2];                // container that changed, -1 if no container
7938 +};
7939 +
7940 +struct AifEnsContainerEvent {
7941 +       AAC_UINT32 container;           // container number 
7942 +       AAC_UINT32 eventType;           // event type
7943 +};
7944 +
7945 +struct AifEnsEnclosureEvent {
7946 +       AAC_UINT32 empID;                               // enclosure management processor number 
7947 +       AAC_UINT32 unitID;                      // unitId, fan id, power supply id, slot id, tempsensor id. 
7948 +       AAC_UINT32 eventType;           // event type
7949 +};
7950 +
7951 +
7952 +struct AifEnsBatteryEvent {
7953 +       NVBATT_TRANSITION transition_type;      // e.g. from low to ok
7954 +       NVBATTSTATUS current_state;                     // current battery state
7955 +       NVBATTSTATUS prior_state;                       // previous battery state
7956 +};
7957 +
7958 +struct AifEnsDiskSetEvent {
7959 +       AAC_UINT32      eventType;
7960 +       AAC_UINT32      DsNum[2];
7961 +       AAC_UINT32      CreatorId[2];
7962 +};
7963 +
7964 +
7965 +
7966 +typedef enum _CLUSTER_AIF_EVENT {
7967 +       CLUSTER_NULL_EVENT = 0,
7968 +       CLUSTER_PARTNER_NAME_EVENT,             // change in partner hostname or adaptername from NULL to non-NULL
7969 +                                                                       // (partner's agent may be up)
7970 +       CLUSTER_PARTNER_NULL_NAME_EVENT // change in partner hostname or adaptername from non-null to NULL
7971 +                                                                       // (partner has rebooted)
7972 +} _E_CLUSTER_AIF_EVENT;
7973 +
7974 +#ifdef AAC_32BIT_ENUMS
7975 +typedef        _E_CLUSTER_AIF_EVENT    CLUSTER_AIF_EVENT;
7976 +#else
7977 +typedef        AAC_UINT32                              CLUSTER_AIF_EVENT;
7978 +#endif
7979 +
7980 +struct AifEnsClusterEvent {
7981 +       CLUSTER_AIF_EVENT   eventType;
7982 +};
7983 +
7984 +struct AifEventNotify {
7985 +       AifEventNotifyType      type;
7986 +       union {
7987 +               struct AifEnsGeneric            EG;
7988 +               struct AifEnsDeviceFailure      EDF;
7989 +               struct AifEnsMirrorFailover EMF;
7990 +               struct AifEnsContainerChange ECC;
7991 +               struct AifEnsContainerEvent ECE;
7992 +               struct AifEnsEnclosureEvent EEE;
7993 +               struct AifEnsBatteryEvent       EBE;
7994 +               struct AifEnsDiskSetEvent       EDS;
7995 +#ifdef BRIDGE
7996 +               struct AifEnsSMARTEvent ES;
7997 +#endif
7998 +               struct AifEnsClusterEvent ECLE;
7999 +       } data;
8000 +};
8001 +
8002 +//
8003 +//     Generic API structure
8004 +//
8005 +#define AIF_API_REPORT_MAX_SIZE 64
8006 +typedef AAC_INT8 AifApiReport[AIF_API_REPORT_MAX_SIZE];
8007 +
8008 +
8009 +
8010 +//
8011 +//     For FIB communication, we need all of the following things
8012 +//     to send back to the user.
8013 +//
8014 +typedef enum {
8015 +       AifCmdEventNotify = 1,  // Notify of event
8016 +       AifCmdJobProgress,              // Progress report
8017 +       AifCmdAPIReport,                // Report from other user of API
8018 +       AifCmdDriverNotify,             // Notify host driver of event
8019 +       AifReqJobList = 100,    // Gets back complete job list
8020 +       AifReqJobsForCtr,               // Gets back jobs for specific container
8021 +       AifReqJobsForScsi,              // Gets back jobs for specific SCSI device
8022 +       AifReqJobReport,                // Gets back a specific job report or list of them
8023 +       AifReqTerminateJob,             // Terminates job
8024 +       AifReqSuspendJob,               // Suspends a job
8025 +       AifReqResumeJob,                // Resumes a job
8026 +       AifReqSendAPIReport,    // API generic report requests
8027 +       AifReqAPIJobStart,              // Start a job from the API
8028 +       AifReqAPIJobUpdate,             // Update a job report from the API
8029 +       AifReqAPIJobFinish              // Finish a job from the API
8030 +} _E_AIFCOMMAND;
8031 +
8032 +#ifdef AAC_32BIT_ENUMS
8033 +typedef _E_AIFCOMMAND  AIFCOMMAND;
8034 +#else
8035 +typedef        AAC_UINT32              AIFCOMMAND;
8036 +#endif
8037 +
8038 +
8039 +
8040 +//
8041 +//     Adapter Initiated FIB command structures. Start with the adapter
8042 +//     initiated FIBs that really come from the adapter, and get responded
8043 +//     to by the host.
8044 +//
8045 +typedef struct _AIFCOMMANDTOHOST {
8046 +       AIFCOMMAND command;                     // Tell host what type of notify this is
8047 +       AAC_UINT32 seqNumber;   // To allow ordering of reports (if necessary)
8048 +       union {
8049 +               // First define data going to the adapter
8050 +               struct AifEventNotify EN;       // Event notify structure
8051 +               struct AifJobProgressReport PR[1]; // Progress report
8052 +               AifApiReport AR;
8053 +       } data;
8054 +} AIFCOMMANDTOHOST, *PAIFCOMMANDTOHOST;
8055 +
8056 +
8057 +#endif // _AIFSTRUC_H
8058 +
8059 +
8060 +
8061 diff -urN linux/drivers/scsi/aacraid/include/build_number.h linux/drivers/scsi/aacraid/include/build_number.h
8062 --- linux/drivers/scsi/aacraid/include/build_number.h   Wed Dec 31 19:00:00 1969
8063 +++ linux/drivers/scsi/aacraid/include/build_number.h   Thu Dec 21 13:14:30 2000
8064 @@ -0,0 +1,39 @@
8065 +/*++
8066 + * Adaptec aacraid device driver for Linux.
8067 + *
8068 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8069 + *
8070 + * This program is free software; you can redistribute it and/or modify
8071 + * it under the terms of the GNU General Public License as published by
8072 + * the Free Software Foundation; either version 2, or (at your option)
8073 + * any later version.
8074 + *
8075 + * This program is distributed in the hope that it will be useful,
8076 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8077 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
8078 + * GNU General Public License for more details.
8079 + *
8080 + * You should have received a copy of the GNU General Public License
8081 + * along with this program; see the file COPYING.  If not, write to
8082 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8083 + *
8084 + * Module Name:
8085 + *   build_number.h
8086 + *
8087 + * Abstract:
8088 + *   DThis module contains the single location where the build number
8089 + *   is kept.
8090 + *
8091 + *
8092 + *
8093 + --*/
8094 +#ifndef _BUILD_NUMBER_H 
8095 +#define _BUILD_NUMBER_H 
8096 +
8097 +static char *ident_build_num = "aacraid_ident build_number.h 1.0.6 2000/10/09 Adaptec, Inc.";
8098 +
8099 +#define REV_BUILD_NUMBER 3911 
8100 +
8101 +
8102 +#endif  // _BUILD_NUMBER_H 
8103 +
8104 diff -urN linux/drivers/scsi/aacraid/include/commdata.h linux/drivers/scsi/aacraid/include/commdata.h
8105 --- linux/drivers/scsi/aacraid/include/commdata.h       Wed Dec 31 19:00:00 1969
8106 +++ linux/drivers/scsi/aacraid/include/commdata.h       Thu Dec 21 13:14:30 2000
8107 @@ -0,0 +1,112 @@
8108 +/*++
8109 + * Adaptec aacraid device driver for Linux.
8110 + *
8111 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8112 + *
8113 + * This program is free software; you can redistribute it and/or modify
8114 + * it under the terms of the GNU General Public License as published by
8115 + * the Free Software Foundation; either version 2, or (at your option)
8116 + * any later version.
8117 + *
8118 + * This program is distributed in the hope that it will be useful,
8119 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8120 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
8121 + * GNU General Public License for more details.
8122 + *
8123 + * You should have received a copy of the GNU General Public License
8124 + * along with this program; see the file COPYING.  If not, write to
8125 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8126 + *
8127 + * Module Name:
8128 + *   commdata.h
8129 + *
8130 + * Abstract: Define the communication layer of the adapter
8131 + *
8132 + *
8133 + *
8134 + --*/
8135 +#ifndef _COMMDATA_
8136 +#define _COMMDATA_
8137 +
8138 +static char *ident_commdata = "aacraid_ident commdata.h 1.0.6 2000/10/09 Adaptec, Inc.";
8139 +
8140 +typedef struct _FSA_COMM_DATA {
8141 +  
8142 +  //
8143 +  //  A pointer to the Driver and Device object we were initialized with
8144 +  //
8145 +  
8146 +  PDRIVER_OBJECT DriverObject;
8147 +  PDEVICE_OBJECT DeviceObject;
8148 +  
8149 +  //
8150 +  // A list of all adapters we have configured.
8151 +  // 
8152 +  
8153 +  PAFA_COMM_ADAPTER AdapterList;
8154 +  ULONG                  TotalAdapters;
8155 +  
8156 +  //
8157 +  // Adapter timeout support. This is the default timeout to wait for the
8158 +  // adapter to respond(setup in initfs.c), and a boolean to indicate if
8159 +  // we should timeout requests to the adapter or not.
8160 +  //
8161 +
8162 +  LARGE_INTEGER QueueFreeTimeout;
8163 +  LARGE_INTEGER AdapterTimeout;
8164 +  BOOLEAN EnableAdapterTimeouts;
8165 +
8166 +  ULONG        FibTimeoutIncrement;
8167 +  
8168 +  ULONG FibsSent;
8169 +  ULONG FibRecved;
8170 +  ULONG NoResponseSent;
8171 +  ULONG NoResponseRecved;
8172 +  ULONG AsyncSent;
8173 +  ULONG AsyncRecved;
8174 +  ULONG NormalSent;
8175 +  ULONG NormalRecved;
8176 +  
8177 +  ULONG TimedOutFibs;
8178 +  
8179 +  KDPC         TimeoutDPC;
8180 +  KTIMER       TimeoutTimer;
8181 +  
8182 +  // 
8183 +  // If this value is set to 1 then interrupt moderation will occur 
8184 +  // in the base commuication support.
8185 +  //
8186 +
8187 +  ULONG EnableInterruptModeration;
8188 +
8189 +  int HardInterruptModeration;
8190 +  int HardInterruptModeration1;
8191 +  int PeakFibsConsumed;
8192 +  int ZeroFibsConsumed;
8193 +  int EnableFibTimeoutBreak;
8194 +  ULONG FibTimeoutSeconds;
8195 +  
8196 +  //
8197 +  // The following holds all of the available user settable variables.
8198 +  // This includes all for the comm layer as well as any from the class
8199 +  // drivers as well.
8200 +  //
8201 +  
8202 +  FSA_USER_VAR *UserVars;
8203 +  ULONG                        NumUserVars;
8204 +  
8205 +  
8206 +  ULONG           MeterFlag;
8207 +  
8208 +#ifdef FIB_CHECKSUMS
8209 +  int do_fib_checksums;
8210 +#endif
8211 +  
8212 +} FSA_COMM_DATA;
8213 +typedef FSA_COMM_DATA *PFSA_COMM_DATA;
8214 +
8215 +extern FSA_COMM_DATA FsaCommData;
8216 +
8217 +
8218 +#endif // _COMMDATA_
8219 +
8220 diff -urN linux/drivers/scsi/aacraid/include/commerr.h linux/drivers/scsi/aacraid/include/commerr.h
8221 --- linux/drivers/scsi/aacraid/include/commerr.h        Wed Dec 31 19:00:00 1969
8222 +++ linux/drivers/scsi/aacraid/include/commerr.h        Thu Dec 21 13:14:30 2000
8223 @@ -0,0 +1,125 @@
8224 +/*++
8225 + * Adaptec aacraid device driver for Linux.
8226 + *
8227 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8228 + *
8229 + * This program is free software; you can redistribute it and/or modify
8230 + * it under the terms of the GNU General Public License as published by
8231 + * the Free Software Foundation; either version 2, or (at your option)
8232 + * any later version.
8233 + *
8234 + * This program is distributed in the hope that it will be useful,
8235 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8236 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
8237 + * GNU General Public License for more details.
8238 + *
8239 + * You should have received a copy of the GNU General Public License
8240 + * along with this program; see the file COPYING.  If not, write to
8241 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8242 + *
8243 + * Module Name:
8244 + *   commerr.h
8245 + *
8246 + * Abstract: This file defines all errors that are unique to the Adaptec Fsa Filesystem
8247 + *
8248 + *
8249 + *
8250 + --*/
8251 +
8252 +#ifndef _FSAERR_
8253 +#define _FSAERR_
8254 +
8255 +static char *ident_commerr = "aacraid_ident commerr.h 1.0.6 2000/10/09 Adaptec, Inc.";
8256 +
8257 +//
8258 +//  Note: comments in the .mc file must use both ";" and "//".
8259 +//
8260 +//  Status values are 32 bit values layed out as follows:
8261 +//
8262 +//   3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
8263 +//   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
8264 +//  +---+-+-------------------------+-------------------------------+
8265 +//  |Sev|C|       Facility          |               Code            |
8266 +//  +---+-+-------------------------+-------------------------------+
8267 +//
8268 +//  where
8269 +//
8270 +//      Sev - is the severity code
8271 +//
8272 +//          00 - Success
8273 +//          01 - Informational
8274 +//          10 - Warning
8275 +//          11 - Error
8276 +//
8277 +//      C - is the Customer code flag
8278 +//
8279 +//      Facility - is the facility code
8280 +//
8281 +//      Code - is the facility's status code
8282 +//
8283 +
8284 +
8285 +//
8286 +// %1 is reserved by the IO Manager. If IoAllocateErrorLogEntry is
8287 +// called with a device, the name of the device will be inserted into
8288 +// the message at %1. Otherwise, the place of %1 will be left empty.
8289 +// In either case, the insertion strings from the driver's error log
8290 +// entry starts at %2. In other words, the first insertion string goes
8291 +// to %2, the second to %3 and so on.
8292 +//
8293 +
8294 +//
8295 +//  Values are 32 bit values layed out as follows:
8296 +//
8297 +//   3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
8298 +//   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
8299 +//  +---+-+-+-----------------------+-------------------------------+
8300 +//  |Sev|C|R|     Facility          |               Code            |
8301 +//  +---+-+-+-----------------------+-------------------------------+
8302 +//
8303 +//  where
8304 +//
8305 +//      Sev - is the severity code
8306 +//
8307 +//          00 - Success
8308 +//          01 - Informational
8309 +//          10 - Warning
8310 +//          11 - Error
8311 +//
8312 +//      C - is the Customer code flag
8313 +//
8314 +//      R - is a reserved bit
8315 +//
8316 +//      Facility - is the facility code
8317 +//
8318 +//      Code - is the facility's status code
8319 +//
8320 +//
8321 +// Define the facility codes
8322 +//
8323 +
8324 +
8325 +#define FACILITY_FSAFS_ERROR_CODE        0x7
8326 +
8327 +
8328 +
8329 +//
8330 +// MessageId: FSAFS_FIB_INVALID
8331 +//
8332 +// MessageText:
8333 +//
8334 +//  A communication packet was detected to be formatted poorly. Please Contact Adaptec support.
8335 +//
8336 +#define FSAFS_FIB_INVALID                ((AAC_STATUS)0xE0070009L)
8337 +
8338 +
8339 +//
8340 +// MessageId: FSAFS_TIMED_OUT_FIB_COMPLETED
8341 +//
8342 +// MessageText:
8343 +//
8344 +//  A Fib previously timed out by host has been completed by the adapter. (\\.\Afa%2)
8345 +//
8346 +#define FSAFS_TIMED_OUT_FIB_COMPLETED    ((AAC_STATUS)0xA007000EL)
8347 +
8348 +#endif _FSAERR_
8349 diff -urN linux/drivers/scsi/aacraid/include/commfibcontext.h linux/drivers/scsi/aacraid/include/commfibcontext.h
8350 --- linux/drivers/scsi/aacraid/include/commfibcontext.h Wed Dec 31 19:00:00 1969
8351 +++ linux/drivers/scsi/aacraid/include/commfibcontext.h Thu Dec 21 13:14:30 2000
8352 @@ -0,0 +1,98 @@
8353 +/*++
8354 + * Adaptec aacraid device driver for Linux.
8355 + *
8356 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8357 + *
8358 + * This program is free software; you can redistribute it and/or modify
8359 + * it under the terms of the GNU General Public License as published by
8360 + * the Free Software Foundation; either version 2, or (at your option)
8361 + * any later version.
8362 + *
8363 + * This program is distributed in the hope that it will be useful,
8364 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8365 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
8366 + * GNU General Public License for more details.
8367 + *
8368 + * You should have received a copy of the GNU General Public License
8369 + * along with this program; see the file COPYING.  If not, write to
8370 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8371 + *
8372 + * Module Name:
8373 + *   commfibcontext.h
8374 + *
8375 + * Abstract: defines the _COMM_FIB_CONTEXT strcuture
8376 + *
8377 + *
8378 + *
8379 + --*/
8380 +#ifndef _COMM_FIB_CONTEXT_
8381 +#define _COMM_FIB_CONTEXT_
8382 +
8383 +static char *ident_commfib = "aacraid_ident commfibcontext.h 1.0.6 2000/10/09 Adaptec, Inc.";
8384 +
8385 +typedef struct _COMM_FIB_CONTEXT {
8386 +
8387 +       PVOID           Next;   // this is used by the zone allocation
8388 +
8389 +    //
8390 +    //  Type and size of this record (must be FSA_NTC_FIB_CONTEXT)
8391 +    //
8392 +    //  NOTE:  THIS STRUCTURE MUST REMAIN 64-bit ALIGNED IN SIZE, SINCE
8393 +    //         IT IS ZONE ALLOCATED, AND REPINNED_BCBS_ARRAY_SIZE AFFECTS
8394 +    //         ITS SIZE.
8395 +    //
8396 +
8397 +    NODE_TYPE_CODE NodeTypeCode;
8398 +    NODE_BYTE_SIZE NodeByteSize;
8399 +
8400 +       //
8401 +       //      The Adapter that this I/O is destined for.
8402 +       //
8403 +
8404 +       PAFA_COMM_ADAPTER Adapter;
8405 +
8406 +    PHYSICAL_ADDRESS LogicalFibAddress;
8407 +
8408 +    //
8409 +    // This is the event the sendfib routine will wait on if the
8410 +    // caller did not pass one and this is synch io.
8411 +    //
8412 +
8413 +  OS_CV_T      FsaEvent;
8414 +       OS_CVLOCK       *FsaEventMutex;
8415 +
8416 +       ULONG   FibComplete;    // gets set to 1 when fib is complete
8417 +    
8418 +       PFIB_CALLBACK FibCallback;
8419 +       PVOID FibCallbackContext;
8420 +
8421 +       ULONG   Flags;
8422 +
8423 +
8424 +#ifdef GATHER_FIB_TIMES
8425 +       LARGE_INTEGER   FibTimeStamp;
8426 +       PFIB_TIMES              FibTimesPtr;
8427 +#endif
8428 +
8429 +       //
8430 +       // The following is used to put this fib context onto the Outstanding I/O queue.
8431 +       //
8432 +               
8433 +       LIST_ENTRY      QueueEntry;     
8434 +
8435 +       //
8436 +       // The following is used to timeout a fib to the adapter.
8437 +       //
8438 +
8439 +       LARGE_INTEGER   TimeoutValue;
8440 +
8441 +       PVOID   FibData;
8442 +
8443 +    PFIB Fib;
8444 +
8445 +} COMM_FIB_CONTEXT;
8446 +typedef COMM_FIB_CONTEXT *PCOMM_FIB_CONTEXT;
8447 +
8448 +#define FIB_CONTEXT_FLAG_TIMED_OUT             (0x00000001)
8449 +
8450 +#endif /* _COMM_FIB_CONTEXT_ */
8451 diff -urN linux/drivers/scsi/aacraid/include/comprocs.h linux/drivers/scsi/aacraid/include/comprocs.h
8452 --- linux/drivers/scsi/aacraid/include/comprocs.h       Wed Dec 31 19:00:00 1969
8453 +++ linux/drivers/scsi/aacraid/include/comprocs.h       Thu Dec 21 13:14:30 2000
8454 @@ -0,0 +1,93 @@
8455 +/*++
8456 + * Adaptec aacraid device driver for Linux.
8457 + *
8458 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8459 + *
8460 + * This program is free software; you can redistribute it and/or modify
8461 + * it under the terms of the GNU General Public License as published by
8462 + * the Free Software Foundation; either version 2, or (at your option)
8463 + * any later version.
8464 + *
8465 + * This program is distributed in the hope that it will be useful,
8466 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8467 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
8468 + * GNU General Public License for more details.
8469 + *
8470 + * You should have received a copy of the GNU General Public License
8471 + * along with this program; see the file COPYING.  If not, write to
8472 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8473 + *
8474 + * Module Name:
8475 + *   comprocs.h
8476 + *
8477 + * Abstract: This module defines all of the globally used procedures in the Afa comm layer
8478 + *
8479 + *
8480 + *
8481 + --*/
8482 +#ifndef _COMPROCS_
8483 +#define _COMPROCS_
8484 +
8485 +static char *ident_comproc = "aacraid_ident comprocs.h 1.0.6 2000/10/09 Adaptec, Inc.";
8486 +
8487 +#include "osheaders.h"
8488 +
8489 +#include "AacGenericTypes.h"
8490 +
8491 +#include "aac_unix_defs.h"
8492 +
8493 +#include "nodetype.h"
8494 +
8495 +// #define GATHER_FIB_TIMES
8496 +
8497 +#include "fsatypes.h"
8498 +
8499 +#include "perfpack.h"
8500 +
8501 +#include "comstruc.h"
8502 +
8503 +//#include "unix_protocol.h"
8504 +
8505 +#include "fsact.h"
8506 +
8507 +#include "protocol.h"
8508 +
8509 +#include "fsaioctl.h"
8510 +
8511 +#undef GATHER_FIB_TIMES
8512 +
8513 +#include "aifstruc.h"
8514 +
8515 +#include "fsaport.h"
8516 +#include "comsup.h"
8517 +#include "afacomm.h"
8518 +#include "adapter.h"
8519 +
8520 +#include "commfibcontext.h"
8521 +#include "comproto.h"
8522 +#include "commdata.h"
8523 +#include "commerr.h"
8524 +
8525 +
8526 +
8527 +
8528 +//
8529 +// The following macro is used when sending and receiving FIBs.  It is only used for
8530 +// debugging.
8531 +
8532 +#if DBG
8533 +#define        FIB_COUNTER_INCREMENT(Counter)          InterlockedIncrement(&(Counter))
8534 +#else
8535 +#define        FIB_COUNTER_INCREMENT(Counter)          
8536 +#endif
8537 +
8538 +
8539 +
8540 +int
8541 +AfaCommAdapterDeviceControl (
8542 +       IN PVOID AdapterArg,
8543 +       IN PAFA_IOCTL_CMD       IoctlCmdPtr
8544 +       );
8545 +
8546 +
8547 +#endif // _COMPROCS_
8548 diff -urN linux/drivers/scsi/aacraid/include/comproto.h linux/drivers/scsi/aacraid/include/comproto.h
8549 --- linux/drivers/scsi/aacraid/include/comproto.h       Wed Dec 31 19:00:00 1969
8550 +++ linux/drivers/scsi/aacraid/include/comproto.h       Thu Dec 21 13:14:30 2000
8551 @@ -0,0 +1,170 @@
8552 +/*++
8553 + * Adaptec aacraid device driver for Linux.
8554 + *
8555 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8556 + *
8557 + * This program is free software; you can redistribute it and/or modify
8558 + * it under the terms of the GNU General Public License as published by
8559 + * the Free Software Foundation; either version 2, or (at your option)
8560 + * any later version.
8561 + *
8562 + * This program is distributed in the hope that it will be useful,
8563 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8564 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
8565 + * GNU General Public License for more details.
8566 + *
8567 + * You should have received a copy of the GNU General Public License
8568 + * along with this program; see the file COPYING.  If not, write to
8569 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8570 + *
8571 + * Module Name:
8572 + *   comproto.h
8573 + *
8574 + * Abstract: Global routines for the commuication interface that are device
8575 + *           independant.
8576 + *
8577 + *
8578 + *
8579 + --*/
8580 +#ifndef _COMM_PROTO
8581 +#define _COMM_PROTO
8582 +
8583 +static char *ident_comproto = "aacraid_ident comproto.h 1.0.6 2000/10/09 Adaptec, Inc.";
8584 +
8585 +//
8586 +// define the routines we need so we can commuicate with the
8587 +// fsa adapter
8588 +//
8589 +
8590 +//
8591 +// The following 4 dpc routines will support commuication from the adapter to the
8592 +// host. There is one DPC routine to deal with each type of queue that supports
8593 +// commuication from the adapter. (adapter to host resposes, adapter to host commands)
8594 +// These routines will simply pull off the QE and set an event. In the case of a
8595 +// adapter to host command they will also put the FIB on a queue to be processed by
8596 +// a FS thread running at passive level.
8597 +//
8598 +
8599 +// Handle queue not full notification to the file system thread waiting for a queue entry
8600 +
8601 +u_int
8602 +CommonNotFullDpc(
8603 +       IN PCOMM_REGION CommRegion
8604 +    );
8605 +
8606 +// Adapter to host normal priority responses
8607 +
8608 +u_int
8609 +HostResponseNormalDpc(
8610 +    IN PCOMM_QUE OurQueue
8611 +    );
8612 +
8613 +// Adapter to host high priority responses
8614 +u_int
8615 +HostResponseHighDpc(
8616 +    IN PCOMM_QUE OurQueue
8617 +    );
8618 +
8619 +// Adapter to host high priority commands
8620 +u_int
8621 +HostCommandHighDpc(
8622 +    IN PCOMM_QUE OurQueue
8623 +    );
8624 +    
8625 +
8626 +// Adapter to host normal priority commands
8627 +u_int
8628 +HostCommandNormDpc(
8629 +    IN PCOMM_QUE OurQueue
8630 +    );
8631 +
8632 +
8633 +
8634 +BOOLEAN
8635 +SendSynchFib(
8636 +       PVOID                   Arg,
8637 +       FIB_COMMAND     Command,
8638 +       PVOID                   Data,
8639 +       USHORT                  Size,
8640 +       PVOID                   Response,
8641 +       USHORT                  *ResponseSize
8642 +       );
8643 +
8644 +PFIB_CONTEXT
8645 +AllocateFib (
8646 +       IN PVOID Adapter
8647 +    );
8648 +
8649 +VOID
8650 +FreeFib (
8651 +    IN PFIB_CONTEXT FibContext
8652 +    );
8653 +
8654 +VOID
8655 +FreeFibFromDpc(
8656 +    IN PFIB_CONTEXT FibContext
8657 +    );
8658 +
8659 +AAC_STATUS
8660 +DeallocateFib(
8661 +    IN PFIB_CONTEXT FibContext
8662 +    );
8663 +
8664 +
8665 +
8666 +AAC_STATUS
8667 +SendFib(
8668 +    IN FIB_COMMAND Command, 
8669 +       IN PFIB_CONTEXT FibContext,
8670 +    IN ULONG Size,
8671 +    IN COMM_PRIORITIES Priority,
8672 +    IN BOOLEAN Wait,
8673 +    IN PVOID WaitOn,
8674 +    IN BOOLEAN ResponseExpected,
8675 +       IN PFIB_CALLBACK FibCallback,
8676 +       IN PVOID FibCallbackContext
8677 +    );
8678 +
8679 +AAC_STATUS
8680 +CompleteFib(
8681 +       IN PFIB_CONTEXT FibContext
8682 +    );
8683 +
8684 +AAC_STATUS
8685 +CompleteAdapterFib(
8686 +       IN PFIB_CONTEXT FibContext,
8687 +    IN USHORT Size
8688 +    );
8689 +
8690 +AAC_STATUS
8691 +InitializeFib(
8692 +       IN PFIB_CONTEXT FibContext
8693 +    );
8694 +
8695 +
8696 +PVOID
8697 +FsaGetFibData(
8698 +       IN PFIB_CONTEXT FibContext
8699 +       );
8700 +
8701 +
8702 +
8703 +AAC_STATUS
8704 +AfaCommOpenAdapter (
8705 +       IN PVOID AdapterArg
8706 +       );
8707 +
8708 +AAC_STATUS
8709 +AfaCommCloseAdapter (
8710 +       IN PVOID AdapterArg
8711 +       );
8712 +
8713 +
8714 +VOID
8715 +AfaCommInterruptHost(
8716 +       PVOID   Adapter,
8717 +       ADAPTER_EVENT   AdapterEvent
8718 +       );
8719 +
8720 +
8721 +#endif // _COMM_PROTO
8722 diff -urN linux/drivers/scsi/aacraid/include/comstruc.h linux/drivers/scsi/aacraid/include/comstruc.h
8723 --- linux/drivers/scsi/aacraid/include/comstruc.h       Wed Dec 31 19:00:00 1969
8724 +++ linux/drivers/scsi/aacraid/include/comstruc.h       Thu Dec 21 13:14:30 2000
8725 @@ -0,0 +1,435 @@
8726 +/*++
8727 + * Adaptec aacraid device driver for Linux.
8728 + *
8729 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8730 + *
8731 + * This program is free software; you can redistribute it and/or modify
8732 + * it under the terms of the GNU General Public License as published by
8733 + * the Free Software Foundation; either version 2, or (at your option)
8734 + * any later version.
8735 + *
8736 + * This program is distributed in the hope that it will be useful,
8737 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8738 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
8739 + * GNU General Public License for more details.
8740 + *
8741 + * You should have received a copy of the GNU General Public License
8742 + * along with this program; see the file COPYING.  If not, write to
8743 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8744 + *
8745 + * Module Name:
8746 + *   comstruc.h
8747 + *
8748 + * Abstract: This module defines the data structures that make up the communication
8749 + *           region for the FSA filesystem. This region is how the host based code
8750 + *           communicates both control and data to the adapter based code.
8751 + *
8752 + *
8753 + *
8754 + --*/
8755 +#ifndef _COMM_STRUCT
8756 +#define _COMM_STRUCT
8757 +
8758 +static char *ident_comstruc = "aacraid_ident comstruc.h 1.0.7 2000/10/11 Adaptec, Inc.";
8759 +
8760 +//
8761 +// Define all the constants needed for the communication interface
8762 +//
8763 +
8764 +// Define how many queue entries each queue will have and the total number of
8765 +// entries for the entire communication interface. Also define how many queues
8766 +// we support.
8767 +
8768 +#define NUMBER_OF_COMM_QUEUES  8   // 4 command; 4 response
8769 +#define HOST_HIGH_CMD_ENTRIES  4
8770 +#define HOST_NORM_CMD_ENTRIES  8
8771 +#define ADAP_HIGH_CMD_ENTRIES  4
8772 +#define ADAP_NORM_CMD_ENTRIES  512
8773 +#define HOST_HIGH_RESP_ENTRIES 4
8774 +#define HOST_NORM_RESP_ENTRIES 512
8775 +#define ADAP_HIGH_RESP_ENTRIES 4
8776 +#define ADAP_NORM_RESP_ENTRIES 8
8777 +
8778 +#define TOTAL_QUEUE_ENTRIES  \
8779 +    (HOST_NORM_CMD_ENTRIES + HOST_HIGH_CMD_ENTRIES + ADAP_NORM_CMD_ENTRIES + ADAP_HIGH_CMD_ENTRIES + \
8780 +           HOST_NORM_RESP_ENTRIES + HOST_HIGH_RESP_ENTRIES + ADAP_NORM_RESP_ENTRIES + ADAP_HIGH_RESP_ENTRIES)
8781 +
8782 +
8783 +
8784 +
8785 +// Set the queues on a 16 byte alignment
8786 +#define QUEUE_ALIGNMENT                16
8787 +
8788 +
8789 +//
8790 +// The queue headers define the Communication Region queues. These
8791 +// are physically contiguous and accessible by both the adapter and the
8792 +// host. Even though all queue headers are in the same contiguous block they will be
8793 +// represented as individual units in the data structures.
8794 +//
8795 +
8796 +typedef AAC_UINT32 QUEUE_INDEX;
8797 +
8798 +typedef QUEUE_INDEX *PQUEUE_INDEX;
8799 +
8800 +typedef struct _QUEUE_ENTRY {
8801 +
8802 +    AAC_UINT32 Size;                     // Size in bytes of the Fib which this QE points to
8803 +    AAC_UINT32 FibAddress;             // Receiver addressable address of the FIB (low 32 address bits)
8804 +
8805 +} QUEUE_ENTRY;
8806 +
8807 +typedef QUEUE_ENTRY *PQUEUE_ENTRY;
8808 +
8809 +
8810 +
8811 +// The adapter assumes the ProducerIndex and ConsumerIndex are grouped
8812 +// adjacently and in that order.
8813 +//
8814 +typedef struct _QUEUE_HEADERS {
8815 +
8816 +    PHYSICAL_ADDRESS LogicalHeaderAddress;  // Address to hand the adapter to access to this queue head
8817 +    PQUEUE_INDEX ProducerIndex;              // The producer index for this queue (host address)
8818 +    PQUEUE_INDEX ConsumerIndex;              // The consumer index for this queue (host address)
8819 +
8820 +} QUEUE_HEADERS;
8821 +typedef QUEUE_HEADERS *PQUEUE_HEADERS;
8822 +
8823 +//
8824 +// Define all the events which the adapter would like to notify
8825 +// the host of.
8826 +//
8827 +typedef enum _ADAPTER_EVENT {
8828 +    HostNormCmdQue = 1,         // Change in host normal priority command queue
8829 +    HostHighCmdQue,             // Change in host high priority command queue
8830 +    HostNormRespQue,            // Change in host normal priority response queue
8831 +    HostHighRespQue,            // Change in host high priority response queue
8832 +    AdapNormRespNotFull,
8833 +    AdapHighRespNotFull,
8834 +    AdapNormCmdNotFull,
8835 +    AdapHighCmdNotFull,
8836 +       SynchCommandComplete,
8837 +    AdapInternalError = 0xfe    // The adapter detected an internal error shutting down
8838 +
8839 +} _E_ADAPTER_EVENT;
8840 +
8841 +#ifdef AAC_32BIT_ENUMS
8842 +typedef _E_ADAPTER_EVENT       ADAPTER_EVENT;
8843 +#else
8844 +typedef AAC_UINT32                     ADAPTER_EVENT;
8845 +#endif
8846 +
8847 +//
8848 +// Define all the events the host wishes to notify the
8849 +// adapter of.
8850 +//
8851 +typedef enum _HOST_2_ADAP_EVENT {
8852 +    AdapNormCmdQue = 1,
8853 +    AdapHighCmdQue,
8854 +    AdapNormRespQue,
8855 +    AdapHighRespQue,
8856 +    HostShutdown,
8857 +    HostPowerFail,
8858 +    FatalCommError,
8859 +    HostNormRespNotFull,
8860 +    HostHighRespNotFull,
8861 +    HostNormCmdNotFull,
8862 +    HostHighCmdNotFull,
8863 +       FastIo,
8864 +       AdapPrintfDone
8865 +} _E_HOST_2_ADAP_EVENT;
8866 +
8867 +#ifdef AAC_32BIT_ENUMS
8868 +typedef _E_HOST_2_ADAP_EVENT   HOST_2_ADAP_EVENT;
8869 +#else
8870 +typedef        AAC_UINT32                              HOST_2_ADAP_EVENT;
8871 +#endif
8872 +
8873 +//
8874 +// Define all the queues that the adapter and host use to communicate
8875 +//
8876 +
8877 +typedef enum _QUEUE_TYPES {
8878 +        HostNormCmdQueue = 1,       // Adapter to host normal priority command traffic
8879 +        HostHighCmdQueue,           // Adapter to host high priority command traffic
8880 +        AdapNormRespQueue,          // Host to adapter normal priority response traffic
8881 +        AdapHighRespQueue,          // Host to adapter high priority response traffic
8882 +        AdapNormCmdQueue,           // Host to adapter normal priority command traffic
8883 +        AdapHighCmdQueue,           // Host to adapter high priority command traffic
8884 +        HostNormRespQueue,          // Adapter to host normal priority response traffic
8885 +        HostHighRespQueue           // Adapter to host high priority response traffic
8886 +} _E_QUEUE_TYPES;
8887 +
8888 +#ifdef AAC_32BIT_ENUMS
8889 +typedef _E_QUEUE_TYPES         QUEUE_TYPES;
8890 +#else
8891 +typedef        AAC_UINT32                      QUEUE_TYPES;
8892 +#endif
8893 +
8894 +
8895 +//
8896 +// Assign type values to the FSA communication data structures
8897 +//
8898 +
8899 +typedef enum _STRUCT_TYPES {
8900 +    TFib = 1,
8901 +    TQe,
8902 +       TCtPerf
8903 +} _E_STRUCT_TYPES;
8904 +
8905 +#ifdef AAC_32BIT_ENUMS
8906 +typedef        _E_STRUCT_TYPES STRUCT_TYPES;
8907 +#else
8908 +typedef        AAC_UINT32              STRUCT_TYPES;
8909 +#endif
8910 +
8911 +//
8912 +// Define the priority levels the FSA communication routines support.
8913 +//
8914 +
8915 +typedef enum _COMM_PRIORITIES {
8916 +    FsaNormal = 1,
8917 +    FsaHigh
8918 +} _E_COMM_PRIORITIES;
8919 +
8920 +#ifdef AAC_32BIT_ENUMS
8921 +typedef _E_COMM_PRIORITIES     COMM_PRIORITIES;
8922 +#else
8923 +typedef        AAC_UINT32                      COMM_PRIORITIES;
8924 +#endif
8925 +
8926 +
8927 +
8928 +//
8929 +// Define the LIST_ENTRY structure.  This structure is used on the NT side to link
8930 +// the FIBs together in a linked list.  Since this structure gets compiled on the adapter
8931 +// as well, we need to define this structure for the adapter's use.  If '_NT_DEF_'
8932 +// is defined, then this header is being included from the NT side, and therefore LIST_ENTRY
8933 +// is already defined.
8934 +#if !defined(_NTDEF_) && !defined(_WINNT_)
8935 +typedef struct _LIST_ENTRY {
8936 +   struct _LIST_ENTRY *Flink;
8937 +   struct _LIST_ENTRY *Blink;
8938 +} LIST_ENTRY;
8939 +typedef LIST_ENTRY *PLIST_ENTRY;
8940 +#endif
8941 +
8942 +
8943 +//
8944 +// Define the FIB. The FIB is the where all the requested data and
8945 +// command information are put to the application on the FSA adapter.
8946 +//
8947 +
8948 +typedef struct _FIB_HEADER {
8949 +    AAC_UINT32 XferState;                    // Current transfer state for this CCB
8950 +    AAC_UINT16 Command;                     // Routing information for the destination
8951 +    AAC_UINT8 StructType;                   // Type FIB
8952 +       AAC_UINT8 Flags;                                                  // Flags for FIB
8953 +    AAC_UINT16 Size;                        // Size of this FIB in bytes
8954 +    AAC_UINT16 SenderSize;                  // Size of the FIB in the sender (for response sizing)
8955 +    AAC_UINT32 SenderFibAddress;               // Host defined data in the FIB
8956 +    AAC_UINT32 ReceiverFibAddress;             // Logical address of this FIB for the adapter
8957 +    AAC_UINT32 SenderData;                     // Place holder for the sender to store data
8958 +#ifndef __midl
8959 +       union {
8960 +               struct {
8961 +                   AAC_UINT32 _ReceiverTimeStart;      // Timestamp for receipt of fib
8962 +                   AAC_UINT32 _ReceiverTimeDone;       // Timestamp for completion of fib
8963 +               } _s;
8964 +               LIST_ENTRY _FibLinks;                   // Used to link Adapter Initiated Fibs on the host
8965 +       } _u;
8966 +#else                          // The MIDL compiler does not support unions without a discriminant.
8967 +       struct {                // Since nothing during the midl compile actually looks into this
8968 +               struct {        // structure, this shoudl be ok.
8969 +                       AAC_UINT32 _ReceiverTimeStart;  // Timestamp for receipt of fib
8970 +                   AAC_UINT32 _ReceiverTimeDone;       // Timestamp for completion of fib
8971 +               } _s;
8972 +       } _u;
8973 +#endif
8974 +} FIB_HEADER;
8975 +
8976 +
8977 +#define FibLinks                       _u._FibLinks
8978 +
8979 +
8980 +#define FIB_DATA_SIZE_IN_BYTES (512 - sizeof(FIB_HEADER))
8981 +
8982 +
8983 +typedef struct _FIB {
8984 +
8985 +#ifdef BRIDGE //rma
8986 +       DLQUE link;
8987 +#endif
8988 +    FIB_HEADER Header;
8989 +
8990 +    AAC_UINT8 data[FIB_DATA_SIZE_IN_BYTES];            // Command specific data
8991 +
8992 +} FIB;
8993 +typedef FIB *PFIB;
8994 +
8995 +
8996 +
8997 +//
8998 +// FIB commands
8999 +//
9000 +
9001 +typedef enum _FIB_COMMANDS {
9002 +    TestCommandResponse =                      1,
9003 +    TestAdapterCommand =                       2,
9004 +
9005 +       // Lowlevel and comm commands
9006 +
9007 +    LastTestCommand =                          100,
9008 +    ReinitHostNormCommandQueue =       101,
9009 +    ReinitHostHighCommandQueue =       102,
9010 +    ReinitHostHighRespQueue =          103,
9011 +    ReinitHostNormRespQueue =          104,
9012 +    ReinitAdapNormCommandQueue =       105,
9013 +    ReinitAdapHighCommandQueue =       107,
9014 +    ReinitAdapHighRespQueue =          108,
9015 +    ReinitAdapNormRespQueue =          109,
9016 +    InterfaceShutdown =                        110,
9017 +    DmaCommandFib =                            120,
9018 +    StartProfile =                                     121,
9019 +    TermProfile =                                      122,
9020 +    SpeedTest =                                        123,
9021 +    TakeABreakPt =                                     124,
9022 +    RequestPerfData =                          125,
9023 +    SetInterruptDefTimer=           126,
9024 +    SetInterruptDefCount=           127,
9025 +    GetInterruptDefStatus=          128,
9026 +    LastCommCommand =                          129,
9027 +
9028 +       // Filesystem commands
9029 +
9030 +    NuFileSystem =                                     300,
9031 +    UFS =                                                      301,
9032 +    HostFileSystem =                           302,
9033 +    LastFileSystemCommand =            303,
9034 +
9035 +       // Container Commands
9036 +
9037 +    ContainerCommand =                                 500,
9038 +       ContainerCommand64 =                    501,
9039 +
9040 +       // Cluster Commands
9041 +
9042 +    ClusterCommand =                           550,
9043 +
9044 +       // Scsi Port commands (scsi passthrough)
9045 +
9046 +    ScsiPortCommand =                          600,
9047 +
9048 +       // misc house keeping and generic adapter initiated commands
9049 +
9050 +    AifRequest =                                       700,
9051 +    CheckRevision =                                    701,
9052 +    FsaHostShutdown =                          702,
9053 +    RequestAdapterInfo =                       703,
9054 +    IsAdapterPaused =                          704,
9055 +    SendHostTime =                                     705,
9056 +    LastMiscCommand =                          706
9057 +
9058 +} _E_FIB_COMMANDS;
9059 +
9060 +
9061 +
9062 +typedef AAC_UINT16 FIB_COMMAND;
9063 +
9064 +//
9065 +// Commands that will target the failover level on the FSA adapter
9066 +//
9067 +
9068 +typedef enum _FIB_XFER_STATE {
9069 +    HostOwned                          = (1<<0),
9070 +    AdapterOwned                       = (1<<1),
9071 +    FibInitialized                     = (1<<2),
9072 +    FibEmpty                           = (1<<3),
9073 +    AllocatedFromPool          = (1<<4),
9074 +    SentFromHost                       = (1<<5),
9075 +    SentFromAdapter            = (1<<6),
9076 +    ResponseExpected           = (1<<7),
9077 +    NoResponseExpected                 = (1<<8),
9078 +    AdapterProcessed           = (1<<9),
9079 +    HostProcessed                      = (1<<10),
9080 +    HighPriority                       = (1<<11),
9081 +    NormalPriority                     = (1<<12),
9082 +    Async                                      = (1<<13),
9083 +    AsyncIo                                    = (1<<13),      // rpbfix: remove with new regime
9084 +    PageFileIo                         = (1<<14),      // rpbfix: remove with new regime
9085 +    ShutdownRequest                    = (1<<15),
9086 +    LazyWrite                          = (1<<16),      // rpbfix: remove with new regime
9087 +    AdapterMicroFib                    = (1<<17),
9088 +    BIOSFibPath                                = (1<<18),
9089 +    FastResponseCapable                = (1<<19),
9090 +       ApiFib                                  = (1<<20)       // Its an API Fib.
9091 +
9092 +} _E_FIB_XFER_STATE;
9093 +
9094 +
9095 +typedef enum _FSA_ERRORS {
9096 +    FSA_NORMAL                  = 0,
9097 +    FSA_SUCCESS                 = 0,
9098 +    FSA_PENDING                 = 0x01,
9099 +    FSA_FATAL                   = 0x02,
9100 +    FSA_INVALID_QUEUE           = 0x03,
9101 +    FSA_NOENTRIES               = 0x04,
9102 +    FSA_SENDFAILED              = 0x05,
9103 +    FSA_INVALID_QUEUE_PRIORITY  = 0x06,
9104 +    FSA_FIB_ALLOCATION_FAILED   = 0x07,
9105 +    FSA_FIB_DEALLOCATION_FAILED = 0x08
9106 +
9107 +} _E_FSA_ERRORS;
9108 +
9109 +
9110 +//
9111 +// The following defines needs to be updated any time there is an incompatible change made
9112 +// to the ADAPTER_INIT_STRUCT structure.
9113 +//
9114 +#define ADAPTER_INIT_STRUCT_REVISION           3
9115 +
9116 +typedef struct _ADAPTER_INIT_STRUCT {
9117 +       AAC_UINT32              InitStructRevision;
9118 +       AAC_UINT32              MiniPortRevision;
9119 +       AAC_UINT32              FilesystemRevision;
9120 +       PAAC_VOID               CommHeaderAddress;
9121 +       PAAC_VOID               FastIoCommAreaAddress;
9122 +       PAAC_VOID               AdapterFibsPhysicalAddress;
9123 +       PAAC_VOID               AdapterFibsVirtualAddress;
9124 +       AAC_UINT32              AdapterFibsSize;
9125 +       AAC_UINT32              AdapterFibAlign;
9126 +       PAAC_VOID               PrintfBufferAddress;
9127 +       AAC_UINT32              PrintfBufferSize;
9128 +       AAC_UINT32              HostPhysMemPages;               // number of 4k pages of host physical memory
9129 +       AAC_UINT32              HostElapsedSeconds;             // number of seconds since 1970.
9130 +} ADAPTER_INIT_STRUCT;
9131 +typedef ADAPTER_INIT_STRUCT *PADAPTER_INIT_STRUCT;
9132 +
9133 +#ifdef AAC_32BIT_ENUMS
9134 +typedef _E_FSA_ERRORS  FSA_ERRORS;
9135 +#else
9136 +typedef        AAC_UINT32              FSA_ERRORS;
9137 +#endif
9138 +
9139 +typedef enum _LOG_LEVEL {
9140 +       LOG_INIT                                = 10,
9141 +       LOG_INFORMATIONAL               = 20,
9142 +       LOG_WARNING                             = 30,
9143 +       LOG_LOW_ERROR                   = 40,
9144 +       LOG_MEDIUM_ERROR                = 50,
9145 +       LOG_HIGH_ERROR                  = 60,
9146 +       LOG_PANIC                               = 70,
9147 +       LOG_DEBUG                               = 80,
9148 +       LOG_WINDBG_PRINT                = 90
9149 +} _E_LOG_LEVEL;
9150 +
9151 +#ifdef AAC_32BIT_ENUMS
9152 +typedef _E_LOG_LEVEL   LOG_LEVEL;
9153 +#else
9154 +typedef        AAC_UINT32              LOG_LEVEL;
9155 +#endif
9156 +
9157 +
9158 +#endif //_COMM_STRUCT
9159 +
9160 +
9161 diff -urN linux/drivers/scsi/aacraid/include/comsup.h linux/drivers/scsi/aacraid/include/comsup.h
9162 --- linux/drivers/scsi/aacraid/include/comsup.h Wed Dec 31 19:00:00 1969
9163 +++ linux/drivers/scsi/aacraid/include/comsup.h Thu Dec 21 13:14:30 2000
9164 @@ -0,0 +1,132 @@
9165 +/*++
9166 + * Adaptec aacraid device driver for Linux.
9167 + *
9168 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9169 + *
9170 + * This program is free software; you can redistribute it and/or modify
9171 + * it under the terms of the GNU General Public License as published by
9172 + * the Free Software Foundation; either version 2, or (at your option)
9173 + * any later version.
9174 + *
9175 + * This program is distributed in the hope that it will be useful,
9176 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9177 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9178 + * GNU General Public License for more details.
9179 + *
9180 + * You should have received a copy of the GNU General Public License
9181 + * along with this program; see the file COPYING.  If not, write to
9182 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9183 + *
9184 + * Module Name:
9185 + *   comsup.h
9186 + *
9187 + * Abstract: This module defines the data structures that make up the 
9188 + *           commuication region for the FSA filesystem. This region is
9189 + *           how the host based code commuicates both control and data
9190 + *           to the adapter based code. 
9191 + *
9192 + *
9193 + *
9194 + --*/
9195 +#ifndef _COMM_SUP_DEF
9196 +#define _COMM_SUP_DEF
9197 +
9198 +static char *ident_comsup = "aacraid_ident comsup.h 1.0.6 2000/10/09 Adaptec, Inc.";
9199 +
9200 +//
9201 +// The adapter interface specs all queues to be located in the same physically
9202 +// contigous block. The host structure that defines the commuication queues will
9203 +// assume they are each a seperate physically contigous memory region that will
9204 +// support them all being one big contigous block.
9205 +// There is a command and response queue for each level and direction of
9206 +// commuication. These regions are accessed by both the host and adapter.
9207 +//
9208 +typedef struct _COMM_QUE {
9209 +
9210 +    PHYSICAL_ADDRESS LogicalAddress;    // This is the address we give the adapter
9211 +    
9212 +    PQUEUE_ENTRY       BaseAddress;        // This is the system virtual address 
9213 +    QUEUE_HEADERS      Headers;            // A pointer to the producer and consumer queue headers for this queue
9214 +    ULONG                      QueueEntries;       // Number of queue entries on this queue
9215 +    OS_CV_T                    QueueFull;          // Event to wait on if the queue is full
9216 +    OS_CV_T                    CommandReady;       // Indicates there is a Command ready from the adapter on this queue.
9217 +                                        // This is only valid for adapter to host command queues.                                        
9218 +    OS_SPINLOCK                *QueueLock;         // Spinlock for this queue must take this lock before accessing the lock
9219 +    KIRQL                      SavedIrql;          // Previous IRQL when the spin lock is taken
9220 +    ddi_softintr_t     ConsumerRoutine;    // The DPC routine which will consume entries off this queue
9221 +                                        // Only queues which the host will be the consumer will this field be valid
9222 +    LIST_ENTRY                 CommandQueue;       // A queue of FIBs which need to be prcessed by the FS thread. This is
9223 +                                        // only valid for command queues which receive entries from the adapter.
9224 +       LIST_ENTRY              OutstandingIoQueue;     // A queue of outstanding fib's to the adapter.
9225 +       ULONG                   NumOutstandingIos;      // Number of entries on outstanding queue.
9226 +
9227 +       PVOID                   Adapter;                        // Back pointer to adapter structure
9228 +
9229 +} COMM_QUE;
9230 +typedef COMM_QUE *PCOMM_QUE;
9231 +
9232 +
9233 +typedef struct _COMM_REGION {
9234 +
9235 +    COMM_QUE HostNormCmdQue;           // Command queue for normal priority commands from the host
9236 +    COMM_QUE HostNormRespQue;           // A response for normal priority adapter responses
9237 +    
9238 +    COMM_QUE HostHighCmdQue;            // Command queue for high priority commands from the host
9239 +    COMM_QUE HostHighRespQue;           // A response for normal priority adapter responses
9240 +    
9241 +    COMM_QUE AdapNormCmdQue;            // Command queue for normal priority command from the adapter
9242 +    COMM_QUE AdapNormRespQue;           // A response for normal priority host responses
9243 +
9244 +    COMM_QUE AdapHighCmdQue;            // Command queue for high priority command from the adapter
9245 +    COMM_QUE AdapHighRespQue;           // A response for high priority host responses
9246 +
9247 +    //
9248 +    // The 2 threads below are the threads which handle command traffic from the
9249 +    // the adapter. There is one for normal priority and one for high priority queues.
9250 +    // These threads will wait on the commandready event for it's queue.
9251 +    //
9252 +
9253 +    HANDLE NormCommandThread;
9254 +    HANDLE HighCommandThread;
9255 +
9256 +    //
9257 +    // This dpc routine will handle the setting the of not full event when the adapter
9258 +    // lets us know the queue is not longer full via interrupt
9259 +    //
9260 +
9261 +    KDPC QueueNotFullDpc;
9262 +
9263 +#ifdef API_THROTTLE
9264 +       //
9265 +       // Support for data I/O throttling to improve CLI performance
9266 +       // while the system is under load.
9267 +       // This is the throttling mechanism built into the COMM layer.
9268 +       // Look in commsup.c, dpcsup.c and comminit.c for use.
9269 +       //
9270 +
9271 +       int                             ThrottleLimit;                          // Max queue depth of data ops allowed during throttle
9272 +       int                             ThrottleOutstandingFibs;        // Number of data FIBs outstanding to adapter
9273 +       LARGE_INTEGER   ThrottleTimeout;                        // Duration of a a throttle period
9274 +       LARGE_INTEGER   ThrottleWaitTimeout;            // Timeout for a suspended threads to wait
9275 +       BOOLEAN                 ThrottleActive;                         // Is there a current throttle active period ?
9276 +       KTIMER                  ThrottleTimer;                          // Throttle timer to end a throttle period.
9277 +       KDPC                    ThrottleDpc;                            // Throttle timer timeout DPC routine.
9278 +       KSEMAPHORE              ThrottleReleaseSema;            // Semaphore callers of SendFib wait on during a throttle.
9279 +
9280 +       unsigned int    ThrottleExceptionsCount;        // Number of times throttle exception handler executed (0!)
9281 +       unsigned int    ThrottleTimerFires;                     // Debug info - #times throttle timer Dpc has fired
9282 +       unsigned int    ThrottleTimerSets;                      // Debug info - #times throttle timer was set
9283 +
9284 +       unsigned int    ThrottledFibs;
9285 +       unsigned int    ThrottleTimedoutFibs;
9286 +       unsigned int    ApiFibs;
9287 +       unsigned int    NonPassiveFibs;
9288 +       unsigned int    TotalFibs;
9289 +       unsigned int    FSInfoFibs;
9290 +
9291 +#endif // #ifdef API_THROTTLE
9292 +
9293 +} COMM_REGION;
9294 +typedef COMM_REGION *PCOMM_REGION;
9295 +
9296 +#endif // _COMM_SUP
9297 diff -urN linux/drivers/scsi/aacraid/include/fsact.h linux/drivers/scsi/aacraid/include/fsact.h
9298 --- linux/drivers/scsi/aacraid/include/fsact.h  Wed Dec 31 19:00:00 1969
9299 +++ linux/drivers/scsi/aacraid/include/fsact.h  Thu Dec 21 13:14:30 2000
9300 @@ -0,0 +1,165 @@
9301 +/*++
9302 + * Adaptec aacraid device driver for Linux.
9303 + *
9304 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9305 + *
9306 + * This program is free software; you can redistribute it and/or modify
9307 + * it under the terms of the GNU General Public License as published by
9308 + * the Free Software Foundation; either version 2, or (at your option)
9309 + * any later version.
9310 + *
9311 + * This program is distributed in the hope that it will be useful,
9312 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9313 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9314 + * GNU General Public License for more details.
9315 + *
9316 + * You should have received a copy of the GNU General Public License
9317 + * along with this program; see the file COPYING.  If not, write to
9318 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9319 + *
9320 + * Module Name:
9321 + *   fsact.h
9322 + *
9323 + * Abstract:  Common container structures that are required to be
9324 + *            known on both the host and adapter.
9325 + *
9326 + *
9327 + --*/
9328 +#ifndef _FSACT_H_
9329 +#define        _FSACT_H_
9330 +
9331 +static char *ident_fsact = "aacraid_ident fsact.h 1.0.6 2000/10/09 Adaptec, Inc.";
9332 +
9333 +//#include <comstruc.h>
9334 +//#include <fsatypes.h>
9335 +#include <protocol.h> // definitions for FSASTATUS
9336 +
9337 +
9338 +/*
9339 + * Object-Server / Volume-Manager Dispatch Classes
9340 + */
9341 +typedef enum _VM_COMMANDS {
9342 +   VM_Null = 0,
9343 +   VM_NameServe,
9344 +   VM_ContainerConfig,
9345 +   VM_Ioctl,
9346 +   VM_FilesystemIoctl,
9347 +   VM_CloseAll,
9348 +   VM_CtBlockRead,             // see protocol.h for BlockRead command layout
9349 +   VM_CtBlockWrite,            // see protocol.h for BlockWrite command layout
9350 +   VM_SliceBlockRead,  // raw access to configured "storage objects"
9351 +   VM_SliceBlockWrite,
9352 +   VM_DriveBlockRead,  // raw access to physical devices
9353 +   VM_DriveBlockWrite,
9354 +   VM_EnclosureMgt,            // enclosure management
9355 +   VM_Unused,                  // used to be diskset management
9356 +   VM_CtBlockVerify,   // see protocol.h for BlockVerify command layout
9357 +   VM_CtPerf,                  // performance test
9358 +   VM_CtBlockRead64,   // see protocol.h for BlockRead64 command layout
9359 +   VM_CtBlockWrite64,  // see protocol.h for BlockWrite64 command layout
9360 +   VM_CtBlockVerify64, // see protocol.h for BlockVerify64 command layout   
9361 +   MAX_VMCOMMAND_NUM   // used for sizing stats array - leave last
9362 +} _E_VMCOMMAND;
9363 +
9364 +#ifdef AAC_32BIT_ENUMS
9365 +typedef _E_VMCOMMAND   VMCOMMAND;
9366 +#else
9367 +typedef        AAC_UINT32              VMCOMMAND;
9368 +#endif
9369 +
9370 +
9371 +
9372 +//
9373 +// Descriptive information (eg, vital stats)
9374 +// that a content manager might report.  The
9375 +// FileArray filesystem component is one example
9376 +// of a content manager.  Raw mode might be
9377 +// another.
9378 +//
9379 +
9380 +struct FileSysInfo {
9381 +/*
9382 +       a) DOS usage - THINK ABOUT WHERE THIS MIGHT GO -- THXXX
9383 +       b) FSA usage (implemented by ObjType and ContentState fields)
9384 +       c) Block size
9385 +       d) Frag size
9386 +       e) Max file system extension size - (fsMaxExtendSize * fsSpaceUnits)
9387 +       f) I-node density - (computed from other fields)
9388 +*/
9389 +       AAC_UINT32  fsTotalSize;        // consumed by fs, incl. metadata
9390 +       AAC_UINT32  fsBlockSize;
9391 +       AAC_UINT32  fsFragSize;
9392 +       AAC_UINT32  fsMaxExtendSize;
9393 +       AAC_UINT32  fsSpaceUnits;
9394 +       AAC_UINT32  fsMaxNumFiles;
9395 +       AAC_UINT32  fsNumFreeFiles;
9396 +       AAC_UINT32  fsInodeDensity;
9397 +};     // valid iff ObjType == FT_FILESYS && !(ContentState & FSCS_NOTCLEAN)
9398 +
9399 +union ContentManagerInfo {
9400 +       struct FileSysInfo FileSys;     // valid iff ObjType == FT_FILESYS && !(ContentState & FSCS_NOTCLEAN)
9401 +};
9402 +
9403 +//
9404 +// Query for "mountable" objects, ie, objects that are typically
9405 +// associated with a drive letter on the client (host) side.
9406 +//
9407 +
9408 +typedef struct _MNTOBJ {
9409 +
9410 +   AAC_UINT32    ObjectId;
9411 +   FSASTRING  FileSystemName;   // if applicable
9412 +   ContainerCreationInfo   CreateInfo; // if applicable
9413 +   AAC_UINT32    Capacity;
9414 +   FSAVOLTYPE VolType;          // substrate structure
9415 +   FTYPE      ObjType;          // FT_FILESYS, FT_DATABASE, etc.
9416 +   AAC_UINT32     ContentState;     // unready for mounting, readonly, etc.
9417 +
9418 +   union ContentManagerInfo
9419 +              ObjExtension;     // Info specific to content manager (eg, filesystem)
9420 +
9421 +   AAC_UINT32    AlterEgoId;       // != ObjectId <==> snapshot or broken mirror exists
9422 +
9423 +} MNTOBJ;
9424 +
9425 +
9426 +#define FSCS_READONLY  0x0002  // possible result of broken mirror
9427 +
9428 +
9429 +
9430 +typedef struct _MNTINFO {
9431 +
9432 +   VMCOMMAND  Command;
9433 +   FTYPE      MntType;
9434 +   AAC_UINT32     MntCount;
9435 +
9436 +} MNTINFO;
9437 +typedef MNTINFO *PMNTINFO;
9438 +
9439 +typedef struct _MNTINFORESPONSE {
9440 +
9441 +   FSASTATUS Status;
9442 +   FTYPE     MntType;           // should be same as that requested
9443 +   AAC_UINT32    MntRespCount;
9444 +   MNTOBJ    MntTable[1];
9445 +
9446 +} MNTINFORESPONSE;
9447 +typedef MNTINFORESPONSE *PMNTINFORESPONSE;
9448 +
9449 +
9450 +//
9451 +// The following command is sent to shut down each container.
9452 +//
9453 +
9454 +typedef struct _CLOSECOMMAND {
9455 +
9456 +   VMCOMMAND  Command;
9457 +   AAC_UINT32    ContainerId;
9458 +
9459 +} CLOSECOMMAND;
9460 +typedef CLOSECOMMAND *PCLOSECOMMAND;
9461 +
9462 +
9463 +#endif /* _FSACT_H_ */
9464 +
9465 +
9466 diff -urN linux/drivers/scsi/aacraid/include/fsafs.h linux/drivers/scsi/aacraid/include/fsafs.h
9467 --- linux/drivers/scsi/aacraid/include/fsafs.h  Wed Dec 31 19:00:00 1969
9468 +++ linux/drivers/scsi/aacraid/include/fsafs.h  Thu Dec 21 13:14:30 2000
9469 @@ -0,0 +1,78 @@
9470 +/*++
9471 + * Adaptec aacraid device driver for Linux.
9472 + *
9473 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9474 + *
9475 + * This program is free software; you can redistribute it and/or modify
9476 + * it under the terms of the GNU General Public License as published by
9477 + * the Free Software Foundation; either version 2, or (at your option)
9478 + * any later version.
9479 + *
9480 + * This program is distributed in the hope that it will be useful,
9481 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9482 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9483 + * GNU General Public License for more details.
9484 + *
9485 + * You should have received a copy of the GNU General Public License
9486 + * along with this program; see the file COPYING.  If not, write to
9487 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9488 + *
9489 + * Module Name:
9490 + *   fsafs.h
9491 + *
9492 + * Abstract: Common file system structures that are required to be
9493 + *           known on both the host and adapter
9494 + *
9495 + *
9496 + *
9497 + --*/
9498 +
9499 +#ifndef _FSAFS_H_
9500 +#define        _FSAFS_H_ 1
9501 +
9502 +static char *ident_fsafs = "aacraid_ident fsafs.h 1.0.6 2000/10/09 Adaptec, Inc.";
9503 +
9504 +#include <fsatypes.h>   // core types, shared by client and server, eg, u_long
9505 +
9506 +/*
9507 + *  Maximum number of filesystems.
9508 + */
9509 +#define NFILESYS   24
9510 +
9511 +/*
9512 + * File identifier.
9513 + * These are unique and self validating within a filesystem
9514 + * on a single machine and can persist across reboots.
9515 + * The hint field may be volatile and is not guaranteed to persist
9516 + * across reboots but is used to speed up the FID to file object translation
9517 + * if possible. The opaque f1 and f2 fields are guaranteed to uniquely identify
9518 + * the file object (assuming a filesystem context, i.e. driveno).
9519 + */
9520 +typedef struct {
9521 +                               AAC_UINT32  hint; // last used hint for fast reclaim
9522 +                               AAC_UINT32  f1;   // opaque
9523 +                               AAC_UINT32  f2;   // opaque
9524 +                       } fileid_t;             /* intra-filesystem file ID type */
9525 +
9526 +       
9527 +/*
9528 + * Generic file handle
9529 + */
9530 +struct fhandle {
9531 +       fsid_t   fh_fsid;       /* File system id of mount point */
9532 +       fileid_t fh_fid;        /* File sys specific file id */
9533 +};
9534 +typedef struct fhandle fhandle_t;
9535 +
9536 +#define        FIDSIZE         sizeof(fhandle_t)
9537 +
9538 +typedef struct {
9539 +       union {
9540 +               AAC_INT8        fid_data[FIDSIZE];
9541 +               struct  fhandle fsafid;
9542 +       } fidu;
9543 +} FSAFID;                                      /* FSA File ID type */
9544 +
9545 +                                                               
9546 +#endif /* _FSAFS_H_ */
9547 +
9548 diff -urN linux/drivers/scsi/aacraid/include/fsaioctl.h linux/drivers/scsi/aacraid/include/fsaioctl.h
9549 --- linux/drivers/scsi/aacraid/include/fsaioctl.h       Wed Dec 31 19:00:00 1969
9550 +++ linux/drivers/scsi/aacraid/include/fsaioctl.h       Thu Dec 21 13:14:30 2000
9551 @@ -0,0 +1,159 @@
9552 +/*++
9553 + * Adaptec aacraid device driver for Linux.
9554 + *
9555 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9556 + *
9557 + * This program is free software; you can redistribute it and/or modify
9558 + * it under the terms of the GNU General Public License as published by
9559 + * the Free Software Foundation; either version 2, or (at your option)
9560 + * any later version.
9561 + *
9562 + * This program is distributed in the hope that it will be useful,
9563 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9564 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9565 + * GNU General Public License for more details.
9566 + *
9567 + * You should have received a copy of the GNU General Public License
9568 + * along with this program; see the file COPYING.  If not, write to
9569 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9570 + *
9571 + * Module Name:
9572 + *   fsaioctl.h
9573 + *
9574 + * Abstract: Defines the interface structures between user mode applications
9575 + *           and the fsa driver.  This structures are used in 
9576 + *           DeviceIoControl() calls.
9577 + *
9578 + *
9579 + *
9580 + --*/
9581 +#ifndef _FSAIOCTL_H_
9582 +#define _FSAIOCTL_H_
9583 +
9584 +static char *ident_fsaioctl = "aacraid_ident fsaioctl.h 1.0.6 2000/10/09 Adaptec, Inc.";
9585 +
9586 +#ifndef IOTRACEUSER
9587 +
9588 +#ifndef CTL_CODE
9589 +
9590 +
9591 +#define FILE_DEVICE_CONTROLLER          0x00000004
9592 +
9593 +//
9594 +// Macro definition for defining IOCTL and FSCTL function control codes.  Note
9595 +// that function codes 0-2047 are reserved for Microsoft Corporation, and
9596 +// 2048-4095 are reserved for customers.
9597 +//
9598 +
9599 +#define CTL_CODE( DeviceType, Function, Method, Access ) (                 \
9600 +    ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
9601 +)
9602 +
9603 +//
9604 +// Define the method codes for how buffers are passed for I/O and FS controls
9605 +//
9606 +
9607 +#define METHOD_BUFFERED                 0
9608 +
9609 +
9610 +#define METHOD_NEITHER                  3
9611 +
9612 +//
9613 +// Define the access check value for any access
9614 +//
9615 +//
9616 +// The FILE_READ_ACCESS and FILE_WRITE_ACCESS constants are also defined in
9617 +// ntioapi.h as FILE_READ_DATA and FILE_WRITE_DATA. The values for these
9618 +// constants *MUST* always be in sync.
9619 +//
9620 +#define FILE_ANY_ACCESS                 0
9621 +
9622 +
9623 +
9624 +#endif
9625 +
9626 +
9627 +
9628 +typedef struct _UNIX_QUERY_DISK {
9629 +       AAC_INT32       ContainerNumber;
9630 +       AAC_INT32       Bus;
9631 +       AAC_INT32       Target;
9632 +       AAC_INT32       Lun;
9633 +       AAC_BOOLEAN     Valid;
9634 +       AAC_BOOLEAN     Locked;
9635 +       AAC_BOOLEAN     Deleted;
9636 +       AAC_INT32       Instance;
9637 +       AAC_INT8        diskDeviceName[10];
9638 +       AAC_BOOLEAN UnMapped;
9639 +} UNIX_QUERY_DISK;
9640 +typedef UNIX_QUERY_DISK *PUNIX_QUERY_DISK;
9641 +
9642 +
9643 +typedef struct _DELETE_DISK {
9644 +       AAC_UINT32      NtDiskNumber;
9645 +       AAC_UINT32      ContainerNumber;
9646 +} DELETE_DISK;
9647 +typedef DELETE_DISK *PDELETE_DISK;
9648 +
9649 +
9650 +#endif /*IOTRACEUSER*/
9651 +
9652 +#define FSACTL_NULL_IO_TEST             0x43    // CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 2048, METHOD_NEITHER, FILE_ANY_ACCESS)
9653 +#define FSACTL_SIM_IO_TEST              0x53    // CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 2049, METHOD_NEITHER, FILE_ANY_ACCESS)
9654 +
9655 +
9656 +#define FSACTL_SENDFIB                  CTL_CODE(FILE_DEVICE_CONTROLLER, 2050, METHOD_BUFFERED, FILE_ANY_ACCESS)
9657 +
9658 +
9659 +#define FSACTL_GET_VAR                                 0x93
9660 +#define FSACTL_SET_VAR                                 0xa3
9661 +#define FSACTL_GET_FIBTIMES                            0xb3
9662 +#define FSACTL_ZERO_FIBTIMES                   0xc3
9663 +
9664 +
9665 +#define FSACTL_DELETE_DISK                             0x163
9666 +#define FSACTL_QUERY_DISK                              0x173
9667 +
9668 +
9669 +// AfaComm perfmon ioctls
9670 +#define FSACTL_GET_COMM_PERF_DATA              CTL_CODE(FILE_DEVICE_CONTROLLER, 2084, METHOD_BUFFERED, FILE_ANY_ACCESS)
9671 +
9672 +
9673 +#define FSACTL_OPENCLS_COMM_PERF_DATA  CTL_CODE(FILE_DEVICE_CONTROLLER, 2085, METHOD_BUFFERED, FILE_ANY_ACCESS)
9674 +
9675 +
9676 +typedef struct _GET_ADAPTER_FIB_IOCTL {
9677 +       char    *AdapterFibContext;
9678 +       int             Wait;
9679 +       char    *AifFib;
9680 +} GET_ADAPTER_FIB_IOCTL, *PGET_ADAPTER_FIB_IOCTL;
9681 +
9682 +//
9683 +// filesystem ioctls
9684 +//
9685 +#define FSACTL_OPEN_GET_ADAPTER_FIB            CTL_CODE(FILE_DEVICE_CONTROLLER, 2100, METHOD_BUFFERED, FILE_ANY_ACCESS)
9686 +
9687 +#define FSACTL_GET_NEXT_ADAPTER_FIB            CTL_CODE(FILE_DEVICE_CONTROLLER, 2101, METHOD_BUFFERED, FILE_ANY_ACCESS)
9688 +
9689 +#define FSACTL_CLOSE_GET_ADAPTER_FIB   CTL_CODE(FILE_DEVICE_CONTROLLER, 2102, METHOD_BUFFERED, FILE_ANY_ACCESS)
9690 +
9691 +#define FSACTL_OPEN_ADAPTER_CONFIG             CTL_CODE(FILE_DEVICE_CONTROLLER, 2103, METHOD_NEITHER, FILE_ANY_ACCESS)
9692 +
9693 +#define FSACTL_CLOSE_ADAPTER_CONFIG            CTL_CODE(FILE_DEVICE_CONTROLLER, 2104, METHOD_NEITHER, FILE_ANY_ACCESS)
9694 +
9695 +
9696 +#define FSACTL_MINIPORT_REV_CHECK              CTL_CODE(FILE_DEVICE_CONTROLLER, 2107, METHOD_BUFFERED, FILE_ANY_ACCESS)
9697 +
9698 +
9699 +#define FSACTL_QUERY_ADAPTER_CONFIG            CTL_CODE(FILE_DEVICE_CONTROLLER, 2113, METHOD_BUFFERED, FILE_ANY_ACCESS)
9700 +
9701 +
9702 +#define FSACTL_FORCE_DELETE_DISK               CTL_CODE(FILE_DEVICE_CONTROLLER, 2120, METHOD_NEITHER, FILE_ANY_ACCESS)
9703 +
9704 +
9705 +#define FSACTL_AIF_THREAD                              CTL_CODE(FILE_DEVICE_CONTROLLER, 2127, METHOD_NEITHER, FILE_ANY_ACCESS)
9706 +
9707 +
9708 +#endif // _FSAIOCTL_H_
9709 +
9710 +
9711 diff -urN linux/drivers/scsi/aacraid/include/fsaport.h linux/drivers/scsi/aacraid/include/fsaport.h
9712 --- linux/drivers/scsi/aacraid/include/fsaport.h        Wed Dec 31 19:00:00 1969
9713 +++ linux/drivers/scsi/aacraid/include/fsaport.h        Thu Dec 21 13:14:30 2000
9714 @@ -0,0 +1,223 @@
9715 +/*++
9716 + * Adaptec aacraid device driver for Linux.
9717 + *
9718 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9719 + *
9720 + * This program is free software; you can redistribute it and/or modify
9721 + * it under the terms of the GNU General Public License as published by
9722 + * the Free Software Foundation; either version 2, or (at your option)
9723 + * any later version.
9724 + *
9725 + * This program is distributed in the hope that it will be useful,
9726 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9727 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9728 + * GNU General Public License for more details.
9729 + *
9730 + * You should have received a copy of the GNU General Public License
9731 + * along with this program; see the file COPYING.  If not, write to
9732 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9733 + *
9734 + * Module Name:
9735 + *   fsaport.h
9736 + *
9737 + * Abstract: This module defines all of the globally used procedures in the FSA
9738 + *           file system.
9739 + *
9740 + *
9741 + *
9742 + --*/
9743 +#ifndef _FSAPORT_
9744 +#define _FSAPORT_
9745 +
9746 +static char *ident_fsaport = "aacraid_ident fsaport.h 1.0.6 2000/10/09 Adaptec, Inc.";
9747 +
9748 +//
9749 +// The scatter/gather map context is the information we 
9750 +// we need to keep the map and transfer data to and from the
9751 +// adapter.
9752 +//
9753 +
9754 +typedef struct _SGMAP_CONTEXT {
9755 +       
9756 +       caddr_t         BaseAddress;
9757 +    PVOID              MapRegBase;
9758 +    ULONG              NumberMapRegs;
9759 +       PSGMAP          SgMapPtr;
9760 +       ULONG           ByteCount;              // Used to check the Mdl length.
9761 +       BOOLEAN         WriteToDevice;
9762 +
9763 +       struct buf      *bp;
9764 +
9765 +
9766 +} SGMAP_CONTEXT;
9767 +typedef SGMAP_CONTEXT *PSGMAP_CONTEXT;
9768 +
9769 +typedef struct _MAPFIB_CONTEXT {
9770 +       PMDL            Mdl;    
9771 +    PVOID              MapRegBase;
9772 +    ULONG              NumberMapRegs;
9773 +       PVOID           FibVirtualAddress;
9774 +       ULONG           Size;
9775 +       PVOID       FibPhysicalAddress;
9776 +
9777 +
9778 +} MAPFIB_CONTEXT;
9779 +typedef MAPFIB_CONTEXT *PMAPFIB_CONTEXT;
9780 +
9781 +typedef BOOLEAN
9782 +(*PFSA_ALLOCATE_ADAPTER_COMM_AREA)(
9783 +       PVOID AdapterExtension,
9784 +       IN OUT PVOID    *BaseAddress,
9785 +       IN ULONG                Size,
9786 +       IN ULONG                Alignment
9787 +       );
9788 +
9789 +typedef BOOLEAN
9790 +(*PFSA_FREE_ADAPTER_COMM_AREA)(
9791 +       PVOID   AdapterExtension
9792 +       );
9793 +
9794 +typedef VOID
9795 +(*PFSA_FREE_DMA_RESOURCES)(     
9796 +       IN PVOID AdapterExtension,
9797 +    IN PSGMAP_CONTEXT SgMapContext
9798 +    );
9799 +
9800 +typedef BOOLEAN
9801 +(*PFSA_ALLOCATE_AND_MAP_FIB_SPACE)(
9802 +       IN PVOID AdapterExtension, 
9803 +       IN PMAPFIB_CONTEXT MapFibContext
9804 +    );
9805 +
9806 +typedef BOOLEAN
9807 +(*PFSA_UNMAP_AND_FREE_FIB_SPACE)(
9808 +       IN PVOID AdapterExtension, 
9809 +       IN PMAPFIB_CONTEXT MapFibContext
9810 +    );
9811 +
9812 +typedef VOID
9813 +(*PFSA_INTERRUPT_ADAPTER)(
9814 +       IN PVOID AdapterExtension
9815 +       );
9816 +
9817 +typedef VOID
9818 +(*PFSA_NOTIFY_ADAPTER)(
9819 +       IN PVOID AdapterExtension,
9820 +    IN HOST_2_ADAP_EVENT AdapterEvent
9821 +    );
9822 +
9823 +typedef VOID
9824 +(*PFSA_RESET_DEVICE)(
9825 +       PVOID AdapterExtension
9826 +       );
9827 +
9828 +typedef AAC_STATUS
9829 +(*PFSA_BUILD_SGMAP)(  
9830 +       IN PVOID AdapterExtension,
9831 +       IN PSGMAP_CONTEXT SgMapContext
9832 +       );
9833 +
9834 +typedef PVOID
9835 +(*PFSA_ADAPTER_ADDR_TO_SYSTEM_ADDR)(  
9836 +       IN PVOID AdapterExtension,
9837 +       IN PVOID AdapterAddress
9838 +       );
9839 +
9840 +typedef VOID
9841 +(*PFSA_INTERRUPT_HOST)(
9842 +       PVOID                   Adapter,
9843 +       ADAPTER_EVENT   AdapterEvent
9844 +       );
9845 +
9846 +typedef VOID
9847 +(*PFSA_ENABLE_INTERRUPT)(
9848 +       PVOID                   Adapter,
9849 +       ADAPTER_EVENT   AdapterEvent,
9850 +       BOOLEAN                 AtDeviceIrq
9851 +       );
9852 +
9853 +
9854 +typedef VOID
9855 +(*PFSA_DISABLE_INTERRUPT)(
9856 +       PVOID                   Adapter,
9857 +       ADAPTER_EVENT   AdapterEvent,
9858 +       BOOLEAN                 AtDeviceIrq
9859 +       );
9860 +
9861 +typedef AAC_STATUS
9862 +(*PFSA_OPEN_ADAPTER) (
9863 +       IN PVOID Adapter
9864 +       );
9865 +
9866 +typedef int
9867 +(*PFSA_DEVICE_CONTROL) (
9868 +       IN PVOID Adapter,
9869 +       IN PAFA_IOCTL_CMD IoctlCmdPtr
9870 +       );
9871 +
9872 +typedef AAC_STATUS
9873 +(*PFSA_CLOSE_ADAPTER) (
9874 +       IN PVOID Adapter
9875 +       );
9876 +
9877 +typedef BOOLEAN
9878 +(*PFSA_SEND_SYNCH_FIB) (
9879 +       IN PVOID Adapter,
9880 +       IN ULONG FibPhysicalAddress
9881 +       );
9882 +
9883 +typedef struct _FSAPORT_FUNCS {
9884 +       ULONG                                                           SizeOfFsaPortFuncs;
9885 +
9886 +       PFSA_ALLOCATE_ADAPTER_COMM_AREA         AllocateAdapterCommArea;
9887 +       PFSA_FREE_ADAPTER_COMM_AREA                     FreeAdapterCommArea;
9888 +       PFSA_FREE_DMA_RESOURCES                         FreeDmaResources;
9889 +       PFSA_ALLOCATE_AND_MAP_FIB_SPACE         AllocateAndMapFibSpace;
9890 +       PFSA_UNMAP_AND_FREE_FIB_SPACE           UnmapAndFreeFibSpace;
9891 +       PFSA_INTERRUPT_ADAPTER                          InterruptAdapter;
9892 +       PFSA_NOTIFY_ADAPTER                                     NotifyAdapter;
9893 +       PFSA_ENABLE_INTERRUPT                           EnableInterrupt;
9894 +       PFSA_DISABLE_INTERRUPT                          DisableInterrupt;
9895 +       PFSA_RESET_DEVICE                                       ResetDevice;
9896 +       PFSA_BUILD_SGMAP                                        BuildSgMap;
9897 +       PFSA_ADAPTER_ADDR_TO_SYSTEM_ADDR        AdapterAddressToSystemAddress;
9898 +
9899 +       PFSA_INTERRUPT_HOST                                     InterruptHost;
9900 +       PFSA_OPEN_ADAPTER                                       OpenAdapter;
9901 +       PFSA_DEVICE_CONTROL                                     DeviceControl;
9902 +       PFSA_CLOSE_ADAPTER                                      CloseAdapter;
9903 +
9904 +       PFSA_SEND_SYNCH_FIB                                     SendSynchFib;
9905 +
9906 +} FSAPORT_FUNCS;
9907 +typedef FSAPORT_FUNCS *PFSAPORT_FUNCS;
9908 +
9909 +typedef AAC_STATUS
9910 +(*PFSA_SETVAR_CALLBACK) (
9911 +       IN PVOID Adapter,
9912 +       IN ULONG NewValue
9913 +       );
9914 +
9915 +typedef struct _FSA_USER_VAR {
9916 +       char                                    Name[32];
9917 +       ULONG                                   *Address;
9918 +       PFSA_SETVAR_CALLBACK    SetVarCallback;
9919 +} FSA_USER_VAR;
9920 +
9921 +typedef FSA_USER_VAR *PFSA_USER_VAR;
9922 +
9923 +typedef struct _FSA_NEW_ADAPTER {
9924 +       PVOID                           AdapterExtension;
9925 +       PFSAPORT_FUNCS          AdapterFuncs;
9926 +       PVOID                           Adapter;
9927 +       BOOLEAN                         AdapterInterruptsBelowDpc;
9928 +       PFSA_USER_VAR           AdapterUserVars;
9929 +       ULONG                           AdapterUserVarsSize;
9930 +       void                            *Dip;
9931 +} FSA_NEW_ADAPTER;
9932 +typedef FSA_NEW_ADAPTER *PFSA_NEW_ADAPTER;
9933 +
9934 +#define        FSAFS_GET_NEXT_ADAPTER                  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 2048, METHOD_NEITHER, FILE_ANY_ACCESS)
9935 +#define        FSAFS_INIT_NEW_ADAPTER                  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 2049, METHOD_NEITHER, FILE_ANY_ACCESS)
9936 +
9937 +#endif
9938 diff -urN linux/drivers/scsi/aacraid/include/fsatypes.h linux/drivers/scsi/aacraid/include/fsatypes.h
9939 --- linux/drivers/scsi/aacraid/include/fsatypes.h       Wed Dec 31 19:00:00 1969
9940 +++ linux/drivers/scsi/aacraid/include/fsatypes.h       Thu Dec 21 13:14:30 2000
9941 @@ -0,0 +1,214 @@
9942 +/*++
9943 + * Adaptec aacraid device driver for Linux.
9944 + *
9945 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9946 + *
9947 + * This program is free software; you can redistribute it and/or modify
9948 + * it under the terms of the GNU General Public License as published by
9949 + * the Free Software Foundation; either version 2, or (at your option)
9950 + * any later version.
9951 + *
9952 + * This program is distributed in the hope that it will be useful,
9953 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9954 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9955 + * GNU General Public License for more details.
9956 + *
9957 + * You should have received a copy of the GNU General Public License
9958 + * along with this program; see the file COPYING.  If not, write to
9959 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9960 + *
9961 + * Module Name:
9962 + *   fsatypes.h
9963 + *
9964 + * Abstract: Define all shared data types here, ie, those
9965 + *           types shared among several components, such
9966 + *           as host (driver + apps), adapter, and BIOS.
9967 + *
9968 + *
9969 + --*/
9970 +#ifndef _FSATYPES_H
9971 +#define _FSATYPES_H
9972 +
9973 +static char *ident_fsatype = "aacraid_ident fsatypes.h 1.0.6 2000/10/09 Adaptec, Inc.";
9974 +
9975 +typedef        AAC_UINT32              AAC_BOOLEAN;
9976 +
9977 +//
9978 +// Define a 64-bit address structure for use on
9979 +// a 32-bit processor architecture.
9980 +//
9981 +typedef struct {
9982 +       AAC_UINT32              lo32;
9983 +       AAC_UINT32              hi32;
9984 +} AAC_UINT64S, *PAAC_UINT64S;
9985 +
9986 +
9987 +
9988 +//
9989 +// Container Types
9990 +//
9991 +typedef struct {
9992 +   AAC_UINT32 data[2];  // RMA FIX, make this a real serial number when we
9993 +                           // know what it looks like.  Note, BIOS sees this
9994 +                           // definition and it must be coded in such a way
9995 +                           // that it appears to be 64 bits.  ints are 16 bits
9996 +                           // in BIOS land; fortunately, longs are 32 bits.
9997 +} SerialNumberT;
9998 +
9999 +
10000 +
10001 +//
10002 +//     ***********************
10003 +//     DON'T CHANGE THE ORDER, ctdevsw use this order to map the drivers
10004 +//     ***********************
10005 +//     drivers for CT_NONE to CT_PASSTHRU
10006 +//
10007 +typedef enum _FSAVOLTYPE {
10008 +       CT_NONE = 0,                            
10009 +       CT_VOLUME,                                      
10010 +       CT_MIRROR,
10011 +       CT_STRIPE,
10012 +       CT_RAID5,
10013 +       CT_SSRW,
10014 +       CT_SSRO,
10015 +       CT_MORPH,
10016 +       CT_PASSTHRU,
10017 +       CT_RAID4,
10018 +       CT_RAID10,                                      // stripe of mirror
10019 +       CT_RAID00,                                      // stripe of stripe
10020 +       CT_VOLUME_OF_MIRRORS,           // volume of mirror
10021 +       CT_PSEUDO_RAID3,                        // really raid4
10022 +
10023 +       CT_LAST_VOLUME_TYPE
10024 +
10025 +} _E_FSAVOLTYPE;
10026 +
10027 +#ifdef AAC_32BIT_ENUMS
10028 +typedef        _E_FSAVOLTYPE   FSAVOLTYPE;
10029 +#else
10030 +typedef        AAC_UINT32              FSAVOLTYPE;
10031 +#endif
10032 +
10033 +
10034 +//
10035 +// Types of objects addressable in some fashion by the client.
10036 +// This is a superset of those objects handled just by the filesystem
10037 +// and includes "raw" objects that an administrator would use to
10038 +// configure containers and filesystems.
10039 +//
10040 +typedef enum _FTYPE {
10041 +    FT_REG = 1,     // regular file
10042 +    FT_DIR,         // directory
10043 +    FT_BLK,         // "block" device - reserved
10044 +    FT_CHR,         // "character special" device - reserved
10045 +    FT_LNK,         // symbolic link
10046 +    FT_SOCK,        // socket
10047 +    FT_FIFO,        // fifo
10048 +    FT_FILESYS,     // ADAPTEC's "FSA"(tm) filesystem
10049 +    FT_DRIVE,       // physical disk - addressable in scsi by bus/target/lun
10050 +    FT_SLICE,       // virtual disk - raw volume - slice
10051 +    FT_PARTITION,   // FSA partition - carved out of a slice - building block for containers
10052 +    FT_VOLUME,      // Container - Volume Set
10053 +    FT_STRIPE,      // Container - Stripe Set
10054 +    FT_MIRROR,      // Container - Mirror Set
10055 +    FT_RAID5,       // Container - Raid 5 Set
10056 +    FT_DATABASE     // Storage object with "foreign" content manager
10057 +} _E_FTYPE;
10058 +
10059 +#ifdef AAC_32BIT_ENUMS
10060 +typedef        _E_FTYPE        FTYPE;
10061 +#else
10062 +typedef        AAC_UINT32      FTYPE;
10063 +#endif
10064 +
10065 +
10066 +
10067 +//
10068 +// Host side memory scatter gather list
10069 +// Used by the adapter for read, write, and readdirplus operations
10070 +//
10071 +typedef  PAAC_UINT8 HOSTADDRESS;
10072 +
10073 +typedef struct _SGENTRY {
10074 +       HOSTADDRESS             SgAddress;              /* 32-bit Base address. */
10075 +       AAC_UINT32                      SgByteCount;    /* Length. */
10076 +} SGENTRY;
10077 +typedef SGENTRY *PSGENTRY;
10078 +
10079 +
10080 +
10081 +//
10082 +// SGMAP
10083 +//
10084 +// This is the SGMAP structure for all commands that use
10085 +// 32-bit addressing.
10086 +//
10087 +// Note that the upper 16 bits of SgCount are used as flags.
10088 +// Only the lower 16 bits of SgCount are actually used as the
10089 +// SG element count.
10090 +//
10091 +typedef struct _SGMAP {
10092 +       AAC_UINT32              SgCount;
10093 +       SGENTRY                 SgEntry[1];
10094 +} SGMAP;
10095 +typedef SGMAP *PSGMAP;
10096 +
10097 +
10098 +
10099 +//
10100 +// SGMAP64
10101 +//
10102 +// This is the SGMAP structure for 64-bit container commands.
10103 +//
10104 +typedef struct _SGMAP64 {
10105 +       AAC_UINT8       SgCount;
10106 +       AAC_UINT8       SgSectorsPerPage;
10107 +       AAC_UINT16      SgByteOffset; // For the first page 
10108 +       AAC_UINT64S     SgEntry[1];     // Must be last entry
10109 +} SGMAP64;
10110 +typedef SGMAP64 *PSGMAP64;
10111 +
10112 +
10113 +
10114 +
10115 +//
10116 +// attempt at common time structure across host and adapter
10117 +//
10118 +typedef struct __TIME_T {
10119 +
10120 +       AAC_UINT32      tv_sec;         /* seconds (maybe, depends upon host) */
10121 +       AAC_UINT32      tv_usec;        /* and nanoseconds (maybe, depends upon host)*/
10122 +
10123 +} TIME_T;
10124 +typedef TIME_T *PTIME_T;
10125 +
10126 +#ifndef _TIME_T
10127 +#define timespec __TIME_T
10128 +#define ts_sec tv_sec
10129 +#define ts_nsec        tv_usec
10130 +#endif
10131 +
10132 +
10133 +
10134 +
10135 +typedef struct _ContainerCreationInfo
10136 +{
10137 +
10138 +       AAC_UINT8               ViaBuildNumber;         // e.g., 588
10139 +       AAC_UINT8               MicroSecond;            // e.g., 588
10140 +       AAC_UINT8               Via;                            // e.g.,        1 = FSU,
10141 +                                                                               //                      2 = API,
10142 +       AAC_UINT8               YearsSince1900;         // e.g., 1997 = 97
10143 +       AAC_UINT32              Date;                   //
10144 +                                                                               // unsigned     Month           :4;             // 1 - 12
10145 +                                                                               // unsigned     Day                     :6;             // 1 - 32
10146 +                                                                               // unsigned     Hour            :6;             // 0 - 23
10147 +                                                                               // unsigned     Minute          :6;             // 0 - 60
10148 +                                                                               // unsigned     Second          :6;             // 0 - 60
10149 +       SerialNumberT   ViaAdapterSerialNumber; // e.g., 0x1DEADB0BFAFAF001
10150 +} ContainerCreationInfo;
10151 +
10152 +
10153 +#endif // _FSATYPES_H
10154 +
10155 +
10156 diff -urN linux/drivers/scsi/aacraid/include/linit.h linux/drivers/scsi/aacraid/include/linit.h
10157 --- linux/drivers/scsi/aacraid/include/linit.h  Wed Dec 31 19:00:00 1969
10158 +++ linux/drivers/scsi/aacraid/include/linit.h  Thu Dec 21 13:14:30 2000
10159 @@ -0,0 +1,106 @@
10160 +/*++
10161 + * Adaptec aacraid device driver for Linux.
10162 + *
10163 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10164 + *
10165 + * This program is free software; you can redistribute it and/or modify
10166 + * it under the terms of the GNU General Public License as published by
10167 + * the Free Software Foundation; either version 2, or (at your option)
10168 + * any later version.
10169 + *
10170 + * This program is distributed in the hope that it will be useful,
10171 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10172 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10173 + * GNU General Public License for more details.
10174 + *
10175 + * You should have received a copy of the GNU General Public License
10176 + * along with this program; see the file COPYING.  If not, write to
10177 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10178 + *
10179 + * Module Name:
10180 + *   linit.h
10181 + *
10182 + * Abstract: Header file for Linux Driver for Adaptec RAID Array Controller
10183 + *
10184 + --*/
10185 +/*------------------------------------------------------------------------------
10186 + *              I N C L U D E S
10187 + *----------------------------------------------------------------------------*/
10188 +
10189 +#ifndef _LINIT_H_
10190 +#define _LINIT_H_
10191 +
10192 +static char *ident_linith = "aacraid_ident linit.h 1.0.6 2000/10/09 Adaptec, Inc.";
10193 +
10194 +#include <linux/config.h>
10195 +
10196 +/*------------------------------------------------------------------------------
10197 + *              D E F I N E S
10198 + *----------------------------------------------------------------------------*/
10199 +/* Define the AAC SCSI Host Template structure. */
10200 +#define AAC_HOST_TEMPLATE_ENTRY        \
10201 +  { name:           "AAC",                   /* Driver Name            */ \
10202 +    proc_info:      AAC_ProcDirectoryInfo,   /* ProcFS Info Func       */ \
10203 +    detect:         AAC_DetectHostAdapter,   /* Detect Host Adapter    */ \
10204 +    release:        AAC_ReleaseHostAdapter,  /* Release Host Adapter   */ \
10205 +    info:           AAC_DriverInfo,          /* Driver Info Function   */ \
10206 +    ioctl:          AAC_Ioctl,               /* ioctl Interface        */ \
10207 +    command:        AAC_Command,             /* unqueued command       */ \
10208 +    queuecommand:   AAC_QueueCommand,        /* Queue Command Function */ \
10209 +    abort:          AAC_AbortCommand,        /* Abort Command Function */ \
10210 +    reset:          AAC_ResetCommand,        /* Reset Command Function */ \
10211 +    bios_param:     AAC_BIOSDiskParameters,  /* BIOS Disk Parameters   */ \
10212 +    can_queue:      1,                       /* Default initial value  */ \
10213 +    this_id:        0,                       /* Default initial value  */ \
10214 +    sg_tablesize:   0,                       /* Default initial value  */ \
10215 +    cmd_per_lun:    0,                       /* Default initial value  */ \
10216 +    present:        0,                       /* Default initial value  */ \
10217 +    unchecked_isa_dma: 0,                    /* Default Initial Value  */ \
10218 +    use_new_eh_code:         0,                  /* Default initial value      */ \
10219 +    eh_abort_handler:        AAC_AbortCommand,   /* New Abort Command func     */ \
10220 +    eh_strategy_handler:     NULL,               /* New Strategy Error Handler */ \
10221 +    eh_device_reset_handler: NULL,               /* New Device Reset Handler   */ \
10222 +    eh_bus_reset_handler:    NULL,               /* New Bus Reset Handler      */ \
10223 +    eh_host_reset_handler:   NULL,               /* New Host reset Handler     */ \
10224 +    use_clustering: ENABLE_CLUSTERING        /* Disable Clustering      */ \
10225 +  }
10226 +
10227 +
10228 +/*------------------------------------------------------------------------------
10229 + *              T Y P E D E F S / S T R U C T S
10230 + *----------------------------------------------------------------------------*/
10231 +typedef struct AAC_BIOS_DiskParameters
10232 +{
10233 +       int heads;
10234 +       int sectors;
10235 +       int cylinders;
10236 +} AAC_BIOS_DiskParameters_T;
10237 +
10238 +
10239 +/*------------------------------------------------------------------------------
10240 + *              P R O G R A M   G L O B A L S
10241 + *----------------------------------------------------------------------------*/
10242 +
10243 +const char *AAC_DriverInfo( struct Scsi_Host * );
10244 +
10245 +
10246 +/*------------------------------------------------------------------------------
10247 + *              F U N C T I O N   P R O T O T Y P E S
10248 + *----------------------------------------------------------------------------*/
10249 +/* Define prototypes for the AAC Driver Interface Functions. */
10250 +int AAC_DetectHostAdapter( Scsi_Host_Template * );
10251 +int AAC_ReleaseHostAdapter( struct Scsi_Host * );
10252 +int AAC_QueueCommand( Scsi_Cmnd *, void ( *CompletionRoutine )( Scsi_Cmnd * ) );
10253 +int AAC_Command( Scsi_Cmnd * );
10254 +int AAC_ResetCommand( Scsi_Cmnd *, unsigned int );
10255 +int AAC_BIOSDiskParameters( Disk *, kdev_t, int * );
10256 +int AAC_ProcDirectoryInfo( char *, char **, off_t, int, int, int );
10257 +int AAC_Ioctl( Scsi_Device *, int, void * );
10258 +
10259 +
10260 +void AAC_SelectQueueDepths(    struct Scsi_Host *, Scsi_Device * );
10261 +
10262 +
10263 +int AAC_AbortCommand( Scsi_Cmnd *scsi_cmnd_ptr );
10264 +
10265 +#endif /* _LINIT_H_ */
10266 diff -urN linux/drivers/scsi/aacraid/include/monkerapi.h linux/drivers/scsi/aacraid/include/monkerapi.h
10267 --- linux/drivers/scsi/aacraid/include/monkerapi.h      Wed Dec 31 19:00:00 1969
10268 +++ linux/drivers/scsi/aacraid/include/monkerapi.h      Thu Dec 21 13:14:30 2000
10269 @@ -0,0 +1,98 @@
10270 +/*++
10271 + * Adaptec aacraid device driver for Linux.
10272 + *
10273 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10274 + *
10275 + * This program is free software; you can redistribute it and/or modify
10276 + * it under the terms of the GNU General Public License as published by
10277 + * the Free Software Foundation; either version 2, or (at your option)
10278 + * any later version.
10279 + *
10280 + * This program is distributed in the hope that it will be useful,
10281 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10282 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10283 + * GNU General Public License for more details.
10284 + *
10285 + * You should have received a copy of the GNU General Public License
10286 + * along with this program; see the file COPYING.  If not, write to
10287 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10288 + *
10289 + * Module Name:
10290 + *   monkerapi.h
10291 + *
10292 + * Abstract: This module contains the definitions used by the Host Adapter
10293 + *      Communications interface.
10294 + *      This is the interface used for by host programs and the Adapter 
10295 + *      to communicate via synchronous commands via a shared set of registers
10296 + *      on a platform (typically doorbells and mailboxes).
10297 + *
10298 + --*/
10299 +//**********************************************************************
10300 +//
10301 +//     Monitor / Kernel API
10302 +//
10303 +//     03/24/1998 Bob Peret    Initial creation
10304 +//
10305 +//**********************************************************************
10306 +
10307 +#ifndef MONKER_H
10308 +#define MONKER_H
10309 +
10310 +static char *ident_monk = "aacraid_ident monkerapi.h 1.0.6 2000/10/09 Adaptec, Inc.";
10311 +
10312 +#define        BREAKPOINT_REQUEST                                      0x00000004
10313 +#define        INIT_STRUCT_BASE_ADDRESS                        0x00000005
10314 +
10315 +
10316 +#define        SEND_SYNCHRONOUS_FIB                            0x0000000c
10317 +
10318 +
10319 +
10320 +//
10321 +//     Adapter Status Register
10322 +//
10323 +//  Phase Staus mailbox is 32bits:
10324 +//     <31:16> = Phase Status
10325 +//     <15:0>  = Phase
10326 +//
10327 +//  The adapter reports is present state through the phase.  Only
10328 +//  a single phase should be ever be set.  Each phase can have multiple
10329 +//     phase status bits to provide more detailed information about the 
10330 +//     state of the board.  Care should be taken to ensure that any phase status 
10331 +//  bits that are set when changing the phase are also valid for the new phase
10332 +//  or be cleared out.  Adapter software (monitor, iflash, kernel) is responsible
10333 +//  for properly maintining the phase status mailbox when it is running.
10334 +
10335 +//                                                                                     
10336 +// MONKER_API Phases                                                   
10337 +//
10338 +// Phases are bit oriented.  It is NOT valid 
10339 +// to have multiple bits set                                           
10340 +//                                     
10341 +
10342 +
10343 +#define        SELF_TEST_FAILED                                        0x00000004
10344 +
10345 +
10346 +#define        KERNEL_UP_AND_RUNNING                           0x00000080
10347 +#define        KERNEL_PANIC                                            0x00000100
10348 +
10349 +
10350 +
10351 +//
10352 +// Doorbell bit defines
10353 +//
10354 +
10355 +
10356 +#define DoorBellPrintfDone                             (1<<5)  // Host -> Adapter
10357 +
10358 +
10359 +#define DoorBellAdapterNormCmdReady            (1<<1)  // Adapter -> Host
10360 +#define DoorBellAdapterNormRespReady   (1<<2)  // Adapter -> Host
10361 +#define DoorBellAdapterNormCmdNotFull  (1<<3)  // Adapter -> Host
10362 +#define DoorBellAdapterNormRespNotFull (1<<4)  // Adapter -> Host
10363 +#define DoorBellPrintfReady                            (1<<5)  // Adapter -> Host
10364 +
10365 +
10366 +#endif // MONKER_H
10367 +
10368 diff -urN linux/drivers/scsi/aacraid/include/nodetype.h linux/drivers/scsi/aacraid/include/nodetype.h
10369 --- linux/drivers/scsi/aacraid/include/nodetype.h       Wed Dec 31 19:00:00 1969
10370 +++ linux/drivers/scsi/aacraid/include/nodetype.h       Thu Dec 21 13:14:30 2000
10371 @@ -0,0 +1,67 @@
10372 +/*++
10373 + * Adaptec aacraid device driver for Linux.
10374 + *
10375 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10376 + *
10377 + * This program is free software; you can redistribute it and/or modify
10378 + * it under the terms of the GNU General Public License as published by
10379 + * the Free Software Foundation; either version 2, or (at your option)
10380 + * any later version.
10381 + *
10382 + * This program is distributed in the hope that it will be useful,
10383 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10384 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10385 + * GNU General Public License for more details.
10386 + *
10387 + * You should have received a copy of the GNU General Public License
10388 + * along with this program; see the file COPYING.  If not, write to
10389 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10390 + *
10391 + * Module Name:
10392 + *   nodetype.h
10393 + *
10394 + * Abstract:     This module defines all of the node type codes used in this development
10395 + *  shell.  Every major data structure in the file system is assigned a node
10396 + *  type code that is.  This code is the first CSHORT in the structure and is
10397 + *  followed by a CSHORT containing the size, in bytes, of the structure.
10398 + *
10399 + --*/
10400 +#ifndef _NODETYPE_
10401 +#define _NODETYPE_
10402 +
10403 +static char *ident_node = "aacraid_ident nodetype.h 1.0.6 2000/10/09 Adaptec, Inc.";
10404 +
10405 +typedef CSHORT NODE_TYPE_CODE;
10406 +
10407 +
10408 +#define FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT ((NODE_TYPE_CODE)0x030b)
10409 +#define FSAFS_NTC_FIB_CONTEXT            ((NODE_TYPE_CODE)0x030c)
10410 +
10411 +
10412 +typedef CSHORT NODE_BYTE_SIZE;
10413 +
10414 +
10415 +//
10416 +//  The following definitions are used to generate meaningful blue bugcheck
10417 +//  screens.  On a bugcheck the file system can output 4 ulongs of useful
10418 +//  information.  The first ulong will have encoded in it a source file id
10419 +//  (in the high word) and the line number of the bugcheck (in the low word).
10420 +//  The other values can be whatever the caller of the bugcheck routine deems
10421 +//  necessary.
10422 +//
10423 +//  Each individual file that calls bugcheck needs to have defined at the
10424 +//  start of the file a constant called BugCheckFileId with one of the
10425 +//  FSAFS_BUG_CHECK_ values defined below and then use FsaBugCheck to bugcheck
10426 +//  the system.
10427 +//
10428 +
10429 +
10430 +#define FSAFS_BUG_CHECK_COMMSUP           (0X001e0000)
10431 +#define FSAFS_BUG_CHECK_DPCSUP            (0X001f0000)
10432 +
10433 +
10434 +#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); }
10435 +
10436 +
10437 +#endif // _NODETYPE_
10438 +
10439 diff -urN linux/drivers/scsi/aacraid/include/nvramioctl.h linux/drivers/scsi/aacraid/include/nvramioctl.h
10440 --- linux/drivers/scsi/aacraid/include/nvramioctl.h     Wed Dec 31 19:00:00 1969
10441 +++ linux/drivers/scsi/aacraid/include/nvramioctl.h     Thu Dec 21 13:14:30 2000
10442 @@ -0,0 +1,112 @@
10443 +/*++
10444 + * Adaptec aacraid device driver for Linux.
10445 + *
10446 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10447 + *
10448 + * This program is free software; you can redistribute it and/or modify
10449 + * it under the terms of the GNU General Public License as published by
10450 + * the Free Software Foundation; either version 2, or (at your option)
10451 + * any later version.
10452 + *
10453 + * This program is distributed in the hope that it will be useful,
10454 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10455 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10456 + * GNU General Public License for more details.
10457 + *
10458 + * You should have received a copy of the GNU General Public License
10459 + * along with this program; see the file COPYING.  If not, write to
10460 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10461 + *
10462 + * Module Name:
10463 + *   nvramioctl.h
10464 + *
10465 + * Abstract: This file defines the data structures related to querying
10466 + *    and controlling the FSA NVRAM/WriteCache subsystem via the NVRAMIOCTL FIB.
10467 + *
10468 + --*/
10469 +#ifndef _NVRAMIOCTL_H_
10470 +#define _NVRAMIOCTL_H_ 1
10471 +
10472 +static char *ident_nvram = "aacraid_ident nvramioctl.h 1.0.6 2000/10/09 Adaptec, Inc.";
10473 +
10474 +/*
10475 + * NVRAM/Write Cache subsystem states
10476 + */
10477 +typedef enum _NVSTATUS {
10478 +       NVSTATUS_DISABLED = 0,  // present, clean, not being used
10479 +       NVSTATUS_ENABLED,               // present, possibly dirty, ready for use
10480 +       NVSTATUS_ERROR,                 // present, dirty, contains dirty data
10481 +                                                       // for bad/missing device
10482 +       NVSTATUS_BATTERY,               // present, bad or low battery, may contain dirty data
10483 +                                                       // for bad/missing device
10484 +       NVSTATUS_UNKNOWN                // present?????
10485 +} _E_NVSTATUS;
10486 +
10487 +#ifdef AAC_32BIT_ENUMS
10488 +typedef _E_NVSTATUS    NVSTATUS;
10489 +#else
10490 +typedef AAC_UINT32     NVSTATUS;
10491 +#endif
10492 +
10493 +/*
10494 + * NVRAM/Write Cache subsystem battery component states
10495 + *
10496 + */
10497 +//NB: this enum should be identical to battery_status in nvram.h
10498 +//       or else collapsed into one enum someday
10499 +typedef enum _NVBATTSTATUS {
10500 +       NVBATTSTATUS_NONE = 0,  // battery has no power or is not present
10501 +       NVBATTSTATUS_LOW,               // battery is low on power
10502 +       NVBATTSTATUS_OK,                        // battery is okay - normal operation possible only in this state
10503 +       NVBATTSTATUS_RECONDITIONING     // no battery present - reconditioning in process
10504 +} _E_NVBATTSTATUS;
10505 +
10506 +#ifdef AAC_32BIT_ENUMS
10507 +typedef        _E_NVBATTSTATUS NVBATTSTATUS;
10508 +#else
10509 +typedef AAC_UINT32             NVBATTSTATUS;
10510 +#endif
10511 +
10512 +/*
10513 + * battery transition type
10514 + */
10515 +typedef enum _NVBATT_TRANSITION {
10516 +       NVBATT_TRANSITION_NONE = 0,     // battery now has no power or is not present
10517 +       NVBATT_TRANSITION_LOW,          // battery is now low on power
10518 +       NVBATT_TRANSITION_OK            // battery is now okay - normal operation possible only in this state
10519 +} _E_NVBATT_TRANSITION;
10520 +
10521 +#ifdef AAC_32BIT_ENUMS
10522 +typedef _E_NVBATT_TRANSITION   NVBATT_TRANSITION;
10523 +#else
10524 +typedef        AAC_UINT32                              NVBATT_TRANSITION;
10525 +#endif
10526 +
10527 +/*
10528 + * NVRAM Info structure returned for NVRAM_GetInfo call
10529 + */
10530 +typedef struct _NVRAMDEVINFO {
10531 +       AAC_UINT32              NV_Enabled;             /* write caching enabled */
10532 +       AAC_UINT32              NV_Error;               /* device in error state */
10533 +       AAC_UINT32              NV_NDirty;              /* count of dirty NVRAM buffers */
10534 +       AAC_UINT32              NV_NActive;             /* count of NVRAM buffers being written */
10535 +} NVRAMDEVINFO, *PNVRAMDEVINFO;
10536 +
10537 +typedef struct _NVRAMINFO {
10538 +       NVSTATUS                NV_Status;                              /* nvram subsystem status */
10539 +       NVBATTSTATUS    NV_BattStatus;                  /* battery status */
10540 +       AAC_UINT32              NV_Size;                                /* size of WriteCache NVRAM in bytes */
10541 +       AAC_UINT32              NV_BufSize;                             /* size of NVRAM buffers in bytes */
10542 +       AAC_UINT32              NV_NBufs;                               /* number of NVRAM buffers */
10543 +       AAC_UINT32              NV_NDirty;                              /* count of dirty NVRAM buffers */
10544 +       AAC_UINT32              NV_NClean;                              /* count of clean NVRAM buffers */
10545 +       AAC_UINT32              NV_NActive;                             /* count of NVRAM buffers being written */
10546 +       AAC_UINT32              NV_NBrokered;                   /* count of brokered NVRAM buffers */
10547 +       NVRAMDEVINFO    NV_DevInfo[NFILESYS];   /* per device info */
10548 +       AAC_UINT32              NV_BattNeedsReconditioning;     /* boolean */
10549 +       AAC_UINT32              NV_TotalSize;                   /* total size of all non-volatile memories in bytes */
10550 +} NVRAMINFO, *PNVRAMINFO;
10551 +
10552 +#endif /* !_NVRAMIOCTL_H_ */
10553 +
10554 +
10555 diff -urN linux/drivers/scsi/aacraid/include/osheaders.h linux/drivers/scsi/aacraid/include/osheaders.h
10556 --- linux/drivers/scsi/aacraid/include/osheaders.h      Wed Dec 31 19:00:00 1969
10557 +++ linux/drivers/scsi/aacraid/include/osheaders.h      Thu Dec 21 13:14:30 2000
10558 @@ -0,0 +1,150 @@
10559 +/*++
10560 + * Adaptec aacraid device driver for Linux.
10561 + *
10562 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10563 + *
10564 + * This program is free software; you can redistribute it and/or modify
10565 + * it under the terms of the GNU General Public License as published by
10566 + * the Free Software Foundation; either version 2, or (at your option)
10567 + * any later version.
10568 + *
10569 + * This program is distributed in the hope that it will be useful,
10570 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10571 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10572 + * GNU General Public License for more details.
10573 + *
10574 + * You should have received a copy of the GNU General Public License
10575 + * along with this program; see the file COPYING.  If not, write to
10576 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10577 + *
10578 + * Module Name:
10579 + *   osheaders.h
10580 + *
10581 + * Abstract: Holds all of the header file includes for a particular O/S flavor.
10582 + *
10583 + --*/
10584 +#ifndef _OSHEADERS_H_
10585 +#define _OSHEADERS_H_
10586 +
10587 +static char *ident_oshead = "aacraid_ident osheaders.h 1.0.6 2000/10/09 Adaptec, Inc.";
10588 +
10589 +#include <linux/autoconf.h>    // retrieve the kernel configuration info
10590 +#if defined( CONFIG_MODVERSIONS ) && !defined( MODVERSIONS )
10591 +#define MODVERSIONS    // force it on
10592 +#endif
10593 +
10594 +#include <linux/version.h>
10595 +
10596 +#if defined( MODVERSIONS ) && defined( MODULE )
10597 +#if DRIVER_KERNEL_CODE >= KERNEL_VERSION(2,2,12)
10598 +#ifdef __SMP__
10599 +#include <linux/modversions-smp.h>
10600 +#elif defined( BOOT_DRIVER ) 
10601 +#include <linux/modversions-BOOT.h>
10602 +#else 
10603 +#include <linux/modversions-up.h>
10604 +#endif // ifdef __SMP__
10605 +#else
10606 +#include <linux/modversions.h>
10607 +#endif
10608 +#endif
10609 +
10610 +
10611 +#include <linux/kernel.h>
10612 +#include <linux/config.h>
10613 +#include <linux/init.h>
10614 +#include <linux/types.h>
10615 +#include <linux/blk.h>
10616 +#include <linux/blkdev.h>
10617 +#include <linux/delay.h>
10618 +#include <linux/ioport.h>
10619 +#include <linux/mm.h>
10620 +#include <linux/sched.h>
10621 +#include <linux/stat.h>
10622 +#include <linux/pci.h>
10623 +#include <linux/interrupt.h>
10624 +#include <asm/dma.h>
10625 +#include <asm/io.h>
10626 +#include <linux/spinlock.h>
10627 +#include <asm/system.h>
10628 +#include <asm/bitops.h>
10629 +#include <asm/uaccess.h>
10630 +#include <linux/wait.h>
10631 +#include <linux/malloc.h>
10632 +#include <linux/tqueue.h>
10633 +/* bmb fix
10634 +#include <linux/tasks.h>
10635 +*/
10636 +#include <ostypes.h>
10637 +#include "scsi.h"
10638 +#include "hosts.h"
10639 +
10640 +#ifndef intptr_t
10641 +#define intptr_t void *
10642 +#endif
10643 +
10644 +#ifndef cred_t
10645 +#define cred_t void
10646 +#endif
10647 +
10648 +#ifndef paddr32_t
10649 +#define paddr32_t unsigned
10650 +#endif
10651 +
10652 +#ifndef bzero 
10653 +#define bzero(b,len) memset(b,0,len)
10654 +#endif
10655 +
10656 +#ifndef bcopy
10657 +#define bcopy(src,dst,len) memcpy(dst,src,len )
10658 +#endif
10659 +
10660 +#ifndef DEVICE_NR
10661 +#define DEVICE_NR(device) ( ( ( MAJOR( device ) & 7 ) << 4 ) + ( MINOR( device ) >> 4 ) )
10662 +#endif
10663 +
10664 +typedef unsigned uint_t;
10665 +
10666 +typedef enum
10667 +{
10668 +       CE_PANIC = 0,
10669 +       CE_WARN,
10670 +       CE_NOTE, 
10671 +       CE_CONT, 
10672 +       CE_DEBUG,
10673 +       CE_DEBUG2,
10674 +       CE_TAIL
10675 +} CE_ENUM_T;
10676 +
10677 +#define CMN_ERR_LEVEL CE_NOTE
10678 +
10679 +#ifndef IN
10680 +#define IN
10681 +#endif
10682 +
10683 +// usage of READ & WRITE as a typedefs in protocol.h
10684 +// conflicts with <linux/fs.h> definition.
10685 +#ifdef READ
10686 +#undef READ
10687 +#endif
10688 +
10689 +#ifdef WRITE
10690 +#undef WRITE
10691 +#endif
10692 +
10693 +typedef struct aac_options
10694 +{
10695 +       int message_level;
10696 +       int reverse_scan; 
10697 +} aac_options_t;
10698 +
10699 +#endif // _OSHEADERS_H_
10700 +
10701 +
10702 +
10703 +
10704 +
10705 +
10706 +
10707 +
10708 +
10709 diff -urN linux/drivers/scsi/aacraid/include/ostypes.h linux/drivers/scsi/aacraid/include/ostypes.h
10710 --- linux/drivers/scsi/aacraid/include/ostypes.h        Wed Dec 31 19:00:00 1969
10711 +++ linux/drivers/scsi/aacraid/include/ostypes.h        Thu Dec 21 13:14:30 2000
10712 @@ -0,0 +1,149 @@
10713 +/*++
10714 + * Adaptec aacraid device driver for Linux.
10715 + *
10716 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10717 + *
10718 + * This program is free software; you can redistribute it and/or modify
10719 + * it under the terms of the GNU General Public License as published by
10720 + * the Free Software Foundation; either version 2, or (at your option)
10721 + * any later version.
10722 + *
10723 + * This program is distributed in the hope that it will be useful,
10724 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10725 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10726 + * GNU General Public License for more details.
10727 + *
10728 + * You should have received a copy of the GNU General Public License
10729 + * along with this program; see the file COPYING.  If not, write to
10730 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10731 + *
10732 + * Module Name:
10733 + *   ostypes.h
10734 + *
10735 + * Abstract: Holds all of the O/S specific types.
10736 + *
10737 + --*/
10738 +/*------------------------------------------------------------------------------
10739 + *              D E F I N E S
10740 + *----------------------------------------------------------------------------*/
10741 +#ifndef _OSTYPES_H_
10742 +#define _OSTYPES_H_
10743 +
10744 +static char *ident_ostypes = "aacraid_ident ostypes.h 1.0.7 2000/10/11 Adaptec, Inc.";
10745 +
10746 +#include <linux/types.h>
10747 +
10748 +#define MAXIMUM_NUM_CONTAINERS 64              // 4 Luns * 16 Targets
10749 +#define MAXIMUM_NUM_ADAPTERS   8
10750 +
10751 +#define OS_ALLOC_MEM_SLEEP             GFP_KERNEL
10752 +
10753 +#define Os_remove_softintr OsSoftInterruptRemove
10754 +#define OsPrintf printk
10755 +#define FsaCommPrint
10756 +
10757 +// the return values for copy_from_user & copy_to_user is the 
10758 +// number of bytes not transferred. Thus if an internal error 
10759 +// occurs, the return value is greater than zero.
10760 +#define COPYIN(SRC,DST,COUNT,FLAGS)  copy_from_user(DST,SRC,COUNT)
10761 +#define COPYOUT(SRC,DST,COUNT,FLAGS) copy_to_user(DST,SRC,COUNT)
10762 +
10763 +#define copyin(SRC,DST,COUNT) copy_from_user(DST,SRC,COUNT)
10764 +#define copyout(SRC,DST,COUNT) copy_to_user(DST,SRC,COUNT)
10765 +
10766 +/*------------------------------------------------------------------------------
10767 + *              S T R U C T S / T Y P E D E F S
10768 + *----------------------------------------------------------------------------*/
10769 +typedef struct OS_MUTEX
10770 +{
10771 +       unsigned long lock_var;
10772 +       wait_queue_head_t wq;
10773 +       unsigned owner;
10774 +} OS_MUTEX;
10775 +
10776 +typedef        struct OS_SPINLOCK
10777 +{
10778 +       spinlock_t      spin_lock;
10779 +       unsigned cpu_lock_count[NR_CPUS];
10780 +       long cpu_flag;
10781 +       long lockout_count;
10782 +} OS_SPINLOCK;
10783 +
10784 +#ifdef CVLOCK_USE_SPINLOCK
10785 +       typedef OS_SPINLOCK OS_CVLOCK;
10786 +#else
10787 +       typedef OS_MUTEX OS_CVLOCK;
10788 +#endif
10789 +
10790 +typedef size_t         OS_SIZE_T;
10791 +
10792 +typedef        struct OS_CV_T
10793 +{
10794 +       unsigned long lock_var;
10795 +       unsigned long type;
10796 +       wait_queue_head_t wq;   
10797 +} OS_CV_T;
10798 +
10799 +struct fsa_scsi_hba {
10800 +       void                            *CommonExtension;
10801 +       unsigned long           ContainerSize[MAXIMUM_NUM_CONTAINERS];
10802 +       unsigned long           ContainerType[MAXIMUM_NUM_CONTAINERS];
10803 +       unsigned char           ContainerValid[MAXIMUM_NUM_CONTAINERS];
10804 +       unsigned char           ContainerReadOnly[MAXIMUM_NUM_CONTAINERS];
10805 +       unsigned char           ContainerLocked[MAXIMUM_NUM_CONTAINERS];
10806 +       unsigned char           ContainerDeleted[MAXIMUM_NUM_CONTAINERS];
10807 +       long                            ContainerDevNo[MAXIMUM_NUM_CONTAINERS];
10808 +};
10809 +
10810 +typedef struct fsa_scsi_hba fsadev_t;
10811 +
10812 +typedef struct OsKI
10813 +{
10814 +       struct Scsi_Host *scsi_host_ptr;
10815 +       void * dip;     // #REVISIT#
10816 +       fsadev_t fsa_dev;
10817 +       int thread_pid;
10818 +  int    MiniPortIndex;
10819 +} OsKI_t;
10820 +
10821 +#define dev_info_t     fsadev_t
10822 +
10823 +typedef int    OS_SPINLOCK_COOKIE;
10824 +
10825 +typedef unsigned int   OS_STATUS;
10826 +
10827 +typedef struct tq_struct OS_SOFTINTR;
10828 +
10829 +typedef        OS_SOFTINTR     *ddi_softintr_t;
10830 +
10831 +
10832 +
10833 +//-----------------------------------------------------------------------------
10834 +// Conditional variable functions
10835 +
10836 +void OsCv_init ( 
10837 +       OS_CV_T *cv_ptr );
10838 +
10839 +
10840 +//-----------------------------------------------------------------------------
10841 +// Printing functions
10842 +void printk_err(int flag, char *fmt, ...);
10843 +
10844 +#define cmn_err printk_err
10845 +
10846 +
10847 +//
10848 +// just ignore these solaris ddi functions in the code
10849 +//
10850 +#define DDI_SUCCESS                                            0
10851 +
10852 +#define ddi_add_softintr(A,B,C,D,E,F,G)                OsSoftInterruptAdd(C,F,G)
10853 +
10854 +//#REVIEW#
10855 +#define ddi_remove_softintr(A)                         0
10856 +#define ddi_get_soft_iblock_cookie(A, B, C)    0
10857 +
10858 +#define ASSERT(expr) ((void) 0)
10859 +#define drv_usecwait udelay
10860 +
10861 +#endif // _OSTYPES_H_
10862 diff -urN linux/drivers/scsi/aacraid/include/pcisup.h linux/drivers/scsi/aacraid/include/pcisup.h
10863 --- linux/drivers/scsi/aacraid/include/pcisup.h Wed Dec 31 19:00:00 1969
10864 +++ linux/drivers/scsi/aacraid/include/pcisup.h Thu Dec 21 13:14:30 2000
10865 @@ -0,0 +1,97 @@
10866 +/*++
10867 + * Adaptec aacraid device driver for Linux.
10868 + *
10869 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10870 + *
10871 + * This program is free software; you can redistribute it and/or modify
10872 + * it under the terms of the GNU General Public License as published by
10873 + * the Free Software Foundation; either version 2, or (at your option)
10874 + * any later version.
10875 + *
10876 + * This program is distributed in the hope that it will be useful,
10877 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10878 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10879 + * GNU General Public License for more details.
10880 + *
10881 + * You should have received a copy of the GNU General Public License
10882 + * along with this program; see the file COPYING.  If not, write to
10883 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10884 + *
10885 + * Module Name:
10886 + *   pcisup.h
10887 + *
10888 + * Abstract: This module defines functions that are defined in PciSup.c
10889 + *
10890 + --*/
10891 +#ifndef _PCISUP_
10892 +#define _PCISUP_
10893 +
10894 +static char *ident_pcisup = "aacraid_ident pcisup.h 1.0.6 2000/10/09 Adaptec, Inc.";
10895 +
10896 +       
10897 +/*
10898 + * define which interrupt handler needs to be installed
10899 + */
10900 +
10901 +#define SaISR  1
10902 +#define RxISR  2
10903 +
10904 +typedef struct _PCI_MINIPORT_COMMON_EXTENSION {
10905 +       ULONG                                   AdapterNumber;                  // Which FSA# this miniport is
10906 +       
10907 +       ULONG                                   PciBusNumber;                   // Which PCI bus we are located on
10908 +       ULONG                                   PciSlotNumber;                  // Whiat PCI slot we are in
10909 +       
10910 +       PVOID                                   Adapter;                                // Back pointer to Fsa adapter object
10911 +       ULONG                                   AdapterIndex;                   // Index into PlxAdapterTypes array
10912 +       PDEVICE_OBJECT                  DeviceObject;                   // Pointer to our device object
10913 +       
10914 +       FSAPORT_FUNCS                   AdapterFuncs;
10915 +       ULONG                                   FilesystemRevision;     // Main driver's revision number
10916 +       
10917 +       
10918 +       PADAPTER_INIT_STRUCT    InitStruct;                             // Holds initialization info to communicate with adapter
10919 +       PVOID                                   PhysicalInitStruct;     // Holds physical address of the init struct
10920 +       
10921 +       
10922 +       PVOID                                   PrintfBufferAddress;    // pointer to buffer used for printf's from the adapter
10923 +       
10924 +       BOOLEAN                                 AdapterPrintfsToScreen;                 
10925 +       BOOLEAN                                 AdapterConfigured;              // set to true when we know adapter can take FIBs
10926 +       
10927 +       void *                                  MiniPort;
10928 +       
10929 +       caddr_t                                 CommAddress;    // Base address of Comm area
10930 +       paddr32_t                               CommPhysAddr;   // Physical Address of Comm area
10931 +       size_t                                  CommSize;
10932 +
10933 +       OsKI_t                                  OsDep;                  // OS dependent kernel interfaces
10934 +
10935 +       
10936 +} PCI_MINIPORT_COMMON_EXTENSION;
10937 +
10938 +typedef PCI_MINIPORT_COMMON_EXTENSION *PPCI_MINIPORT_COMMON_EXTENSION;
10939 +
10940 +typedef int
10941 +(*PFSA_MINIPORT_INIT) (
10942 +       IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
10943 +       IN ULONG AdapterNumber,
10944 +       IN ULONG PciBus,
10945 +       IN ULONG PciSlot
10946 +       );
10947 +
10948 +typedef struct _FSA_MINIPORT {
10949 +       USHORT                          VendorId;
10950 +       USHORT                          DeviceId;
10951 +       USHORT                          SubVendorId;
10952 +       USHORT                          SubSystemId;
10953 +       PCHAR                           DevicePrefix;
10954 +  PFSA_MINIPORT_INIT   InitRoutine;
10955 +  PCHAR               DeviceName;
10956 +  PCHAR               Vendor;
10957 +  PCHAR               Model;
10958 +} FSA_MINIPORT;
10959 +typedef FSA_MINIPORT *PFSA_MINIPORT;
10960 +
10961 +
10962 +#endif // _PCISUP_
10963 diff -urN linux/drivers/scsi/aacraid/include/perfpack.h linux/drivers/scsi/aacraid/include/perfpack.h
10964 --- linux/drivers/scsi/aacraid/include/perfpack.h       Wed Dec 31 19:00:00 1969
10965 +++ linux/drivers/scsi/aacraid/include/perfpack.h       Thu Dec 21 13:14:30 2000
10966 @@ -0,0 +1,110 @@
10967 +/*++
10968 + * Adaptec aacraid device driver for Linux.
10969 + *
10970 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10971 + *
10972 + * This program is free software; you can redistribute it and/or modify
10973 + * it under the terms of the GNU General Public License as published by
10974 + * the Free Software Foundation; either version 2, or (at your option)
10975 + * any later version.
10976 + *
10977 + * This program is distributed in the hope that it will be useful,
10978 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10979 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10980 + * GNU General Public License for more details.
10981 + *
10982 + * You should have received a copy of the GNU General Public License
10983 + * along with this program; see the file COPYING.  If not, write to
10984 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10985 + *
10986 + * Module Name:
10987 + *   perfpack.h
10988 + *
10989 + * Abstract: This file defines the layout of the performance data that is passed
10990 + *           back from the FSA filesystem driver.
10991 + *
10992 + *     
10993 + --*/
10994 +
10995 +#ifndef _FSA_PERFPACK_H_
10996 +#define _FSA_PERFPACK_H_       1
10997 +
10998 +static char *ident_perf = "aacraid_ident perfpack.h 1.0.6 2000/10/09 Adaptec, Inc.";
10999 +
11000 +//#define FSA_DO_PERF          1               /* enable the engineering counters */
11001 +
11002 +#ifdef FSA_DO_PERF
11003 +//
11004 +// engineering counters
11005 +//
11006 +typedef struct _FSA_PERF_DATA {
11007 +                       ULONG FibsSent;
11008 +                       ULONG ReadDirs;
11009 +                       ULONG GetAttrs;
11010 +                       ULONG SetAttrs;
11011 +                       ULONG Lookups;
11012 +                       ULONG ReadFibs;
11013 +                       ULONG WriteFibs;
11014 +                       ULONG CreateFibs;
11015 +                       ULONG MakeDirs;
11016 +                       ULONG RemoveFibs;
11017 +                       ULONG RemoveDirs;
11018 +                       ULONG RenameFibs;
11019 +                       ULONG ReadDirPlus;
11020 +                       ULONG FsStat;
11021 +                       ULONG WriteBytes;
11022 +                       ULONG ReadBytes;
11023 +// NT FSA entry points
11024 +                       ULONG FsaFsdCreateCount;
11025 +                       ULONG FsaFsdCloseCount;
11026 +                       ULONG FsaFsdReadCount;
11027 +                       ULONG FsaFsdWriteCount;
11028 +                       ULONG FsaFsdQueryInformationCount;
11029 +
11030 +                       struct _FsaFsdSetInfomation{
11031 +                               ULONG FsaSetAllocationInfoCount;
11032 +                               ULONG FsaSetBasicInfoCount;
11033 +                               ULONG FsaSetDispositionInfoCount;
11034 +                               ULONG FsaSetEndOfFileInfoCount;
11035 +                               ULONG FsaSetPositionInfoCount;
11036 +                               ULONG FsaSetRenameInfoCount;
11037 +                               ULONG FsaClearArchiveBitCount;
11038 +                       };
11039 +
11040 +                       ULONG FsaFsdFlushBuffersCount;
11041 +                       ULONG FsaFsdQueryVolumeInfoCount;
11042 +                       ULONG FsaFsdSetVolumeInfoCount;
11043 +                       ULONG FsaFsdCleanupCount;
11044 +                       ULONG FsaFsdDirectoryControlCount;
11045 +                       ULONG FsaFsdFileSystemControlCount;
11046 +                       ULONG FsaFsdLockControlCount;
11047 +                       ULONG FsaFsdDeviceControlCount;
11048 +                       ULONG FsaFsdShutdownCount;
11049 +                       ULONG FsaFsdQuerySecurityInfo;
11050 +                       ULONG FsaFsdSetSecurityInfo;
11051 +                       ULONG FastIoCheckIfPossibleCount;
11052 +                       ULONG FastIoReadCount;
11053 +                       ULONG FastIoWriteCount;
11054 +                       ULONG FastIoQueryBasicInfoCount;
11055 +                       ULONG FastIoQueryStandardInfoCount;
11056 +                       ULONG FastIoLockCount;
11057 +                       ULONG FastIoUnlockSingleCount;
11058 +                       ULONG FastIoUnlockAllCount;
11059 +                       ULONG FastIoUnlockAllByKeyCount;
11060 +                       ULONG FastIoDeviceControlCount;
11061 + } FSA_PERF_DATA;
11062 +
11063 +typedef FSA_PERF_DATA *PFSA_PERF_DATA;
11064 +
11065 +
11066 +#else /* FSA_DO_PERF */
11067 +
11068 +//
11069 +// engineering performance counters are disabled
11070 +//
11071 +#define FSA_DO_PERF_INC(Counter)               /* */
11072 +#define FSA_DO_FSP_PERF_INC(Counter)   /* */
11073 +
11074 +#endif /* FSA_DO_PERF */
11075 +
11076 +#endif // _FSA_PERFPACK_H_
11077 diff -urN linux/drivers/scsi/aacraid/include/port.h linux/drivers/scsi/aacraid/include/port.h
11078 --- linux/drivers/scsi/aacraid/include/port.h   Wed Dec 31 19:00:00 1969
11079 +++ linux/drivers/scsi/aacraid/include/port.h   Thu Dec 21 13:14:30 2000
11080 @@ -0,0 +1,87 @@
11081 +/*++
11082 + * Adaptec aacraid device driver for Linux.
11083 + *
11084 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11085 + *
11086 + * This program is free software; you can redistribute it and/or modify
11087 + * it under the terms of the GNU General Public License as published by
11088 + * the Free Software Foundation; either version 2, or (at your option)
11089 + * any later version.
11090 + *
11091 + * This program is distributed in the hope that it will be useful,
11092 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11093 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11094 + * GNU General Public License for more details.
11095 + *
11096 + * You should have received a copy of the GNU General Public License
11097 + * along with this program; see the file COPYING.  If not, write to
11098 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11099 + *
11100 + * Module Name:
11101 + *   port.h
11102 + *
11103 + * Abstract: This module defines functions and structures that are in common among all miniports
11104 + *
11105 + *     
11106 + --*/
11107 +
11108 +#ifndef _PORT_
11109 +#define _PORT_
11110 +
11111 +static char *ident_porth = "aacraid_ident port.h 1.0.6 2000/10/09 Adaptec, Inc.";
11112 +
11113 +#ifdef DBG
11114 +#define AfaPortPrint if (AfaPortPrinting) DbgPrint
11115 +extern int AfaPortPrinting;
11116 +#else
11117 +#define AfaPortPrint 
11118 +#endif DBG
11119 +
11120 +extern int AfaPortPrinting;
11121 +
11122 +
11123 +BOOLEAN
11124 +AfaPortAllocateAdapterCommArea(
11125 +       IN PVOID                Arg1,
11126 +       IN OUT PVOID    *CommHeaderAddress,
11127 +       IN ULONG                CommAreaSize,
11128 +       IN ULONG                CommAreaAlignment
11129 +       );
11130 +
11131 +
11132 +BOOLEAN
11133 +AfaPortFreeAdapterCommArea(
11134 +       IN PVOID                Arg1
11135 +       );
11136 +
11137 +
11138 +AAC_STATUS
11139 +AfaPortBuildSgMap(
11140 +       PVOID Arg1,
11141 +       IN PSGMAP_CONTEXT SgMapContext
11142 +       );
11143 +
11144 +
11145 +VOID
11146 +AfaPortFreeDmaResources(
11147 +       PVOID Arg1,
11148 +    IN PSGMAP_CONTEXT SgMapContext
11149 +    );
11150 +
11151 +
11152 +BOOLEAN
11153 +AfaPortAllocateAndMapFibSpace(
11154 +       PVOID Arg1,
11155 +    IN PMAPFIB_CONTEXT MapFibContext
11156 +    );
11157 +
11158 +
11159 +BOOLEAN
11160 +AfaPortUnmapAndFreeFibSpace(
11161 +       PVOID Arg1,
11162 +    IN PMAPFIB_CONTEXT MapFibContext
11163 +    );
11164 +
11165 +
11166 +#endif // _PORT_
11167 +
11168 diff -urN linux/drivers/scsi/aacraid/include/protocol.h linux/drivers/scsi/aacraid/include/protocol.h
11169 --- linux/drivers/scsi/aacraid/include/protocol.h       Wed Dec 31 19:00:00 1969
11170 +++ linux/drivers/scsi/aacraid/include/protocol.h       Thu Dec 21 13:14:30 2000
11171 @@ -0,0 +1,249 @@
11172 +/*++
11173 + * Adaptec aacraid device driver for Linux.
11174 + *
11175 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11176 + *
11177 + * This program is free software; you can redistribute it and/or modify
11178 + * it under the terms of the GNU General Public License as published by
11179 + * the Free Software Foundation; either version 2, or (at your option)
11180 + * any later version.
11181 + *
11182 + * This program is distributed in the hope that it will be useful,
11183 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11184 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11185 + * GNU General Public License for more details.
11186 + *
11187 + * You should have received a copy of the GNU General Public License
11188 + * along with this program; see the file COPYING.  If not, write to
11189 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11190 + *
11191 + * Module Name:
11192 + *   protocol.h
11193 + *
11194 + * Abstract: Defines the commands and command data which enables the nt
11195 + *    filesystem driver to be the client of the fsa adapter
11196 + *    filesystem. This protocol is largely modeled after the NFS
11197 + *    V3 protocol with modifications allowed due to the unique
11198 + *    client/server model FSA works under.
11199 + *
11200 + *
11201 + *     
11202 + --*/
11203 +
11204 +#ifndef _PROTOCOL_H_
11205 +#define _PROTOCOL_H_
11206 +
11207 +static char *ident_protocol = "aacraid_ident protocol.h 1.0.6 2000/10/09 Adaptec, Inc.";
11208 +
11209 +#include <fsafs.h>      // definition of FSAFID; includes fsatypes.h
11210 +#include <nvramioctl.h> // for NVRAMINFO definition
11211 +
11212 +// #define MDL_READ_WRITE
11213 +
11214 +//
11215 +// Define the command values
11216 +//
11217 +typedef enum _FSA_COMMANDS {
11218 +        Null = 0,
11219 +        GetAttributes,
11220 +        SetAttributes,
11221 +        Lookup,
11222 +        ReadLink,
11223 +        Read,
11224 +        Write,
11225 +        Create,
11226 +        MakeDirectory,
11227 +        SymbolicLink,
11228 +        MakeNode,
11229 +        Removex,
11230 +        RemoveDirectoryx, // bkpfix added x to this because already defined in nt
11231 +        Rename,
11232 +        Link,
11233 +        ReadDirectory,
11234 +        ReadDirectoryPlus,
11235 +        FileSystemStatus,
11236 +        FileSystemInfo,
11237 +        PathConfigure,
11238 +        Commit,
11239 +        Mount,
11240 +        UnMount,
11241 +        Newfs,
11242 +        FsCheck,
11243 +        FsSync,
11244 +               SimReadWrite,
11245 +               SetFileSystemStatus,
11246 +               BlockRead,
11247 +               BlockWrite,
11248 +               NvramIoctl,
11249 +               FsSyncWait,
11250 +               ClearArchiveBit,
11251 +#ifdef MDL_READ_WRITE
11252 +               MdlReadComplete,
11253 +               MdlWriteComplete,
11254 +               MdlRead,                        // these are used solely for stats, Mdl really controlled by 
11255 +               MdlWrite,                       // flags field in Fib.
11256 +#endif
11257 +               SetAcl,
11258 +               GetAcl,
11259 +               AssignAcl,
11260 +               FaultInsertion,         // Fault Insertion Command
11261 +               CrazyCache,                     // crazycache
11262 +               MAX_FSACOMMAND_NUM      //CJ: used for sizing stats array - leave last
11263 +} _E_FSACOMMAND;
11264 +
11265 +#ifdef AAC_32BIT_ENUMS
11266 +typedef        _E_FSACOMMAND   FSACOMMAND;
11267 +#else
11268 +typedef AAC_UINT32             FSACOMMAND;
11269 +#endif
11270 +
11271 +
11272 +
11273 +//
11274 +// Define the status returns
11275 +//
11276 +// See include\comm\errno.h for adapter kernel errno's
11277 +typedef enum _FSASTATUS {
11278 +       ST_OK = 0,
11279 +       ST_PERM = 1,
11280 +       ST_NOENT = 2,
11281 +       ST_IO = 5,
11282 +       ST_NXIO = 6,
11283 +       ST_E2BIG = 7,
11284 +       ST_ACCES = 13,
11285 +       ST_EXIST = 17,
11286 +       ST_XDEV = 18,
11287 +       ST_NODEV = 19,
11288 +       ST_NOTDIR = 20,
11289 +       ST_ISDIR = 21,
11290 +       ST_INVAL = 22,
11291 +       ST_FBIG = 27,
11292 +       ST_NOSPC = 28,
11293 +       ST_ROFS = 30,
11294 +       ST_MLINK = 31,
11295 +       ST_WOULDBLOCK = 35,
11296 +       ST_NAMETOOLONG = 63,
11297 +       ST_NOTEMPTY = 66,
11298 +       ST_DQUOT = 69,
11299 +       ST_STALE = 70,
11300 +       ST_REMOTE = 71,
11301 +       ST_BADHANDLE = 10001,
11302 +       ST_NOT_SYNC = 10002,
11303 +       ST_BAD_COOKIE = 10003,
11304 +       ST_NOTSUPP = 10004,
11305 +       ST_TOOSMALL = 10005,
11306 +       ST_SERVERFAULT = 10006,
11307 +       ST_BADTYPE = 10007,
11308 +       ST_JUKEBOX = 10008,
11309 +       ST_NOTMOUNTED = 10009,
11310 +       ST_MAINTMODE = 10010,
11311 +       ST_STALEACL = 10011
11312 +} _E_FSASTATUS;
11313 +
11314 +#ifdef AAC_32BIT_ENUMS
11315 +typedef _E_FSASTATUS   FSASTATUS;
11316 +#else
11317 +typedef        AAC_UINT32              FSASTATUS;
11318 +#endif
11319 +
11320 +//
11321 +// On writes how does the client want the data written.
11322 +//
11323 +
11324 +typedef enum _CACHELEVEL {
11325 +       CSTABLE = 1,
11326 +    CUNSTABLE
11327 +} _E_CACHELEVEL;
11328 +
11329 +#ifdef AAC_32BIT_ENUMS
11330 +typedef _E_CACHELEVEL  CACHELEVEL;
11331 +#else
11332 +typedef        AAC_UINT32              CACHELEVEL;
11333 +#endif
11334 +
11335 +//
11336 +// Lets the client know at which level the data was commited on a write request
11337 +//
11338 +
11339 +typedef enum _COMMITLEVEL {
11340 +    CMFILE_SYNCH_NVRAM = 1,
11341 +    CMDATA_SYNCH_NVRAM,
11342 +    CMFILE_SYNCH,
11343 +    CMDATA_SYNCH,
11344 +    CMUNSTABLE
11345 +} _E_COMMITLEVEL;
11346 +
11347 +#ifdef AAC_32BIT_ENUMS
11348 +typedef _E_COMMITLEVEL COMMITLEVEL;
11349 +#else
11350 +typedef AAC_UINT32             COMMITLEVEL;
11351 +#endif
11352 +
11353 +
11354 +
11355 +//
11356 +// The following are all the different commands or FIBs which can be sent to the
11357 +// FSA filesystem. We will define a required subset which cannot return STATUS_NOT_IMPLEMENTED,
11358 +// but others outside that subset are allowed to return not implemented. The client is then
11359 +// responsible for dealing with the fact it is not implemented.
11360 +//
11361 +typedef AAC_INT8 FSASTRING[16];
11362 +
11363 +
11364 +typedef AAC_UINT32     BYTECOUNT;      // only 32 bit-ism
11365 +
11366 +
11367 +
11368 +//
11369 +// BlockRead
11370 +//
11371 +
11372 +typedef struct _BLOCKREAD { // variable size struct
11373 +
11374 +    FSACOMMAND                 Command;
11375 +    AAC_UINT32                 ContainerId;
11376 +    BYTECOUNT          BlockNumber;
11377 +    BYTECOUNT          ByteCount;
11378 +       SGMAP                   SgMap;  // Must be last in struct because it is variable
11379 +
11380 +} BLOCKREAD;
11381 +typedef BLOCKREAD *PBLOCKREAD;
11382 +
11383 +typedef struct _BLOCKREADRESPONSE {
11384 +
11385 +    FSASTATUS          Status;
11386 +    BYTECOUNT          ByteCount;
11387 +
11388 +} BLOCKREADRESPONSE;
11389 +typedef BLOCKREADRESPONSE *PBLOCKREADRESPONSE;
11390 +
11391 +//
11392 +// BlockWrite
11393 +//
11394 +
11395 +typedef struct _BLOCKWRITE {   // variable size struct
11396 +
11397 +    FSACOMMAND                 Command;
11398 +    AAC_UINT32                 ContainerId;
11399 +    BYTECOUNT          BlockNumber;
11400 +    BYTECOUNT          ByteCount;
11401 +    CACHELEVEL                 Stable;
11402 +       SGMAP                   SgMap;  // Must be last in struct because it is variable
11403 +
11404 +} BLOCKWRITE;
11405 +typedef BLOCKWRITE *PBLOCKWRITE;
11406 +
11407 +
11408 +typedef struct _BLOCKWRITERESPONSE {
11409 +
11410 +    FSASTATUS          Status;
11411 +    BYTECOUNT          ByteCount;
11412 +    COMMITLEVEL        Committed;
11413 +
11414 +} BLOCKWRITERESPONSE;
11415 +typedef BLOCKWRITERESPONSE *PBLOCKWRITERESPONSE;
11416 +
11417 +
11418 +
11419 +#endif // _PROTOCOL_H_
11420 +
11421 diff -urN linux/drivers/scsi/aacraid/include/revision.h linux/drivers/scsi/aacraid/include/revision.h
11422 --- linux/drivers/scsi/aacraid/include/revision.h       Wed Dec 31 19:00:00 1969
11423 +++ linux/drivers/scsi/aacraid/include/revision.h       Thu Dec 21 13:14:30 2000
11424 @@ -0,0 +1,350 @@
11425 +/*++
11426 + * Adaptec aacraid device driver for Linux.
11427 + *
11428 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11429 + *
11430 + * This program is free software; you can redistribute it and/or modify
11431 + * it under the terms of the GNU General Public License as published by
11432 + * the Free Software Foundation; either version 2, or (at your option)
11433 + * any later version.
11434 + *
11435 + * This program is distributed in the hope that it will be useful,
11436 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11437 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11438 + * GNU General Public License for more details.
11439 + *
11440 + * You should have received a copy of the GNU General Public License
11441 + * along with this program; see the file COPYING.  If not, write to
11442 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11443 + *
11444 + * Module Name:
11445 + *   revision.h
11446 + *
11447 + * Abstract: This module contains all of the revision information for
11448 + *     the FSA product, as well as the support routines for
11449 + *     checking module compatibility.
11450 + *
11451 + *     Before editing anything in this module, make sure that
11452 + *     you read the comments. Some lines are changed automatically
11453 + *     as part of the build, and should never be changed by hand.
11454 + *
11455 + * Routines (all inlines):
11456 + *
11457 + *     RevGetBuildNumber - Retrieve current build number
11458 + *     RevGetExternalRev - Retrieve revision for external use
11459 + *     RevGetFullRevision - Retrieve full revision structure
11460 + *
11461 + *     RevCheckCompatibility - Checks compatibility base on internal table
11462 + *
11463 + *     RevCheckCompatibilityFullInfo - Check for static component
11464 + *     RevGetCompInfoTableSize - Get size for static component table
11465 + *     RevGetCompInfoTable - Get actual table to place on static component
11466 + *     RevGetBuildNumberFromInfo - Get build number for static component.
11467 + *
11468 + *
11469 + *     
11470 + --*/
11471 +
11472 +#ifndef _REVISION_H
11473 +#define _REVISION_H
11474 +
11475 +static char *ident_revision = "aacraid_ident revision.h 1.0.6 2000/10/09 Adaptec, Inc.";
11476 +
11477 +#include "version.h" // revision numbers kept separate so they can be used by resource compiler as well
11478 +
11479 +typedef int REV_BOOL;
11480 +
11481 +#define REV_TRUE 1
11482 +#define REV_FALSE 0
11483 +
11484 +//
11485 +//     Define Revision Levels for this product
11486 +//
11487 +//  IMPORTANT: Do NOT modify BUILD_NUMBER define, this is modified
11488 +//                        automatically by the build.
11489 +//
11490 +//  Version is VMAJOR.MINOR-DASH TYPE (Build BUILD_NUMBER)
11491 +//
11492 +//     IMPORTANT: Don't access these revisions directly. They can be
11493 +//                        accessed via, the RevGetXxxxx rouines.
11494 +//
11495 +
11496 +
11497 +#define REV_AS_LONGWORD \
11498 +       ((REV_MAJOR << 24) | (REV_MINOR << 16) | (REV_TYPE << 8) | (REV_DASH))
11499 +
11500 +
11501 +
11502 +#ifndef BIOS
11503 +
11504 +//
11505 +//     Enumerate the types of product levels we can have
11506 +//
11507 +enum {
11508 +       RevType_Devo=1,         // Development mode, testing all of latest
11509 +       RevType_Alpha,          // Alpha - Internal field test
11510 +       RevType_Beta,           // Beta - External field test
11511 +       RevType_Release         // Release - Retail version
11512 +};
11513 +
11514 +//
11515 +//     Define the basic structure for all revision information. Note
11516 +//     that the ordering of the components is such that they should
11517 +//     always increase. dash will be updated the most, then the version
11518 +//     type, then minor and major.
11519 +//
11520 +typedef struct {
11521 +       union {
11522 +               struct {
11523 +                       unsigned char dash;     // Dash version number
11524 +                       unsigned char type;     // Type, 1=Devo, 2=Alpha, 3=Beta, 4=Release
11525 +                       unsigned char minor;// Minor version minor
11526 +                       unsigned char major;// Major version number
11527 +               } comp;                         // Components to external viewed rev number
11528 +               unsigned long ul;       // External revision as single 32-bit value
11529 +       } external;                     // External revision number (union)
11530 +       unsigned long buildNumber; // Automatically generated build number
11531 +} FsaRevision;
11532 +
11533 +
11534 +//
11535 +//     Define simple routines to get basic revision information. The
11536 +//     definitions should never be accessed directly. These routines
11537 +//     are meant to be used to access all relevant information no matter
11538 +//     how simple.
11539 +//
11540 +static inline unsigned long RevGetBuildNumber() {return REV_BUILD_NUMBER;}
11541 +
11542 +static inline unsigned long RevGetExternalRev() {return REV_AS_LONGWORD;}
11543 +
11544 +
11545 +//
11546 +//     Enumerate different components that may have to check
11547 +//     compatibility. This list of components can be changed
11548 +//     at any time.
11549 +//
11550 +//     IMPORTANT: ONLY add to the END of this enum structure. Otherwise,
11551 +//                        incompatibilities between component rev checking will
11552 +//                        cause wrong checking results.
11553 +//
11554 +typedef enum {
11555 +       RevApplication = 1,     // Any user End application
11556 +       RevDkiCli,                      // ADAPTEC proprietary interface (knows FIBs)
11557 +       RevNetService,          // Network Service Revision (under API)
11558 +       RevApi,                         // ADAPTEC User mode API
11559 +       RevFileSysDriver,       // FSA File System Driver
11560 +       RevMiniportDriver,      // FSA File System Miniport Driver
11561 +       RevAdapterSW,           // Adapter Software (or NT Simulator)
11562 +       RevMonitor,                     // Monitor for adapter hardware (MON960 for now)
11563 +       RevRemoteApi            // The remote API.
11564 +       // ALWAYS ADD NEW COMPONENTS HERE - AT END
11565 +} RevComponent;
11566 +
11567 +//
11568 +//     Define a structure so that we can create a compatibility table.
11569 +//
11570 +typedef struct {
11571 +       RevComponent A,B;
11572 +       unsigned long BuildNumOfB_RequiredByA;
11573 +       unsigned long BuildNumOfA_RequiredByB;
11574 +} RevCompareElement;
11575 +
11576 +//
11577 +//     Now, define the table. This table should only be included once,
11578 +//     in one program. If it is linked from 2 modules, there will likely
11579 +//     be a multiply defined symbol error from the linker.
11580 +//
11581 +//     To fix this problem, REV_REFERENCE_ONLY can be defined. This will
11582 +//     allow access to the revision information table without a redefinition
11583 +//     of the tables.
11584 +//
11585 +extern const int                          RevCompareTableLength;
11586 +
11587 +extern const RevCompareElement RevCompareTable[];
11588 +
11589 +/********************************************************************\
11590 +* Routine: RevCheckCompatibility(callerComp,compB,compB_BuildNumber)
11591 +*
11592 +*      The following routine is used to check compatibility between
11593 +*      the calling component and a component that has some dependencies
11594 +*      on it. If this routine returns REV_FALSE, it is expected that the caller
11595 +*      will send an appropriate incompatibility message and stop.
11596 +*
11597 +*      This routine is only meant to check for compatibility in the
11598 +*      absolute sense. If code wishes to execute a different path based
11599 +*      on the CompB_BuildNumber, then this routine is not useful. The
11600 +*      routine RevGetBuildNumber can be used to get the calling module's
11601 +*      current build number for a comparison check.
11602 +*
11603 +*      The return value is REV_TRUE, if compatibility is possible, and REV_FALSE
11604 +*      if the components are definitely not compatible, or there is an
11605 +*      error when trying to figure it out. To be more specific:
11606 +*
11607 +*              1) REV_TRUE if component B is newer than calling component. (In this
11608 +*                 case, the revision check done by component B with respect to
11609 +*                 this component will give the real compatibility information.
11610 +*                 It is the only one with the knowledge, since this component
11611 +*                 could not look into the future.)
11612 +*              2) REV_TRUE if calling component is more recent and table shows okay
11613 +*              3) REV_FALSE if calling component more recent and table show not okay
11614 +*              4) REV_FALSE if calling component is more recent and table entry to
11615 +*                 check does not exist.
11616 +*
11617 +*      Note that the CompB_BuildNumber must be attained by the calling
11618 +*      routine through some mechanism done by the caller.
11619 +*
11620 +* Input:
11621 +*
11622 +*      callerComp - Name of component making this call
11623 +*      compB - Name of component to check compatibility with
11624 +*      compB_BuildNumber - Build number to component B
11625 +*
11626 +* Output:
11627 +*
11628 +*      None
11629 +*
11630 +* Return Value:
11631 +*
11632 +*      REV_TRUE - Component compatibility is possible, continue as usual. compB
11633 +*                 must give true compatibility information.
11634 +*      REV_FALSE - Incompatible components, notify and end
11635 +*
11636 +\********************************************************************/
11637 +static inline REV_BOOL RevCheckCompatibility(
11638 +               RevComponent callerComp,
11639 +               RevComponent compB,
11640 +               unsigned long compB_BuildNumber)
11641 +{
11642 +       int i;
11643 +       unsigned long RevForB;
11644 +
11645 +       //
11646 +       //      Compatibility check is possible, so we should continue. When
11647 +       //      compB makes this call in its own component, it will get the
11648 +       //      true compatibility information, since only it can know.
11649 +       //
11650 +       if (RevGetBuildNumber() < compB_BuildNumber) return REV_TRUE;
11651 +
11652 +       //
11653 +       //      Go through rev table. When the components are found in the
11654 +       //      same table entry, return the approprate number.
11655 +       //
11656 +       for (i=0; i<RevCompareTableLength; i++) {
11657 +               if (RevCompareTable[i].A == callerComp) {
11658 +                       if (RevCompareTable[i].B == compB) {
11659 +                               RevForB = RevCompareTable[i].BuildNumOfB_RequiredByA;
11660 +                               return (compB_BuildNumber >= RevForB);
11661 +                       }
11662 +               } else if (RevCompareTable[i].B == callerComp) {
11663 +                       if (RevCompareTable[i].A == compB) {
11664 +                               RevForB = RevCompareTable[i].BuildNumOfA_RequiredByB;
11665 +                               return (compB_BuildNumber >= RevForB);
11666 +                       }
11667 +               }
11668 +       }
11669 +
11670 +       //
11671 +       //      Uh oh! No relevant table entry was found (this should never
11672 +       //      happen).
11673 +       //
11674 +       return REV_FALSE;
11675 +}
11676 +
11677 +
11678 +//
11679 +//     Now create a structure that can be used by a FIB to check
11680 +//     compatibility.
11681 +//
11682 +typedef struct _RevCheck {
11683 +       RevComponent callingComponent;
11684 +       FsaRevision callingRevision;
11685 +} RevCheck;
11686 +
11687 +typedef struct _RevCheckResp {
11688 +       REV_BOOL possiblyCompatible;
11689 +       FsaRevision adapterSWRevision;
11690 +} RevCheckResp;
11691 +
11692 +#endif /* bios */
11693 +#endif /* _REVISION_H */
11694 +
11695 +//
11696 +//     The following allows for inclusion of revision.h in other h
11697 +//     files. when you include this file in another h file, simply
11698 +//     define REV_REFERENCE_ONLY. This will be undefined later, so that
11699 +//     the single C file inclusion in the module will be used to
11700 +//     implement the global structures.
11701 +//
11702 +#ifndef REV_REFERENCE_ONLY
11703 +#ifndef _REVISION_H_GLOBAL
11704 +#define _REVISION_H_GLOBAL
11705 +
11706 +
11707 +
11708 +//
11709 +//     The following array is the table of compatibility. This table
11710 +//     can be modified in two ways:
11711 +//
11712 +//             1) A component which has an incompatible change done to
11713 +//                it, can get a new build number.
11714 +//
11715 +//             2) A new component can be added, requiring more entries
11716 +//                to be place into this table.
11717 +//
11718 +//
11719 +//     In case (1), you must change the revision number in the appropriate
11720 +//     column, based on which component absolutely requires an upgrade.
11721 +//
11722 +//     Example: A new FIB used by the API, in build number 105
11723 +//             {RevApi,        RevAdapterSW,           100,  100}
11724 +//                     ---> would be changed to <---
11725 +//             {RevApi,        RevAdapterSW,           105,  100}
11726 +//
11727 +//     Example: A structure is changed for a FIB that only the API uses
11728 +//             {RevApi,        RevAdapterSW,           100,  100}
11729 +//                     ---> would be changed to <---
11730 +//             {RevApi,        RevAdapterSW,           105,  105}
11731 +//
11732 +//
11733 +//     In case (2), the less common case, the enumerated list of
11734 +//     components must be changed to include the new component. Then
11735 +//     entries need to be placed into this table.
11736 +//
11737 +//     Since the revisions must be communicated between the two
11738 +//     components, it is likely that you would need to put in the
11739 +//     current build number for both columns. That is the recommended
11740 +//     way to start revision test.
11741 +//
11742 +const RevCompareElement RevCompareTable[] = {
11743 +       // Component A          Component B                     MinBForA        MinAForB
11744 +       // -----------          -----------                     --------        --------
11745 +       {RevApplication,        RevApi,                         2120,           2120    },
11746 +       {RevDkiCli,             RevApi,                         2120,           2120    },
11747 +       {RevDkiCli,             RevFileSysDriver,               257,            257     },
11748 +       {RevDkiCli,             RevMiniportDriver,              257,            257     },
11749 +       {RevDkiCli,             RevAdapterSW,                   257,            257     },
11750 +       {RevApi,                RevFileSysDriver,               2120,           2120    },
11751 +       {RevApi,                RevMiniportDriver,              2120,           2120    },
11752 +       {RevApi,                RevAdapterSW,                   2120,           2120    },
11753 +       {RevApi,                RevNetService,                  2120,           2120    },
11754 +       {RevFileSysDriver,      RevMiniportDriver,              100,            100     },
11755 +       {RevFileSysDriver,      RevAdapterSW,                   257,            257     },
11756 +       {RevMiniportDriver,     RevAdapterSW,                   257,            257     },
11757 +       {RevMiniportDriver,     RevMonitor,                     100,            100     },
11758 +       {RevApi,                RevNetService,                  2120,           2120    },
11759 +       {RevApi,                RevRemoteApi,                   2120,           2120    },
11760 +       {RevNetService,         RevRemoteApi,                   2120,           2120    }
11761 +};
11762 +
11763 +const int RevCompareTableLength = sizeof(RevCompareTable)/sizeof(RevCompareElement);
11764 +
11765 +#endif /* _REVISION_H_GLOBAL */
11766 +#endif /* REV_REFERENCE_ONLY */
11767 +#undef REV_REFERENCE_ONLY
11768 +
11769 +
11770 +
11771 +
11772 +
11773 +
11774 +
11775 diff -urN linux/drivers/scsi/aacraid/include/rx.h linux/drivers/scsi/aacraid/include/rx.h
11776 --- linux/drivers/scsi/aacraid/include/rx.h     Wed Dec 31 19:00:00 1969
11777 +++ linux/drivers/scsi/aacraid/include/rx.h     Thu Dec 21 13:14:30 2000
11778 @@ -0,0 +1,81 @@
11779 +/*++
11780 + * Adaptec aacraid device driver for Linux.
11781 + *
11782 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11783 + *
11784 + * This program is free software; you can redistribute it and/or modify
11785 + * it under the terms of the GNU General Public License as published by
11786 + * the Free Software Foundation; either version 2, or (at your option)
11787 + * any later version.
11788 + *
11789 + * This program is distributed in the hope that it will be useful,
11790 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11791 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11792 + * GNU General Public License for more details.
11793 + *
11794 + * You should have received a copy of the GNU General Public License
11795 + * along with this program; see the file COPYING.  If not, write to
11796 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11797 + *
11798 + * Module Name:
11799 + *   rx.h
11800 + *
11801 + * Abstract: Prototypes and data structures unique to the Rx based controller board.
11802 + *
11803 + *     
11804 + --*/
11805 +
11806 +static char *ident_rxh = "aacraid_ident rx.h 1.0.6 2000/10/09 Adaptec, Inc.";
11807 +
11808 +typedef struct _Rx_ADAPTER_EXTENSION {
11809 +
11810 +       //
11811 +       // The following must be first.
11812 +       //
11813 +       PPCI_MINIPORT_COMMON_EXTENSION  Common;
11814 +       struct _Rx_ADAPTER_EXTENSION    *Next;                          // Next adapter miniport structure
11815 +    USHORT                                                     LocalMaskInterruptControl;
11816 +       PRx_DEVICE_REGISTERS                    Device;
11817 +
11818 +} Rx_ADAPTER_EXTENSION;
11819 +
11820 +    
11821 +typedef Rx_ADAPTER_EXTENSION *PRx_ADAPTER_EXTENSION;
11822 +
11823 +
11824 +
11825 +#ifdef LINUX
11826 +/*
11827 + * 
11828 + */
11829 +
11830 +#define Rx_READ_UCHAR(AEP,  CSR)                       *(volatile unsigned char *)  &((AEP)->Device->CSR)
11831 +    
11832 +
11833 +
11834 +#define Rx_READ_ULONG(AEP,  CSR)                       *(volatile unsigned int *)   &((AEP)->Device->CSR)
11835 +#define Rx_WRITE_UCHAR(AEP,  CSR, Value)       *(volatile unsigned char *)  &((AEP)->Device->CSR) = (Value)
11836 +
11837 +
11838 +#define Rx_WRITE_ULONG(AEP, CSR, Value)                *(volatile unsigned int *)   &((AEP)->Device->CSR) = (Value)
11839 +
11840 +#endif /* LINUX */
11841 +
11842 +
11843 +VOID
11844 +RxInterruptAdapter(
11845 +       PVOID Arg1
11846 +       );
11847 +
11848 +VOID
11849 +RxNotifyAdapter(
11850 +       PVOID Arg1,
11851 +    IN HOST_2_ADAP_EVENT AdapterEvent
11852 +    );
11853 +
11854 +VOID
11855 +RxResetDevice(
11856 +       PVOID Arg1
11857 +       );
11858 +
11859 +
11860 diff -urN linux/drivers/scsi/aacraid/include/rxcommon.h linux/drivers/scsi/aacraid/include/rxcommon.h
11861 --- linux/drivers/scsi/aacraid/include/rxcommon.h       Wed Dec 31 19:00:00 1969
11862 +++ linux/drivers/scsi/aacraid/include/rxcommon.h       Thu Dec 21 13:14:30 2000
11863 @@ -0,0 +1,105 @@
11864 +/*++
11865 + * Adaptec aacraid device driver for Linux.
11866 + *
11867 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11868 + *
11869 + * This program is free software; you can redistribute it and/or modify
11870 + * it under the terms of the GNU General Public License as published by
11871 + * the Free Software Foundation; either version 2, or (at your option)
11872 + * any later version.
11873 + *
11874 + * This program is distributed in the hope that it will be useful,
11875 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11876 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11877 + * GNU General Public License for more details.
11878 + *
11879 + * You should have received a copy of the GNU General Public License
11880 + * along with this program; see the file COPYING.  If not, write to
11881 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11882 + *
11883 + * Module Name:
11884 + *   rxcommon.h
11885 + *
11886 + * Abstract: Structures and defines for the i960 Rx chip.
11887 + *
11888 + *     
11889 + --*/
11890 +
11891 +#ifndef _Rx_COMMON_H_
11892 +#define _Rx_COMMON_H_
11893 +
11894 +static char *ident_rxcommon = "aacraid_ident rxcommon.h 1.0.6 2000/10/09 Adaptec, Inc.";
11895 +
11896 +//
11897 +// Rx Message Unit Registers
11898 +//
11899 +
11900 +typedef volatile struct _StructRxMURegisters {
11901 +                                                                               //       Local  |   PCI*        |       Name
11902 +                                                                               //                      |               |
11903 +       unsigned        ARSR;                                   //      1300h   |       00h     |       APIC Register Select Register
11904 +       unsigned        reserved0;                              //      1304h   |       04h     |       Reserved
11905 +       unsigned        AWR;                                    //      1308h   |       08h     |       APIC Window Register
11906 +       unsigned        reserved1;                              //      130Ch   |       0Ch     |       Reserved
11907 +       unsigned        IMRx[2];                                //      1310h   |       10h     |       Inbound Message Registers
11908 +       unsigned        OMRx[2];                                //      1318h   |       18h     |       Outbound Message Registers
11909 +       unsigned        IDR;                                    //      1320h   |       20h     |       Inbound Doorbell Register
11910 +       unsigned        IISR;                                   //      1324h   |       24h     |       Inbound Interrupt Status Register
11911 +       unsigned        IIMR;                                   //      1328h   |       28h     |       Inbound Interrupt Mask Register
11912 +       unsigned        ODR;                                    //      132Ch   |       2Ch     |       Outbound Doorbell Register
11913 +       unsigned        OISR;                                   //      1330h   |       30h     |       Outbound Interrupt Status Register
11914 +       unsigned        OIMR;                                   //      1334h   |       34h     |       Outbound Interrupt Mask Register
11915 +                                                                               // * Must access trhough ATU Inbound Translation Window
11916 +
11917 +}Rx_MU_CONFIG;
11918 +typedef Rx_MU_CONFIG *PRx_MU_CONFIG;
11919 +
11920 +typedef volatile struct _Rx_Inbound {
11921 +
11922 +       unsigned        Mailbox[8];
11923 +
11924 +}Rx_Inbound;
11925 +
11926 +typedef Rx_Inbound *PRx_Inbound;
11927 +
11928 +#define        InboundMailbox0         IndexRegs.Mailbox[0]
11929 +#define        InboundMailbox1         IndexRegs.Mailbox[1]
11930 +#define        InboundMailbox2         IndexRegs.Mailbox[2]
11931 +#define        InboundMailbox3         IndexRegs.Mailbox[3]
11932 +#define        InboundMailbox4         IndexRegs.Mailbox[4]
11933 +
11934 +
11935 +
11936 +#define        INBOUNDDOORBELL_0       0x00000001
11937 +#define INBOUNDDOORBELL_1      0x00000002
11938 +#define INBOUNDDOORBELL_2      0x00000004
11939 +#define INBOUNDDOORBELL_3      0x00000008
11940 +#define INBOUNDDOORBELL_4      0x00000010
11941 +#define INBOUNDDOORBELL_5      0x00000020
11942 +#define INBOUNDDOORBELL_6      0x00000040
11943 +
11944 +
11945 +#define        OUTBOUNDDOORBELL_0      0x00000001
11946 +#define OUTBOUNDDOORBELL_1     0x00000002
11947 +#define OUTBOUNDDOORBELL_2     0x00000004
11948 +#define OUTBOUNDDOORBELL_3     0x00000008
11949 +#define OUTBOUNDDOORBELL_4     0x00000010
11950 +
11951 +
11952 +#define InboundDoorbellReg     MUnit.IDR
11953 +
11954 +#define OutboundDoorbellReg    MUnit.ODR
11955 +
11956 +
11957 +typedef struct _Rx_DEVICE_REGISTERS {
11958 +       Rx_MU_CONFIG                    MUnit;                  // 1300h - 1334h
11959 +       unsigned                                reserved1[6];   // 1338h - 134ch
11960 +       Rx_Inbound                              IndexRegs;
11961 +} Rx_DEVICE_REGISTERS;
11962 +
11963 +typedef Rx_DEVICE_REGISTERS *PRx_DEVICE_REGISTERS;
11964 +
11965 +
11966 +#endif // _Rx_COMMON_H_
11967 +
11968 +
11969 diff -urN linux/drivers/scsi/aacraid/include/sap1.h linux/drivers/scsi/aacraid/include/sap1.h
11970 --- linux/drivers/scsi/aacraid/include/sap1.h   Wed Dec 31 19:00:00 1969
11971 +++ linux/drivers/scsi/aacraid/include/sap1.h   Thu Dec 21 13:14:30 2000
11972 @@ -0,0 +1,85 @@
11973 +/*++
11974 + * Adaptec aacraid device driver for Linux.
11975 + *
11976 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11977 + *
11978 + * This program is free software; you can redistribute it and/or modify
11979 + * it under the terms of the GNU General Public License as published by
11980 + * the Free Software Foundation; either version 2, or (at your option)
11981 + * any later version.
11982 + *
11983 + * This program is distributed in the hope that it will be useful,
11984 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11985 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11986 + * GNU General Public License for more details.
11987 + *
11988 + * You should have received a copy of the GNU General Public License
11989 + * along with this program; see the file COPYING.  If not, write to
11990 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11991 + *
11992 + * Module Name:
11993 + *   sap1.h
11994 + *
11995 + * Abstract: Prototypes and data structures unique to the Strong Arm based controller board.
11996 + *
11997 + *     
11998 + --*/
11999 +#ifndef _SAP1_H_
12000 +#define _SAP1_H_
12001 +
12002 +static char *ident_sap1h = "aacraid_ident sap1.h 1.0.6 2000/10/09 Adaptec, Inc.";
12003 +
12004 +#define Sa_MINIPORT_REVISION                   1
12005 +
12006 +typedef struct _Sa_ADAPTER_EXTENSION {
12007 +
12008 +       //
12009 +       // The following must be first.
12010 +       //
12011 +       PPCI_MINIPORT_COMMON_EXTENSION  Common;
12012 +       struct _Sa_ADAPTER_EXTENSION    *Next;                  // Next adapter miniport structure
12013 +       USHORT                                                  LocalMaskInterruptControl;
12014 +       PSa_DEVICE_REGISTERS                    Device;
12015 +
12016 +} Sa_ADAPTER_EXTENSION;
12017 +
12018 +typedef Sa_ADAPTER_EXTENSION *PSa_ADAPTER_EXTENSION;
12019 +
12020
12021 +
12022 +#ifdef LINUX
12023 +/*
12024 + * 
12025 + */
12026 +
12027
12028 +#define Sa_READ_USHORT(AEP, CSR)                       *(volatile unsigned short *) &((AEP)->Device->CSR)
12029 +#define Sa_READ_ULONG(AEP,  CSR)                       *(volatile unsigned int *)   &((AEP)->Device->CSR)
12030 +
12031
12032 +#define Sa_WRITE_USHORT(AEP, CSR, Value)       *(volatile unsigned short *) &((AEP)->Device->CSR) = (Value)
12033 +#define Sa_WRITE_ULONG(AEP, CSR, Value)                *(volatile unsigned int *)   &((AEP)->Device->CSR) = (Value)
12034 +
12035 +#endif /* LINUX */
12036 +
12037
12038 +VOID
12039 +SaInterruptAdapter(
12040 +       PVOID Arg1
12041 +       );
12042 +
12043 +VOID
12044 +SaNotifyAdapter(
12045 +       PVOID Arg1,
12046 +    IN HOST_2_ADAP_EVENT AdapterEvent
12047 +    );
12048 +
12049 +VOID
12050 +SaResetDevice(
12051 +       PVOID Arg1
12052 +       );
12053 +
12054
12055 +#endif /* _SAP1_H_ */
12056 +
12057 +
12058 diff -urN linux/drivers/scsi/aacraid/include/sap1common.h linux/drivers/scsi/aacraid/include/sap1common.h
12059 --- linux/drivers/scsi/aacraid/include/sap1common.h     Wed Dec 31 19:00:00 1969
12060 +++ linux/drivers/scsi/aacraid/include/sap1common.h     Thu Dec 21 13:14:30 2000
12061 @@ -0,0 +1,111 @@
12062 +/*++
12063 + * Adaptec aacraid device driver for Linux.
12064 + *
12065 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
12066 + *
12067 + * This program is free software; you can redistribute it and/or modify
12068 + * it under the terms of the GNU General Public License as published by
12069 + * the Free Software Foundation; either version 2, or (at your option)
12070 + * any later version.
12071 + *
12072 + * This program is distributed in the hope that it will be useful,
12073 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
12074 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12075 + * GNU General Public License for more details.
12076 + *
12077 + * You should have received a copy of the GNU General Public License
12078 + * along with this program; see the file COPYING.  If not, write to
12079 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
12080 + *
12081 + * Module Name:
12082 + *   sap1common.h
12083 + *
12084 + * Abstract: Structures and defines for the Drawbridge and StrongArm110 chip.
12085 + *     
12086 + --*/
12087 +
12088 +#ifndef _Sa_COMMON_H_
12089 +#define _Sa_COMMON_H_
12090 +
12091 +static char *ident_sap1common = "aacraid_ident sap1common.h 1.0.6 2000/10/09 Adaptec, Inc.";
12092 +
12093 +//
12094 +// SaP1 Message Unit Registers
12095 +//
12096 +
12097 +typedef volatile struct _StructSaDrawbridge_CSR_RegisterMap {
12098 +                                                                                               //       Offset |       Name
12099 +       unsigned                        reserved[10];                   //      00h-27h |   Reserved
12100 +       unsigned char           LUT_Offset;                             //              28h     |       Looup Table Offset
12101 +       unsigned char           reserved1[3];                   //      29h-2bh |       Reserved
12102 +       unsigned                        LUT_Data;                               //              2ch     |       Looup Table Data        
12103 +       unsigned                        reserved2[26];                  //      30h-97h |       Reserved
12104 +       unsigned short          PRICLEARIRQ;                    //              98h     |       Primary Clear Irq
12105 +       unsigned short          SECCLEARIRQ;                    //              9ah     |       Secondary Clear Irq
12106 +       unsigned short          PRISETIRQ;                              //              9ch     |       Primary Set Irq
12107 +       unsigned short          SECSETIRQ;                              //              9eh     |       Secondary Set Irq
12108 +       unsigned short          PRICLEARIRQMASK;                //              a0h     |       Primary Clear Irq Mask
12109 +       unsigned short          SECCLEARIRQMASK;                //              a2h     |       Secondary Clear Irq Mask
12110 +       unsigned short          PRISETIRQMASK;                  //              a4h     |       Primary Set Irq Mask
12111 +       unsigned short          SECSETIRQMASK;                  //              a6h     |       Secondary Set Irq Mask
12112 +       unsigned                        MAILBOX0;                               //              a8h     |       Scratchpad 0
12113 +       unsigned                        MAILBOX1;                               //              ach     |       Scratchpad 1
12114 +       unsigned                        MAILBOX2;                               //              b0h     |       Scratchpad 2
12115 +       unsigned                        MAILBOX3;                               //              b4h     |       Scratchpad 3
12116 +       unsigned                        MAILBOX4;                               //              b8h     |       Scratchpad 4
12117 +       unsigned                        MAILBOX5;                               //              bch     |       Scratchpad 5
12118 +       unsigned                        MAILBOX6;                               //              c0h     |       Scratchpad 6
12119 +       unsigned                        MAILBOX7;                               //              c4h     |       Scratchpad 7
12120 +
12121 +       unsigned                        ROM_Setup_Data;                 //              c8h |   Rom Setup and Data
12122 +       unsigned                        ROM_Control_Addr;               //              cch |   Rom Control and Address
12123 +
12124 +       unsigned                        reserved3[12];                  //      d0h-ffh |       reserved
12125 +       unsigned                        LUT[64];                                // 100h-1ffh|   Lookup Table Entries
12126 +
12127 +       //
12128 +       //  TO DO
12129 +       //      need to add DMA, I2O, UART, etc registers form 80h to 364h
12130 +       //
12131 +
12132 +}Sa_Drawbridge_CSR;
12133 +
12134 +typedef Sa_Drawbridge_CSR *PSa_Drawbridge_CSR;
12135 +
12136 +
12137 +#define Mailbox0       SaDbCSR.MAILBOX0
12138 +#define Mailbox1       SaDbCSR.MAILBOX1
12139 +#define Mailbox2       SaDbCSR.MAILBOX2
12140 +#define Mailbox3       SaDbCSR.MAILBOX3
12141 +#define Mailbox4       SaDbCSR.MAILBOX4
12142 +
12143 +       
12144 +#define Mailbox7       SaDbCSR.MAILBOX7
12145 +       
12146 +#define DoorbellReg_p SaDbCSR.PRISETIRQ
12147 +#define DoorbellReg_s SaDbCSR.SECSETIRQ
12148 +#define DoorbellClrReg_p SaDbCSR.PRICLEARIRQ
12149 +
12150 +
12151 +#define        DOORBELL_0      0x00000001
12152 +#define DOORBELL_1     0x00000002
12153 +#define DOORBELL_2     0x00000004
12154 +#define DOORBELL_3     0x00000008
12155 +#define DOORBELL_4     0x00000010
12156 +#define DOORBELL_5     0x00000020
12157 +#define DOORBELL_6     0x00000040
12158 +
12159 +       
12160 +#define PrintfReady                    DOORBELL_5
12161 +#define PrintfDone                     DOORBELL_5
12162 +       
12163 +typedef struct _Sa_DEVICE_REGISTERS {
12164 +       Sa_Drawbridge_CSR       SaDbCSR;                        // 98h - c4h
12165 +} Sa_DEVICE_REGISTERS;
12166 +       
12167 +typedef Sa_DEVICE_REGISTERS *PSa_DEVICE_REGISTERS;
12168 +
12169 +       
12170 +#endif // _Sa_COMMON_H_
12171 +
12172 +
12173 diff -urN linux/drivers/scsi/aacraid/include/version.h linux/drivers/scsi/aacraid/include/version.h
12174 --- linux/drivers/scsi/aacraid/include/version.h        Wed Dec 31 19:00:00 1969
12175 +++ linux/drivers/scsi/aacraid/include/version.h        Thu Dec 21 13:14:30 2000
12176 @@ -0,0 +1,40 @@
12177 +/*++
12178 + * Adaptec aacraid device driver for Linux.
12179 + *
12180 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
12181 + *
12182 + * This program is free software; you can redistribute it and/or modify
12183 + * it under the terms of the GNU General Public License as published by
12184 + * the Free Software Foundation; either version 2, or (at your option)
12185 + * any later version.
12186 + *
12187 + * This program is distributed in the hope that it will be useful,
12188 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
12189 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12190 + * GNU General Public License for more details.
12191 + *
12192 + * You should have received a copy of the GNU General Public License
12193 + * along with this program; see the file COPYING.  If not, write to
12194 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
12195 + *
12196 + * Module Name:
12197 + *   version.h
12198 + *
12199 + * Abstract: Keeps track of build number for development purposes.
12200 + *     
12201 + --*/
12202 +#ifndef _VERSION_H_
12203 +#define _VERSION_H_
12204 +
12205 +static char *ident_version = "aacraid_ident version.h 1.0.6 2000/10/09 Adaptec, Inc.";
12206 +
12207 +#include "build_number.h"
12208 +
12209 +#define REV_MAJOR 2
12210 +#define REV_MINOR 1
12211 +#define REV_TYPE RevType_Release
12212 +#define REV_DASH 5
12213 +
12214 +#define FSA_VERSION_STRING "2.1.5.3857\0"
12215 +
12216 +#endif /* _VERSION_H_ */
12217 diff -urN linux/drivers/scsi/aacraid/linit.c linux/drivers/scsi/aacraid/linit.c
12218 --- linux/drivers/scsi/aacraid/linit.c  Wed Dec 31 19:00:00 1969
12219 +++ linux/drivers/scsi/aacraid/linit.c  Thu Dec 21 14:21:32 2000
12220 @@ -0,0 +1,1060 @@
12221 +/*++
12222 + * Adaptec aacraid device driver for Linux.
12223 + *
12224 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
12225 + *
12226 + * This program is free software; you can redistribute it and/or modify
12227 + * it under the terms of the GNU General Public License as published by
12228 + * the Free Software Foundation; either version 2, or (at your option)
12229 + * any later version.
12230 + *
12231 + * This program is distributed in the hope that it will be useful,
12232 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
12233 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12234 + * GNU General Public License for more details.
12235 + *
12236 + * You should have received a copy of the GNU General Public License
12237 + * along with this program; see the file COPYING.  If not, write to
12238 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
12239 + *
12240 + * Module Name:
12241 + *   linit.c
12242 + *
12243 + * Abstract: Linux Driver entry module for Adaptec RAID Array Controller
12244 + *                             
12245 + *     Provides the following driver entry points:
12246 + *             AAC_DetectHostAdapter()
12247 + *             AAC_ReleaseHostAdapter()
12248 + *             AAC_QueueCommand()
12249 + *             AAC_ResetCommand()
12250 + *             AAC_BIOSDiskParameters()
12251 + *     
12252 + --*/
12253 +
12254 +static char *ident_linit = "aacraid_ident linit.c 1.0.6 2000/10/09 Adaptec, Inc.";
12255 +
12256 +/*------------------------------------------------------------------------------
12257 + *              D E F I N E S
12258 + *----------------------------------------------------------------------------*/
12259 +#define AAC_DRIVER_VERSION                             "0.1.1"
12260 +#define AAC_DRIVER_BUILD_DATE                  __DATE__
12261 +#define MAX_DRIVER_QUEUE_DEPTH                 500
12262 +
12263 +/*------------------------------------------------------------------------------
12264 + *              I N C L U D E S
12265 + *----------------------------------------------------------------------------*/
12266 +#include "osheaders.h"
12267 +
12268 +#include "AacGenericTypes.h"
12269 +
12270 +#ifdef MODULE
12271 +#include <linux/module.h>
12272 +#endif
12273 +#include "sd.h"
12274 +#include "linit.h"
12275 +#include "aac_unix_defs.h"
12276 +#include "fsatypes.h"
12277 +#include "comstruc.h"
12278 +#include "fsaport.h"
12279 +#include "pcisup.h"
12280 +#include "port.h"
12281 +#include "afacomm.h"
12282 +#include "nodetype.h"
12283 +#include "comsup.h"
12284 +#include "adapter.h"
12285 +
12286 +/*------------------------------------------------------------------------------
12287 + *              G L O B A L S
12288 + *----------------------------------------------------------------------------*/
12289 +extern FSA_MINIPORT MiniPorts[];
12290 +extern int CommPrinting;
12291 +extern char DescriptionString[];
12292 +extern char devicestr[];
12293 +
12294 +/*------------------------------------------------------------------------------
12295 + *              M O D U L E   G L O B A L S
12296 + *----------------------------------------------------------------------------*/
12297 +aac_options_t g_options = { CMN_ERR_LEVEL, 0 };        // default message_level
12298 +
12299 +char g_DriverName[] = { "aacraid" };
12300 +#define module_options aacraid_options
12301 +static char * aacraid_options = NULL;
12302 +
12303 +PCI_MINIPORT_COMMON_EXTENSION *g_CommonExtensionPtrArray[ MAXIMUM_NUM_ADAPTERS ];
12304 +unsigned g_HostAdapterCount = 0;
12305 +unsigned g_chardev_major = 0;
12306 +
12307 +int g_single_command_done = FALSE;
12308 +
12309 +/*------------------------------------------------------------------------------
12310 + *              F U N C T I O N   P R O T O T Y P E S
12311 + *----------------------------------------------------------------------------*/
12312 +int AacHba_Ioctl(
12313 +       PCI_MINIPORT_COMMON_EXTENSION *CommonExtension,
12314 +       int cmd,
12315 +       void * arg );
12316 +
12317 +int AacHba_ProbeContainers( 
12318 +       PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr );
12319 +
12320 +int AacHba_DoScsiCmd(
12321 +       Scsi_Cmnd *scsi_cmnd_ptr,
12322 +       int wait );
12323 +
12324 +void AacHba_DetachAdapter(
12325 +       IN PVOID AdapterArg );
12326 +
12327 +int AacHba_ClassDriverInit(
12328 +       PCI_MINIPORT_COMMON_EXTENSION * CommonExtensionPtr);
12329 +
12330 +void AacHba_AbortScsiCommand(
12331 +       Scsi_Cmnd *scsi_cmnd_ptr );
12332 +
12333 +
12334 +/*------------------------------------------------------------------------------
12335 + *              L O C A L   F U N C T I O N   P R O T O T Y P E S
12336 + *----------------------------------------------------------------------------*/
12337 +static int parse_keyword(
12338 +       char ** str_ptr, 
12339 +       char * keyword );
12340 +
12341 +static void AAC_ParseDriverOptions( 
12342 +       char * cmnd_line_options_str );
12343 +
12344 +static void AAC_AnnounceDriver( void );
12345 +
12346 +int AAC_ChardevIoctl(
12347 +       struct inode * inode_ptr, 
12348 +       struct file * file_ptr,
12349 +       unsigned int cmd,
12350 +       unsigned long arg );
12351 +
12352 +int AAC_ChardevOpen(
12353 +       struct inode * inode_ptr,
12354 +       struct file * file_ptr );
12355 +
12356 +int AAC_ChardevRelease(
12357 +       struct inode * inode_ptr,
12358 +       struct file * file_ptr );
12359 +
12360 +struct file_operations AAC_fops = {
12361 +       NULL,               // module name
12362 +       NULL,                           // lseek
12363 +       NULL,                           // read
12364 +       NULL,                           // write
12365 +       NULL,                           // readdir
12366 +       NULL,                           // poll
12367 +       AAC_ChardevIoctl,       // ioctl
12368 +       NULL,                           // mmap
12369 +       AAC_ChardevOpen,        // open
12370 +       NULL,                           // flush
12371 +       AAC_ChardevRelease,     // release
12372 +       NULL,                           // fsync
12373 +       NULL,                           // fasync
12374 +       NULL,                           // check media change
12375 +       NULL,                           // revalidate
12376 +       NULL                            // lock
12377 +};
12378 +
12379 +/*------------------------------------------------------------------------------
12380 + *              F U N C T I O N S
12381 + *----------------------------------------------------------------------------*/
12382 +/*------------------------------------------------------------------------------
12383 +       AAC_AnnounceDriver()
12384 +
12385 +               Announce the driver name, version and date.
12386 + *----------------------------------------------------------------------------*/
12387 +static void AAC_AnnounceDriver( void ){
12388 +  printk("<1>%s, %s\n", 
12389 +                "aacraid raid driver version", AAC_DRIVER_BUILD_DATE );   
12390 +  schedule();
12391 +}
12392 +
12393 +
12394 +/*------------------------------------------------------------------------------
12395 +       AAC_DetectHostAdapter()
12396 +
12397 +               Probe for AAC Host Adapters initialize, register, and report the 
12398 +               configuration of each AAC Host Adapter found.
12399 +
12400 +       Preconditions:
12401 +       Postconditions:
12402 +               - Returns the number of adapters successfully initialized and 
12403 +               registered.
12404 +               - Initialize all data necessary for this particular SCSI driver.
12405 +       Notes:
12406 +               The detect routine must not call any of the mid level functions 
12407 +               to queue commands because things are not guaranteed to be set 
12408 +               up yet. The detect routine can send commands to the host adapter 
12409 +               as long as the program control will not be passed to scsi.c in 
12410 +               the processing of the command. Note especially that 
12411 +               scsi_malloc/scsi_free must not be called.
12412 + *----------------------------------------------------------------------------*/
12413 +int AAC_DetectHostAdapter (Scsi_Host_Template *HostTemplate)
12414 +{
12415 +               int index;
12416 +               int ContainerId;
12417 +               uint16_t vendor_id, device_id, sub_vendor_id, sub_system_id;
12418 +               struct Scsi_Host *host_ptr;
12419 +               PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
12420 +               struct pci_dev *dev = NULL;
12421 +               extern int NumMiniPorts;
12422 +               fsadev_t *fsa_dev_ptr;
12423 +               char *DeviceName;
12424 +
12425 +               struct pci_dev *devp;
12426 +
12427 +               int     first_index, last_index, increment;
12428 +
12429 +               CommPrinting = TRUE;
12430 +
12431 +#ifdef MODULE
12432 +               EXPORT_NO_SYMBOLS;
12433 +#endif
12434 +
12435 +               AAC_AnnounceDriver();
12436 +
12437 +               /* setting up the proc directory structure */
12438 +               HostTemplate->proc_name = "aacraid";
12439 +
12440 +               if( module_options != NULL ) AAC_ParseDriverOptions( module_options );
12441 +
12442 +               // NumMiniPorts & MiniPorts[] defined in aacid.c
12443 +               if (g_options.reverse_scan == 0) {
12444 +                               first_index = 0;
12445 +                               last_index  = NumMiniPorts;
12446 +                               increment   = 1;
12447 +               } else {
12448 +                               first_index = NumMiniPorts -1;
12449 +                               last_index  = -1;
12450 +                               increment   = -1;
12451 +               }
12452 +
12453 +               for( index = first_index; index != last_index; index += increment )
12454 +               {
12455 +                               device_id = MiniPorts[index].DeviceId;
12456 +                               vendor_id = MiniPorts[index].VendorId;
12457 +                               DeviceName = MiniPorts[index].DeviceName;
12458 +                               cmn_err(CE_DEBUG, "Checking %s %x/%x/%x/%x", 
12459 +                                               DeviceName,     vendor_id, device_id,
12460 +                                               MiniPorts[index].SubVendorId,
12461 +                                               MiniPorts[index].SubSystemId);
12462 +
12463 +
12464 +                               // pci_find_device traverses the pci_devices linked list for devices
12465 +                               // with matching vendor and device ids.
12466 +
12467 +                               dev = NULL;     // start from beginning of list
12468 +                               while( ( dev = pci_find_device( vendor_id, device_id, dev ) ) )
12469 +                               {
12470 +                                               if (pci_enable_device(dev)) continue;
12471 +                 
12472 +                                               if( pci_read_config_word( dev, PCI_SUBSYSTEM_VENDOR_ID, &sub_vendor_id ) ){
12473 +                                                               cmn_err(CE_WARN, "pci_read_config_word SUBSYS_VENDOR_ID failed");
12474 +                                                               break;
12475 +                                               }
12476 +                                               if( pci_read_config_word( dev, PCI_SUBSYSTEM_ID, &sub_system_id ) ){
12477 +                                                               cmn_err(CE_WARN, "pci_read_config_work SUBSYSTEM_ID failed");
12478 +                                                               break;
12479 +                                               }
12480 +
12481 +                                               cmn_err(CE_DEBUG, "     found: %x/%x/%x/%x", vendor_id, device_id, sub_vendor_id, sub_system_id);
12482 +                                               if( ( sub_vendor_id != MiniPorts[index].SubVendorId ) || 
12483 +                                                       ( sub_system_id != MiniPorts[index].SubSystemId ) ){
12484 +                                                               continue;
12485 +                                               }
12486 +                       
12487 +
12488 +                                               printk("<1>%s device detected\n", DeviceName );
12489 +                                               cmn_err(CE_DEBUG, "%x/%x/%x/%x", vendor_id, device_id, sub_vendor_id, sub_system_id);
12490 +
12491 +                                               // Increment the host adapter count
12492 +                                               g_HostAdapterCount++;
12493 +
12494 +                                               // scsi_register() allocates memory for a Scsi_Hosts structure and
12495 +                                               // links it into the linked list of host adapters. This linked list
12496 +                                               // contains the data for all possible <supported> scsi hosts.
12497 +                                               // This is similar to the Scsi_Host_Template, except that we have
12498 +                                               // one entry for each actual physical host adapter on the system,
12499 +                                               // stored as a linked list. If there are two AAC boards, then we
12500 +                                               // will need to make two Scsi_Host entries, but there will be only
12501 +                                               // one Scsi_Host_Template entry. The second argument to scsi_register()
12502 +                                               // specifies the size of the extra memory we want to hold any device 
12503 +                                               // specific information.
12504 +                                               host_ptr = scsi_register( HostTemplate, sizeof( PCI_MINIPORT_COMMON_EXTENSION ) );
12505 +
12506 +                                               // These three parameters can be used to allow for wide SCSI 
12507 +                                               // and for host adapters that support multiple buses.
12508 +                                               host_ptr->max_id = 17;
12509 +                                               host_ptr->max_lun = 8;
12510 +                                               host_ptr->max_channel = 1;
12511 +
12512 +
12513 +                                               host_ptr->irq = dev->irq;               // Adapter IRQ number
12514 +                                               /* host_ptr->base = ( char * )(dev->resource[0].start & ~0xff); */
12515 +                                               host_ptr->base = ( char * )(dev->resource[0].start);
12516 +                       
12517 +                                               cmn_err( CE_DEBUG, "Device base address = 0x%lx [0x%lx]", host_ptr->base, dev->resource[0].start );
12518 +                                               cmn_err( CE_DEBUG, "Device irq = 0x%lx", dev->irq );
12519 +
12520 +                                               // The unique_id field is a unique identifier that must be assigned
12521 +                                               // so that we have some way of identifying each host adapter properly
12522 +                                               // and uniquely. For hosts that do not support more than one card in the
12523 +                                               // system, this does not need to be set. It is initialized to zero in
12524 +                                               // scsi_register(). This is the value returned from OsGetDeviceInstance().
12525 +
12526 +                                               host_ptr->unique_id = g_HostAdapterCount - 1;
12527 +                                               host_ptr->this_id = 16;                 // SCSI Id for the adapter itself
12528 +
12529 +                                               // Set the maximum number of simultaneous commands supported by the driver.
12530 +                                               host_ptr->can_queue = MAX_DRIVER_QUEUE_DEPTH;
12531 +
12532 +                                               // Define the maximum number of scatter/gather elements supported by 
12533 +                                               // the driver. 
12534 +
12535 +                                               host_ptr->sg_tablesize = 16;
12536 +                                               host_ptr->cmd_per_lun = 1;              // untagged queue depth
12537 +
12538 +                                               // This function is called after the device list has been built to find
12539 +                                               // tagged queueing depth supported for each device.
12540 +
12541 +                                               host_ptr->select_queue_depths = AAC_SelectQueueDepths;
12542 +                                               CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )host_ptr->hostdata;
12543 +                       
12544 +                                               // attach a pointer back to Scsi_Host
12545 +                                               CommonExtensionPtr->OsDep.scsi_host_ptr = host_ptr;     
12546 +                                               CommonExtensionPtr->OsDep.MiniPortIndex =  index;
12547 +
12548 +                                               // Initialize the ordinal number of the device to -1
12549 +                                               fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
12550 +                                               for( ContainerId = 0; ContainerId < MAXIMUM_NUM_CONTAINERS; ContainerId++ )
12551 +                                                               fsa_dev_ptr->ContainerDevNo[ContainerId] = -1;
12552 +
12553 +                                               // Call initialization routine
12554 +                                               cmn_err (CE_DEBUG, "Initializing Hardware...\n");
12555 +                                               if( ( *MiniPorts[index].InitRoutine )
12556 +                                                       ( CommonExtensionPtr, host_ptr->unique_id, dev->bus->number, 0 ) != 0 )
12557 +                                               {
12558 +                                                               // device initialization failed
12559 +                                                               cmn_err( CE_WARN, "%s:%d device initialization failed", DeviceName, host_ptr->unique_id );
12560 +                                                               scsi_unregister( host_ptr );
12561 +                                                               g_HostAdapterCount--;
12562 +                                               } /* end if */
12563 +                                               else
12564 +                                               {
12565 +                                                       cmn_err( CE_NOTE, "%s:%d device initialization successful", DeviceName, host_ptr->unique_id  );
12566 +                                                       AacHba_ClassDriverInit( CommonExtensionPtr );
12567 +                                                       cmn_err(CE_NOTE, "%s:%d AacHba_ClassDriverInit complete", DeviceName, host_ptr->unique_id);
12568 +                                                       AacHba_ProbeContainers( CommonExtensionPtr );
12569 +                                                       g_CommonExtensionPtrArray[ g_HostAdapterCount - 1 ] = CommonExtensionPtr;
12570 +
12571 +                                               } /* end else */
12572 +
12573 +                               } /* end while */
12574 +
12575 +               } /* end for */
12576 +
12577 +               if( g_HostAdapterCount ){
12578 +                       if( !( g_chardev_major = register_chrdev( 0, devicestr, &AAC_fops ) ) )
12579 +                               cmn_err( CE_WARN, "%s: unable to register %s device", DeviceName, devicestr);
12580 +               }
12581 +
12582 +               HostTemplate->present = g_HostAdapterCount; // # of cards of this type found
12583 +
12584 +               return( g_HostAdapterCount ); 
12585 +}
12586 +
12587 +
12588 +/*------------------------------------------------------------------------------
12589 +       AAC_ReleaseHostAdapter()
12590 +
12591 +               Release all resources previously acquired to support a specific Host 
12592 +               Adapter and unregister the AAC Host Adapter.
12593 + *----------------------------------------------------------------------------*/
12594 +int AAC_ReleaseHostAdapter( 
12595 +       struct Scsi_Host *host_ptr )
12596 +/*----------------------------------------------------------------------------*/
12597 +{
12598 +       PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
12599 +
12600 +       cmn_err( CE_DEBUG, "AAC_ReleaseHostAdapter" );
12601 +
12602 +       CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )host_ptr->hostdata;
12603 +
12604 +       // kill any threads we started
12605 +       kill_proc( CommonExtensionPtr->OsDep.thread_pid, SIGKILL, 0 );
12606 +
12607 +       // Call the comm layer to detach from this adapter
12608 +       AacHba_DetachAdapter( CommonExtensionPtr->Adapter );
12609 +
12610 +       // remove interrupt binding
12611 +       OsDetachInterrupt( CommonExtensionPtr->MiniPort );
12612 +
12613 +       SaDetachDevice( CommonExtensionPtr );
12614 +
12615 +       // unregister adapter
12616 +       scsi_unregister( host_ptr );
12617 +
12618 +       if( g_chardev_major )
12619 +       {
12620 +               unregister_chrdev( g_chardev_major, devicestr );
12621 +               g_chardev_major = 0;
12622 +       }
12623 +
12624 +       return( 0 ); // #REVISIT# return code
12625 +}
12626 +
12627 +
12628 +/*------------------------------------------------------------------------------
12629 +       AAC_QueueCommand()
12630 +
12631 +               Queues a command for execution by the associated Host Adapter.
12632 + *----------------------------------------------------------------------------*/
12633 +int AAC_QueueCommand(
12634 +       Scsi_Cmnd *scsi_cmnd_ptr,
12635 +       void ( *CompletionRoutine )( Scsi_Cmnd * ) )
12636 +/*----------------------------------------------------------------------------*/
12637 +{
12638 +       scsi_cmnd_ptr->scsi_done = CompletionRoutine;
12639 +
12640 +       // AacHba_DoScsiCmd() handles command processing, setting the 
12641 +       // result code and calling completion routine. 
12642 +       #ifdef SYNC_FIB
12643 +       if( AacHba_DoScsiCmd( scsi_cmnd_ptr, 1 ) )      // called with wait = TRUE
12644 +       #else
12645 +       if( AacHba_DoScsiCmd( scsi_cmnd_ptr, 0 ) )      // called with wait = FALSE
12646 +       #endif
12647 +               cmn_err( CE_DEBUG, "AacHba_DoScsiCmd failed" );
12648 +       return 0;
12649 +} 
12650 +
12651 +
12652 +/*------------------------------------------------------------------------------
12653 +       AAC_Done()
12654 +
12655 +               Callback function for a non-queued command.
12656 +
12657 +       Postconditions
12658 +               Sets g_single_command done to TRUE
12659 + *----------------------------------------------------------------------------*/
12660 +void AAC_Done( 
12661 +       Scsi_Cmnd * scsi_cmnd_ptr ) 
12662 +/*----------------------------------------------------------------------------*/
12663 +{
12664 +       g_single_command_done = TRUE;
12665 +}
12666 +
12667 +
12668 +/*------------------------------------------------------------------------------
12669 +       AAC_Command()
12670 +       
12671 +               Accepts a single command for execution by the associated Host Adapter.
12672 +
12673 +       Postconditions
12674 +               Returns an int where:
12675 +               Byte 0 = SCSI status code
12676 +               Byte 1 = SCSI 1 byte message
12677 +               Byte 2 = host error return
12678 +               Byte 3 = mid level error return
12679 + *----------------------------------------------------------------------------*/
12680 +int AAC_Command(
12681 +       Scsi_Cmnd *scsi_cmnd_ptr )
12682 +/*----------------------------------------------------------------------------*/
12683 +{
12684 +       scsi_cmnd_ptr->scsi_done = AAC_Done;
12685 +
12686 +       cmn_err( CE_DEBUG, "AAC_Command" );
12687 +
12688 +       // AacHba_DoScsiCmd() handles command processing, setting the 
12689 +       // result code and calling completion routine.
12690 +       g_single_command_done = FALSE;
12691 +       
12692 +       AacHba_DoScsiCmd( scsi_cmnd_ptr, 0 );
12693 +       while( !g_single_command_done );
12694 +       return( scsi_cmnd_ptr->result );
12695 +} 
12696 +
12697 +
12698 +/*------------------------------------------------------------------------------
12699 +       AAC_AbortCommand()
12700 +
12701 +               Abort command if possible.
12702 + *----------------------------------------------------------------------------*/
12703 +int AAC_AbortCommand( 
12704 +       Scsi_Cmnd *scsi_cmnd_ptr )
12705 +/*----------------------------------------------------------------------------*/
12706 +{
12707 +       int target = scsi_cmnd_ptr->target;
12708 +       int hba = scsi_cmnd_ptr->host->unique_id;
12709 +       int result = 0;
12710 +       u_short interrupt_status;
12711 +       PCI_MINIPORT_COMMON_EXTENSION *cep;
12712 +       char   *DeviceName;
12713 +
12714 +       cmn_err( CE_WARN, "%s:%d ABORT", g_DriverName, hba, target );
12715 +       AacHba_AbortScsiCommand( scsi_cmnd_ptr );
12716 +
12717 +       cep = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
12718 +       DeviceName = MiniPorts[cep->OsDep.MiniPortIndex].DeviceName; 
12719 +
12720 +               /*
12721 +               cmn_err( CE_WARN, "%s:%d Unable to abort command to target %d - "
12722 +                 "command already completed", DeviceName, hba, target);
12723 +               result = SCSI_ABORT_NOT_RUNNING;
12724 +
12725 +               cmn_err(CE_WARN, "%s:%d Unable to abort command to target %d - "
12726 +                  "no command found\n", DeviceName, hba, target);
12727 +               result = SCSI_ABORT_NOT_RUNNING;
12728 +
12729 +               cmn_err(CE_WARN, "%s:%d Unable to abort command to target %d - "
12730 +                  "command reset\n", DeviceName, hba, target);
12731 +               result = SCSI_ABORT_PENDING;
12732 +
12733 +               cmn_err(CE_WARN, "%s:%d Unable to abort command to target %d - "
12734 +                  "abort tag not supported\n", DeviceName, hba, target);
12735 +               result = SCSI_ABORT_SNOOZE;
12736 +
12737 +               cmn_err(CE_WARN, "%s:%d Aborting command to target %d - pending",
12738 +                  DeviceName, hba, target);
12739 +               result = SCSI_ABORT_PENDING;
12740 +
12741 +               cmn_err(CE_WARN, "%s:%d Unable to abort command to target %d",
12742 +                  DeviceName, hba, target);
12743 +               result = SCSI_ABORT_BUSY;
12744 +
12745 +               cmn_err(CE_WARN, "%s:%d Aborted command to target %d\n",
12746 +                  DeviceName, hba, target);
12747 +               result = SCSI_ABORT_SUCCESS;
12748 +               */
12749 +
12750 +       // Abort not supported yet
12751 +       result = SCSI_ABORT_BUSY;
12752 +       return result;
12753 +}
12754 +
12755 +
12756 +/*------------------------------------------------------------------------------
12757 +       AAC_ResetCommand()
12758 +
12759 +               Reset command handling.
12760 + *----------------------------------------------------------------------------*/
12761 +int AAC_ResetCommand( 
12762 +       struct scsi_cmnd *scsi_cmnd_ptr, 
12763 +       unsigned int reset_flags )
12764 +/*----------------------------------------------------------------------------*/
12765 +{
12766 +       int target = scsi_cmnd_ptr->target;
12767 +       int hba = scsi_cmnd_ptr->host->unique_id;
12768 +       PCI_MINIPORT_COMMON_EXTENSION *cep;
12769 +       char    *DeviceName;
12770 +
12771 +       cep = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
12772 +       DeviceName = MiniPorts[cep->OsDep.MiniPortIndex].DeviceName;
12773 +
12774 +       cmn_err( CE_WARN, "%s:%d RESET", DeviceName, hba, target );
12775 +
12776 +       return SCSI_RESET_PUNT;
12777 +}
12778 +
12779 +
12780 +/*------------------------------------------------------------------------------
12781 +       AAC_DriverInfo()
12782 +
12783 +               Returns the host adapter name
12784 + *----------------------------------------------------------------------------*/
12785 +const char *AAC_DriverInfo( 
12786 +       struct Scsi_Host *host_ptr )
12787 +/*----------------------------------------------------------------------------*/
12788 +{
12789 +  PCI_MINIPORT_COMMON_EXTENSION *cep;
12790 +  char *DeviceName;
12791 +
12792 +  cep = ( PCI_MINIPORT_COMMON_EXTENSION * )( host_ptr->hostdata );
12793 +  DeviceName = MiniPorts[cep->OsDep.MiniPortIndex].DeviceName;
12794 +
12795 +  cmn_err( CE_DEBUG, "AAC_DriverInfo" );
12796 +  return (DeviceName);
12797 +}
12798 +
12799 +
12800 +/*------------------------------------------------------------------------------
12801 +       AAC_BIOSDiskParameters()
12802 +
12803 +               Return the Heads/Sectors/Cylinders BIOS Disk Parameters for Disk.  
12804 +               The default disk geometry is 64 heads, 32 sectors, and the appropriate 
12805 +               number of cylinders so as not to exceed drive capacity.  In order for 
12806 +               disks equal to or larger than 1 GB to be addressable by the BIOS
12807 +               without exceeding the BIOS limitation of 1024 cylinders, Extended 
12808 +               Translation should be enabled.   With Extended Translation enabled, 
12809 +               drives between 1 GB inclusive and 2 GB exclusive are given a disk 
12810 +               geometry of 128 heads and 32 sectors, and drives above 2 GB inclusive 
12811 +               are given a disk geometry of 255 heads and 63 sectors.  However, if 
12812 +               the BIOS detects that the Extended Translation setting does not match 
12813 +               the geometry in the partition table, then the translation inferred 
12814 +               from the partition table will be used by the BIOS, and a warning may 
12815 +               be displayed.
12816 + *----------------------------------------------------------------------------*/
12817 +int AAC_BIOSDiskParameters(
12818 +       Scsi_Disk *scsi_disk_ptr, 
12819 +       kdev_t device,
12820 +       int *parameter_ptr )
12821 +/*----------------------------------------------------------------------------*/
12822 +{
12823 +       AAC_BIOS_DiskParameters_T *disk_parameters = 
12824 +               ( AAC_BIOS_DiskParameters_T *)parameter_ptr;
12825 +       struct buffer_head * buffer_head_ptr;
12826 +
12827 +       cmn_err( CE_DEBUG, "AAC_BIOSDiskParameters" );
12828 +
12829 +       // Assuming extended translation is enabled - #REVISIT#
12830 +       if( scsi_disk_ptr->capacity >= 2 * 1024 * 1024 ) // 1 GB in 512 byte sectors
12831 +       {
12832 +               if( scsi_disk_ptr->capacity >= 4 * 1024 * 1024 ) // 2 GB in 512 byte sectors
12833 +               {
12834 +                       disk_parameters->heads = 255;
12835 +                       disk_parameters->sectors = 63;
12836 +               }
12837 +               else
12838 +               {
12839 +                       disk_parameters->heads = 128;
12840 +                       disk_parameters->sectors = 32;
12841 +               }
12842 +       }
12843 +       else
12844 +       {
12845 +               disk_parameters->heads = 64;
12846 +               disk_parameters->sectors = 32;
12847 +       }
12848 +
12849 +       disk_parameters->cylinders = scsi_disk_ptr->capacity
12850 +               /( disk_parameters->heads * disk_parameters->sectors );
12851 +
12852 +       // Read the first 1024 bytes from the disk device
12853 +       buffer_head_ptr = bread( 
12854 +                                               MKDEV( MAJOR( device ), 
12855 +                                               MINOR( device ) & ~0x0F ), 
12856 +                                               0, 1024 );
12857 +
12858 +       if( buffer_head_ptr == NULL )
12859 +               return( 0 );
12860 +       /* 
12861 +               If the boot sector partition table is valid, search for a partition 
12862 +               table entry whose end_head matches one of the standard geometry 
12863 +               translations ( 64/32, 128/32, 255/63 ).
12864 +       */
12865 +       if( *( unsigned short * )( buffer_head_ptr->b_data + 0x1fe ) == 0xaa55 )
12866 +       {
12867 +               struct partition *first_partition_entry =
12868 +                       ( struct partition * )( buffer_head_ptr->b_data + 0x1be );
12869 +               struct partition *partition_entry = first_partition_entry;
12870 +               int saved_cylinders = disk_parameters->cylinders;
12871 +               int partition_number;
12872 +               unsigned char partition_entry_end_head, partition_entry_end_sector;
12873 +
12874 +               for( partition_number = 0; partition_number < 4; partition_number++ )
12875 +               {
12876 +                       partition_entry_end_head   = partition_entry->end_head;
12877 +                       partition_entry_end_sector = partition_entry->end_sector & 0x3f;
12878 +
12879 +                       if( partition_entry_end_head == ( 64 - 1 ) )
12880 +                       {
12881 +                               disk_parameters->heads = 64;
12882 +                               disk_parameters->sectors = 32;
12883 +                               break;
12884 +                       }
12885 +                       else if( partition_entry_end_head == ( 128 - 1 ) )
12886 +                       {
12887 +                               disk_parameters->heads = 128;
12888 +                               disk_parameters->sectors = 32;
12889 +                               break;
12890 +                       }
12891 +                       else if( partition_entry_end_head == ( 255 - 1 ) ) 
12892 +                       {
12893 +                               disk_parameters->heads = 255;
12894 +                               disk_parameters->sectors = 63;
12895 +                               break;
12896 +                       }
12897 +                       partition_entry++;
12898 +               }
12899 +
12900 +               if( partition_number == 4 )
12901 +               {
12902 +                       partition_entry_end_head   = first_partition_entry->end_head;
12903 +                       partition_entry_end_sector = first_partition_entry->end_sector & 0x3f;
12904 +               }
12905 +
12906 +               disk_parameters->cylinders = scsi_disk_ptr->capacity
12907 +                       /( disk_parameters->heads * disk_parameters->sectors );
12908 +
12909 +               if( ( partition_number < 4 )  && ( partition_entry_end_sector == disk_parameters->sectors ) )
12910 +               {
12911 +                       if( disk_parameters->cylinders != saved_cylinders )
12912 +                               cmn_err( CE_DEBUG, "Adopting geometry: heads=%d, sectors=%d from partition table %d",
12913 +                                       disk_parameters->heads, disk_parameters->sectors, partition_number );
12914 +               }
12915 +               else if( ( partition_entry_end_head > 0 ) || ( partition_entry_end_sector > 0 ) )
12916 +               {
12917 +                       cmn_err( CE_DEBUG, "Strange geometry: heads=%d, sectors=%d in partition table %d",
12918 +                               partition_entry_end_head + 1, partition_entry_end_sector, partition_number );
12919 +                       cmn_err( CE_DEBUG, "Using geometry: heads=%d, sectors=%d",
12920 +                                       disk_parameters->heads, disk_parameters->sectors );
12921 +               }
12922 +       }
12923 +       
12924 +       brelse( buffer_head_ptr );
12925 +
12926 +       return( 0 );
12927 +}
12928 +
12929 +
12930 +/*------------------------------------------------------------------------------
12931 +       AAC_SelectQueueDepths()
12932 +
12933 +               Selects queue depths for each target device based on the host adapter's
12934 +               total capacity and the queue depth supported by the target device.
12935 +               A queue depth of one automatically disables tagged queueing.
12936 + *----------------------------------------------------------------------------*/
12937 +void AAC_SelectQueueDepths(
12938 +       struct Scsi_Host * host_ptr,
12939 +       Scsi_Device * scsi_device_ptr )
12940 +/*----------------------------------------------------------------------------*/
12941 +{
12942 +       Scsi_Device * device_ptr;
12943 +
12944 +       cmn_err( CE_DEBUG, "AAC_SelectQueueDepths" );
12945 +       cmn_err( CE_DEBUG, "Device #   Q Depth   Online" );
12946 +       cmn_err( CE_DEBUG, "---------------------------" );
12947 +       for( device_ptr = scsi_device_ptr; device_ptr != NULL; device_ptr = device_ptr->next )
12948 +               if( device_ptr->host == host_ptr )
12949 +               {
12950 +                       device_ptr->queue_depth = 10;           
12951 +                       cmn_err( CE_DEBUG, "  %2d         %d        %d", 
12952 +                               device_ptr->id, device_ptr->queue_depth, device_ptr->online );
12953 +               }
12954 +}
12955 +
12956 +
12957 +/*------------------------------------------------------------------------------
12958 +       AAC_SearchBiosSignature()
12959 +
12960 +               Locate adapter signature in BIOS
12961 + *----------------------------------------------------------------------------*/
12962 +int AAC_SearchBiosSignature( void )
12963 +/*----------------------------------------------------------------------------*/
12964 +{
12965 +       unsigned base;
12966 +       unsigned namep;
12967 +       int index;
12968 +       int val;
12969 +       char name_buf[32];
12970 +       int result = FALSE;
12971 +
12972 +       for( base = 0xc8000; base < 0xdffff; base += 0x4000 )
12973 +       {
12974 +               val = readb( base );
12975 +               if( val != 0x55 ) 
12976 +                       continue;
12977 +
12978 +               result = TRUE;
12979 +               namep = base + 0x1e;
12980 +               memcpy_fromio( name_buf, namep, 32 );
12981 +               name_buf[31] = '\0';
12982 +       }
12983 +       return( result );
12984 +}
12985 +
12986 +
12987 +/*------------------------------------------------------------------------------
12988 +       AAC_Ioctl()
12989 +
12990 +               Handle SCSI ioctls
12991 + *----------------------------------------------------------------------------*/
12992 +int AAC_Ioctl(
12993 +       Scsi_Device * scsi_dev_ptr,
12994 +       int cmd,
12995 +       void * arg )
12996 +/*----------------------------------------------------------------------------*/
12997 +{
12998 +       PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
12999 +
13000 +       cmn_err( CE_DEBUG, "AAC_Ioctl" );
13001 +       CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )scsi_dev_ptr->host->hostdata;
13002 +       return( AacHba_Ioctl( CommonExtensionPtr, cmd, arg ) );
13003 +}
13004 +
13005 +
13006 +
13007 +/*------------------------------------------------------------------------------
13008 +       AAC_ChardevOpen()
13009 +       
13010 +               Handle character device open
13011 +       
13012 +       Preconditions:
13013 +       Postconditions:
13014 +               Returns 0 if successful, -ENODEV or -EINVAL otherwise
13015 + *----------------------------------------------------------------------------*/
13016 +int AAC_ChardevOpen(
13017 +       struct inode * inode_ptr,
13018 +       struct file * file_ptr )
13019 +/*----------------------------------------------------------------------------*/
13020 +{
13021 +       unsigned minor_number;
13022 +
13023 +       cmn_err( CE_DEBUG, "AAC_ChardevOpen" );
13024 +
13025 +       // check device permissions in file_ptr->f_mode ??
13026 +
13027 +       // extract & check the minor number
13028 +       minor_number = MINOR( inode_ptr->i_rdev );
13029 +       if( minor_number > ( g_HostAdapterCount - 1 ) )
13030 +       {
13031 +               cmn_err( CE_WARN, "AAC_ChardevOpen: Minor number %d not supported", minor_number );
13032 +               return( -ENODEV );
13033 +       }
13034 +
13035 +#ifdef MODULE
13036 +       MOD_INC_USE_COUNT;
13037 +#endif
13038 +
13039 +       return( 0 );
13040 +}
13041 +
13042 +
13043 +/*------------------------------------------------------------------------------
13044 +       AAC_ChardevRelease()
13045 +       
13046 +               Handle character device release.
13047 +       
13048 +       Preconditions:
13049 +       Postconditions:
13050 +               Returns 0 if successful, -ENODEV or -EINVAL otherwise
13051 + *----------------------------------------------------------------------------*/
13052 +int AAC_ChardevRelease(
13053 +       struct inode * inode_ptr,
13054 +       struct file * file_ptr )
13055 +/*----------------------------------------------------------------------------*/
13056 +{
13057 +       cmn_err( CE_DEBUG, "AAC_ChardevRelease" );
13058 +
13059 +#ifdef MODULE
13060 +       MOD_DEC_USE_COUNT;
13061 +#endif
13062 +
13063 +       return( 0 );
13064 +}
13065 +
13066 +
13067 +/*------------------------------------------------------------------------------
13068 +       AAC_ChardevIoctl()
13069 +       
13070 +               Handle character device interface ioctls
13071 +       
13072 +       Preconditions:
13073 +       Postconditions:
13074 +               Returns 0 if successful, -ENODEV or -EINVAL otherwise
13075 + *----------------------------------------------------------------------------*/
13076 +int AAC_ChardevIoctl(
13077 +       struct inode * inode_ptr, 
13078 +       struct file * file_ptr,
13079 +       unsigned int cmd,
13080 +       unsigned long arg )
13081 +{
13082 +       unsigned minor_number;
13083 +       PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
13084 +
13085 +       cmn_err( CE_DEBUG, "AAC_ChardevIoctl" );
13086 +
13087 +       // check device permissions in file_ptr->f_mode ??
13088 +
13089 +       // extract & check the minor number
13090 +       minor_number = MINOR( inode_ptr->i_rdev );
13091 +       if( minor_number > ( g_HostAdapterCount - 1 ) )
13092 +       {
13093 +               cmn_err( CE_WARN, "AAC_ChardevIoctl: Minor number %d not supported", minor_number );
13094 +               return( -ENODEV );
13095 +       }
13096 +
13097 +       // get device pointer
13098 +       CommonExtensionPtr = g_CommonExtensionPtrArray[ minor_number ];
13099 +
13100 +       // dispatch ioctl - AacHba_Ioctl() returns zero on success
13101 +       if( AacHba_Ioctl( CommonExtensionPtr, cmd, ( void * )arg ) )
13102 +               return( -EINVAL );
13103 +
13104 +       return( 0 );
13105 +}
13106 +
13107 +
13108 +/*------------------------------------------------------------------------------
13109 +       parse_keyword()
13110 +
13111 +               Look for the keyword in str_ptr
13112 +
13113 +       Preconditions:
13114 +       Postconditions:
13115 +               If keyword found
13116 +                       - return true and update the pointer str_ptr.
13117 +               otherwise
13118 +                       - return false
13119 + *----------------------------------------------------------------------------*/
13120 +static int parse_keyword(
13121 +       char ** str_ptr, 
13122 +       char * keyword )
13123 +/*----------------------------------------------------------------------------*/
13124 +{
13125 +       char * ptr = *str_ptr;
13126 +       
13127 +       while( *keyword != '\0' )
13128 +       {
13129 +               char string_char = *ptr++;
13130 +               char keyword_char = *keyword++;
13131 +
13132 +               if ( ( string_char >= 'A' ) && ( string_char <= 'Z' ) )
13133 +                       string_char += 'a' - 'Z';
13134 +               if( ( keyword_char >= 'A' ) && ( keyword_char <= 'Z' ) ) 
13135 +                       keyword_char += 'a' - 'Z';
13136 +               if( string_char != keyword_char )
13137 +                       return FALSE;
13138 +       }
13139 +       *str_ptr = ptr;
13140 +       return TRUE;
13141 +}
13142 +
13143 +
13144 +/*------------------------------------------------------------------------------
13145 +       AAC_ParseDriverOptions()
13146 +
13147 +       For modules the usage is:
13148 +               insmod -f aacraid.o 'aacraid_options="<option_name:argument>"'
13149 + *----------------------------------------------------------------------------*/
13150 +static void AAC_ParseDriverOptions( 
13151 +       char * cmnd_line_options_str )
13152 +/*----------------------------------------------------------------------------*/
13153 +{
13154 +       int message_level;
13155 +       int reverse_scan;
13156 +       char *cp;
13157 +       char *endp;
13158 +
13159 +       cp = cmnd_line_options_str;
13160 +
13161 +       cmn_err(CE_DEBUG, "AAC_ParseDriverOptions: <%s>", cp);
13162 +
13163 +       while( *cp ) {
13164 +               if( parse_keyword( &cp, "message_level:" ) ) {
13165 +                       message_level = simple_strtoul( cp, 0, 0 );
13166 +                       if( ( message_level < CE_TAIL ) && ( message_level >= 0 ) ) {
13167 +                               g_options.message_level = message_level;
13168 +                               cmn_err( CE_WARN, "%s: new message level = %d", g_DriverName, g_options.message_level );
13169 +                       }
13170 +                       else {
13171 +                               cmn_err( CE_WARN, "%s: invalid message level = %d", g_DriverName, message_level );
13172 +                       }
13173 +               } else if (parse_keyword( &cp, "reverse_scan:" ) ) {
13174 +                       reverse_scan = simple_strtoul( cp, 0, 0 );
13175 +                       if (reverse_scan) {
13176 +                               g_options.reverse_scan = 1;
13177 +                               cmn_err( CE_WARN, "%s: reversing device discovery order", g_DriverName, g_options.message_level );
13178 +                       }
13179 +               }
13180 +               else {
13181 +                       cmn_err( CE_WARN, "%s: unknown command line option <%s>", g_DriverName, cp );
13182 +               }
13183 +
13184 +               /*
13185 +                * skip to next option,  accept " ", ";", and "," as delimiters
13186 +                */
13187 +               while ( *cp && (*cp != ' ')  && (*cp != ';')  && (*cp != ','))
13188 +                       cp++;
13189 +
13190 +               if (*cp)                                 /* skip over the delimiter */
13191 +                       cp++;
13192 +       }
13193 +
13194 +}
13195 +
13196 +
13197 +/*------------------------------------------------------------------------------
13198 +       Include Module support if requested.
13199 +
13200 +       To use the low level SCSI driver support using the linux kernel loadable 
13201 +       module interface we should initialize the global variable driver_interface  
13202 +       (datatype Scsi_Host_Template) and then include the file scsi_module.c.
13203 +       This should also be wrapped in a #ifdef MODULE/#endif
13204 + *----------------------------------------------------------------------------*/
13205 +#ifdef MODULE
13206 +
13207 +/*
13208 +       The Loadable Kernel Module Installation Facility may pass us
13209 +       a pointer to a driver specific options string to be parsed, 
13210 +       we assign this to options string. 
13211 +*/
13212 +MODULE_PARM( module_options, "s" );
13213 +
13214 +Scsi_Host_Template driver_template = AAC_HOST_TEMPLATE_ENTRY;
13215 +
13216 +#include "scsi_module.c"
13217 +
13218 +#else
13219 +Scsi_Host_Template driver_template = AAC_HOST_TEMPLATE_ENTRY;
13220 +
13221 +#include "scsi_module.c"
13222 +#endif
13223 +
13224 +/*********************************************************************
13225 +       AAC_ProcDirectoryInfo()
13226 +
13227 +               Implement /proc/scsi/<drivername>/<n>.
13228 +               Used to export driver statistics and other infos to the world outside 
13229 +               the kernel using the proc file system. Also provides an interface to
13230 +               feed the driver with information.
13231 +
13232 +       Postconditions
13233 +               For reads
13234 +                       - if offset > 0 return 0
13235 +                       - if offset == 0 write data to proc_buffer and set the start_ptr to
13236 +                       beginning of proc_buffer, return the number of characters written.
13237 +               For writes
13238 +                       - writes currently not supported, return 0
13239 +************************************************************/
13240 +int AAC_ProcDirectoryInfo(
13241 +       char *proc_buffer,              // read/write buffer
13242 +       char **start_ptr,               // start of valid data in the buffer
13243 +       off_t offset,                   // offset from the beginning of the imaginary file 
13244 +       int bytes_available,    // bytes available
13245 +       int host_no,                    // SCSI host number 
13246 +       int write )                             // direction of dataflow: TRUE for writes, FALSE for reads      
13247 +{
13248 +       int length = 0;
13249 +       cmn_err( CE_WARN, "AAC_ProcDirectoryInfo" );
13250 +
13251 +       if( ( write ) || ( offset > 0 ) )
13252 +               return( 0 );
13253 +
13254 +       *start_ptr = proc_buffer;
13255 +
13256 +       return( sprintf(&proc_buffer[length], "%s  %d\n", "Raid Controller, scsi hba number", host_no ) );
13257 +}
13258 +
13259 +void aac_allocate_SyncFibs (PCI_MINIPORT_COMMON_EXTENSION *CommonExtension)
13260 +{
13261 +  void         *BaseAddress;
13262 +  ULONG                PhysAddress;
13263 +  int          size;
13264 +  int          npages;
13265 +  int          i;
13266 +
13267 +  AFA_COMM_ADAPTER             *Adapter;
13268 +  Adapter = CommonExtension->Adapter;
13269 +
13270 +
13271 +  // Allocate 1 fib for synch fibs
13272 +  // Allocate 1 page.
13273 +  BaseAddress = OsAllocMemory ( PAGE_SIZE, OS_ALLOC_MEM_SLEEP);
13274 +  bzero(BaseAddress, PAGE_SIZE);
13275 +  PhysAddress = virt_to_phys (BaseAddress);
13276 +  Adapter->SyncFib = BaseAddress;
13277 +  Adapter->SyncFibPhysicalAddress = PhysAddress;
13278 +  cmn_err(CE_DEBUG,"aac_allocate_SyncFibs: syncFib: vaddr: 0x%x paddr: 0x%x ", BaseAddress, PhysAddress);
13279 +
13280 +}
13281 diff -urN linux/drivers/scsi/aacraid/osddi.c linux/drivers/scsi/aacraid/osddi.c
13282 --- linux/drivers/scsi/aacraid/osddi.c  Wed Dec 31 19:00:00 1969
13283 +++ linux/drivers/scsi/aacraid/osddi.c  Thu Dec 21 13:14:30 2000
13284 @@ -0,0 +1,512 @@
13285 +/*++
13286 + * Adaptec aacraid device driver for Linux.
13287 + *
13288 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
13289 + *
13290 + * This program is free software; you can redistribute it and/or modify
13291 + * it under the terms of the GNU General Public License as published by
13292 + * the Free Software Foundation; either version 2, or (at your option)
13293 + * any later version.
13294 + *
13295 + * This program is distributed in the hope that it will be useful,
13296 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
13297 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13298 + * GNU General Public License for more details.
13299 + *
13300 + * You should have received a copy of the GNU General Public License
13301 + * along with this program; see the file COPYING.  If not, write to
13302 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
13303 + *
13304 + * Module Name:
13305 + *   osddi.c
13306 + *
13307 + * Abstract: This file contains all the proceedures which use LINUX specific Device 
13308 + *             Driver Interfaces.
13309 + *     
13310 + --*/
13311 +
13312 +static char *ident_osddi = "aacraid_ident osddi.c 1.0.6 2000/10/09 Adaptec, Inc.";
13313 +
13314 +#include "osheaders.h"
13315 +
13316 +#include <linux/smp_lock.h>
13317 +
13318 +#ifdef fsid_t
13319 +#undef fsid_t
13320 +#endif
13321 +#include "AacGenericTypes.h"
13322 +#include "aac_unix_defs.h"
13323 +#include "comstruc.h"
13324 +#include "monkerapi.h"
13325 +#include "protocol.h"
13326 +#include "fsafs.h"
13327 +
13328 +#include "sap1common.h"
13329 +#include "fsaport.h"
13330 +#include "pcisup.h"
13331 +#include "sap1.h"
13332 +#include "nodetype.h"
13333 +#include "comsup.h"
13334 +#include "afacomm.h"
13335 +#include "adapter.h"
13336 +
13337 +
13338 +void AacSaPciIsr( 
13339 +       int irq,
13340 +       void * irq_data,
13341 +       struct pt_regs *regs);
13342 +
13343 +void AacRxPciIsr( 
13344 +       int irq,
13345 +       void * irq_data,
13346 +       struct pt_regs *regs);
13347 +
13348 +unsigned SaPciIsr (
13349 +    IN PSa_ADAPTER_EXTENSION AdapterExtension );
13350 +
13351 +unsigned RxPciIsr (
13352 +    IN PSa_ADAPTER_EXTENSION AdapterExtension );
13353 +
13354 +
13355 +/*----------------------------------------------------------------------------*/
13356 +VOID AfaCommInterruptHost(
13357 +       PVOID                   AdapterArg,
13358 +       ADAPTER_EVENT   AdapterEvent )
13359 +/*----------------------------------------------------------------------------*/
13360 +{
13361 +       PAFA_COMM_ADAPTER       Adapter = ( PAFA_COMM_ADAPTER ) AdapterArg;
13362 +       PCOMM_REGION CommRegion = Adapter->CommRegion;
13363 +
13364 +       switch (AdapterEvent) {
13365 +
13366 +         case HostNormRespQue:
13367 +               OsSoftInterruptTrigger( CommRegion->HostNormRespQue.ConsumerRoutine );
13368 +       
13369 +       // #REVIEW# - what do we do with this
13370 +       // if (FsaCommData.HardInterruptModeration)
13371 +       //                      DisableInterrupt( Adapter, HostNormRespQue, TRUE );
13372 +
13373 +                       break;
13374 +
13375 +      case AdapNormCmdNotFull:
13376 +               OsSoftInterruptTrigger( CommRegion->QueueNotFullDpc );
13377 +                       break;
13378 +
13379 +         case HostNormCmdQue:
13380 +               OsSoftInterruptTrigger( CommRegion->HostNormCmdQue.ConsumerRoutine );
13381 +                       break;
13382 +
13383 +      case AdapNormRespNotFull:
13384 +               OsSoftInterruptTrigger( CommRegion->QueueNotFullDpc );
13385 +                       break;
13386 +
13387 +       // #REVIEW# - what do we do with these
13388 +         case HostHighCmdQue:
13389 +         case HostHighRespQue:
13390 +         case AdapHighCmdNotFull:
13391 +         case AdapHighRespNotFull:
13392 +         case SynchCommandComplete:
13393 +         case AdapInternalError:
13394 +                 break;
13395 +       }
13396 +}
13397 +
13398 +
13399 +// get the device name associated with this instance of the device
13400 +/*----------------------------------------------------------------------------*/
13401 +char *OsGetDeviceName( 
13402 +       void *AdapterExtension )
13403 +/*----------------------------------------------------------------------------*/
13404 +{
13405 +       return( ( ( Sa_ADAPTER_EXTENSION * )AdapterExtension )->Common->
13406 +               OsDep.scsi_host_ptr->hostt->name );
13407 +}
13408 +
13409 +
13410 +/*----------------------------------------------------------------------------*/
13411 +int OsGetDeviceInstance( 
13412 +       void *AdapterExtension )
13413 +/*----------------------------------------------------------------------------*/
13414 +{
13415 +       return( ( int )( ( Sa_ADAPTER_EXTENSION * )AdapterExtension )->Common->
13416 +               OsDep.scsi_host_ptr->unique_id );
13417 +}
13418 +
13419 +
13420 +/*------------------------------------------------------------------------------
13421 +       OsMapDeviceRegisters()
13422 +
13423 +       Postconditions:
13424 +               Return zero on success non-zero otherwise.
13425 + *----------------------------------------------------------------------------*/
13426 +int OsMapDeviceRegisters( 
13427 +       Sa_ADAPTER_EXTENSION *AdapterExtension )
13428 +/*----------------------------------------------------------------------------*/
13429 +{
13430 +       PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
13431 +
13432 +       CommonExtension = AdapterExtension->Common;
13433 +
13434 +       if( AdapterExtension->Device = ( Sa_DEVICE_REGISTERS * )
13435 +                       ioremap( ( unsigned long )CommonExtension->OsDep.scsi_host_ptr->base, 8192 ) )
13436 +       {
13437 +               cmn_err( CE_WARN, "Device mapped to virtual address 0x%x", AdapterExtension->Device ); 
13438 +               return( 0 );
13439 +       }
13440 +       else
13441 +       {       
13442 +               cmn_err( CE_WARN, "OsMapDeviceRegisters: ioremap() failed" );
13443 +               return( 1 );
13444 +       }
13445 +}
13446 +
13447 +
13448 +/*------------------------------------------------------------------------------
13449 +       OsUnMapDeviceRegisters()
13450 +
13451 +       Postconditions:
13452 + *----------------------------------------------------------------------------*/
13453 +void OsUnMapDeviceRegisters( 
13454 +       Sa_ADAPTER_EXTENSION *AdapterExtension )
13455 +/*----------------------------------------------------------------------------*/
13456 +{
13457 +       iounmap( ( void * )AdapterExtension->Device );
13458 +}
13459 +
13460 +
13461 +/*----------------------------------------------------------------------------*/
13462 +int OsAttachInterrupt( 
13463 +       Sa_ADAPTER_EXTENSION *AdapterExtension ,
13464 +       int     WhichIsr )
13465 +/*----------------------------------------------------------------------------*/
13466 +{
13467 +       PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
13468 +       void *irq_data;
13469 +       void (*Isr)();
13470 +
13471 +       CommonExtension = AdapterExtension->Common;
13472 +       irq_data = ( void * )AdapterExtension;
13473 +
13474 +       switch (WhichIsr) {
13475 +               case SaISR:
13476 +                       Isr = AacSaPciIsr;
13477 +                       break;
13478 +               case RxISR:
13479 +                       Isr = AacRxPciIsr;
13480 +                       break;
13481 +               default:
13482 +                       cmn_err(CE_WARN, "OsAttachInterrupt: invalid ISR case: 0x%x", WhichIsr);
13483 +                       return( FAILURE );
13484 +                       break;
13485 +       }
13486 +
13487 +       
13488 +       if      ( OsRegisterInterrupt (
13489 +                               CommonExtension->OsDep.scsi_host_ptr->irq,      // interrupt number
13490 +                               Isr,                                                                            // handler function
13491 +                               irq_data )
13492 +               ) 
13493 +       {
13494 +               cmn_err( CE_WARN, "OsAttachInterrupt: Failed for IRQ: 0x%x", 
13495 +                       CommonExtension->OsDep.scsi_host_ptr->irq );
13496 +               return( FAILURE );
13497 +       }
13498 +
13499 +       return ( 0 );
13500 +}
13501 +
13502 +
13503 +/*----------------------------------------------------------------------------*/
13504 +void AacSaPciIsr( 
13505 +       int irq,
13506 +       void * irq_data,
13507 +       struct pt_regs *regs)
13508 +/*----------------------------------------------------------------------------*/
13509 +{
13510 +       // call the actual interrupt handler
13511 +       SaPciIsr( ( Sa_ADAPTER_EXTENSION * )irq_data );
13512 +}
13513 +
13514 +/*----------------------------------------------------------------------------*/
13515 +void AacRxPciIsr( 
13516 +       int irq,
13517 +       void * irq_data,
13518 +       struct pt_regs *regs)
13519 +/*----------------------------------------------------------------------------*/
13520 +{
13521 +       // call the actual interrupt handler
13522 +       RxPciIsr( ( Sa_ADAPTER_EXTENSION * )irq_data );
13523 +}
13524 +
13525 +
13526 +/*----------------------------------------------------------------------------*/
13527 +void OsDetachInterrupt( 
13528 +       Sa_ADAPTER_EXTENSION *AdapterExtension )
13529 +/*----------------------------------------------------------------------------*/
13530 +{
13531 +       PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
13532 +       void *irq_data;
13533 +
13534 +       CommonExtension = AdapterExtension->Common;
13535 +       irq_data = ( void * )AdapterExtension;
13536 +
13537 +       OsUnregisterInterrupt (
13538 +               CommonExtension->OsDep.scsi_host_ptr->irq,      // interrupt number
13539 +               irq_data );
13540 +}
13541 +
13542 +
13543 +/*----------------------------------------------------------------------------*/
13544 +int OsAttachDMA( 
13545 +       Sa_ADAPTER_EXTENSION *AdapterExtension )
13546 +/*----------------------------------------------------------------------------*/
13547 +{
13548 +       return( 0 );
13549 +}
13550 +
13551 +/*----------------------------------------------------------------------------*/
13552 +int OsAttachHBA( 
13553 +       Sa_ADAPTER_EXTENSION *AdapterExtension )
13554 +/*----------------------------------------------------------------------------*/
13555 +{
13556 +       return( 0 );
13557 +}
13558 +
13559 +/*----------------------------------------------------------------------------*/
13560 +void OsDetachDevice( 
13561 +       Sa_ADAPTER_EXTENSION *AdapterExtension )
13562 +/*----------------------------------------------------------------------------*/
13563 +{
13564 +       OsUnMapDeviceRegisters( AdapterExtension );
13565 +       return( 0 );
13566 +}
13567 +
13568 +/*----------------------------------------------------------------------------*/
13569 +ULONG *OsAllocCommPhysMem(
13570 +       Sa_ADAPTER_EXTENSION    *AdapterExtension, 
13571 +       ULONG                                   size,
13572 +       ULONG                                   **virt_addr_pptr,
13573 +       ULONG                                   *phys_addr_ptr )
13574 +/*----------------------------------------------------------------------------*/
13575 +{
13576 +       if( ( *virt_addr_pptr = ( ULONG * )OsAllocMemory( size, GFP_KERNEL ) ) )
13577 +       {
13578 +               *phys_addr_ptr = OsVirtToPhys( ( volatile void * )*virt_addr_pptr );
13579 +               if( !*phys_addr_ptr )
13580 +               {
13581 +                       cmn_err( CE_WARN, "OsAllocCommPhysMem: OsVirtToPhys failed" );
13582 +               }
13583 +                               
13584 +               return( *virt_addr_pptr );
13585 +       }
13586 +       else
13587 +               return( NULL );
13588 +}
13589 +
13590 +OsAifKernelThread(
13591 +       Sa_ADAPTER_EXTENSION    *AdapterExtension )
13592 +{
13593 +
13594 +       struct fs_struct *fs;
13595 +       int i;
13596 +       struct task_struct *tsk;
13597 +
13598 +       tsk = current;
13599 +
13600 +
13601 +       /*
13602 +        * set up the name that will appear in 'ps'
13603 +        * stored in  task_struct.comm[16].
13604 +        */
13605 +
13606 +       sprintf(tsk->comm, "AIFd");
13607 +
13608 +
13609 +       // use_init_fs_context();  only exists in 2.2.13 onward.
13610 +
13611 +#ifdef __SMP__
13612 +       lock_kernel();
13613 +#endif
13614 +
13615 +       /*
13616 +        * we were started as a result of loading the  module.
13617 +        * free all of user space pages
13618 +        */
13619 +
13620 +       exit_mm(tsk);
13621 +
13622 +       exit_files(tsk);
13623 +
13624 +       exit_fs(tsk);
13625 +
13626 +       fs = init_task.fs;
13627 +       tsk->fs = fs;
13628 +
13629 +       tsk->session = 1;
13630 +       tsk->pgrp = 1;
13631 +
13632 +       if (fs)
13633 +               atomic_inc(&fs->count);
13634 +
13635 +#ifdef __SMP__
13636 +       unlock_kernel();
13637 +#endif
13638 +
13639 +
13640 +
13641 +
13642 +       NormCommandThread(AdapterExtension);
13643 +       /* NOT REACHED */
13644 +}
13645 +
13646 +/*----------------------------------------------------------------------------*/
13647 +void OsStartKernelThreads(
13648 +       Sa_ADAPTER_EXTENSION    *AdapterExtension )
13649 +/*----------------------------------------------------------------------------*/
13650 +{
13651 +       PCI_MINIPORT_COMMON_EXTENSION   *CommonExtension;
13652 +       AFA_COMM_ADAPTER                                *Adapter;
13653 +       extern void                                     NormCommandThread(void *Adapter);
13654 +
13655 +       CommonExtension = AdapterExtension->Common;
13656 +       Adapter = (AFA_COMM_ADAPTER *)CommonExtension->Adapter;
13657 +
13658 +       // 
13659 +       // Start thread which will handle interrupts for this adapter
13660 +       //
13661 +       //kthread_spawn(FsaCommIntrHandler, AdapterExtension, "fsaintr",0);
13662 +
13663 +       //
13664 +       // Start thread which will handle AdapterInititatedFibs from this adapter
13665 +       //
13666 +       CommonExtension->OsDep.thread_pid = 
13667 +               kernel_thread( ( int ( * )( void * ) )OsAifKernelThread, Adapter, 0 );
13668 +//             kernel_thread( ( int ( * )( void * ) )NormCommandThread, Adapter, 0 );
13669 +}
13670 +
13671 +/*----------------------------------------------------------------------------*/
13672 +BOOLEAN AfaPortAllocateAndMapFibSpace(
13673 +       PVOID Arg1,
13674 +    IN PMAPFIB_CONTEXT MapFibContext )
13675 +/*----------------------------------------------------------------------------*/
13676 +{
13677 +       PVOID           BaseAddress;
13678 +       ULONG           PhysAddress;
13679 +
13680 +       if( !( BaseAddress = (ULONG *)OsAllocMemory( MapFibContext->Size, GFP_KERNEL ) ) )
13681 +       {
13682 +               cmn_err( CE_WARN, "AfaPortAllocateAndMapFibSpace: OsAllocMemory failed" );
13683 +               return( FALSE );
13684 +       }
13685 +
13686 +       PhysAddress = OsVirtToPhys( BaseAddress );
13687 +       
13688 +       MapFibContext->FibVirtualAddress = BaseAddress;
13689 +       MapFibContext->FibPhysicalAddress = (PVOID) PhysAddress;
13690 +
13691 +       return (TRUE);
13692 +}
13693 +
13694 +/*----------------------------------------------------------------------------*/
13695 +BOOLEAN AfaPortUnmapAndFreeFibSpace(
13696 +       PVOID Arg1,
13697 +    IN PMAPFIB_CONTEXT MapFibContext )
13698 +/*----------------------------------------------------------------------------*/
13699 +{
13700 +       PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
13701 +
13702 +       OsFreeMemory( MapFibContext->FibVirtualAddress, 0 );
13703 +
13704 +       return (TRUE);
13705 +}
13706 +
13707 +/*----------------------------------------------------------------------------*/
13708 +BOOLEAN AfaPortFreeAdapterCommArea(
13709 +       IN PVOID Arg1 )
13710 +/*----------------------------------------------------------------------------*/
13711 +{
13712 +       PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
13713 +
13714 +       OsFreeMemory( CommonExtension->CommAddress, 0 );
13715 +
13716 +       return (TRUE);
13717 +}
13718 +
13719 +
13720 +/* ================================================================================ */
13721 +/*
13722 + * Not sure if the functions below here ever get called in the current code
13723 + * These probably should be a different file.
13724 + */
13725 +/*
13726 +ddi_dma_attr_t AfaPortDmaAttributes = {
13727 +       //rpbfix : we may want something different for I/O
13728 +       DMA_ATTR_V0,
13729 +       0,
13730 +       0xffffffff,
13731 +       0x0000ffff,
13732 +       1,
13733 +       1,
13734 +       1,
13735 +       0x0000ffff,
13736 +       0x0000ffff,
13737 +       17,
13738 +       512,
13739 +       0
13740 +};
13741 +*/
13742 +
13743 +AAC_STATUS
13744 +AfaPortBuildSgMap(
13745 +       PVOID Arg1,
13746 +       IN PSGMAP_CONTEXT SgMapContext
13747 +       )
13748 +
13749 +/*++
13750 +
13751 +Routine Description:
13752 +
13753 +       This routine build a scatter gather map using the information
13754 +       in the SgMapContext.
13755 +
13756 +Arguments:
13757 +
13758 +       AdapterExtension - Pointer to adapter extension structure.
13759 +    SgMapContext - Pointer to the SgMapContext for the request.
13760 +
13761 +
13762 +Return Value:
13763 +
13764 +       AAC_STATUS      
13765 +--*/
13766 +{
13767 +       printk( "<1>AfaPortBuildSgMap: unimplemented function called" );
13768 +       return (STATUS_UNSUCCESSFUL);
13769 +}
13770 +
13771 +VOID
13772 +AfaPortFreeDmaResources(
13773 +       PVOID Arg1,
13774 +    IN PSGMAP_CONTEXT SgMapContext
13775 +    )
13776 +
13777 +/*++
13778 +
13779 +Routine Description:
13780 +
13781 +    Given a pointer to the IRP context will free all reserved DMA resources allocated for
13782 +    the completed IO operation.
13783 +
13784 +Arguments:
13785 +
13786 +    Fib - Pointer to the Fib the caller wishes to have transfered over to the adapter.
13787 +    Context - Pointer to the Irp Context we use to store the dma mapping information
13788 +        we need to do and complete the IO.
13789 +
13790 +Return Value:
13791 +
13792 +    Nothing
13793 +
13794 +--*/
13795 +{
13796 +}
13797 diff -urN linux/drivers/scsi/aacraid/osfuncs.c linux/drivers/scsi/aacraid/osfuncs.c
13798 --- linux/drivers/scsi/aacraid/osfuncs.c        Wed Dec 31 19:00:00 1969
13799 +++ linux/drivers/scsi/aacraid/osfuncs.c        Thu Dec 21 13:14:30 2000
13800 @@ -0,0 +1,596 @@
13801 +/*++
13802 + * Adaptec aacraid device driver for Linux.
13803 + *
13804 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
13805 + *
13806 + * This program is free software; you can redistribute it and/or modify
13807 + * it under the terms of the GNU General Public License as published by
13808 + * the Free Software Foundation; either version 2, or (at your option)
13809 + * any later version.
13810 + *
13811 + * This program is distributed in the hope that it will be useful,
13812 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
13813 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13814 + * GNU General Public License for more details.
13815 + *
13816 + * You should have received a copy of the GNU General Public License
13817 + * along with this program; see the file COPYING.  If not, write to
13818 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
13819 + *
13820 + * Module Name:
13821 + *  osfuncs.c
13822 + *
13823 + * Abstract: Holds all of the O/S specific interface functions.
13824 + *     
13825 + --*/
13826 +
13827 +static char *ident_osfuncs = "aacraid_ident osfuncs.c 1.0.6 2000/10/09 Adaptec, Inc.";
13828 +
13829 +#include "osheaders.h"
13830 +
13831 +//static LKINFO_DECL(fsa_locks, "fsa_locks",0);
13832 +
13833 +extern aac_options_t g_options;
13834 +
13835 +OS_SOFTINTR g_idle_task = { 0, 0, 0, 0 };
13836 +wait_queue_t * g_wait_queue_ptr = NULL;
13837 +wait_queue_t g_wait;
13838 +
13839 +void OsTimeoutHandler( 
13840 +       struct semaphore * sem );
13841 +
13842 +int * OsIdleTask( void * data );
13843 +
13844 +//-----------------------------------------------------------------------------
13845 +// Memory Allocation functions
13846 +
13847 +/*----------------------------------------------------------------------------*/
13848 +void * OsAllocMemory(
13849 +       OS_SIZE_T Size,
13850 +       unsigned int Flags )
13851 +/*----------------------------------------------------------------------------*/
13852 +{
13853 +       void *mem_ptr;
13854 +
13855 +       if( !( mem_ptr = kmalloc( Size, GFP_KERNEL ) ) )
13856 +               cmn_err( CE_WARN, "OsAllocMemory: FAILED\n" );
13857 +       return( mem_ptr );
13858 +}
13859 +
13860 +
13861 +/*----------------------------------------------------------------------------*/
13862 +void OsFreeMemory(
13863 +       void * Buffer,
13864 +       OS_SIZE_T Size )
13865 +/*----------------------------------------------------------------------------*/
13866 +{
13867 +       kfree( Buffer );
13868 +}
13869 +
13870 +
13871 +/*----------------------------------------------------------------------------*/
13872 +int OsRegisterInterrupt(
13873 +       unsigned int irq,               // interrupt number
13874 +       void ( *handler )( int, void*, struct pt_regs * ),      // handler function
13875 +       void *irq_data )                // argument to handler function
13876 +/*----------------------------------------------------------------------------*/
13877 +{
13878 +  return( request_irq (irq, handler, SA_INTERRUPT | SA_SHIRQ,  "aacraid", irq_data ) );
13879 +}
13880 +
13881 +
13882 +/*----------------------------------------------------------------------------*/
13883 +void OsUnregisterInterrupt(
13884 +       unsigned int irq,               // interrupt number
13885 +       void *irq_data)
13886 +/*----------------------------------------------------------------------------*/
13887 +{
13888 +       free_irq (
13889 +               irq,                                                                            // interrupt number
13890 +               irq_data );
13891 +}
13892 +
13893 +
13894 +/*----------------------------------------------------------------------------*/
13895 +unsigned long OsVirtToPhys( 
13896 +       void * virtual_address )
13897 +/*----------------------------------------------------------------------------*/
13898 +{
13899 +       return( virt_to_phys( virtual_address ) );
13900 +}
13901 +
13902 +
13903 +//-----------------------------------------------------------------------------
13904 +// MUTEX functions
13905 +
13906 +/*----------------------------------------------------------------------------*/
13907 +OS_STATUS OsMutexInit( 
13908 +       OS_MUTEX *Mutex,
13909 +       OS_SPINLOCK_COOKIE Cookie )
13910 +/*----------------------------------------------------------------------------*/
13911 +{
13912 +       Mutex->lock_var = 0;
13913 +       //      bzero (&Mutex->wq, sizeof (Mutex->wq));
13914 +       init_waitqueue_head (&Mutex->wq);
13915 +       return ( 0 );
13916 +}
13917 +
13918 +
13919 +/*----------------------------------------------------------------------------*/
13920 +void OsMutexDestroy( 
13921 +       OS_MUTEX *Mutex )
13922 +/*----------------------------------------------------------------------------*/
13923 +{
13924 +}
13925 +
13926 +
13927 +/*----------------------------------------------------------------------------*/
13928 +void OsMutexAcquire( 
13929 +       OS_MUTEX *Mutex )
13930 +/*----------------------------------------------------------------------------*/
13931 +{
13932 +  //   wait_queue_t wait = { current, NULL };
13933 +       unsigned long time_stamp;
13934 +
13935 +       DECLARE_WAITQUEUE (wait, current);
13936 +
13937 +       time_stamp = jiffies;
13938 +
13939 +       if( test_and_set_bit( 0, &( Mutex->lock_var ) ) != 0 )
13940 +       {
13941 +               if( in_interrupt() )
13942 +                       panic( "OsMutexAcquire going to sleep at interrupt time\n" );
13943 +               current->state = TASK_INTERRUPTIBLE;
13944 +               add_wait_queue( &( Mutex->wq ), &wait );
13945 +               while( test_and_set_bit( 0, &( Mutex->lock_var ) ) != 0 )
13946 +                       schedule();
13947 +               remove_wait_queue( &( Mutex->wq ), &wait );
13948 +       }
13949 +
13950 +       if( ( jiffies - 1 ) > time_stamp )
13951 +               cmn_err( CE_WARN, "Mutex %ld locked out for %ld ticks", 
13952 +                       Mutex, jiffies - time_stamp );
13953 +}
13954 +
13955 +
13956 +/*----------------------------------------------------------------------------*/
13957 +void OsMutexRelease( 
13958 +       OS_MUTEX *Mutex )
13959 +/*----------------------------------------------------------------------------*/
13960 +{
13961 +       if( test_and_clear_bit( 0, &( Mutex->lock_var ) ) == 0 )
13962 +               cmn_err( CE_WARN, "OsMutexRelease: mutex not locked" );
13963 +       wake_up_interruptible( &( Mutex->wq ) );
13964 +}
13965 +
13966 +// see man hierarchy(D5)
13967 +#define FSA_LOCK 1
13968 +
13969 +//-----------------------------------------------------------------------------
13970 +// Spinlock functions
13971 +
13972 +/*----------------------------------------------------------------------------*/
13973 +OS_SPINLOCK * OsSpinLockAlloc( void ) 
13974 +/*----------------------------------------------------------------------------*/
13975 +{
13976 +       OS_SPINLOCK *SpinLock;
13977 +       int i;
13978 +
13979 +
13980 +       SpinLock = ( OS_SPINLOCK * )kmalloc( sizeof( OS_SPINLOCK ), GFP_KERNEL );
13981 +
13982 +       if (SpinLock == NULL)
13983 +               cmn_err (CE_WARN, "WARNING: OsSpinLockAlloc Failed!!!");
13984 +       
13985 +       SpinLock->spin_lock = SPIN_LOCK_UNLOCKED;
13986 +       for( i = 0; i < NR_CPUS; i++ )
13987 +               SpinLock->cpu_lock_count[ i ] = 0;
13988 +       return( SpinLock );
13989 +}
13990 +
13991 +
13992 +/*----------------------------------------------------------------------------*/
13993 +OS_STATUS OsSpinLockInit( 
13994 +       OS_SPINLOCK *SpinLock,
13995 +       OS_SPINLOCK_COOKIE Cookie )
13996 +/*----------------------------------------------------------------------------*/
13997 +{
13998 +       return( 0 );
13999 +}
14000 +
14001 +
14002 +/*----------------------------------------------------------------------------*/
14003 +void OsSpinLockDestroy( 
14004 +       OS_SPINLOCK *SpinLock )
14005 +/*----------------------------------------------------------------------------*/
14006 +{
14007 +       kfree( SpinLock );
14008 +       SpinLock = NULL;
14009 +}
14010 +
14011 +
14012 +/*----------------------------------------------------------------------------*/
14013 +void OsSpinLockAcquire( 
14014 +       OS_SPINLOCK *SpinLock )
14015 +/*----------------------------------------------------------------------------*/
14016 +{
14017 +       unsigned cpu_id, i;
14018 +
14019 +
14020 +       if( SpinLock )
14021 +       {
14022 +               cpu_id = smp_processor_id();
14023 +               if( SpinLock->cpu_lock_count[ cpu_id ] ){
14024 +                       cmn_err (CE_PANIC, "CPU %d trying to acquire lock again: lock count = %d\n",
14025 +                                cpu_id, SpinLock->cpu_lock_count[ cpu_id ]);
14026 +               }                 
14027 +               
14028 +               spin_lock_irqsave( &( SpinLock->spin_lock ), SpinLock->cpu_flag );
14029 +               SpinLock->cpu_lock_count[ cpu_id ]++;
14030 +          
14031 +       } else {
14032 +               cmn_err( CE_WARN, "OsSpinLockAcquire: lock does not exist" );
14033 +       }
14034 +}
14035 +
14036 +
14037 +/*----------------------------------------------------------------------------*/
14038 +void OsSpinLockRelease( 
14039 +       OS_SPINLOCK *SpinLock )
14040 +/*----------------------------------------------------------------------------*/
14041 +{
14042 +       if( SpinLock )
14043 +       {
14044 +               SpinLock->cpu_lock_count[ smp_processor_id() ]--;
14045 +               spin_unlock_irqrestore( &( SpinLock->spin_lock ), SpinLock->cpu_flag );
14046 +       }
14047 +       else
14048 +               cmn_err( CE_WARN, "OsSpinLockRelease: lock does not exist" );
14049 +}
14050 +
14051 +
14052 +/*----------------------------------------------------------------------------*/
14053 +int OsSpinLockOwned(
14054 +       OS_SPINLOCK *SpinLock )
14055 +/*----------------------------------------------------------------------------*/
14056 +{
14057 +#ifdef __SMP__
14058 +       if( SpinLock->spin_lock.lock != 0 )
14059 +               return( 1 );
14060 +       else
14061 +#endif
14062 +               return( 0 );
14063 +}
14064 +
14065 +
14066 +//-----------------------------------------------------------------------------
14067 +// CvLock functions
14068 +
14069 +/*----------------------------------------------------------------------------*/
14070 +OS_CVLOCK *OsCvLockAlloc( void ) 
14071 +{
14072 +       OS_CVLOCK *cv_lock;
14073 +
14074 +
14075 +#ifdef CVLOCK_USE_SPINLOCK
14076 +       cv_lock = OsSpinLockAlloc(); 
14077 +#else
14078 +       cv_lock = ( OS_CVLOCK * )kmalloc( sizeof( OS_CVLOCK ), GFP_KERNEL );
14079 +       cv_lock->wq = NULL;
14080 +       cv_lock->lock_var = 0;
14081 +#endif
14082 +
14083 +       return( cv_lock );
14084 +}
14085 +
14086 +
14087 +/*----------------------------------------------------------------------------*/
14088 +OS_STATUS OsCvLockInit( 
14089 +       OS_CVLOCK *cv_lock,
14090 +       OS_SPINLOCK_COOKIE Cookie )
14091 +/*----------------------------------------------------------------------------*/
14092 +{
14093 +       return ( 0 );
14094 +}
14095 +
14096 +
14097 +/*----------------------------------------------------------------------------*/
14098 +void OsCvLockDestroy( 
14099 +       OS_CVLOCK *cv_lock )
14100 +/*----------------------------------------------------------------------------*/
14101 +{
14102 +       if( cv_lock )
14103 +               kfree( cv_lock );
14104 +       cv_lock = NULL;
14105 +}
14106 +
14107 +
14108 +/*----------------------------------------------------------------------------*/
14109 +void OsCvLockAcquire (OS_CVLOCK *cv_lock)
14110 +{
14111 +#ifdef CVLOCK_USE_SPINLOCK
14112 +               OsSpinLockAcquire( cv_lock );
14113 +#else
14114 +               OsMutexAcquire( cv_lock );
14115 +#endif
14116 +}
14117 +
14118 +
14119 +/*----------------------------------------------------------------------------*/
14120 +void OsCvLockRelease( 
14121 +       OS_CVLOCK *cv_lock )
14122 +/*----------------------------------------------------------------------------*/
14123 +{
14124 +#ifdef CVLOCK_USE_SPINLOCK
14125 +               OsSpinLockRelease( cv_lock );
14126 +#else
14127 +               OsMutexRelease( cv_lock );
14128 +#endif
14129 +}
14130 +
14131 +
14132 +/*----------------------------------------------------------------------------*/
14133 +int OsCvLockOwned(
14134 +       OS_CVLOCK *cv_lock )
14135 +/*----------------------------------------------------------------------------*/
14136 +{
14137 +       return( 1 );
14138 +}
14139 +
14140 +
14141 +//-----------------------------------------------------------------------------
14142 +// Conditional variable functions
14143 +
14144 +/*----------------------------------------------------------------------------*/
14145 +void OsCv_init ( 
14146 +       OS_CV_T *cv_ptr )
14147 +/*----------------------------------------------------------------------------*/
14148 +{
14149 +       cv_ptr->lock_var = 1;
14150 +       init_waitqueue_head (&cv_ptr->wq);
14151 +}
14152 +
14153 +
14154 +/*----------------------------------------------------------------------------*/
14155 +void OsCv_destroy( 
14156 +       OS_CV_T  *cv_ptr )
14157 +/*----------------------------------------------------------------------------*/
14158 +{
14159 +}
14160 +
14161 +
14162 +/*______________________________________________________________________________
14163 + -
14164 + -
14165 + -----------------------------------------------------------------------------*/
14166 +OsCv_wait (OS_CV_T *cv_ptr, OS_CVLOCK *cv_lock_ptr)
14167 +{
14168 +       unsigned long flags;
14169 +
14170 +       DECLARE_WAITQUEUE (wait, current);
14171 +       
14172 +       if( in_interrupt() )
14173 +               panic( "OsCv_wait going to sleep at interrupt time\n" );
14174 +
14175 +       cv_ptr->type = TASK_UNINTERRUPTIBLE;
14176 +       current->state = TASK_UNINTERRUPTIBLE;
14177 +
14178 +       add_wait_queue( &cv_ptr->wq, &wait );
14179 +
14180 +       OsCvLockRelease( cv_lock_ptr );
14181 +       schedule();
14182 +
14183 +       while( test_and_set_bit( 0, &( cv_ptr->lock_var ) ) != 0 )
14184 +       {
14185 +               if( in_interrupt() )
14186 +                       panic( "OsCv_wait going to sleep at interrupt time\n" );
14187 +               schedule();
14188 +       }
14189 +
14190 +       remove_wait_queue( &( cv_ptr->wq ), &wait );
14191 +
14192 +       OsCvLockAcquire( cv_lock_ptr );
14193 +}
14194 +
14195 +
14196 +/*----------------------------------------------------------------------------*/
14197 +int OsCv_wait_sig( 
14198 +       OS_CV_T *cv_ptr,
14199 +       OS_CVLOCK *cv_lock_ptr ) 
14200 +/*----------------------------------------------------------------------------*/
14201 +{
14202 +       unsigned long flags;
14203 +       int signal_state = 1;
14204 +
14205 +       DECLARE_WAITQUEUE (wait, current);
14206 +       
14207 +       if( in_interrupt() )
14208 +               panic( "OsCv_wait_sig going to sleep at interrupt time\n" );
14209 +
14210 +       cv_ptr->type = TASK_INTERRUPTIBLE;
14211 +       current->state = TASK_INTERRUPTIBLE;
14212 +
14213 +       add_wait_queue( &( cv_ptr->wq ), &wait );
14214 +
14215 +       OsCvLockRelease( cv_lock_ptr );
14216 +       schedule();
14217 +
14218 +       while( ( test_and_set_bit( 0, &( cv_ptr->lock_var ) ) != 0 ) && 
14219 +                       ( !signal_pending( current ) ) )
14220 +       {
14221 +               if( in_interrupt() )
14222 +                       panic( "OsCv_wait_sig going to sleep at interrupt time\n" );
14223 +               schedule();
14224 +       }
14225 +
14226 +       if( signal_pending( current ) )
14227 +               signal_state = 0;
14228 +       
14229 +       remove_wait_queue( &( cv_ptr->wq ), &wait );
14230 +       
14231 +       OsCvLockAcquire( cv_lock_ptr );
14232 +       return( signal_state );
14233 +}
14234 +
14235 +
14236 +/*----------------------------------------------------------------------------*/
14237 +void OsCv_signal( 
14238 +       OS_CV_T *cv_ptr )
14239 +/*----------------------------------------------------------------------------*/
14240 +{
14241 +
14242 +       clear_bit( 0, &( cv_ptr->lock_var ) );
14243 +       if( cv_ptr->type == TASK_INTERRUPTIBLE )
14244 +                       wake_up_interruptible( &( cv_ptr->wq ) );
14245 +       else{
14246 +                       wake_up( &( cv_ptr->wq ) );
14247 +       }
14248 +}
14249 +
14250 +
14251 +// return time in seconds
14252 +/*----------------------------------------------------------------------------*/
14253 +unsigned long OsGetSeconds( void )
14254 +/*----------------------------------------------------------------------------*/
14255 +{
14256 +       return( jiffies/HZ );
14257 +}
14258 +
14259 +
14260 +//-----------------------------------------------------------------------------
14261 +// Deferred procedure call functions
14262 +
14263 +// create a soft interrupt object
14264 +/*----------------------------------------------------------------------------*/
14265 +int OsSoftInterruptAdd( 
14266 +       OS_SOFTINTR **ptr,
14267 +       void * handler,
14268 +       void * data )
14269 +/*----------------------------------------------------------------------------*/
14270 +{
14271 +       OS_SOFTINTR *tmp_ptr;
14272 +
14273 +       if( !( tmp_ptr = ( OS_SOFTINTR * )kmalloc( sizeof( OS_SOFTINTR ), GFP_KERNEL ) ) )
14274 +               return( -1 );
14275 +       tmp_ptr->routine = handler;
14276 +       tmp_ptr->data = data;
14277 +       tmp_ptr->sync = 0;
14278 +
14279 +       *ptr = tmp_ptr; 
14280 +
14281 +       return( 0 );
14282 +}
14283 +
14284 +/*
14285 +       Use kernel_thread( ( int ( * )( void * ) )OsIdleTask, NULL, 0 ); to start
14286 +*/
14287 +/*----------------------------------------------------------------------------*/
14288 +int * OsIdleTask( void * data )
14289 +/*----------------------------------------------------------------------------*/
14290 +{
14291 +       DECLARE_WAITQUEUE (wait, current);
14292 +
14293 +       while( 1 )
14294 +       {
14295 +               current->state = TASK_INTERRUPTIBLE;
14296 +               add_wait_queue( &g_wait_queue_ptr, &wait );
14297 +               schedule();
14298 +               remove_wait_queue( &g_wait_queue_ptr, &wait );
14299 +               wait.task =  current;
14300 +               wait.task_list.next = NULL;
14301 +       }
14302 +       return( NULL );
14303 +}
14304 +
14305 +
14306 +// dispatch a soft interrupt 
14307 +/*----------------------------------------------------------------------------*/
14308 +void OsSoftInterruptTrigger( 
14309 +       OS_SOFTINTR *soft_intr_ptr )
14310 +/*----------------------------------------------------------------------------*/
14311 +{
14312 +       // call the completion routine directly
14313 +       soft_intr_ptr->routine( soft_intr_ptr->data );
14314 +}
14315 +
14316 +
14317 +// delete a soft interrupt object
14318 +/*----------------------------------------------------------------------------*/
14319 +void OsSoftInterruptRemove( 
14320 +       OS_SOFTINTR *arg )
14321 +/*----------------------------------------------------------------------------*/
14322 +{
14323 +       if( arg )
14324 +               kfree( arg );
14325 +       arg = NULL;
14326 +}
14327 +
14328 +
14329 +/*----------------------------------------------------------------------------*/
14330 +void OsSleep( 
14331 +       unsigned time )         // in seconds
14332 +/*----------------------------------------------------------------------------*/
14333 +{
14334 +       struct semaphore sem;
14335 +       struct timer_list timer_var;
14336 +       
14337 +       init_MUTEX_LOCKED (&sem);
14338 +
14339 +       //      if( in_interrupt() )
14340 +       //              panic( "OsSleep going to sleep at interrupt time\n" );
14341 +
14342 +       init_timer( &timer_var );
14343 +       timer_var.function = ( void ( * )( unsigned long ) )OsTimeoutHandler;
14344 +       timer_var.data = ( unsigned long )&sem;
14345 +       timer_var.expires = jiffies + time * HZ;
14346 +
14347 +       add_timer( &timer_var );
14348 +       down( &sem );
14349 +
14350 +       del_timer( &timer_var );
14351 +}
14352 +
14353 +
14354 +/*----------------------------------------------------------------------------*/
14355 +void OsTimeoutHandler( 
14356 +       struct semaphore * sem )
14357 +/*----------------------------------------------------------------------------*/
14358 +{
14359 +       if( sem != NULL )
14360 +               up( sem );
14361 +}
14362 +
14363 +
14364 +/*----------------------------------------------------------------------------*/
14365 +void printk_err(
14366 +       int flag, 
14367 +       char *fmt, 
14368 +       ...)
14369 +/*----------------------------------------------------------------------------*/
14370 +{
14371 +       char    buf[256];
14372 +       va_list ap;
14373 +
14374 +       va_start(ap, fmt);
14375 +       (void) vsprintf(buf, fmt, ap);
14376 +       va_end(ap);
14377 +       
14378 +       if( flag <= g_options.message_level )
14379 +               printk("<1>%s\n", buf);
14380 +}
14381 +
14382 +/*  void aac_show_tasks (struct list_head *our_tasks){ */
14383
14384 +/*             cmn_err (CE_DEBUG, "Entering aac_show_tasks"); */
14385 +
14386 +/*             if (our_tasks->next == NULL || our_tasks->next == 0) */
14387 +/*                             cmn_err (CE_DEBUG, "list_head->next is NULL or 0"); */
14388 +/*             else */
14389 +/*                             cmn_err (CE_DEBUG, "list_head->next: 0x%x", our_tasks->next); */
14390 +
14391 +/*             if (our_tasks->prev == NULL || our_tasks->prev == 0) */
14392 +/*                             cmn_err (CE_DEBUG, "list_head->prev is NULL or 0"); */
14393 +/*             else */
14394 +/*                             cmn_err (CE_DEBUG, "list_head->prev: 0x%x", our_tasks->prev); */
14395 +
14396 +/*  } */
14397 diff -urN linux/drivers/scsi/aacraid/ossup.c linux/drivers/scsi/aacraid/ossup.c
14398 --- linux/drivers/scsi/aacraid/ossup.c  Wed Dec 31 19:00:00 1969
14399 +++ linux/drivers/scsi/aacraid/ossup.c  Thu Dec 21 13:14:30 2000
14400 @@ -0,0 +1,199 @@
14401 +/*++
14402 + * Adaptec aacraid device driver for Linux.
14403 + *
14404 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
14405 + *
14406 + * This program is free software; you can redistribute it and/or modify
14407 + * it under the terms of the GNU General Public License as published by
14408 + * the Free Software Foundation; either version 2, or (at your option)
14409 + * any later version.
14410 + *
14411 + * This program is distributed in the hope that it will be useful,
14412 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
14413 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14414 + * GNU General Public License for more details.
14415 + *
14416 + * You should have received a copy of the GNU General Public License
14417 + * along with this program; see the file COPYING.  If not, write to
14418 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
14419 + *
14420 + * Module Name:
14421 + *  ossup.c
14422 + *
14423 + * 
14424 + *
14425 + --*/
14426 +
14427 +static char *ident_ossup = "aacraid_ident ossup.c 1.0.6 2000/10/09 Adaptec, Inc.";
14428 +
14429 +#include "osheaders.h"
14430 +
14431 +#include "aac_unix_defs.h"
14432 +
14433 +
14434 +AAC_STATUS
14435 +ExInitializeZone(
14436 +    IN PZONE_HEADER Zone,
14437 +    IN ULONG BlockSize,
14438 +    IN PVOID InitialSegment,
14439 +    IN ULONG InitialSegmentSize
14440 +    )
14441 +
14442 +/*++
14443 +
14444 +Routine Description:
14445 +
14446 +    This function initializes a zone header.  Once successfully
14447 +    initialized, blocks can be allocated and freed from the zone, and
14448 +    the zone can be extended.
14449 +
14450 +Arguments:
14451 +
14452 +    Zone - Supplies the address of a zone header to be initialized.
14453 +
14454 +    BlockSize - Supplies the block size of the allocatable unit within
14455 +                the zone.  The size must be larger that the size of the
14456 +                initial segment, and must be 64-bit aligned.
14457 +
14458 +    InitialSegment - Supplies the address of a segment of storage.  The
14459 +                     first ZONE_SEGMENT_HEADER-sized portion of the segment
14460 +                     is used by the zone allocator.  The remainder of
14461 +                     the segment is carved up into fixed size
14462 +                     (BlockSize) blocks and is made available for
14463 +                     allocation and deallocation from the zone.  The
14464 +                     address of the segment must be aligned on a 64-bit
14465 +                     boundary.
14466 +
14467 +    InitialSegmentSize - Supplies the size in bytes of the InitialSegment.
14468 +
14469 +Return Value:
14470 +
14471 +    STATUS_UNSUCCESSFUL - BlockSize or InitialSegment was not aligned on
14472 +                          64-bit boundaries, or BlockSize was larger than
14473 +                          the initial segment size.
14474 +
14475 +    STATUS_SUCCESS - The zone was successfully initialized.
14476 +
14477 +--*/
14478 +
14479 +{
14480 +    ULONG i;
14481 +    PCHAR p;
14482 +
14483 +
14484 +    Zone->BlockSize = BlockSize;
14485 +
14486 +    Zone->SegmentList.Next = &((PZONE_SEGMENT_HEADER) InitialSegment)->SegmentList;
14487 +    ((PZONE_SEGMENT_HEADER) InitialSegment)->SegmentList.Next = NULL;
14488 +    ((PZONE_SEGMENT_HEADER) InitialSegment)->Reserved = NULL;
14489 +
14490 +    Zone->FreeList.Next = NULL;
14491 +
14492 +    p = (PCHAR)InitialSegment + sizeof(ZONE_SEGMENT_HEADER);
14493 +
14494 +    for (i = sizeof(ZONE_SEGMENT_HEADER);
14495 +         i <= InitialSegmentSize - BlockSize;
14496 +         i += BlockSize
14497 +        ) {
14498 +        ((PSINGLE_LIST_ENTRY)p)->Next = Zone->FreeList.Next;
14499 +        Zone->FreeList.Next = (PSINGLE_LIST_ENTRY)p;
14500 +        p += BlockSize;
14501 +    }
14502 +    Zone->TotalSegmentSize = i;
14503 +
14504 +#if 0
14505 +    DbgPrint( "EX: ExInitializeZone( %lx, %lx, %lu, %lu, %lx )\n",
14506 +              Zone, InitialSegment, InitialSegmentSize,
14507 +              BlockSize, p
14508 +            );
14509 +#endif
14510 +
14511 +    return STATUS_SUCCESS;
14512 +}
14513 +
14514 +AAC_STATUS
14515 +ExExtendZone(
14516 +    IN PZONE_HEADER Zone,
14517 +    IN PVOID Segment,
14518 +    IN ULONG SegmentSize
14519 +    )
14520 +
14521 +/*++
14522 +
14523 +Routine Description:
14524 +
14525 +    This function extends a zone by adding another segment's worth of
14526 +    blocks to the zone.
14527 +
14528 +Arguments:
14529 +
14530 +    Zone - Supplies the address of a zone header to be extended.
14531 +
14532 +    Segment - Supplies the address of a segment of storage.  The first
14533 +              ZONE_SEGMENT_HEADER-sized portion of the segment is used by the
14534 +              zone allocator.  The remainder of the segment is carved up
14535 +              into fixed-size (BlockSize) blocks and is added to the
14536 +              zone.  The address of the segment must be aligned on a 64-
14537 +              bit boundary.
14538 +
14539 +    SegmentSize - Supplies the size in bytes of Segment.
14540 +
14541 +Return Value:
14542 +
14543 +    STATUS_UNSUCCESSFUL - BlockSize or Segment was not aligned on
14544 +                          64-bit boundaries, or BlockSize was larger than
14545 +                          the segment size.
14546 +
14547 +    STATUS_SUCCESS - The zone was successfully extended.
14548 +
14549 +--*/
14550 +
14551 +{
14552 +    ULONG i;
14553 +    PCHAR p;
14554 +
14555 +
14556 +    ((PZONE_SEGMENT_HEADER) Segment)->SegmentList.Next = Zone->SegmentList.Next;
14557 +    Zone->SegmentList.Next = &((PZONE_SEGMENT_HEADER) Segment)->SegmentList;
14558 +
14559 +    p = (PCHAR)Segment + sizeof(ZONE_SEGMENT_HEADER);
14560 +
14561 +    for (i = sizeof(ZONE_SEGMENT_HEADER);
14562 +         i <= SegmentSize - Zone->BlockSize;
14563 +         i += Zone->BlockSize
14564 +        ) {
14565 +
14566 +        ((PSINGLE_LIST_ENTRY)p)->Next = Zone->FreeList.Next;
14567 +        Zone->FreeList.Next = (PSINGLE_LIST_ENTRY)p;
14568 +        p += Zone->BlockSize;
14569 +    }
14570 +    Zone->TotalSegmentSize += i;
14571 +
14572 +#if 0
14573 +    DbgPrint( "EX: ExExtendZone( %lx, %lx, %lu, %lu, %lx )\n",
14574 +              Zone, Segment, SegmentSize, Zone->BlockSize, p
14575 +            );
14576 +#endif
14577 +
14578 +    return STATUS_SUCCESS;
14579 +}
14580 +
14581 +DbgPrint()
14582 +{
14583 +}
14584 +
14585 +/* Function: InqStrCopy()
14586 + *
14587 + * Arguments: [2] pointer to char
14588 + *
14589 + * Purpose: Copy a String from one location to another
14590 + * without copying \0
14591 + */
14592 +void
14593 +InqStrCopy(char *a, char *b)
14594 +{
14595 +
14596 +       while(*a != (char)0) 
14597 +               *b++ = *a++;
14598 +}
14599 +
14600 diff -urN linux/drivers/scsi/aacraid/port.c linux/drivers/scsi/aacraid/port.c
14601 --- linux/drivers/scsi/aacraid/port.c   Wed Dec 31 19:00:00 1969
14602 +++ linux/drivers/scsi/aacraid/port.c   Thu Dec 21 13:14:30 2000
14603 @@ -0,0 +1,287 @@
14604 +/*++
14605 + * Adaptec aacraid device driver for Linux.
14606 + *
14607 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
14608 + *
14609 + * This program is free software; you can redistribute it and/or modify
14610 + * it under the terms of the GNU General Public License as published by
14611 + * the Free Software Foundation; either version 2, or (at your option)
14612 + * any later version.
14613 + *
14614 + * This program is distributed in the hope that it will be useful,
14615 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
14616 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14617 + * GNU General Public License for more details.
14618 + *
14619 + * You should have received a copy of the GNU General Public License
14620 + * along with this program; see the file COPYING.  If not, write to
14621 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
14622 + *
14623 + * Module Name:
14624 + *  port.c
14625 + *
14626 + * Abstract: All support routines for FSA communication which are miniport specific.
14627 + *
14628 + --*/
14629 +
14630 +static char *ident_port = "aacraid_ident port.c 1.0.7 2000/10/11 Adaptec, Inc.";
14631 +
14632 +#include "osheaders.h"
14633 +
14634 +
14635 +#include "AacGenericTypes.h"
14636 +
14637 +#include "aac_unix_defs.h"
14638 +
14639 +#include "fsatypes.h"
14640 +#include "comstruc.h"
14641 +#include "protocol.h"
14642 +
14643 +#include "fsaport.h"
14644 +#include "fsaioctl.h"
14645 +
14646 +#include "pcisup.h"
14647 +#include "port.h"
14648 +
14649 +int AfaPortPrinting = 1;
14650 +
14651 +extern AAC_STATUS AfaPort_Err_Adapter_Printf;
14652 +extern AAC_STATUS AfaPort_Warn_Adapter_Printf;
14653 +extern AAC_STATUS AfaPort_Info_Adapter_Printf;
14654 +extern AAC_STATUS AfaPort_Err_FastAfa_Load_Driver;
14655 +
14656 +
14657 +
14658 +VOID
14659 +AfaPortLogError(
14660 +       IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
14661 +       IN AAC_STATUS ErrorCode,
14662 +       IN PUCHAR StringBuffer,
14663 +       IN ULONG StringLength
14664 +       )
14665 +/*++
14666 +
14667 +Routine Description:
14668 +
14669 +       Does all of the work to log an error log entry
14670 +Arguments:
14671 +
14672 +       CommonExtension - Pointer to the adapter that caused the error.
14673 +
14674 +       ErrorCode - Which error is being logged.
14675 +
14676 +       StringBuffer - Pointer to optional String for error log entry.
14677 +
14678 +       StringLength - Length of StringBuffer.
14679 +
14680 +Return Value:
14681 +
14682 +    Nothing
14683 +
14684 +--*/
14685 +
14686 +{
14687 +
14688 +}
14689 +
14690 +BOOLEAN
14691 +AfaPortGetNextAdapterNumber(
14692 +    IN  PDRIVER_OBJECT  DriverObject,
14693 +       OUT PDEVICE_OBJECT      *FsaDeviceObject,
14694 +       OUT PFILE_OBJECT        *FileObject,
14695 +       OUT PULONG                      AdapterNumber
14696 +       )
14697 +{
14698 +}
14699 +BOOLEAN
14700 +AfaPortAllocateAdapterCommArea(
14701 +       IN PVOID                Arg1,
14702 +       IN OUT PVOID    *CommHeaderAddress,
14703 +       IN ULONG                CommAreaSize,
14704 +       IN ULONG                CommAreaAlignment
14705 +       )
14706 +{
14707 +       PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
14708 +       PVOID BaseAddress;
14709 +       PHYSICAL_ADDRESS PhysicalBaseAddress;
14710 +       ULONG TotalSize, BytesToAlign;
14711 +       size_t          RealLength;
14712 +       uint_t          Count;
14713 +//     ULONG SizeOfFastIoComm = sizeof(FASTIO_STRUCT);
14714 +//     ULONG AdapterFibsSize = PAGE_SIZE;
14715 +       ULONG AdapterFibsSize = 4096;
14716 +       ULONG PrintfBufferSize = 256;
14717 +       PADAPTER_INIT_STRUCT InitStruct;
14718 +       extern int MiniPortRevision;
14719 +       ULONG   PhysAddress;
14720 +
14721 +//     TotalSize = AdapterFibsSize + sizeof(ADAPTER_INIT_STRUCT) + CommAreaSize + CommAreaAlignment +
14722 +//              SizeOfFastIoComm + PrintfBufferSize;
14723 +       TotalSize = AdapterFibsSize + sizeof(ADAPTER_INIT_STRUCT) + CommAreaSize + CommAreaAlignment +
14724 +                PrintfBufferSize;
14725 +
14726 +
14727 +       OsAllocCommPhysMem(CommonExtension->MiniPort, TotalSize, &BaseAddress, &PhysAddress);
14728 +
14729 +       CommonExtension->CommAddress  = BaseAddress;
14730 +       CommonExtension->CommPhysAddr = PhysAddress;
14731 +       CommonExtension->CommSize         = TotalSize;
14732 +
14733 +       PhysicalBaseAddress.HighPart = 0;
14734 +       PhysicalBaseAddress.LowPart = PhysAddress;
14735 +
14736 +       CommonExtension->InitStruct = (PADAPTER_INIT_STRUCT)((PUCHAR)(BaseAddress) + AdapterFibsSize);
14737 +       CommonExtension->PhysicalInitStruct = (PADAPTER_INIT_STRUCT)((PUCHAR)(PhysicalBaseAddress.LowPart) + AdapterFibsSize);
14738 +
14739 +       InitStruct = CommonExtension->InitStruct;
14740 +
14741 +       InitStruct->InitStructRevision = ADAPTER_INIT_STRUCT_REVISION;
14742 +       InitStruct->MiniPortRevision = MiniPortRevision;
14743 +       InitStruct->FilesystemRevision = CommonExtension->FilesystemRevision;
14744 +
14745 +       //
14746 +       // Adapter Fibs are the first thing allocated so that they start page aligned
14747 +       //
14748 +       InitStruct->AdapterFibsVirtualAddress = BaseAddress;
14749 +       InitStruct->AdapterFibsPhysicalAddress = (PVOID) PhysicalBaseAddress.LowPart;
14750 +       InitStruct->AdapterFibsSize = AdapterFibsSize;
14751 +       InitStruct->AdapterFibAlign = sizeof(FIB);
14752 +
14753 +       //
14754 +       // Increment the base address by the amount already used
14755 +       //
14756 +       BaseAddress = (PVOID)((PUCHAR)(BaseAddress) + AdapterFibsSize + sizeof(ADAPTER_INIT_STRUCT));
14757 +       PhysicalBaseAddress.LowPart = (ULONG)((PUCHAR)(PhysicalBaseAddress.LowPart) + AdapterFibsSize + sizeof(ADAPTER_INIT_STRUCT));
14758 +
14759 +       //
14760 +       // Align the beginning of Headers to CommAreaAlignment
14761 +       //
14762 +       BytesToAlign = (CommAreaAlignment - ((ULONG)(BaseAddress) & (CommAreaAlignment - 1)));
14763 +       BaseAddress = (PVOID)((PUCHAR)(BaseAddress) + BytesToAlign);
14764 +       PhysicalBaseAddress.LowPart = (ULONG)((PUCHAR)(PhysicalBaseAddress.LowPart) + BytesToAlign);
14765 +
14766 +       //
14767 +       // Fill in addresses of the Comm Area Headers and Queues
14768 +       //
14769 +       *CommHeaderAddress = BaseAddress;
14770 +       InitStruct->CommHeaderAddress = (PVOID)PhysicalBaseAddress.LowPart;
14771 +
14772 +       //
14773 +       //      Increment the base address by the size of the CommArea
14774 +       //
14775 +       BaseAddress = (PVOID)((PUCHAR)(BaseAddress) + CommAreaSize);
14776 +       PhysicalBaseAddress.LowPart = (ULONG)((PUCHAR)(PhysicalBaseAddress.LowPart) + CommAreaSize);
14777 +
14778 +
14779 +       //
14780 +       // Place the Printf buffer area after the Fast I/O comm area.
14781 +       //
14782 +       CommonExtension->PrintfBufferAddress = (PVOID)(BaseAddress);
14783 +       InitStruct->PrintfBufferAddress = (PVOID)PhysicalBaseAddress.LowPart;
14784 +       InitStruct->PrintfBufferSize = PrintfBufferSize;
14785 +       bzero (BaseAddress, PrintfBufferSize);
14786 +
14787 +       AfaPortPrint("FsaAllocateAdapterCommArea: allocated a common buffer of 0x%x bytes from address 0x%x to address 0x%x\n",
14788 +                        TotalSize, InitStruct->AdapterFibsVirtualAddress,
14789 +                        (PUCHAR)(InitStruct->AdapterFibsVirtualAddress) + TotalSize);
14790 +
14791 +       AfaPortPrint("Mapped on to PCI address 0x%x\n", InitStruct->AdapterFibsPhysicalAddress);
14792 +
14793 +       return (TRUE);
14794 +}
14795 +
14796 +AAC_STATUS
14797 +AfaPortCreate (
14798 +    IN PDEVICE_OBJECT DeviceObject,
14799 +    IN PIRP Irp
14800 +    )
14801 +/*++
14802 +
14803 +Routine Description:
14804 +
14805 +       The routine will get called each time a user issues a CreateFile on the DeviceObject
14806 +       for the adapter.
14807 +
14808 +       The main purpose of this routine is to set up any data structures that may be needed
14809 +       to handle any requests made on this DeviceObject.
14810 +
14811 +Arguments:
14812 +
14813 +       DeviceObject - Pointer to device object representing adapter
14814 +
14815 +       Irp - Pointer to Irp that caused this open
14816 +
14817 +
14818 +Return Value:
14819 +
14820 +       Status value returned from File system driver AdapterOpen
14821 +
14822 +--*/
14823 +
14824 +{
14825 +}
14826 +
14827 +AAC_STATUS
14828 +AfaPortClose (
14829 +    IN PDEVICE_OBJECT DeviceObject,
14830 +    IN PIRP Irp
14831 +    )
14832 +/*++
14833 +
14834 +Routine Description:
14835 +
14836 +       This routine will get called each time a user issues a CloseHandle on the DeviceObject
14837 +       for the adapter.
14838 +
14839 +       The main purpose of this routine is to cleanup any data structures that have been set up
14840 +       while this FileObject has been opened.
14841 +
14842 +Arguments:
14843 +
14844 +       DeviceObject - Pointer to device object representing adapter
14845 +
14846 +       Irp - Pointer to Irp that caused this close
14847 +
14848 +Return Value:
14849 +
14850 +       Status value returned from File system driver AdapterClose
14851 +
14852 +--*/
14853 +
14854 +{
14855 +
14856 +}
14857 +
14858 +AAC_STATUS
14859 +AfaPortDeviceControl (
14860 +    IN PDEVICE_OBJECT DeviceObject,
14861 +    IN PIRP Irp
14862 +    )
14863 +{
14864 +
14865 +}
14866 +
14867 +ULONG
14868 +AfaPortGetMaxPhysicalPage(
14869 +       IN PPCI_MINIPORT_COMMON_EXTENSION       CommonExtension
14870 +       )
14871 +/*++
14872 +
14873 +Routine Description:
14874 +
14875 +       This routine determines the max physical page in host memory.
14876 +
14877 +Arguments:
14878 +
14879 +       AdapterExtension
14880 +
14881 +Return Value:
14882 +
14883 +       Max physical page in host memory.
14884 +
14885 +--*/
14886 +{
14887 +
14888 +}
14889 +
14890 +
14891 diff -urN linux/drivers/scsi/aacraid/rx.c linux/drivers/scsi/aacraid/rx.c
14892 --- linux/drivers/scsi/aacraid/rx.c     Wed Dec 31 19:00:00 1969
14893 +++ linux/drivers/scsi/aacraid/rx.c     Thu Dec 21 13:14:30 2000
14894 @@ -0,0 +1,917 @@
14895 +/*++
14896 + * Adaptec aacraid device driver for Linux.
14897 + *
14898 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
14899 + *
14900 + * This program is free software; you can redistribute it and/or modify
14901 + * it under the terms of the GNU General Public License as published by
14902 + * the Free Software Foundation; either version 2, or (at your option)
14903 + * any later version.
14904 + *
14905 + * This program is distributed in the hope that it will be useful,
14906 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
14907 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14908 + * GNU General Public License for more details.
14909 + *
14910 + * You should have received a copy of the GNU General Public License
14911 + * along with this program; see the file COPYING.  If not, write to
14912 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
14913 + *
14914 + * Module Name:
14915 + *  rx.c
14916 + *
14917 + * Abstract: Hardware miniport for Drawbridge specific hardware functions.
14918 + *
14919 + --*/
14920 +
14921 +static char *ident_rx = "aacraid_ident rx.c 1.0.7 2000/10/11 Adaptec, Inc.";
14922 +
14923 +#include "osheaders.h"
14924 +
14925 +
14926 +#include "AacGenericTypes.h"
14927 +
14928 +#include "aac_unix_defs.h"
14929 +
14930 +#include "fsatypes.h"
14931 +#include "comstruc.h"
14932 +#include "fsact.h"
14933 +#include "protocol.h"
14934 +
14935 +#define DEFINE_PCI_IDS
14936 +#include "rxcommon.h"
14937 +#include "monkerapi.h"
14938 +
14939 +#include "fsaport.h"
14940 +#include "fsaioctl.h"
14941 +
14942 +#include "pcisup.h"
14943 +#include "rx.h"
14944 +
14945 +#include "port.h"
14946 +
14947 +#define BugCheckFileId                   (FSAFS_BUG_CHECK_CYCLONESUP)
14948 +
14949 +// #define RxBugCheck(A,B,C) { KeBugCheckEx(0x00000AFA, __LINE__, (ULONG)A, (ULONG)B,(ULONG)C ); }
14950 +
14951 +#define RxBugCheck(A, B, C) {  cmn_err(CE_PANIC, "aacdisk : line %s, 0x%x, 0x%x, 0x%x ", __LINE__, A, B, C);  }
14952 +
14953 +#define NUM_TICKS_PER_SECOND (1000 * 1000 * 10) /* time is in 100 nanoseconds */
14954 +
14955 +
14956 +//
14957 +// The list of all the Rx adapter structures
14958 +//
14959 +
14960 +PRx_ADAPTER_EXTENSION  RxAdapterList;
14961 +
14962 +int
14963 +RxInitDevice(
14964 +       IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
14965 +       IN ULONG AdapterNumber,
14966 +       IN ULONG PciBus,
14967 +       IN ULONG PciSlot
14968 +);
14969 +
14970 +BOOLEAN
14971 +RxSendSynchFib(
14972 +       PVOID Arg1,
14973 +       ULONG FibPhysicalAddress
14974 +       );
14975 +
14976 +FSA_USER_VAR   RxUserVars[] = {
14977 +       { "AfaPortPrinting", (PULONG)&AfaPortPrinting, NULL },
14978 +};
14979 +
14980 +
14981 +//
14982 +// Declare private use routines for this modual
14983 +//
14984 +
14985 +u_int
14986 +RxPciIsr (
14987 +    IN PRx_ADAPTER_EXTENSION AdapterExtension
14988 +    )
14989 +
14990 +/*++
14991 +
14992 +Routine Description:
14993 +
14994 +    The Isr routine for fsa Rx based adapter boards.
14995 +
14996 +Arguments:
14997 +
14998 +
14999 +Return Value:
15000 +
15001 +       TRUE - if the interrupt was handled by this isr
15002 +       FALSE - if the interrupt was not handled by this isr
15003 +
15004 +--*/
15005 +
15006 +{
15007 +       ULONG   DoorbellBits;
15008 +       UCHAR   InterruptStatus, Mask;
15009 +       u_int OurInterrupt = INTR_UNCLAIMED;
15010 +
15011 +       //cmn_err(CE_WARN, "RxPciIsr entered\n");
15012 +
15013 +       InterruptStatus = Rx_READ_UCHAR(AdapterExtension, MUnit.OISR);
15014 +
15015 +       //
15016 +       // Read mask and invert because drawbridge is reversed.
15017 +       //
15018 +       // This allows us to only service interrupts that have been enabled.
15019 +       //
15020 +
15021 +       Mask = ~(Rx_READ_UCHAR(AdapterExtension, MUnit.OIMR));
15022 +
15023 +       // Check to see if this is our interrupt.  If it isn't just return FALSE.
15024 +
15025 +
15026 +       if (InterruptStatus & Mask) {
15027 +
15028 +               DoorbellBits = Rx_READ_ULONG(AdapterExtension, OutboundDoorbellReg);
15029 +
15030 +               OurInterrupt = INTR_CLAIMED;
15031 +
15032 +               if (DoorbellBits & DoorBellPrintfReady) {
15033 +
15034 +                       ULONG Length, Level;
15035 +                       unsigned char *cp;
15036 +
15037 +                       cp = AdapterExtension->Common->PrintfBufferAddress;
15038 +
15039 +                       //
15040 +                       // The size of the Printfbuffer is set in port.c
15041 +                       // There is no variable or define for it
15042 +                       //
15043 +                       if (Length > 255)
15044 +                               Length = 255;
15045 +
15046 +                       if (cp[Length] != 0) {
15047 +                               // cmn_err (CE_NOTE, "byte %d is 0x%x, should be 0", Length, cp[Length]);
15048 +                               cp[Length] = 0;
15049 +                       }
15050 +
15051 +                       if (Level == LOG_HIGH_ERROR)
15052 +                               cmn_err (CE_WARN, "%s:%s", OsGetDeviceName(AdapterExtension), AdapterExtension->Common->PrintfBufferAddress);
15053 +                       else
15054 +                               cmn_err (CE_NOTE, "%s:%s", OsGetDeviceName(AdapterExtension), AdapterExtension->Common->PrintfBufferAddress);
15055 +
15056 +                       bzero (AdapterExtension->Common->PrintfBufferAddress, 256);
15057 +
15058 +                       Rx_WRITE_ULONG(AdapterExtension, MUnit.ODR,DoorBellPrintfReady); //clear PrintfReady
15059 +
15060 +                       Rx_WRITE_ULONG(AdapterExtension, InboundDoorbellReg,DoorBellPrintfDone);
15061 +
15062 +
15063 +               } else if (DoorbellBits & DoorBellAdapterNormCmdReady) {        // Adapter -> Host Normal Command Ready
15064 +
15065 +                       AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, HostNormCmdQue);
15066 +                       Rx_WRITE_ULONG(AdapterExtension, MUnit.ODR, DoorBellAdapterNormCmdReady);
15067 +
15068 +               } else if (DoorbellBits & DoorBellAdapterNormRespReady) {       // Adapter -> Host Normal Response Ready
15069 +
15070 +                       AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, HostNormRespQue);
15071 +                       Rx_WRITE_ULONG(AdapterExtension, MUnit.ODR,DoorBellAdapterNormRespReady);
15072 +
15073 +               } else if (DoorbellBits & DoorBellAdapterNormCmdNotFull) {      // Adapter -> Host Normal Command Not Full
15074 +
15075 +                       AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, AdapNormCmdNotFull);
15076 +                       Rx_WRITE_ULONG(AdapterExtension, MUnit.ODR, DoorBellAdapterNormCmdNotFull);
15077 +
15078 +               } else if (DoorbellBits & DoorBellAdapterNormRespNotFull) {     // Adapter -> Host Normal Response Not Full
15079 +
15080 +                       AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, AdapNormRespNotFull);
15081 +                       Rx_WRITE_ULONG(AdapterExtension, MUnit.ODR, DoorBellAdapterNormRespNotFull);
15082 +
15083 +               }
15084 +
15085 +       }
15086 +       return(OurInterrupt);
15087 +}
15088 +
15089 +VOID
15090 +RxEnableInterrupt(
15091 +       PVOID                                           Arg1,
15092 +       ADAPTER_EVENT                           AdapterEvent,
15093 +       BOOLEAN                                         AtDeviceIrq
15094 +       )
15095 +/*++
15096 +
15097 +Routine Description:
15098 +
15099 +       This routine will enable the corresponding adapter event to cause an interrupt on 
15100 +       the host.
15101 +
15102 +Arguments:
15103 +
15104 +       AdapterExtension - Which adapter to enable.
15105 +
15106 +       AdapterEvent - Which adapter event.
15107 +
15108 +       AtDeviceIrq - Whether the system is in DEVICE irql
15109 +
15110 +Return Value:
15111 +
15112 +    Nothing.
15113 +
15114 +--*/
15115 +{
15116 +       PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
15117 +       PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) CommonExtension->MiniPort;
15118 +
15119 +       //cmn_err(CE_WARN, "RxEnableInterrupt");
15120 +       switch (AdapterEvent) {
15121 +
15122 +         case HostNormCmdQue:
15123 +
15124 +               AdapterExtension->LocalMaskInterruptControl &= ~(OUTBOUNDDOORBELL_1);
15125 +
15126 +               break;
15127 +
15128 +         case HostNormRespQue:
15129 +
15130 +               AdapterExtension->LocalMaskInterruptControl &= ~(OUTBOUNDDOORBELL_2);
15131 +
15132 +               break;
15133 +
15134 +      case AdapNormCmdNotFull:
15135 +
15136 +               AdapterExtension->LocalMaskInterruptControl &= ~(OUTBOUNDDOORBELL_3);
15137 +
15138 +               break;
15139 +
15140 +      case AdapNormRespNotFull:
15141 +
15142 +               AdapterExtension->LocalMaskInterruptControl &= ~(OUTBOUNDDOORBELL_4);
15143 +
15144 +               break;
15145 +
15146 +       }
15147 +
15148 +}
15149 +
15150 +VOID
15151 +RxDisableInterrupt(
15152 +       PVOID                                           Arg1,
15153 +       ADAPTER_EVENT                           AdapterEvent,
15154 +       BOOLEAN                                         AtDeviceIrq
15155 +       )
15156 +/*++
15157 +
15158 +Routine Description:
15159 +
15160 +       This routine will disable the corresponding adapter event to cause an interrupt on 
15161 +       the host.
15162 +
15163 +Arguments:
15164 +
15165 +       AdapterExtension - Which adapter to enable.
15166 +
15167 +       AdapterEvent - Which adapter event.
15168 +
15169 +       AtDeviceIrq - Whether the system is in DEVICE irql
15170 +
15171 +Return Value:
15172 +
15173 +    Nothing.
15174 +
15175 +--*/
15176 +{
15177 +       PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
15178 +       PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) CommonExtension->MiniPort;
15179 +
15180 +       //cmn_err(CE_WARN, "RxEnableInterrupt");
15181 +
15182 +       switch (AdapterEvent) {
15183 +
15184 +
15185 +         case HostNormCmdQue:
15186 +
15187 +               AdapterExtension->LocalMaskInterruptControl |= (OUTBOUNDDOORBELL_1);
15188 +
15189 +               break;
15190 +
15191 +         case HostNormRespQue:
15192 +
15193 +               AdapterExtension->LocalMaskInterruptControl |= (OUTBOUNDDOORBELL_2);
15194 +
15195 +               break;
15196 +
15197 +      case AdapNormCmdNotFull:
15198 +
15199 +               AdapterExtension->LocalMaskInterruptControl |= (OUTBOUNDDOORBELL_3);
15200 +
15201 +               break;
15202 +
15203 +
15204 +      case AdapNormRespNotFull:
15205 +
15206 +               AdapterExtension->LocalMaskInterruptControl |= (OUTBOUNDDOORBELL_4);
15207 +
15208 +               break;
15209 +
15210 +       }
15211 +
15212 +}
15213 +
15214 +
15215 +
15216 +RxDetachDevice(
15217 +       IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension
15218 +       )
15219 +{
15220 +       PRx_ADAPTER_EXTENSION AdapterExtension = CommonExtension->MiniPort;
15221 +
15222 +       //
15223 +       // Free the register mapping.
15224 +       //
15225 +
15226 +       OsDetachDevice( AdapterExtension);
15227 +
15228 +       OsFreeMemory( AdapterExtension, sizeof(Rx_ADAPTER_EXTENSION) );
15229 +
15230 +}
15231 +
15232 +int
15233 +RxInitDevice(
15234 +       IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
15235 +       IN ULONG AdapterNumber,
15236 +       IN ULONG PciBus,
15237 +       IN ULONG PciSlot
15238 +)
15239 +
15240 +/*++
15241 +
15242 +Routine Description:
15243 +
15244 +       Scans the PCI bus looking for the Rx card. When found all resources for the
15245 +       device will be allocated and the interrupt vectors and csrs will be allocated and
15246 +       mapped.
15247 +
15248 +       The device_interface in the commregion will be allocated and linked to the comm region.
15249 +
15250 +Arguments:
15251 +
15252 +
15253 +Return Value:
15254 +
15255 +    TRUE - if the device was setup with not problems
15256 +    FALSE - if the device could not be mapped and init successfully
15257 +
15258 +--*/
15259 +
15260 +{
15261 +       AAC_STATUS Status;
15262 +       PRx_ADAPTER_EXTENSION AdapterExtension = NULL;
15263 +       FSA_NEW_ADAPTER NewAdapter;
15264 +       ULONG StartTime, EndTime, WaitTime;
15265 +       ULONG InitStatus;
15266 +       int instance;
15267 +       int nIntrs;
15268 +       char * name;
15269 +
15270 +    AfaPortPrint("In init device.\n");
15271 +
15272 +       //cmn_err(CE_WARN, "In RxInitDevice");
15273 +
15274 +//     AdapterExtension->Common->AdapterIndex = AdapterIndex;
15275 +       CommonExtension->AdapterNumber = AdapterNumber;
15276 +
15277 +
15278 +       CommonExtension->PciBusNumber = PciBus;
15279 +       CommonExtension->PciSlotNumber = PciSlot;
15280 +
15281 +
15282 +       AdapterExtension = OsAllocMemory( sizeof(Rx_ADAPTER_EXTENSION), OS_ALLOC_MEM_SLEEP );
15283 +       AdapterExtension->Common = CommonExtension;
15284 +       CommonExtension->MiniPort = AdapterExtension;
15285 +
15286 +       instance = OsGetDeviceInstance(AdapterExtension);
15287 +       name     = OsGetDeviceName(AdapterExtension);
15288 +       //
15289 +       // Map in the registers from the adapter, register space 0 is config space,
15290 +       // register space 1 is the memery space.
15291 +       //
15292 +
15293 +       if (OsMapDeviceRegisters(AdapterExtension)) {
15294 +
15295 +               cmn_err(CE_CONT, "%s%d: can't map device registers\n",
15296 +                               OsGetDeviceName(AdapterExtension), instance);
15297 +               return(FAILURE);
15298 +       }
15299 +
15300 +       //
15301 +       // Check to see if the board failed any self tests.
15302 +       //
15303 +
15304 +       if (Rx_READ_ULONG( AdapterExtension, IndexRegs.Mailbox[7]) & SELF_TEST_FAILED) {
15305 +
15306 +               cmn_err(CE_CONT, "%s%d: adapter self-test failed\n",
15307 +                               OsGetDeviceName(AdapterExtension), instance);
15308 +               return(FAILURE);
15309 +
15310 +       }
15311 +       //cmn_err(CE_WARN, "RxInitDevice: %s%d: adapter passwd self-test\n",
15312 +       //                      OsGetDeviceName(AdapterExtension), instance);
15313 +
15314 +       //
15315 +       // Check to see if the board panic'd while booting.
15316 +       //
15317 +
15318 +       if (Rx_READ_ULONG( AdapterExtension, IndexRegs.Mailbox[7]) & KERNEL_PANIC) {
15319 +
15320 +               cmn_err(CE_CONT, "%s%d: adapter kernel panic'd\n",
15321 +                               OsGetDeviceName(AdapterExtension), instance);
15322 +               return(FAILURE);
15323 +
15324 +       }
15325 +
15326 +       StartTime = OsGetSeconds();
15327 +       WaitTime = 0;
15328 +
15329 +
15330 +       //
15331 +       //  Wait for the adapter to be up and running. Wait up until 3 minutes.
15332 +       //
15333 +
15334 +       while (!(Rx_READ_ULONG( AdapterExtension, IndexRegs.Mailbox[7]) & KERNEL_UP_AND_RUNNING)) {
15335 +       
15336 +               EndTime = OsGetSeconds();
15337 +
15338 +               WaitTime = EndTime - StartTime;
15339 +
15340 +               if ( WaitTime > (3 * 10) ) {
15341 +
15342 +                       InitStatus = Rx_READ_ULONG( AdapterExtension, IndexRegs.Mailbox[7]) >> 16;
15343 +
15344 +                       cmn_err(CE_CONT, "%s%d: adapter kernel failed to start, init status = %d\n",
15345 +                                       OsGetDeviceName(AdapterExtension), instance, InitStatus);
15346 +                       return(FAILURE);
15347 +
15348 +               }
15349 +       }
15350 +
15351 +       if (OsAttachInterrupt(AdapterExtension,RxISR)) {
15352 +               cmn_err(CE_WARN, "%s%d RxInitDevice: failed OsAttachIntterupt", name, instance);
15353 +               return(FAILURE);
15354 +       }
15355 +
15356 +
15357 +       if (OsAttachDMA(AdapterExtension)) {
15358 +               cmn_err(CE_WARN, "%s%d SaInitDevice: failed OsAttachDMA", name, instance);
15359 +               return(FAILURE);
15360 +       }
15361 +
15362 +       //
15363 +       // Fill in the function dispatch table.
15364 +       //
15365 +
15366 +       AdapterExtension->Common->AdapterFuncs.SizeOfFsaPortFuncs = sizeof(FSAPORT_FUNCS);
15367 +       AdapterExtension->Common->AdapterFuncs.AllocateAdapterCommArea = AfaPortAllocateAdapterCommArea;
15368 +       AdapterExtension->Common->AdapterFuncs.FreeAdapterCommArea = AfaPortFreeAdapterCommArea;
15369 +       AdapterExtension->Common->AdapterFuncs.BuildSgMap = AfaPortBuildSgMap;
15370 +       AdapterExtension->Common->AdapterFuncs.FreeDmaResources = AfaPortFreeDmaResources;
15371 +       AdapterExtension->Common->AdapterFuncs.AllocateAndMapFibSpace = AfaPortAllocateAndMapFibSpace;
15372 +       AdapterExtension->Common->AdapterFuncs.UnmapAndFreeFibSpace = AfaPortUnmapAndFreeFibSpace;
15373 +       AdapterExtension->Common->AdapterFuncs.InterruptAdapter = RxInterruptAdapter;
15374 +       AdapterExtension->Common->AdapterFuncs.EnableInterrupt = RxEnableInterrupt;
15375 +       AdapterExtension->Common->AdapterFuncs.DisableInterrupt = RxDisableInterrupt;
15376 +       AdapterExtension->Common->AdapterFuncs.NotifyAdapter = RxNotifyAdapter;
15377 +       AdapterExtension->Common->AdapterFuncs.ResetDevice = RxResetDevice;
15378 +       AdapterExtension->Common->AdapterFuncs.InterruptHost = NULL;
15379 +
15380 +       AdapterExtension->Common->AdapterFuncs.SendSynchFib = RxSendSynchFib;
15381 +
15382 +       NewAdapter.AdapterExtension = CommonExtension;
15383 +       NewAdapter.AdapterFuncs = &AdapterExtension->Common->AdapterFuncs;
15384 +       NewAdapter.AdapterInterruptsBelowDpc = FALSE;
15385 +       NewAdapter.AdapterUserVars = RxUserVars;
15386 +       NewAdapter.AdapterUserVarsSize = sizeof(RxUserVars) / sizeof(FSA_USER_VAR);
15387 +
15388 +       NewAdapter.Dip = CommonExtension->OsDep.dip;
15389 +
15390 +       
15391 +       if (AfaCommInitNewAdapter( &NewAdapter ) == NULL) {
15392 +               
15393 +               cmn_err(CE_WARN, "AfaCommInitNewAdapter failed\n");
15394 +               return (FAILURE);
15395 +       }
15396 +
15397 +
15398 +       AdapterExtension->Common->Adapter = NewAdapter.Adapter;
15399 +
15400 +       if (AdapterExtension->Common->Adapter == NULL) {
15401 +
15402 +               AfaPortLogError(AdapterExtension->Common, FAILURE, NULL, 0);
15403 +               cmn_err(CE_WARN, "%s%d RxInitDevice: No Adapter pointer", name, instance);
15404 +
15405 +
15406 +               return (FAILURE);
15407 +       }
15408 +
15409 +
15410 +       //
15411 +       // Start any kernel threads needed
15412 +       //
15413 +       OsStartKernelThreads(AdapterExtension);
15414 +
15415 +       //
15416 +       // Tell the adapter that all is configure, and it can start accepting requests
15417 +       //
15418 +
15419 +       RxStartAdapter(AdapterExtension);
15420 +
15421 +
15422 +#ifdef AACDISK
15423 +#endif
15424 +
15425 +
15426 +       //
15427 +       // Put this adapter into the list of Rx adapters
15428 +       //
15429 +
15430 +       AdapterExtension->Next = RxAdapterList;
15431 +       RxAdapterList = AdapterExtension;
15432 +
15433 +       AdapterExtension->Common->AdapterConfigured = TRUE;
15434 +
15435 +
15436 +#ifdef AACDISK
15437 +       //
15438 +       // Call the disk layer to initialize itself.
15439 +       //
15440 +
15441 +       AfaDiskInitNewAdapter( AdapterExtension->Common->AdapterNumber, AdapterExtension->Common->Adapter );
15442 +#endif
15443 +
15444 +
15445 +init_done:
15446 +
15447 +       AdapterExtension->Common->AdapterPrintfsToScreen = FALSE;
15448 +
15449 +
15450 +
15451 +       OsAttachHBA(AdapterExtension);
15452 +
15453 +    return(0);
15454 +}
15455 +
15456 +VOID
15457 +RxStartAdapter(
15458 +       PRx_ADAPTER_EXTENSION AdapterExtension
15459 +       )
15460 +{
15461 +       ULONG ReturnStatus;
15462 +       LARGE_INTEGER HostTime;
15463 +       ULONG ElapsedSeconds;
15464 +       PADAPTER_INIT_STRUCT InitStruct;
15465 +
15466 +       //cmn_err(CE_WARN, "RxStartAdapter");
15467 +       //
15468 +       // Fill in the remaining pieces of the InitStruct.
15469 +       //
15470 +
15471 +       InitStruct = AdapterExtension->Common->InitStruct;
15472 +
15473 +       InitStruct->HostPhysMemPages = AfaPortGetMaxPhysicalPage(AdapterExtension->Common);
15474 +
15475 +       ElapsedSeconds = OsGetSeconds();
15476 +
15477 +       InitStruct->HostElapsedSeconds = ElapsedSeconds;
15478 +
15479 +       //
15480 +       // Tell the adapter we are back and up and running so it will scan its command
15481 +       // queues and enable our interrupts
15482 +       //
15483 +
15484 +       AdapterExtension->LocalMaskInterruptControl =
15485 +               (DoorBellPrintfReady | OUTBOUNDDOORBELL_1 | OUTBOUNDDOORBELL_2 | OUTBOUNDDOORBELL_3 | OUTBOUNDDOORBELL_4);
15486 +
15487 +       //
15488 +       // First clear out all interrupts.  Then enable the one's that we can handle.
15489 +       //
15490 +
15491 +       Rx_WRITE_UCHAR( AdapterExtension, MUnit.OIMR, 0xff);
15492 +       Rx_WRITE_ULONG( AdapterExtension, MUnit.ODR, 0xffffffff);
15493 +//     Rx_WRITE_UCHAR(AdapterExtension, MUnit.OIMR, ~(UCHAR)OUTBOUND_DOORBELL_INTERRUPT_MASK);
15494 +       Rx_WRITE_UCHAR( AdapterExtension, MUnit.OIMR, 0xfb);
15495 +
15496 +       RxSendSynchCommand(AdapterExtension, 
15497 +                                        INIT_STRUCT_BASE_ADDRESS, 
15498 +                                        (ULONG) AdapterExtension->Common->PhysicalInitStruct,
15499 +                                        0,
15500 +                                        0,
15501 +                                        0,
15502 +                                        &ReturnStatus);
15503 +
15504 +}
15505 +
15506 +
15507 +VOID
15508 +RxResetDevice(
15509 +       PVOID Arg1
15510 +    )
15511 +
15512 +{
15513 +}
15514 +
15515 +VOID
15516 +RxInterruptAdapter(
15517 +       PVOID Arg1
15518 +       )
15519 +/*++
15520 +
15521 +Routine Description:
15522 +
15523 +       The will cause the adapter to take a break point.
15524 +
15525 +Arguments:
15526 +
15527 +       None
15528 +
15529 +Return Value:
15530 +
15531 +    Nothing
15532 +
15533 +--*/
15534 +{
15535 +       PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
15536 +       PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) CommonExtension->MiniPort;
15537 +
15538 +       ULONG ReturnStatus;
15539 +
15540 +       RxSendSynchCommand(AdapterExtension, 
15541 +                                          BREAKPOINT_REQUEST,
15542 +                                          0,
15543 +                                          0,
15544 +                                          0,
15545 +                                          0,
15546 +                                          &ReturnStatus);
15547 +
15548 +}
15549 +
15550 +VOID
15551 +RxNotifyAdapter(
15552 +       PVOID Arg1,
15553 +    IN HOST_2_ADAP_EVENT AdapterEvent
15554 +    )
15555 +/*++
15556 +
15557 +Routine Description:
15558 +
15559 +    Will read the adapter CSRs to find the reason the adapter has
15560 +    interrupted us.
15561 +
15562 +Arguments:
15563 +
15564 +    AdapterEvent - Enumerated type the returns the reason why we were interrutped.
15565 +
15566 +Return Value:
15567 +
15568 +    Nothing
15569 +
15570 +--*/
15571 +{
15572 +       PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
15573 +       PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) CommonExtension->MiniPort;
15574 +       ULONG ReturnStatus;
15575 +
15576 +       //cmn_err(CE_WARN, "RxNotifyAdapter %d", AdapterEvent);
15577 +
15578 +    switch (AdapterEvent) {
15579 +        case AdapNormCmdQue:
15580 +
15581 +                       Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_1);
15582 +            break;
15583 +
15584 +        case HostNormRespNotFull:
15585 +
15586 +                       Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_4);
15587 +            break;
15588 +
15589 +        case AdapNormRespQue:
15590 +
15591 +                       Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_2);
15592 +            break;
15593 +
15594 +        case HostNormCmdNotFull:
15595 +
15596 +                       Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_3);
15597 +            break;
15598 +
15599 +        case HostShutdown:
15600 +
15601 +//                     RxSendSynchCommand(AdapterExtension, HOST_CRASHING, 0, 0, 0, 0, &ReturnStatus);
15602 +
15603 +            break;
15604 +
15605 +               case FastIo:
15606 +                       Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_6);
15607 +                       break;
15608 +
15609 +               case AdapPrintfDone:
15610 +                       Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_5);
15611 +                       break;
15612 +
15613 +        default:
15614 +
15615 +                       RxBugCheck(0,0,0);
15616 +            AfaPortPrint("Notify requested with an invalid request 0x%x.\n",AdapterEvent);
15617 +            break;
15618 +    }
15619 +}
15620 +
15621 +AAC_STATUS
15622 +RxSendSynchCommand(
15623 +       PVOID Arg1,
15624 +       ULONG Command,
15625 +       ULONG Parameter1,
15626 +       ULONG Parameter2,
15627 +       ULONG Parameter3,
15628 +       ULONG Parameter4,
15629 +       PULONG  ReturnStatus
15630 +       )
15631 +/*++
15632 +
15633 +Routine Description:
15634 +
15635 +       This routine will send a synchronous comamnd to the adapter and wait for its
15636 +       completion.
15637 +
15638 +Arguments:
15639 +
15640 +       AdapterExtension - Pointer to adapter extension structure.
15641 +       Command - Which command to send
15642 +       Parameter1 - 4  - Parameters for command
15643 +       ReturnStatus - return status from adapter after completion of command
15644 +
15645 +
15646 +Return Value:
15647 +
15648 +       AAC_STATUS
15649 +
15650 +--*/
15651 +{
15652 +       PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) Arg1;
15653 +       ULONG StartTime,EndTime,WaitTime;
15654 +       BOOLEAN CommandSucceeded;
15655 +
15656 +       //cmn_err(CE_WARN, "RxSendSyncCommand");
15657 +       //
15658 +       // Write the Command into Mailbox 0
15659 +       //
15660 +
15661 +       Rx_WRITE_ULONG( AdapterExtension, InboundMailbox0, Command);
15662 +
15663 +       //
15664 +       // Write the parameters into Mailboxes 1 - 4
15665 +       //
15666 +
15667 +       Rx_WRITE_ULONG( AdapterExtension, InboundMailbox1, Parameter1);
15668 +       Rx_WRITE_ULONG( AdapterExtension, InboundMailbox2, Parameter2);
15669 +       Rx_WRITE_ULONG( AdapterExtension, InboundMailbox3, Parameter3);
15670 +       Rx_WRITE_ULONG( AdapterExtension, InboundMailbox4, Parameter4);
15671 +
15672 +       //
15673 +       // Clear the synch command doorbell to start on a clean slate.
15674 +       //
15675 +               
15676 +       Rx_WRITE_ULONG( AdapterExtension, OutboundDoorbellReg, OUTBOUNDDOORBELL_0);
15677 +
15678 +       //
15679 +       // disable doorbell interrupts
15680 +       //
15681 +
15682 +       Rx_WRITE_UCHAR( AdapterExtension, MUnit.OIMR, 
15683 +                                       Rx_READ_UCHAR(AdapterExtension, MUnit.OIMR) | 0x04);
15684 +
15685 +       //
15686 +       // force the completion of the mask register write before issuing the interrupt.
15687 +       //
15688 +
15689 +       Rx_READ_UCHAR ( AdapterExtension, MUnit.OIMR);
15690 +
15691 +       //
15692 +       // Signal that there is a new synch command
15693 +       //
15694 +
15695 +       Rx_WRITE_ULONG( AdapterExtension, InboundDoorbellReg, INBOUNDDOORBELL_0);
15696 +
15697 +       CommandSucceeded = FALSE;
15698 +
15699 +       StartTime = OsGetSeconds();
15700 +       WaitTime = 0;
15701 +
15702 +       while (WaitTime < 30) { // wait up to 30 seconds
15703 +
15704 +               drv_usecwait(5);                                // delay 5 microseconds to let Mon960 get info.
15705 +
15706 +               //
15707 +               // Mon110 will set doorbell0 bit when it has completed the command.
15708 +               //
15709 +
15710 +               if (Rx_READ_ULONG(AdapterExtension, OutboundDoorbellReg) & OUTBOUNDDOORBELL_0) {
15711 +
15712 +                       //
15713 +                       // clear the doorbell.
15714 +                       //
15715 +
15716 +                       Rx_WRITE_ULONG(AdapterExtension, OutboundDoorbellReg, OUTBOUNDDOORBELL_0);
15717 +
15718 +                       CommandSucceeded = TRUE;
15719 +                       break;
15720 +               }
15721 +
15722 +               EndTime = OsGetSeconds();
15723 +               WaitTime = EndTime - StartTime;
15724 +
15725 +       }
15726 +
15727 +       if (CommandSucceeded != TRUE) {
15728 +
15729 +               //
15730 +               // restore interrupt mask even though we timed out
15731 +               //
15732 +
15733 +               Rx_WRITE_UCHAR(AdapterExtension, MUnit.OIMR, 
15734 +                                          Rx_READ_ULONG(AdapterExtension, MUnit.OIMR) & 0xfb);
15735 +
15736 +               return (STATUS_IO_TIMEOUT);
15737 +
15738 +       }
15739 +
15740 +       //
15741 +       // Pull the synch status from Mailbox 0.
15742 +       //
15743 +
15744 +       *ReturnStatus = Rx_READ_ULONG(AdapterExtension, IndexRegs.Mailbox[0]);
15745 +
15746 +       //
15747 +       // Clear the synch command doorbell.
15748 +       //
15749 +               
15750 +       Rx_WRITE_ULONG(AdapterExtension, OutboundDoorbellReg, OUTBOUNDDOORBELL_0);
15751 +
15752 +       //
15753 +       // restore interrupt mask
15754 +       //
15755 +
15756 +       Rx_WRITE_UCHAR(AdapterExtension, MUnit.OIMR, 
15757 +                                  Rx_READ_ULONG(AdapterExtension, MUnit.OIMR) & 0xfb);
15758 +
15759 +       //
15760 +       // Return SUCCESS
15761 +       //
15762 +
15763 +       return (STATUS_SUCCESS);
15764 +
15765 +}
15766 +
15767 +BOOLEAN
15768 +RxSendSynchFib(
15769 +       PVOID Arg1,
15770 +       ULONG FibPhysicalAddress
15771 +       )
15772 +/*++
15773 +
15774 +Routine Description:
15775 +
15776 +       This routine will send a synchronous fib to the adapter and wait for its
15777 +       completion.
15778 +
15779 +Arguments:
15780 +
15781 +       AdapterExtension - Pointer to adapter extension structure.
15782 +       FibPhysicalAddress - Physical address of fib to send.
15783 +
15784 +
15785 +Return Value:
15786 +
15787 +       BOOLEAN
15788 +
15789 +--*/
15790 +{
15791 +       PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
15792 +       PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) CommonExtension->MiniPort;
15793 +       ULONG returnStatus;
15794 +
15795 +       if (RxSendSynchCommand( AdapterExtension,
15796 +                                                   SEND_SYNCHRONOUS_FIB,
15797 +                                                   FibPhysicalAddress,
15798 +                                                   0,
15799 +                                                   0,
15800 +                                                   0,
15801 +                                                   &returnStatus ) != STATUS_SUCCESS ) {
15802 +
15803 +               return (FALSE);
15804 +               
15805 +       }
15806 +       
15807 +       return (TRUE);
15808 +                                                                               
15809 +}
15810 +
15811 +
15812 diff -urN linux/drivers/scsi/aacraid/sap1sup.c linux/drivers/scsi/aacraid/sap1sup.c
15813 --- linux/drivers/scsi/aacraid/sap1sup.c        Wed Dec 31 19:00:00 1969
15814 +++ linux/drivers/scsi/aacraid/sap1sup.c        Thu Dec 21 13:14:30 2000
15815 @@ -0,0 +1,859 @@
15816 +/*++
15817 + * Adaptec aacraid device driver for Linux.
15818 + *
15819 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
15820 + *
15821 + * This program is free software; you can redistribute it and/or modify
15822 + * it under the terms of the GNU General Public License as published by
15823 + * the Free Software Foundation; either version 2, or (at your option)
15824 + * any later version.
15825 + *
15826 + * This program is distributed in the hope that it will be useful,
15827 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
15828 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15829 + * GNU General Public License for more details.
15830 + *
15831 + * You should have received a copy of the GNU General Public License
15832 + * along with this program; see the file COPYING.  If not, write to
15833 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
15834 + *
15835 + * Module Name:
15836 + *  sap1sup.c
15837 + *
15838 + * Abstract: Drawbridge specific support functions
15839 + *
15840 + --*/
15841 +
15842 +static char *ident_sap1 = "aacraid_ident sap1sup.c 1.0.7 2000/10/11 Adaptec, Inc.";
15843 +
15844 +#include "osheaders.h"
15845 +
15846 +
15847 +#include "AacGenericTypes.h"
15848 +
15849 +#include "aac_unix_defs.h"
15850 +
15851 +#include "fsatypes.h"
15852 +#include "comstruc.h"
15853 +#include "fsact.h"
15854 +#include "protocol.h"
15855 +
15856 +#define DEFINE_PCI_IDS
15857 +#include "sap1common.h"
15858 +#include "monkerapi.h"
15859 +
15860 +#include "fsaport.h"
15861 +#include "fsaioctl.h"
15862 +
15863 +
15864 +#include "pcisup.h"
15865 +#include "sap1.h"
15866 +
15867 +#include "port.h"
15868 +
15869 +#include "nodetype.h"
15870 +#include "comsup.h"
15871 +#include "afacomm.h"
15872 +#include "adapter.h"
15873 +
15874 +#define BugCheckFileId                   (FSAFS_BUG_CHECK_CYCLONESUP)
15875 +
15876 +// #define SaBugCheck(A,B,C) { KeBugCheckEx(0x00000AFA, __LINE__, (ULONG)A, (ULONG)B,(ULONG)C ); }
15877 +
15878 +#define SaBugCheck(A, B, C) {  cmn_err(CE_PANIC, "aacdisk : line %s, 0x%x, 0x%x, 0x%x ", __LINE__, A, B, C);  }
15879 +
15880 +#define NUM_TICKS_PER_SECOND (1000 * 1000 * 10) /* time is in 100 nanoseconds */
15881 +
15882 +int MiniPortRevision = Sa_MINIPORT_REVISION;
15883 +
15884 +
15885 +//
15886 +// The list of all the Sa adapter structures
15887 +//
15888 +
15889 +PSa_ADAPTER_EXTENSION  SaAdapterList;
15890 +
15891 +int
15892 +SaInitDevice(
15893 +       IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
15894 +       IN ULONG AdapterNumber,
15895 +       IN ULONG PciBus,
15896 +       IN ULONG PciSlot
15897 +);
15898 +
15899 +BOOLEAN
15900 +SaSendSynchFib(
15901 +       PVOID Arg1,
15902 +       ULONG FibPhysicalAddress
15903 +       );
15904 +
15905 +FSA_USER_VAR   SaUserVars[] = {
15906 +       { "AfaPortPrinting", (PULONG)&AfaPortPrinting, NULL },
15907 +};
15908 +
15909 +
15910 +//
15911 +// Declare private use routines for this modual
15912 +//
15913 +
15914 +
15915 +/*++
15916 +
15917 +Routine Description:
15918 +
15919 +    The Isr routine for fsa Sa based adapter boards.
15920 +
15921 +Arguments:
15922 +
15923 +
15924 +Return Value:
15925 +
15926 +       TRUE - if the interrupt was handled by this isr
15927 +       FALSE - if the interrupt was not handled by this isr
15928 +
15929 +--*/
15930 +u_int
15931 +SaPciIsr (IN PSa_ADAPTER_EXTENSION AdapterExtension)
15932 +{
15933 +               USHORT InterruptStatus, Mask;
15934 +               u_int OurInterrupt = INTR_UNCLAIMED;
15935 +
15936 +       InterruptStatus = Sa_READ_USHORT( AdapterExtension, DoorbellReg_p);
15937 +
15938 +       //
15939 +       // Read mask and invert because drawbridge is reversed.
15940 +       //
15941 +       // This allows us to only service interrupts that have been enabled.
15942 +       //
15943 +
15944 +       Mask = ~(Sa_READ_USHORT( AdapterExtension, SaDbCSR.PRISETIRQMASK));
15945 +
15946 +       // Check to see if this is our interrupt.  If it isn't just return FALSE.
15947 +
15948 +
15949 +       if (InterruptStatus & Mask) {
15950 +
15951 +               OurInterrupt = INTR_CLAIMED;
15952 +
15953 +               if (InterruptStatus & PrintfReady) {
15954 +
15955 +                       ULONG Length, Level;
15956 +                       unsigned char *cp;
15957 +
15958 +                       cp = AdapterExtension->Common->PrintfBufferAddress;
15959 +
15960 +                       //
15961 +                       // The size of the Printbuffer is set in port.c
15962 +                       // There is no variable or define for it
15963 +                       //
15964 +                       if (Length > 255)
15965 +                               Length = 255;
15966 +
15967 +                       if (cp[Length] != 0) {
15968 +                               // cmn_err (CE_NOTE, "byte %d is 0x%x, should be 0", Length, cp[Length]);
15969 +                               cp[Length] = 0;
15970 +                       }
15971 +
15972 +                       if (Level == LOG_HIGH_ERROR)
15973 +                               cmn_err (CE_WARN, "%s:%s", OsGetDeviceName(AdapterExtension), AdapterExtension->Common->PrintfBufferAddress);
15974 +                       else
15975 +                               cmn_err (CE_NOTE, "%s:%s", OsGetDeviceName(AdapterExtension), AdapterExtension->Common->PrintfBufferAddress);
15976 +
15977 +                       bzero (AdapterExtension->Common->PrintfBufferAddress, 256);
15978 +
15979 +                       Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p,PrintfReady); //clear PrintfReady
15980 +
15981 +                       Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,PrintfDone);
15982 +
15983 +               } else if (InterruptStatus & DOORBELL_1) {      // Adapter -> Host Normal Command Ready
15984 +
15985 +                       AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, HostNormCmdQue);
15986 +                       Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p, DOORBELL_1);
15987 +
15988 +               } else if (InterruptStatus & DOORBELL_2) {      // Adapter -> Host Normal Response Ready
15989 +
15990 +                               AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, HostNormRespQue);
15991 +                               Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p,DOORBELL_2);
15992 +
15993 +               } else if (InterruptStatus & DOORBELL_3) {      // Adapter -> Host Normal Command Not Full
15994 +
15995 +                       AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, AdapNormCmdNotFull);
15996 +                       Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p, DOORBELL_3);
15997 +
15998 +               } else if (InterruptStatus & DOORBELL_4) {      // Adapter -> Host Normal Response Not Full
15999 +
16000 +                       AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, AdapNormRespNotFull);
16001 +                       Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p, DOORBELL_4);
16002 +
16003 +               }
16004 +
16005 +       }
16006 +       return(OurInterrupt);
16007 +}
16008 +
16009 +
16010 +/*++
16011 +
16012 +Routine Description:
16013 +
16014 +       This routine will enable the corresponding adapter event to cause an interrupt on 
16015 +       the host.
16016 +
16017 +Arguments:
16018 +
16019 +       AdapterExtension - Which adapter to enable.
16020 +
16021 +       AdapterEvent - Which adapter event.
16022 +
16023 +       AtDeviceIrq - Whether the system is in DEVICE irql
16024 +
16025 +Return Value:
16026 +
16027 +    Nothing.
16028 +
16029 +--*/
16030 +VOID
16031 +SaEnableInterrupt (PVOID Arg1, ADAPTER_EVENT AdapterEvent, BOOLEAN AtDeviceIrq)
16032 +{
16033 +       PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
16034 +       PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) CommonExtension->MiniPort;
16035 +
16036 +       switch (AdapterEvent) {
16037 +
16038 +         case HostNormCmdQue:
16039 +
16040 +               Sa_WRITE_USHORT( AdapterExtension,  SaDbCSR.PRICLEARIRQMASK, DOORBELL_1 );
16041 +
16042 +               break;
16043 +
16044 +         case HostNormRespQue:
16045 +
16046 +               Sa_WRITE_USHORT( AdapterExtension,  SaDbCSR.PRICLEARIRQMASK, DOORBELL_2 );
16047 +
16048 +               break;
16049 +
16050 +      case AdapNormCmdNotFull:
16051 +
16052 +               Sa_WRITE_USHORT( AdapterExtension,  SaDbCSR.PRICLEARIRQMASK, DOORBELL_3 );
16053 +
16054 +               break;
16055 +
16056 +      case AdapNormRespNotFull:
16057 +
16058 +               Sa_WRITE_USHORT( AdapterExtension,  SaDbCSR.PRICLEARIRQMASK, DOORBELL_4 );
16059 +
16060 +               break;
16061 +
16062 +       }
16063 +
16064 +}
16065 +
16066 +
16067 +
16068 +/*++
16069 +
16070 +Routine Description:
16071 +
16072 +       This routine will disable the corresponding adapter event to cause an interrupt on 
16073 +       the host.
16074 +
16075 +Arguments:
16076 +
16077 +       AdapterExtension - Which adapter to enable.
16078 +
16079 +       AdapterEvent - Which adapter event.
16080 +
16081 +       AtDeviceIrq - Whether the system is in DEVICE irql
16082 +
16083 +Return Value:
16084 +
16085 +    Nothing.
16086 +
16087 +--*/
16088 +VOID
16089 +SaDisableInterrupt (PVOID Arg1,        ADAPTER_EVENT AdapterEvent, BOOLEAN AtDeviceIrq)
16090 +{
16091 +       PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
16092 +       PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) CommonExtension->MiniPort;
16093 +
16094 +       switch (AdapterEvent) {
16095 +
16096 +
16097 +         case HostNormCmdQue:
16098 +
16099 +               Sa_WRITE_USHORT( AdapterExtension,  SaDbCSR.PRISETIRQMASK, DOORBELL_1 );
16100 +
16101 +               break;
16102 +
16103 +         case HostNormRespQue:
16104 +
16105 +               Sa_WRITE_USHORT( AdapterExtension,  SaDbCSR.PRISETIRQMASK, DOORBELL_2 );
16106 +
16107 +               break;
16108 +
16109 +      case AdapNormCmdNotFull:
16110 +
16111 +               Sa_WRITE_USHORT( AdapterExtension,  SaDbCSR.PRISETIRQMASK, DOORBELL_3 );
16112 +
16113 +               break;
16114 +
16115 +
16116 +      case AdapNormRespNotFull:
16117 +
16118 +               Sa_WRITE_USHORT( AdapterExtension,  SaDbCSR.PRISETIRQMASK, DOORBELL_4 );
16119 +
16120 +               break;
16121 +
16122 +       }
16123 +
16124 +}
16125 +
16126 +
16127 +SaDetachDevice (IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension)
16128 +{
16129 +       PSa_ADAPTER_EXTENSION AdapterExtension = CommonExtension->MiniPort;
16130 +
16131 +       //
16132 +       // Free the register mapping.
16133 +       //
16134 +
16135 +       OsDetachDevice(AdapterExtension);
16136 +
16137 +       OsFreeMemory( AdapterExtension, sizeof(Sa_ADAPTER_EXTENSION) );
16138 +
16139 +}
16140 +
16141 +
16142 +/*++
16143 +
16144 +Routine Description:
16145 +
16146 +       Scans the PCI bus looking for the Sa card. When found all resources for the
16147 +       device will be allocated and the interrupt vectors and csrs will be allocated and
16148 +       mapped.
16149 +
16150 +       The device_interface in the commregion will be allocated and linked to the comm region.
16151 +
16152 +Arguments:
16153 +
16154 +
16155 +Return Value:
16156 +
16157 +    TRUE - if the device was setup with not problems
16158 +    FALSE - if the device could not be mapped and init successfully
16159 +
16160 +--*/
16161 +int
16162 +SaInitDevice (IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
16163 +                         IN ULONG AdapterNumber, IN ULONG PciBus,
16164 +                         IN ULONG PciSlot)
16165 +{
16166 +       AAC_STATUS Status;
16167 +       PSa_ADAPTER_EXTENSION AdapterExtension = NULL;
16168 +       FSA_NEW_ADAPTER NewAdapter;
16169 +       ULONG StartTime, EndTime, WaitTime;
16170 +       ULONG InitStatus;
16171 +       int instance;
16172 +       char *name;
16173 +
16174 +    AfaPortPrint("In init device.\n");
16175 +
16176 +       CommonExtension->AdapterNumber = AdapterNumber;
16177 +
16178 +       CommonExtension->PciBusNumber = PciBus;
16179 +       CommonExtension->PciSlotNumber = PciSlot;
16180 +
16181 +       AdapterExtension = OsAllocMemory( sizeof(Sa_ADAPTER_EXTENSION), OS_ALLOC_MEM_SLEEP );
16182 +       AdapterExtension->Common = CommonExtension;
16183 +       CommonExtension->MiniPort = AdapterExtension;
16184 +
16185 +       instance = OsGetDeviceInstance(AdapterExtension);
16186 +       name     = OsGetDeviceName(AdapterExtension);
16187 +
16188 +       //
16189 +       // Map in the registers from the adapter, register space 0 is config space,
16190 +       // register space 1 is the memery space.
16191 +       //
16192 +
16193 +       if (OsMapDeviceRegisters(AdapterExtension)){
16194 +               cmn_err(CE_WARN, "%s%d SaInitDevice: failed OsMapDeviceRegisters", name, instance);
16195 +               return(FAILURE);
16196 +       }
16197 +
16198 +
16199 +       //
16200 +       // Check to see if the board failed any self tests.
16201 +       //
16202 +
16203 +       if (Sa_READ_ULONG( AdapterExtension, Mailbox7) & SELF_TEST_FAILED) {
16204 +
16205 +               cmn_err(CE_WARN, "%s%d: adapter self-test failed\n",
16206 +                               name, instance);
16207 +               return(FAILURE);
16208 +       }
16209 +
16210 +       //
16211 +       // Check to see if the board panic'd while booting.
16212 +       //
16213 +
16214 +       if (Sa_READ_ULONG( AdapterExtension, Mailbox7) & KERNEL_PANIC) {
16215 +
16216 +               cmn_err(CE_WARN, "%s%d: adapter kernel panic'd\n",
16217 +                               name, instance);
16218 +               return(FAILURE);
16219 +       }
16220 +
16221 +
16222 +       StartTime = OsGetSeconds();
16223 +       WaitTime = 0;
16224 +
16225 +
16226 +       //
16227 +       //  Wait for the adapter to be up and running. Wait up until 3 minutes.
16228 +       //
16229 +
16230 +       while (!(Sa_READ_ULONG( AdapterExtension, Mailbox7) & KERNEL_UP_AND_RUNNING)) {
16231 +       
16232 +               EndTime = OsGetSeconds();
16233 +
16234 +               WaitTime = EndTime - StartTime;
16235 +
16236 +               if ( WaitTime > (3 * 60) ) {
16237 +
16238 +                       InitStatus = Sa_READ_ULONG( AdapterExtension, Mailbox7) >> 16;
16239 +
16240 +                       cmn_err(CE_WARN, "%s%d: adapter kernel failed to start, init status = %d\n",
16241 +                                       name, instance, InitStatus);
16242 +                       return(FAILURE);
16243 +
16244 +               }
16245 +       }
16246 +
16247 +       if (OsAttachInterrupt(AdapterExtension, SaISR)) {
16248 +               cmn_err(CE_WARN, "%s%d SaInitDevice: failed OsAttachIntterupt", name, instance);
16249 +               return(FAILURE);
16250 +       }
16251 +
16252 +       if (OsAttachDMA(AdapterExtension)) {
16253 +               cmn_err(CE_WARN, "%s%d SaInitDevice: failed OsAttachDMA", name, instance);
16254 +               return(FAILURE);
16255 +       }
16256 +
16257 +
16258 +       //
16259 +       // Fill in the function dispatch table.
16260 +       //
16261 +
16262 +       AdapterExtension->Common->AdapterFuncs.SizeOfFsaPortFuncs = sizeof(FSAPORT_FUNCS);
16263 +       AdapterExtension->Common->AdapterFuncs.AllocateAdapterCommArea = AfaPortAllocateAdapterCommArea;
16264 +       AdapterExtension->Common->AdapterFuncs.FreeAdapterCommArea = AfaPortFreeAdapterCommArea;
16265 +       AdapterExtension->Common->AdapterFuncs.BuildSgMap = AfaPortBuildSgMap;
16266 +       AdapterExtension->Common->AdapterFuncs.FreeDmaResources = AfaPortFreeDmaResources;
16267 +       AdapterExtension->Common->AdapterFuncs.AllocateAndMapFibSpace = AfaPortAllocateAndMapFibSpace;
16268 +       AdapterExtension->Common->AdapterFuncs.UnmapAndFreeFibSpace = AfaPortUnmapAndFreeFibSpace;
16269 +       AdapterExtension->Common->AdapterFuncs.InterruptAdapter = SaInterruptAdapter;
16270 +       AdapterExtension->Common->AdapterFuncs.EnableInterrupt = SaEnableInterrupt;
16271 +       AdapterExtension->Common->AdapterFuncs.DisableInterrupt = SaDisableInterrupt;
16272 +       AdapterExtension->Common->AdapterFuncs.NotifyAdapter = SaNotifyAdapter;
16273 +       AdapterExtension->Common->AdapterFuncs.ResetDevice = SaResetDevice;
16274 +       AdapterExtension->Common->AdapterFuncs.InterruptHost = NULL;
16275 +
16276 +       AdapterExtension->Common->AdapterFuncs.SendSynchFib = SaSendSynchFib;
16277 +
16278 +       NewAdapter.AdapterExtension = CommonExtension;
16279 +       NewAdapter.AdapterFuncs = &AdapterExtension->Common->AdapterFuncs;
16280 +       NewAdapter.AdapterInterruptsBelowDpc = FALSE;
16281 +       NewAdapter.AdapterUserVars = SaUserVars;
16282 +       NewAdapter.AdapterUserVarsSize = sizeof(SaUserVars) / sizeof(FSA_USER_VAR);
16283 +
16284 +       NewAdapter.Dip = CommonExtension->OsDep.dip;
16285 +
16286 +       
16287 +       if ( AfaCommInitNewAdapter( &NewAdapter ) == NULL) {
16288 +                       cmn_err(CE_WARN, "SaInitDevice: AfaCommInitNewAdapter failed\n");
16289 +                       return (FAILURE);
16290 +       };
16291 +
16292 +
16293 +       AdapterExtension->Common->Adapter = NewAdapter.Adapter;
16294 +
16295 +       if (AdapterExtension->Common->Adapter == NULL) {
16296 +
16297 +               AfaPortLogError(AdapterExtension->Common, FAILURE, NULL, 0);
16298 +               cmn_err(CE_WARN, "%s%d SaInitDevice: No Adapter pointer", name, instance);
16299 +
16300 +               return (FAILURE); 
16301 +       }
16302 +
16303 +
16304 +    //
16305 +       // Start any kernel threads needed
16306 +       OsStartKernelThreads(AdapterExtension);
16307 +
16308 +       //
16309 +       // Tell the adapter that all is configure, and it can start accepting requests
16310 +       //
16311 +
16312 +       SaStartAdapter(AdapterExtension);
16313 +
16314 +
16315 +
16316 +       //
16317 +       // Put this adapter into the list of Sa adapters
16318 +       //
16319 +
16320 +       AdapterExtension->Next = SaAdapterList;
16321 +       SaAdapterList = AdapterExtension;
16322 +
16323 +       AdapterExtension->Common->AdapterConfigured = TRUE;
16324 +
16325 +
16326 +#ifdef AACDISK
16327 +       //
16328 +       // Call the disk layer to initialize itself.
16329 +       //
16330 +
16331 +       AfaDiskInitNewAdapter( AdapterExtension->Common->AdapterNumber, AdapterExtension->Common->Adapter );
16332 +#endif
16333 +
16334 +
16335 +init_done:
16336 +
16337 +       AdapterExtension->Common->AdapterPrintfsToScreen = FALSE;
16338 +
16339 +       OsAttachHBA(AdapterExtension);
16340 +
16341 +       return (0);
16342 +
16343 +init_error:
16344 +
16345 +       return (FAILURE);
16346 +}
16347 +
16348 +
16349 +
16350 +VOID
16351 +SaStartAdapter (PSa_ADAPTER_EXTENSION AdapterExtension)
16352 +{
16353 +       ULONG ReturnStatus;
16354 +       LARGE_INTEGER HostTime;
16355 +       ULONG ElapsedSeconds;
16356 +       PADAPTER_INIT_STRUCT InitStruct;
16357 +
16358 +       //
16359 +       // Fill in the remaining pieces of the InitStruct.
16360 +       //
16361 +
16362 +       InitStruct = AdapterExtension->Common->InitStruct;
16363 +
16364 +       InitStruct->HostPhysMemPages = AfaPortGetMaxPhysicalPage(AdapterExtension->Common);
16365 +
16366 +       ElapsedSeconds = OsGetSeconds();
16367 +
16368 +       InitStruct->HostElapsedSeconds = ElapsedSeconds;
16369 +
16370 +       //
16371 +       // Tell the adapter we are back and up and running so it will scan its command
16372 +       // queues and enable our interrupts
16373 +       //
16374 +
16375 +       AdapterExtension->LocalMaskInterruptControl =
16376 +               (PrintfReady | DOORBELL_1 | DOORBELL_2 | DOORBELL_3 | DOORBELL_4);
16377 +
16378 +
16379 +       //
16380 +       // First clear out all interrupts.  Then enable the one's that we can handle.
16381 +       //
16382 +
16383 +       Sa_WRITE_USHORT( AdapterExtension,  SaDbCSR.PRISETIRQMASK, (USHORT) 0xffff );
16384 +       Sa_WRITE_USHORT( AdapterExtension,  SaDbCSR.PRICLEARIRQMASK,
16385 +                                       (PrintfReady | DOORBELL_1 | DOORBELL_2 | DOORBELL_3 | DOORBELL_4) );
16386 +
16387 +       SaSendSynchCommand(AdapterExtension, 
16388 +                          INIT_STRUCT_BASE_ADDRESS, 
16389 +                          (ULONG) AdapterExtension->Common->PhysicalInitStruct,
16390 +                          0,
16391 +                          0,
16392 +                          0,
16393 +                          &ReturnStatus);
16394 +
16395 +}
16396 +
16397 +
16398 +VOID
16399 +SaResetDevice (PVOID Arg1){
16400 +
16401 +}
16402 +
16403 +
16404 +/*++
16405 +
16406 +Routine Description:
16407 +
16408 +       The will cause the adapter to take a break point.
16409 +
16410 +Arguments:
16411 +
16412 +       None
16413 +
16414 +Return Value:
16415 +
16416 +    Nothing
16417 +
16418 +--*/
16419 +VOID
16420 +SaInterruptAdapter (PVOID Arg1)
16421 +{
16422 +       PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
16423 +       PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) CommonExtension->MiniPort;
16424 +
16425 +       ULONG ReturnStatus;
16426 +
16427 +       SaSendSynchCommand(AdapterExtension, 
16428 +                          BREAKPOINT_REQUEST,
16429 +                          0,
16430 +                          0,
16431 +                          0,
16432 +                          0,
16433 +                          &ReturnStatus);
16434 +
16435 +}
16436 +
16437 +
16438 +/*++
16439 +
16440 +Routine Description:
16441 +
16442 +    Will read the adapter CSRs to find the reason the adapter has
16443 +    interrupted us.
16444 +
16445 +Arguments:
16446 +
16447 +    AdapterEvent - Enumerated type the returns the reason why we were interrutped.
16448 +
16449 +Return Value:
16450 +
16451 +    Nothing
16452 +
16453 +--*/
16454 +VOID
16455 +SaNotifyAdapter (PVOID Arg1, IN HOST_2_ADAP_EVENT AdapterEvent)
16456 +{
16457 +       PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
16458 +       PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) CommonExtension->MiniPort;
16459 +       ULONG ReturnStatus;
16460 +
16461 +    switch (AdapterEvent) {
16462 +        case AdapNormCmdQue:
16463 +
16464 +                       Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_1);
16465 +            break;
16466 +
16467 +        case HostNormRespNotFull:
16468 +
16469 +                       Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_4);
16470 +            break;
16471 +
16472 +        case AdapNormRespQue:
16473 +
16474 +                       Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_2);
16475 +            break;
16476 +
16477 +        case HostNormCmdNotFull:
16478 +
16479 +                       Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_3);
16480 +            break;
16481 +
16482 +        case HostShutdown:
16483 +
16484 +//                     SaSendSynchCommand(AdapterExtension, HOST_CRASHING, 0, 0, 0, 0, &ReturnStatus);
16485 +
16486 +            break;
16487 +
16488 +               case FastIo:
16489 +                       Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_6);
16490 +                       break;
16491 +
16492 +               case AdapPrintfDone:
16493 +                       Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_5);
16494 +                       break;
16495 +
16496 +        default:
16497 +
16498 +                       SaBugCheck(0,0,0);
16499 +            AfaPortPrint("Notify requested with an invalid request 0x%x.\n",AdapterEvent);
16500 +            break;
16501 +    }
16502 +}
16503 +
16504 +
16505 +/*++
16506 +
16507 +Routine Description:
16508 +
16509 +       This routine will send a synchronous comamnd to the adapter and wait for its
16510 +       completion.
16511 +
16512 +Arguments:
16513 +
16514 +       AdapterExtension - Pointer to adapter extension structure.
16515 +       Command - Which command to send
16516 +       Parameter1 - 4  - Parameters for command
16517 +       ReturnStatus - return status from adapter after completion of command
16518 +
16519 +
16520 +Return Value:
16521 +
16522 +       AAC_STATUS
16523 +
16524 +--*/
16525 +AAC_STATUS
16526 +SaSendSynchCommand(
16527 +                  PVOID Arg1,
16528 +                  ULONG Command,
16529 +                  ULONG Parameter1,
16530 +                  ULONG Parameter2,
16531 +                  ULONG Parameter3,
16532 +                  ULONG Parameter4,
16533 +                  PULONG       ReturnStatus
16534 +       )
16535 +{
16536 +       PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) Arg1;
16537 +       ULONG StartTime,EndTime,WaitTime;
16538 +       BOOLEAN CommandSucceeded;
16539 +
16540 +       //
16541 +       // Write the Command into Mailbox 0
16542 +       //
16543 +
16544 +       Sa_WRITE_ULONG( AdapterExtension, Mailbox0, Command);
16545 +
16546 +       //
16547 +       // Write the parameters into Mailboxes 1 - 4
16548 +       //
16549 +
16550 +       Sa_WRITE_ULONG( AdapterExtension, Mailbox1, Parameter1);
16551 +       Sa_WRITE_ULONG( AdapterExtension, Mailbox2, Parameter2);
16552 +       Sa_WRITE_ULONG( AdapterExtension, Mailbox3, Parameter3);
16553 +       Sa_WRITE_ULONG( AdapterExtension, Mailbox4, Parameter4);
16554 +
16555 +       //
16556 +       // Clear the synch command doorbell to start on a clean slate.
16557 +       //
16558 +               
16559 +       Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p, DOORBELL_0);
16560 +
16561 +       //
16562 +       // Signal that there is a new synch command
16563 +       //
16564 +
16565 +       Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s, DOORBELL_0);
16566 +
16567 +       CommandSucceeded = FALSE;
16568 +
16569 +       StartTime = OsGetSeconds();
16570 +       WaitTime = 0;
16571 +
16572 +       while (WaitTime < 30) { // wait up to 30 seconds
16573 +
16574 +               drv_usecwait(5);                                // delay 5 microseconds to let Mon960 get info.
16575 +
16576 +               //
16577 +               // Mon110 will set doorbell0 bit when it has completed the command.
16578 +               //
16579 +
16580 +               if( Sa_READ_USHORT( AdapterExtension, DoorbellReg_p) & DOORBELL_0 )  {
16581 +
16582 +                       CommandSucceeded = TRUE;
16583 +                       break;
16584 +               }
16585 +
16586 +               EndTime = OsGetSeconds();
16587 +               WaitTime = EndTime - StartTime;
16588 +
16589 +       }
16590 +
16591 +       if (CommandSucceeded != TRUE) {
16592 +
16593 +               return (STATUS_IO_TIMEOUT);
16594 +
16595 +       }
16596 +
16597 +       //
16598 +       // Clear the synch command doorbell.
16599 +       //
16600 +               
16601 +       Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p, DOORBELL_0);
16602 +
16603 +       //
16604 +       // Pull the synch status from Mailbox 0.
16605 +       //
16606 +
16607 +       *ReturnStatus = Sa_READ_ULONG( AdapterExtension, Mailbox0);
16608 +
16609 +       //
16610 +       // Return SUCCESS
16611 +       //
16612 +
16613 +       return (STATUS_SUCCESS);
16614 +
16615 +}
16616 +
16617 +
16618 +/*++
16619 +
16620 +Routine Description:
16621 +
16622 +       This routine will send a synchronous fib to the adapter and wait for its
16623 +       completion.
16624 +
16625 +Arguments:
16626 +
16627 +       AdapterExtension - Pointer to adapter extension structure.
16628 +       FibPhysicalAddress - Physical address of fib to send.
16629 +
16630 +
16631 +Return Value:
16632 +
16633 +       BOOLEAN
16634 +
16635 +--*/
16636 +BOOLEAN
16637 +SaSendSynchFib (PVOID Arg1, ULONG FibPhysicalAddress)
16638 +{
16639 +       PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
16640 +       PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) CommonExtension->MiniPort;
16641 +       ULONG returnStatus;
16642 +
16643 +       if (SaSendSynchCommand( AdapterExtension,
16644 +                                                   SEND_SYNCHRONOUS_FIB,
16645 +                                                   FibPhysicalAddress,
16646 +                                                   0,
16647 +                                                   0,
16648 +                                                   0,
16649 +                                                   &returnStatus ) != STATUS_SUCCESS ) {
16650 +
16651 +               return (FALSE);
16652 +               
16653 +       }
16654 +       
16655 +       return (TRUE);
16656 +                                                                               
16657 +}
16658 +
16659 +BOOLEAN
16660 +WriteFlash(
16661 +       PVOID AdapterExtension,
16662 +       ULONG *MappedBuffer)
16663 +{
16664 +       return (FALSE);
16665 +}
16666 +
16667 +BOOLEAN
16668 +ReadFlash(
16669 +       PVOID AdapterExtension,
16670 +       ULONG *MappedBuffer)
16671 +{
16672 +       return (FALSE);
16673 +}
16674 +
This page took 1.331667 seconds and 3 git commands to generate.