]> git.pld-linux.org Git - packages/kernel.git/blame - linux-2.4.7-aacraid-20010721.patch
- obsolete
[packages/kernel.git] / linux-2.4.7-aacraid-20010721.patch
CommitLineData
508c79f0 1diff -burN linux-2.4.7/MAINTAINERS linux/MAINTAINERS
2--- linux-2.4.7/MAINTAINERS Sun Jul 15 18:15:44 2001
3+++ linux/MAINTAINERS Sat Jul 21 17:55:13 2001
4@@ -119,6 +119,14 @@
5 W: http://www.uni-karlsruhe.de/~Robert.Siemer/Private/
6 S: Maintained
7
8+AACRAID SCSI RAID DRIVER
9+P: Adaptec OEM Raid Solutions
10+M: linux-aacraid-devel@dell.com
11+L: linux-aacraid-devel@dell.com
12+L: linux-aacraid-announce@dell.com
13+W: http://domsch.com/linux
14+S: Supported
15+
16 ACPI
17 P: Andy Grover
18 M: andrew.grover@intel.com
19diff -burN linux-2.4.7/arch/i386/defconfig linux/arch/i386/defconfig
20--- linux-2.4.7/arch/i386/defconfig Mon Jul 16 12:45:15 2001
21+++ linux/arch/i386/defconfig Sat Jul 21 17:55:13 2001
22@@ -284,6 +284,7 @@
23 # CONFIG_SCSI_AHA152X is not set
24 # CONFIG_SCSI_AHA1542 is not set
25 # CONFIG_SCSI_AHA1740 is not set
26+# CONFIG_SCSI_AACRAID is not set
27 # CONFIG_SCSI_AIC7XXX is not set
28 # CONFIG_SCSI_AIC7XXX_OLD is not set
29 # CONFIG_SCSI_ADVANSYS is not set
30diff -burN linux-2.4.7/drivers/scsi/Config.in linux/drivers/scsi/Config.in
31--- linux-2.4.7/drivers/scsi/Config.in Thu Jul 5 13:28:16 2001
32+++ linux/drivers/scsi/Config.in Sat Jul 21 17:55:13 2001
33@@ -50,6 +50,7 @@
34 dep_tristate 'Adaptec AHA152X/2825 support' CONFIG_SCSI_AHA152X $CONFIG_SCSI
35 dep_tristate 'Adaptec AHA1542 support' CONFIG_SCSI_AHA1542 $CONFIG_SCSI
36 dep_tristate 'Adaptec AHA1740 support' CONFIG_SCSI_AHA1740 $CONFIG_SCSI
37+dep_tristate 'Adaptec AACRAID support' CONFIG_SCSI_AACRAID $CONFIG_SCSI
38 source drivers/scsi/aic7xxx/Config.in
39 if [ "$CONFIG_SCSI_AIC7XXX" != "y" ]; then
40 dep_tristate 'Old Adaptec AIC7xxx support' CONFIG_SCSI_AIC7XXX_OLD $CONFIG_SCSI
41diff -burN linux-2.4.7/drivers/scsi/Makefile linux/drivers/scsi/Makefile
42--- linux-2.4.7/drivers/scsi/Makefile Fri May 4 17:16:28 2001
43+++ linux/drivers/scsi/Makefile Sat Jul 21 17:55:13 2001
44@@ -70,6 +70,7 @@
45 obj-$(CONFIG_SCSI_AHA152X) += aha152x.o
46 obj-$(CONFIG_SCSI_AHA1542) += aha1542.o
47 obj-$(CONFIG_SCSI_AHA1740) += aha1740.o
48+obj-$(CONFIG_SCSI_AACRAID) += aacraid.o
49 ifeq ($(CONFIG_SCSI_AIC7XXX),y)
50 obj-$(CONFIG_SCSI_AIC7XXX) += aic7xxx/aic7xxx_drv.o
51 endif
52@@ -193,3 +194,7 @@
53 sim710_u.h: sim710_d.h
54
55 sim710.o : sim710_d.h
56+
57+aacraid.o:
58+ cd aacraid; make
59+
60diff -burN linux-2.4.7/drivers/scsi/aacraid/ChangeLog linux/drivers/scsi/aacraid/ChangeLog
61--- linux-2.4.7/drivers/scsi/aacraid/ChangeLog Wed Dec 31 18:00:00 1969
62+++ linux/drivers/scsi/aacraid/ChangeLog Sat Jul 21 17:55:51 2001
63@@ -0,0 +1,17 @@
64+2001-07-21 Matt Domsch <Matt_Domsch@dell.com>
65+* changed __SMP__ to CONFIG_SMP everywhere (really this time)
66+* Applied read capacity patch
67+* released patch against 2.4.6
68+* released patch against 2.4.7
69+
70+2001-07-04 Matt Domsch <Matt_Domsch@dell.com>
71+* Started with linux-2.4.5-aacraid-043001.patch
72+* Applied Chris Pascoe's SMP fix patch
73+* Released patch against 2.4.6
74+
75+
76+2001-04-30 Matt Domsch <Matt_Domsch@dell.com>
77+* Started with linux-2.4.3-aacraid-030101.patch
78+* Applied against 2.4.4.
79+* Added scsi_set_pci_device() call in linit.c
80+
81diff -burN linux-2.4.7/drivers/scsi/aacraid/Makefile linux/drivers/scsi/aacraid/Makefile
82--- linux-2.4.7/drivers/scsi/aacraid/Makefile Wed Dec 31 18:00:00 1969
83+++ linux/drivers/scsi/aacraid/Makefile Sat Jul 21 17:55:13 2001
84@@ -0,0 +1,169 @@
85+#
86+# Makefile aacraid Raid Controller
87+#
88+
89+###############################################################################
90+### SOURCE FILES DEFINES
91+###############################################################################
92+
93+CFILES_DRIVER=\
94+ ./aachba.c \
95+ ./aacid.c \
96+ ./commctrl.c \
97+ ./comminit.c \
98+ ./commsup.c \
99+ ./dpcsup.c \
100+ ./linit.c \
101+ ./osddi.c \
102+ ./osfuncs.c \
103+ ./ossup.c \
104+ ./port.c \
105+ ./rx.c \
106+ ./sap1sup.c
107+
108+IFILES_DRIVER=\
109+ ./include/AacGenericTypes.h \
110+ ./include/aac_unix_defs.h \
111+ ./include/adapter.h \
112+ ./include/afacomm.h \
113+ ./include/aifstruc.h \
114+ ./include/build_number.h \
115+ ./include/commdata.h \
116+ ./include/commerr.h \
117+ ./include/commfibcontext.h \
118+ ./include/comprocs.h \
119+ ./include/comproto.h \
120+ ./include/comstruc.h \
121+ ./include/comsup.h \
122+ ./include/fsact.h \
123+ ./include/fsafs.h \
124+ ./include/fsaioctl.h \
125+ ./include/fsaport.h \
126+ ./include/fsatypes.h \
127+ ./include/linit.h \
128+ ./include/monkerapi.h \
129+ ./include/nodetype.h \
130+ ./include/nvramioctl.h \
131+ ./include/osheaders.h \
132+ ./include/ostypes.h \
133+ ./include/pcisup.h \
134+ ./include/perfpack.h \
135+ ./include/port.h \
136+ ./include/protocol.h \
137+ ./include/revision.h \
138+ ./include/rxcommon.h \
139+ ./include/rx.h \
140+ ./include/sap1common.h \
141+ ./include/sap1.h \
142+ ./include/version.h
143+
144+ALL_SOURCE=\
145+ ${CFILES_DRIVER} \
146+ ${IFILES_DRIVER}
147+
148+###############################################################################
149+### OBJECT FILES DEFINES
150+###############################################################################
151+
152+
153+OFILES_DRIVER=\
154+ linit.o \
155+ osfuncs.o \
156+ osddi.o \
157+ aachba.o \
158+ commctrl.o \
159+ comminit.o \
160+ commsup.o \
161+ dpcsup.o \
162+ ossup.o \
163+ port.o \
164+ rx.o \
165+ sap1sup.o
166+
167+TARGET_OFILES= ${OFILES_DRIVER} aacid.o
168+
169+###############################################################################
170+### GENERAL DEFINES
171+###############################################################################
172+
173+# Remember that we're doing a chdir one level lower, so we need an extra ../
174+INCS= \
175+ -I./include \
176+ -I../../../include -I..
177+
178+WARNINGS= -w -Wall -Wno-unused -Wno-switch -Wno-missing-prototypes -Wno-implicit
179+
180+
181+COMMON_FLAGS=\
182+ -D__KERNEL__=1 -DUNIX -DCVLOCK_USE_SPINLOCK -DLINUX \
183+ ${INCS} \
184+ ${WARNINGS}
185+
186+AACFLAGS=${CFLAGS} ${COMMON_FLAGS} ${EXTRA_FLAGS}
187+
188+###############################################################################
189+### DO GENERAL STUFF
190+###############################################################################
191+
192+.SUFFIXES:
193+.SUFFIXES: .c .o .h .a
194+
195+all: source ${TARGET_OFILES} aacraid.o
196+
197+source: ${ALL_SOURCE}
198+
199+clean:
200+ rm *.o
201+
202+###############################################################################
203+### DRIVER LINKS
204+###############################################################################
205+
206+aacraid.o: source ${TARGET_OFILES}
207+ ld -r -o $@ $(TARGET_OFILES)
208+ cp -r aacraid.o ../
209+
210+###############################################################################
211+### SIMPLE COMPILES
212+###############################################################################
213+
214+linit.o: ./linit.c
215+ $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o linit.o ./linit.c
216+
217+aachba.o: ./aachba.c
218+ $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o aachba.o ./aachba.c
219+
220+osddi.o: ./osddi.c
221+ $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o osddi.o ./osddi.c
222+
223+osfuncs.o: ./osfuncs.c
224+ $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o osfuncs.o ./osfuncs.c
225+
226+commctrl.o: ./commctrl.c
227+ $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o commctrl.o ./commctrl.c
228+
229+comminit.o: ./comminit.c
230+ $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o comminit.o ./comminit.c
231+
232+commsup.o: ./commsup.c
233+ $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o commsup.o ./commsup.c
234+
235+dpcsup.o: ./dpcsup.c
236+ $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o dpcsup.o ./dpcsup.c
237+
238+aacid.o: ./aacid.c
239+ $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o aacid.o ./aacid.c
240+
241+port.o: ./port.c
242+ $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o port.o ./port.c
243+
244+ossup.o: ./ossup.c
245+ $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o ossup.o ./ossup.c
246+
247+rx.o: ./rx.c
248+ $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o rx.o ./rx.c
249+
250+sap1sup.o: ./sap1sup.c
251+ $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o sap1sup.o ./sap1sup.c
252+
253+
254diff -burN linux-2.4.7/drivers/scsi/aacraid/README linux/drivers/scsi/aacraid/README
255--- linux-2.4.7/drivers/scsi/aacraid/README Wed Dec 31 18:00:00 1969
256+++ linux/drivers/scsi/aacraid/README Sat Jul 21 17:55:13 2001
257@@ -0,0 +1,46 @@
258+ AACRAID Driver for Linux
259+
260+Introduction
261+-------------------------
262+The aacraid driver adds support for Adaptec (http://www.adaptec.com)
263+OEM based RAID controllers.
264+
265+It is important to note the amount of test time the 2.4.x driver
266+received. Though not a great deal has changed between 2.2 and 2.4
267+for this version, it has not recevied a great deal of test time.
268+
269+A new driver version is in the works and that version will be
270+submitted to the standard distribution kernel. The previous
271+2.2 version was submitted but rejected due to the large
272+amount of code reduncdancy and NTisms. This driver was
273+initially ported from NT to Solaris and then to Linux.
274+
275+The new version is being written on Unix for Unix and
276+should be much easier to read and a great deal cleaner.
277+
278+Supported Cards/Chipsets
279+-------------------------
280+ Dell Computer Corporation PERC 2 Quad Channel
281+ Dell Computer Corporation PERC 2/Si
282+ Dell Computer Corporation PERC 3/Si
283+ Dell Computer Corporation PERC 3/Di
284+ HP NetRAID-4M
285+
286+Not Supported Devices
287+-------------------------
288+ Any and All Adaptec branded raid controllers.
289+
290+People
291+-------------------------
292+ Adaptec Unix OEM Product Group
293+
294+Mailing List
295+-------------------------
296+please see http://domsch.com/linux for information
297+on mailing lists. There is both a development and
298+an announcment list. Due to the overwhelming amount
299+of mail I receive about this driver, I can not
300+answer questions individually and requests should
301+be directed to the list server. Thanks.
302+
303+Modified by Brian Boerner February 2001
304diff -burN linux-2.4.7/drivers/scsi/aacraid/aachba.c linux/drivers/scsi/aacraid/aachba.c
305--- linux-2.4.7/drivers/scsi/aacraid/aachba.c Wed Dec 31 18:00:00 1969
306+++ linux/drivers/scsi/aacraid/aachba.c Sat Jul 21 17:55:13 2001
307@@ -0,0 +1,1897 @@
308+/*++
309+ * Adaptec aacraid device driver for Linux.
310+ *
311+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
312+ *
313+ * This program is free software; you can redistribute it and/or modify
314+ * it under the terms of the GNU General Public License as published by
315+ * the Free Software Foundation; either version 2, or (at your option)
316+ * any later version.
317+ *
318+ * This program is distributed in the hope that it will be useful,
319+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
320+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
321+ * GNU General Public License for more details.
322+ *
323+ * You should have received a copy of the GNU General Public License
324+ * along with this program; see the file COPYING. If not, write to
325+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
326+ *
327+ * Module Name:
328+ * aachba.c
329+ *
330+ * Abstract: driver...
331+ *
332+--*/
333+
334+static char *ident_aachba = "aacraid_ident aachba.c 1.0.6 2000/10/09 Adaptec, Inc.";
335+
336+/*------------------------------------------------------------------------------
337+ * I N C L U D E S
338+ *----------------------------------------------------------------------------*/
339+#include "osheaders.h"
340+#include "AacGenericTypes.h"
341+#include "aac_unix_defs.h"
342+#include "comstruc.h"
343+#include "monkerapi.h"
344+#include "protocol.h"
345+#include "fsafs.h"
346+#include "fsact.h"
347+#include "fsaioctl.h"
348+
349+#include "sap1common.h"
350+#include "fsaport.h"
351+#include "pcisup.h"
352+#include "sap1.h"
353+#include "nodetype.h"
354+#include "comsup.h"
355+#include "afacomm.h"
356+#include "adapter.h"
357+
358+/*------------------------------------------------------------------------------
359+ * D E F I N E S
360+ *----------------------------------------------------------------------------*/
361+/* SCSI Commands */
362+#define SS_TEST 0x00 /* Test unit ready */
363+#define SS_REZERO 0x01 /* Rezero unit */
364+#define SS_REQSEN 0x03 /* Request Sense */
365+#define SS_REASGN 0x07 /* Reassign blocks */
366+#define SS_READ 0x08 /* Read 6 */
367+#define SS_WRITE 0x0A /* Write 6 */
368+#define SS_INQUIR 0x12 /* inquiry */
369+#define SS_ST_SP 0x1B /* Start/Stop unit */
370+#define SS_LOCK 0x1E /* prevent/allow medium removal */
371+#define SS_RESERV 0x16 /* Reserve */
372+#define SS_RELES 0x17 /* Release */
373+#define SS_MODESEN 0x1A /* Mode Sense 6 */
374+#define SS_RDCAP 0x25 /* Read Capacity */
375+#define SM_READ 0x28 /* Read 10 */
376+#define SM_WRITE 0x2A /* Write 10 */
377+#define SS_SEEK 0x2B /* Seek */
378+
379+/* values for inqd_pdt: Peripheral device type in plain English */
380+#define INQD_PDT_DA 0x00 /* Direct-access (DISK) device */
381+#define INQD_PDT_PROC 0x03 /* Processor device */
382+#define INQD_PDT_CHNGR 0x08 /* Changer (jukebox, scsi2) */
383+#define INQD_PDT_COMM 0x09 /* Communication device (scsi2) */
384+#define INQD_PDT_NOLUN2 0x1f /* Unknown Device (scsi2) */
385+#define INQD_PDT_NOLUN 0x7f /* Logical Unit Not Present */
386+
387+#define INQD_PDT_DMASK 0x1F /* Peripheral Device Type Mask */
388+#define INQD_PDT_QMASK 0xE0 /* Peripheral Device Qualifer Mask */
389+
390+#define TARGET_LUN_TO_CONTAINER(Target, Lun) (((Lun) << 4) | Target)
391+#define CONTAINER_TO_TARGET(Container) ((Container) & 0xf)
392+#define CONTAINER_TO_LUN(Container) ((Container) >> 4)
393+
394+#define MAX_FIB_DATA (sizeof(FIB) - sizeof(FIB_HEADER))
395+
396+#define MAX_DRIVER_SG_SEGMENT_COUNT 17
397+
398+// ------------------------------------------------------
399+// Sense keys
400+//
401+#define SENKEY_NO_SENSE 0x00 //
402+#define SENKEY_UNDEFINED 0x01 //
403+#define SENKEY_NOT_READY 0x02 //
404+#define SENKEY_MEDIUM_ERR 0x03 //
405+#define SENKEY_HW_ERR 0x04 //
406+#define SENKEY_ILLEGAL 0x05 //
407+#define SENKEY_ATTENTION 0x06 //
408+#define SENKEY_PROTECTED 0x07 //
409+#define SENKEY_BLANK 0x08 //
410+#define SENKEY_V_UNIQUE 0x09 //
411+#define SENKEY_CPY_ABORT 0x0A //
412+#define SENKEY_ABORT 0x0B //
413+#define SENKEY_EQUAL 0x0C //
414+#define SENKEY_VOL_OVERFLOW 0x0D //
415+#define SENKEY_MISCOMP 0x0E //
416+#define SENKEY_RESERVED 0x0F //
417+
418+// ------------------------------------------------------
419+// Sense codes
420+//
421+#define SENCODE_NO_SENSE 0x00
422+#define SENCODE_END_OF_DATA 0x00
423+#define SENCODE_BECOMING_READY 0x04
424+#define SENCODE_INIT_CMD_REQUIRED 0x04
425+#define SENCODE_PARAM_LIST_LENGTH_ERROR 0x1A
426+#define SENCODE_INVALID_COMMAND 0x20
427+#define SENCODE_LBA_OUT_OF_RANGE 0x21
428+#define SENCODE_INVALID_CDB_FIELD 0x24
429+#define SENCODE_LUN_NOT_SUPPORTED 0x25
430+#define SENCODE_INVALID_PARAM_FIELD 0x26
431+#define SENCODE_PARAM_NOT_SUPPORTED 0x26
432+#define SENCODE_PARAM_VALUE_INVALID 0x26
433+#define SENCODE_RESET_OCCURRED 0x29
434+#define SENCODE_LUN_NOT_SELF_CONFIGURED_YET 0x3E
435+#define SENCODE_INQUIRY_DATA_CHANGED 0x3F
436+#define SENCODE_SAVING_PARAMS_NOT_SUPPORTED 0x39
437+#define SENCODE_DIAGNOSTIC_FAILURE 0x40
438+#define SENCODE_INTERNAL_TARGET_FAILURE 0x44
439+#define SENCODE_INVALID_MESSAGE_ERROR 0x49
440+#define SENCODE_LUN_FAILED_SELF_CONFIG 0x4c
441+#define SENCODE_OVERLAPPED_COMMAND 0x4E
442+
443+// ------------------------------------------------------
444+// Additional sense codes
445+//
446+#define ASENCODE_NO_SENSE 0x00
447+#define ASENCODE_END_OF_DATA 0x05
448+#define ASENCODE_BECOMING_READY 0x01
449+#define ASENCODE_INIT_CMD_REQUIRED 0x02
450+#define ASENCODE_PARAM_LIST_LENGTH_ERROR 0x00
451+#define ASENCODE_INVALID_COMMAND 0x00
452+#define ASENCODE_LBA_OUT_OF_RANGE 0x00
453+#define ASENCODE_INVALID_CDB_FIELD 0x00
454+#define ASENCODE_LUN_NOT_SUPPORTED 0x00
455+#define ASENCODE_INVALID_PARAM_FIELD 0x00
456+#define ASENCODE_PARAM_NOT_SUPPORTED 0x01
457+#define ASENCODE_PARAM_VALUE_INVALID 0x02
458+#define ASENCODE_RESET_OCCURRED 0x00
459+#define ASENCODE_LUN_NOT_SELF_CONFIGURED_YET 0x00
460+#define ASENCODE_INQUIRY_DATA_CHANGED 0x03
461+#define ASENCODE_SAVING_PARAMS_NOT_SUPPORTED 0x00
462+#define ASENCODE_DIAGNOSTIC_FAILURE 0x80
463+#define ASENCODE_INTERNAL_TARGET_FAILURE 0x00
464+#define ASENCODE_INVALID_MESSAGE_ERROR 0x00
465+#define ASENCODE_LUN_FAILED_SELF_CONFIG 0x00
466+#define ASENCODE_OVERLAPPED_COMMAND 0x00
467+
468+#define BYTE0( x ) ( unsigned char )( x )
469+#define BYTE1( x ) ( unsigned char )( x >> 8 )
470+#define BYTE2( x ) ( unsigned char )( x >> 16 )
471+#define BYTE3( x ) ( unsigned char )( x >> 24 )
472+
473+/*------------------------------------------------------------------------------
474+ * S T R U C T S / T Y P E D E F S
475+ *----------------------------------------------------------------------------*/
476+/* SCSI inquiry data */
477+struct inquiry_data {
478+ unchar inqd_pdt; /* Peripheral qualifier | Peripheral Device Type */
479+ unchar inqd_dtq; /* RMB | Device Type Qualifier */
480+ unchar inqd_ver; /* ISO version | ECMA version | ANSI-approved version */
481+ unchar inqd_rdf; /* AENC | TrmIOP | Response data format */
482+ unchar inqd_len; /* Additional length (n-4) */
483+ unchar inqd_pad1[2]; /* Reserved - must be zero */
484+ unchar inqd_pad2; /* RelAdr | WBus32 | WBus16 | Sync | Linked |Reserved| CmdQue | SftRe */
485+ unchar inqd_vid[8]; /* Vendor ID */
486+ unchar inqd_pid[16]; /* Product ID */
487+ unchar inqd_prl[4]; /* Product Revision Level */
488+};
489+
490+struct sense_data {
491+ unchar error_code; // 70h (current errors), 71h(deferred errors)
492+ unchar valid:1; // A valid bit of one indicates that the information
493+ // field contains valid information as defined in the
494+ // SCSI-2 Standard.
495+
496+ unchar segment_number; // Only used for COPY, COMPARE, or COPY AND VERIFY
497+ // commands
498+
499+ unchar sense_key:4; // Sense Key
500+ unchar reserved:1;
501+ unchar ILI:1; // Incorrect Length Indicator
502+ unchar EOM:1; // End Of Medium - reserved for random access devices
503+ unchar filemark:1; // Filemark - reserved for random access devices
504+
505+ unchar information[4]; // for direct-access devices, contains the unsigned
506+ // logical block address or residue associated with
507+ // the sense key
508+ unchar add_sense_len; // number of additional sense bytes to follow this field
509+ unchar cmnd_info[4]; // not used
510+ unchar ASC; // Additional Sense Code
511+ unchar ASCQ; // Additional Sense Code Qualifier
512+ unchar FRUC; // Field Replaceable Unit Code - not used
513+
514+ unchar bit_ptr:3; // indicates which byte of the CDB or parameter data
515+ // was in error
516+ unchar BPV:1; // bit pointer valid (BPV): 1- indicates that
517+ // the bit_ptr field has valid value
518+ unchar reserved2:2;
519+ unchar CD:1; // command data bit: 1- illegal parameter in CDB.
520+ // 0- illegal parameter in data.
521+ unchar SKSV:1;
522+
523+ unchar field_ptr[2]; // byte of the CDB or parameter data in error
524+};
525+
526+/*------------------------------------------------------------------------------
527+ * G L O B A L S
528+ *----------------------------------------------------------------------------*/
529+/*------------------------------------------------------------------------------
530+ * M O D U L E G L O B A L S
531+ *----------------------------------------------------------------------------*/
532+static fsadev_t *g_fsa_dev_array[8]; // SCSI Device Instance Pointers
533+static struct sense_data g_sense_data[MAXIMUM_NUM_CONTAINERS];
534+
535+/*------------------------------------------------------------------------------
536+ * F U N C T I O N P R O T O T Y P E S
537+ *----------------------------------------------------------------------------*/
538+AAC_STATUS AacHba_OpenAdapter( PVOID AdapterArg);
539+AAC_STATUS AacHba_CloseAdapter( PVOID AdapterArg);
540+BOOLEAN AacHba_HandleAif( PVOID AdapterArg, PFIB_CONTEXT FibContext);
541+BOOLEAN AacHba_AdapterDeviceControl ( PVOID AdapterArg,
542+ PAFA_IOCTL_CMD IoctlCmdPtr, int * ReturnStatus);
543+
544+void AacHba_CompleteScsi(
545+ Scsi_Cmnd *scsi_cmnd_ptr );
546+
547+void AacHba_CompleteScsiNoLock(
548+ Scsi_Cmnd *scsi_cmnd_ptr );
549+
550+static void AacHba_ReadCallback(
551+ void *Context,
552+ PFIB_CONTEXT FibContext,
553+ int FibStatus );
554+
555+static void AacHba_WriteCallback(
556+ void *Context,
557+ PFIB_CONTEXT FibContext,
558+ int FibStatus );
559+
560+int AacHba_DoScsiRead(
561+ Scsi_Cmnd *scsi_cmnd_ptr,
562+ int ContainerId,
563+ int wait );
564+
565+int AacHba_DoScsiWrite(
566+ Scsi_Cmnd *scsi_cmnd_ptr,
567+ int ContainerId,
568+ int wait );
569+
570+int AacHba_QueryDisk(
571+ PVOID AdapterArg, // CommonExtensionPtr
572+ IN PAFA_IOCTL_CMD IoctlCmdPtr );
573+
574+int AacHba_ForceDeleteDisk(
575+ PVOID AdapterArg, // CommonExtensionPtr
576+ IN PAFA_IOCTL_CMD IoctlCmdPtr );
577+
578+int AacHba_DeleteDisk(
579+ PVOID AdapterArg,
580+ IN PAFA_IOCTL_CMD IoctlCmdPtr );
581+
582+void AacHba_DetachAdapter(
583+ IN PVOID AdapterArg );
584+
585+BOOLEAN AacCommDetachAdapter(
586+ IN PAFA_COMM_ADAPTER Adapter );
587+
588+void AacHba_SetSenseData(
589+ char * sense_buf,
590+ unchar sense_key,
591+ unchar sense_code,
592+ unchar a_sense_code,
593+ unchar incorrect_length,
594+ unchar bit_pointer,
595+ unsigned field_pointer,
596+ unsigned long residue );
597+
598+static void get_sd_devname(
599+ long disknum,
600+ char * buffer);
601+
602+// Keep these here for the time being - #REVIEW#
603+int
604+AfaCommAdapterDeviceControl (
605+ IN PVOID AdapterArg,
606+ IN PAFA_IOCTL_CMD IoctlCmdPtr
607+ );
608+
609+AAC_STATUS
610+AfaCommRegisterNewClassDriver(
611+ IN PAFA_COMM_ADAPTER Adapter,
612+ IN PAFA_NEW_CLASS_DRIVER NewClassDriver,
613+ OUT PAFA_NEW_CLASS_DRIVER_RESPONSE NewClassDriverResponse
614+ );
615+
616+void
617+SetInqDataStr (int, void *, int);
618+/*------------------------------------------------------------------------------
619+ * F U N C T I O N S
620+ *----------------------------------------------------------------------------*/
621+
622+/*------------------------------------------------------------------------------
623+ AacHba_ClassDriverInit()
624+
625+ Setup 'core' class driver to answer ioctl's
626+ *----------------------------------------------------------------------------*/
627+int AacHba_ClassDriverInit(
628+ PCI_MINIPORT_COMMON_EXTENSION * CommonExtensionPtr)
629+/*----------------------------------------------------------------------------*/
630+{
631+ AFA_NEW_CLASS_DRIVER NewClassDriver;
632+ AFA_NEW_CLASS_DRIVER_RESPONSE NewClassDriverResponse;
633+ PAFA_COMM_ADAPTER Adapter;
634+
635+ Adapter = (AFA_COMM_ADAPTER *)CommonExtensionPtr->Adapter;
636+
637+ RtlZeroMemory( &NewClassDriver, sizeof( AFA_NEW_CLASS_DRIVER ) );
638+
639+ // ClassDriverExtension is the first argument passed to class driver functions below
640+ NewClassDriver.ClassDriverExtension = CommonExtensionPtr;
641+
642+ NewClassDriver.OpenAdapter = AacHba_OpenAdapter;
643+ NewClassDriver.CloseAdapter = AacHba_CloseAdapter;
644+ NewClassDriver.DeviceControl = AacHba_AdapterDeviceControl;
645+ NewClassDriver.HandleAif = AacHba_HandleAif;
646+ AfaCommRegisterNewClassDriver( Adapter, &NewClassDriver, &NewClassDriverResponse );
647+
648+ return(0);
649+}
650+
651+
652+/*------------------------------------------------------------------------------
653+ AacHba_ProbeContainers()
654+
655+ Make a list of all containers in the system.
656+------------------------------------------------------------------------------*/
657+int AacHba_ProbeContainers (PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr)
658+{
659+ fsadev_t *fsa_dev_ptr;
660+ int Index, Status;
661+ PMNTINFO DiskInfo;
662+ PMNTINFORESPONSE DiskInfoResponse;
663+ PFIB_CONTEXT FibContext;
664+ AFA_COMM_ADAPTER *Adapter;
665+ unsigned instance;
666+ char *bufp;
667+ int size;
668+
669+
670+ Adapter = ( AFA_COMM_ADAPTER * )CommonExtensionPtr->Adapter;
671+ fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
672+ instance = CommonExtensionPtr->OsDep.scsi_host_ptr->unique_id;
673+
674+ if( !( FibContext = Adapter->CommFuncs.AllocateFib( Adapter ) ) )
675+ {
676+ cmn_err( CE_WARN, "AacHba_ProbeContainers: AllocateFib failed" );
677+ return( STATUS_UNSUCCESSFUL );
678+ }
679+
680+ for ( Index = 0; Index < MAXIMUM_NUM_CONTAINERS; Index++ )
681+ {
682+ Adapter->CommFuncs.InitializeFib( FibContext );
683+
684+ DiskInfo = ( PMNTINFO )Adapter->CommFuncs.GetFibData( FibContext );
685+
686+ DiskInfo->Command = VM_NameServe;
687+ DiskInfo->MntCount = Index;
688+ DiskInfo->MntType = FT_FILESYS;
689+
690+ Status = Adapter->CommFuncs.SendFib( ContainerCommand,
691+ FibContext,
692+ sizeof(MNTINFO),
693+ FsaNormal,
694+ TRUE,
695+ NULL,
696+ TRUE,
697+ NULL,
698+ NULL );
699+ if ( Status )
700+ {
701+ cmn_err( CE_WARN, "ProbeContainers: SendFIb Failed" );
702+ break;
703+ }
704+
705+ DiskInfoResponse = ( PMNTINFORESPONSE )Adapter->CommFuncs.GetFibData( FibContext );
706+
707+
708+ if ( ( DiskInfoResponse->Status == ST_OK ) &&
709+ ( DiskInfoResponse->MntTable[0].VolType != CT_NONE ) )
710+ {
711+
712+
713+ fsa_dev_ptr->ContainerValid[Index] = TRUE;
714+ fsa_dev_ptr->ContainerType[Index] = DiskInfoResponse->MntTable[0].VolType;
715+ fsa_dev_ptr->ContainerSize[Index] = DiskInfoResponse->MntTable[0].Capacity;
716+
717+ if (DiskInfoResponse->MntTable[0].ContentState & FSCS_READONLY)
718+ fsa_dev_ptr->ContainerReadOnly[Index] = TRUE;
719+ }
720+
721+ Adapter->CommFuncs.CompleteFib( FibContext );
722+
723+ // If there are no more containers, then stop asking.
724+ if ((Index + 1) >= DiskInfoResponse->MntRespCount)
725+ break;
726+ } // end for()
727+
728+ Adapter->CommFuncs.FreeFib( FibContext );
729+
730+ g_fsa_dev_array[instance] = fsa_dev_ptr;
731+ return( Status );
732+}
733+
734+
735+/*------------------------------------------------------------------------------
736+ AacHba_ProbeContainer()
737+
738+ Probe a single container.
739+ *----------------------------------------------------------------------------*/
740+int AacHba_ProbeContainer(
741+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr,
742+ int ContainerId )
743+/*----------------------------------------------------------------------------*/
744+{
745+ fsadev_t *fsa_dev_ptr;
746+ int Status;
747+ PMNTINFO DiskInfo;
748+ PMNTINFORESPONSE DiskInfoResponse;
749+ PFIB_CONTEXT FibContext;
750+ AFA_COMM_ADAPTER *Adapter;
751+ unsigned instance;
752+
753+ Adapter = ( AFA_COMM_ADAPTER * )CommonExtensionPtr->Adapter;
754+ fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
755+ instance = CommonExtensionPtr->OsDep.scsi_host_ptr->unique_id;
756+
757+ if( !( FibContext = Adapter->CommFuncs.AllocateFib( Adapter ) ) )
758+ {
759+ cmn_err( CE_WARN, "AacHba_ProbeContainers: AllocateFib failed" );
760+ return( STATUS_UNSUCCESSFUL );
761+ }
762+
763+ Adapter->CommFuncs.InitializeFib( FibContext );
764+
765+ DiskInfo = ( PMNTINFO )Adapter->CommFuncs.GetFibData( FibContext );
766+
767+ DiskInfo->Command = VM_NameServe;
768+ DiskInfo->MntCount = ContainerId;
769+ DiskInfo->MntType = FT_FILESYS;
770+
771+ Status = Adapter->CommFuncs.SendFib (ContainerCommand,
772+ FibContext,
773+ sizeof(MNTINFO),
774+ FsaNormal,
775+ TRUE,
776+ NULL,
777+ TRUE,
778+ NULL,
779+ NULL );
780+ if ( Status )
781+ {
782+ cmn_err( CE_WARN, "ProbeContainers: SendFIb Failed" );
783+ Adapter->CommFuncs.CompleteFib( FibContext );
784+ Adapter->CommFuncs.FreeFib( FibContext );
785+ return( Status );
786+ }
787+
788+ DiskInfoResponse = ( PMNTINFORESPONSE )Adapter->CommFuncs.GetFibData( FibContext );
789+
790+
791+ if ( ( DiskInfoResponse->Status == ST_OK ) &&
792+ ( DiskInfoResponse->MntTable[0].VolType != CT_NONE ) )
793+ {
794+
795+ fsa_dev_ptr->ContainerValid[ContainerId] = TRUE;
796+ fsa_dev_ptr->ContainerType[ContainerId] = DiskInfoResponse->MntTable[0].VolType;
797+ fsa_dev_ptr->ContainerSize[ContainerId] = DiskInfoResponse->MntTable[0].Capacity;
798+ if (DiskInfoResponse->MntTable[0].ContentState & FSCS_READONLY)
799+ fsa_dev_ptr->ContainerReadOnly[ContainerId] = TRUE;
800+ }
801+
802+ Adapter->CommFuncs.CompleteFib( FibContext );
803+ Adapter->CommFuncs.FreeFib( FibContext );
804+
805+ return( Status );
806+}
807+
808+
809+/*------------------------------------------------------------------------------
810+ AacHba_CompleteScsi()
811+
812+ Call SCSI completion routine after acquiring io_request_lock
813+
814+ Preconditions:
815+ Postconditions:
816+ *----------------------------------------------------------------------------*/
817+void AacHba_CompleteScsi(
818+ Scsi_Cmnd *scsi_cmnd_ptr )
819+{
820+ unsigned long cpu_flags;
821+
822+ spin_lock_irqsave( &io_request_lock, cpu_flags );
823+ scsi_cmnd_ptr->scsi_done( scsi_cmnd_ptr );
824+ spin_unlock_irqrestore( &io_request_lock, cpu_flags );
825+}
826+
827+
828+/*------------------------------------------------------------------------------
829+ AacHba_CompleteScsiNoLock()
830+
831+ Call SCSI completion routine
832+
833+ Preconditions:
834+ Postconditions:
835+ *----------------------------------------------------------------------------*/
836+void AacHba_CompleteScsiNoLock(
837+ Scsi_Cmnd *scsi_cmnd_ptr )
838+{
839+ scsi_cmnd_ptr->scsi_done( scsi_cmnd_ptr );
840+}
841+
842+/*------------------------------------------------------------------------------
843+ AacHba_DoScsiCmd()
844+
845+ Process SCSI command
846+
847+ Preconditions:
848+ Postconditions:
849+ Returns 0 on success, -1 on failure
850+ *----------------------------------------------------------------------------*/
851+int AacHba_DoScsiCmd(
852+ Scsi_Cmnd *scsi_cmnd_ptr,
853+ int wait )
854+{
855+ int ContainerId = 0;
856+ fsadev_t *fsa_dev_ptr;
857+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
858+ int MiniPortIndex;
859+
860+ CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
861+ MiniPortIndex = CommonExtensionPtr->OsDep.MiniPortIndex;
862+
863+ fsa_dev_ptr = g_fsa_dev_array[ scsi_cmnd_ptr->host->unique_id ];
864+
865+ // If the bus, target or lun is out of range, return fail
866+ // Test does not apply to ID 16, the pseudo id for the controller itself.
867+ if ( scsi_cmnd_ptr->target != scsi_cmnd_ptr->host->this_id )
868+ {
869+ if( ( scsi_cmnd_ptr->channel > 0 ) ||
870+ ( scsi_cmnd_ptr->target > 15 ) ||
871+ ( scsi_cmnd_ptr->lun > 7 ) )
872+ {
873+ cmn_err( CE_DEBUG, "The bus, target or lun is out of range = %d, %d, %d",
874+ scsi_cmnd_ptr->channel,
875+ scsi_cmnd_ptr->target,
876+ scsi_cmnd_ptr->lun );
877+ scsi_cmnd_ptr->result = DID_BAD_TARGET << 16;
878+
879+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
880+
881+ return ( -1 );
882+ }
883+
884+ ContainerId = TARGET_LUN_TO_CONTAINER( scsi_cmnd_ptr->target, scsi_cmnd_ptr->lun );
885+
886+
887+ // If the target container doesn't exist, it may have been newly created
888+ if( fsa_dev_ptr->ContainerValid[ContainerId] == 0 )
889+ {
890+ switch( scsi_cmnd_ptr->cmnd[0] )
891+ {
892+ case SS_INQUIR:
893+ case SS_RDCAP:
894+ case SS_TEST:
895+ spin_unlock_irq( &io_request_lock );
896+ AacHba_ProbeContainer( CommonExtensionPtr, ContainerId );
897+ spin_lock_irq( &io_request_lock );
898+ default:
899+ break;
900+ }
901+ }
902+
903+ // If the target container still doesn't exist, return failure
904+ if( fsa_dev_ptr->ContainerValid[ContainerId] == 0 )
905+ {
906+
907+ scsi_cmnd_ptr->result = DID_BAD_TARGET << 16;
908+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
909+
910+ return ( -1 );
911+ }
912+ }
913+ else // the command is for the controller itself
914+ if( ( scsi_cmnd_ptr->cmnd[0] != SS_INQUIR ) && // only INQUIRY & TUR cmnd supported for controller
915+ ( scsi_cmnd_ptr->cmnd[0] != SS_TEST ) )
916+ {
917+ cmn_err( CE_WARN, "Only INQUIRY & TUR command supported for controller, rcvd = 0x%x",
918+ scsi_cmnd_ptr->cmnd[0] );
919+
920+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
921+
922+ AacHba_SetSenseData( (char *)&g_sense_data[ ContainerId ],
923+ SENKEY_ILLEGAL, SENCODE_INVALID_COMMAND, ASENCODE_INVALID_COMMAND,
924+ 0, 0, 0, 0 );
925+
926+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
927+
928+ return ( -1 );
929+ }
930+
931+ // Handle commands here that don't really require going out to the adapter
932+ switch ( scsi_cmnd_ptr->cmnd[0] )
933+ {
934+ case SS_INQUIR:
935+ {
936+ struct inquiry_data *inq_data_ptr;
937+
938+ cmn_err( CE_DEBUG, "INQUIRY command, ID: %d", scsi_cmnd_ptr->target );
939+ inq_data_ptr = ( struct inquiry_data * )scsi_cmnd_ptr->request_buffer;
940+ bzero( inq_data_ptr, sizeof( struct inquiry_data ) );
941+
942+ inq_data_ptr->inqd_ver = 2; // claim compliance to SCSI-2
943+
944+ inq_data_ptr->inqd_dtq = 0x80; // set RMB bit to one indicating
945+ // that the medium is removable
946+ inq_data_ptr->inqd_rdf = 2; // A response data format value of
947+ // two indicates that the data shall
948+ // be in the format specified in SCSI-2
949+ inq_data_ptr->inqd_len = 31;
950+
951+ // Set the Vendor, Product, and Revision Level see: <vendor>.c i.e. aac.c
952+ SetInqDataStr( MiniPortIndex,
953+ (void *)(inq_data_ptr->inqd_vid),
954+ fsa_dev_ptr->ContainerType[ContainerId]);
955+
956+ if ( scsi_cmnd_ptr->target == scsi_cmnd_ptr->host->this_id )
957+ inq_data_ptr->inqd_pdt = INQD_PDT_PROC; // Processor device
958+ else
959+ inq_data_ptr->inqd_pdt = INQD_PDT_DA; // Direct/random access device
960+
961+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
962+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
963+
964+ return ( 0 );
965+ }
966+
967+ case SS_RDCAP:
968+ {
969+ int capacity;
970+ char *cp;
971+
972+ cmn_err( CE_DEBUG, "READ CAPACITY command" );
973+ capacity = fsa_dev_ptr->ContainerSize[ContainerId] - 1;
974+ cp = scsi_cmnd_ptr->request_buffer;
975+ cp[0] = ( capacity >> 24 ) & 0xff;
976+ cp[1] = ( capacity >> 16 ) & 0xff;
977+ cp[2] = ( capacity >> 8 ) & 0xff;
978+ cp[3] = ( capacity >> 0 ) & 0xff;
979+ cp[4] = 0;
980+ cp[5] = 0;
981+ cp[6] = 2;
982+ cp[7] = 0;
983+
984+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
985+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
986+
987+ return ( 0 );
988+ }
989+
990+ case SS_MODESEN:
991+ {
992+ char *mode_buf;
993+
994+ cmn_err( CE_DEBUG, "MODE SENSE command" );
995+ mode_buf = scsi_cmnd_ptr->request_buffer;
996+ mode_buf[0] = 0; // Mode data length (MSB)
997+ mode_buf[1] = 6; // Mode data length (LSB)
998+ mode_buf[2] = 0; // Medium type - default
999+ mode_buf[3] = 0; // Device-specific param, bit 8: 0/1 = write enabled/protected
1000+ mode_buf[4] = 0; // reserved
1001+ mode_buf[5] = 0; // reserved
1002+ mode_buf[6] = 0; // Block descriptor length (MSB)
1003+ mode_buf[7] = 0; // Block descriptor length (LSB)
1004+
1005+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1006+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1007+
1008+ return ( 0 );
1009+ }
1010+
1011+
1012+ // These commands are all No-Ops
1013+ case SS_TEST:
1014+ cmn_err( CE_DEBUG, "TEST UNIT READY command" );
1015+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1016+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1017+ return ( 0 );
1018+
1019+ case SS_REQSEN:
1020+ cmn_err( CE_DEBUG, "REQUEST SENSE command" );
1021+
1022+ memcpy( scsi_cmnd_ptr->sense_buffer, &g_sense_data[ContainerId],
1023+ sizeof( struct sense_data ) );
1024+ bzero( &g_sense_data[ContainerId], sizeof( struct sense_data ) );
1025+
1026+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1027+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1028+ return ( 0 );
1029+
1030+ case SS_LOCK:
1031+ cmn_err(CE_DEBUG, "LOCK command");
1032+
1033+ if( scsi_cmnd_ptr->cmnd[4] )
1034+ fsa_dev_ptr->ContainerLocked[ContainerId] = 1;
1035+ else
1036+ fsa_dev_ptr->ContainerLocked[ContainerId] = 0;
1037+
1038+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1039+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1040+ return ( 0 );
1041+
1042+ case SS_RESERV:
1043+ cmn_err( CE_DEBUG, "RESERVE command" );
1044+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1045+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1046+ return ( 0 );
1047+
1048+ case SS_RELES:
1049+ cmn_err( CE_DEBUG, "RELEASE command" );
1050+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1051+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1052+ return ( 0 );
1053+
1054+ case SS_REZERO:
1055+ cmn_err( CE_DEBUG, "REZERO command" );
1056+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1057+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1058+ return ( 0 );
1059+
1060+ case SS_REASGN:
1061+ cmn_err( CE_DEBUG, "REASSIGN command" );
1062+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1063+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1064+ return ( 0 );
1065+
1066+ case SS_SEEK:
1067+ cmn_err( CE_DEBUG, "SEEK command" );
1068+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1069+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1070+ return ( 0 );
1071+
1072+ case SS_ST_SP:
1073+ cmn_err( CE_DEBUG, "START/STOP command" );
1074+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1075+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1076+ return ( 0 );
1077+ }
1078+
1079+ switch ( scsi_cmnd_ptr->cmnd[0] )
1080+ {
1081+ case SS_READ:
1082+ case SM_READ:
1083+ // Hack to keep track of ordinal number of the device that corresponds
1084+ // to a container. Needed to convert containers to /dev/sd device names
1085+ fsa_dev_ptr->ContainerDevNo[ContainerId] =
1086+ DEVICE_NR( scsi_cmnd_ptr->request.rq_dev );
1087+
1088+ return( AacHba_DoScsiRead( scsi_cmnd_ptr, ContainerId, wait ) );
1089+ break;
1090+
1091+ case SS_WRITE:
1092+ case SM_WRITE:
1093+
1094+ return( AacHba_DoScsiWrite( scsi_cmnd_ptr, ContainerId, wait ) );
1095+ break;
1096+ }
1097+ //
1098+ // Unhandled commands
1099+ //
1100+ cmn_err( CE_WARN, "Unhandled SCSI Command: 0x%x", scsi_cmnd_ptr->cmnd[0] );
1101+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1102+
1103+ AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1104+ SENKEY_ILLEGAL, SENCODE_INVALID_COMMAND, ASENCODE_INVALID_COMMAND,
1105+ 0, 0, 0, 0 );
1106+
1107+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1108+ return ( -1 );
1109+}
1110+
1111+
1112+/*------------------------------------------------------------------------------
1113+ AacHba_DoScsiRead()
1114+
1115+ Handles SCSI READ requests
1116+
1117+ Preconditions:
1118+ Postconditions:
1119+ Returns 0 on success, -1 on failure
1120+ *----------------------------------------------------------------------------*/
1121+int AacHba_DoScsiRead(
1122+ Scsi_Cmnd *scsi_cmnd_ptr,
1123+ int ContainerId,
1124+ int wait )
1125+/*----------------------------------------------------------------------------*/
1126+{
1127+ u_long lba;
1128+ u_long count;
1129+ u_long byte_count;
1130+ int Status;
1131+
1132+ PBLOCKREAD BlockReadDisk;
1133+ PBLOCKREADRESPONSE BlockReadResponse;
1134+ uint16_t FibSize;
1135+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
1136+ AFA_COMM_ADAPTER *Adapter;
1137+ PFIB_CONTEXT cmd_fibcontext;
1138+
1139+ CommonExtension = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
1140+ Adapter = ( AFA_COMM_ADAPTER * )CommonExtension->Adapter;
1141+
1142+ // Get block address and transfer length
1143+ if ( scsi_cmnd_ptr->cmnd[0] == SS_READ ) // 6 byte command
1144+ {
1145+ cmn_err( CE_DEBUG, "aachba: received a read(6) command on target %d", ContainerId );
1146+
1147+ lba = ( ( scsi_cmnd_ptr->cmnd[1] & 0x1F ) << 16 ) |
1148+ ( scsi_cmnd_ptr->cmnd[2] << 8 ) |
1149+ scsi_cmnd_ptr->cmnd[3];
1150+ count = scsi_cmnd_ptr->cmnd[4];
1151+
1152+ if ( count == 0 )
1153+ count = 256;
1154+ }
1155+ else
1156+ {
1157+ cmn_err( CE_DEBUG, "aachba: received a read(10) command on target %d", ContainerId );
1158+
1159+ lba = ( scsi_cmnd_ptr->cmnd[2] << 24 ) | ( scsi_cmnd_ptr->cmnd[3] << 16 ) |
1160+ ( scsi_cmnd_ptr->cmnd[4] << 8 ) | scsi_cmnd_ptr->cmnd[5];
1161+
1162+ count = ( scsi_cmnd_ptr->cmnd[7] << 8 ) | scsi_cmnd_ptr->cmnd[8];
1163+ }
1164+ cmn_err( CE_DEBUG, "AacHba_DoScsiRead[cpu %d]: lba = %lu, t = %ld", smp_processor_id(), lba, jiffies );
1165+
1166+ //-------------------------------------------------------------------------
1167+ // Alocate and initialize a Fib
1168+ // Setup BlockRead command
1169+ if( !( cmd_fibcontext = Adapter->CommFuncs.AllocateFib( Adapter ) ) )
1170+ {
1171+ cmn_err( CE_WARN, "AacHba_DoScsiRead: AllocateFib failed\n" );
1172+ scsi_cmnd_ptr->result = DID_ERROR << 16;
1173+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1174+ return ( -1 );
1175+ }
1176+
1177+ Adapter->CommFuncs.InitializeFib( cmd_fibcontext );
1178+
1179+ BlockReadDisk = ( PBLOCKREAD )Adapter->CommFuncs.GetFibData( cmd_fibcontext );
1180+ BlockReadDisk->Command = VM_CtBlockRead;
1181+ BlockReadDisk->ContainerId = ContainerId;
1182+ BlockReadDisk->BlockNumber = lba;
1183+ BlockReadDisk->ByteCount = count * 512;
1184+ BlockReadDisk->SgMap.SgCount = 1;
1185+
1186+ if( BlockReadDisk->ByteCount > ( 64 * 1024 ) )
1187+ {
1188+ cmn_err( CE_WARN, "AacHba_DoScsiRead: READ request is larger than 64K" );
1189+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1190+
1191+ AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1192+ SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD,
1193+ 0, 0, 7, 0 );
1194+
1195+ goto err_return;
1196+ }
1197+
1198+ //-------------------------------------------------------------------------
1199+ // Build Scatter/Gather list
1200+ //
1201+ if ( scsi_cmnd_ptr->use_sg ) // use scatter/gather list
1202+ {
1203+ struct scatterlist *scatterlist_ptr;
1204+ int segment;
1205+
1206+ scatterlist_ptr = ( struct scatterlist * )scsi_cmnd_ptr->request_buffer;
1207+
1208+ byte_count = 0;
1209+ for( segment = 0; segment< scsi_cmnd_ptr->use_sg; segment++ )
1210+ {
1211+ BlockReadDisk->SgMap.SgEntry[segment].SgAddress =
1212+ ( void * )OsVirtToPhys( scatterlist_ptr[segment].address );
1213+ BlockReadDisk->SgMap.SgEntry[segment].SgByteCount =
1214+ scatterlist_ptr[segment].length;
1215+
1216+#ifdef DEBUG_SGBUFFER
1217+ memset( scatterlist_ptr[segment].address, 0xa5,
1218+ scatterlist_ptr[segment].length );
1219+#endif
1220+
1221+ byte_count += scatterlist_ptr[segment].length;
1222+
1223+ if( BlockReadDisk->SgMap.SgEntry[segment].SgByteCount > ( 64 * 1024 ) )
1224+ {
1225+ cmn_err( CE_WARN, "AacHba_DoScsiRead: Segment byte count is larger than 64K" );
1226+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1227+
1228+ AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1229+ SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD,
1230+ 0, 0, 7, 0 );
1231+
1232+ goto err_return;
1233+ }
1234+ /*
1235+ cmn_err(CE_DEBUG, "SgEntry[%d].SgAddress = 0x%x, Byte count = 0x%x",
1236+ segment,
1237+ BlockReadDisk->SgMap.SgEntry[segment].SgAddress,
1238+ BlockReadDisk->SgMap.SgEntry[segment].SgByteCount);
1239+ */
1240+ }
1241+ BlockReadDisk->SgMap.SgCount = scsi_cmnd_ptr->use_sg;
1242+
1243+ if( BlockReadDisk->SgMap.SgCount > MAX_DRIVER_SG_SEGMENT_COUNT )
1244+ {
1245+ cmn_err( CE_WARN, "AacHba_DoScsiRead: READ request with SgCount > %d",
1246+ MAX_DRIVER_SG_SEGMENT_COUNT );
1247+ scsi_cmnd_ptr->result = DID_ERROR << 16;
1248+ goto err_return;
1249+ }
1250+ }
1251+ else // one piece of contiguous phys mem
1252+ {
1253+ BlockReadDisk->SgMap.SgEntry[0].SgAddress =
1254+ ( void * )OsVirtToPhys( scsi_cmnd_ptr->request_buffer );
1255+ BlockReadDisk->SgMap.SgEntry[0].SgByteCount = scsi_cmnd_ptr->request_bufflen;
1256+
1257+ byte_count = scsi_cmnd_ptr->request_bufflen;
1258+
1259+ if( BlockReadDisk->SgMap.SgEntry[0].SgByteCount > ( 64 * 1024 ) )
1260+ {
1261+ cmn_err( CE_WARN, "AacHba_DoScsiRead: Single segment byte count is larger than 64K" );
1262+ cmn_err( CE_WARN, "AacHba_DoScsiRead: ByteCount: %d", BlockReadDisk->ByteCount);
1263+ cmn_err( CE_WARN, "AacHba_DoScsiRead: SG ELEMENTS: %d", scsi_cmnd_ptr->use_sg);
1264+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1265+
1266+ AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1267+ SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD,
1268+ 0, 0, 7, 0 );
1269+
1270+ goto err_return;
1271+ }
1272+ }
1273+
1274+ if( byte_count != BlockReadDisk->ByteCount )
1275+ cmn_err( CE_WARN, "AacHba_DoScsiRead: byte_count != BlockReadDisk->ByteCount" );
1276+
1277+ //-------------------------------------------------------------------------
1278+ // Now send the Fib to the adapter
1279+ //
1280+ FibSize = sizeof( BLOCKREAD ) + ( ( BlockReadDisk->SgMap.SgCount - 1 ) * sizeof( SGENTRY ) );
1281+
1282+ if( wait )
1283+ {
1284+ // This path shouldn't ever get executed with the current driver
1285+ Status = Adapter->CommFuncs.SendFib( ContainerCommand,
1286+ cmd_fibcontext,
1287+ FibSize,
1288+ FsaNormal,
1289+ TRUE,
1290+ NULL,
1291+ TRUE,
1292+ NULL,
1293+ NULL);
1294+
1295+ BlockReadResponse = ( PBLOCKREADRESPONSE )
1296+ Adapter->CommFuncs.GetFibData( cmd_fibcontext );
1297+
1298+ Adapter->CommFuncs.CompleteFib( cmd_fibcontext );
1299+ Adapter->CommFuncs.FreeFib( cmd_fibcontext );
1300+
1301+ if( BlockReadResponse->Status != ST_OK )
1302+ {
1303+ cmn_err( CE_WARN, "AacHba_DoScsiRead: BlockReadCommand failed with status: %d",
1304+ BlockReadResponse->Status );
1305+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1306+
1307+ AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1308+ SENKEY_HW_ERR, SENCODE_INTERNAL_TARGET_FAILURE, ASENCODE_INTERNAL_TARGET_FAILURE,
1309+ 0, 0, 0, 0 );
1310+
1311+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1312+ return ( -1 );
1313+ }
1314+ else
1315+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1316+
1317+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1318+ return ( 0 );
1319+ }
1320+ else
1321+ {
1322+ Status = Adapter->CommFuncs.SendFib( ContainerCommand,
1323+ cmd_fibcontext,
1324+ FibSize,
1325+ FsaNormal,
1326+ FALSE,
1327+ NULL,
1328+ TRUE,
1329+ ( PFIB_CALLBACK )AacHba_ReadCallback,
1330+ ( void *)scsi_cmnd_ptr );
1331+
1332+ // Check that the command queued to the controller
1333+ if (Status != STATUS_PENDING) {
1334+ cmn_err( CE_WARN, "AacHba_DoScsiRead: SendFib failed with status: %d\n",
1335+ Status);
1336+
1337+ // For some reason, the Fib didn't queue, return QUEUE_FULL
1338+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | QUEUE_FULL ;
1339+ goto err_return;
1340+ }
1341+
1342+ // don't call done func here
1343+ return ( 0 );
1344+ }
1345+
1346+err_return:
1347+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1348+
1349+ Adapter->CommFuncs.CompleteFib( cmd_fibcontext );
1350+ Adapter->CommFuncs.FreeFib( cmd_fibcontext );
1351+
1352+ return ( -1 );
1353+}
1354+
1355+
1356+/*------------------------------------------------------------------------------
1357+ AacHba_DoScsiWrite()
1358+
1359+ Handles SCSI WRITE requests
1360+
1361+ Preconditions:
1362+ Postconditions:
1363+ Returns 0 on success, -1 on failure
1364+ *----------------------------------------------------------------------------*/
1365+int AacHba_DoScsiWrite(
1366+ Scsi_Cmnd *scsi_cmnd_ptr,
1367+ int ContainerId,
1368+ int wait )
1369+/*----------------------------------------------------------------------------*/
1370+{
1371+ u_long lba;
1372+ u_long count;
1373+ u_long byte_count;
1374+ int Status;
1375+
1376+ PBLOCKWRITE BlockWriteDisk;
1377+ PBLOCKWRITERESPONSE BlockWriteResponse;
1378+ uint16_t FibSize;
1379+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
1380+ AFA_COMM_ADAPTER *Adapter;
1381+ PFIB_CONTEXT cmd_fibcontext;
1382+
1383+ CommonExtension = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
1384+ Adapter = ( AFA_COMM_ADAPTER * )CommonExtension->Adapter;
1385+
1386+ // Get block address and transfer length
1387+ if ( scsi_cmnd_ptr->cmnd[0] == SS_WRITE ) // 6 byte command
1388+ {
1389+ lba = ( ( scsi_cmnd_ptr->cmnd[1] & 0x1F ) << 16 ) |
1390+ ( scsi_cmnd_ptr->cmnd[2] << 8 ) |
1391+ scsi_cmnd_ptr->cmnd[3];
1392+ count = scsi_cmnd_ptr->cmnd[4];
1393+
1394+ if ( count == 0 )
1395+ count = 256;
1396+ }
1397+ else
1398+ {
1399+ cmn_err( CE_DEBUG, "aachba: received a write(10) command on target %d", ContainerId );
1400+
1401+ lba = ( scsi_cmnd_ptr->cmnd[2] << 24 ) | ( scsi_cmnd_ptr->cmnd[3] << 16 ) |
1402+ ( scsi_cmnd_ptr->cmnd[4] << 8 ) | scsi_cmnd_ptr->cmnd[5];
1403+
1404+ count = ( scsi_cmnd_ptr->cmnd[7] << 8 ) | scsi_cmnd_ptr->cmnd[8];
1405+
1406+ }
1407+ cmn_err( CE_DEBUG, "AacHba_DoScsiWrite[cpu %d]: lba = %lu, t = %ld", smp_processor_id(), lba, jiffies );
1408+
1409+ //-------------------------------------------------------------------------
1410+ // Alocate and initialize a Fib
1411+ // Setup BlockWrite command
1412+ if( !( cmd_fibcontext = Adapter->CommFuncs.AllocateFib( Adapter ) ) )
1413+ {
1414+ cmn_err( CE_WARN, "AacHba_DoScsiWrite: AllocateFib failed\n" );
1415+ scsi_cmnd_ptr->result = DID_ERROR << 16;
1416+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1417+ return ( -1 );
1418+ }
1419+
1420+ Adapter->CommFuncs.InitializeFib( cmd_fibcontext );
1421+
1422+ BlockWriteDisk = (PBLOCKWRITE) Adapter->CommFuncs.GetFibData( cmd_fibcontext );
1423+ BlockWriteDisk->Command = VM_CtBlockWrite;
1424+ BlockWriteDisk->ContainerId = ContainerId;
1425+ BlockWriteDisk->BlockNumber = lba;
1426+ BlockWriteDisk->ByteCount = count * 512;
1427+ BlockWriteDisk->SgMap.SgCount = 1;
1428+
1429+
1430+ if ( BlockWriteDisk->ByteCount > ( 64 * 1024 ) )
1431+ {
1432+ struct scatterlist *scatterlist_ptr;
1433+ int segment;
1434+ scatterlist_ptr = (struct scatterlist *)scsi_cmnd_ptr->request_buffer;
1435+
1436+ cmn_err( CE_WARN, "\n");
1437+ cmn_err( CE_WARN, "AacHba_DoScsiWrite: WRITE request is larger than 64K");
1438+ cmn_err( CE_WARN, "AacHba_DoScsiWrite: ByteCount: %d", BlockWriteDisk->ByteCount);
1439+/* cmn_err( CE_WARN, "AacHba_DoScsiWrite: SG ELEMENTS: %d", scsi_cmnd_ptr->use_sg); */
1440+/* cmn_err( CE_WARN, "Dump SG Element Size..."); */
1441+/* for( segment = 0; segment < scsi_cmnd_ptr->use_sg; segment++ ) */
1442+/* { */
1443+/* cmn_err (CE_WARN, "SG Segment %d: %d", segment, scatterlist_ptr[segment].length); */
1444+/* } */
1445+/* cmn_err (CE_WARN, "\n"); */
1446+
1447+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1448+
1449+ AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1450+ SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD,
1451+ 0, 0, 7, 0 );
1452+
1453+ goto err_return;
1454+ }
1455+
1456+ //-------------------------------------------------------------------------
1457+ // Build Scatter/Gather list
1458+ //
1459+ if ( scsi_cmnd_ptr->use_sg ) // use scatter/gather list
1460+ {
1461+ struct scatterlist *scatterlist_ptr;
1462+ int segment;
1463+
1464+ scatterlist_ptr = ( struct scatterlist * )scsi_cmnd_ptr->request_buffer;
1465+
1466+ byte_count = 0;
1467+ for( segment = 0; segment< scsi_cmnd_ptr->use_sg; segment++ )
1468+ {
1469+ BlockWriteDisk->SgMap.SgEntry[segment].SgAddress =
1470+ ( HOSTADDRESS )OsVirtToPhys( scatterlist_ptr[segment].address );
1471+ BlockWriteDisk->SgMap.SgEntry[segment].SgByteCount =
1472+ scatterlist_ptr[segment].length;
1473+
1474+ byte_count += scatterlist_ptr[segment].length;
1475+
1476+ if ( BlockWriteDisk->SgMap.SgEntry[segment].SgByteCount > ( 64 * 1024 ) )
1477+ {
1478+ cmn_err( CE_WARN, "AacHba_DoScsiWrite: Segment byte count is larger than 64K" );
1479+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1480+
1481+ AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1482+ SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD,
1483+ 0, 0, 7, 0 );
1484+
1485+ goto err_return;
1486+ }
1487+
1488+ /*
1489+ cmn_err(CE_DEBUG, "SgEntry[%d].SgAddress = 0x%x, Byte count = 0x%x",
1490+ segment,
1491+ BlockWriteDisk->SgMap.SgEntry[segment].SgAddress,
1492+ BlockWriteDisk->SgMap.SgEntry[segment].SgByteCount);
1493+ */
1494+ }
1495+ BlockWriteDisk->SgMap.SgCount = scsi_cmnd_ptr->use_sg;
1496+
1497+ if( BlockWriteDisk->SgMap.SgCount > MAX_DRIVER_SG_SEGMENT_COUNT )
1498+ {
1499+ cmn_err( CE_WARN, "AacHba_DoScsiWrite: WRITE request with SgCount > %d",
1500+ MAX_DRIVER_SG_SEGMENT_COUNT );
1501+ scsi_cmnd_ptr->result = DID_ERROR << 16;
1502+ goto err_return;
1503+ }
1504+ }
1505+ else // one piece of contiguous phys mem
1506+ {
1507+ BlockWriteDisk->SgMap.SgEntry[0].SgAddress =
1508+ ( HOSTADDRESS )OsVirtToPhys( scsi_cmnd_ptr->request_buffer );
1509+ BlockWriteDisk->SgMap.SgEntry[0].SgByteCount = scsi_cmnd_ptr->request_bufflen;
1510+
1511+ byte_count = scsi_cmnd_ptr->request_bufflen;
1512+
1513+ if ( BlockWriteDisk->SgMap.SgEntry[0].SgByteCount > ( 64 * 1024 ) )
1514+ {
1515+ cmn_err( CE_WARN, "AacHba_DoScsiWrite: Single segment byte count is larger than 64K" );
1516+
1517+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1518+ AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1519+ SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD,
1520+ 0, 0, 7, 0 );
1521+
1522+ goto err_return;
1523+ }
1524+ }
1525+
1526+ if( byte_count != BlockWriteDisk->ByteCount )
1527+ cmn_err( CE_WARN, "AacHba_DoScsiWrite: byte_count != BlockReadDisk->ByteCount" );
1528+
1529+ //-------------------------------------------------------------------------
1530+ // Now send the Fib to the adapter
1531+ //
1532+ FibSize = sizeof( BLOCKWRITE ) + ( ( BlockWriteDisk->SgMap.SgCount - 1 ) * sizeof( SGENTRY ) );
1533+
1534+ if( wait )
1535+ {
1536+ // This path shouldn't ever get executed with the current driver
1537+ Status = Adapter->CommFuncs.SendFib( ContainerCommand,
1538+ cmd_fibcontext,
1539+ FibSize,
1540+ FsaNormal,
1541+ TRUE,
1542+ NULL,
1543+ TRUE,
1544+ NULL,
1545+ NULL );
1546+
1547+ BlockWriteResponse = ( PBLOCKWRITERESPONSE )
1548+ Adapter->CommFuncs.GetFibData( cmd_fibcontext );
1549+
1550+ Adapter->CommFuncs.CompleteFib( cmd_fibcontext );
1551+ Adapter->CommFuncs.FreeFib( cmd_fibcontext );
1552+
1553+ if( BlockWriteResponse->Status != ST_OK )
1554+ {
1555+ cmn_err( CE_WARN, "AacHba_DoScsiWrite: BlockWriteCommand failed with status: %d\n",
1556+ BlockWriteResponse->Status );
1557+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;;
1558+ AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1559+ SENKEY_HW_ERR, SENCODE_INTERNAL_TARGET_FAILURE, ASENCODE_INTERNAL_TARGET_FAILURE,
1560+ 0, 0, 0, 0 );
1561+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1562+ return ( -1 );
1563+ }
1564+ else
1565+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1566+
1567+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1568+ return ( 0 );
1569+ }
1570+ else
1571+ {
1572+ Status = Adapter->CommFuncs.SendFib( ContainerCommand,
1573+ cmd_fibcontext,
1574+ FibSize,
1575+ FsaNormal,
1576+ FALSE,
1577+ NULL,
1578+ TRUE,
1579+ ( PFIB_CALLBACK )AacHba_WriteCallback,
1580+ ( void * )scsi_cmnd_ptr );
1581+
1582+ // Check that the command queued to the controller
1583+ if (Status != STATUS_PENDING) {
1584+ cmn_err( CE_WARN, "AacHba_DoScsiWrite: SendFib failed with status: %d\n",
1585+ Status);
1586+
1587+ // For some reason, the Fib didn't queue, return QUEUE_FULL
1588+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | QUEUE_FULL ;
1589+ goto err_return;
1590+ }
1591+
1592+ // don't call done func here - it should be called by the WriteCallback
1593+ return ( 0 );
1594+ }
1595+
1596+err_return:
1597+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1598+
1599+ Adapter->CommFuncs.CompleteFib( cmd_fibcontext );
1600+ Adapter->CommFuncs.FreeFib( cmd_fibcontext );
1601+
1602+ return ( -1 );
1603+}
1604+
1605+
1606+/*------------------------------------------------------------------------------
1607+ AacHba_ReadCallback()
1608+ *----------------------------------------------------------------------------*/
1609+void AacHba_ReadCallback(
1610+ VOID *Context,
1611+ PFIB_CONTEXT FibContext,
1612+ int FibStatus )
1613+/*----------------------------------------------------------------------------*/
1614+{
1615+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
1616+ AFA_COMM_ADAPTER *Adapter;
1617+ BLOCKREADRESPONSE *BlockReadResponse;
1618+ Scsi_Cmnd * scsi_cmnd_ptr;
1619+ u_long lba;
1620+ int ContainerId;
1621+
1622+ scsi_cmnd_ptr = ( Scsi_Cmnd * )Context;
1623+
1624+ CommonExtension = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
1625+ Adapter = ( AFA_COMM_ADAPTER * )CommonExtension->Adapter;
1626+
1627+ ContainerId = TARGET_LUN_TO_CONTAINER( scsi_cmnd_ptr->target, scsi_cmnd_ptr->lun );
1628+
1629+ lba = ( ( scsi_cmnd_ptr->cmnd[1] & 0x1F ) << 16 ) |
1630+ ( scsi_cmnd_ptr->cmnd[2] << 8 ) |
1631+ scsi_cmnd_ptr->cmnd[3];
1632+ cmn_err( CE_DEBUG, "AacHba_ReadCallback[cpu %d]: lba = %ld, t = %ld", smp_processor_id(), lba, jiffies );
1633+
1634+ if( FibContext == 0 )
1635+ {
1636+ cmn_err( CE_WARN, "AacHba_ReadCallback: no fib context" );
1637+ scsi_cmnd_ptr->result = DID_ERROR << 16;
1638+ AacHba_CompleteScsi( scsi_cmnd_ptr );
1639+ return;
1640+ }
1641+
1642+ BlockReadResponse = ( PBLOCKREADRESPONSE )Adapter->CommFuncs.GetFibData( FibContext );
1643+
1644+ if ( BlockReadResponse->Status == ST_OK )
1645+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1646+ else
1647+ {
1648+ cmn_err( CE_WARN, "AacHba_ReadCallback: read failed, status = %d\n",
1649+ BlockReadResponse->Status );
1650+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1651+ AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1652+ SENKEY_HW_ERR, SENCODE_INTERNAL_TARGET_FAILURE, ASENCODE_INTERNAL_TARGET_FAILURE,
1653+ 0, 0, 0, 0 );
1654+ }
1655+
1656+#ifdef DEBUG_SGBUFFER
1657+ if ( scsi_cmnd_ptr->use_sg ) // use scatter/gather list
1658+ {
1659+ struct scatterlist *scatterlist_ptr;
1660+ int i, segment, count;
1661+ char *ptr;
1662+
1663+ scatterlist_ptr = ( struct scatterlist * )scsi_cmnd_ptr->request_buffer;
1664+
1665+ for( segment = 0; segment < scsi_cmnd_ptr->use_sg; segment++ )
1666+ {
1667+ count = 0;
1668+ ptr = scatterlist_ptr[segment].address;
1669+ for( i = 0; i < scatterlist_ptr[segment].length; i++ )
1670+ {
1671+ if( *( ptr++ ) == 0xa5 )
1672+ count++;
1673+ }
1674+ if( count == scatterlist_ptr[segment].length )
1675+ cmn_err( CE_WARN, "AacHba_ReadCallback: segment %d not filled", segment );
1676+
1677+ }
1678+ }
1679+#endif
1680+
1681+ Adapter->CommFuncs.CompleteFib( FibContext );
1682+ Adapter->CommFuncs.FreeFib( FibContext );
1683+
1684+ AacHba_CompleteScsi( scsi_cmnd_ptr );
1685+}
1686+
1687+/*------------------------------------------------------------------------------
1688+ AacHba_WriteCallback()
1689+ *----------------------------------------------------------------------------*/
1690+void AacHba_WriteCallback(
1691+ VOID *Context,
1692+ PFIB_CONTEXT FibContext,
1693+ int FibStatus )
1694+/*----------------------------------------------------------------------------*/
1695+{
1696+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
1697+ AFA_COMM_ADAPTER *Adapter;
1698+ BLOCKWRITERESPONSE *BlockWriteResponse;
1699+ Scsi_Cmnd *scsi_cmnd_ptr;
1700+ u_long lba;
1701+ int ContainerId;
1702+
1703+ scsi_cmnd_ptr = ( Scsi_Cmnd * )Context;
1704+
1705+ CommonExtension = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
1706+ Adapter = ( AFA_COMM_ADAPTER * )CommonExtension->Adapter;
1707+
1708+ ContainerId = TARGET_LUN_TO_CONTAINER( scsi_cmnd_ptr->target, scsi_cmnd_ptr->lun );
1709+
1710+ lba = ( ( scsi_cmnd_ptr->cmnd[1] & 0x1F ) << 16 ) |
1711+ ( scsi_cmnd_ptr->cmnd[2] << 8 ) |
1712+ scsi_cmnd_ptr->cmnd[3];
1713+ cmn_err( CE_DEBUG, "AacHba_WriteCallback[cpu %d]: lba = %ld, t = %ld", smp_processor_id(), lba, jiffies );
1714+ if( FibContext == 0 )
1715+ {
1716+ cmn_err( CE_WARN, "AacHba_WriteCallback: no fib context" );
1717+ scsi_cmnd_ptr->result = DID_ERROR << 16;
1718+ AacHba_CompleteScsi( scsi_cmnd_ptr );
1719+ return;
1720+ }
1721+
1722+ BlockWriteResponse = (PBLOCKWRITERESPONSE) Adapter->CommFuncs.GetFibData( FibContext );
1723+ if (BlockWriteResponse->Status == ST_OK)
1724+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1725+ else
1726+ {
1727+ cmn_err( CE_WARN, "AacHba_WriteCallback: write failed, status = %d\n",
1728+ BlockWriteResponse->Status );
1729+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1730+ AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1731+ SENKEY_HW_ERR, SENCODE_INTERNAL_TARGET_FAILURE, ASENCODE_INTERNAL_TARGET_FAILURE,
1732+ 0, 0, 0, 0 );
1733+ }
1734+
1735+ Adapter->CommFuncs.CompleteFib( FibContext );
1736+ Adapter->CommFuncs.FreeFib( FibContext );
1737+
1738+ AacHba_CompleteScsi( scsi_cmnd_ptr );
1739+}
1740+
1741+
1742+/*------------------------------------------------------------------------------
1743+ AacHba_Ioctl()
1744+
1745+ Handle IOCTL requests
1746+
1747+ Preconditions:
1748+ Postconditions:
1749+ *----------------------------------------------------------------------------*/
1750+int AacHba_Ioctl(
1751+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtension,
1752+ int cmd,
1753+ void * arg )
1754+/*----------------------------------------------------------------------------*/
1755+{
1756+ Sa_ADAPTER_EXTENSION *AdapterExtension;
1757+ AFA_IOCTL_CMD IoctlCmd;
1758+ int status;
1759+
1760+ AdapterExtension = ( Sa_ADAPTER_EXTENSION * )CommonExtension->MiniPort;
1761+
1762+ cmn_err( CE_DEBUG, "AacHba_Ioctl, type = %d", cmd );
1763+ switch( cmd )
1764+ {
1765+ case FSACTL_SENDFIB:
1766+ cmn_err( CE_DEBUG, "FSACTL_SENDFIB" );
1767+ break;
1768+
1769+ case FSACTL_AIF_THREAD:
1770+ cmn_err( CE_DEBUG, "FSACTL_AIF_THREAD" );
1771+ break;
1772+
1773+ case FSACTL_NULL_IO_TEST:
1774+ cmn_err( CE_DEBUG, "FSACTL_NULL_IO_TEST" );
1775+ break;
1776+
1777+ case FSACTL_SIM_IO_TEST:
1778+ cmn_err( CE_DEBUG, "FSACTL_SIM_IO_TEST" );
1779+ break;
1780+
1781+ case FSACTL_GET_FIBTIMES:
1782+ cmn_err( CE_DEBUG, "FSACTL_GET_FIBTIMES" );
1783+ break;
1784+
1785+ case FSACTL_ZERO_FIBTIMES:
1786+ cmn_err( CE_DEBUG, "FSACTL_ZERO_FIBTIMES");
1787+ break;
1788+
1789+ case FSACTL_GET_VAR:
1790+ cmn_err( CE_DEBUG, "FSACTL_GET_VAR" );
1791+ break;
1792+
1793+ case FSACTL_SET_VAR:
1794+ cmn_err( CE_DEBUG, "FSACTL_SET_VAR" );
1795+ break;
1796+
1797+ case FSACTL_OPEN_ADAPTER_CONFIG:
1798+ cmn_err( CE_DEBUG, "FSACTL_OPEN_ADAPTER_CONFIG" );
1799+ break;
1800+
1801+ case FSACTL_CLOSE_ADAPTER_CONFIG:
1802+ cmn_err( CE_DEBUG, "FSACTL_CLOSE_ADAPTER_CONFIG" );
1803+ break;
1804+
1805+ case FSACTL_QUERY_ADAPTER_CONFIG:
1806+ cmn_err( CE_DEBUG, "FSACTL_QUERY_ADAPTER_CONFIG" );
1807+ break;
1808+
1809+ case FSACTL_OPEN_GET_ADAPTER_FIB:
1810+ cmn_err( CE_DEBUG, "FSACTL_OPEN_GET_ADAPTER_FIB" );
1811+ break;
1812+
1813+ case FSACTL_GET_NEXT_ADAPTER_FIB:
1814+ cmn_err( CE_DEBUG, "FSACTL_GET_NEXT_ADAPTER_FIB" );
1815+ break;
1816+
1817+ case FSACTL_CLOSE_GET_ADAPTER_FIB:
1818+ cmn_err( CE_DEBUG, "FSACTL_CLOSE_GET_ADAPTER_FIB" );
1819+ break;
1820+
1821+ case FSACTL_MINIPORT_REV_CHECK:
1822+ cmn_err( CE_DEBUG, "FSACTL_MINIPORT_REV_CHECK" );
1823+ break;
1824+
1825+ case FSACTL_OPENCLS_COMM_PERF_DATA:
1826+ cmn_err( CE_DEBUG, "FSACTL_OPENCLS_COMM_PERF_DATA" );
1827+ break;
1828+
1829+ case FSACTL_GET_COMM_PERF_DATA:
1830+ cmn_err( CE_DEBUG, "FSACTL_GET_COMM_PERF_DATA" );
1831+ break;
1832+
1833+ case FSACTL_QUERY_DISK:
1834+ cmn_err( CE_DEBUG, "FSACTL_QUERY_DISK" );
1835+ break;
1836+
1837+ case FSACTL_DELETE_DISK:
1838+ cmn_err( CE_DEBUG, "FSACTL_DELETE_DISK" );
1839+ break;
1840+
1841+ default:
1842+ cmn_err( CE_DEBUG, "Unknown ioctl: 0x%x", cmd );
1843+ }
1844+
1845+ IoctlCmd.cmd = cmd;
1846+ IoctlCmd.arg = ( intptr_t )arg;
1847+ IoctlCmd.flag = 0;
1848+ IoctlCmd.cred_p = 0;
1849+ IoctlCmd.rval_p = 0;
1850+
1851+ status = AfaCommAdapterDeviceControl( CommonExtension->Adapter, &IoctlCmd );
1852+ cmn_err( CE_DEBUG, "AAC_Ioctl, completion status = %d", status );
1853+ return( status );
1854+}
1855+
1856+
1857+/*------------------------------------------------------------------------------
1858+ AacHba_AdapterDeviceControl()
1859+
1860+ Preconditions:
1861+ Postconditions:
1862+ Returns TRUE if ioctl handled, FALSE otherwise
1863+ *ReturnStatus set to completion status
1864+ *----------------------------------------------------------------------------*/
1865+BOOLEAN AacHba_AdapterDeviceControl (
1866+ PVOID AdapterArg, // CommonExtensionPtr
1867+ IN PAFA_IOCTL_CMD IoctlCmdPtr,
1868+ OUT int * ReturnStatus )
1869+/*----------------------------------------------------------------------------*/
1870+{
1871+ BOOLEAN Handled = TRUE; // start out handling it.
1872+ int Status = EFAULT;
1873+
1874+ switch( IoctlCmdPtr->cmd )
1875+ {
1876+ case FSACTL_QUERY_DISK:
1877+ Status = AacHba_QueryDisk( AdapterArg, IoctlCmdPtr );
1878+ break;
1879+
1880+ case FSACTL_DELETE_DISK:
1881+ Status = AacHba_DeleteDisk( AdapterArg, IoctlCmdPtr );
1882+ break;
1883+
1884+ case FSACTL_FORCE_DELETE_DISK:
1885+ Status = AacHba_ForceDeleteDisk( AdapterArg, IoctlCmdPtr );
1886+ break;
1887+
1888+ case 2131:
1889+ if( AacHba_ProbeContainers( ( PCI_MINIPORT_COMMON_EXTENSION * )AdapterArg ) )
1890+ Status = -EFAULT;
1891+ break;
1892+
1893+ default:
1894+ Handled = FALSE;
1895+ break;
1896+ }
1897+
1898+ *ReturnStatus = Status;
1899+
1900+ return( Handled );
1901+}
1902+
1903+
1904+/*------------------------------------------------------------------------------
1905+ AacHba_QueryDisk()
1906+
1907+ Postconditions:
1908+ Return values
1909+ 0 = OK
1910+ -EFAULT = Bad address
1911+ -EINVAL = Bad container number
1912+ *----------------------------------------------------------------------------*/
1913+int AacHba_QueryDisk(
1914+ PVOID AdapterArg, // CommonExtensionPtr
1915+ IN PAFA_IOCTL_CMD IoctlCmdPtr )
1916+/*----------------------------------------------------------------------------*/
1917+{
1918+ UNIX_QUERY_DISK QueryDisk;
1919+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
1920+ fsadev_t *fsa_dev_ptr;
1921+
1922+ CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )AdapterArg;
1923+ fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
1924+
1925+ if( copyin( IoctlCmdPtr->arg, &QueryDisk, sizeof( UNIX_QUERY_DISK ) ) )
1926+ return( -EFAULT );
1927+
1928+ if (QueryDisk.ContainerNumber == -1)
1929+ QueryDisk.ContainerNumber = TARGET_LUN_TO_CONTAINER( QueryDisk.Target, QueryDisk.Lun );
1930+ else
1931+ if( ( QueryDisk.Bus == -1 ) && ( QueryDisk.Target == -1 ) && ( QueryDisk.Lun == -1 ) )
1932+ {
1933+ if( QueryDisk.ContainerNumber > MAXIMUM_NUM_CONTAINERS )
1934+ return( -EINVAL );
1935+
1936+ QueryDisk.Instance = CommonExtensionPtr->OsDep.scsi_host_ptr->host_no;
1937+ QueryDisk.Bus = 0;
1938+ QueryDisk.Target = CONTAINER_TO_TARGET( QueryDisk.ContainerNumber );
1939+ QueryDisk.Lun = CONTAINER_TO_LUN( QueryDisk.ContainerNumber );
1940+ }
1941+ else
1942+ return( -EINVAL );
1943+
1944+ QueryDisk.Valid = fsa_dev_ptr->ContainerValid[QueryDisk.ContainerNumber];
1945+ QueryDisk.Locked = fsa_dev_ptr->ContainerLocked[QueryDisk.ContainerNumber];
1946+ QueryDisk.Deleted = fsa_dev_ptr->ContainerDeleted[QueryDisk.ContainerNumber];
1947+
1948+ if( fsa_dev_ptr->ContainerDevNo[QueryDisk.ContainerNumber] == -1 )
1949+ QueryDisk.UnMapped = TRUE;
1950+ else
1951+ QueryDisk.UnMapped = FALSE;
1952+
1953+ get_sd_devname( fsa_dev_ptr->ContainerDevNo[QueryDisk.ContainerNumber],
1954+ QueryDisk.diskDeviceName );
1955+
1956+ if( copyout( &QueryDisk, IoctlCmdPtr->arg, sizeof( UNIX_QUERY_DISK ) ) )
1957+ return( -EFAULT );
1958+
1959+ return( 0 );
1960+}
1961+
1962+
1963+/*------------------------------------------------------------------------------
1964+ get_sd_devname()
1965+ *----------------------------------------------------------------------------*/
1966+static void get_sd_devname(
1967+ long disknum,
1968+ char * buffer)
1969+/*----------------------------------------------------------------------------*/
1970+{
1971+ if( disknum < 0 )
1972+ {
1973+ sprintf(buffer, "%s", "");
1974+ return;
1975+ }
1976+
1977+ if( disknum < 26 )
1978+ sprintf(buffer, "sd%c", 'a' + disknum);
1979+ else {
1980+ unsigned int min1;
1981+ unsigned int min2;
1982+ /*
1983+ * For larger numbers of disks, we need to go to a new
1984+ * naming scheme.
1985+ */
1986+ min1 = disknum / 26;
1987+ min2 = disknum % 26;
1988+ sprintf(buffer, "sd%c%c", 'a' + min1 - 1, 'a' + min2);
1989+ }
1990+}
1991+
1992+
1993+/*------------------------------------------------------------------------------
1994+ AacHba_ForceDeleteDisk()
1995+
1996+ Postconditions:
1997+ Return values
1998+ 0 = OK
1999+ -EFAULT = Bad address
2000+ -EINVAL = Bad container number
2001+ *----------------------------------------------------------------------------*/
2002+int AacHba_ForceDeleteDisk(
2003+ PVOID AdapterArg, // CommonExtensionPtr
2004+ IN PAFA_IOCTL_CMD IoctlCmdPtr )
2005+/*----------------------------------------------------------------------------*/
2006+{
2007+ DELETE_DISK DeleteDisk;
2008+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
2009+ fsadev_t *fsa_dev_ptr;
2010+
2011+ CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )AdapterArg;
2012+ fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
2013+
2014+ if ( copyin( IoctlCmdPtr->arg, &DeleteDisk, sizeof( DELETE_DISK ) ) )
2015+ return( -EFAULT );
2016+
2017+ if ( DeleteDisk.ContainerNumber > MAXIMUM_NUM_CONTAINERS )
2018+ return( -EINVAL );
2019+
2020+ // Mark this container as being deleted.
2021+ fsa_dev_ptr->ContainerDeleted[DeleteDisk.ContainerNumber] = TRUE;
2022+
2023+ // Mark the container as no longer valid
2024+ fsa_dev_ptr->ContainerValid[DeleteDisk.ContainerNumber] = 0;
2025+
2026+ return( 0 );
2027+}
2028+
2029+
2030+/*------------------------------------------------------------------------------
2031+ AacHba_DeleteDisk()
2032+
2033+ Postconditions:
2034+ Return values
2035+ 0 = OK
2036+ -EFAULT = Bad address
2037+ -EINVAL = Bad container number
2038+ -EBUSY = Device locked
2039+ *----------------------------------------------------------------------------*/
2040+int AacHba_DeleteDisk(
2041+ PVOID AdapterArg,
2042+ IN PAFA_IOCTL_CMD IoctlCmdPtr )
2043+/*----------------------------------------------------------------------------*/
2044+{
2045+ DELETE_DISK DeleteDisk;
2046+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
2047+ fsadev_t *fsa_dev_ptr;
2048+
2049+ CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )AdapterArg;
2050+ fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
2051+
2052+ if( copyin( IoctlCmdPtr->arg, &DeleteDisk, sizeof( DELETE_DISK ) ) )
2053+ return( -EFAULT );
2054+
2055+ if( DeleteDisk.ContainerNumber > MAXIMUM_NUM_CONTAINERS )
2056+ return( -EINVAL );
2057+
2058+ // If the container is locked, it can not be deleted by the API.
2059+ if( fsa_dev_ptr->ContainerLocked[DeleteDisk.ContainerNumber] )
2060+ return( -EBUSY );
2061+ else
2062+ {
2063+ // Mark the container as no longer being valid.
2064+ fsa_dev_ptr->ContainerValid[DeleteDisk.ContainerNumber] = 0;
2065+ fsa_dev_ptr->ContainerDevNo[DeleteDisk.ContainerNumber] = -1;
2066+ return(0);
2067+ }
2068+}
2069+
2070+
2071+/*------------------------------------------------------------------------------
2072+ AacHba_OpenAdapter()
2073+ *----------------------------------------------------------------------------*/
2074+AAC_STATUS AacHba_OpenAdapter(
2075+ IN PVOID AdapterArg )
2076+/*----------------------------------------------------------------------------*/
2077+{
2078+ return( STATUS_SUCCESS );
2079+}
2080+
2081+
2082+/*------------------------------------------------------------------------------
2083+ AacHba_CloseAdapter()
2084+ *----------------------------------------------------------------------------*/
2085+AAC_STATUS AacHba_CloseAdapter(
2086+ IN PVOID AdapterArg )
2087+/*----------------------------------------------------------------------------*/
2088+{
2089+ return( STATUS_SUCCESS );
2090+}
2091+
2092+
2093+/*------------------------------------------------------------------------------
2094+ AacHba_DetachAdapter()
2095+ *----------------------------------------------------------------------------*/
2096+void AacHba_DetachAdapter(
2097+ IN PVOID AdapterArg )
2098+/*----------------------------------------------------------------------------*/
2099+{
2100+ AacCommDetachAdapter( AdapterArg );
2101+}
2102+
2103+
2104+/*------------------------------------------------------------------------------
2105+ AacHba_AbortScsiCommand()
2106+ *----------------------------------------------------------------------------*/
2107+void AacHba_AbortScsiCommand(
2108+ Scsi_Cmnd *scsi_cmnd_ptr )
2109+/*----------------------------------------------------------------------------*/
2110+{
2111+ u_short interrupt_status;
2112+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
2113+
2114+ CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
2115+ interrupt_status = Sa_READ_USHORT( ( PSa_ADAPTER_EXTENSION )( CommonExtensionPtr->MiniPort ),
2116+ DoorbellReg_p );
2117+ cmn_err( CE_WARN, "interrupt_status = %d", interrupt_status );
2118+
2119+ if( interrupt_status & DOORBELL_1) { // Adapter -> Host Normal Command Ready
2120+ cmn_err( CE_WARN, "DOORBELL_1: Adapter -> Host Normal Command Ready" );
2121+ }
2122+
2123+ if( interrupt_status & DOORBELL_2) { // Adapter -> Host Normal Response Ready
2124+ cmn_err( CE_WARN, "DOORBELL_2: Adapter -> Host Normal Response Ready" );
2125+ }
2126+
2127+ if ( interrupt_status & DOORBELL_3) { // Adapter -> Host Normal Command Not Full
2128+ cmn_err( CE_WARN, "DOORBELL_3: Adapter -> Host Normal Command Not Full" );
2129+ }
2130+
2131+ if ( interrupt_status & DOORBELL_4) { // Adapter -> Host Normal Response Not Full
2132+ cmn_err( CE_WARN, "DOORBELL_4: Adapter -> Host Normal Response Not Full" );
2133+ }
2134+
2135+}
2136+
2137+
2138+/*------------------------------------------------------------------------------
2139+ AacHba_HandleAif()
2140+ *----------------------------------------------------------------------------*/
2141+BOOLEAN AacHba_HandleAif(
2142+ IN PVOID AdapterArg,
2143+ IN PFIB_CONTEXT FibContext )
2144+/*----------------------------------------------------------------------------*/
2145+{
2146+ return( FALSE );
2147+}
2148+
2149+
2150+/*------------------------------------------------------------------------------
2151+ AacHba_SetSenseData()
2152+ Fill in the sense data.
2153+ Preconditions:
2154+ Postconditions:
2155+ *----------------------------------------------------------------------------*/
2156+void AacHba_SetSenseData(
2157+ char * sense_buf,
2158+ unchar sense_key,
2159+ unchar sense_code,
2160+ unchar a_sense_code,
2161+ unchar incorrect_length,
2162+ unchar bit_pointer,
2163+ unsigned field_pointer,
2164+ unsigned long residue )
2165+/*----------------------------------------------------------------------------*/
2166+{
2167+ sense_buf[0] = 0xF0; // Sense data valid, err code 70h (current error)
2168+ sense_buf[1] = 0; // Segment number, always zero
2169+
2170+ if( incorrect_length )
2171+ {
2172+ sense_buf[2] = sense_key | 0x20; // Set the ILI bit | sense key
2173+ sense_buf[3] = BYTE3(residue);
2174+ sense_buf[4] = BYTE2(residue);
2175+ sense_buf[5] = BYTE1(residue);
2176+ sense_buf[6] = BYTE0(residue);
2177+ }
2178+ else
2179+ sense_buf[2] = sense_key; // Sense key
2180+
2181+ if( sense_key == SENKEY_ILLEGAL )
2182+ sense_buf[7] = 10; // Additional sense length
2183+ else
2184+ sense_buf[7] = 6; // Additional sense length
2185+
2186+ sense_buf[12] = sense_code; // Additional sense code
2187+ sense_buf[13] = a_sense_code; // Additional sense code qualifier
2188+ if( sense_key == SENKEY_ILLEGAL )
2189+ {
2190+ sense_buf[15] = 0;
2191+
2192+ if( sense_code == SENCODE_INVALID_PARAM_FIELD )
2193+ sense_buf[15] = 0x80; // Std sense key specific field
2194+ // Illegal parameter is in the parameter block
2195+
2196+ if( sense_code == SENCODE_INVALID_CDB_FIELD )
2197+ sense_buf[15] = 0xc0; // Std sense key specific field
2198+ // Illegal parameter is in the CDB block
2199+ sense_buf[15] |= bit_pointer;
2200+ sense_buf[16] = field_pointer >> 8; // MSB
2201+ sense_buf[17] = field_pointer; // LSB
2202+ }
2203+}
2204+
2205diff -burN linux-2.4.7/drivers/scsi/aacraid/aacid.c linux/drivers/scsi/aacraid/aacid.c
2206--- linux-2.4.7/drivers/scsi/aacraid/aacid.c Wed Dec 31 18:00:00 1969
2207+++ linux/drivers/scsi/aacraid/aacid.c Sat Jul 21 17:55:13 2001
2208@@ -0,0 +1,153 @@
2209+/*++
2210+ * Adaptec aacraid device driver for Linux.
2211+ *
2212+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
2213+ *
2214+ * This program is free software; you can redistribute it and/or modify
2215+ * it under the terms of the GNU General Public License as published by
2216+ * the Free Software Foundation; either version 2, or (at your option)
2217+ * any later version.
2218+ *
2219+ * This program is distributed in the hope that it will be useful,
2220+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2221+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2222+ * GNU General Public License for more details.
2223+ *
2224+ * You should have received a copy of the GNU General Public License
2225+ * along with this program; see the file COPYING. If not, write to
2226+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
2227+ *
2228+ * Module Name:
2229+ * aac.c
2230+ *
2231+ * Abstract: Data structures for controller specific info.
2232+ *
2233+--*/
2234+
2235+static char *ident_aacid = "aacraid_ident aacid.c 1.0.6 2000/10/09 Adaptec, Inc.";
2236+
2237+#include "osheaders.h"
2238+
2239+#include "AacGenericTypes.h"
2240+
2241+#include "aac_unix_defs.h"
2242+
2243+#include "fsatypes.h"
2244+#include "comstruc.h"
2245+#include "fsaport.h"
2246+#include "pcisup.h"
2247+
2248+#include "version.h"
2249+
2250+
2251+/* Function Prototypes */
2252+void InqStrCopy(char *a, char *b); /* ossup.c */
2253+
2254+/* Device name used to register and unregister
2255+ the device in linit.c */
2256+char devicestr[]="aac";
2257+
2258+char *container_types[] = {
2259+ "None",
2260+ "Volume",
2261+ "Mirror",
2262+ "Stripe",
2263+ "RAID5",
2264+ "SSRW",
2265+ "SSRO",
2266+ "Morph",
2267+ "Legacy",
2268+ "RAID4",
2269+ "RAID10",
2270+ "RAID00",
2271+ "V-MIRRORS",
2272+ "PSEUDO R4",
2273+ "RAID50",
2274+ "Unknown"
2275+};
2276+
2277+/* Local Structure to set SCSI inquiry data strings */
2278+typedef struct _INQSTR {
2279+ char vid[8]; /* Vendor ID */
2280+ char pid[16]; /* Product ID */
2281+ char prl[4]; /* Product Revision Level */
2282+} INQSTR, *INQSTRP;
2283+
2284+FSA_MINIPORT MiniPorts[];
2285+
2286+/* Function: SetInqDataStr
2287+ *
2288+ * Arguments: [1] pointer to void [1] int
2289+ *
2290+ * Purpose: Sets SCSI inquiry data strings for vendor, product
2291+ * and revision level. Allows strings to be set in platform dependant
2292+ * files instead of in OS dependant driver source.
2293+ */
2294+void
2295+SetInqDataStr (
2296+ int MiniPortIndex,
2297+ void *dataPtr,
2298+ int tindex)
2299+{
2300+ INQSTRP InqStrPtr;
2301+ char *findit;
2302+ FSA_MINIPORT *mp;
2303+
2304+ mp = &MiniPorts[MiniPortIndex];
2305+
2306+ InqStrPtr = (INQSTRP)(dataPtr); /* cast dataPtr to type INQSTRP */
2307+
2308+ InqStrCopy (mp->Vendor, InqStrPtr->vid);
2309+ InqStrCopy (mp->Model, InqStrPtr->pid); /* last six chars reserved for vol type */
2310+
2311+ findit = InqStrPtr->pid;
2312+
2313+ for ( ; *findit != ' '; findit++); /* walk till we find a space then incr by 1 */
2314+ findit++;
2315+
2316+ if (tindex < (sizeof(container_types)/sizeof(char *))){
2317+ InqStrCopy (container_types[tindex], findit);
2318+ }
2319+ InqStrCopy ("0001", InqStrPtr->prl);
2320+}
2321+
2322+int
2323+SaInitDevice(
2324+ IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
2325+ IN ULONG AdapterNumber,
2326+ IN ULONG PciBus,
2327+ IN ULONG PciSlot
2328+);
2329+
2330+int
2331+RxInitDevice(
2332+ IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
2333+ IN ULONG AdapterNumber,
2334+ IN ULONG PciBus,
2335+ IN ULONG PciSlot
2336+);
2337+
2338+
2339+/*
2340+ * Because of the way Linux names scsi devices, the order in this table has
2341+ * become important. Check for on-board Raid first, add-in cards second.
2342+ */
2343+
2344+FSA_MINIPORT MiniPorts[] = {
2345+ { 0x1028, 0x0001, 0x1028, 0x0001, "afa", RxInitDevice, "percraid", "DELL ", "PERCRAID " }, /* PERC 3/Si */
2346+ { 0x1028, 0x0002, 0x1028, 0x0002, "afa", RxInitDevice, "percraid", "DELL ", "PERCRAID " }, /* PERC 3/Di */
2347+ { 0x1028, 0x0003, 0x1028, 0x0003, "afa", RxInitDevice, "percraid", "DELL ", "PERCRAID " }, /* PERC 3/Si */
2348+ { 0x1028, 0x0004, 0x1028, 0x00d0, "afa", RxInitDevice, "percraid", "DELL ", "PERCRAID " }, /* PERC 3/Si */
2349+ { 0x1028, 0x0002, 0x1028, 0x00d1, "afa", RxInitDevice, "percraid", "DELL ", "PERCRAID " }, /* PERC 3/Di */
2350+ { 0x1028, 0x0002, 0x1028, 0x00d9, "afa", RxInitDevice, "percraid", "DELL ", "PERCRAID " }, /* PERC 3/Di */
2351+ { 0x1028, 0x000a, 0x1028, 0x0106, "afa", RxInitDevice, "percraid", "DELL ", "PERCRAID " }, /* PERC 3/Di */
2352+ { 0x1011, 0x0046, 0x9005, 0x1364, "afa", SaInitDevice, "percraid", "DELL ", "PERCRAID " }, /* Dell PERC2 "Quad Channel */
2353+ { 0x1011, 0x0046, 0x103c, 0x10c2, "hpn", SaInitDevice, "hpnraid", "HP ", "NetRAID-4M " } /* HP NetRAID-4M */
2354+};
2355+
2356+
2357+#define NUM_MINIPORTS (sizeof(MiniPorts) / sizeof(FSA_MINIPORT))
2358+
2359+int NumMiniPorts = NUM_MINIPORTS;
2360+
2361+char DescriptionString[] = "AACxxx Raid Controller" FSA_VERSION_STRING ;
2362diff -burN linux-2.4.7/drivers/scsi/aacraid/commctrl.c linux/drivers/scsi/aacraid/commctrl.c
2363--- linux-2.4.7/drivers/scsi/aacraid/commctrl.c Wed Dec 31 18:00:00 1969
2364+++ linux/drivers/scsi/aacraid/commctrl.c Sat Jul 21 17:55:13 2001
2365@@ -0,0 +1,1098 @@
2366+/*++
2367+ * Adaptec aacraid device driver for Linux.
2368+ *
2369+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
2370+ *
2371+ * This program is free software; you can redistribute it and/or modify
2372+ * it under the terms of the GNU General Public License as published by
2373+ * the Free Software Foundation; either version 2, or (at your option)
2374+ * any later version.
2375+ *
2376+ * This program is distributed in the hope that it will be useful,
2377+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2378+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2379+ * GNU General Public License for more details.
2380+ *
2381+ * You should have received a copy of the GNU General Public License
2382+ * along with this program; see the file COPYING. If not, write to
2383+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
2384+ *
2385+ * Module Name:
2386+ * commctrl.c
2387+ *
2388+ * Abstract: Contains all routines for control of the AFA comm layer
2389+ *
2390+--*/
2391+
2392+static char *ident_commctrl = "aacraid_ident commctrl.c 1.0.7 2000/10/11 Adaptec, Inc.";
2393+
2394+#include "comprocs.h"
2395+#include "osheaders.h"
2396+#include "ostypes.h"
2397+
2398+
2399+
2400+
2401+
2402+typedef BOOLEAN BOOL;
2403+#define inline /* _inline */
2404+
2405+#include <revision.h>
2406+AAC_STATUS
2407+FsaCtlCheckRevision(
2408+ IN PAFA_COMM_ADAPTER Adapter,
2409+ IN PAFA_IOCTL_CMD IoctlCmdPtr
2410+ )
2411+/*++
2412+
2413+Routine Description:
2414+
2415+ This routine validates the revision of the caller with the current revision
2416+ of the filesystem.
2417+
2418+Arguments:
2419+
2420+ Adapter - Supplies which adapter is being processed.
2421+
2422+ Irp - Supplies the Irp being processed.
2423+
2424+ IrpContext - Supplies the IrpContext.
2425+
2426+Return Value:
2427+
2428+ AAC_STATUS
2429+
2430+--*/
2431+
2432+{
2433+ RevCheck APIRevCheck;
2434+ RevCheckResp APIRevCheckResp;
2435+ RevComponent APICallingComponent;
2436+ ULONG APIBuildNumber;
2437+
2438+ if (COPYIN( (caddr_t) IoctlCmdPtr->arg, (caddr_t) &APIRevCheck, sizeof(RevCheck), IoctlCmdPtr->flag )) {
2439+ return (EFAULT);
2440+ }
2441+
2442+ APICallingComponent = APIRevCheck.callingComponent;
2443+ APIBuildNumber = APIRevCheck.callingRevision.buildNumber;
2444+
2445+ APIRevCheckResp.possiblyCompatible = RevCheckCompatibility( RevMiniportDriver , APICallingComponent, APIBuildNumber );
2446+
2447+ APIRevCheckResp.adapterSWRevision.external.ul = RevGetExternalRev();
2448+ APIRevCheckResp.adapterSWRevision.buildNumber = RevGetBuildNumber();
2449+
2450+ if (COPYOUT( (caddr_t) &APIRevCheckResp, (caddr_t) IoctlCmdPtr->arg, sizeof(RevCheckResp), IoctlCmdPtr->flag )) {
2451+ return (EFAULT);
2452+ }
2453+
2454+ return (0);
2455+}
2456+
2457+
2458+int
2459+AfaCommAdapterDeviceControl(
2460+ IN PVOID AdapterArg,
2461+ IN PAFA_IOCTL_CMD IoctlCmdPtr
2462+ )
2463+{
2464+ PAFA_COMM_ADAPTER Adapter = (PAFA_COMM_ADAPTER) AdapterArg;
2465+ int Status = ENOTTY;
2466+// PIO_STACK_LOCATION IrpSp;
2467+ PAFA_CLASS_DRIVER ClassDriver;
2468+
2469+ //
2470+ // First loop through all of the class drivers to give them a chance to handle
2471+ // the Device control first.
2472+ //
2473+
2474+ ClassDriver = Adapter->ClassDriverList;
2475+
2476+ while (ClassDriver) {
2477+
2478+ if (ClassDriver->DeviceControl) {
2479+
2480+ if (ClassDriver->DeviceControl( ClassDriver->ClassDriverExtension, IoctlCmdPtr, &Status ) ) {
2481+
2482+ return (Status);
2483+
2484+ }
2485+ }
2486+
2487+ ClassDriver = ClassDriver->Next;
2488+ }
2489+
2490+ switch (IoctlCmdPtr->cmd) {
2491+
2492+
2493+ case FSACTL_SENDFIB:
2494+
2495+ Status = AfaCommCtlSendFib( Adapter, IoctlCmdPtr );
2496+ break;
2497+
2498+ case FSACTL_AIF_THREAD:
2499+
2500+ Status = AfaCommCtlAifThread( Adapter, IoctlCmdPtr );
2501+ break;
2502+
2503+
2504+ case FSACTL_OPEN_GET_ADAPTER_FIB:
2505+
2506+ Status = FsaCtlOpenGetAdapterFib( Adapter, IoctlCmdPtr );
2507+ break;
2508+
2509+ case FSACTL_GET_NEXT_ADAPTER_FIB:
2510+
2511+ Status = FsaCtlGetNextAdapterFib( Adapter, IoctlCmdPtr );
2512+ break;
2513+
2514+ case FSACTL_CLOSE_GET_ADAPTER_FIB:
2515+
2516+ Status = FsaCtlCloseGetAdapterFib( Adapter, IoctlCmdPtr );
2517+ break;
2518+
2519+ case FSACTL_MINIPORT_REV_CHECK:
2520+
2521+ Status = FsaCtlCheckRevision( Adapter , IoctlCmdPtr );
2522+ break;
2523+
2524+
2525+ default:
2526+
2527+ Status = ENOTTY;
2528+ break;
2529+
2530+ }
2531+
2532+
2533+ return (Status);
2534+}
2535+
2536+AAC_STATUS
2537+AfaCommRegisterNewClassDriver(
2538+ IN PAFA_COMM_ADAPTER Adapter,
2539+ IN PAFA_NEW_CLASS_DRIVER NewClassDriver,
2540+ OUT PAFA_NEW_CLASS_DRIVER_RESPONSE NewClassDriverResponse
2541+ )
2542+/*++
2543+
2544+Routine Description:
2545+
2546+ This routine registers a new class driver for the comm layer.
2547+
2548+ It will return a pointer to the communication functions for the class driver
2549+ to use.
2550+
2551+Arguments:
2552+
2553+ Adapter - Supplies which adapter is being processed.
2554+
2555+ Irp - Supplies the Irp being processed.
2556+
2557+Return Value:
2558+
2559+ STATUS_SUCCESS - Everything OK.
2560+
2561+--*/
2562+{
2563+ AAC_STATUS Status;
2564+ PAFA_CLASS_DRIVER ClassDriver;
2565+
2566+
2567+ ClassDriver = (PAFA_CLASS_DRIVER) OsAllocMemory( sizeof(AFA_CLASS_DRIVER), OS_ALLOC_MEM_SLEEP );
2568+
2569+ if (ClassDriver == NULL) {
2570+
2571+ Status = STATUS_INSUFFICIENT_RESOURCES;
2572+
2573+ return Status;
2574+ }
2575+
2576+ //
2577+ // If the class driver has sent in user Vars, then copy them into the global
2578+ // area.
2579+ //
2580+
2581+ if (NewClassDriver->NumUserVars) {
2582+
2583+ PFSA_USER_VAR NewUserVars;
2584+
2585+ NewUserVars = OsAllocMemory( (FsaCommData.NumUserVars +
2586+ NewClassDriver->NumUserVars) * sizeof(FSA_USER_VAR), OS_ALLOC_MEM_SLEEP );
2587+
2588+ //
2589+ // First copy the existing into the new area.
2590+ //
2591+
2592+ RtlCopyMemory( NewUserVars, FsaCommData.UserVars, FsaCommData.NumUserVars * sizeof(FSA_USER_VAR) );
2593+
2594+ //
2595+ // Next copy the new vars passed in from class driver.
2596+ //
2597+
2598+ RtlCopyMemory( (NewUserVars + FsaCommData.NumUserVars),
2599+ NewClassDriver->UserVars,
2600+ NewClassDriver->NumUserVars * sizeof(FSA_USER_VAR) );
2601+
2602+ //
2603+ // Free up the old user vars.
2604+ //
2605+
2606+ OsFreeMemory( FsaCommData.UserVars, FsaCommData.NumUserVars * sizeof(FSA_USER_VAR) );
2607+
2608+ //
2609+ // Point the global to the new area.
2610+ //
2611+
2612+ FsaCommData.UserVars = NewUserVars;
2613+
2614+ //
2615+ // Update the total count.
2616+ //
2617+
2618+ FsaCommData.NumUserVars += NewClassDriver->NumUserVars;
2619+
2620+ }
2621+
2622+ ClassDriver->OpenAdapter = NewClassDriver->OpenAdapter;
2623+ ClassDriver->CloseAdapter = NewClassDriver->CloseAdapter;
2624+ ClassDriver->DeviceControl = NewClassDriver->DeviceControl;
2625+ ClassDriver->HandleAif = NewClassDriver->HandleAif;
2626+ ClassDriver->ClassDriverExtension = NewClassDriver->ClassDriverExtension;
2627+
2628+ ClassDriver->Next = Adapter->ClassDriverList;
2629+ Adapter->ClassDriverList = ClassDriver;
2630+
2631+ //
2632+ // Now return the information needed by the class driver to communicate to us.
2633+ //
2634+
2635+ NewClassDriverResponse->CommFuncs = &Adapter->CommFuncs;
2636+ NewClassDriverResponse->CommPortExtension = Adapter;
2637+ NewClassDriverResponse->MiniPortExtension = Adapter->AdapterExtension;
2638+ NewClassDriverResponse->SpinLockCookie = Adapter->SpinLockCookie;
2639+ NewClassDriverResponse->Dip = Adapter->Dip;
2640+
2641+ return (STATUS_SUCCESS);
2642+
2643+
2644+}
2645+
2646+int
2647+AfaCommCtlSendFib(
2648+ IN PAFA_COMM_ADAPTER Adapter,
2649+ IN PAFA_IOCTL_CMD IoctlCmdPtr
2650+)
2651+/*++
2652+
2653+Routine Description:
2654+
2655+ This routine sends a fib to the adapter on behalf of a user level
2656+ program.
2657+
2658+Arguments:
2659+
2660+ Adapter - Supplies which adapter is being processed.
2661+
2662+ IoctlCmdPtr - Pointer to the arguments to the IOCTL call
2663+
2664+Return Value:
2665+
2666+ STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2667+
2668+ STATUS_INSUFFICIENT_RESOURCES - If a memory allocation failed.
2669+
2670+ STATUS_SUCCESS - Everything OK.
2671+
2672+--*/
2673+{
2674+ PFIB KFib;
2675+// PMDL DmaMdl = NULL;
2676+ PCOMM_FIB_CONTEXT FibContext;
2677+ PSGMAP_CONTEXT SgMapContext;
2678+ SGMAP_CONTEXT _SgMapContext;
2679+ QUEUE_TYPES WhichQueue;
2680+ PVOID UsersAddress;
2681+ AAC_STATUS Status;
2682+
2683+ FibContext = AllocateFib( Adapter );
2684+
2685+ KFib = FibContext->Fib;
2686+
2687+ //
2688+ // First copy in the header so that we can check the size field.
2689+ //
2690+
2691+ if (COPYIN( (caddr_t) IoctlCmdPtr->arg, (caddr_t) KFib, sizeof(FIB_HEADER), IoctlCmdPtr->flag )) {
2692+ FreeFib( FibContext );
2693+ Status = EFAULT;
2694+ return (Status);
2695+ }
2696+
2697+ //
2698+ // Since we copy based on the fib header size, make sure that we
2699+ // will not overrun the buffer when we copy the memory. Return
2700+ // an error if we would.
2701+ //
2702+
2703+ if (KFib->Header.Size > sizeof(FIB) - sizeof(FIB_HEADER)) {
2704+ FreeFib( FibContext );
2705+ Status = EINVAL;
2706+ return Status;
2707+
2708+ }
2709+
2710+ if (COPYIN( (caddr_t) IoctlCmdPtr->arg, (caddr_t) KFib, KFib->Header.Size + sizeof(FIB_HEADER), IoctlCmdPtr->flag )) {
2711+ FreeFib( FibContext );
2712+ Status = EFAULT;
2713+ return (Status);
2714+ }
2715+
2716+ WhichQueue = AdapNormCmdQueue;
2717+
2718+
2719+ if (KFib->Header.Command == TakeABreakPt) {
2720+
2721+ InterruptAdapter(Adapter);
2722+
2723+ //
2724+ // Since we didn't really send a fib, zero out the state to allow
2725+ // cleanup code not to assert.
2726+ //
2727+
2728+ KFib->Header.XferState = 0;
2729+
2730+
2731+ } else {
2732+
2733+ if (SendFib(KFib->Header.Command, FibContext, KFib->Header.Size , FsaNormal,
2734+ TRUE, NULL, TRUE, NULL, NULL) != FSA_SUCCESS) {
2735+ FsaCommPrint("User SendFib failed!.\n");
2736+
2737+
2738+ FreeFib( FibContext );
2739+ return (ENXIO);
2740+ }
2741+
2742+ if (CompleteFib(FibContext) != FSA_SUCCESS) {
2743+ FsaCommPrint("User Complete FIB failed.\n");
2744+
2745+ FreeFib( FibContext );
2746+ return (ENXIO);
2747+ }
2748+
2749+
2750+ }
2751+
2752+
2753+ //
2754+ // Make sure that the size returned by the adapter (which includes
2755+ // the header) is less than or equal to the size of a fib, so we
2756+ // don't corrupt application data. Then copy that size to the user
2757+ // buffer. (Don't try to add the header information again, since it
2758+ // was already included by the adapter.)
2759+ //
2760+ ASSERT(KFib->Header.Size <= sizeof(FIB));
2761+
2762+ if (COPYOUT( (caddr_t) KFib, (caddr_t) IoctlCmdPtr->arg, KFib->Header.Size, IoctlCmdPtr->flag )) {
2763+ FreeFib( FibContext );
2764+ Status = EFAULT;
2765+ return (Status);
2766+ }
2767+
2768+ FreeFib( FibContext );
2769+
2770+ return (0);
2771+
2772+}
2773+
2774+int
2775+AfaCommCtlAifThread(
2776+ IN PAFA_COMM_ADAPTER Adapter,
2777+ IN PAFA_IOCTL_CMD IoctlCmdPtr
2778+)
2779+/*++
2780+
2781+Routine Description:
2782+
2783+ This routine will act as the AIF thread for this adapter.
2784+
2785+Arguments:
2786+
2787+ Adapter - Supplies which adapter is being processed.
2788+
2789+ IoctlCmdPtr - Pointer to the arguments to the IOCTL call
2790+
2791+Return Value:
2792+
2793+ STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2794+
2795+ STATUS_INSUFFICIENT_RESOURCES - If a memory allocation failed.
2796+
2797+ STATUS_SUCCESS - Everything OK.
2798+
2799+--*/
2800+{
2801+ return (NormCommandThread(Adapter));
2802+}
2803+
2804+
2805+
2806+#ifdef GATHER_FIB_TIMES
2807+AAC_STATUS
2808+AfaCommGetFibTimes(
2809+ IN PAFA_COMM_ADAPTER Adapter,
2810+ IN PIRP Irp
2811+ )
2812+/*++
2813+
2814+Routine Description:
2815+
2816+ This routine returns the gathered fibtimes to the user.
2817+
2818+Arguments:
2819+
2820+ Adapter - Supplies which adapter is being processed.
2821+
2822+ Irp - Supplies the Irp being processed.
2823+
2824+Return Value:
2825+
2826+ STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2827+
2828+ STATUS_INSUFFICIENT_RESOURCES - If a memory allocation failed.
2829+
2830+ STATUS_SUCCESS - Everything OK.
2831+
2832+--*/
2833+{
2834+ PALL_FIB_TIMES AllFibTimes;
2835+ PLARGE_INTEGER FreqPtr;
2836+ PIO_STACK_LOCATION IrpSp;
2837+
2838+ //
2839+ // Get a pointer to the current Irp stack location
2840+ //
2841+
2842+ IrpSp = IoGetCurrentIrpStackLocation( Irp );
2843+
2844+ FreqPtr = (PLARGE_INTEGER)IrpSp->Parameters.FileSystemControl.Type3InputBuffer;
2845+
2846+ *FreqPtr = Adapter->FibTimesFrequency;
2847+
2848+ AllFibTimes = (PALL_FIB_TIMES)((PUCHAR)FreqPtr + sizeof(LARGE_INTEGER));
2849+
2850+ RtlCopyMemory(AllFibTimes, Adapter->FibTimes, sizeof(ALL_FIB_TIMES));
2851+
2852+ Irp->IoStatus.Information = 0;
2853+
2854+ return (STATUS_SUCCESS);
2855+
2856+}
2857+
2858+AAC_STATUS
2859+AfaCommZeroFibTimes(
2860+ IN PAFA_COMM_ADAPTER Adapter,
2861+ IN PIRP Irp
2862+ )
2863+/*++
2864+
2865+Routine Description:
2866+
2867+ This routine zero's the FibTimes structure within the adapter structure.
2868+
2869+Arguments:
2870+
2871+ Adapter - Supplies which adapter is being processed.
2872+
2873+ Irp - Supplies the Irp being processed.
2874+
2875+Return Value:
2876+
2877+ STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2878+
2879+ STATUS_INSUFFICIENT_RESOURCES - If a memory allocation failed.
2880+
2881+ STATUS_SUCCESS - Everything OK.
2882+
2883+--*/
2884+{
2885+ PFIB_TIMES FibTimesPtr;
2886+ int i;
2887+ PIO_STACK_LOCATION IrpSp;
2888+
2889+ //
2890+ // Get a pointer to the current Irp stack location
2891+ //
2892+
2893+ IrpSp = IoGetCurrentIrpStackLocation( Irp );
2894+
2895+ //
2896+ // Initialize the Fib timing data structures
2897+ //
2898+ RtlZeroMemory(Adapter->FibTimes, sizeof(ALL_FIB_TIMES));
2899+
2900+ for (i = 0; i < MAX_FSACOMMAND_NUM; i++) {
2901+
2902+ FibTimesPtr = &Adapter->FibTimes->FileSys[i];
2903+
2904+ FibTimesPtr->Minimum.LowPart = 0xffffffff;
2905+ FibTimesPtr->Minimum.HighPart = 0x7fffffff;
2906+ FibTimesPtr->AdapterMinimum.LowPart = 0xffffffff;
2907+ FibTimesPtr->AdapterMinimum.HighPart = 0x7fffffff;
2908+ }
2909+ for (i = 0; i < MAX_RW_FIB_TIMES; i++) {
2910+
2911+ FibTimesPtr = &Adapter->FibTimes->Read[i];
2912+
2913+ FibTimesPtr->Minimum.LowPart = 0xffffffff;
2914+ FibTimesPtr->Minimum.HighPart = 0x7fffffff;
2915+ FibTimesPtr->AdapterMinimum.LowPart = 0xffffffff;
2916+ FibTimesPtr->AdapterMinimum.HighPart = 0x7fffffff;
2917+ }
2918+ for (i = 0; i < MAX_RW_FIB_TIMES; i++) {
2919+
2920+ FibTimesPtr = &Adapter->FibTimes->Write[i];
2921+
2922+ FibTimesPtr->Minimum.LowPart = 0xffffffff;
2923+ FibTimesPtr->Minimum.HighPart = 0x7fffffff;
2924+ FibTimesPtr->AdapterMinimum.LowPart = 0xffffffff;
2925+ FibTimesPtr->AdapterMinimum.HighPart = 0x7fffffff;
2926+ }
2927+
2928+ FibTimesPtr = &Adapter->FibTimes->Other;
2929+
2930+ FibTimesPtr->Minimum.LowPart = 0xffffffff;
2931+ FibTimesPtr->Minimum.HighPart = 0x7fffffff;
2932+ FibTimesPtr->AdapterMinimum.LowPart = 0xffffffff;
2933+ FibTimesPtr->AdapterMinimum.HighPart = 0x7fffffff;
2934+
2935+ Irp->IoStatus.Information = 0;
2936+
2937+ return (STATUS_SUCCESS);
2938+
2939+}
2940+#endif // GATHER_FIB_TIMES
2941+
2942+#ifndef unix_aif
2943+int
2944+FsaCtlOpenGetAdapterFib(
2945+ IN PAFA_COMM_ADAPTER Adapter,
2946+ IN PAFA_IOCTL_CMD IoctlCmdPtr
2947+ )
2948+/*++
2949+
2950+Routine Description:
2951+
2952+ This routine will get the next Fib, if available, from the AdapterFibContext
2953+ passed in from the user.
2954+
2955+Arguments:
2956+
2957+ Adapter - Supplies which adapter is being processed.
2958+
2959+ Irp - Supplies the Irp being processed.
2960+
2961+Return Value:
2962+
2963+ STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2964+
2965+ STATUS_INSUFFICIENT_RESOURCES - If a memory allocation failed.
2966+
2967+ STATUS_SUCCESS - Everything OK.
2968+
2969+--*/
2970+{
2971+ PGET_ADAPTER_FIB_CONTEXT AdapterFibContext;
2972+// HANDLE Event;
2973+// PKEVENT eventObject = (PKEVENT) NULL;
2974+ int Status;
2975+
2976+ //
2977+ // The context must be allocated from NonPagedPool because we need to use MmIsAddressValid.
2978+ //
2979+
2980+ AdapterFibContext = OsAllocMemory(sizeof(GET_ADAPTER_FIB_CONTEXT), OS_ALLOC_MEM_SLEEP);
2981+
2982+ if (AdapterFibContext == NULL) {
2983+
2984+ Status = ENOMEM;
2985+
2986+ } else {
2987+
2988+ AdapterFibContext->NodeTypeCode = FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT;
2989+ AdapterFibContext->NodeByteSize = sizeof(GET_ADAPTER_FIB_CONTEXT);
2990+
2991+
2992+ //
2993+ // Initialize the conditional variable use to wait for the next AIF.
2994+ //
2995+
2996+ OsCv_init( &AdapterFibContext->UserEvent);
2997+
2998+ //
2999+ // Set WaitingForFib to FALSE to indicate we are not in a WaitForSingleObject
3000+ //
3001+
3002+ AdapterFibContext->WaitingForFib = FALSE;
3003+
3004+ //
3005+ // Initialize the FibList and set the count of fibs on the list to 0.
3006+ //
3007+
3008+ AdapterFibContext->FibCount = 0;
3009+ InitializeListHead(&AdapterFibContext->FibList);
3010+
3011+ //
3012+ // Overload FileObject with a time stamp.
3013+ //
3014+ AdapterFibContext->FileObject = (void *)OsGetSeconds();
3015+
3016+ //
3017+ // Now add this context onto the adapter's AdapterFibContext list.
3018+ //
3019+
3020+ OsCvLockAcquire(Adapter->AdapterFibMutex);
3021+
3022+ InsertTailList(&Adapter->AdapterFibContextList, &AdapterFibContext->NextContext);
3023+
3024+ OsCvLockRelease(Adapter->AdapterFibMutex);
3025+
3026+ if (COPYOUT( &AdapterFibContext, (caddr_t) IoctlCmdPtr->arg, sizeof(PGET_ADAPTER_FIB_CONTEXT),
3027+ IoctlCmdPtr->flag )) {
3028+
3029+ Status = EFAULT;
3030+
3031+ } else {
3032+
3033+ Status = 0;
3034+
3035+ }
3036+
3037+ }
3038+
3039+ return (Status);
3040+}
3041+
3042+int
3043+FsaCtlGetNextAdapterFib(
3044+ IN PAFA_COMM_ADAPTER Adapter,
3045+ IN PAFA_IOCTL_CMD IoctlCmdPtr
3046+ )
3047+/*++
3048+
3049+Routine Description:
3050+
3051+ This routine will get the next Fib, if available, from the AdapterFibContext
3052+ passed in from the user.
3053+
3054+Arguments:
3055+
3056+ Adapter - Supplies which adapter is being processed.
3057+
3058+ Irp - Supplies the Irp being processed.
3059+
3060+Return Value:
3061+
3062+ STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
3063+
3064+ STATUS_NO_MORE_ENTRIES - There are no more Fibs for this AdapterFibContext.
3065+
3066+ STATUS_SUCCESS - Everything OK.
3067+
3068+--*/
3069+{
3070+ GET_ADAPTER_FIB_IOCTL AdapterFibIoctl;
3071+ PGET_ADAPTER_FIB_CONTEXT AdapterFibContext, aifcp;
3072+ PFIB Fib;
3073+ int Status;
3074+ PLIST_ENTRY Entry;
3075+ int found;
3076+
3077+ if (COPYIN( (caddr_t) IoctlCmdPtr->arg, (caddr_t) &AdapterFibIoctl,
3078+ sizeof(GET_ADAPTER_FIB_IOCTL), IoctlCmdPtr->flag )) {
3079+ return (EFAULT);
3080+ }
3081+
3082+ //
3083+ // Extract the AdapterFibContext from the Input parameters.
3084+ //
3085+
3086+ AdapterFibContext = (PGET_ADAPTER_FIB_CONTEXT) AdapterFibIoctl.AdapterFibContext;
3087+
3088+ //
3089+ // Verify that the HANDLE passed in was a valid AdapterFibContext
3090+ //
3091+ // Search the list of AdapterFibContext addresses on the adapter to be sure
3092+ // this is a valid address
3093+
3094+ found = 0;
3095+ Entry = Adapter->AdapterFibContextList.Flink;
3096+
3097+ while ( Entry != &Adapter->AdapterFibContextList ) {
3098+ aifcp = CONTAINING_RECORD ( Entry, GET_ADAPTER_FIB_CONTEXT, NextContext );
3099+ if ( AdapterFibContext == aifcp ) { // We found a winner
3100+ found = 1;
3101+ break;
3102+ }
3103+ Entry = Entry->Flink;
3104+ }
3105+
3106+ if ( found == 0 ) {
3107+ return ( EINVAL );;
3108+ }
3109+
3110+ if ( (AdapterFibContext->NodeTypeCode != FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT) ||
3111+ (AdapterFibContext->NodeByteSize != sizeof(GET_ADAPTER_FIB_CONTEXT)) ) {
3112+
3113+ return ( EINVAL );
3114+
3115+ }
3116+
3117+ Status = STATUS_SUCCESS;
3118+
3119+ OsCvLockAcquire(Adapter->AdapterFibMutex);
3120+
3121+ //
3122+ // If there are no fibs to send back, then either wait or return EAGAIN
3123+ //
3124+return_fib:
3125+
3126+ if (!IsListEmpty(&AdapterFibContext->FibList)) {
3127+
3128+ PLIST_ENTRY Entry;
3129+
3130+ //
3131+ // Pull the next fib from the FibList
3132+ //
3133+ Entry = RemoveHeadList(&AdapterFibContext->FibList);
3134+
3135+ Fib = CONTAINING_RECORD( Entry, FIB, Header.FibLinks );
3136+
3137+ AdapterFibContext->FibCount--;
3138+
3139+ if (COPYOUT( Fib, AdapterFibIoctl.AifFib, sizeof(FIB), IoctlCmdPtr->flag )) {
3140+
3141+ OsCvLockRelease( Adapter->AdapterFibMutex );
3142+ OsFreeMemory( Fib, sizeof(Fib) );
3143+ return (EFAULT);
3144+
3145+ }
3146+
3147+ //
3148+ // Free the space occupied by this copy of the fib.
3149+ //
3150+
3151+ OsFreeMemory(Fib, sizeof(FIB));
3152+
3153+ Status = 0;
3154+
3155+ //
3156+ // Overload FileObject with a time stamp
3157+ //
3158+ AdapterFibContext->FileObject = ( void * )OsGetSeconds();
3159+
3160+ } else {
3161+
3162+ if (AdapterFibIoctl.Wait) {
3163+
3164+ if (OsCv_wait_sig( &AdapterFibContext->UserEvent, Adapter->AdapterFibMutex ) == 0) {
3165+
3166+ Status = EINTR;
3167+
3168+ } else {
3169+
3170+ goto return_fib;
3171+
3172+ }
3173+ } else {
3174+
3175+ Status = EAGAIN;
3176+
3177+ }
3178+
3179+ }
3180+ OsCvLockRelease( Adapter->AdapterFibMutex );
3181+
3182+ return (Status);
3183+}
3184+
3185+int
3186+FsaCtlCloseGetAdapterFib(
3187+ IN PAFA_COMM_ADAPTER Adapter,
3188+ IN PAFA_IOCTL_CMD IoctlCmdPtr
3189+ )
3190+/*++
3191+
3192+Routine Description:
3193+
3194+ This routine will close down the AdapterFibContext passed in from the user.
3195+
3196+Arguments:
3197+
3198+ Adapter - Supplies which adapter is being processed.
3199+
3200+ Irp - Supplies the Irp being processed.
3201+
3202+Return Value:
3203+
3204+ STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
3205+
3206+ STATUS_SUCCESS - Everything OK.
3207+
3208+--*/
3209+{
3210+ PGET_ADAPTER_FIB_CONTEXT AdapterFibContext, aifcp;
3211+ AAC_STATUS Status;
3212+
3213+ PLIST_ENTRY Entry;
3214+ int found;
3215+
3216+ //
3217+ // Extract the AdapterFibContext from the Input parameters
3218+ //
3219+
3220+ AdapterFibContext = (PGET_ADAPTER_FIB_CONTEXT) IoctlCmdPtr->arg;
3221+
3222+ if (AdapterFibContext == 0) {
3223+ cmn_err(CE_WARN, "FsaCtlCloseGetAdapterFib: AdapterFibContext is NULL");
3224+ return(EINVAL);
3225+ }
3226+
3227+ //
3228+ // Verify that the HANDLE passed in was a valid AdapterFibContext
3229+ //
3230+ // Search the list of AdapterFibContext addresses on the adapter to be sure
3231+ // this is a valid address
3232+
3233+ found = 0;
3234+ Entry = Adapter->AdapterFibContextList.Flink;
3235+
3236+ while ( Entry != &Adapter->AdapterFibContextList ) {
3237+ aifcp = CONTAINING_RECORD ( Entry, GET_ADAPTER_FIB_CONTEXT, NextContext );
3238+ if ( AdapterFibContext == aifcp ) { // We found a winner
3239+ found = 1;
3240+ break;
3241+ }
3242+ Entry = Entry->Flink;
3243+ }
3244+
3245+ if ( found == 0 ) {
3246+ return ( 0 ); // Already Gone
3247+ }
3248+
3249+ if ( (AdapterFibContext->NodeTypeCode != FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT) ||
3250+ (AdapterFibContext->NodeByteSize != sizeof(GET_ADAPTER_FIB_CONTEXT)) ) {
3251+
3252+ return (EINVAL);
3253+
3254+ }
3255+
3256+ OsCvLockAcquire(Adapter->AdapterFibMutex);
3257+
3258+ Status = FsaCloseAdapterFibContext(Adapter, AdapterFibContext);
3259+
3260+ OsCvLockRelease(Adapter->AdapterFibMutex);
3261+
3262+ return (Status);
3263+}
3264+
3265+int
3266+FsaCloseAdapterFibContext(
3267+ IN PAFA_COMM_ADAPTER Adapter,
3268+ IN PGET_ADAPTER_FIB_CONTEXT AdapterFibContext
3269+ )
3270+{
3271+ int Status;
3272+ PFIB Fib;
3273+
3274+ //
3275+ // First free any FIBs that have not been consumed yet.
3276+ //
3277+
3278+ while (!IsListEmpty(&AdapterFibContext->FibList)) {
3279+
3280+ PLIST_ENTRY Entry;
3281+
3282+ //
3283+ // Pull the next fib from the FibList
3284+ //
3285+
3286+ Entry = RemoveHeadList(&AdapterFibContext->FibList);
3287+
3288+ Fib = CONTAINING_RECORD( Entry, FIB, Header.FibLinks );
3289+
3290+ AdapterFibContext->FibCount--;
3291+
3292+ //
3293+ // Free the space occupied by this copy of the fib.
3294+ //
3295+
3296+ OsFreeMemory(Fib, sizeof(FIB));
3297+ }
3298+
3299+ //
3300+ // Remove the Context from the AdapterFibContext List
3301+ //
3302+
3303+ RemoveEntryList(&AdapterFibContext->NextContext);
3304+
3305+ OsCv_destroy( &AdapterFibContext->UserEvent );
3306+
3307+ //
3308+ // Invalidate context
3309+ //
3310+
3311+ AdapterFibContext->NodeTypeCode = 0;
3312+
3313+ //
3314+ // Free the space occupied by the Context
3315+ //
3316+
3317+ OsFreeMemory(AdapterFibContext, sizeof(GET_ADAPTER_FIB_CONTEXT));
3318+
3319+ Status = STATUS_SUCCESS;
3320+
3321+ return Status;
3322+}
3323+#endif
3324+
3325+AAC_STATUS
3326+AfaCommOpenAdapter(
3327+ IN PVOID Arg
3328+ )
3329+/*++
3330+
3331+Routine Description:
3332+
3333+ The routine will get called by the miniport each time a user issues a CreateFile on the DeviceObject
3334+ for the adapter.
3335+
3336+ The main purpose of this routine is to set up any data structures that may be needed
3337+ to handle any requests made on this DeviceObject.
3338+
3339+Arguments:
3340+
3341+ Adapter - Pointer to which adapter miniport was opened.
3342+
3343+
3344+Return Value:
3345+
3346+ STATUS_SUCCESS
3347+
3348+--*/
3349+
3350+{
3351+ PAFA_COMM_ADAPTER Adapter = (PAFA_COMM_ADAPTER) Arg;
3352+ AAC_STATUS Status = STATUS_SUCCESS;
3353+ PAFA_CLASS_DRIVER ClassDriver;
3354+
3355+ ClassDriver = Adapter->ClassDriverList;
3356+
3357+ while (ClassDriver) {
3358+
3359+ if (ClassDriver->OpenAdapter) {
3360+
3361+ Status = ClassDriver->OpenAdapter( ClassDriver->ClassDriverExtension );
3362+
3363+ if (Status != STATUS_SUCCESS)
3364+ break;
3365+ }
3366+
3367+ ClassDriver = ClassDriver->Next;
3368+ }
3369+
3370+ return ( Status );
3371+}
3372+
3373+AAC_STATUS
3374+AfaCommCloseAdapter(
3375+ IN PVOID Arg
3376+ )
3377+/*++
3378+
3379+Routine Description:
3380+
3381+ This routine will get called by the miniport each time a user issues a CloseHandle on the DeviceObject
3382+ for the adapter.
3383+
3384+ The main purpose of this routine is to cleanup any data structures that have been set up
3385+ while this FileObject has been opened.
3386+
3387+ This routine loops through all of the AdapterFibContext structures to determine if any need
3388+ to be deleted for this FileObject.
3389+
3390+Arguments:
3391+
3392+ Adapter - Pointer to adapter miniport
3393+
3394+ Irp - Pointer to Irp that caused this close
3395+
3396+Return Value:
3397+
3398+ Status value returned from File system driver AdapterClose
3399+
3400+--*/
3401+{
3402+ PAFA_COMM_ADAPTER Adapter = (PAFA_COMM_ADAPTER) Arg;
3403+ PLIST_ENTRY Entry, NextEntry;
3404+ PGET_ADAPTER_FIB_CONTEXT AdapterFibContext;
3405+ AAC_STATUS Status = STATUS_SUCCESS;
3406+ PAFA_CLASS_DRIVER ClassDriver;
3407+
3408+ OsCvLockAcquire(Adapter->AdapterFibMutex);
3409+
3410+ Entry = Adapter->AdapterFibContextList.Flink;
3411+
3412+ //
3413+ // Loop through all of the AdapterFibContext, looking for any that
3414+ // were created with the FileObject that is being closed.
3415+ //
3416+ while (Entry != &Adapter->AdapterFibContextList) {
3417+
3418+ //
3419+ // Extract the AdapterFibContext
3420+ //
3421+ AdapterFibContext = CONTAINING_RECORD( Entry, GET_ADAPTER_FIB_CONTEXT, NextContext );
3422+
3423+ //
3424+ // Save the next entry because CloseAdapterFibContext will delete the AdapterFibContext
3425+ //
3426+ NextEntry = Entry->Flink;
3427+
3428+ Entry = NextEntry;
3429+
3430+ }
3431+
3432+#ifdef unix_config_file
3433+ //
3434+ // If this FileObject had the adapter open for configuration, then release it.
3435+ //
3436+ if ( Adapter->AdapterConfigFileObject == IrpSp->FileObject ) {
3437+
3438+ Adapter->AdapterConfigFileObject = NULL;
3439+
3440+ }
3441+#endif
3442+
3443+ OsCvLockRelease(Adapter->AdapterFibMutex);
3444+
3445+ ClassDriver = Adapter->ClassDriverList;
3446+
3447+ while (ClassDriver) {
3448+
3449+ if (ClassDriver->CloseAdapter) {
3450+
3451+ Status = ClassDriver->CloseAdapter( ClassDriver->ClassDriverExtension );
3452+
3453+ if (Status != STATUS_SUCCESS)
3454+ break;
3455+ }
3456+
3457+ ClassDriver = ClassDriver->Next;
3458+ }
3459+
3460+ return ( Status );
3461+
3462+}
3463+
3464diff -burN linux-2.4.7/drivers/scsi/aacraid/comminit.c linux/drivers/scsi/aacraid/comminit.c
3465--- linux-2.4.7/drivers/scsi/aacraid/comminit.c Wed Dec 31 18:00:00 1969
3466+++ linux/drivers/scsi/aacraid/comminit.c Sat Jul 21 17:55:13 2001
3467@@ -0,0 +1,986 @@
3468+/*++
3469+ * Adaptec aacraid device driver for Linux.
3470+ *
3471+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
3472+ *
3473+ * This program is free software; you can redistribute it and/or modify
3474+ * it under the terms of the GNU General Public License as published by
3475+ * the Free Software Foundation; either version 2, or (at your option)
3476+ * any later version.
3477+ *
3478+ * This program is distributed in the hope that it will be useful,
3479+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3480+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3481+ * GNU General Public License for more details.
3482+ *
3483+ * You should have received a copy of the GNU General Public License
3484+ * along with this program; see the file COPYING. If not, write to
3485+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
3486+ *
3487+ * Module Name:
3488+ * comminit.c
3489+ *
3490+ * Abstract: This supports the initialization of the host adapter commuication interface.
3491+ * This is a platform dependent module for the pci cyclone board.
3492+ *
3493+ --*/
3494+
3495+static char *ident_comminit = "aacraid_ident comminit.c 1.0.6 2000/10/09 Adaptec, Inc.";
3496+
3497+#include "comprocs.h"
3498+
3499+#define BugCheckFileId (FSAFS_BUG_CHECK_COMMINIT)
3500+
3501+VOID
3502+AfaCommBugcheckHandler(
3503+ IN PVOID Buffer,
3504+ IN ULONG Length
3505+ );
3506+
3507+VOID
3508+ThrottlePeriodEndDpcRtn(
3509+ IN PKDPC Dpc,
3510+ IN PVOID DeferredContext,
3511+ IN PVOID SystemArgument1,
3512+ IN PVOID SystemArgument2);
3513+
3514+FSA_COMM_DATA FsaCommData;
3515+
3516+AAC_STATUS
3517+HardInterruptModeration1Changed(
3518+ IN PVOID AdapterContext,
3519+ IN ULONG NewValue
3520+ )
3521+{
3522+ PAFA_COMM_ADAPTER Adapter = AdapterContext;
3523+
3524+ //
3525+ // If we are using interrupt moderation, then disable the interrupt
3526+ // until we need to use it.
3527+ //
3528+ if (FsaCommData.HardInterruptModeration1)
3529+ DisableInterrupt( Adapter, AdapNormCmdNotFull, FALSE );
3530+ else
3531+ EnableInterrupt( Adapter, AdapNormCmdNotFull, FALSE );
3532+
3533+ return (STATUS_SUCCESS);
3534+}
3535+
3536+AAC_STATUS
3537+FsaFibTimeoutChanged(
3538+ IN PVOID AdapterContext,
3539+ IN ULONG NewValue
3540+ )
3541+{
3542+ //
3543+ // scale the new timeout from seconds to 100 nsec units
3544+ //
3545+// FsaCommData.AdapterTimeout = RtlConvertLongToLargeInteger(-10*1000*1000*NewValue);
3546+
3547+ return (STATUS_SUCCESS);
3548+}
3549+
3550+#ifdef GATHER_FIB_TIMES
3551+extern int GatherFibTimes;
3552+#endif
3553+
3554+FSA_USER_VAR FsaCommUserVars[] = {
3555+#ifdef FIB_CHECKSUMS
3556+ { "do_fib_checksums", (PULONG)&FsaCommData.do_fib_checksums, NULL },
3557+#endif
3558+#ifdef GATHER_FIB_TIMES
3559+ { "GatherFibTimes", (PULONG)&GatherFibTimes, NULL },
3560+#endif
3561+ { "EnableAdapterTimeouts", (PULONG)&FsaCommData.EnableAdapterTimeouts, NULL},
3562+ { "EnableInterruptModeration", (PULONG)&FsaCommData.EnableInterruptModeration, NULL },
3563+ { "FsaDataFibsSent", (PULONG) &FsaCommData.FibsSent, NULL },
3564+ { "FsaDataFibRecved", (PULONG) &FsaCommData.FibRecved, NULL },
3565+ { "HardInterruptModeration", (PULONG)&FsaCommData.HardInterruptModeration, NULL},
3566+ { "HardInterruptModeration1", (PULONG)&FsaCommData.HardInterruptModeration1, HardInterruptModeration1Changed},
3567+ { "EnableFibTimeoutBreak", (PULONG)&FsaCommData.EnableFibTimeoutBreak, NULL},
3568+ { "PeakFibsConsumed", (PULONG)&FsaCommData.PeakFibsConsumed, NULL },
3569+ { "ZeroFibsConsumed", (PULONG)&FsaCommData.ZeroFibsConsumed, NULL },
3570+ { "FibTimeoutSeconds", (PULONG) &FsaCommData.FibTimeoutSeconds, FsaFibTimeoutChanged },
3571+};
3572+
3573+#define NUM_COMM_USER_VARS (sizeof(FsaCommUserVars) / sizeof(FSA_USER_VAR) )
3574+
3575+\f
3576+AAC_STATUS
3577+AacCommDriverEntry(
3578+ )
3579+
3580+/*++
3581+
3582+Routine Description:
3583+
3584+ This is the initialization routine for the FileArray Comm layer device driver.
3585+
3586+Arguments:
3587+
3588+ DriverObject - Pointer to driver object created by the system.
3589+
3590+Return Value:
3591+
3592+ AAC_STATUS - The function value is the final status from the initialization
3593+ operation.
3594+
3595+--*/
3596+
3597+{
3598+ AAC_STATUS Status;
3599+ PVOID BugCheckBuffer;
3600+
3601+ RtlZeroMemory( &FsaCommData, sizeof(FSA_COMM_DATA) );
3602+
3603+
3604+ //
3605+ // Load the global timeout value for the adapter timeout
3606+ // Also init the global that enables or disables adapter timeouts
3607+ //
3608+
3609+// FsaCommData.AdapterTimeout = RtlConvertLongToLargeInteger(-10*1000*1000*180);
3610+
3611+ FsaCommData.FibTimeoutSeconds = 180;
3612+
3613+ FsaCommData.EnableAdapterTimeouts = TRUE;
3614+
3615+// FsaCommData.QueueFreeTimeout = RtlConvertLongToLargeInteger(QUEUE_ENTRY_FREE_TIMEOUT);
3616+
3617+#ifdef unix_fib_timeout
3618+ FsaCommData.FibTimeoutIncrement = (180 * 1000 * 1000 * 10) / KeQueryTimeIncrement();
3619+#endif
3620+
3621+ FsaCommData.EnableInterruptModeration = FALSE;
3622+
3623+ //
3624+ // Preload UserVars with all variables from the comm layer. The class layers will
3625+ // include theirs when they register.
3626+ //
3627+
3628+ FsaCommData.UserVars = OsAllocMemory(NUM_COMM_USER_VARS * sizeof(FSA_USER_VAR), OS_ALLOC_MEM_SLEEP );
3629+ FsaCommData.NumUserVars = NUM_COMM_USER_VARS;
3630+
3631+ RtlCopyMemory( FsaCommData.UserVars, &FsaCommUserVars, NUM_COMM_USER_VARS * sizeof(FSA_USER_VAR) );
3632+
3633+
3634+#ifdef AACDISK
3635+ //
3636+ // Call the disk driver to initialize itself.
3637+ //
3638+
3639+ AacDiskDriverEntry();
3640+
3641+#endif
3642+
3643+
3644+
3645+ return (STATUS_SUCCESS);
3646+}
3647+
3648+
3649+VOID
3650+DetachNTQueue(
3651+ IN PAFA_COMM_ADAPTER Adapter,
3652+ IN OUT PCOMM_QUE Queue,
3653+ IN QUEUE_TYPES WhichQueue
3654+ )
3655+/*++
3656+
3657+Routine Description:
3658+
3659+ This routine will release all of the resources used by a given queue.
3660+
3661+Arguments:
3662+
3663+ Adapter - Which adapter the queue belongs to
3664+ Queue - Pointer to the queue itself
3665+ WhichQueue - Identifies which of the host queues this is.
3666+
3667+Return Value:
3668+
3669+ NONE.
3670+
3671+--*/
3672+{
3673+ switch (WhichQueue) {
3674+
3675+ case HostNormCmdQueue:
3676+
3677+ Os_remove_softintr( Queue->ConsumerRoutine );
3678+ OsSpinLockDestroy( Queue->QueueLock );
3679+ OsCv_destroy( &Queue->CommandReady );
3680+
3681+ break;
3682+
3683+ case HostHighCmdQueue:
3684+
3685+ Os_remove_softintr( Queue->ConsumerRoutine );
3686+ OsSpinLockDestroy( Queue->QueueLock );
3687+ OsCv_destroy( &Queue->CommandReady );
3688+
3689+ break;
3690+
3691+ case HostNormRespQueue:
3692+
3693+ Os_remove_softintr( Queue->ConsumerRoutine );
3694+ OsSpinLockDestroy( Queue->QueueLock );
3695+ break;
3696+
3697+ case HostHighRespQueue:
3698+
3699+ Os_remove_softintr( Queue->ConsumerRoutine );
3700+ OsSpinLockDestroy( Queue->QueueLock );
3701+ break;
3702+
3703+ case AdapNormCmdQueue:
3704+ case AdapHighCmdQueue:
3705+ case AdapNormRespQueue:
3706+ case AdapHighRespQueue:
3707+ OsCv_destroy( &Queue->QueueFull );
3708+ break;
3709+ }
3710+}
3711+
3712+VOID
3713+InitializeNTQueue(
3714+ IN PAFA_COMM_ADAPTER Adapter,
3715+ IN OUT PCOMM_QUE Queue,
3716+ IN QUEUE_TYPES WhichQueue
3717+ )
3718+/*++
3719+
3720+Routine Description:
3721+
3722+ Will initialize all entries in the queue that is NT specific.
3723+
3724+Arguments:
3725+
3726+Return Value:
3727+
3728+ Nothing there is nothing to allocate so nothing should fail
3729+
3730+--*/
3731+{
3732+
3733+ Queue->NumOutstandingIos = 0;
3734+
3735+ //
3736+ // Store a pointer to the adapter structure.
3737+ //
3738+
3739+ Queue->Adapter = Adapter;
3740+
3741+ InitializeListHead( &Queue->OutstandingIoQueue );
3742+
3743+ switch (WhichQueue) {
3744+
3745+ case HostNormCmdQueue:
3746+
3747+ OsCv_init( &Queue->CommandReady);
3748+ OsSpinLockInit( Queue->QueueLock, Adapter->SpinLockCookie);
3749+ if (ddi_add_softintr( Adapter->Dip, DDI_SOFTINT_HIGH, &Queue->ConsumerRoutine, NULL,
3750+ NULL, (PUNIX_INTR_HANDLER)HostCommandNormDpc,
3751+ (caddr_t)Queue ) != DDI_SUCCESS) {
3752+
3753+ cmn_err(CE_CONT, "OS_addr_intr failed\n");
3754+ }
3755+
3756+ InitializeListHead(&Queue->CommandQueue);
3757+
3758+ break;
3759+
3760+ case HostHighCmdQueue:
3761+
3762+ OsCv_init( &Queue->CommandReady);
3763+ OsSpinLockInit( Queue->QueueLock, Adapter->SpinLockCookie);
3764+ if (ddi_add_softintr( Adapter->Dip, DDI_SOFTINT_HIGH, &Queue->ConsumerRoutine, NULL,
3765+ NULL, (PUNIX_INTR_HANDLER)HostCommandHighDpc,
3766+ (caddr_t) Queue ) != DDI_SUCCESS) {
3767+
3768+ cmn_err(CE_CONT, "OS_addr_intr failed\n");
3769+ }
3770+
3771+ InitializeListHead(&Queue->CommandQueue);
3772+ break;
3773+
3774+ case HostNormRespQueue:
3775+
3776+ OsSpinLockInit( Queue->QueueLock, Adapter->SpinLockCookie);
3777+ if (ddi_add_softintr( Adapter->Dip, DDI_SOFTINT_HIGH, &Queue->ConsumerRoutine, NULL,
3778+ NULL, (PUNIX_INTR_HANDLER)HostResponseNormalDpc,
3779+ (caddr_t) Queue ) != DDI_SUCCESS) {
3780+
3781+ cmn_err(CE_CONT, "OS_addr_intr failed\n");
3782+ }
3783+ break;
3784+
3785+ case HostHighRespQueue:
3786+
3787+
3788+ OsSpinLockInit( Queue->QueueLock, Adapter->SpinLockCookie);
3789+ if (ddi_add_softintr( Adapter->Dip, DDI_SOFTINT_HIGH, &Queue->ConsumerRoutine, NULL,
3790+ NULL, (PUNIX_INTR_HANDLER)HostResponseHighDpc,
3791+ (caddr_t) Queue ) != DDI_SUCCESS) {
3792+
3793+ cmn_err(CE_CONT, "OS_addr_intr failed\n");
3794+ }
3795+ break;
3796+
3797+ case AdapNormCmdQueue:
3798+ case AdapHighCmdQueue:
3799+ case AdapNormRespQueue:
3800+ case AdapHighRespQueue:
3801+
3802+ OsCv_init( &Queue->QueueFull);
3803+ break;
3804+ }
3805+}
3806+
3807+BOOLEAN
3808+StartFsaCommandThreads(PAFA_COMM_ADAPTER Adapter)
3809+/*++
3810+
3811+Routine Description:
3812+
3813+ Create and start the command receiver threads.
3814+
3815+Arguments:
3816+
3817+
3818+Return Value:
3819+
3820+ Nothing
3821+
3822+--*/
3823+
3824+{
3825+ return(TRUE);
3826+}
3827+
3828+
3829+
3830+/*++
3831+
3832+Routine Description:
3833+
3834+ This routine gets called to detach all resources that have been allocated for
3835+ this adapter.
3836+
3837+Arguments:
3838+
3839+ Adapter - Pointer to the adapter structure to detach.
3840+
3841+Return Value:
3842+
3843+ TRUE - All resources have been properly released.
3844+ FALSE - An error occured while trying to release resources.
3845+--*/
3846+BOOLEAN
3847+AacCommDetachAdapter (IN PAFA_COMM_ADAPTER Adapter)
3848+{
3849+ PAFA_CLASS_DRIVER ClassDriver;
3850+ //
3851+ // First remove this adapter from the list of adapters.
3852+ //
3853+
3854+ if (FsaCommData.AdapterList == Adapter) {
3855+
3856+ FsaCommData.AdapterList = Adapter->NextAdapter;
3857+
3858+ } else {
3859+
3860+ PAFA_COMM_ADAPTER CurrentAdapter, NextAdapter;
3861+
3862+ CurrentAdapter = FsaCommData.AdapterList;
3863+ NextAdapter = CurrentAdapter->NextAdapter;
3864+
3865+ while (NextAdapter) {
3866+
3867+ if (NextAdapter == Adapter) {
3868+
3869+ CurrentAdapter->NextAdapter = NextAdapter->NextAdapter;
3870+ break;
3871+
3872+ }
3873+
3874+ CurrentAdapter = NextAdapter;
3875+ NextAdapter = CurrentAdapter->NextAdapter;
3876+ }
3877+ }
3878+
3879+ //
3880+ // First send a shutdown to the adapter.
3881+ //
3882+
3883+ AfaCommShutdown( Adapter );
3884+
3885+ //
3886+ // Destroy the FibContextZone for this adapter. This will free up all
3887+ // of the fib space used by this adapter.
3888+ //
3889+
3890+ FsaFreeFibContextZone( Adapter );
3891+
3892+ //
3893+ // Destroy the mutex used for synch'ing adapter fibs.
3894+ //
3895+
3896+ OsCvLockDestroy( Adapter->AdapterFibMutex );
3897+
3898+ //
3899+ // Detach all of the host queues.
3900+ //
3901+
3902+ DetachNTQueue( Adapter, &Adapter->CommRegion->AdapHighRespQue, AdapHighRespQueue );
3903+ DetachNTQueue( Adapter, &Adapter->CommRegion->AdapNormRespQue, AdapNormRespQueue );
3904+ DetachNTQueue( Adapter, &Adapter->CommRegion->HostHighRespQue, HostHighRespQueue );
3905+ DetachNTQueue( Adapter, &Adapter->CommRegion->HostNormRespQue, HostNormRespQueue );
3906+ DetachNTQueue( Adapter, &Adapter->CommRegion->AdapHighCmdQue, AdapHighCmdQueue );
3907+ DetachNTQueue( Adapter, &Adapter->CommRegion->AdapNormCmdQue, AdapNormCmdQueue );
3908+ DetachNTQueue( Adapter, &Adapter->CommRegion->HostHighCmdQue, HostHighCmdQueue );
3909+ DetachNTQueue( Adapter, &Adapter->CommRegion->HostNormCmdQue, HostNormCmdQueue );
3910+
3911+ //
3912+ // Destroy the mutex used to protect the FibContextZone
3913+ //
3914+
3915+ OsSpinLockDestroy( Adapter->FibContextZoneSpinLock );
3916+
3917+ //
3918+ // Call the miniport to free the space allocated for the shared comm queues
3919+ // between the host and the adapter.
3920+ //
3921+
3922+ FsaFreeAdapterCommArea( Adapter );
3923+
3924+ //
3925+ // Free the memory used by the comm region for this adapter
3926+ //
3927+
3928+ OsFreeMemory( Adapter->CommRegion, sizeof(COMM_REGION) );
3929+
3930+ //
3931+ // Free the memory used by the adapter structure.
3932+ //
3933+ ClassDriver = Adapter->ClassDriverList;
3934+ Adapter->ClassDriverList = Adapter->ClassDriverList->Next;
3935+ OsFreeMemory( ClassDriver, sizeof(AFA_CLASS_DRIVER) );
3936+
3937+ OsFreeMemory( Adapter, sizeof(AFA_COMM_ADAPTER) );
3938+
3939+ return (TRUE);
3940+}
3941+
3942+PVOID
3943+AfaCommInitNewAdapter (IN PFSA_NEW_ADAPTER NewAdapter)
3944+{
3945+ PVOID BugCheckBuffer;
3946+ PAFA_COMM_ADAPTER Adapter;
3947+ MAPFIB_CONTEXT MapFibContext;
3948+ LARGE_INTEGER Time;
3949+ char ErrorBuffer[60];
3950+
3951+ Adapter = (PAFA_COMM_ADAPTER) OsAllocMemory( sizeof(AFA_COMM_ADAPTER) , OS_ALLOC_MEM_SLEEP );
3952+
3953+ if (Adapter == NULL)
3954+ return (NULL);
3955+
3956+ RtlZeroMemory(Adapter, sizeof(AFA_COMM_ADAPTER));
3957+
3958+
3959+ //
3960+ // Save the current adapter number and increment the total number.
3961+ //
3962+
3963+ Adapter->AdapterNumber = FsaCommData.TotalAdapters++;
3964+
3965+
3966+ //
3967+ // Fill in the pointer back to the device specific structures.
3968+ // The device specific driver has also passed a pointer for us to
3969+ // fill in with the Adapter object that we have created.
3970+ //
3971+
3972+ Adapter->AdapterExtension = NewAdapter->AdapterExtension;
3973+ Adapter->AdapterFuncs = NewAdapter->AdapterFuncs;
3974+ Adapter->InterruptsBelowDpc = NewAdapter->AdapterInterruptsBelowDpc;
3975+ Adapter->AdapterUserVars = NewAdapter->AdapterUserVars;
3976+ Adapter->AdapterUserVarsSize = NewAdapter->AdapterUserVarsSize;
3977+
3978+ Adapter->Dip = NewAdapter->Dip;
3979+
3980+ //
3981+ // Fill in Our address into the function dispatch table
3982+ //
3983+
3984+ NewAdapter->AdapterFuncs->InterruptHost = AfaCommInterruptHost;
3985+ NewAdapter->AdapterFuncs->OpenAdapter = AfaCommOpenAdapter;
3986+ NewAdapter->AdapterFuncs->CloseAdapter = AfaCommCloseAdapter;
3987+ NewAdapter->AdapterFuncs->DeviceControl = AfaCommAdapterDeviceControl;
3988+
3989+ //
3990+ // Ok now init the communication subsystem
3991+ //
3992+
3993+ Adapter->CommRegion = (PCOMM_REGION) OsAllocMemory(sizeof(COMM_REGION), OS_ALLOC_MEM_SLEEP);
3994+ if (Adapter->CommRegion == NULL) {
3995+ cmn_err(CE_WARN, "Error could not allocate comm region.\n");
3996+ return (NULL);
3997+ }
3998+ RtlZeroMemory(Adapter->CommRegion, sizeof(COMM_REGION));
3999+
4000+ //
4001+ // Get a pointer to the iblock_cookie
4002+ //
4003+
4004+ ddi_get_soft_iblock_cookie( Adapter->Dip, DDI_SOFTINT_HIGH, &Adapter->SpinLockCookie );
4005+
4006+ if (!CommInit(Adapter)) {
4007+ FsaCommPrint("Failed to init the commuication subsystem.\n");
4008+ return(NULL);
4009+ }
4010+
4011+
4012+ //
4013+ // Initialize the list of AdapterFibContext's.
4014+ //
4015+
4016+ InitializeListHead(&Adapter->AdapterFibContextList);
4017+
4018+ //
4019+ // Initialize the fast mutex used for synchronization of the adapter fibs
4020+ //
4021+
4022+ Adapter->AdapterFibMutex = OsCvLockAlloc();
4023+ OsCvLockInit(Adapter->AdapterFibMutex, NULL);
4024+
4025+ //
4026+ // Allocate and start the FSA command threads. These threads will handle
4027+ // command requests from the adapter. They will wait on an event then pull
4028+ // all CDBs off the thread's queue. Each CDB will be given to a worker thread
4029+ // upto a defined limit. When that limit is reached wait a event will be waited
4030+ // on till a worker thread is finished.
4031+ //
4032+
4033+ if (!StartFsaCommandThreads(Adapter)) {
4034+ FsaCommPrint("Fsainit could not initilize the command receiver threads.\n");
4035+ return (NULL);
4036+ }
4037+
4038+#ifdef unix_crash_dump
4039+ //
4040+ // Allocate and map a fib for use by the synch path, which is used for crash
4041+ // dumps.
4042+ //
4043+ // Allocate an entire page so that alignment is correct.
4044+ //
4045+
4046+ Adapter->SyncFib = OsAllocMemory( PAGE_SIZE, OS_ALLOC_MEM_SLEEP );
4047+ MapFibContext.Fib = Adapter->SyncFib;
4048+ MapFibContext.Size = sizeof(FIB);
4049+ MapFib( Adapter, &MapFibContext );
4050+ Adapter->SyncFibPhysicalAddress = MapFibContext.LogicalFibAddress.LowPart;
4051+#endif
4052+
4053+ Adapter->CommFuncs.SizeOfAfaCommFuncs = sizeof(AFACOMM_FUNCS);
4054+
4055+ Adapter->CommFuncs.AllocateFib = AllocateFib;
4056+
4057+ Adapter->CommFuncs.FreeFib = FreeFib;
4058+ Adapter->CommFuncs.FreeFibFromDpc = FreeFibFromDpc;
4059+ Adapter->CommFuncs.DeallocateFib = DeallocateFib;
4060+
4061+ Adapter->CommFuncs.InitializeFib = InitializeFib;
4062+ Adapter->CommFuncs.GetFibData = FsaGetFibData;
4063+ Adapter->CommFuncs.SendFib = SendFib;
4064+ Adapter->CommFuncs.CompleteFib = CompleteFib;
4065+ Adapter->CommFuncs.CompleteAdapterFib = CompleteAdapterFib;
4066+
4067+ Adapter->CommFuncs.SendSynchFib = SendSynchFib;
4068+
4069+ Adapter->CommFuncs.FreeDmaResources = Adapter->AdapterFuncs->FreeDmaResources;
4070+ Adapter->CommFuncs.BuildSgMap = Adapter->AdapterFuncs->BuildSgMap;
4071+
4072+ //
4073+ // Add this adapter in to our Adapter List.
4074+ //
4075+
4076+ Adapter->NextAdapter = FsaCommData.AdapterList;
4077+ FsaCommData.AdapterList = Adapter;
4078+
4079+ NewAdapter->Adapter = Adapter;
4080+
4081+// AfaDiskInitNewAdapter( Adapter->AdapterNumber, Adapter );
4082+
4083+ return (Adapter);
4084+}
4085+
4086+AAC_STATUS
4087+CommInitialize(
4088+ PAFA_COMM_ADAPTER Adapter
4089+ )
4090+{
4091+ //
4092+ // Now allocate and initialize the zone structures used as our pool
4093+ // of FIB context records. The size of the zone is based on the
4094+ // system memory size. We also initialize the mutex used to protect
4095+ // the zone.
4096+ //
4097+ Adapter->FibContextZoneSpinLock = OsSpinLockAlloc();
4098+ OsSpinLockInit( Adapter->FibContextZoneSpinLock, Adapter->SpinLockCookie );
4099+
4100+ Adapter->FibContextZoneExtendSize = 64;
4101+
4102+ return (STATUS_SUCCESS);
4103+}
4104+
4105+
4106+
4107+/*++
4108+
4109+Routine Description:
4110+
4111+ Initializes the data structures that are required for the FSA commuication
4112+ interface to operate.
4113+
4114+Arguments:
4115+
4116+ None - all global or allocated data.
4117+
4118+Return Value:
4119+
4120+ TRUE - if we were able to init the commuication interface.
4121+ FALSE - If there were errors initing. This is a fatal error.
4122+--*/
4123+BOOLEAN
4124+CommInit(PAFA_COMM_ADAPTER Adapter)
4125+{
4126+
4127+ ULONG SizeOfHeaders = (sizeof(QUEUE_INDEX) * NUMBER_OF_COMM_QUEUES) * 2;
4128+ ULONG SizeOfQueues = sizeof(QUEUE_ENTRY) * TOTAL_QUEUE_ENTRIES;
4129+ PQUEUE_INDEX Headers;
4130+ PQUEUE_ENTRY Queues;
4131+ ULONG TotalSize;
4132+ PCOMM_REGION CommRegion = Adapter->CommRegion;
4133+
4134+ CommInitialize( Adapter );
4135+
4136+ FsaCommPrint("CommInit: Queue entry size is 0x%x, Queue index size is 0x%x, Number of total entries is 0x%x, # queues = 0x%x.\n",
4137+ sizeof(QUEUE_ENTRY), sizeof(QUEUE_INDEX), TOTAL_QUEUE_ENTRIES, NUMBER_OF_COMM_QUEUES);
4138+ //
4139+ //
4140+ // Allocate the physically contigous space for the commuication queue
4141+ // headers.
4142+ //
4143+
4144+ TotalSize = SizeOfHeaders + SizeOfQueues;
4145+
4146+ if (!FsaAllocateAdapterCommArea(Adapter, (PVOID *)&Headers, TotalSize, QUEUE_ALIGNMENT))
4147+ return (FALSE);
4148+
4149+ Queues = (PQUEUE_ENTRY)((PUCHAR)Headers + SizeOfHeaders);
4150+
4151+ if (ddi_add_softintr( Adapter->Dip, DDI_SOFTINT_HIGH, &CommRegion->QueueNotFullDpc, NULL,
4152+ NULL, (PUNIX_INTR_HANDLER)CommonNotFullDpc,
4153+ (caddr_t)CommRegion ) != DDI_SUCCESS) {
4154+
4155+ cmn_err(CE_CONT, "Os_addr_intr failed\n");
4156+ }
4157+
4158+
4159+ // Adapter to Host normal priority Command queue
4160+
4161+
4162+ CommRegion->HostNormCmdQue.Headers.ProducerIndex = Headers++;
4163+ CommRegion->HostNormCmdQue.Headers.ConsumerIndex = Headers++;
4164+ *CommRegion->HostNormCmdQue.Headers.ProducerIndex = HOST_NORM_CMD_ENTRIES;
4165+ *CommRegion->HostNormCmdQue.Headers.ConsumerIndex = HOST_NORM_CMD_ENTRIES;
4166+
4167+ CommRegion->HostNormCmdQue.SavedIrql = 0;
4168+ CommRegion->HostNormCmdQue.BaseAddress = Queues;
4169+ CommRegion->HostNormCmdQue.QueueEntries = HOST_NORM_CMD_ENTRIES;
4170+
4171+ CommRegion->HostNormCmdQue.QueueLock = OsSpinLockAlloc();
4172+ if (CommRegion->HostNormCmdQue.QueueLock == NULL) {
4173+ return (FALSE);
4174+ }
4175+ InitializeNTQueue(Adapter, &CommRegion->HostNormCmdQue, HostNormCmdQueue);
4176+
4177+
4178+ Queues += HOST_NORM_CMD_ENTRIES;
4179+
4180+ // Adapter to Host high priority command queue
4181+
4182+ CommRegion->HostHighCmdQue.Headers.ProducerIndex = Headers++;
4183+ CommRegion->HostHighCmdQue.Headers.ConsumerIndex = Headers++;
4184+ *CommRegion->HostHighCmdQue.Headers.ProducerIndex = HOST_HIGH_CMD_ENTRIES;
4185+ *CommRegion->HostHighCmdQue.Headers.ConsumerIndex = HOST_HIGH_CMD_ENTRIES;
4186+
4187+ CommRegion->HostHighCmdQue.SavedIrql = 0;
4188+ CommRegion->HostHighCmdQue.BaseAddress = Queues;
4189+ CommRegion->HostHighCmdQue.QueueEntries = HOST_HIGH_CMD_ENTRIES;
4190+// CommRegion->HostHighCmdQue.QueueLock = (PKSPIN_LOCK) ExAllocatePool(NonPagedPool, sizeof(KSPIN_LOCK));
4191+ CommRegion->HostHighCmdQue.QueueLock = OsSpinLockAlloc();
4192+ if (CommRegion->HostHighCmdQue.QueueLock == NULL) {
4193+ return (FALSE);
4194+ }
4195+ InitializeNTQueue(Adapter, &CommRegion->HostHighCmdQue, HostHighCmdQueue);
4196+
4197+ Queues += HOST_HIGH_CMD_ENTRIES;
4198+
4199+ // Host to adapter normal priority command queue
4200+
4201+ CommRegion->AdapNormCmdQue.Headers.ProducerIndex = Headers++;
4202+ CommRegion->AdapNormCmdQue.Headers.ConsumerIndex = Headers++;
4203+ *CommRegion->AdapNormCmdQue.Headers.ProducerIndex = ADAP_NORM_CMD_ENTRIES;
4204+ *CommRegion->AdapNormCmdQue.Headers.ConsumerIndex = ADAP_NORM_CMD_ENTRIES;
4205+
4206+ CommRegion->AdapNormCmdQue.SavedIrql = 0;
4207+ CommRegion->AdapNormCmdQue.BaseAddress = Queues;
4208+ CommRegion->AdapNormCmdQue.QueueEntries = ADAP_NORM_CMD_ENTRIES;
4209+ InitializeNTQueue(Adapter, &CommRegion->AdapNormCmdQue, AdapNormCmdQueue);
4210+
4211+ Queues += ADAP_NORM_CMD_ENTRIES;
4212+
4213+ // host to adapter high priority command queue
4214+
4215+ CommRegion->AdapHighCmdQue.Headers.ProducerIndex = Headers++;
4216+ CommRegion->AdapHighCmdQue.Headers.ConsumerIndex = Headers++;
4217+ *CommRegion->AdapHighCmdQue.Headers.ProducerIndex = ADAP_HIGH_CMD_ENTRIES;
4218+ *CommRegion->AdapHighCmdQue.Headers.ConsumerIndex = ADAP_HIGH_CMD_ENTRIES;
4219+
4220+ CommRegion->AdapHighCmdQue.SavedIrql = 0;
4221+ CommRegion->AdapHighCmdQue.BaseAddress = Queues;
4222+ CommRegion->AdapHighCmdQue.QueueEntries = ADAP_HIGH_CMD_ENTRIES;
4223+ InitializeNTQueue(Adapter, &CommRegion->AdapHighCmdQue, AdapHighCmdQueue);
4224+
4225+ Queues += ADAP_HIGH_CMD_ENTRIES;
4226+
4227+ // adapter to host normal priority response queue
4228+
4229+ CommRegion->HostNormRespQue.Headers.ProducerIndex = Headers++;
4230+ CommRegion->HostNormRespQue.Headers.ConsumerIndex = Headers++;
4231+ *CommRegion->HostNormRespQue.Headers.ProducerIndex = HOST_NORM_RESP_ENTRIES;
4232+ *CommRegion->HostNormRespQue.Headers.ConsumerIndex = HOST_NORM_RESP_ENTRIES;
4233+
4234+ CommRegion->HostNormRespQue.SavedIrql = 0;
4235+ CommRegion->HostNormRespQue.BaseAddress = Queues;
4236+ CommRegion->HostNormRespQue.QueueEntries = HOST_NORM_RESP_ENTRIES;
4237+// CommRegion->HostNormRespQue.QueueLock = (PKSPIN_LOCK) ExAllocatePool(NonPagedPool, sizeof(KSPIN_LOCK));
4238+ CommRegion->HostNormRespQue.QueueLock = OsSpinLockAlloc();
4239+ if (CommRegion->HostNormRespQue.QueueLock == NULL) {
4240+ return (FALSE);
4241+ }
4242+ InitializeNTQueue(Adapter, &CommRegion->HostNormRespQue, HostNormRespQueue);
4243+
4244+ Queues += HOST_NORM_RESP_ENTRIES;
4245+
4246+ // adapter to host high priority response queue
4247+
4248+ CommRegion->HostHighRespQue.Headers.ProducerIndex = Headers++;
4249+ CommRegion->HostHighRespQue.Headers.ConsumerIndex = Headers++;
4250+ *CommRegion->HostHighRespQue.Headers.ProducerIndex = HOST_HIGH_RESP_ENTRIES;
4251+ *CommRegion->HostHighRespQue.Headers.ConsumerIndex = HOST_HIGH_RESP_ENTRIES;
4252+
4253+ CommRegion->HostHighRespQue.SavedIrql = 0;
4254+ CommRegion->HostHighRespQue.BaseAddress = Queues;
4255+ CommRegion->HostHighRespQue.QueueEntries = HOST_HIGH_RESP_ENTRIES;
4256+// CommRegion->HostHighRespQue.QueueLock = (PKSPIN_LOCK) ExAllocatePool(NonPagedPool, sizeof(KSPIN_LOCK));
4257+ CommRegion->HostHighRespQue.QueueLock = OsSpinLockAlloc();
4258+ if (CommRegion->HostHighRespQue.QueueLock == NULL) {
4259+ return (FALSE);
4260+ }
4261+ InitializeNTQueue(Adapter, &CommRegion->HostHighRespQue, HostHighRespQueue);
4262+
4263+ Queues += HOST_HIGH_RESP_ENTRIES;
4264+
4265+ // host to adapter normal priority response queue
4266+
4267+ CommRegion->AdapNormRespQue.Headers.ProducerIndex = Headers++;
4268+ CommRegion->AdapNormRespQue.Headers.ConsumerIndex = Headers++;
4269+ *CommRegion->AdapNormRespQue.Headers.ProducerIndex = ADAP_NORM_RESP_ENTRIES;
4270+ *CommRegion->AdapNormRespQue.Headers.ConsumerIndex = ADAP_NORM_RESP_ENTRIES;
4271+
4272+ CommRegion->AdapNormRespQue.SavedIrql = 0;
4273+ CommRegion->AdapNormRespQue.BaseAddress = Queues;
4274+ CommRegion->AdapNormRespQue.QueueEntries = ADAP_NORM_RESP_ENTRIES;
4275+ InitializeNTQueue(Adapter, &CommRegion->AdapNormRespQue, AdapNormRespQueue);
4276+
4277+ Queues += ADAP_NORM_RESP_ENTRIES;
4278+
4279+ // host to adapter high priority response queue
4280+
4281+ CommRegion->AdapHighRespQue.Headers.ProducerIndex = Headers++;
4282+ CommRegion->AdapHighRespQue.Headers.ConsumerIndex = Headers++;
4283+ *CommRegion->AdapHighRespQue.Headers.ProducerIndex = ADAP_HIGH_RESP_ENTRIES;
4284+ *CommRegion->AdapHighRespQue.Headers.ConsumerIndex = ADAP_HIGH_RESP_ENTRIES;
4285+
4286+ CommRegion->AdapHighRespQue.SavedIrql = 0;
4287+ CommRegion->AdapHighRespQue.BaseAddress = Queues;
4288+ CommRegion->AdapHighRespQue.QueueEntries = ADAP_HIGH_RESP_ENTRIES;
4289+ InitializeNTQueue(Adapter, &CommRegion->AdapHighRespQue, AdapHighRespQueue);
4290+
4291+ CommRegion->AdapNormCmdQue.QueueLock = CommRegion->HostNormRespQue.QueueLock;
4292+ CommRegion->AdapHighCmdQue.QueueLock = CommRegion->HostHighRespQue.QueueLock;
4293+ CommRegion->AdapNormRespQue.QueueLock = CommRegion->HostNormCmdQue.QueueLock;
4294+ CommRegion->AdapHighRespQue.QueueLock = CommRegion->HostHighCmdQue.QueueLock;
4295+
4296+ return(TRUE);
4297+}
4298+
4299+AAC_STATUS
4300+AfaCommShutdown(
4301+ PAFA_COMM_ADAPTER Adapter
4302+ )
4303+/*++
4304+
4305+Routine Description:
4306+
4307+ This routine will send a shutdown request to each adapter.
4308+
4309+Arguments:
4310+
4311+ Adapter - which adapter to send the shutdown to.
4312+
4313+Return Value:
4314+
4315+ NT Status success.
4316+
4317+--*/
4318+
4319+{
4320+ PFIB_CONTEXT FibContext;
4321+ PCLOSECOMMAND CloseCommand;
4322+ AAC_STATUS Status;
4323+
4324+ FibContext = AllocateFib( Adapter );
4325+
4326+ InitializeFib( FibContext );
4327+
4328+ CloseCommand = (PCLOSECOMMAND) FsaGetFibData( FibContext );
4329+
4330+ CloseCommand->Command = VM_CloseAll;
4331+ CloseCommand->ContainerId = 0xffffffff;
4332+
4333+ Status = SendFib( ContainerCommand, FibContext, sizeof(CLOSECOMMAND), FsaNormal, TRUE, NULL, TRUE, NULL, NULL );
4334+
4335+ if (Status != STATUS_SUCCESS) {
4336+
4337+ FreeFib( FibContext );
4338+
4339+ goto ret;
4340+
4341+ }
4342+
4343+ CompleteFib( FibContext );
4344+
4345+ FreeFib( FibContext );
4346+
4347+
4348+ Status = STATUS_SUCCESS;
4349+
4350+ret:
4351+
4352+ return (Status);
4353+
4354+}
4355+
4356+VOID
4357+AfaCommBugcheckHandler(
4358+ IN PVOID Buffer,
4359+ IN ULONG Length
4360+ )
4361+/*++
4362+
4363+Routine Description:
4364+
4365+ This routine will shutdown the adapter if there is a bugcheck and
4366+ copy the shutdown data from the adapter response into the buffer
4367+ so it will show up in the host dump file.
4368+p
4369+Arguments:
4370+
4371+ Buffer - This buffer will be written to the host dump by nt for us.
4372+
4373+ Length - The size of the buffer.
4374+
4375+Return Value:
4376+
4377+ N/A
4378+
4379+--*/
4380+{
4381+ PAFA_COMM_ADAPTER Adapter = FsaCommData.AdapterList;
4382+
4383+ while (Adapter) {
4384+
4385+ NotifyAdapter(Adapter, HostShutdown);
4386+
4387+ Adapter = Adapter->NextAdapter;
4388+
4389+ }
4390+
4391+}
4392+
4393+VOID
4394+FsaCommLogEvent(
4395+ PFIB_CONTEXT FibContext,
4396+ PDEVICE_OBJECT DeviceObject,
4397+ AAC_STATUS FsaStatus,
4398+ AAC_STATUS AacStatus,
4399+ ULONG LocationCode,
4400+ USHORT Category,
4401+ PUCHAR String,
4402+ BOOLEAN DumpFib
4403+)
4404+{
4405+}
4406+
4407+AfaCommProbeDisks(
4408+ PAFA_COMM_ADAPTER Adapter
4409+ )
4410+{
4411+ PMNTINFO DiskInfo;
4412+ PMNTINFORESPONSE DiskInfoResponse;
4413+ AAC_STATUS Status;
4414+ PCOMM_FIB_CONTEXT FibContext;
4415+
4416+ FibContext = AllocateFib( Adapter );
4417+
4418+ InitializeFib( FibContext );
4419+
4420+ DiskInfo = (PMNTINFO) FibContext->Fib->data;
4421+ DiskInfo->Command = VM_NameServe;
4422+ DiskInfo->MntCount = 0;
4423+ DiskInfo->MntType = FT_FILESYS;
4424+
4425+ Status = SendFib(ContainerCommand,
4426+ FibContext,
4427+ sizeof(MNTINFO),
4428+ FsaNormal,
4429+ TRUE,
4430+ NULL,
4431+ TRUE,
4432+ NULL,
4433+ NULL);
4434+
4435+ DiskInfoResponse = (PMNTINFORESPONSE) FibContext->Fib->data;
4436+
4437+ if (DiskInfoResponse->MntRespCount) {
4438+
4439+ cmn_err(CE_CONT, "container found on adapter, size = 0x%x blocks\n",
4440+ DiskInfoResponse->MntTable[0].Capacity);
4441+
4442+ } else {
4443+
4444+ cmn_err(CE_CONT, "no containers found on adapter\n");
4445+
4446+ }
4447+
4448+ CompleteFib( FibContext );
4449+
4450+ FreeFib( FibContext );
4451+}
4452+
4453+
4454diff -burN linux-2.4.7/drivers/scsi/aacraid/commsup.c linux/drivers/scsi/aacraid/commsup.c
4455--- linux-2.4.7/drivers/scsi/aacraid/commsup.c Wed Dec 31 18:00:00 1969
4456+++ linux/drivers/scsi/aacraid/commsup.c Sat Jul 21 17:55:13 2001
4457@@ -0,0 +1,2185 @@
4458+/*++
4459+ * Adaptec aacraid device driver for Linux.
4460+ *
4461+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
4462+ *
4463+ * This program is free software; you can redistribute it and/or modify
4464+ * it under the terms of the GNU General Public License as published by
4465+ * the Free Software Foundation; either version 2, or (at your option)
4466+ * any later version.
4467+ *
4468+ * This program is distributed in the hope that it will be useful,
4469+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4470+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4471+ * GNU General Public License for more details.
4472+ *
4473+ * You should have received a copy of the GNU General Public License
4474+ * along with this program; see the file COPYING. If not, write to
4475+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
4476+ *
4477+ * Module Name:
4478+ * commsup.c
4479+ *
4480+ * Abstract: Contain all routines that are required for FSA host/adapter
4481+ * commuication.
4482+ *
4483+ *
4484+ --*/
4485+
4486+static char *ident_commsup = "aacraid_ident commsup.c 1.0.7 2000/10/11 Adaptec, Inc.";
4487+
4488+#include "comprocs.h"
4489+
4490+#define BugCheckFileId (FSAFS_BUG_CHECK_COMMSUP)
4491+
4492+int CommPrinting;
4493+
4494+void
4495+ThrottleExceptionHandler(
4496+ IN PCOMM_REGION CommRegion,
4497+ AAC_STATUS Status
4498+ );
4499+
4500+void ThrottlePeriodEndDpcRtn(
4501+ IN PKDPC Dpc,
4502+ IN PVOID DeferredContext,
4503+ IN PVOID SystemArgument1,
4504+ IN PVOID SystemArgument2
4505+ );
4506+
4507+
4508+/*++
4509+
4510+Routine Description:
4511+
4512+ This routine will free all resources used by a given FibContextSegment.
4513+
4514+Arguments:
4515+
4516+ Adapter - The adapter that this COMM_FIB_CONTEXT will communicate with.
4517+ ZoneSegment - The segment to release resources from.
4518+
4519+Return Value:
4520+
4521+ TRUE - All resources were properly freed.
4522+ FALSE - An Error occured while freeing resources.
4523+
4524+--*/
4525+BOOLEAN
4526+FsaFreeFibContextSegment (PAFA_COMM_ADAPTER Adapter,
4527+ PFIB_CONTEXT_ZONE_SEGMENT ZoneSegment)
4528+{
4529+ PCOMM_FIB_CONTEXT FibContext;
4530+ int i;
4531+
4532+ // Account for the ZONE_SEGMENT_HEADER before the first actual FibContext.
4533+
4534+ for (i = 0, FibContext = (PCOMM_FIB_CONTEXT)((PUCHAR)ZoneSegment->FibContextSegment + sizeof(ZONE_SEGMENT_HEADER));
4535+ i < ZoneSegment->ExtendSize; i++, FibContext++) {
4536+
4537+ OsCvLockDestroy( FibContext->FsaEventMutex );
4538+ OsCv_destroy( &FibContext->FsaEvent );
4539+
4540+ }
4541+
4542+ UnmapAndFreeFibSpace( Adapter, &ZoneSegment->MapFibContext );
4543+
4544+ OsFreeMemory( ZoneSegment->FibContextSegment, ZoneSegment->FibContextSegmentSize );
4545+
4546+ OsFreeMemory( ZoneSegment, sizeof( FIB_CONTEXT_ZONE_SEGMENT ) );
4547+
4548+ return (TRUE);
4549+}
4550+
4551+BOOLEAN
4552+FsaFreeFibContextZone(
4553+ PAFA_COMM_ADAPTER Adapter
4554+ )
4555+/*++
4556+
4557+Routine Description:
4558+
4559+ This routine will walk through the FibContextSegmentList and free up all
4560+ resources used by the FibContextZone.
4561+
4562+Arguments:
4563+
4564+ Adapter - The adapter that this COMM_FIB_CONTEXT will communicate with.
4565+
4566+Return Value:
4567+
4568+ TRUE - All resources were properly freed.
4569+ FALSE - An Error occured while freeing resources.
4570+
4571+--*/
4572+
4573+{
4574+ PFIB_CONTEXT_ZONE_SEGMENT ZoneSegment, NextZoneSegment;
4575+
4576+ ZoneSegment = Adapter->FibContextSegmentList;
4577+
4578+ while (ZoneSegment) {
4579+
4580+ NextZoneSegment = ZoneSegment->Next;
4581+
4582+ FsaFreeFibContextSegment( Adapter, ZoneSegment );
4583+
4584+ ZoneSegment = NextZoneSegment;
4585+ }
4586+
4587+ return (TRUE);
4588+}
4589+
4590+
4591+
4592+BOOLEAN
4593+FsaExtendFibContextZone (IN PAFA_COMM_ADAPTER Adapter)
4594+{
4595+ int ExtendSize;
4596+ KIRQL SavedIrql;
4597+ ULONG ZoneSegmentAllocSize, FibAllocSize;
4598+ PVOID FibContextSegment;
4599+ PCOMM_FIB_CONTEXT FibContext;
4600+ PFIB Fib;
4601+ PVOID FibPhysicalAddress;
4602+ int i;
4603+ PFIB_CONTEXT_ZONE_SEGMENT ZoneSegment;
4604+
4605+ //
4606+ // Allocate space to describe this zone segment.
4607+ //
4608+
4609+ cmn_err (CE_DEBUG, "Entered FsaExtendFibContextZone");
4610+ ZoneSegment = OsAllocMemory( sizeof( FIB_CONTEXT_ZONE_SEGMENT ), OS_ALLOC_MEM_SLEEP );
4611+ if (ZoneSegment == NULL) {
4612+ return (FALSE);
4613+ }
4614+
4615+ ExtendSize = Adapter->FibContextZoneExtendSize;
4616+ ZoneSegmentAllocSize = (ExtendSize * sizeof(COMM_FIB_CONTEXT)) + sizeof(ZONE_SEGMENT_HEADER);
4617+
4618+ FibContextSegment = OsAllocMemory( ZoneSegmentAllocSize, OS_ALLOC_MEM_SLEEP );
4619+
4620+ if (FibContextSegment == NULL) {
4621+ OsFreeMemory(ZoneSegment);
4622+ return (FALSE);
4623+ }
4624+
4625+ RtlZeroMemory( FibContextSegment, ZoneSegmentAllocSize );
4626+
4627+ ZoneSegment->FibContextSegment = FibContextSegment;
4628+ ZoneSegment->FibContextSegmentSize = ZoneSegmentAllocSize;
4629+ ZoneSegment->ExtendSize = ExtendSize;
4630+
4631+ FibAllocSize = ExtendSize * sizeof(FIB);
4632+
4633+
4634+ ZoneSegment->MapFibContext.Size = FibAllocSize;
4635+
4636+ AllocateAndMapFibSpace( Adapter, &ZoneSegment->MapFibContext );
4637+
4638+ Fib = ZoneSegment->MapFibContext.FibVirtualAddress;
4639+ FibPhysicalAddress = ZoneSegment->MapFibContext.FibPhysicalAddress;
4640+
4641+ RtlZeroMemory( Fib, FibAllocSize );
4642+
4643+ // Account for the ZONE_SEGMENT_HEADER before the first actual FibContext.
4644+
4645+ for (i = 0, FibContext = (PCOMM_FIB_CONTEXT)((PUCHAR)FibContextSegment + sizeof(ZONE_SEGMENT_HEADER));
4646+ i < ExtendSize; i++, FibContext++) {
4647+
4648+ FibContext->Adapter = Adapter;
4649+
4650+ FibContext->Fib = Fib;
4651+ FibContext->FibData = (PVOID) FibContext->Fib->data;
4652+
4653+ OsCv_init( &FibContext->FsaEvent);
4654+ FibContext->FsaEventMutex = OsCvLockAlloc();
4655+ OsCvLockInit( FibContext->FsaEventMutex, Adapter->SpinLockCookie );
4656+
4657+ Fib->Header.XferState = 0xffffffff;
4658+ Fib->Header.SenderSize = sizeof(FIB);
4659+
4660+ FibContext->LogicalFibAddress.LowPart = (ULONG) FibPhysicalAddress;
4661+
4662+ Fib = (PFIB)((PUCHAR)Fib + sizeof(FIB));
4663+ FibPhysicalAddress = (PVOID)((PUCHAR)FibPhysicalAddress + sizeof(FIB));
4664+ }
4665+
4666+ //
4667+ // If FibContextZone.TotalSegmentSize is non-zero, then a zone has already been
4668+ // initialized, we just need to extend it.
4669+ //
4670+
4671+ if (Adapter->FibContextZone.TotalSegmentSize) {
4672+
4673+ OsSpinLockAcquire( Adapter->FibContextZoneSpinLock );
4674+
4675+ ExExtendZone( &Adapter->FibContextZone,
4676+ FibContextSegment,
4677+ ZoneSegmentAllocSize );
4678+
4679+ OsSpinLockRelease( Adapter->FibContextZoneSpinLock );
4680+
4681+ } else {
4682+
4683+ if (ExInitializeZone( &Adapter->FibContextZone,
4684+ sizeof(COMM_FIB_CONTEXT),
4685+ FibContextSegment,
4686+ ZoneSegmentAllocSize ) != STATUS_SUCCESS)
4687+ FsaBugCheck(0,0,0);
4688+
4689+ }
4690+
4691+ //
4692+ // Add this segment to the adapter's list of segments
4693+ //
4694+
4695+ ZoneSegment->Next = Adapter->FibContextSegmentList;
4696+ Adapter->FibContextSegmentList = ZoneSegment;
4697+
4698+ return (TRUE);
4699+}
4700+
4701+
4702+
4703+/*++
4704+
4705+Routine Description:
4706+
4707+ This routine creates a new COMM_FIB_CONTEXT record
4708+
4709+Arguments:
4710+
4711+ Adapter - The adapter that this COMM_FIB_CONTEXT will communicate with.
4712+
4713+Return Value:
4714+
4715+ PCOMM_FIB_CONTEXT - returns a pointer to the newly allocate COMM_FIB_CONTEXT Record
4716+
4717+--*/
4718+PFIB_CONTEXT
4719+AllocateFib (IN PVOID AdapterArg)
4720+{
4721+ PAFA_COMM_ADAPTER Adapter = (PAFA_COMM_ADAPTER) AdapterArg;
4722+ KIRQL SavedIrql;
4723+ PCOMM_FIB_CONTEXT FibContext;
4724+ int FullZoneLoopCounter = 0;
4725+
4726+
4727+ //
4728+ // Acquire the zone spin lock, and check to see if the zone is full.
4729+ // If it is, then release the spin lock and allocate more fibs for the
4730+ // zone. The ExtendFibZone routine will re-acquire the spin lock to add
4731+ // the new fibs onto the zone.
4732+ //
4733+
4734+ OsSpinLockAcquire( Adapter->FibContextZoneSpinLock );
4735+
4736+ while (ExIsFullZone( &Adapter->FibContextZone )) {
4737+
4738+ if (++FullZoneLoopCounter > 10)
4739+ FsaBugCheck(0,0,0);
4740+
4741+ OsSpinLockRelease( Adapter->FibContextZoneSpinLock );
4742+
4743+ // bmb debug
4744+ cmn_err (CE_DEBUG, "Extending FibContextZone");
4745+ if (FsaExtendFibContextZone(Adapter) == FALSE) {
4746+ return (NULL);
4747+ }
4748+
4749+ OsSpinLockAcquire( Adapter->FibContextZoneSpinLock );
4750+
4751+ }
4752+
4753+ //
4754+ // At this point we now know that the zone has at least one more
4755+ // IRP context record available. So allocate from the zone and
4756+ // then release the mutex.
4757+ //
4758+
4759+ FibContext = (PCOMM_FIB_CONTEXT) ExAllocateFromZone( &Adapter->FibContextZone );
4760+
4761+ OsSpinLockRelease( Adapter->FibContextZoneSpinLock );
4762+
4763+ //
4764+ // Set the proper node type code and node byte size
4765+ //
4766+
4767+ FibContext->NodeTypeCode = FSAFS_NTC_FIB_CONTEXT;
4768+ FibContext->NodeByteSize = sizeof( COMM_FIB_CONTEXT );
4769+
4770+ //
4771+ // Null out fields that depend on being zero at the start of each I/O
4772+ //
4773+
4774+ FibContext->Fib->Header.XferState = 0;
4775+ FibContext->FibCallback = NULL;
4776+ FibContext->FibCallbackContext = NULL;
4777+
4778+
4779+ //
4780+ // return and tell the caller
4781+ //
4782+
4783+ return ((PFIB_CONTEXT) FibContext);
4784+}
4785+
4786+
4787+/*++
4788+
4789+Routine Description:
4790+
4791+ This routine deallocates and removes the specified COMM_FIB_CONTEXT record
4792+ from the Fsafs in memory data structures. It should only be called
4793+ by FsaCompleteRequest.
4794+
4795+Arguments:
4796+
4797+ FibContext - Supplies the COMM_FIB_CONTEXT to remove
4798+
4799+Return Value:
4800+
4801+ None
4802+
4803+--*/
4804+VOID
4805+FreeFib (IN PFIB_CONTEXT Context)
4806+{
4807+ KIRQL SavedIrql;
4808+ PCOMM_FIB_CONTEXT FibContext = Context;
4809+
4810+ ASSERT(FibContext->NodeTypeCode == FSAFS_NTC_FIB_CONTEXT);
4811+
4812+ OsSpinLockAcquire( FibContext->Adapter->FibContextZoneSpinLock );
4813+
4814+ if (FibContext->Flags & FIB_CONTEXT_FLAG_TIMED_OUT) {
4815+
4816+ FsaCommData.TimedOutFibs++;
4817+
4818+ FibContext->Next = FibContext->Adapter->FibContextTimedOutList;
4819+ FibContext->Adapter->FibContextTimedOutList = FibContext;
4820+
4821+ } else {
4822+
4823+ ASSERT(FibContext->Fib->Header.XferState == 0);
4824+
4825+ if (FibContext->Fib->Header.XferState != 0) {
4826+ cmn_err(CE_WARN, "FreeFib, XferState != 0, FibContext = 0x%x, XferState = 0x%x\n",
4827+ FibContext, FibContext->Fib->Header.XferState);
4828+ }
4829+
4830+ ExFreeToZone( &FibContext->Adapter->FibContextZone, FibContext );
4831+
4832+ }
4833+
4834+ OsSpinLockRelease( FibContext->Adapter->FibContextZoneSpinLock );
4835+
4836+ //
4837+ // return and tell the caller
4838+ //
4839+
4840+ return;
4841+}
4842+
4843+
4844+/*++
4845+
4846+Routine Description:
4847+
4848+ This routine deallocates and removes the specified COMM_FIB_CONTEXT record
4849+ from the Fsafs in memory data structures. It should only be called
4850+ from the dpc routines to from dpc to free an FibContext from an async or
4851+ no response io
4852+
4853+Arguments:
4854+
4855+ FibContext - Supplies the COMM_FIB_CONTEXT to remove
4856+
4857+Return Value:
4858+
4859+ None
4860+
4861+--*/
4862+VOID
4863+FreeFibFromDpc (IN PFIB_CONTEXT Context)
4864+{
4865+ PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
4866+
4867+ ASSERT(FibContext->NodeTypeCode == FSAFS_NTC_FIB_CONTEXT);
4868+
4869+ OsSpinLockAcquire(FibContext->Adapter->FibContextZoneSpinLock);
4870+
4871+ if (FibContext->Flags & FIB_CONTEXT_FLAG_TIMED_OUT) {
4872+
4873+ FsaCommData.TimedOutFibs++;
4874+
4875+ FibContext->Next = FibContext->Adapter->FibContextTimedOutList;
4876+ FibContext->Adapter->FibContextTimedOutList = FibContext;
4877+
4878+ } else {
4879+
4880+ ASSERT(FibContext->Fib->Header.XferState == 0);
4881+
4882+ if (FibContext->Fib->Header.XferState != 0) {
4883+ cmn_err(CE_WARN, "FreeFibFromDpc, XferState != 0, FibContext = 0x%x, XferState = 0x%x\n",
4884+ FibContext, FibContext->Fib->Header.XferState);
4885+ }
4886+
4887+
4888+ ExFreeToZone( &FibContext->Adapter->FibContextZone, FibContext );
4889+
4890+ }
4891+
4892+ OsSpinLockRelease(FibContext->Adapter->FibContextZoneSpinLock);
4893+
4894+ //
4895+ // return and tell the caller
4896+ //
4897+
4898+ return;
4899+}
4900+
4901+
4902+/*++
4903+
4904+Routine Description:
4905+
4906+ Will initialize a FIB of the requested size.
4907+
4908+Arguments:
4909+
4910+ Fib is a pointer to a location which will receive the address of the allocated
4911+ FIB.
4912+
4913+ Size is the size of the Fib to allocate.
4914+
4915+Return Value:
4916+
4917+ NT_SUCCESS if a Fib was returned to the caller.
4918+ NT_ERROR if event was an invalid event.
4919+
4920+--*/
4921+AAC_STATUS
4922+InitializeFib (IN PFIB_CONTEXT Context)
4923+{
4924+ PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
4925+ PFIB Fib = FibContext->Fib;
4926+
4927+ Fib->Header.StructType = TFib;
4928+ Fib->Header.Size = sizeof(FIB);
4929+// if (Fib->Header.XferState & AllocatedFromPool)
4930+// Fib->Header.XferState = HostOwned | FibInitialized | FibEmpty | AllocatedFromPool;
4931+// else
4932+ Fib->Header.XferState = HostOwned | FibInitialized | FibEmpty | FastResponseCapable;
4933+ Fib->Header.SenderFibAddress = 0;
4934+ Fib->Header.ReceiverFibAddress = 0;
4935+ Fib->Header.SenderSize = sizeof(FIB);
4936+
4937+ return(STATUS_SUCCESS);
4938+}
4939+
4940+
4941+/*++
4942+
4943+Routine Description:
4944+
4945+ Will allocate and initialize a FIB of the requested size and return a
4946+ pointer to the structure. The size allocated may be larger than the size
4947+ requested due to allocation performace optimizations.
4948+
4949+Arguments:
4950+
4951+ Fib is a pointer to a location which will receive the address of the allocated
4952+ FIB.
4953+
4954+ Size is the size of the Fib to allocate.
4955+
4956+ JustInitialize is a boolean which indicates a Fib has been allocated most likly in an
4957+ imbedded structure the FS always allocates. So just initiaize it and return.
4958+
4959+Return Value:
4960+
4961+ NT_SUCCESS if a Fib was returned to the caller.
4962+ NT_ERROR if event was an invalid event.
4963+
4964+--*/
4965+AAC_STATUS
4966+AllocatePoolFib (OUT PFIB *Fib, IN USHORT Size)
4967+{}
4968+
4969+
4970+/*++
4971+
4972+Routine Description:
4973+
4974+ Will deallocate and return to the free pool the FIB pointed to by the
4975+ caller. Upon return accessing locations pointed to by the FIB parameter
4976+ could cause system access faults.
4977+
4978+Arguments:
4979+
4980+ Fib is a pointer to the FIB that caller wishes to deallocate.
4981+
4982+Return Value:
4983+
4984+ NT_SUCCESS if a Fib was returned to the caller.
4985+ NT_ERROR if event was an invalid event.
4986+
4987+--*/
4988+AAC_STATUS
4989+DeallocateFib (PFIB_CONTEXT Context)
4990+{
4991+ PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
4992+ PFIB Fib = FibContext->Fib;
4993+
4994+ if ( Fib->Header.StructType != TFib ) {
4995+ FsaCommPrint("Error CompleteFib called with a non Fib structure.\n");
4996+ return(STATUS_UNSUCCESSFUL);
4997+ }
4998+
4999+
5000+ Fib->Header.XferState = 0;
5001+
5002+ return(STATUS_SUCCESS);
5003+
5004+}
5005+
5006+
5007+AAC_STATUS
5008+GetResponse(
5009+ IN PCOMM_QUE ResponseQueue,
5010+ OUT PFIB Fib
5011+ )
5012+/*++
5013+
5014+Routine Description:
5015+
5016+ Gets a QE off the requested response queue and gets the response FIB into
5017+ host memory. The FIB may already be in host memory depending on the bus
5018+ interface, or may require the host to DMA it over from the adapter. The routine
5019+ will return the FIB to the caller.
5020+
5021+Arguments:
5022+
5023+ ResponseQueue - Is the queue the caller wishes to have the response gotten from.
5024+ Fib - Is the Fib which was the response from the adapter
5025+
5026+Return Value:
5027+
5028+ NT_SUCCESS if a Fib was returned to the caller.
5029+ NT_ERROR if there was no Fib to return to the caller.
5030+ bkpfix - add in all the other possible errors ect
5031+
5032+--*/
5033+{
5034+return(STATUS_UNSUCCESSFUL);
5035+}
5036+
5037+//
5038+// Commuication primitives define and support the queuing method we use to
5039+// support host to adapter commuication. All queue accesses happen through
5040+// these routines and are the only routines which have a knowledge of the
5041+// how these queues are implemented.
5042+//
5043+
5044+
5045+/*++
5046+
5047+Routine Description:
5048+
5049+ With a priority the routine returns a queue entry if the queue has free entries. If the queue
5050+ is full(no free entries) than no entry is returned and the function returns FALSE otherwise TRUE is
5051+ returned.
5052+
5053+Arguments:
5054+
5055+ Priority is an enumerated type which determines which priority level
5056+ command queue the QE is going to be queued on.
5057+
5058+ Entry is a pointer to the address of where to return the address of
5059+ the queue entry from the requested command queue.
5060+
5061+ Index is a pointer to the address of where to store the index of the new
5062+ queue entry returned.
5063+
5064+ DontInterrupt - We set this true if the queue state is such that we don't
5065+ need to interrupt the adapter for this queue entry.
5066+
5067+Return Value:
5068+
5069+ TRUE - If a queue entry is returned
5070+ FALSE - If there are no free queue entries on the requested command queue.
5071+
5072+--*/
5073+BOOLEAN
5074+GetEntry (IN PAFA_COMM_ADAPTER Adapter, IN QUEUE_TYPES WhichQueue,
5075+ OUT PQUEUE_ENTRY *Entry, OUT PQUEUE_INDEX Index,
5076+ OUT ULONG *DontInterrupt)
5077+{
5078+ ULONG QueueOffset;
5079+ BOOLEAN status;
5080+ PCOMM_REGION CommRegion;
5081+
5082+ CommRegion = Adapter->CommRegion;
5083+
5084+ //
5085+ // All of the queues wrap when they reach the end, so we check to see if they
5086+ // have reached the end and if they have we just set the index back to zero.
5087+ // This is a wrap. You could or off the high bits in all updates but this is
5088+ // a bit faster I think.
5089+ //
5090+
5091+ if (WhichQueue == AdapHighCmdQueue) {
5092+ *Index = *(CommRegion->AdapHighCmdQue.Headers.ProducerIndex);
5093+
5094+ if (*Index - 2 == *(CommRegion->AdapHighCmdQue.Headers.ConsumerIndex))
5095+ *DontInterrupt = TRUE;
5096+
5097+ if (*Index >= ADAP_HIGH_CMD_ENTRIES)
5098+ *Index = 0;
5099+
5100+ if (*Index + 1 == *(CommRegion->AdapHighCmdQue.Headers.ConsumerIndex)) { // Queue is full
5101+ status = FALSE;
5102+ cmn_err(CE_WARN, "Adapter High Command Queue full, %d outstanding",
5103+ CommRegion->AdapHighCmdQue.NumOutstandingIos);
5104+ } else {
5105+ QueueOffset = sizeof(QUEUE_ENTRY) * (*Index);
5106+ *Entry = QueueOffset + CommRegion->AdapHighCmdQue.BaseAddress;
5107+
5108+ status = TRUE;
5109+ }
5110+ } else if (WhichQueue == AdapNormCmdQueue) {
5111+
5112+ *Index = *(CommRegion->AdapNormCmdQue.Headers.ProducerIndex);
5113+
5114+ if (*Index - 2 == *(CommRegion->AdapNormCmdQue.Headers.ConsumerIndex))
5115+ *DontInterrupt = TRUE;
5116+
5117+ //
5118+ // If we are at the end of the QUEUE then wrap back to
5119+ // the beginning.
5120+ //
5121+
5122+ if (*Index >= ADAP_NORM_CMD_ENTRIES)
5123+ *Index = 0; // Wrap to front of the Producer Queue.
5124+
5125+ //
5126+ // The IEEE spec says that it the producer is one behind the consumer then
5127+ // the queue is full.
5128+ //
5129+
5130+ ASSERT(*(CommRegion->AdapNormCmdQue.Headers.ConsumerIndex) != 0);
5131+
5132+ if (*Index + 1 == *(CommRegion->AdapNormCmdQue.Headers.ConsumerIndex)) { // Queue is full
5133+ cmn_err(CE_WARN, "Adapter Norm Command Queue full, %d outstanding",
5134+ CommRegion->AdapNormCmdQue.NumOutstandingIos);
5135+ status = FALSE;
5136+ } else {
5137+ //
5138+ // The success case just falls through and returns the a valid queue entry.
5139+ //
5140+
5141+#ifdef commdebug
5142+ FsaCommPrint("queue entry = %x.\n",CommRegion->AdapNormCmdQue.BaseAddress + *Index);
5143+ FsaCommPrint("GetEntry: Index = %d, QueueOffset = %x, Entry = %x, *Entry = %x.\n",
5144+ *Index, QueueOffset, Entry, *Entry);
5145+#endif
5146+ *Entry = CommRegion->AdapNormCmdQue.BaseAddress + *Index;
5147+
5148+ status = TRUE;
5149+ }
5150+ } else if (WhichQueue == AdapHighRespQueue) {
5151+
5152+ *Index = *(CommRegion->AdapHighRespQue.Headers.ProducerIndex);
5153+
5154+ if (*Index - 2 == *(CommRegion->AdapHighRespQue.Headers.ConsumerIndex))
5155+ *DontInterrupt = TRUE;
5156+
5157+ if (*Index >= ADAP_HIGH_RESP_ENTRIES)
5158+ *Index = 0;
5159+
5160+ if (*Index + 1 == *(CommRegion->AdapHighRespQue.Headers.ConsumerIndex)) { // Queue is full
5161+ status = FALSE;
5162+ cmn_err(CE_WARN, "Adapter High Resp Queue full, %d outstanding",
5163+ CommRegion->AdapHighRespQue.NumOutstandingIos);
5164+ } else {
5165+ *Entry = CommRegion->AdapHighRespQue.BaseAddress + *Index;
5166+ status = TRUE;
5167+ }
5168+ } else if (WhichQueue == AdapNormRespQueue) {
5169+
5170+ *Index = *(CommRegion->AdapNormRespQue.Headers.ProducerIndex);
5171+
5172+ if (*Index - 2 == *(CommRegion->AdapNormRespQue.Headers.ConsumerIndex))
5173+ *DontInterrupt = TRUE;
5174+
5175+ //
5176+ // If we are at the end of the QUEUE then wrap back to
5177+ // the beginning.
5178+ //
5179+
5180+ if (*Index >= ADAP_NORM_RESP_ENTRIES)
5181+ *Index = 0; // Wrap to front of the Producer Queue.
5182+
5183+ //
5184+ // The IEEE spec says that it the producer is one behind the consumer then
5185+ // the queue is full.
5186+ //
5187+
5188+ if (*Index + 1 == *(CommRegion->AdapNormRespQue.Headers.ConsumerIndex)) { // Queue is full
5189+ status = FALSE;
5190+ cmn_err(CE_WARN, "Adapter Norm Resp Queue full, %d outstanding",
5191+ CommRegion->AdapNormRespQue.NumOutstandingIos);
5192+ } else {
5193+ //
5194+ // The success case just falls through and returns the a valid queue entry.
5195+ //
5196+
5197+ *Entry = CommRegion->AdapNormRespQue.BaseAddress + *Index;
5198+
5199+#ifdef commdebug
5200+ FsaCommPrint("queue entry = %x.\n",CommRegion->AdapNormRespQue.BaseAddress + *Index);
5201+ FsaCommPrint("GetEntry: Index = %d, Entry = %x, *Entry = %x.\n",*Index, Entry, *Entry);
5202+#endif
5203+ status = TRUE;
5204+ }
5205+ } else {
5206+ cmn_err(CE_PANIC, "GetEntry: invalid queue %d", WhichQueue);
5207+ }
5208+
5209+
5210+ return (status);
5211+}
5212+
5213+
5214+
5215+#ifdef API_THROTTLE
5216+
5217+void ThrottleCheck(
5218+ IN PAFA_COMM_ADAPTER Adapter,
5219+ IN PFIB Fib
5220+ )
5221+/*++
5222+
5223+Routine Description:
5224+
5225+ This routine implements data I/O throttling. Throttling occurs when
5226+ a CLI FIB is detected. To ensure the CLI responds quickly (the user
5227+ is waiting for the response), this mechanism restricts the queue
5228+ depth of data IOs at the adapter for a period of time (called the
5229+ Throttle Period, default 5 seconds).
5230+
5231+ The mechanism uses a counted semaphore to place threads into a wait
5232+ state should there be too many data I/Os outstanding.
5233+
5234+ At the start of a throttle period (indicated by the first CLI FIB)
5235+ a timer is started. When the timer expires, new requests can go to
5236+ the adapter freely. Throttled requests gradually drain to the
5237+ adapter as each outstanding throttle I/O completes.
5238+
5239+ To avoid hurting regular I/O performance, we use a flag in the FIB
5240+ header to mark FIBs involved in throttling. This means we only need
5241+ take the extra spinlock in the response DPC routine for FIBs who
5242+ were subject to throttling. If no throttling is occurring, the cost
5243+ to the regular code paths is a handful of instructions.
5244+
5245+Arguments:
5246+
5247+ Adapter - Pointer to per-adapter context. This is used to locate the
5248+ throttle information for this adapter.
5249+
5250+ Fib - Pointer to the header for the fib being sent.
5251+
5252+Return Value:
5253+
5254+ None.
5255+
5256+--*/
5257+{
5258+ PCOMM_REGION CommRegion = Adapter->CommRegion;
5259+ AAC_STATUS Status;
5260+
5261+ //
5262+ // This routine is called under protection of the queue spinlock.
5263+ // As such we are allowed to check and change the counts for the
5264+ // throttle.
5265+ // Check the FIB. If its not a data operation, send it on without
5266+ // throttle check. If it is a data operation, check for throttle.
5267+ //
5268+
5269+ CommRegion->TotalFibs++; // Keep statistics
5270+
5271+ if ((Fib->Header.XferState & ApiFib) != 0) {
5272+
5273+ CommRegion->ApiFibs++; // Keep statistics
5274+
5275+ //
5276+ // Its an API fib. If the throttle is not already active,
5277+ // make it so. This will prevent new data Fibs being sent
5278+ // if they exceed the throttle check.
5279+ //
5280+
5281+ if (!CommRegion->ThrottleActive) {
5282+ BOOLEAN InQue;
5283+
5284+ CommRegion->ThrottleActive = TRUE; // This causes new data I/Os to be throttled
5285+
5286+ //
5287+ // Schedule a timer for the throttle active period. When
5288+ // it expires, we'll be called back at routine ThrottleDpcRoutine
5289+ // above. This will signify the throttle active period ended
5290+ // and any waiting threads will be signalled to restart.
5291+ //
5292+
5293+ FsaCommPrint("Throttle Period Start - CommRegion: %x\n", CommRegion);
5294+ CommRegion->ThrottleTimerSets++;
5295+ InQue = KeSetTimer( &CommRegion->ThrottleTimer,
5296+ CommRegion->ThrottleTimeout,
5297+ &CommRegion->ThrottleDpc);
5298+ ASSERT(InQue == FALSE);
5299+ }
5300+
5301+ return;
5302+ }
5303+
5304+ //
5305+ // Its a non-API fib, so subject to throttle checks.
5306+ // The following are exempt from throttling:
5307+ // o FIBs marked as "throttle exempt" by upper layers.
5308+ // o I/Os issued from a raised IRQL. We can't suspend
5309+ // a thread when at raised IRQL so throttling is exempt.
5310+ //
5311+
5312+ if (CommRegion->AdapNormCmdQue.SavedIrql != PASSIVE_LEVEL) {
5313+
5314+ CommRegion->NonPassiveFibs++;
5315+ FsaCommPrint("ThrottleCheck: Non-Passive level FIB bypasses throttle: %x\n", Fib);
5316+ return;
5317+
5318+ }
5319+
5320+ if (CommRegion->ThrottleActive) {
5321+
5322+ //
5323+ // Throttle is active.
5324+ // Check if the FIB is a read or write. If so, and its to the
5325+ // file system information area, let it through without throttling.
5326+ //
5327+
5328+ if (Fib->Header.Command == ContainerCommand) {
5329+ PBLOCKREAD BlockDisk = (PBLOCKREAD) &Fib->data;
5330+
5331+ //
5332+ // *** Note *** We are using read and write command formats
5333+ // interchangably here. This is ok for this purpose as the
5334+ // command is in the same place for both. Read and write command
5335+ // formats are different at higher offsets though.
5336+ //
5337+
5338+ if ( ((BlockDisk->Command == VM_CtBlockRead) ||
5339+ (BlockDisk->Command == VM_CtBlockWrite)) &&
5340+ (BlockDisk->BlockNumber <= FILESYSTEM_INFO_MAX_BLKNO)) {
5341+
5342+ CommRegion->FSInfoFibs++; // Keep statistics
5343+ return;
5344+
5345+ }
5346+
5347+ }
5348+
5349+ //
5350+ // Throttle the FIB.
5351+ // Mark it as throttle active so that it can signal a waiter
5352+ // when it completes.
5353+
5354+ CommRegion->ThrottledFibs++;
5355+ Fib->Header.Flags |= ThrottledFib;
5356+
5357+ //
5358+ // Release the spinlock so we can wait the thread if necessary.
5359+ // Since we specify a timeout, check the caller is at passive level.
5360+ //
5361+
5362+ OsSpinLockRelease((CommRegion->AdapNormCmdQue.QueueLock), CommRegion->AdapNormCmdQue.SavedIrql);
5363+
5364+ FsaCommPrint("ThrottleCheck - Thread Suspension - FIB: %x\n", Fib);
5365+
5366+ Status = KeWaitForSingleObject(&CommRegion->ThrottleReleaseSema,
5367+ Executive, // Don't allow user APCs to wake us
5368+ KernelMode, // Wait in kernel mode
5369+ FALSE, // Not alertable
5370+ &CommRegion->ThrottleWaitTimeout); // Timeout after this time
5371+
5372+ //
5373+ // Check the signal status. If we've timed out, clear the throttle
5374+ // flag on the FIB to avoid us signalling the semaphore on completion.
5375+ // We never acquired the semaphore.
5376+ //
5377+ if (Status == STATUS_TIMEOUT) {
5378+
5379+ CommRegion->ThrottleTimedoutFibs++;
5380+ FsaCommPrint("ThrottledFib Timed Out - FIB: %x\n", Fib);
5381+ Fib->Header.Flags &= ~ThrottledFib; // Clear the throttledfib flag
5382+
5383+ } else {
5384+
5385+ ASSERT(Status == STATUS_SUCCESS); // No other return is possible
5386+
5387+ }
5388+
5389+ //
5390+ // We've been woken up and can now send the FIB to the adapter.
5391+ // Acquire the spinlock again so we can get a queue entry. This
5392+ // returns to GetQueueEntry.
5393+ //
5394+
5395+ FsaCommPrint("ThrottleCheck - Thread Resume - FIB: %x\n", Fib);
5396+ KeAcquireSpinLock((CommRegion->AdapNormCmdQue.QueueLock), &(CommRegion->AdapNormCmdQue.SavedIrql));
5397+ CommRegion->ThrottleOutstandingFibs++; // There's another throttle controlled FIB going.
5398+ return;
5399+
5400+ }
5401+}
5402+
5403+#endif //#ifdef API_THROTTLE
5404+
5405+int GetQueueEntryTimeouts = 0;
5406+
5407+
5408+/*++
5409+
5410+Routine Description:
5411+
5412+ Gets the next free QE off the requested priorty adapter command queue and
5413+ associates the Fib with the QE. The QE represented by index is ready to
5414+ insert on the queue when this routine returns success.
5415+
5416+Arguments:
5417+
5418+ Index is the returned value which represents the QE which is ready to
5419+ insert on the adapter's command queue.
5420+
5421+ Priority is an enumerated type which determines which priority level
5422+ command queue the QE is going to be queued on.
5423+
5424+ Fib is a pointer to the FIB the caller wishes to have associated with the
5425+ QE.
5426+
5427+ Wait is a boolean which determines if the routine will wait if there are
5428+ no free QEs on the requested priority command queue.
5429+
5430+ FibContext is where the driver stores all system resources required to execute the
5431+ command requested from the calling thread. This includes mapping resources for
5432+ the FIB and the 'users' buffer.
5433+
5434+ DontInterrupt - We set this true if the queue state is such that we don't
5435+ need to interrupt the adapter for this queue entry.
5436+
5437+Return Value:
5438+
5439+ NT_SUCCESS if a Fib was returned to the caller.
5440+ NT_ERROR if event was an invalid event.
5441+
5442+--*/
5443+AAC_STATUS
5444+GetQueueEntry (IN PAFA_COMM_ADAPTER Adapter, OUT PQUEUE_INDEX Index,
5445+ IN QUEUE_TYPES WhichQueue, IN PFIB Fib, IN BOOLEAN Wait,
5446+ IN PCOMM_FIB_CONTEXT FibContext, OUT ULONG *DontInterrupt)
5447+{
5448+ PQUEUE_ENTRY QueueEntry = NULL;
5449+ BOOLEAN MapAddress = FALSE;
5450+ int timeouts = 0;
5451+ AAC_STATUS Status;
5452+ PCOMM_REGION CommRegion;
5453+
5454+ CommRegion = Adapter->CommRegion;
5455+
5456+ //
5457+ // Get the spinlock for the queue we are putting a command on
5458+ //
5459+
5460+ if (WhichQueue == AdapHighCmdQueue)
5461+ OsSpinLockAcquire(CommRegion->AdapHighCmdQue.QueueLock);
5462+ else if (WhichQueue == AdapNormCmdQueue)
5463+ OsSpinLockAcquire(CommRegion->AdapNormCmdQue.QueueLock);
5464+ else if (WhichQueue == AdapHighRespQueue)
5465+ OsSpinLockAcquire(CommRegion->AdapHighRespQue.QueueLock);
5466+ else if (WhichQueue == AdapNormRespQueue)
5467+ OsSpinLockAcquire(CommRegion->AdapNormRespQue.QueueLock);
5468+ else {
5469+ FsaCommPrint("Invalid queue priority passed to GetQueueEntry.\n");
5470+ return(FSA_INVALID_QUEUE);
5471+ }
5472+
5473+ //
5474+ // Get the pointers to a queue entry on the queue the caller wishes to queue
5475+ // a command request on. If there are no entries then wait if that is what the
5476+ // caller requested.
5477+ //
5478+
5479+ if (WhichQueue == AdapHighCmdQueue) {
5480+ // if no entries wait for some if caller wants to
5481+ while ( !GetEntry(Adapter, AdapHighCmdQueue, &QueueEntry, Index, DontInterrupt) ) {
5482+ cmn_err(CE_PANIC, "GetEntries failed (1)\n");
5483+ }
5484+
5485+ //
5486+ // Setup queue entry with a command, status and Fib mapped
5487+ //
5488+
5489+ QueueEntry->Size = Fib->Header.Size;
5490+ MapAddress = TRUE;
5491+
5492+ } else if (WhichQueue == AdapNormCmdQueue) {
5493+ // if no entries wait for some if caller wants to
5494+ while ( !GetEntry(Adapter, AdapNormCmdQueue, &QueueEntry, Index, DontInterrupt) ) {
5495+ cmn_err(CE_PANIC, "GetEntries failed (2)\n");
5496+ }
5497+
5498+ //
5499+ // Setup queue entry with command, status and Fib mapped
5500+ //
5501+
5502+ QueueEntry->Size = Fib->Header.Size;
5503+ MapAddress = TRUE;
5504+
5505+ } else if (WhichQueue == AdapHighRespQueue) {
5506+
5507+ while ( !GetEntry(Adapter, AdapHighRespQueue, &QueueEntry, Index, DontInterrupt) ) { // if no entries wait for some if caller wants to
5508+ }
5509+
5510+ //
5511+ // Setup queue entry with command, status and Fib mapped
5512+ //
5513+
5514+ QueueEntry->Size = Fib->Header.Size;
5515+ QueueEntry->FibAddress = Fib->Header.SenderFibAddress; // Restore adapters pointer to the FIB
5516+ Fib->Header.ReceiverFibAddress = Fib->Header.SenderFibAddress; // Let the adapter now where to find its data
5517+ MapAddress = FALSE;
5518+
5519+ } else if (WhichQueue == AdapNormRespQueue) {
5520+ while ( !GetEntry(Adapter, AdapNormRespQueue, &QueueEntry, Index, DontInterrupt) ) { // if no entries wait for some if caller wants to
5521+ }
5522+
5523+ //
5524+ // Setup queue entry with command, status, adapter's pointer to the Fib it sent
5525+ //
5526+
5527+ QueueEntry->Size = Fib->Header.Size;
5528+ QueueEntry->FibAddress = Fib->Header.SenderFibAddress; // Restore adapters pointer to the FIB
5529+ Fib->Header.ReceiverFibAddress = Fib->Header.SenderFibAddress; // Let the adapter now where to find its data
5530+ MapAddress = FALSE;
5531+ }
5532+
5533+ //
5534+ // If MapFib is true than we need to map the Fib and put pointers in the queue entry.
5535+ //
5536+
5537+ if (MapAddress) {
5538+ QueueEntry->FibAddress = (ULONG)(FibContext->LogicalFibAddress.LowPart);
5539+ }
5540+
5541+ //
5542+ // Return
5543+ //
5544+#ifdef commdebug
5545+ FsaCommPrint("Queue Entry contents:.\n");
5546+ FsaCommPrint(" Command = %d.\n", QueueEntry->Command);
5547+ FsaCommPrint(" Status = %x.\n", QueueEntry->Status);
5548+ FsaCommPrint(" Rec Fib address low = %x.\n", QueueEntry->FibAddressLow);
5549+ FsaCommPrint(" Fib size in bytes = %d.\n", QueueEntry->Size);
5550+#endif
5551+
5552+ return(FSA_SUCCESS);
5553+}
5554+
5555+
5556+/*++
5557+
5558+Routine Description:
5559+
5560+ Gets the next free QE off the requested priorty adapter command queue and
5561+ associates the Fib with the QE. The QE represented by index is ready to
5562+ insert on the queue when this routine returns success.
5563+
5564+Arguments:
5565+
5566+ Index is the returned value which represents the QE which is ready to
5567+ insert on the adapter's command queue.
5568+
5569+ WhichQueue tells us which queue the caller wishes to have the entry put.
5570+
5571+Return Value:
5572+
5573+ NT_SUCCESS if a Fib was returned to the caller.
5574+ NT_ERROR if event was an invalid event.
5575+
5576+--*/
5577+AAC_STATUS
5578+InsertQueueEntry(
5579+ IN PAFA_COMM_ADAPTER Adapter,
5580+ IN QUEUE_INDEX Index,
5581+ IN QUEUE_TYPES WhichQueue,
5582+ IN ULONG DontInterrupt
5583+ )
5584+{
5585+ PCOMM_REGION CommRegion;
5586+
5587+ CommRegion = Adapter->CommRegion;
5588+
5589+ //
5590+ // We have already verified the queue in getentry, but we still have to make
5591+ // sure we don't wrap here too.
5592+ //
5593+
5594+ if (WhichQueue == AdapHighCmdQueue) {
5595+
5596+ *(CommRegion->AdapHighCmdQue.Headers.ProducerIndex) = Index + 1;
5597+
5598+ OsSpinLockRelease(CommRegion->AdapHighCmdQue.QueueLock);
5599+
5600+ if (!DontInterrupt)
5601+ NotifyAdapter(Adapter, AdapHighCmdQue);
5602+
5603+ } else if (WhichQueue == AdapNormCmdQueue) {
5604+
5605+#ifdef commdebug
5606+ FsaCommPrint("InsertQueueEntry: Inerting with an index of %d.\n",Index);
5607+#endif
5608+ *(CommRegion->AdapNormCmdQue.Headers.ProducerIndex) = Index + 1;
5609+
5610+ OsSpinLockRelease(CommRegion->AdapNormCmdQue.QueueLock);
5611+
5612+ if (!DontInterrupt)
5613+ NotifyAdapter(Adapter, AdapNormCmdQue);
5614+
5615+ } else if (WhichQueue == AdapHighRespQueue) {
5616+
5617+ *(CommRegion->AdapHighRespQue.Headers.ProducerIndex) = Index + 1;
5618+
5619+ OsSpinLockRelease(CommRegion->AdapHighRespQue.QueueLock);
5620+
5621+ if (!DontInterrupt)
5622+ NotifyAdapter(Adapter, AdapHighRespQue);
5623+
5624+ } else if (WhichQueue == AdapNormRespQueue) {
5625+
5626+ *(CommRegion->AdapNormRespQue.Headers.ProducerIndex) = Index + 1;
5627+
5628+ OsSpinLockRelease(CommRegion->AdapNormRespQue.QueueLock);
5629+
5630+ if (!DontInterrupt)
5631+ NotifyAdapter(Adapter, AdapNormRespQue);
5632+
5633+ } else {
5634+ FsaCommPrint("Invalid queue priority passed to InsertQueueEntry.\n");
5635+ return(FSA_INVALID_QUEUE_PRIORITY);
5636+ }
5637+
5638+ return(FSA_SUCCESS);
5639+}
5640+
5641+extern int GatherFibTimes;
5642+
5643+BOOLEAN
5644+SendSynchFib(
5645+ PVOID Arg,
5646+ FIB_COMMAND Command,
5647+ PVOID Data,
5648+ USHORT Size,
5649+ PVOID Response,
5650+ USHORT *ResponseSize
5651+ )
5652+/*++
5653+
5654+Routine Description:
5655+
5656+ This routine will send a synchronous FIB to the adapter and wait for its
5657+ completion.
5658+
5659+Arguments:
5660+
5661+ DeviceExtension - Pointer to adapter extension structure.
5662+
5663+
5664+Return Value:
5665+
5666+ BOOLEAN
5667+
5668+--*/
5669+{
5670+ PAFA_COMM_ADAPTER Adapter = Arg;
5671+ FIB *Fib;
5672+ ULONG returnStatus;
5673+
5674+ Fib = Adapter->SyncFib;
5675+
5676+ Fib->Header.StructType = TFib;
5677+ Fib->Header.Size = sizeof(FIB);
5678+ Fib->Header.XferState = HostOwned | FibInitialized | FibEmpty;
5679+ Fib->Header.ReceiverFibAddress = 0;
5680+ Fib->Header.SenderSize = sizeof(FIB);
5681+ Fib->Header.SenderFibAddress = (ULONG)Fib;
5682+ Fib->Header.Command = Command;
5683+
5684+ //
5685+ // Copy the Data portion into the Fib.
5686+ //
5687+
5688+ RtlCopyMemory( Fib->data, Data, Size );
5689+
5690+
5691+ Fib->Header.XferState |= (SentFromHost | NormalPriority);
5692+
5693+ //
5694+ // Set the size of the Fib we want to send to the adapter
5695+ //
5696+
5697+ Fib->Header.Size = sizeof(FIB_HEADER) + Size;
5698+
5699+ if (!Adapter->AdapterFuncs->SendSynchFib( Adapter->AdapterExtension,
5700+ Adapter->SyncFibPhysicalAddress )) {
5701+
5702+ return (FALSE);
5703+
5704+ }
5705+
5706+ //
5707+ // Copy the response back to the caller's buffer.
5708+ //
5709+
5710+ RtlCopyMemory( Response, Fib->data, Fib->Header.Size - sizeof(FIB_HEADER) );
5711+
5712+ *ResponseSize = Fib->Header.Size - sizeof(FIB_HEADER);
5713+
5714+ //
5715+ // Indicate success
5716+ //
5717+
5718+ return (TRUE);
5719+}
5720+
5721+//
5722+// Define the highest level of host to adapter communication routines. These
5723+// routines will support host to adapter FS commuication. These routines have
5724+// no knowledge of the commuication method used. This level sends and receives
5725+// FIBs. This level has no knowledge of how these FIBs get passed back and forth.
5726+//
5727+
5728+
5729+
5730+/*++
5731+
5732+Routine Description:
5733+
5734+ Sends the requested FIB to the adapter and optionally will wait for a
5735+ response FIB. If the caller does not wish to wait for a response than
5736+ an event to wait on must be supplied. This event will be set when a
5737+ response FIB is received from the adapter.
5738+
5739+Arguments:
5740+
5741+ Fib is a pointer to the FIB the caller wishes to send to the adapter.
5742+
5743+ Size - Size of the data portion of the Fib.
5744+
5745+ Priority is an enumerated type which determines which priority level
5746+ the caller wishes to send this command at.
5747+
5748+ Wait is a boolean which determines if the routine will wait for the
5749+ completion Fib to be returned(TRUE), or return when the Fib has been
5750+ successfully received by the adapter(FALSE).
5751+
5752+ WaitOn is only vaild when Wait is FALSE. The Event will be set when the response
5753+ FIB has been returned by the adapter.
5754+
5755+ ReturnFib is an optional pointer to a FIB that if present the response FIB will
5756+ copied to.
5757+
5758+Return Value:
5759+
5760+ NT_SUCCESS if a Fib was returned to the caller.
5761+ NT_ERROR if event was an invalid event.
5762+
5763+ --*/
5764+AAC_STATUS
5765+SendFib (IN FIB_COMMAND Command,
5766+ IN PFIB_CONTEXT Context,
5767+ IN ULONG Size,
5768+ IN COMM_PRIORITIES Priority,
5769+ IN BOOLEAN Wait,
5770+ IN PVOID WaitOn,
5771+ IN BOOLEAN ResponseExpected,
5772+ IN PFIB_CALLBACK FibCallback,
5773+ IN PVOID FibCallbackContext)
5774+{
5775+ PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
5776+ QUEUE_INDEX Index;
5777+ QUEUE_TYPES WhichQueue;
5778+ LARGE_INTEGER Timeout;
5779+ AAC_STATUS Status;
5780+ PAFA_COMM_ADAPTER Adapter = FibContext->Adapter;
5781+ ULONG DontInterrupt = FALSE;
5782+ PFIB Fib = FibContext->Fib;
5783+ IN PCOMM_QUE OurQueue;
5784+
5785+ Timeout = FsaCommData.AdapterTimeout;
5786+
5787+ if (!(Fib->Header.XferState & HostOwned)) {
5788+ FsaCommPrint("SendFib was called with a xfer state not set to HostOwned!\n");
5789+ FsaCommLogEvent(FibContext,
5790+ FsaCommData.DeviceObject,
5791+ FSAFS_FIB_INVALID,
5792+ STATUS_UNSUCCESSFUL,
5793+ BugCheckFileId | __LINE__,
5794+ FACILITY_FSAFS_ERROR_CODE,
5795+ NULL,
5796+ TRUE);
5797+
5798+ return(STATUS_UNSUCCESSFUL);
5799+
5800+ }
5801+
5802+ //
5803+ // There are 5 cases with the wait and reponse requested flags. The only invalid cases
5804+ // are if the caller requests to wait and does not request a response and if the
5805+ // caller does not want a response and the Fib is not allocated from pool. If a response
5806+ // is not requesed the Fib will just be deallocaed by the DPC routine when the response
5807+ // comes back from the adapter. No further processing will be done besides deleting the
5808+ // Fib. We will have a debug mode where the adapter can notify the host it had a problem
5809+ // and the host can log that fact.
5810+
5811+ if (Wait && !ResponseExpected) {
5812+
5813+ FsaCommLogEvent(FibContext,
5814+ FsaCommData.DeviceObject,
5815+ FSAFS_FIB_INVALID,
5816+ STATUS_UNSUCCESSFUL,
5817+ BugCheckFileId | __LINE__,
5818+ FACILITY_FSAFS_ERROR_CODE,
5819+ NULL,
5820+ TRUE);
5821+
5822+ return(STATUS_UNSUCCESSFUL);
5823+
5824+ } else if (!Wait && ResponseExpected) {
5825+ Fib->Header.XferState |= (Async | ResponseExpected);
5826+ FIB_COUNTER_INCREMENT(FsaCommData.AsyncSent);
5827+ } else if (!Wait && !ResponseExpected) {
5828+ Fib->Header.XferState |= NoResponseExpected;
5829+ FIB_COUNTER_INCREMENT(FsaCommData.NoResponseSent);
5830+ } else if (Wait && ResponseExpected) {
5831+ Fib->Header.XferState |= ResponseExpected;
5832+ FIB_COUNTER_INCREMENT(FsaCommData.NormalSent);
5833+ }
5834+
5835+ Fib->Header.SenderData = (ULONG)FibContext; // so we can complete the io in the dpc routine
5836+
5837+ //
5838+ // Set FIB state to indicate where it came from and if we want a response from the
5839+ // adapter. Also load the command from the caller.
5840+ //
5841+
5842+ Fib->Header.SenderFibAddress = (ULONG)Fib;
5843+ Fib->Header.Command = Command;
5844+ Fib->Header.XferState |= SentFromHost;
5845+ FibContext->Fib->Header.Flags = 0; // Zero the flags field - its internal only...
5846+
5847+ //
5848+ // Set the size of the Fib we want to send to the adapter
5849+ //
5850+
5851+ Fib->Header.Size = sizeof(FIB_HEADER) + Size;
5852+ if (Fib->Header.Size > Fib->Header.SenderSize) {
5853+ return(STATUS_BUFFER_OVERFLOW);
5854+ }
5855+
5856+ //
5857+ // Get a queue entry connect the FIB to it and send an notify the adapter a command is ready.
5858+ //
5859+
5860+ if (Priority == FsaHigh) {
5861+ Fib->Header.XferState |= HighPriority;
5862+ WhichQueue = AdapHighCmdQueue;
5863+ OurQueue = &Adapter->CommRegion->AdapHighCmdQue;
5864+ } else {
5865+ Fib->Header.XferState |= NormalPriority;
5866+ WhichQueue = AdapNormCmdQueue;
5867+ OurQueue = &Adapter->CommRegion->AdapNormCmdQue;
5868+ }
5869+
5870+ if (Wait) {
5871+ OsCvLockAcquire( FibContext->FsaEventMutex );
5872+ }
5873+
5874+ if ( GetQueueEntry( Adapter, &Index, WhichQueue, Fib, TRUE, FibContext, &DontInterrupt) != FSA_SUCCESS )
5875+ return(STATUS_UNSUCCESSFUL);
5876+
5877+ // bmb debug
5878+
5879+ cmn_err (CE_DEBUG,"SendFib: inserting a queue entry at index %d.\n",Index);
5880+ cmn_err (CE_DEBUG,"Fib contents:.\n");
5881+ cmn_err (CE_DEBUG," Command = %d.\n", Fib->Header.Command);
5882+ cmn_err (CE_DEBUG," XferState = %x.\n", Fib->Header.XferState );
5883+
5884+ //
5885+ // Fill in the Callback and CallbackContext if we are not going to wait.
5886+ //
5887+
5888+ if (!Wait) {
5889+
5890+ FibContext->FibCallback = FibCallback;
5891+ FibContext->FibCallbackContext = FibCallbackContext;
5892+
5893+ }
5894+
5895+ FIB_COUNTER_INCREMENT(FsaCommData.FibsSent);
5896+
5897+ InsertTailList( &OurQueue->OutstandingIoQueue, &FibContext->QueueEntry );
5898+ OurQueue->NumOutstandingIos++;
5899+
5900+ FibContext->FibComplete = 0;
5901+
5902+
5903+
5904+ if ( InsertQueueEntry( Adapter, Index, WhichQueue, (DontInterrupt & FsaCommData.EnableInterruptModeration)) != FSA_SUCCESS )
5905+ return(STATUS_UNSUCCESSFUL);
5906+
5907+ //
5908+ // If the caller wanted us to wait for response wait now.
5909+ // If Timeouts are enabled than set the timeout otherwise wait forever.
5910+ //
5911+
5912+ if (Wait) {
5913+ while (FibContext->FibComplete == 0) {
5914+ OsCv_wait( &FibContext->FsaEvent, FibContext->FsaEventMutex );
5915+ }
5916+
5917+ OsCvLockRelease( FibContext->FsaEventMutex );
5918+
5919+ if ( (FibContext->Flags & FIB_CONTEXT_FLAG_TIMED_OUT) ) {
5920+ return(STATUS_IO_TIMEOUT);
5921+ } else {
5922+ return(STATUS_SUCCESS);
5923+ }
5924+ }
5925+
5926+ //
5927+ // If the user does not want a response than return success otherwise return pending
5928+ //
5929+
5930+ ASSERT( FibCallback );
5931+
5932+ if (ResponseExpected)
5933+ return(STATUS_PENDING);
5934+ else
5935+ return(STATUS_SUCCESS);
5936+}
5937+
5938+BOOLEAN
5939+GetConsumerEntry(
5940+ IN PAFA_COMM_ADAPTER Adapter,
5941+ PCOMM_QUE OurQueue,
5942+ OUT PQUEUE_ENTRY *Entry
5943+ )
5944+/*++
5945+
5946+Routine Description:
5947+
5948+ Will return a pointer to the entry on the top of the queue requested that we are a consumer
5949+ of, and return the address of the queue entry. It does not change the state of the queue.
5950+
5951+Arguments:
5952+
5953+ OurQueue - is the queue the queue entry should be removed from.
5954+
5955+ Entry - is a pointer where the address of the queue entry should be returned.
5956+
5957+Return Value:
5958+
5959+ TRUE if there was a queue entry on the response queue for the host to consume.
5960+ FALSE if there were no queue entries to consume.
5961+
5962+--*/
5963+
5964+{
5965+ QUEUE_INDEX Index;
5966+ BOOLEAN status;
5967+
5968+ if (*OurQueue->Headers.ProducerIndex == *OurQueue->Headers.ConsumerIndex) {
5969+ status = FALSE;
5970+ } else {
5971+
5972+ //
5973+ // The consumer index must be wrapped if we have reached the end of
5974+ // the queue.
5975+ // Else we just use the entry pointed to by the header index
5976+ //
5977+
5978+ if (*OurQueue->Headers.ConsumerIndex >= OurQueue->QueueEntries)
5979+ Index = 0;
5980+ else
5981+ Index = *OurQueue->Headers.ConsumerIndex;
5982+
5983+ *Entry = OurQueue->BaseAddress + Index;
5984+
5985+#ifdef commdebug
5986+ FsaCommPrint("Got a QE at Index %d, QE Addrss of %x.\n",Index,*Entry);
5987+#endif
5988+ status = TRUE;
5989+ }
5990+
5991+ return(status);
5992+}
5993+
5994+BOOLEAN
5995+ConsumerEntryAvailable(
5996+ IN PAFA_COMM_ADAPTER Adapter,
5997+ PCOMM_QUE OurQueue
5998+ )
5999+{
6000+ return (*OurQueue->Headers.ProducerIndex != *OurQueue->Headers.ConsumerIndex);
6001+}
6002+
6003+VOID
6004+FreeConsumerEntry(
6005+ IN PAFA_COMM_ADAPTER Adapter,
6006+ PCOMM_QUE OurQueue,
6007+ QUEUE_TYPES WhichQueue
6008+ )
6009+/*++
6010+
6011+Routine Description:
6012+
6013+ Frees up the current top of the queue we are a consumer of. If the queue was full
6014+ notify the producer that the queue is no longer full.
6015+
6016+Arguments:
6017+
6018+ OurQueue - is the queue we will free the current consumer entry on.
6019+
6020+Return Value:
6021+
6022+ TRUE if there was a queue entry on the response queue for the host to consume.
6023+ FALSE if there were no queue entries to consume.
6024+
6025+--*/
6026+
6027+{
6028+ BOOLEAN WasFull = FALSE;
6029+ HOST_2_ADAP_EVENT Notify;
6030+
6031+ if (*OurQueue->Headers.ProducerIndex+1 == *OurQueue->Headers.ConsumerIndex)
6032+ WasFull = TRUE;
6033+
6034+ if (*OurQueue->Headers.ConsumerIndex >= OurQueue->QueueEntries)
6035+ *OurQueue->Headers.ConsumerIndex = 1;
6036+ else
6037+ *OurQueue->Headers.ConsumerIndex += 1;
6038+
6039+ if (WasFull) {
6040+ switch (WhichQueue) {
6041+
6042+ case HostNormCmdQueue:
6043+ Notify = HostNormCmdNotFull;
6044+ break;
6045+ case HostHighCmdQueue:
6046+ Notify = HostHighCmdNotFull;
6047+ break;
6048+
6049+ case HostNormRespQueue:
6050+ Notify = HostNormRespNotFull;
6051+ break;
6052+
6053+ case HostHighRespQueue:
6054+ Notify = HostHighRespNotFull;
6055+ break;
6056+
6057+ }
6058+ NotifyAdapter(Adapter, Notify);
6059+ }
6060+
6061+}
6062+
6063+AAC_STATUS
6064+CompleteAdapterFib(
6065+ IN PFIB_CONTEXT Context,
6066+ IN USHORT Size
6067+ )
6068+/*++
6069+
6070+Routine Description:
6071+
6072+ Will do all necessary work to complete a FIB that was sent from the adapter.
6073+
6074+Arguments:
6075+
6076+ Fib is a pointer to the FIB that caller wishes to complete processing on.
6077+
6078+ Size - Size of the completion Packet(Opitional). If not present than the current
6079+ largest size in the Fib will be used
6080+
6081+ Adapter - Pointer to which adapter sent this FIB
6082+
6083+Return Value:
6084+
6085+ NT_SUCCESS if a Fib was returned to the caller.
6086+ NT_ERROR if event was an invalid event.
6087+
6088+--*/
6089+{
6090+ PCOMM_FIB_CONTEXT FibContext = Context;
6091+ PFIB Fib = FibContext->Fib;
6092+ PAFA_COMM_ADAPTER Adapter = FibContext->Adapter;
6093+ ULONG DontInterrupt = FALSE;
6094+
6095+ if (Fib->Header.XferState == 0)
6096+ return(STATUS_SUCCESS);
6097+
6098+ //
6099+ // If we plan to do anything check the structure type first.
6100+ //
6101+
6102+ if ( Fib->Header.StructType != TFib ) {
6103+ FsaCommPrint("Error CompleteFib called with a non Fib structure.\n");
6104+ return(STATUS_UNSUCCESSFUL);
6105+ }
6106+
6107+ //
6108+ // This block handles the case where the adapter had sent us a command and we
6109+ // have finished processing the command. We call completeFib when we are done
6110+ // processing the command and want to send a response back to the adapter. This
6111+ // will send the completed cdb to the adapter.
6112+ //
6113+
6114+ if (Fib->Header.XferState & SentFromAdapter) {
6115+ Fib->Header.XferState |= HostProcessed;
6116+ if (Fib->Header.XferState & HighPriority) {
6117+ QUEUE_INDEX Index;
6118+
6119+ if (Size) {
6120+ Size += sizeof(FIB_HEADER);
6121+ if (Size > Fib->Header.SenderSize)
6122+ return(STATUS_BUFFER_OVERFLOW);
6123+ Fib->Header.Size = Size;
6124+ }
6125+
6126+ if (GetQueueEntry(Adapter, &Index, AdapHighRespQueue, Fib, TRUE, NULL, &DontInterrupt) != STATUS_SUCCESS) {
6127+ FsaCommPrint("CompleteFib got an error geting a queue entry for a response.\n");
6128+ return(FSA_FATAL);
6129+ }
6130+ if (InsertQueueEntry(Adapter,
6131+ Index,
6132+ AdapHighRespQueue,
6133+ (DontInterrupt & (BOOLEAN)FsaCommData.EnableInterruptModeration)) != STATUS_SUCCESS) {
6134+ FsaCommPrint("CompleteFib failed while inserting entry on the queue.\n");
6135+ }
6136+ } else if (Fib->Header.XferState & NormalPriority) {
6137+ QUEUE_INDEX Index;
6138+
6139+ if (Size) {
6140+ Size += sizeof(FIB_HEADER);
6141+ if (Size > Fib->Header.SenderSize)
6142+ return(STATUS_BUFFER_OVERFLOW);
6143+ Fib->Header.Size = Size;
6144+ }
6145+
6146+ if (GetQueueEntry(Adapter, &Index, AdapNormRespQueue, Fib, TRUE, NULL, &DontInterrupt) != STATUS_SUCCESS) {
6147+ FsaCommPrint("CompleteFib got an error geting a queue entry for a response.\n");
6148+ return(FSA_FATAL);
6149+ }
6150+ if (InsertQueueEntry(Adapter,
6151+ Index,
6152+ AdapNormRespQueue,
6153+ (DontInterrupt & (BOOLEAN)FsaCommData.EnableInterruptModeration)) != STATUS_SUCCESS) {
6154+ FsaCommPrint("CompleteFib failed while inserting entry on the queue.\n");
6155+ }
6156+ }
6157+ } else {
6158+ cmn_err(CE_WARN, "CompleteFib: Unknown xferstate detected.\n");
6159+ FsaBugCheck(0,0,0);
6160+ }
6161+ return(STATUS_SUCCESS);
6162+}
6163+
6164+AAC_STATUS
6165+CompleteFib(
6166+ IN PFIB_CONTEXT Context
6167+ )
6168+/*++
6169+
6170+Routine Description:
6171+
6172+ Will do all necessary work to complete a FIB. If the caller wishes to
6173+ reuse the FIB after post processing has been completed Reinitialize
6174+ should be called set to TRUE, otherwise the FIB will be returned to the
6175+ free FIB pool. If Reinitialize is set to TRUE then the FIB header is
6176+ reinitialzied and is ready for reuse on return from this routine.
6177+
6178+Arguments:
6179+
6180+ Fib is a pointer to the FIB that caller wishes to complete processing on.
6181+
6182+ Size - Size of the completion Packet(Opitional). If not present than the current
6183+ largest size in the Fib will be used
6184+
6185+ Reinitialize is a boolean which determines if the routine will ready the
6186+ completed FIB for reuse(TRUE) or not(FALSE).
6187+
6188+Return Value:
6189+
6190+ NT_SUCCESS if a Fib was returned to the caller.
6191+ NT_ERROR if event was an invalid event.
6192+
6193+--*/
6194+{
6195+ PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
6196+ PAFA_COMM_ADAPTER Adapter = FibContext->Adapter;
6197+ PFIB Fib = FibContext->Fib;
6198+
6199+ //
6200+ // Check for a fib which has already been completed
6201+ //
6202+
6203+// ASSERT(Fib->Header.XferState & AdapterProcessed);
6204+ if (Fib->Header.XferState == 0)
6205+ return(STATUS_SUCCESS);
6206+
6207+ //
6208+ // If we plan to do anything check the structure type first.
6209+ //
6210+
6211+ if ( Fib->Header.StructType != TFib ) {
6212+ FsaCommPrint("Error CompleteFib called with a non Fib structure.\n");
6213+ return(STATUS_UNSUCCESSFUL);
6214+ }
6215+
6216+#if 0
6217+//#if FSA_ADAPTER_METER
6218+ //
6219+ // Meter the completion
6220+ //
6221+ fsaMeterEnd( // meter the end of an operation
6222+ &(Adapter->FibMeter), // .. the meter
6223+ IrpContext->FibMeterType, // .. type of operation
6224+ &(IrpContext->FibStartTime), // .. ptr to operation start timestamp
6225+ FibGetMeterSize(Fib, // .. number of bytes in operation
6226+ IrpContext->FibMeterType,
6227+ IrpContext->FibSubCommand));
6228+#endif // FSA_ADAPTER_METER
6229+
6230+ //
6231+ // This block completes a cdb which orginated on the host and we just need
6232+ // to deallocate the cdb or reinit it. At this point the command is complete
6233+ // that we had sent to the adapter and this cdb could be reused.
6234+ //
6235+
6236+ if ( (Fib->Header.XferState & SentFromHost) &&
6237+ (Fib->Header.XferState & AdapterProcessed)) {
6238+
6239+ ASSERT(FibContext->LogicalFibAddress.LowPart != 0);
6240+
6241+ return( DeallocateFib(FibContext) );
6242+
6243+ //
6244+ // This handles the case when the host has aborted the I/O to the
6245+ // adapter because the adapter is not responding
6246+ //
6247+
6248+ } else if (Fib->Header.XferState & SentFromHost) {
6249+
6250+ ASSERT(FibContext->LogicalFibAddress.LowPart != 0);
6251+
6252+
6253+ return( DeallocateFib(FibContext) );
6254+
6255+ } else if (Fib->Header.XferState & HostOwned) {
6256+
6257+ return(DeallocateFib(FibContext));
6258+
6259+ } else {
6260+ cmn_err(CE_WARN, "CompleteFib: Unknown xferstate detected.\n");
6261+ FsaBugCheck(0,0,0);
6262+ }
6263+ return(STATUS_SUCCESS);
6264+}
6265+
6266+VOID
6267+HandleDriverAif(
6268+ IN PAFA_COMM_ADAPTER Adapter,
6269+ IN PCOMM_FIB_CONTEXT FibContext
6270+ )
6271+/*++
6272+
6273+Routine Description:
6274+
6275+ This routine handles a driver notify fib from the adapter and dispatches it to
6276+ the appropriate routine for handling.
6277+
6278+Arguments:
6279+
6280+ Adapter - Which adapter this fib is from
6281+ FibContext - Pointer to FibContext from adapter.
6282+
6283+Return Value:
6284+
6285+ Nothing.
6286+
6287+--*/
6288+{
6289+ PFIB Fib = FibContext->Fib;
6290+ PAFA_CLASS_DRIVER ClassDriver;
6291+ BOOLEAN Handled = FALSE;
6292+
6293+
6294+ //
6295+ // First loop through all of the class drivers to give them a chance to handle
6296+ // the Fib.
6297+ //
6298+
6299+ ClassDriver = Adapter->ClassDriverList;
6300+
6301+ while (ClassDriver) {
6302+
6303+ if (ClassDriver->HandleAif) {
6304+
6305+ if (ClassDriver->HandleAif( ClassDriver->ClassDriverExtension, FibContext ) ) {
6306+
6307+ Handled = TRUE;
6308+ break;
6309+
6310+ }
6311+ }
6312+
6313+ ClassDriver = ClassDriver->Next;
6314+ }
6315+
6316+ if (!Handled) {
6317+
6318+ //
6319+ // Set the status of this FIB to be Invalid parameter.
6320+ //
6321+
6322+// *(FSASTATUS *)Fib->data = ST_INVAL;
6323+ *(FSASTATUS *)Fib->data = ST_OK;
6324+
6325+
6326+ CompleteAdapterFib(FibContext, sizeof(FSASTATUS));
6327+
6328+ }
6329+}
6330+
6331+int
6332+NormCommandThread(
6333+ IN PAFA_COMM_ADAPTER Adapter
6334+ )
6335+/*++
6336+
6337+Routine Description:
6338+
6339+ Waits on the commandready event in it's queue. When the event gets set it will
6340+ pull FIBs off it's queue. It will continue to pull FIBs off till the queue is empty.
6341+ When the queue is empty it will wait for more FIBs.
6342+
6343+Arguments:
6344+
6345+ Context is used. All data os global
6346+
6347+Return Value:
6348+ Nothing.
6349+
6350+--*/
6351+{
6352+ PFIB Fib, NewFib;
6353+ COMM_FIB_CONTEXT FibContext; // for error logging
6354+ KIRQL SavedIrql;
6355+ PCOMM_REGION CommRegion = Adapter->CommRegion;
6356+ PLIST_ENTRY Entry;
6357+ PGET_ADAPTER_FIB_CONTEXT AdapterFibContext;
6358+
6359+ //
6360+ // We can only have one thread per adapter for AIF's.
6361+ //
6362+
6363+ if (Adapter->AifThreadStarted) {
6364+ return (EINVAL);
6365+ }
6366+
6367+// cmn_err(CE_DEBUG, "AIF thread started");
6368+
6369+ //
6370+ // Let the DPC know it has a place to send the AIF's to.
6371+ //
6372+
6373+ Adapter->AifThreadStarted = TRUE;
6374+
6375+ RtlZeroMemory(&FibContext, sizeof(COMM_FIB_CONTEXT));
6376+
6377+ OsSpinLockAcquire(CommRegion->HostNormCmdQue.QueueLock);
6378+
6379+ while (TRUE) {
6380+
6381+ //
6382+ // NOTE : the QueueLock is held at the top of each loop.
6383+ //
6384+
6385+ ASSERT(OsSpinLockOwned(CommRegion->HostNormCmdQue.QueueLock));
6386+
6387+ while (!IsListEmpty(&(CommRegion->HostNormCmdQue.CommandQueue))) {
6388+ PLIST_ENTRY Entry;
6389+ PAIFCOMMANDTOHOST AifCommandToHost;
6390+
6391+ Entry = RemoveHeadList(&(CommRegion->HostNormCmdQue.CommandQueue));
6392+
6393+ OsSpinLockRelease(CommRegion->HostNormCmdQue.QueueLock);
6394+
6395+ Fib = CONTAINING_RECORD( Entry, FIB, Header.FibLinks );
6396+
6397+ //
6398+ // We will process the FIB here or pass it to a worker thread that is TBD. We Really
6399+ // can't do anything at this point since we don't have anything defined for this thread to
6400+ // do.
6401+ //
6402+
6403+ // cmn_err(CE_DEBUG, "Got Fib from the adapter with a NORMAL priority, command 0x%x.\n", Fib->Header.Command);
6404+
6405+ RtlZeroMemory( &FibContext, sizeof(COMM_FIB_CONTEXT) );
6406+
6407+
6408+ FibContext.NodeTypeCode = FSAFS_NTC_FIB_CONTEXT;
6409+ FibContext.NodeByteSize = sizeof( COMM_FIB_CONTEXT );
6410+ FibContext.Fib = Fib;
6411+ FibContext.FibData = Fib->data;
6412+ FibContext.Adapter = Adapter;
6413+
6414+
6415+ //
6416+ // We only handle AifRequest fibs from the adapter.
6417+ //
6418+
6419+ ASSERT(Fib->Header.Command == AifRequest);
6420+
6421+
6422+ AifCommandToHost = (PAIFCOMMANDTOHOST) Fib->data;
6423+
6424+ if (AifCommandToHost->command == AifCmdDriverNotify) {
6425+
6426+
6427+
6428+ HandleDriverAif( Adapter, &FibContext );
6429+
6430+ } else {
6431+ AAC_UINT32 time_now, time_last;
6432+ time_now = (AAC_UINT32)OsGetSeconds();
6433+
6434+
6435+ OsCvLockAcquire(Adapter->AdapterFibMutex);
6436+
6437+ Entry = Adapter->AdapterFibContextList.Flink;
6438+
6439+ //
6440+ // For each Context that is on the AdapterFibContextList, make a copy of the
6441+ // fib, and then set the event to wake up the thread that is waiting for it.
6442+ //
6443+
6444+ while (Entry != &Adapter->AdapterFibContextList) {
6445+
6446+ //
6447+ // Extract the AdapterFibContext
6448+ //
6449+
6450+ AdapterFibContext = CONTAINING_RECORD( Entry, GET_ADAPTER_FIB_CONTEXT, NextContext );
6451+
6452+ //
6453+ // Check if the queue is getting backlogged
6454+ //
6455+ if ( AdapterFibContext->FibCount > 20 ) {
6456+ time_last = (AAC_UINT32)(AdapterFibContext->FileObject);
6457+
6458+ //
6459+ // has it been > 2 minutes since the last read off the queue?
6460+ //
6461+ if ((time_now - time_last) > 120) {
6462+ Entry = Entry->Flink;
6463+ // cmn_err (CE_WARN, "aifd: Flushing orphaned AdapterFibContext: idle %d seconds, %d fibs",
6464+ // time_now - time_last,
6465+ // AdapterFibContext->FibCount);
6466+ FsaCloseAdapterFibContext ( Adapter, AdapterFibContext );
6467+ continue;
6468+ }
6469+ }
6470+
6471+// Warning: sleep possible while holding spinlock
6472+ NewFib = OsAllocMemory(sizeof(FIB), OS_ALLOC_MEM_SLEEP);
6473+
6474+ if (NewFib) {
6475+
6476+ //
6477+ // Make the copy of the FIB
6478+ //
6479+
6480+ RtlCopyMemory(NewFib, Fib, sizeof(FIB));
6481+
6482+ //
6483+ // Put the FIB onto the AdapterFibContext's FibList
6484+ //
6485+
6486+ InsertTailList(&AdapterFibContext->FibList, &NewFib->Header.FibLinks);
6487+ AdapterFibContext->FibCount++;
6488+
6489+ //
6490+ // Set the event to wake up the thread that will waiting.
6491+ //
6492+
6493+ OsCv_signal(&AdapterFibContext->UserEvent);
6494+
6495+ } else {
6496+
6497+ cmn_err (CE_WARN, "aifd: didn't allocate NewFib");
6498+
6499+ }
6500+
6501+ Entry = Entry->Flink;
6502+ }
6503+
6504+ //
6505+ // Set the status of this FIB
6506+ //
6507+
6508+ *(FSASTATUS *)Fib->data = ST_OK;
6509+
6510+ CompleteAdapterFib( &FibContext, sizeof(FSASTATUS) );
6511+
6512+ OsCvLockRelease(Adapter->AdapterFibMutex);
6513+
6514+ }
6515+
6516+ OsSpinLockAcquire(CommRegion->HostNormCmdQue.QueueLock);
6517+
6518+ }
6519+
6520+ //
6521+ // There are no more AIF's, call cv_wait_sig to wait for more
6522+ // to process.
6523+ //
6524+
6525+ // cmn_err(CE_DEBUG, "no more AIF's going to sleep\n");
6526+
6527+ if (OsCv_wait_sig( &(CommRegion->HostNormCmdQue.CommandReady),
6528+ CommRegion->HostNormCmdQue.QueueLock ) == 0) {
6529+
6530+ OsSpinLockRelease(CommRegion->HostNormCmdQue.QueueLock);
6531+
6532+ Adapter->AifThreadStarted = FALSE;
6533+
6534+ // cmn_err(CE_DEBUG, "AifThread awoken by a signal\n");
6535+
6536+ return (EINTR);
6537+
6538+ }
6539+
6540+ // cmn_err(CE_DEBUG, "Aif thread awake, going to look for more AIF's\n");
6541+
6542+ }
6543+}
6544+
6545+
6546+PVOID
6547+FsaGetFibData(
6548+ IN PFIB_CONTEXT Context
6549+ )
6550+{
6551+ PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
6552+
6553+ return ((PVOID)FibContext->Fib->data);
6554+}
6555+
6556+
6557+#ifdef API_THROTTLE
6558+
6559+void ThrottlePeriodEndDpcRtn(
6560+ IN PKDPC Dpc,
6561+ IN PVOID DeferredContext,
6562+ IN PVOID SystemArgument1,
6563+ IN PVOID SystemArgument2
6564+ )
6565+/*++
6566+
6567+Routine Description:
6568+
6569+ This routine is called as a DPC when a throttle period expires. It
6570+ restarts all threads suspended due to the throttling flow control.
6571+
6572+ The throttling counted semaphore is signalled for all waiting threads
6573+ and the indicator of throttling active is cleared.
6574+
6575+Arguments:
6576+
6577+ Dpc - Pointer to Dpc structure. Not used.
6578+ DefferedContext - Pointer to per-adapter context. This is used to locate the
6579+ throttle information for this adapter.
6580+ SystemArgument1 - Not used
6581+ SystemArgument2 - Not used
6582+
6583+Return Value:
6584+
6585+ None.
6586+
6587+--*/
6588+{
6589+ PCOMM_REGION CommRegion;
6590+ PAFA_COMM_ADAPTER Adapter = (PAFA_COMM_ADAPTER) DeferredContext;
6591+
6592+ CommRegion = Adapter->CommRegion;
6593+
6594+ //
6595+ // Acquire the spinlock protecting the throttle status.
6596+ //
6597+ OsSpinLockAcquire(CommRegion->AdapNormCmdQue.QueueLock);
6598+
6599+ FsaCommPrint("ThrottlePeriodEndDpc\n");
6600+
6601+ //
6602+ // Check that the timer has fired as many times as it was set !
6603+ //
6604+
6605+ CommRegion->ThrottleTimerFires++;
6606+ ASSERT(CommRegion->ThrottleTimerFires == CommRegion->ThrottleTimerSets);
6607+
6608+ //
6609+ // The throttle period is now over. Restart all threads waiting
6610+ // on the throttle being released.
6611+ // Clear the throttle active indicator. This will allow new FIBs
6612+ // to be sent to the adapter once we release the spinlock on exiting
6613+ // the DPC. This means all restarted threads will be runnable
6614+ // threads by then.
6615+ //
6616+
6617+ ASSERT(CommRegion->ThrottleActive == TRUE); // The throttle had better be on !
6618+ CommRegion->ThrottleActive = FALSE; // This allows new data FIBs to go to the adapter on dpc exit
6619+
6620+ OsSpinLockRelease(CommRegion->AdapNormCmdQue.QueueLock);
6621+}
6622+
6623+#endif // #ifdef API_THROTTLE
6624+
6625+/*
6626+ * Overrides for Emacs so that we almost follow Linus's tabbing style.
6627+ * Emacs will notice this stuff at the end of the file and automatically
6628+ * adjust the settings for this buffer only. This must remain at the end
6629+ * of the file.
6630+ * ---------------------------------------------------------------------------
6631+ * Local variables:
6632+ * c-indent-level: 4
6633+ * c-brace-imaginary-offset: 0
6634+ * c-brace-offset: -4
6635+ * c-argdecl-indent: 4
6636+ * c-label-offset: -4
6637+ * c-continued-statement-offset: 4
6638+ * c-continued-brace-offset: 0
6639+ * indent-tabs-mode: nil
6640+ * tab-width: 8
6641+ * End:
6642+ */
6643diff -burN linux-2.4.7/drivers/scsi/aacraid/dpcsup.c linux/drivers/scsi/aacraid/dpcsup.c
6644--- linux-2.4.7/drivers/scsi/aacraid/dpcsup.c Wed Dec 31 18:00:00 1969
6645+++ linux/drivers/scsi/aacraid/dpcsup.c Sat Jul 21 17:55:13 2001
6646@@ -0,0 +1,443 @@
6647+/*++
6648+ * Adaptec aacraid device driver for Linux.
6649+ *
6650+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
6651+ *
6652+ * This program is free software; you can redistribute it and/or modify
6653+ * it under the terms of the GNU General Public License as published by
6654+ * the Free Software Foundation; either version 2, or (at your option)
6655+ * any later version.
6656+ *
6657+ * This program is distributed in the hope that it will be useful,
6658+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6659+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6660+ * GNU General Public License for more details.
6661+ *
6662+ * You should have received a copy of the GNU General Public License
6663+ * along with this program; see the file COPYING. If not, write to
6664+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
6665+ *
6666+ * Module Name:
6667+ * dpcsup.c
6668+ *
6669+ * Abstract: All DPC processing routines for the cyclone board occur here.
6670+ *
6671+ *
6672+ --*/
6673+
6674+static char *ident_dpcsup = "aacraid_ident dpcsup.c 1.0.6 2000/10/09 Adaptec, Inc.";
6675+
6676+#include "comprocs.h"
6677+
6678+
6679+//
6680+// The Bug check file id for this module
6681+//
6682+
6683+#define BugCheckFileId (FSAFS_BUG_CHECK_DPCSUP)
6684+
6685+#define Dbg (DEBUG_TRACE_DPCSUP)
6686+
6687+u_int
6688+CommonNotFullDpc(
6689+ IN PCOMM_REGION CommRegion
6690+ )
6691+/*++
6692+
6693+Routine Description:
6694+
6695+ This DPC routine will be queued when the adapter interrupts us to let us know the queue is
6696+ no longer full. The Isr will pass the queue that we will set the not full event.
6697+
6698+Arguments:
6699+
6700+ Dpc - Pointer to this routine.
6701+
6702+ Dummy - is a pointer to the comm region which is global so we don't need it anyway
6703+
6704+ Queue is a pointer to the queue structure we will operate on.
6705+
6706+ MoreData2 are DPC parameters we don't need for this function. Maybe we can add some accounting
6707+ stuff in here.
6708+
6709+Return Value:
6710+ Nothing.
6711+
6712+--*/
6713+{
6714+
6715+#ifdef unix_queue_full
6716+ KeSetEvent(&Queue->QueueFull, 0, FALSE);
6717+#endif
6718+
6719+}
6720+
6721+int GatherFibTimes = 0;
6722+
6723+// XXX - hack this in until I figure out which header file should contain it. <smb>
6724+extern ULONG
6725+FibGetMeterSize(
6726+ PFIB pFib,
6727+ ULONG MeterType,
6728+ char SubCommand
6729+ );
6730+
6731+
6732+/*++
6733+
6734+Routine Description:
6735+
6736+ This DPC routine will be queued when the adapter interrupts us to let us know there
6737+ is a response on our normal priority queue. We will pull off all QE there are and wake
6738+ up all the waiters before exiting. We will take a spinlock out on the queue before operating
6739+ on it.
6740+
6741+Arguments:
6742+
6743+ Dpc - Pointer to this routine.
6744+
6745+ OurQueue is a pointer to the queue structure we will operate on.
6746+
6747+ MoreData1&2 are DPC parameters we don't need for this function. Maybe we can add some accounting
6748+ stuff in here.
6749+
6750+Return Value:
6751+ Nothing.
6752+
6753+--*/
6754+u_int
6755+HostResponseNormalDpc (IN PCOMM_QUE OurQueue)
6756+{
6757+ PAFA_COMM_ADAPTER Adapter = OurQueue->Adapter;
6758+ PQUEUE_ENTRY QueueEntry;
6759+ PFIB Fib;
6760+ PCOMM_FIB_CONTEXT FibContext;
6761+ int Consumed = 0;
6762+ KIRQL OldIrql;
6763+
6764+ LARGE_INTEGER ResponseAllocSize;
6765+
6766+#ifdef commdebug
6767+ FsaCommPrint("entering the host normal reponse dpc routine.\n");
6768+#endif
6769+
6770+ OsSpinLockAcquire( OurQueue->QueueLock );
6771+
6772+ //
6773+ // Keep pulling response QEs off the response queue and waking
6774+ // up the waiters until there are no more QEs. We then return
6775+ // back to the system. If no response was requesed we just
6776+ // deallocate the Fib here and continue.
6777+ //
6778+
6779+ loop:
6780+ while ( GetConsumerEntry( Adapter, OurQueue, &QueueEntry) ) {
6781+
6782+ int IsFastResponse;
6783+
6784+ IsFastResponse = (int) (QueueEntry->FibAddress & 0x01);
6785+ Fib = (PFIB) (QueueEntry->FibAddress & ~0x01);
6786+
6787+ FreeConsumerEntry(Adapter, OurQueue, HostNormRespQueue);
6788+
6789+ FibContext = (PCOMM_FIB_CONTEXT)Fib->Header.SenderData;
6790+
6791+ ASSERT(FibContext->Fib == Fib);
6792+
6793+ //
6794+ // Remove this FibContext from the Outstanding I/O queue.
6795+ // But only if it has not already been timed out.
6796+ //
6797+ // If the fib has been timed out already, then just continue.
6798+ // The caller has already been notified that the fib timed out.
6799+ //
6800+
6801+ if (!(FibContext->Flags & FIB_CONTEXT_FLAG_TIMED_OUT)) {
6802+
6803+ RemoveEntryList( &FibContext->QueueEntry );
6804+ Adapter->CommRegion->AdapNormCmdQue.NumOutstandingIos--;
6805+
6806+ } else {
6807+
6808+ FsaCommLogEvent(FibContext,
6809+ FsaCommData.DeviceObject,
6810+ FSAFS_TIMED_OUT_FIB_COMPLETED,
6811+ STATUS_UNSUCCESSFUL,
6812+ BugCheckFileId | __LINE__,
6813+ FACILITY_FSAFS_ERROR_CODE,
6814+ NULL,
6815+ TRUE);
6816+
6817+ continue;
6818+
6819+ }
6820+
6821+ OsSpinLockRelease( OurQueue->QueueLock );
6822+
6823+ if (IsFastResponse) {
6824+
6825+ //
6826+ // doctor the fib
6827+ //
6828+
6829+ *(FSASTATUS *)Fib->data = ST_OK;
6830+
6831+ Fib->Header.XferState |= AdapterProcessed;
6832+
6833+ }
6834+
6835+ ASSERT((Fib->Header.XferState & (AdapterProcessed | HostOwned | SentFromHost)) == (AdapterProcessed | HostOwned | SentFromHost));
6836+
6837+ FIB_COUNTER_INCREMENT(FsaCommData.FibRecved);
6838+
6839+ ASSERT(FsaCommData.FibsSent >= FsaCommData.FibRecved);
6840+
6841+
6842+ if (Fib->Header.Command == NuFileSystem) {
6843+
6844+ FSASTATUS *pStatus = (FSASTATUS *)Fib->data;
6845+
6846+ if (*pStatus & 0xffff0000) {
6847+
6848+ ULONG Hint = *pStatus;
6849+
6850+ *pStatus = ST_OK;
6851+
6852+/*
6853+ DbgPrint("Replacing hint in fid (drive = %d, f1 = 0x%x, f2 = 0x%x, hint = 0x%x, new_hint = 0x%x)\n",
6854+ IrpContext->NonPaged->FileId.fid_driveno,
6855+ IrpContext->NonPaged->FileId.fid_f1,
6856+ IrpContext->NonPaged->FileId.fid_f2,
6857+ IrpContext->NonPaged->FileId.fid_hint,
6858+ Hint);
6859+*/
6860+
6861+ }
6862+
6863+ }
6864+
6865+ if (Fib->Header.XferState & (NoResponseExpected | Async) ) {
6866+
6867+ ASSERT(FibContext->FibCallback);
6868+
6869+ if (Fib->Header.XferState & NoResponseExpected)
6870+ FIB_COUNTER_INCREMENT(FsaCommData.NoResponseRecved);
6871+ else
6872+ FIB_COUNTER_INCREMENT(FsaCommData.AsyncRecved);
6873+
6874+ //
6875+ // NOTE: we can not touch the FibContext after this call, because it may have been
6876+ // deallocated.
6877+ //
6878+
6879+ FibContext->FibCallback(FibContext->FibCallbackContext, FibContext, STATUS_SUCCESS);
6880+
6881+ } else {
6882+
6883+ OsCvLockAcquire( FibContext->FsaEventMutex);
6884+
6885+ FibContext->FibComplete = 1;
6886+
6887+ OsCv_signal( &FibContext->FsaEvent );
6888+
6889+ OsCvLockRelease( FibContext->FsaEventMutex );
6890+
6891+ FIB_COUNTER_INCREMENT(FsaCommData.NormalRecved);
6892+
6893+ }
6894+
6895+
6896+ Consumed++;
6897+
6898+ OsSpinLockAcquire( OurQueue->QueueLock );
6899+
6900+ }
6901+
6902+ if (Consumed > FsaCommData.PeakFibsConsumed)
6903+ FsaCommData.PeakFibsConsumed = Consumed;
6904+
6905+ if (Consumed == 0)
6906+ FsaCommData.ZeroFibsConsumed++;
6907+
6908+ if (FsaCommData.HardInterruptModeration) {
6909+
6910+ //
6911+ // Re-Enable the interrupt from the adapter, then recheck to see if anything has
6912+ // been put on the queue. This removes the race condition that exists between the
6913+ // last time we checked the queue, and when we re-enabled the interrupt.
6914+ //
6915+ // If there is something on the queue, then go handle it.
6916+ //
6917+
6918+ EnableInterrupt( Adapter, HostNormRespQue, FALSE );
6919+
6920+ if (ConsumerEntryAvailable( Adapter, OurQueue ) ) {
6921+
6922+ DisableInterrupt( Adapter, HostNormRespQue, FALSE );
6923+
6924+ goto loop;
6925+
6926+ }
6927+ }
6928+
6929+#ifdef commdebug
6930+ FsaCommPrint("Exiting host normal reponse dpc routine after consuming %d QE(s).\n",Consumed);
6931+#endif
6932+
6933+ OsSpinLockRelease( OurQueue->QueueLock );
6934+
6935+}
6936+
6937+/*++
6938+
6939+Routine Description:
6940+
6941+ This DPC routine wiol be queued when the adapter interrupts us to let us know there
6942+ is a response on our high priority queue. We will pull off all QE there are and wake
6943+ up all the waiters before exiting. We will take a spinlock out on the queue before operating
6944+ on it.
6945+
6946+Arguments:
6947+
6948+ Dpc - Pointer to this routine.
6949+
6950+ OurQueue is a pointer to the queue structure we will operate on.
6951+
6952+ MoreData1&2 are DPC parameters we don't need for this function. Maybe we can add some accounting
6953+ stuff in here.
6954+
6955+Return Value:
6956+ Nothing.
6957+
6958+--*/
6959+u_int
6960+HostResponseHighDpc (IN PCOMM_QUE OurQueue)
6961+{}
6962+
6963+
6964+/*++
6965+
6966+Routine Description:
6967+
6968+ This DPC routine will be queued when the adapter interrupts us to let us know there
6969+ is a command on our high priority queue. We will pull off all QE there are and wake
6970+ up all the waiters before exiting. We will take a spinlock out on the queue before operating
6971+ on it.
6972+
6973+Arguments:
6974+
6975+ Dpc - Pointer to this routine.
6976+
6977+ OurQueue is a pointer to the queue structure we will operate on.
6978+
6979+ MoreData1&2 are DPC parameters we don't need for this function. Maybe we can add some accounting
6980+ stuff in here.
6981+
6982+Return Value:
6983+ Nothing.
6984+
6985+--*/
6986+u_int
6987+HostCommandHighDpc (IN PCOMM_QUE OurQueue)
6988+{}
6989+
6990+
6991+/*++
6992+
6993+Routine Description:
6994+
6995+ This DPC routine will be queued when the adapter interrupts us to let us know there
6996+ is a command on our normal priority queue. We will pull off all QE there are and wake
6997+ up all the waiters before exiting. We will take a spinlock out on the queue before operating
6998+ on it.
6999+
7000+Arguments:
7001+
7002+ Dpc - Pointer to this routine.
7003+
7004+ OurQueue is a pointer to the queue structure we will operate on.
7005+
7006+ MoreData1&2 are DPC parameters we don't need for this function. Maybe we can add some accounting
7007+ stuff in here.
7008+
7009+Return Value:
7010+ Nothing.
7011+
7012+--*/
7013+u_int
7014+HostCommandNormDpc (IN PCOMM_QUE OurQueue)
7015+{
7016+ PAFA_COMM_ADAPTER Adapter = OurQueue->Adapter;
7017+ PQUEUE_ENTRY QueueEntry;
7018+
7019+ OsSpinLockAcquire( OurQueue->QueueLock );
7020+
7021+ //
7022+ // Keep pulling response QEs off the response queue and waking
7023+ // up the waiters until there are no more QEs. We then return
7024+ // back to the system.
7025+ //
7026+
7027+ while ( GetConsumerEntry( Adapter, OurQueue, &QueueEntry) ) {
7028+
7029+ PFIB Fib;
7030+
7031+ Fib = (PFIB)QueueEntry->FibAddress;
7032+
7033+
7034+ if (Adapter->AifThreadStarted) {
7035+
7036+
7037+// cmn_err(CE_CONT, "^Received AIF, putting onto command queue\n");
7038+
7039+
7040+ InsertTailList(&OurQueue->CommandQueue, &Fib->Header.FibLinks);
7041+ FreeConsumerEntry(Adapter, OurQueue, HostNormCmdQueue);
7042+ OsCv_signal(&OurQueue->CommandReady);
7043+
7044+
7045+
7046+ } else {
7047+
7048+
7049+
7050+ COMM_FIB_CONTEXT FibContext;
7051+
7052+
7053+
7054+ FreeConsumerEntry(Adapter, OurQueue, HostNormCmdQueue);
7055+
7056+
7057+
7058+ OsSpinLockRelease( OurQueue->QueueLock );
7059+
7060+
7061+
7062+// cmn_err(CE_CONT, "^Received AIF, thread not started\n");
7063+
7064+
7065+ RtlZeroMemory( &FibContext, sizeof(COMM_FIB_CONTEXT) );
7066+
7067+ FibContext.NodeTypeCode = FSAFS_NTC_FIB_CONTEXT;
7068+ FibContext.NodeByteSize = sizeof( COMM_FIB_CONTEXT );
7069+ FibContext.Fib = Fib;
7070+ FibContext.FibData = Fib->data;
7071+ FibContext.Adapter = Adapter;
7072+
7073+ //
7074+ // Set the status of this FIB
7075+ //
7076+
7077+ *(FSASTATUS *)Fib->data = ST_OK;
7078+
7079+ CompleteAdapterFib( &FibContext, sizeof(FSASTATUS) );
7080+
7081+
7082+
7083+ OsSpinLockAcquire( OurQueue->QueueLock );
7084+ }
7085+ }
7086+
7087+ OsSpinLockRelease( OurQueue->QueueLock );
7088+
7089+}
7090diff -burN linux-2.4.7/drivers/scsi/aacraid/include/AacGenericTypes.h linux/drivers/scsi/aacraid/include/AacGenericTypes.h
7091--- linux-2.4.7/drivers/scsi/aacraid/include/AacGenericTypes.h Wed Dec 31 18:00:00 1969
7092+++ linux/drivers/scsi/aacraid/include/AacGenericTypes.h Sat Jul 21 17:55:13 2001
7093@@ -0,0 +1,57 @@
7094+/*++
7095+ * Adaptec aacraid device driver for Linux.
7096+ *
7097+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
7098+ *
7099+ * This program is free software; you can redistribute it and/or modify
7100+ * it under the terms of the GNU General Public License as published by
7101+ * the Free Software Foundation; either version 2, or (at your option)
7102+ * any later version.
7103+ *
7104+ * This program is distributed in the hope that it will be useful,
7105+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7106+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7107+ * GNU General Public License for more details.
7108+ *
7109+ * You should have received a copy of the GNU General Public License
7110+ * along with this program; see the file COPYING. If not, write to
7111+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
7112+ *
7113+ * Module Name:
7114+ *
7115+ * AacGenericTypes.h
7116+ *
7117+ * Abstract:
7118+ *
7119+ * The module defines the generic data types that all of the other header files
7120+ * depend upon.
7121+ --*/
7122+
7123+#ifndef _AAC_GENERIC_TYPES
7124+#define _AAC_GENERIC_TYPES
7125+
7126+static char *ident_AacGeneric = "aacraid_ident AacGenericTypes.h 1.0.6 2000/10/09 Adaptec, Inc.";
7127+
7128+typedef char AAC_INT8, *PAAC_INT8;
7129+typedef short AAC_INT16, *PAAC_INT16;
7130+typedef int AAC_INT32, *PAAC_INT32;
7131+typedef long long AAC_INT64, *PAAC_INT64;
7132+
7133+typedef unsigned char AAC_UINT8, *PAAC_UINT8;
7134+typedef unsigned short AAC_UINT16, *PAAC_UINT16;
7135+typedef unsigned int AAC_UINT32, *PAAC_UINT32;
7136+typedef unsigned long long AAC_UINT64, *PAAC_UINT64;
7137+
7138+typedef void AAC_VOID, *PAAC_VOID;
7139+
7140+//
7141+// this compiler uses 32 bit enum data types
7142+//
7143+
7144+#define AAC_32BIT_ENUMS 1
7145+#define FAILURE 1
7146+#define INTR_UNCLAIMED 1
7147+#define INTR_CLAIMED 0
7148+
7149+#endif // _AAC_GENERIC_TYPES
7150+
7151diff -burN linux-2.4.7/drivers/scsi/aacraid/include/aac_unix_defs.h linux/drivers/scsi/aacraid/include/aac_unix_defs.h
7152--- linux-2.4.7/drivers/scsi/aacraid/include/aac_unix_defs.h Wed Dec 31 18:00:00 1969
7153+++ linux/drivers/scsi/aacraid/include/aac_unix_defs.h Sat Jul 21 17:55:13 2001
7154@@ -0,0 +1,300 @@
7155+/*++
7156+ * Adaptec aacraid device driver for Linux.
7157+ *
7158+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
7159+ *
7160+ * This program is free software; you can redistribute it and/or modify
7161+ * it under the terms of the GNU General Public License as published by
7162+ * the Free Software Foundation; either version 2, or (at your option)
7163+ * any later version.
7164+ *
7165+ * This program is distributed in the hope that it will be useful,
7166+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7167+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7168+ * GNU General Public License for more details.
7169+ *
7170+ * You should have received a copy of the GNU General Public License
7171+ * along with this program; see the file COPYING. If not, write to
7172+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
7173+ *
7174+ * Module Name:
7175+ *
7176+ * aac_unix_defs.h
7177+ *
7178+ * Abstract:
7179+ *
7180+ * Macro definition and typedefs
7181+ *
7182+ --*/
7183+
7184+#ifndef _AAC_UNIX_DEFS
7185+#define _AAC_UNIX_DEFS
7186+
7187+static char *ident_aac_unix = "aacraid_ident aac_unix_defs.h 1.0.6 2000/10/09 Adaptec, Inc.";
7188+
7189+#define AAC_MAX_ADAPTERS 64
7190+
7191+#ifndef TRUE
7192+#define TRUE 1
7193+#define FALSE 0
7194+#endif
7195+
7196+#define PAGE_SIZE 4096
7197+
7198+typedef void VOID;
7199+typedef VOID *PVOID;
7200+
7201+typedef char CHAR, *PCHAR;
7202+typedef unsigned char UCHAR, *PUCHAR;
7203+typedef short SHORT, *PSHORT;
7204+typedef short CSHORT, *PCSHORT;
7205+typedef unsigned short USHORT, *PUSHORT;
7206+typedef unsigned long ULONG, *PULONG;
7207+typedef long LONG, *PLONG;
7208+
7209+typedef unsigned long BOOLEAN;
7210+
7211+typedef unsigned long AAC_STATUS, *PNT_STATUS;
7212+
7213+typedef struct {
7214+ unsigned long LowPart;
7215+ unsigned long HighPart;
7216+} LARGE_INTEGER;
7217+
7218+typedef LARGE_INTEGER PHYSICAL_ADDRESS;
7219+
7220+
7221+typedef struct _AFA_IOCTL_CMD {
7222+ int cmd;
7223+ intptr_t arg;
7224+ int flag;
7225+ cred_t *cred_p;
7226+ int *rval_p;
7227+} AFA_IOCTL_CMD, *PAFA_IOCTL_CMD;
7228+
7229+
7230+//
7231+// Singly linked list structure. Can be used as either a list head, or
7232+// as link words.
7233+//
7234+
7235+typedef struct _SINGLE_LIST_ENTRY {
7236+ struct _SINGLE_LIST_ENTRY *Next;
7237+} SINGLE_LIST_ENTRY, *PSINGLE_LIST_ENTRY;
7238+
7239+
7240+//
7241+// Calculate the address of the base of the structure given its type, and an
7242+// address of a field within the structure.
7243+//
7244+
7245+#define CONTAINING_RECORD(address, type, field) ((type *)( \
7246+ (PCHAR)(address) - \
7247+ (PCHAR)(&((type *)0)->field)))
7248+
7249+typedef PVOID PMDL;
7250+typedef PVOID PDEVICE_OBJECT;
7251+typedef PVOID PADAPTER_OBJECT;
7252+typedef ULONG KIRQL;
7253+typedef PVOID HANDLE;
7254+typedef PVOID KDPC, *PKDPC;
7255+typedef PVOID PFILE_OBJECT;
7256+typedef PVOID PIRP;
7257+typedef PVOID PDRIVER_OBJECT;
7258+typedef ULONG KTIMER;
7259+
7260+
7261+#define STATUS_SUCCESS 0x00000000
7262+#define STATUS_PENDING 0x40000001
7263+#define STATUS_IO_TIMEOUT 0xc0000001
7264+#define STATUS_UNSUCCESSFUL 0xc0000002
7265+#define STATUS_INSUFFICIENT_RESOURCES 0xc0000005
7266+#define STATUS_BUFFER_OVERFLOW 0xc0000003
7267+
7268+
7269+#define OUT
7270+
7271+
7272+
7273+typedef u_int
7274+(*PUNIX_INTR_HANDLER)(caddr_t Arg);
7275+
7276+//
7277+// Zone Allocation
7278+//
7279+
7280+typedef struct _ZONE_SEGMENT_HEADER {
7281+ SINGLE_LIST_ENTRY SegmentList;
7282+ PVOID Reserved;
7283+} ZONE_SEGMENT_HEADER, *PZONE_SEGMENT_HEADER;
7284+
7285+typedef struct _ZONE_HEADER {
7286+ SINGLE_LIST_ENTRY FreeList;
7287+ SINGLE_LIST_ENTRY SegmentList;
7288+ ULONG BlockSize;
7289+ ULONG TotalSegmentSize;
7290+} ZONE_HEADER, *PZONE_HEADER;
7291+
7292+
7293+//++
7294+//
7295+// PVOID
7296+// ExAllocateFromZone(
7297+// IN PZONE_HEADER Zone
7298+// )
7299+//
7300+// Routine Description:
7301+//
7302+// This routine removes an entry from the zone and returns a pointer to it.
7303+//
7304+// Arguments:
7305+//
7306+// Zone - Pointer to the zone header controlling the storage from which the
7307+// entry is to be allocated.
7308+//
7309+// Return Value:
7310+//
7311+// The function value is a pointer to the storage allocated from the zone.
7312+//
7313+//--
7314+
7315+#define ExAllocateFromZone(Zone) \
7316+ (PVOID)((Zone)->FreeList.Next); \
7317+ if ( (Zone)->FreeList.Next ) (Zone)->FreeList.Next = (Zone)->FreeList.Next->Next
7318+
7319+//++
7320+//
7321+// PVOID
7322+// ExFreeToZone(
7323+// IN PZONE_HEADER Zone,
7324+// IN PVOID Block
7325+// )
7326+//
7327+// Routine Description:
7328+//
7329+// This routine places the specified block of storage back onto the free
7330+// list in the specified zone.
7331+//
7332+// Arguments:
7333+//
7334+// Zone - Pointer to the zone header controlling the storage to which the
7335+// entry is to be inserted.
7336+//
7337+// Block - Pointer to the block of storage to be freed back to the zone.
7338+//
7339+// Return Value:
7340+//
7341+// Pointer to previous block of storage that was at the head of the free
7342+// list. NULL implies the zone went from no available free blocks to
7343+// at least one free block.
7344+//
7345+//--
7346+
7347+#define ExFreeToZone(Zone,Block) \
7348+ ( ((PSINGLE_LIST_ENTRY)(Block))->Next = (Zone)->FreeList.Next, \
7349+ (Zone)->FreeList.Next = ((PSINGLE_LIST_ENTRY)(Block)), \
7350+ ((PSINGLE_LIST_ENTRY)(Block))->Next \
7351+ )
7352+
7353+//++
7354+//
7355+// BOOLEAN
7356+// ExIsFullZone(
7357+// IN PZONE_HEADER Zone
7358+// )
7359+//
7360+// Routine Description:
7361+//
7362+// This routine determines if the specified zone is full or not. A zone
7363+// is considered full if the free list is empty.
7364+//
7365+// Arguments:
7366+//
7367+// Zone - Pointer to the zone header to be tested.
7368+//
7369+// Return Value:
7370+//
7371+// TRUE if the zone is full and FALSE otherwise.
7372+//
7373+//--
7374+
7375+#define ExIsFullZone(Zone) \
7376+ ( (Zone)->FreeList.Next == (PSINGLE_LIST_ENTRY)NULL )
7377+
7378+
7379+#define RtlCopyMemory( Destination, Source, Size ) bcopy( (Source), (Destination), (Size) )
7380+#define RtlZeroMemory( Destination, Size ) bzero( (Destination), (Size) )
7381+
7382+//
7383+// Doubly-linked list manipulation routines. Implemented as macros
7384+// but logically these are procedures.
7385+//
7386+
7387+//
7388+// VOID
7389+// InitializeListHead(
7390+// PLIST_ENTRY ListHead
7391+// );
7392+//
7393+
7394+#define InitializeListHead(ListHead) (\
7395+ (ListHead)->Flink = (ListHead)->Blink = (ListHead))
7396+
7397+//
7398+// BOOLEAN
7399+// IsListEmpty(
7400+// PLIST_ENTRY ListHead
7401+// );
7402+//
7403+
7404+#define IsListEmpty(ListHead) \
7405+ ((ListHead)->Flink == (ListHead))
7406+
7407+//
7408+// PLIST_ENTRY
7409+// RemoveHeadList(
7410+// PLIST_ENTRY ListHead
7411+// );
7412+//
7413+
7414+#define RemoveHeadList(ListHead) \
7415+ (ListHead)->Flink;\
7416+ {RemoveEntryList((ListHead)->Flink)}
7417+
7418+
7419+//
7420+// VOID
7421+// RemoveEntryList(
7422+// PLIST_ENTRY Entry
7423+// );
7424+//
7425+
7426+#define RemoveEntryList(Entry) {\
7427+ PLIST_ENTRY _EX_Blink;\
7428+ PLIST_ENTRY _EX_Flink;\
7429+ _EX_Flink = (Entry)->Flink;\
7430+ _EX_Blink = (Entry)->Blink;\
7431+ _EX_Blink->Flink = _EX_Flink;\
7432+ _EX_Flink->Blink = _EX_Blink;\
7433+ }
7434+
7435+//
7436+// VOID
7437+// InsertTailList(
7438+// PLIST_ENTRY ListHead,
7439+// PLIST_ENTRY Entry
7440+// );
7441+//
7442+
7443+#define InsertTailList(ListHead,Entry) {\
7444+ PLIST_ENTRY _EX_Blink;\
7445+ PLIST_ENTRY _EX_ListHead;\
7446+ _EX_ListHead = (ListHead);\
7447+ _EX_Blink = _EX_ListHead->Blink;\
7448+ (Entry)->Flink = _EX_ListHead;\
7449+ (Entry)->Blink = _EX_Blink;\
7450+ _EX_Blink->Flink = (Entry);\
7451+ _EX_ListHead->Blink = (Entry);\
7452+ }
7453+
7454+#endif /* AAC_UNIX_DEFS */
7455diff -burN linux-2.4.7/drivers/scsi/aacraid/include/adapter.h linux/drivers/scsi/aacraid/include/adapter.h
7456--- linux-2.4.7/drivers/scsi/aacraid/include/adapter.h Wed Dec 31 18:00:00 1969
7457+++ linux/drivers/scsi/aacraid/include/adapter.h Sat Jul 21 17:55:13 2001
7458@@ -0,0 +1,164 @@
7459+/*++
7460+ * Adaptec aacraid device driver for Linux.
7461+ *
7462+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
7463+ *
7464+ * This program is free software; you can redistribute it and/or modify
7465+ * it under the terms of the GNU General Public License as published by
7466+ * the Free Software Foundation; either version 2, or (at your option)
7467+ * any later version.
7468+ *
7469+ * This program is distributed in the hope that it will be useful,
7470+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7471+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7472+ * GNU General Public License for more details.
7473+ *
7474+ * You should have received a copy of the GNU General Public License
7475+ * along with this program; see the file COPYING. If not, write to
7476+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
7477+ *
7478+ * Module Name:
7479+ *
7480+ * Adapter.h
7481+ *
7482+ * Abstract:
7483+ * The module contains the definitions for a comm layer view of the adapter.
7484+ *
7485+ *
7486+ *
7487+ --*/
7488+
7489+#ifndef _ADAPTER_
7490+#define _ADAPTER_
7491+
7492+static char *ident_adapter = "aacraid_ident adapter.h 1.0.6 2000/10/09 Adaptec, Inc.";
7493+
7494+typedef struct _GET_ADAPTER_FIB_CONTEXT {
7495+
7496+ NODE_TYPE_CODE NodeTypeCode; // used for verification of structure
7497+ NODE_BYTE_SIZE NodeByteSize;
7498+ PFILE_OBJECT FileObject; // used for cleanup
7499+ LIST_ENTRY NextContext; // used to link context's into a linked list
7500+ OS_CV_T UserEvent; // this is used to wait for the next fib to arrive.
7501+ BOOLEAN WaitingForFib; // Set to true when thread is in WaitForSingleObject
7502+ ULONG FibCount; // total number of FIBs on FibList
7503+ LIST_ENTRY FibList;
7504+} GET_ADAPTER_FIB_CONTEXT;
7505+typedef GET_ADAPTER_FIB_CONTEXT *PGET_ADAPTER_FIB_CONTEXT;
7506+
7507+
7508+typedef struct _FIB_CONTEXT_ZONE_SEGMENT {
7509+
7510+ struct _FIB_CONTEXT_ZONE_SEGMENT *Next;
7511+ ULONG FibContextSegmentSize;
7512+ PVOID FibContextSegment;
7513+ ULONG ExtendSize;
7514+ MAPFIB_CONTEXT MapFibContext;
7515+
7516+} FIB_CONTEXT_ZONE_SEGMENT;
7517+typedef FIB_CONTEXT_ZONE_SEGMENT *PFIB_CONTEXT_ZONE_SEGMENT;
7518+
7519+typedef struct _AFA_COMM_ADAPTER {
7520+
7521+ struct _AFA_COMM_ADAPTER *NextAdapter;
7522+
7523+ //
7524+ // The following fields are used to allocate FIB context structures
7525+ // using the zone allocator, and other fixed sized structures from a
7526+ // small cache. The mutex protects access to the zone/lists
7527+ //
7528+
7529+ ZONE_HEADER FibContextZone;
7530+ OS_SPINLOCK *FibContextZoneSpinLock;
7531+ int FibContextZoneExtendSize;
7532+
7533+ PFIB_CONTEXT_ZONE_SEGMENT FibContextSegmentList;
7534+
7535+ PVOID FibContextTimedOutList;
7536+
7537+ PFIB SyncFib;
7538+ ULONG SyncFibPhysicalAddress;
7539+
7540+ PCOMM_REGION CommRegion;
7541+
7542+ OS_SPINLOCK_COOKIE SpinLockCookie;
7543+
7544+ //
7545+ // The user API will use an IOCTL to register itself to receive FIBs
7546+ // from the adapter. The following list is used to keep track of all
7547+ // the threads that have requested these FIBs. The mutex is used to
7548+ // synchronize access to all data associated with the adapter fibs.
7549+ //
7550+ LIST_ENTRY AdapterFibContextList;
7551+ OS_CVLOCK *AdapterFibMutex;
7552+
7553+ //
7554+ // The following holds which FileObject is allow to send configuration
7555+ // commands to the adapter that would modify the configuration.
7556+ //
7557+ // This is controlled by the FSACTL_OPEN_ADAPTER_CONFIG and FSACTL_CLOSE_ADAPTER_CONFIG
7558+ // ioctls.
7559+ //
7560+ PFILE_OBJECT AdapterConfigFileObject;
7561+
7562+ //
7563+ // The following is really here because of the simulator
7564+ //
7565+ BOOLEAN InterruptsBelowDpc;
7566+
7567+ //
7568+ // The following is the device specific extension.
7569+ //
7570+ PVOID AdapterExtension;
7571+ PFSAPORT_FUNCS AdapterFuncs;
7572+ void *Dip;
7573+
7574+ //
7575+ // The following are user variables that are specific to the mini port.
7576+ //
7577+ PFSA_USER_VAR AdapterUserVars;
7578+ ULONG AdapterUserVarsSize;
7579+
7580+ //
7581+ // The following is the number of the individual adapter..i.e. \Device\Afa0
7582+ //
7583+ LONG AdapterNumber;
7584+
7585+ AFACOMM_FUNCS CommFuncs;
7586+
7587+ PAFA_CLASS_DRIVER ClassDriverList;
7588+
7589+ BOOLEAN AifThreadStarted;
7590+
7591+} AFA_COMM_ADAPTER;
7592+
7593+typedef AFA_COMM_ADAPTER *PAFA_COMM_ADAPTER;
7594+
7595+
7596+#define FsaAllocateAdapterCommArea(Adapter, BaseAddress, Size, Alignment) \
7597+ Adapter->AdapterFuncs->AllocateAdapterCommArea(Adapter->AdapterExtension, BaseAddress, Size, Alignment)
7598+
7599+#define FsaFreeAdapterCommArea(Adapter) \
7600+ Adapter->AdapterFuncs->FreeAdapterCommArea(Adapter->AdapterExtension)
7601+
7602+
7603+#define AllocateAndMapFibSpace(Adapter, MapFibContext) \
7604+ Adapter->AdapterFuncs->AllocateAndMapFibSpace(Adapter->AdapterExtension, MapFibContext)
7605+
7606+#define UnmapAndFreeFibSpace(Adapter, MapFibContext) \
7607+ Adapter->AdapterFuncs->UnmapAndFreeFibSpace(Adapter->AdapterExtension, MapFibContext)
7608+
7609+#define InterruptAdapter(Adapter) \
7610+ Adapter->AdapterFuncs->InterruptAdapter(Adapter->AdapterExtension)
7611+
7612+#define NotifyAdapter(Adapter, AdapterEvent) \
7613+ Adapter->AdapterFuncs->NotifyAdapter(Adapter->AdapterExtension, AdapterEvent)
7614+
7615+#define EnableInterrupt(Adapter, AdapterEvent, AtDeviceIrq) \
7616+ Adapter->AdapterFuncs->EnableInterrupt(Adapter->AdapterExtension, AdapterEvent, AtDeviceIrq)
7617+
7618+#define DisableInterrupt(Adapter, AdapterEvent, AtDeviceIrq) \
7619+ Adapter->AdapterFuncs->DisableInterrupt(Adapter->AdapterExtension, AdapterEvent, AtDeviceIrq)
7620+
7621+
7622+#endif // _ADAPTER_
7623diff -burN linux-2.4.7/drivers/scsi/aacraid/include/afacomm.h linux/drivers/scsi/aacraid/include/afacomm.h
7624--- linux-2.4.7/drivers/scsi/aacraid/include/afacomm.h Wed Dec 31 18:00:00 1969
7625+++ linux/drivers/scsi/aacraid/include/afacomm.h Sat Jul 21 17:55:13 2001
7626@@ -0,0 +1,191 @@
7627+/*++
7628+ * Adaptec aacraid device driver for Linux.
7629+ *
7630+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
7631+ *
7632+ * This program is free software; you can redistribute it and/or modify
7633+ * it under the terms of the GNU General Public License as published by
7634+ * the Free Software Foundation; either version 2, or (at your option)
7635+ * any later version.
7636+ *
7637+ * This program is distributed in the hope that it will be useful,
7638+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7639+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7640+ * GNU General Public License for more details.
7641+ *
7642+ * You should have received a copy of the GNU General Public License
7643+ * along with this program; see the file COPYING. If not, write to
7644+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
7645+ *
7646+ * Module Name:
7647+ * AfaComm.h
7648+ *
7649+ * Abstract:
7650+ * This module defines all of the external interfaces to the AFA comm layer.
7651+ *
7652+ *
7653+ *
7654+ --*/
7655+#ifndef _AFACOMM_
7656+#define _AFACOMM_
7657+
7658+static char *ident_afacomm = "aacraid_ident afacomm.h 1.0.6 2000/10/09 Adaptec, Inc.";
7659+
7660+#include "fsaport.h"
7661+
7662+typedef void *PFIB_CONTEXT;
7663+
7664+typedef VOID
7665+(*PFIB_CALLBACK)(
7666+ PVOID FibCallbackContext,
7667+ PFIB_CONTEXT FibContext,
7668+ AAC_STATUS Status
7669+ );
7670+
7671+
7672+typedef PFIB_CONTEXT
7673+(*PAFA_COMM_ALLOCATE_FIB) (
7674+ IN PVOID AdapterExtension
7675+ );
7676+
7677+typedef VOID
7678+(*PAFA_COMM_FREE_FIB) (
7679+ IN PFIB_CONTEXT FibContext
7680+ );
7681+
7682+
7683+typedef AAC_STATUS
7684+(*PAFA_COMM_DEALLOCATE_FIB) (
7685+ IN PFIB_CONTEXT FibContext
7686+ );
7687+
7688+
7689+typedef VOID
7690+(*PAFA_COMM_FREE_FIB_FROM_DPC) (
7691+ IN PFIB_CONTEXT FibContext
7692+ );
7693+
7694+typedef AAC_STATUS
7695+(*PAFA_COMM_INITIALIZE_FIB) (
7696+ IN PFIB_CONTEXT FibContext
7697+ );
7698+
7699+typedef PVOID
7700+(*PAFA_COMM_GET_FIB_DATA) (
7701+ IN PFIB_CONTEXT FibContext
7702+ );
7703+
7704+typedef AAC_STATUS
7705+(*PAFA_COMM_SEND_FIB) (
7706+ IN FIB_COMMAND Command,
7707+ IN PFIB_CONTEXT FibContext,
7708+ IN ULONG Size,
7709+ IN COMM_PRIORITIES Priority,
7710+ IN BOOLEAN Wait,
7711+ IN PVOID WaitOn,
7712+ IN BOOLEAN ResponseExpected,
7713+ IN PFIB_CALLBACK FibCallback,
7714+ IN PVOID FibCallbackContext
7715+ );
7716+
7717+typedef AAC_STATUS
7718+(*PAFA_COMM_COMPLETE_FIB) (
7719+ IN PFIB_CONTEXT FibContext
7720+ );
7721+
7722+typedef AAC_STATUS
7723+(*PAFA_COMM_COMPLETE_ADAPTER_FIB) (
7724+ IN PFIB_CONTEXT FibContext,
7725+ IN USHORT Size
7726+ );
7727+
7728+typedef BOOLEAN
7729+(*PAFA_COMM_SEND_SYNCH_FIB) (
7730+ PVOID AdapterExtension,
7731+ FIB_COMMAND Command,
7732+ PVOID Data,
7733+ USHORT Size,
7734+ PVOID Response,
7735+ USHORT *ResponseSize
7736+ );
7737+
7738+
7739+typedef struct _AFACOMM_FUNCS {
7740+ ULONG SizeOfAfaCommFuncs;
7741+ PAFA_COMM_ALLOCATE_FIB AllocateFib;
7742+ PAFA_COMM_FREE_FIB FreeFib;
7743+ PAFA_COMM_FREE_FIB_FROM_DPC FreeFibFromDpc;
7744+ PAFA_COMM_DEALLOCATE_FIB DeallocateFib;
7745+ PAFA_COMM_INITIALIZE_FIB InitializeFib;
7746+ PAFA_COMM_GET_FIB_DATA GetFibData;
7747+ PAFA_COMM_SEND_FIB SendFib;
7748+ PAFA_COMM_COMPLETE_FIB CompleteFib;
7749+ PAFA_COMM_COMPLETE_ADAPTER_FIB CompleteAdapterFib;
7750+ PAFA_COMM_SEND_SYNCH_FIB SendSynchFib;
7751+ PFSA_FREE_DMA_RESOURCES FreeDmaResources;
7752+ PFSA_BUILD_SGMAP BuildSgMap;
7753+ PFSA_ADAPTER_ADDR_TO_SYSTEM_ADDR AdapterAddressToSystemAddress;
7754+} AFACOMM_FUNCS;
7755+typedef AFACOMM_FUNCS *PAFACOMM_FUNCS;
7756+
7757+
7758+typedef AAC_STATUS
7759+(*PAFA_CLASS_OPEN_ADAPTER) (
7760+ IN PVOID Adapter
7761+ );
7762+
7763+
7764+typedef AAC_STATUS
7765+(*PAFA_CLASS_CLOSE_ADAPTER) (
7766+ IN PVOID Adapter
7767+ );
7768+
7769+
7770+typedef BOOLEAN
7771+(*PAFA_CLASS_DEV_CONTROL) (
7772+ IN PVOID Adapter,
7773+ IN PAFA_IOCTL_CMD IoctlCmdPtr,
7774+ OUT int * Status
7775+ );
7776+
7777+typedef BOOLEAN
7778+(*PAFA_CLASS_HANDLE_AIF) (
7779+ IN PVOID Adapter,
7780+ IN PFIB_CONTEXT FibContext
7781+ );
7782+
7783+
7784+typedef struct _AFA_NEW_CLASS_DRIVER {
7785+ PVOID ClassDriverExtension;
7786+ PAFA_CLASS_OPEN_ADAPTER OpenAdapter;
7787+ PAFA_CLASS_CLOSE_ADAPTER CloseAdapter;
7788+ PAFA_CLASS_DEV_CONTROL DeviceControl;
7789+ PAFA_CLASS_HANDLE_AIF HandleAif;
7790+ PFSA_USER_VAR UserVars;
7791+ ULONG NumUserVars;
7792+} AFA_NEW_CLASS_DRIVER;
7793+typedef AFA_NEW_CLASS_DRIVER *PAFA_NEW_CLASS_DRIVER;
7794+
7795+
7796+typedef struct _AFA_NEW_CLASS_DRIVER_RESPONSE {
7797+ PAFACOMM_FUNCS CommFuncs;
7798+ PVOID CommPortExtension;
7799+ PVOID MiniPortExtension;
7800+ OS_SPINLOCK_COOKIE SpinLockCookie;
7801+ void *Dip;
7802+} AFA_NEW_CLASS_DRIVER_RESPONSE;
7803+typedef AFA_NEW_CLASS_DRIVER_RESPONSE *PAFA_NEW_CLASS_DRIVER_RESPONSE;
7804+
7805+
7806+typedef struct _AFA_CLASS_DRIVER {
7807+ struct _AFA_CLASS_DRIVER *Next;
7808+ PVOID ClassDriverExtension;
7809+ PAFA_CLASS_OPEN_ADAPTER OpenAdapter;
7810+ PAFA_CLASS_CLOSE_ADAPTER CloseAdapter;
7811+ PAFA_CLASS_DEV_CONTROL DeviceControl;
7812+ PAFA_CLASS_HANDLE_AIF HandleAif;
7813+} AFA_CLASS_DRIVER;
7814+typedef AFA_CLASS_DRIVER *PAFA_CLASS_DRIVER;
7815+
7816+
7817+#endif // _AFACOMM_
7818diff -burN linux-2.4.7/drivers/scsi/aacraid/include/aifstruc.h linux/drivers/scsi/aacraid/include/aifstruc.h
7819--- linux-2.4.7/drivers/scsi/aacraid/include/aifstruc.h Wed Dec 31 18:00:00 1969
7820+++ linux/drivers/scsi/aacraid/include/aifstruc.h Sat Jul 21 17:55:13 2001
7821@@ -0,0 +1,319 @@
7822+/*++
7823+ * Adaptec aacraid device driver for Linux.
7824+ *
7825+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
7826+ *
7827+ * This program is free software; you can redistribute it and/or modify
7828+ * it under the terms of the GNU General Public License as published by
7829+ * the Free Software Foundation; either version 2, or (at your option)
7830+ * any later version.
7831+ *
7832+ * This program is distributed in the hope that it will be useful,
7833+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7834+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7835+ * GNU General Public License for more details.
7836+ *
7837+ * You should have received a copy of the GNU General Public License
7838+ * along with this program; see the file COPYING. If not, write to
7839+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
7840+ *
7841+ * Module Name:
7842+ * Aifstruc.h
7843+ *
7844+ * Abstract:
7845+ * Define all shared data types relating to
7846+ * the set of features utilizing Adapter
7847+ * Initiated Fibs.
7848+ *
7849+ *
7850+ *
7851+ --*/
7852+#ifndef _AIFSTRUC_H
7853+#define _AIFSTRUC_H
7854+
7855+static char *ident_aifstruc = "aacraid_ident aifstruc.h 1.0.6 2000/10/09 Adaptec, Inc.";
7856+
7857+#include <protocol.h>
7858+
7859+//
7860+// Progress report structure definitions
7861+//
7862+typedef enum {
7863+ AifJobStsSuccess = 1,
7864+ AifJobStsFinished,
7865+ AifJobStsAborted,
7866+ AifJobStsFailed,
7867+ AifJobStsLastReportMarker = 100, // All before mean last report
7868+ AifJobStsSuspended,
7869+ AifJobStsRunning
7870+} _E_AifJobStatus;
7871+
7872+#ifdef AAC_32BIT_ENUMS
7873+typedef _E_AifJobStatus AifJobStatus;
7874+#else
7875+typedef AAC_UINT32 AifJobStatus;
7876+#endif
7877+
7878+
7879+typedef enum {
7880+ AifJobScsiMin = 1, // Minimum value for Scsi operation
7881+ AifJobScsiZero, // SCSI device clear operation
7882+ AifJobScsiVerify, // SCSI device Verify operation NO REPAIR
7883+ AifJobScsiExercise, // SCSI device Exercise operation
7884+ AifJobScsiVerifyRepair, // SCSI device Verify operation WITH repair
7885+ // Add new SCSI task types above this line
7886+ AifJobScsiMax = 99, // Max Scsi value
7887+ AifJobCtrMin, // Min Ctr op value
7888+ AifJobCtrZero, // Container clear operation
7889+ AifJobCtrCopy, // Container copy operation
7890+ AifJobCtrCreateMirror, // Container Create Mirror operation
7891+ AifJobCtrMergeMirror, // Container Merge Mirror operation
7892+ AifJobCtrScrubMirror, // Container Scrub Mirror operation
7893+ AifJobCtrRebuildRaid5, // Container Rebuild Raid5 operation
7894+ AifJobCtrScrubRaid5, // Container Scrub Raid5 operation
7895+ AifJobCtrMorph, // Container morph operation
7896+ AifJobCtrPartCopy, // Container Partition copy operation
7897+ AifJobCtrRebuildMirror, // Container Rebuild Mirror operation
7898+ AifJobCtrCrazyCache, // crazy cache
7899+ // Add new container task types above this line
7900+ AifJobCtrMax = 199, // Max Ctr type operation
7901+ AifJobFsMin, // Min Fs type operation
7902+ AifJobFsCreate, // File System Create operation
7903+ AifJobFsVerify, // File System Verify operation
7904+ AifJobFsExtend, // File System Extend operation
7905+ // Add new file system task types above this line
7906+ AifJobFsMax = 299, // Max Fs type operation
7907+ // Add new API task types here
7908+ AifJobApiFormatNTFS, // Format a drive to NTFS
7909+ AifJobApiFormatFAT, // Format a drive to FAT
7910+ AifJobApiUpdateSnapshot, // update the read/write half of a snapshot
7911+ AifJobApiFormatFAT32, // Format a drive to FAT32
7912+ AifJobApiMax = 399, // Max API type operation
7913+ AifJobCtlContinuousCtrVerify, // Controller operation
7914+ AifJobCtlMax = 499 // Max Controller type operation
7915+
7916+} _E_AifJobType;
7917+
7918+#ifdef AAC_32BIT_ENUMS
7919+typedef _E_AifJobType AifJobType;
7920+#else
7921+typedef AAC_UINT32 AifJobType;
7922+#endif
7923+
7924+union SrcContainer {
7925+ AAC_UINT32 from;
7926+ AAC_UINT32 master;
7927+ AAC_UINT32 container;
7928+};
7929+
7930+union DstContainer {
7931+ AAC_UINT32 to;
7932+ AAC_UINT32 slave;
7933+ AAC_UINT32 container;
7934+};
7935+
7936+
7937+struct AifContainers {
7938+ union SrcContainer src;
7939+ union DstContainer dst;
7940+};
7941+
7942+union AifJobClient {
7943+
7944+ struct AifContainers container; // For Container nd file system progress ops;
7945+ AAC_INT32 scsi_dh; // For SCSI progress ops
7946+};
7947+
7948+struct AifJobDesc {
7949+ AAC_UINT32 jobID; // DO NOT FILL IN! Will be filled in by AIF
7950+ AifJobType type; // Operation that is being performed
7951+ union AifJobClient client; // Details
7952+};
7953+
7954+struct AifJobProgressReport {
7955+ struct AifJobDesc jd;
7956+ AifJobStatus status;
7957+ AAC_UINT32 finalTick;
7958+ AAC_UINT32 currentTick;
7959+ AAC_UINT32 jobSpecificData1;
7960+ AAC_UINT32 jobSpecificData2;
7961+};
7962+
7963+//
7964+// Notification of events structure definition starts here
7965+//
7966+typedef enum {
7967+ // General application notifies start here
7968+ AifEnGeneric = 1, // Generic notification
7969+ AifEnTaskComplete, // Task has completed
7970+ AifEnConfigChange, // Adapter configuration change occurred
7971+ AifEnContainerChange, // Adapter specific container configuration change
7972+ AifEnDeviceFailure, // SCSI device failed
7973+ AifEnMirrorFailover, // Mirror failover started
7974+ AifEnContainerEvent, // Significant container event
7975+ AifEnFileSystemChange, // File system changed
7976+ AifEnConfigPause, // Container pause event
7977+ AifEnConfigResume, // Container resume event
7978+ AifEnFailoverChange, // Failover space assignment changed
7979+ AifEnRAID5RebuildDone, // RAID5 rebuild finished
7980+ AifEnEnclosureManagement, // Enclosure management event
7981+ AifEnBatteryEvent, // Significant NV battery event
7982+ AifEnAddContainer, // A new container was created.
7983+ AifEnDeleteContainer, // A container was deleted.
7984+ AifEnSMARTEvent, // SMART Event
7985+ AifEnBatteryNeedsRecond, // The battery needs reconditioning
7986+ AifEnClusterEvent, // Some cluster event
7987+ AifEnDiskSetEvent, // A disk set event occured.
7988+ // Add general application notifies above this comment
7989+ AifDriverNotifyStart=199, // Notifies for host driver go here
7990+ // Host driver notifications start here
7991+ AifDenMorphComplete, // A morph operation completed
7992+ AifDenVolumeExtendComplete // A volume expand operation completed
7993+ // Add host driver notifications above this comment
7994+} _E_AifEventNotifyType;
7995+
7996+#ifdef AAC_32BIT_ENUMS
7997+typedef _E_AifEventNotifyType AifEventNotifyType;
7998+#else
7999+typedef AAC_UINT32 AifEventNotifyType;
8000+#endif
8001+
8002+struct AifEnsGeneric {
8003+ AAC_INT8 text[132]; // Generic text
8004+};
8005+
8006+struct AifEnsDeviceFailure {
8007+ AAC_INT32 deviceHandle; // SCSI device handle
8008+};
8009+
8010+struct AifEnsMirrorFailover {
8011+ AAC_UINT32 container; // Container with failed element
8012+ AAC_UINT32 failedSlice; // Old slice which failed
8013+ AAC_UINT32 creatingSlice; // New slice used for auto-create
8014+};
8015+
8016+struct AifEnsContainerChange {
8017+ AAC_UINT32 container[2]; // container that changed, -1 if no container
8018+};
8019+
8020+struct AifEnsContainerEvent {
8021+ AAC_UINT32 container; // container number
8022+ AAC_UINT32 eventType; // event type
8023+};
8024+
8025+struct AifEnsEnclosureEvent {
8026+ AAC_UINT32 empID; // enclosure management processor number
8027+ AAC_UINT32 unitID; // unitId, fan id, power supply id, slot id, tempsensor id.
8028+ AAC_UINT32 eventType; // event type
8029+};
8030+
8031+
8032+struct AifEnsBatteryEvent {
8033+ NVBATT_TRANSITION transition_type; // e.g. from low to ok
8034+ NVBATTSTATUS current_state; // current battery state
8035+ NVBATTSTATUS prior_state; // previous battery state
8036+};
8037+
8038+struct AifEnsDiskSetEvent {
8039+ AAC_UINT32 eventType;
8040+ AAC_UINT32 DsNum[2];
8041+ AAC_UINT32 CreatorId[2];
8042+};
8043+
8044+
8045+
8046+typedef enum _CLUSTER_AIF_EVENT {
8047+ CLUSTER_NULL_EVENT = 0,
8048+ CLUSTER_PARTNER_NAME_EVENT, // change in partner hostname or adaptername from NULL to non-NULL
8049+ // (partner's agent may be up)
8050+ CLUSTER_PARTNER_NULL_NAME_EVENT // change in partner hostname or adaptername from non-null to NULL
8051+ // (partner has rebooted)
8052+} _E_CLUSTER_AIF_EVENT;
8053+
8054+#ifdef AAC_32BIT_ENUMS
8055+typedef _E_CLUSTER_AIF_EVENT CLUSTER_AIF_EVENT;
8056+#else
8057+typedef AAC_UINT32 CLUSTER_AIF_EVENT;
8058+#endif
8059+
8060+struct AifEnsClusterEvent {
8061+ CLUSTER_AIF_EVENT eventType;
8062+};
8063+
8064+struct AifEventNotify {
8065+ AifEventNotifyType type;
8066+ union {
8067+ struct AifEnsGeneric EG;
8068+ struct AifEnsDeviceFailure EDF;
8069+ struct AifEnsMirrorFailover EMF;
8070+ struct AifEnsContainerChange ECC;
8071+ struct AifEnsContainerEvent ECE;
8072+ struct AifEnsEnclosureEvent EEE;
8073+ struct AifEnsBatteryEvent EBE;
8074+ struct AifEnsDiskSetEvent EDS;
8075+#ifdef BRIDGE
8076+ struct AifEnsSMARTEvent ES;
8077+#endif
8078+ struct AifEnsClusterEvent ECLE;
8079+ } data;
8080+};
8081+
8082+//
8083+// Generic API structure
8084+//
8085+#define AIF_API_REPORT_MAX_SIZE 64
8086+typedef AAC_INT8 AifApiReport[AIF_API_REPORT_MAX_SIZE];
8087+
8088+
8089+
8090+//
8091+// For FIB communication, we need all of the following things
8092+// to send back to the user.
8093+//
8094+typedef enum {
8095+ AifCmdEventNotify = 1, // Notify of event
8096+ AifCmdJobProgress, // Progress report
8097+ AifCmdAPIReport, // Report from other user of API
8098+ AifCmdDriverNotify, // Notify host driver of event
8099+ AifReqJobList = 100, // Gets back complete job list
8100+ AifReqJobsForCtr, // Gets back jobs for specific container
8101+ AifReqJobsForScsi, // Gets back jobs for specific SCSI device
8102+ AifReqJobReport, // Gets back a specific job report or list of them
8103+ AifReqTerminateJob, // Terminates job
8104+ AifReqSuspendJob, // Suspends a job
8105+ AifReqResumeJob, // Resumes a job
8106+ AifReqSendAPIReport, // API generic report requests
8107+ AifReqAPIJobStart, // Start a job from the API
8108+ AifReqAPIJobUpdate, // Update a job report from the API
8109+ AifReqAPIJobFinish // Finish a job from the API
8110+} _E_AIFCOMMAND;
8111+
8112+#ifdef AAC_32BIT_ENUMS
8113+typedef _E_AIFCOMMAND AIFCOMMAND;
8114+#else
8115+typedef AAC_UINT32 AIFCOMMAND;
8116+#endif
8117+
8118+
8119+
8120+//
8121+// Adapter Initiated FIB command structures. Start with the adapter
8122+// initiated FIBs that really come from the adapter, and get responded
8123+// to by the host.
8124+//
8125+typedef struct _AIFCOMMANDTOHOST {
8126+ AIFCOMMAND command; // Tell host what type of notify this is
8127+ AAC_UINT32 seqNumber; // To allow ordering of reports (if necessary)
8128+ union {
8129+ // First define data going to the adapter
8130+ struct AifEventNotify EN; // Event notify structure
8131+ struct AifJobProgressReport PR[1]; // Progress report
8132+ AifApiReport AR;
8133+ } data;
8134+} AIFCOMMANDTOHOST, *PAIFCOMMANDTOHOST;
8135+
8136+
8137+#endif // _AIFSTRUC_H
8138+
8139+
8140+
8141diff -burN linux-2.4.7/drivers/scsi/aacraid/include/build_number.h linux/drivers/scsi/aacraid/include/build_number.h
8142--- linux-2.4.7/drivers/scsi/aacraid/include/build_number.h Wed Dec 31 18:00:00 1969
8143+++ linux/drivers/scsi/aacraid/include/build_number.h Sat Jul 21 17:55:13 2001
8144@@ -0,0 +1,39 @@
8145+/*++
8146+ * Adaptec aacraid device driver for Linux.
8147+ *
8148+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8149+ *
8150+ * This program is free software; you can redistribute it and/or modify
8151+ * it under the terms of the GNU General Public License as published by
8152+ * the Free Software Foundation; either version 2, or (at your option)
8153+ * any later version.
8154+ *
8155+ * This program is distributed in the hope that it will be useful,
8156+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
8157+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8158+ * GNU General Public License for more details.
8159+ *
8160+ * You should have received a copy of the GNU General Public License
8161+ * along with this program; see the file COPYING. If not, write to
8162+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8163+ *
8164+ * Module Name:
8165+ * build_number.h
8166+ *
8167+ * Abstract:
8168+ * DThis module contains the single location where the build number
8169+ * is kept.
8170+ *
8171+ *
8172+ *
8173+ --*/
8174+#ifndef _BUILD_NUMBER_H
8175+#define _BUILD_NUMBER_H
8176+
8177+static char *ident_build_num = "aacraid_ident build_number.h 1.0.6 2000/10/09 Adaptec, Inc.";
8178+
8179+#define REV_BUILD_NUMBER 3911
8180+
8181+
8182+#endif // _BUILD_NUMBER_H
8183+
8184diff -burN linux-2.4.7/drivers/scsi/aacraid/include/commdata.h linux/drivers/scsi/aacraid/include/commdata.h
8185--- linux-2.4.7/drivers/scsi/aacraid/include/commdata.h Wed Dec 31 18:00:00 1969
8186+++ linux/drivers/scsi/aacraid/include/commdata.h Sat Jul 21 17:55:13 2001
8187@@ -0,0 +1,112 @@
8188+/*++
8189+ * Adaptec aacraid device driver for Linux.
8190+ *
8191+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8192+ *
8193+ * This program is free software; you can redistribute it and/or modify
8194+ * it under the terms of the GNU General Public License as published by
8195+ * the Free Software Foundation; either version 2, or (at your option)
8196+ * any later version.
8197+ *
8198+ * This program is distributed in the hope that it will be useful,
8199+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
8200+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8201+ * GNU General Public License for more details.
8202+ *
8203+ * You should have received a copy of the GNU General Public License
8204+ * along with this program; see the file COPYING. If not, write to
8205+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8206+ *
8207+ * Module Name:
8208+ * commdata.h
8209+ *
8210+ * Abstract: Define the communication layer of the adapter
8211+ *
8212+ *
8213+ *
8214+ --*/
8215+#ifndef _COMMDATA_
8216+#define _COMMDATA_
8217+
8218+static char *ident_commdata = "aacraid_ident commdata.h 1.0.6 2000/10/09 Adaptec, Inc.";
8219+
8220+typedef struct _FSA_COMM_DATA {
8221+
8222+ //
8223+ // A pointer to the Driver and Device object we were initialized with
8224+ //
8225+
8226+ PDRIVER_OBJECT DriverObject;
8227+ PDEVICE_OBJECT DeviceObject;
8228+
8229+ //
8230+ // A list of all adapters we have configured.
8231+ //
8232+
8233+ PAFA_COMM_ADAPTER AdapterList;
8234+ ULONG TotalAdapters;
8235+
8236+ //
8237+ // Adapter timeout support. This is the default timeout to wait for the
8238+ // adapter to respond(setup in initfs.c), and a boolean to indicate if
8239+ // we should timeout requests to the adapter or not.
8240+ //
8241+
8242+ LARGE_INTEGER QueueFreeTimeout;
8243+ LARGE_INTEGER AdapterTimeout;
8244+ BOOLEAN EnableAdapterTimeouts;
8245+
8246+ ULONG FibTimeoutIncrement;
8247+
8248+ ULONG FibsSent;
8249+ ULONG FibRecved;
8250+ ULONG NoResponseSent;
8251+ ULONG NoResponseRecved;
8252+ ULONG AsyncSent;
8253+ ULONG AsyncRecved;
8254+ ULONG NormalSent;
8255+ ULONG NormalRecved;
8256+
8257+ ULONG TimedOutFibs;
8258+
8259+ KDPC TimeoutDPC;
8260+ KTIMER TimeoutTimer;
8261+
8262+ //
8263+ // If this value is set to 1 then interrupt moderation will occur
8264+ // in the base commuication support.
8265+ //
8266+
8267+ ULONG EnableInterruptModeration;
8268+
8269+ int HardInterruptModeration;
8270+ int HardInterruptModeration1;
8271+ int PeakFibsConsumed;
8272+ int ZeroFibsConsumed;
8273+ int EnableFibTimeoutBreak;
8274+ ULONG FibTimeoutSeconds;
8275+
8276+ //
8277+ // The following holds all of the available user settable variables.
8278+ // This includes all for the comm layer as well as any from the class
8279+ // drivers as well.
8280+ //
8281+
8282+ FSA_USER_VAR *UserVars;
8283+ ULONG NumUserVars;
8284+
8285+
8286+ ULONG MeterFlag;
8287+
8288+#ifdef FIB_CHECKSUMS
8289+ int do_fib_checksums;
8290+#endif
8291+
8292+} FSA_COMM_DATA;
8293+typedef FSA_COMM_DATA *PFSA_COMM_DATA;
8294+
8295+extern FSA_COMM_DATA FsaCommData;
8296+
8297+
8298+#endif // _COMMDATA_
8299+
8300diff -burN linux-2.4.7/drivers/scsi/aacraid/include/commerr.h linux/drivers/scsi/aacraid/include/commerr.h
8301--- linux-2.4.7/drivers/scsi/aacraid/include/commerr.h Wed Dec 31 18:00:00 1969
8302+++ linux/drivers/scsi/aacraid/include/commerr.h Sat Jul 21 17:55:13 2001
8303@@ -0,0 +1,125 @@
8304+/*++
8305+ * Adaptec aacraid device driver for Linux.
8306+ *
8307+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8308+ *
8309+ * This program is free software; you can redistribute it and/or modify
8310+ * it under the terms of the GNU General Public License as published by
8311+ * the Free Software Foundation; either version 2, or (at your option)
8312+ * any later version.
8313+ *
8314+ * This program is distributed in the hope that it will be useful,
8315+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
8316+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8317+ * GNU General Public License for more details.
8318+ *
8319+ * You should have received a copy of the GNU General Public License
8320+ * along with this program; see the file COPYING. If not, write to
8321+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8322+ *
8323+ * Module Name:
8324+ * commerr.h
8325+ *
8326+ * Abstract: This file defines all errors that are unique to the Adaptec Fsa Filesystem
8327+ *
8328+ *
8329+ *
8330+ --*/
8331+
8332+#ifndef _FSAERR_
8333+#define _FSAERR_
8334+
8335+static char *ident_commerr = "aacraid_ident commerr.h 1.0.6 2000/10/09 Adaptec, Inc.";
8336+
8337+//
8338+// Note: comments in the .mc file must use both ";" and "//".
8339+//
8340+// Status values are 32 bit values layed out as follows:
8341+//
8342+// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
8343+// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
8344+// +---+-+-------------------------+-------------------------------+
8345+// |Sev|C| Facility | Code |
8346+// +---+-+-------------------------+-------------------------------+
8347+//
8348+// where
8349+//
8350+// Sev - is the severity code
8351+//
8352+// 00 - Success
8353+// 01 - Informational
8354+// 10 - Warning
8355+// 11 - Error
8356+//
8357+// C - is the Customer code flag
8358+//
8359+// Facility - is the facility code
8360+//
8361+// Code - is the facility's status code
8362+//
8363+
8364+
8365+//
8366+// %1 is reserved by the IO Manager. If IoAllocateErrorLogEntry is
8367+// called with a device, the name of the device will be inserted into
8368+// the message at %1. Otherwise, the place of %1 will be left empty.
8369+// In either case, the insertion strings from the driver's error log
8370+// entry starts at %2. In other words, the first insertion string goes
8371+// to %2, the second to %3 and so on.
8372+//
8373+
8374+//
8375+// Values are 32 bit values layed out as follows:
8376+//
8377+// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
8378+// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
8379+// +---+-+-+-----------------------+-------------------------------+
8380+// |Sev|C|R| Facility | Code |
8381+// +---+-+-+-----------------------+-------------------------------+
8382+//
8383+// where
8384+//
8385+// Sev - is the severity code
8386+//
8387+// 00 - Success
8388+// 01 - Informational
8389+// 10 - Warning
8390+// 11 - Error
8391+//
8392+// C - is the Customer code flag
8393+//
8394+// R - is a reserved bit
8395+//
8396+// Facility - is the facility code
8397+//
8398+// Code - is the facility's status code
8399+//
8400+//
8401+// Define the facility codes
8402+//
8403+
8404+
8405+#define FACILITY_FSAFS_ERROR_CODE 0x7
8406+
8407+
8408+
8409+//
8410+// MessageId: FSAFS_FIB_INVALID
8411+//
8412+// MessageText:
8413+//
8414+// A communication packet was detected to be formatted poorly. Please Contact Adaptec support.
8415+//
8416+#define FSAFS_FIB_INVALID ((AAC_STATUS)0xE0070009L)
8417+
8418+
8419+//
8420+// MessageId: FSAFS_TIMED_OUT_FIB_COMPLETED
8421+//
8422+// MessageText:
8423+//
8424+// A Fib previously timed out by host has been completed by the adapter. (\\.\Afa%2)
8425+//
8426+#define FSAFS_TIMED_OUT_FIB_COMPLETED ((AAC_STATUS)0xA007000EL)
8427+
8428+#endif _FSAERR_
8429diff -burN linux-2.4.7/drivers/scsi/aacraid/include/commfibcontext.h linux/drivers/scsi/aacraid/include/commfibcontext.h
8430--- linux-2.4.7/drivers/scsi/aacraid/include/commfibcontext.h Wed Dec 31 18:00:00 1969
8431+++ linux/drivers/scsi/aacraid/include/commfibcontext.h Sat Jul 21 17:55:13 2001
8432@@ -0,0 +1,98 @@
8433+/*++
8434+ * Adaptec aacraid device driver for Linux.
8435+ *
8436+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8437+ *
8438+ * This program is free software; you can redistribute it and/or modify
8439+ * it under the terms of the GNU General Public License as published by
8440+ * the Free Software Foundation; either version 2, or (at your option)
8441+ * any later version.
8442+ *
8443+ * This program is distributed in the hope that it will be useful,
8444+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
8445+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8446+ * GNU General Public License for more details.
8447+ *
8448+ * You should have received a copy of the GNU General Public License
8449+ * along with this program; see the file COPYING. If not, write to
8450+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8451+ *
8452+ * Module Name:
8453+ * commfibcontext.h
8454+ *
8455+ * Abstract: defines the _COMM_FIB_CONTEXT strcuture
8456+ *
8457+ *
8458+ *
8459+ --*/
8460+#ifndef _COMM_FIB_CONTEXT_
8461+#define _COMM_FIB_CONTEXT_
8462+
8463+static char *ident_commfib = "aacraid_ident commfibcontext.h 1.0.6 2000/10/09 Adaptec, Inc.";
8464+
8465+typedef struct _COMM_FIB_CONTEXT {
8466+
8467+ PVOID Next; // this is used by the zone allocation
8468+
8469+ //
8470+ // Type and size of this record (must be FSA_NTC_FIB_CONTEXT)
8471+ //
8472+ // NOTE: THIS STRUCTURE MUST REMAIN 64-bit ALIGNED IN SIZE, SINCE
8473+ // IT IS ZONE ALLOCATED, AND REPINNED_BCBS_ARRAY_SIZE AFFECTS
8474+ // ITS SIZE.
8475+ //
8476+
8477+ NODE_TYPE_CODE NodeTypeCode;
8478+ NODE_BYTE_SIZE NodeByteSize;
8479+
8480+ //
8481+ // The Adapter that this I/O is destined for.
8482+ //
8483+
8484+ PAFA_COMM_ADAPTER Adapter;
8485+
8486+ PHYSICAL_ADDRESS LogicalFibAddress;
8487+
8488+ //
8489+ // This is the event the sendfib routine will wait on if the
8490+ // caller did not pass one and this is synch io.
8491+ //
8492+
8493+ OS_CV_T FsaEvent;
8494+ OS_CVLOCK *FsaEventMutex;
8495+
8496+ ULONG FibComplete; // gets set to 1 when fib is complete
8497+
8498+ PFIB_CALLBACK FibCallback;
8499+ PVOID FibCallbackContext;
8500+
8501+ ULONG Flags;
8502+
8503+
8504+#ifdef GATHER_FIB_TIMES
8505+ LARGE_INTEGER FibTimeStamp;
8506+ PFIB_TIMES FibTimesPtr;
8507+#endif
8508+
8509+ //
8510+ // The following is used to put this fib context onto the Outstanding I/O queue.
8511+ //
8512+
8513+ LIST_ENTRY QueueEntry;
8514+
8515+ //
8516+ // The following is used to timeout a fib to the adapter.
8517+ //
8518+
8519+ LARGE_INTEGER TimeoutValue;
8520+
8521+ PVOID FibData;
8522+
8523+ PFIB Fib;
8524+
8525+} COMM_FIB_CONTEXT;
8526+typedef COMM_FIB_CONTEXT *PCOMM_FIB_CONTEXT;
8527+
8528+#define FIB_CONTEXT_FLAG_TIMED_OUT (0x00000001)
8529+
8530+#endif /* _COMM_FIB_CONTEXT_ */
8531diff -burN linux-2.4.7/drivers/scsi/aacraid/include/comprocs.h linux/drivers/scsi/aacraid/include/comprocs.h
8532--- linux-2.4.7/drivers/scsi/aacraid/include/comprocs.h Wed Dec 31 18:00:00 1969
8533+++ linux/drivers/scsi/aacraid/include/comprocs.h Sat Jul 21 17:55:13 2001
8534@@ -0,0 +1,93 @@
8535+/*++
8536+ * Adaptec aacraid device driver for Linux.
8537+ *
8538+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8539+ *
8540+ * This program is free software; you can redistribute it and/or modify
8541+ * it under the terms of the GNU General Public License as published by
8542+ * the Free Software Foundation; either version 2, or (at your option)
8543+ * any later version.
8544+ *
8545+ * This program is distributed in the hope that it will be useful,
8546+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
8547+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8548+ * GNU General Public License for more details.
8549+ *
8550+ * You should have received a copy of the GNU General Public License
8551+ * along with this program; see the file COPYING. If not, write to
8552+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8553+ *
8554+ * Module Name:
8555+ * comprocs.h
8556+ *
8557+ * Abstract: This module defines all of the globally used procedures in the Afa comm layer
8558+ *
8559+ *
8560+ *
8561+ --*/
8562+#ifndef _COMPROCS_
8563+#define _COMPROCS_
8564+
8565+static char *ident_comproc = "aacraid_ident comprocs.h 1.0.6 2000/10/09 Adaptec, Inc.";
8566+
8567+#include "osheaders.h"
8568+
8569+#include "AacGenericTypes.h"
8570+
8571+#include "aac_unix_defs.h"
8572+
8573+#include "nodetype.h"
8574+
8575+// #define GATHER_FIB_TIMES
8576+
8577+#include "fsatypes.h"
8578+
8579+#include "perfpack.h"
8580+
8581+#include "comstruc.h"
8582+
8583+//#include "unix_protocol.h"
8584+
8585+#include "fsact.h"
8586+
8587+#include "protocol.h"
8588+
8589+#include "fsaioctl.h"
8590+
8591+#undef GATHER_FIB_TIMES
8592+
8593+#include "aifstruc.h"
8594+
8595+#include "fsaport.h"
8596+#include "comsup.h"
8597+#include "afacomm.h"
8598+#include "adapter.h"
8599+
8600+#include "commfibcontext.h"
8601+#include "comproto.h"
8602+#include "commdata.h"
8603+#include "commerr.h"
8604+
8605+
8606+
8607+
8608+//
8609+// The following macro is used when sending and receiving FIBs. It is only used for
8610+// debugging.
8611+
8612+#if DBG
8613+#define FIB_COUNTER_INCREMENT(Counter) InterlockedIncrement(&(Counter))
8614+#else
8615+#define FIB_COUNTER_INCREMENT(Counter)
8616+#endif
8617+
8618+
8619+
8620+int
8621+AfaCommAdapterDeviceControl (
8622+ IN PVOID AdapterArg,
8623+ IN PAFA_IOCTL_CMD IoctlCmdPtr
8624+ );
8625+
8626+
8627+#endif // _COMPROCS_
8628diff -burN linux-2.4.7/drivers/scsi/aacraid/include/comproto.h linux/drivers/scsi/aacraid/include/comproto.h
8629--- linux-2.4.7/drivers/scsi/aacraid/include/comproto.h Wed Dec 31 18:00:00 1969
8630+++ linux/drivers/scsi/aacraid/include/comproto.h Sat Jul 21 17:55:13 2001
8631@@ -0,0 +1,170 @@
8632+/*++
8633+ * Adaptec aacraid device driver for Linux.
8634+ *
8635+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8636+ *
8637+ * This program is free software; you can redistribute it and/or modify
8638+ * it under the terms of the GNU General Public License as published by
8639+ * the Free Software Foundation; either version 2, or (at your option)
8640+ * any later version.
8641+ *
8642+ * This program is distributed in the hope that it will be useful,
8643+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
8644+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8645+ * GNU General Public License for more details.
8646+ *
8647+ * You should have received a copy of the GNU General Public License
8648+ * along with this program; see the file COPYING. If not, write to
8649+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8650+ *
8651+ * Module Name:
8652+ * comproto.h
8653+ *
8654+ * Abstract: Global routines for the commuication interface that are device
8655+ * independant.
8656+ *
8657+ *
8658+ *
8659+ --*/
8660+#ifndef _COMM_PROTO
8661+#define _COMM_PROTO
8662+
8663+static char *ident_comproto = "aacraid_ident comproto.h 1.0.6 2000/10/09 Adaptec, Inc.";
8664+
8665+//
8666+// define the routines we need so we can commuicate with the
8667+// fsa adapter
8668+//
8669+
8670+//
8671+// The following 4 dpc routines will support commuication from the adapter to the
8672+// host. There is one DPC routine to deal with each type of queue that supports
8673+// commuication from the adapter. (adapter to host resposes, adapter to host commands)
8674+// These routines will simply pull off the QE and set an event. In the case of a
8675+// adapter to host command they will also put the FIB on a queue to be processed by
8676+// a FS thread running at passive level.
8677+//
8678+
8679+// Handle queue not full notification to the file system thread waiting for a queue entry
8680+
8681+u_int
8682+CommonNotFullDpc(
8683+ IN PCOMM_REGION CommRegion
8684+ );
8685+
8686+// Adapter to host normal priority responses
8687+
8688+u_int
8689+HostResponseNormalDpc(
8690+ IN PCOMM_QUE OurQueue
8691+ );
8692+
8693+// Adapter to host high priority responses
8694+u_int
8695+HostResponseHighDpc(
8696+ IN PCOMM_QUE OurQueue
8697+ );
8698+
8699+// Adapter to host high priority commands
8700+u_int
8701+HostCommandHighDpc(
8702+ IN PCOMM_QUE OurQueue
8703+ );
8704+
8705+
8706+// Adapter to host normal priority commands
8707+u_int
8708+HostCommandNormDpc(
8709+ IN PCOMM_QUE OurQueue
8710+ );
8711+
8712+
8713+
8714+BOOLEAN
8715+SendSynchFib(
8716+ PVOID Arg,
8717+ FIB_COMMAND Command,
8718+ PVOID Data,
8719+ USHORT Size,
8720+ PVOID Response,
8721+ USHORT *ResponseSize
8722+ );
8723+
8724+PFIB_CONTEXT
8725+AllocateFib (
8726+ IN PVOID Adapter
8727+ );
8728+
8729+VOID
8730+FreeFib (
8731+ IN PFIB_CONTEXT FibContext
8732+ );
8733+
8734+VOID
8735+FreeFibFromDpc(
8736+ IN PFIB_CONTEXT FibContext
8737+ );
8738+
8739+AAC_STATUS
8740+DeallocateFib(
8741+ IN PFIB_CONTEXT FibContext
8742+ );
8743+
8744+
8745+
8746+AAC_STATUS
8747+SendFib(
8748+ IN FIB_COMMAND Command,
8749+ IN PFIB_CONTEXT FibContext,
8750+ IN ULONG Size,
8751+ IN COMM_PRIORITIES Priority,
8752+ IN BOOLEAN Wait,
8753+ IN PVOID WaitOn,
8754+ IN BOOLEAN ResponseExpected,
8755+ IN PFIB_CALLBACK FibCallback,
8756+ IN PVOID FibCallbackContext
8757+ );
8758+
8759+AAC_STATUS
8760+CompleteFib(
8761+ IN PFIB_CONTEXT FibContext
8762+ );
8763+
8764+AAC_STATUS
8765+CompleteAdapterFib(
8766+ IN PFIB_CONTEXT FibContext,
8767+ IN USHORT Size
8768+ );
8769+
8770+AAC_STATUS
8771+InitializeFib(
8772+ IN PFIB_CONTEXT FibContext
8773+ );
8774+
8775+
8776+PVOID
8777+FsaGetFibData(
8778+ IN PFIB_CONTEXT FibContext
8779+ );
8780+
8781+
8782+
8783+AAC_STATUS
8784+AfaCommOpenAdapter (
8785+ IN PVOID AdapterArg
8786+ );
8787+
8788+AAC_STATUS
8789+AfaCommCloseAdapter (
8790+ IN PVOID AdapterArg
8791+ );
8792+
8793+
8794+VOID
8795+AfaCommInterruptHost(
8796+ PVOID Adapter,
8797+ ADAPTER_EVENT AdapterEvent
8798+ );
8799+
8800+
8801+#endif // _COMM_PROTO
8802diff -burN linux-2.4.7/drivers/scsi/aacraid/include/comstruc.h linux/drivers/scsi/aacraid/include/comstruc.h
8803--- linux-2.4.7/drivers/scsi/aacraid/include/comstruc.h Wed Dec 31 18:00:00 1969
8804+++ linux/drivers/scsi/aacraid/include/comstruc.h Sat Jul 21 17:55:13 2001
8805@@ -0,0 +1,435 @@
8806+/*++
8807+ * Adaptec aacraid device driver for Linux.
8808+ *
8809+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8810+ *
8811+ * This program is free software; you can redistribute it and/or modify
8812+ * it under the terms of the GNU General Public License as published by
8813+ * the Free Software Foundation; either version 2, or (at your option)
8814+ * any later version.
8815+ *
8816+ * This program is distributed in the hope that it will be useful,
8817+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
8818+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8819+ * GNU General Public License for more details.
8820+ *
8821+ * You should have received a copy of the GNU General Public License
8822+ * along with this program; see the file COPYING. If not, write to
8823+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8824+ *
8825+ * Module Name:
8826+ * comstruc.h
8827+ *
8828+ * Abstract: This module defines the data structures that make up the communication
8829+ * region for the FSA filesystem. This region is how the host based code
8830+ * communicates both control and data to the adapter based code.
8831+ *
8832+ *
8833+ *
8834+ --*/
8835+#ifndef _COMM_STRUCT
8836+#define _COMM_STRUCT
8837+
8838+static char *ident_comstruc = "aacraid_ident comstruc.h 1.0.7 2000/10/11 Adaptec, Inc.";
8839+
8840+//
8841+// Define all the constants needed for the communication interface
8842+//
8843+
8844+// Define how many queue entries each queue will have and the total number of
8845+// entries for the entire communication interface. Also define how many queues
8846+// we support.
8847+
8848+#define NUMBER_OF_COMM_QUEUES 8 // 4 command; 4 response
8849+#define HOST_HIGH_CMD_ENTRIES 4
8850+#define HOST_NORM_CMD_ENTRIES 8
8851+#define ADAP_HIGH_CMD_ENTRIES 4
8852+#define ADAP_NORM_CMD_ENTRIES 512
8853+#define HOST_HIGH_RESP_ENTRIES 4
8854+#define HOST_NORM_RESP_ENTRIES 512
8855+#define ADAP_HIGH_RESP_ENTRIES 4
8856+#define ADAP_NORM_RESP_ENTRIES 8
8857+
8858+#define TOTAL_QUEUE_ENTRIES \
8859+ (HOST_NORM_CMD_ENTRIES + HOST_HIGH_CMD_ENTRIES + ADAP_NORM_CMD_ENTRIES + ADAP_HIGH_CMD_ENTRIES + \
8860+ HOST_NORM_RESP_ENTRIES + HOST_HIGH_RESP_ENTRIES + ADAP_NORM_RESP_ENTRIES + ADAP_HIGH_RESP_ENTRIES)
8861+
8862+
8863+
8864+
8865+// Set the queues on a 16 byte alignment
8866+#define QUEUE_ALIGNMENT 16
8867+
8868+
8869+//
8870+// The queue headers define the Communication Region queues. These
8871+// are physically contiguous and accessible by both the adapter and the
8872+// host. Even though all queue headers are in the same contiguous block they will be
8873+// represented as individual units in the data structures.
8874+//
8875+
8876+typedef AAC_UINT32 QUEUE_INDEX;
8877+
8878+typedef QUEUE_INDEX *PQUEUE_INDEX;
8879+
8880+typedef struct _QUEUE_ENTRY {
8881+
8882+ AAC_UINT32 Size; // Size in bytes of the Fib which this QE points to
8883+ AAC_UINT32 FibAddress; // Receiver addressable address of the FIB (low 32 address bits)
8884+
8885+} QUEUE_ENTRY;
8886+
8887+typedef QUEUE_ENTRY *PQUEUE_ENTRY;
8888+
8889+
8890+
8891+// The adapter assumes the ProducerIndex and ConsumerIndex are grouped
8892+// adjacently and in that order.
8893+//
8894+typedef struct _QUEUE_HEADERS {
8895+
8896+ PHYSICAL_ADDRESS LogicalHeaderAddress; // Address to hand the adapter to access to this queue head
8897+ PQUEUE_INDEX ProducerIndex; // The producer index for this queue (host address)
8898+ PQUEUE_INDEX ConsumerIndex; // The consumer index for this queue (host address)
8899+
8900+} QUEUE_HEADERS;
8901+typedef QUEUE_HEADERS *PQUEUE_HEADERS;
8902+
8903+//
8904+// Define all the events which the adapter would like to notify
8905+// the host of.
8906+//
8907+typedef enum _ADAPTER_EVENT {
8908+ HostNormCmdQue = 1, // Change in host normal priority command queue
8909+ HostHighCmdQue, // Change in host high priority command queue
8910+ HostNormRespQue, // Change in host normal priority response queue
8911+ HostHighRespQue, // Change in host high priority response queue
8912+ AdapNormRespNotFull,
8913+ AdapHighRespNotFull,
8914+ AdapNormCmdNotFull,
8915+ AdapHighCmdNotFull,
8916+ SynchCommandComplete,
8917+ AdapInternalError = 0xfe // The adapter detected an internal error shutting down
8918+
8919+} _E_ADAPTER_EVENT;
8920+
8921+#ifdef AAC_32BIT_ENUMS
8922+typedef _E_ADAPTER_EVENT ADAPTER_EVENT;
8923+#else
8924+typedef AAC_UINT32 ADAPTER_EVENT;
8925+#endif
8926+
8927+//
8928+// Define all the events the host wishes to notify the
8929+// adapter of.
8930+//
8931+typedef enum _HOST_2_ADAP_EVENT {
8932+ AdapNormCmdQue = 1,
8933+ AdapHighCmdQue,
8934+ AdapNormRespQue,
8935+ AdapHighRespQue,
8936+ HostShutdown,
8937+ HostPowerFail,
8938+ FatalCommError,
8939+ HostNormRespNotFull,
8940+ HostHighRespNotFull,
8941+ HostNormCmdNotFull,
8942+ HostHighCmdNotFull,
8943+ FastIo,
8944+ AdapPrintfDone
8945+} _E_HOST_2_ADAP_EVENT;
8946+
8947+#ifdef AAC_32BIT_ENUMS
8948+typedef _E_HOST_2_ADAP_EVENT HOST_2_ADAP_EVENT;
8949+#else
8950+typedef AAC_UINT32 HOST_2_ADAP_EVENT;
8951+#endif
8952+
8953+//
8954+// Define all the queues that the adapter and host use to communicate
8955+//
8956+
8957+typedef enum _QUEUE_TYPES {
8958+ HostNormCmdQueue = 1, // Adapter to host normal priority command traffic
8959+ HostHighCmdQueue, // Adapter to host high priority command traffic
8960+ AdapNormRespQueue, // Host to adapter normal priority response traffic
8961+ AdapHighRespQueue, // Host to adapter high priority response traffic
8962+ AdapNormCmdQueue, // Host to adapter normal priority command traffic
8963+ AdapHighCmdQueue, // Host to adapter high priority command traffic
8964+ HostNormRespQueue, // Adapter to host normal priority response traffic
8965+ HostHighRespQueue // Adapter to host high priority response traffic
8966+} _E_QUEUE_TYPES;
8967+
8968+#ifdef AAC_32BIT_ENUMS
8969+typedef _E_QUEUE_TYPES QUEUE_TYPES;
8970+#else
8971+typedef AAC_UINT32 QUEUE_TYPES;
8972+#endif
8973+
8974+
8975+//
8976+// Assign type values to the FSA communication data structures
8977+//
8978+
8979+typedef enum _STRUCT_TYPES {
8980+ TFib = 1,
8981+ TQe,
8982+ TCtPerf
8983+} _E_STRUCT_TYPES;
8984+
8985+#ifdef AAC_32BIT_ENUMS
8986+typedef _E_STRUCT_TYPES STRUCT_TYPES;
8987+#else
8988+typedef AAC_UINT32 STRUCT_TYPES;
8989+#endif
8990+
8991+//
8992+// Define the priority levels the FSA communication routines support.
8993+//
8994+
8995+typedef enum _COMM_PRIORITIES {
8996+ FsaNormal = 1,
8997+ FsaHigh
8998+} _E_COMM_PRIORITIES;
8999+
9000+#ifdef AAC_32BIT_ENUMS
9001+typedef _E_COMM_PRIORITIES COMM_PRIORITIES;
9002+#else
9003+typedef AAC_UINT32 COMM_PRIORITIES;
9004+#endif
9005+
9006+
9007+
9008+//
9009+// Define the LIST_ENTRY structure. This structure is used on the NT side to link
9010+// the FIBs together in a linked list. Since this structure gets compiled on the adapter
9011+// as well, we need to define this structure for the adapter's use. If '_NT_DEF_'
9012+// is defined, then this header is being included from the NT side, and therefore LIST_ENTRY
9013+// is already defined.
9014+#if !defined(_NTDEF_) && !defined(_WINNT_)
9015+typedef struct _LIST_ENTRY {
9016+ struct _LIST_ENTRY *Flink;
9017+ struct _LIST_ENTRY *Blink;
9018+} LIST_ENTRY;
9019+typedef LIST_ENTRY *PLIST_ENTRY;
9020+#endif
9021+
9022+
9023+//
9024+// Define the FIB. The FIB is the where all the requested data and
9025+// command information are put to the application on the FSA adapter.
9026+//
9027+
9028+typedef struct _FIB_HEADER {
9029+ AAC_UINT32 XferState; // Current transfer state for this CCB
9030+ AAC_UINT16 Command; // Routing information for the destination
9031+ AAC_UINT8 StructType; // Type FIB
9032+ AAC_UINT8 Flags; // Flags for FIB
9033+ AAC_UINT16 Size; // Size of this FIB in bytes
9034+ AAC_UINT16 SenderSize; // Size of the FIB in the sender (for response sizing)
9035+ AAC_UINT32 SenderFibAddress; // Host defined data in the FIB
9036+ AAC_UINT32 ReceiverFibAddress; // Logical address of this FIB for the adapter
9037+ AAC_UINT32 SenderData; // Place holder for the sender to store data
9038+#ifndef __midl
9039+ union {
9040+ struct {
9041+ AAC_UINT32 _ReceiverTimeStart; // Timestamp for receipt of fib
9042+ AAC_UINT32 _ReceiverTimeDone; // Timestamp for completion of fib
9043+ } _s;
9044+ LIST_ENTRY _FibLinks; // Used to link Adapter Initiated Fibs on the host
9045+ } _u;
9046+#else // The MIDL compiler does not support unions without a discriminant.
9047+ struct { // Since nothing during the midl compile actually looks into this
9048+ struct { // structure, this shoudl be ok.
9049+ AAC_UINT32 _ReceiverTimeStart; // Timestamp for receipt of fib
9050+ AAC_UINT32 _ReceiverTimeDone; // Timestamp for completion of fib
9051+ } _s;
9052+ } _u;
9053+#endif
9054+} FIB_HEADER;
9055+
9056+
9057+#define FibLinks _u._FibLinks
9058+
9059+
9060+#define FIB_DATA_SIZE_IN_BYTES (512 - sizeof(FIB_HEADER))
9061+
9062+
9063+typedef struct _FIB {
9064+
9065+#ifdef BRIDGE //rma
9066+ DLQUE link;
9067+#endif
9068+ FIB_HEADER Header;
9069+
9070+ AAC_UINT8 data[FIB_DATA_SIZE_IN_BYTES]; // Command specific data
9071+
9072+} FIB;
9073+typedef FIB *PFIB;
9074+
9075+
9076+
9077+//
9078+// FIB commands
9079+//
9080+
9081+typedef enum _FIB_COMMANDS {
9082+ TestCommandResponse = 1,
9083+ TestAdapterCommand = 2,
9084+
9085+ // Lowlevel and comm commands
9086+
9087+ LastTestCommand = 100,
9088+ ReinitHostNormCommandQueue = 101,
9089+ ReinitHostHighCommandQueue = 102,
9090+ ReinitHostHighRespQueue = 103,
9091+ ReinitHostNormRespQueue = 104,
9092+ ReinitAdapNormCommandQueue = 105,
9093+ ReinitAdapHighCommandQueue = 107,
9094+ ReinitAdapHighRespQueue = 108,
9095+ ReinitAdapNormRespQueue = 109,
9096+ InterfaceShutdown = 110,
9097+ DmaCommandFib = 120,
9098+ StartProfile = 121,
9099+ TermProfile = 122,
9100+ SpeedTest = 123,
9101+ TakeABreakPt = 124,
9102+ RequestPerfData = 125,
9103+ SetInterruptDefTimer= 126,
9104+ SetInterruptDefCount= 127,
9105+ GetInterruptDefStatus= 128,
9106+ LastCommCommand = 129,
9107+
9108+ // Filesystem commands
9109+
9110+ NuFileSystem = 300,
9111+ UFS = 301,
9112+ HostFileSystem = 302,
9113+ LastFileSystemCommand = 303,
9114+
9115+ // Container Commands
9116+
9117+ ContainerCommand = 500,
9118+ ContainerCommand64 = 501,
9119+
9120+ // Cluster Commands
9121+
9122+ ClusterCommand = 550,
9123+
9124+ // Scsi Port commands (scsi passthrough)
9125+
9126+ ScsiPortCommand = 600,
9127+
9128+ // misc house keeping and generic adapter initiated commands
9129+
9130+ AifRequest = 700,
9131+ CheckRevision = 701,
9132+ FsaHostShutdown = 702,
9133+ RequestAdapterInfo = 703,
9134+ IsAdapterPaused = 704,
9135+ SendHostTime = 705,
9136+ LastMiscCommand = 706
9137+
9138+} _E_FIB_COMMANDS;
9139+
9140+
9141+
9142+typedef AAC_UINT16 FIB_COMMAND;
9143+
9144+//
9145+// Commands that will target the failover level on the FSA adapter
9146+//
9147+
9148+typedef enum _FIB_XFER_STATE {
9149+ HostOwned = (1<<0),
9150+ AdapterOwned = (1<<1),
9151+ FibInitialized = (1<<2),
9152+ FibEmpty = (1<<3),
9153+ AllocatedFromPool = (1<<4),
9154+ SentFromHost = (1<<5),
9155+ SentFromAdapter = (1<<6),
9156+ ResponseExpected = (1<<7),
9157+ NoResponseExpected = (1<<8),
9158+ AdapterProcessed = (1<<9),
9159+ HostProcessed = (1<<10),
9160+ HighPriority = (1<<11),
9161+ NormalPriority = (1<<12),
9162+ Async = (1<<13),
9163+ AsyncIo = (1<<13), // rpbfix: remove with new regime
9164+ PageFileIo = (1<<14), // rpbfix: remove with new regime
9165+ ShutdownRequest = (1<<15),
9166+ LazyWrite = (1<<16), // rpbfix: remove with new regime
9167+ AdapterMicroFib = (1<<17),
9168+ BIOSFibPath = (1<<18),
9169+ FastResponseCapable = (1<<19),
9170+ ApiFib = (1<<20) // Its an API Fib.
9171+
9172+} _E_FIB_XFER_STATE;
9173+
9174+
9175+typedef enum _FSA_ERRORS {
9176+ FSA_NORMAL = 0,
9177+ FSA_SUCCESS = 0,
9178+ FSA_PENDING = 0x01,
9179+ FSA_FATAL = 0x02,
9180+ FSA_INVALID_QUEUE = 0x03,
9181+ FSA_NOENTRIES = 0x04,
9182+ FSA_SENDFAILED = 0x05,
9183+ FSA_INVALID_QUEUE_PRIORITY = 0x06,
9184+ FSA_FIB_ALLOCATION_FAILED = 0x07,
9185+ FSA_FIB_DEALLOCATION_FAILED = 0x08
9186+
9187+} _E_FSA_ERRORS;
9188+
9189+
9190+//
9191+// The following defines needs to be updated any time there is an incompatible change made
9192+// to the ADAPTER_INIT_STRUCT structure.
9193+//
9194+#define ADAPTER_INIT_STRUCT_REVISION 3
9195+
9196+typedef struct _ADAPTER_INIT_STRUCT {
9197+ AAC_UINT32 InitStructRevision;
9198+ AAC_UINT32 MiniPortRevision;
9199+ AAC_UINT32 FilesystemRevision;
9200+ PAAC_VOID CommHeaderAddress;
9201+ PAAC_VOID FastIoCommAreaAddress;
9202+ PAAC_VOID AdapterFibsPhysicalAddress;
9203+ PAAC_VOID AdapterFibsVirtualAddress;
9204+ AAC_UINT32 AdapterFibsSize;
9205+ AAC_UINT32 AdapterFibAlign;
9206+ PAAC_VOID PrintfBufferAddress;
9207+ AAC_UINT32 PrintfBufferSize;
9208+ AAC_UINT32 HostPhysMemPages; // number of 4k pages of host physical memory
9209+ AAC_UINT32 HostElapsedSeconds; // number of seconds since 1970.
9210+} ADAPTER_INIT_STRUCT;
9211+typedef ADAPTER_INIT_STRUCT *PADAPTER_INIT_STRUCT;
9212+
9213+#ifdef AAC_32BIT_ENUMS
9214+typedef _E_FSA_ERRORS FSA_ERRORS;
9215+#else
9216+typedef AAC_UINT32 FSA_ERRORS;
9217+#endif
9218+
9219+typedef enum _LOG_LEVEL {
9220+ LOG_INIT = 10,
9221+ LOG_INFORMATIONAL = 20,
9222+ LOG_WARNING = 30,
9223+ LOG_LOW_ERROR = 40,
9224+ LOG_MEDIUM_ERROR = 50,
9225+ LOG_HIGH_ERROR = 60,
9226+ LOG_PANIC = 70,
9227+ LOG_DEBUG = 80,
9228+ LOG_WINDBG_PRINT = 90
9229+} _E_LOG_LEVEL;
9230+
9231+#ifdef AAC_32BIT_ENUMS
9232+typedef _E_LOG_LEVEL LOG_LEVEL;
9233+#else
9234+typedef AAC_UINT32 LOG_LEVEL;
9235+#endif
9236+
9237+
9238+#endif //_COMM_STRUCT
9239+
9240+
9241diff -burN linux-2.4.7/drivers/scsi/aacraid/include/comsup.h linux/drivers/scsi/aacraid/include/comsup.h
9242--- linux-2.4.7/drivers/scsi/aacraid/include/comsup.h Wed Dec 31 18:00:00 1969
9243+++ linux/drivers/scsi/aacraid/include/comsup.h Sat Jul 21 17:55:13 2001
9244@@ -0,0 +1,132 @@
9245+/*++
9246+ * Adaptec aacraid device driver for Linux.
9247+ *
9248+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9249+ *
9250+ * This program is free software; you can redistribute it and/or modify
9251+ * it under the terms of the GNU General Public License as published by
9252+ * the Free Software Foundation; either version 2, or (at your option)
9253+ * any later version.
9254+ *
9255+ * This program is distributed in the hope that it will be useful,
9256+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9257+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9258+ * GNU General Public License for more details.
9259+ *
9260+ * You should have received a copy of the GNU General Public License
9261+ * along with this program; see the file COPYING. If not, write to
9262+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9263+ *
9264+ * Module Name:
9265+ * comsup.h
9266+ *
9267+ * Abstract: This module defines the data structures that make up the
9268+ * commuication region for the FSA filesystem. This region is
9269+ * how the host based code commuicates both control and data
9270+ * to the adapter based code.
9271+ *
9272+ *
9273+ *
9274+ --*/
9275+#ifndef _COMM_SUP_DEF
9276+#define _COMM_SUP_DEF
9277+
9278+static char *ident_comsup = "aacraid_ident comsup.h 1.0.6 2000/10/09 Adaptec, Inc.";
9279+
9280+//
9281+// The adapter interface specs all queues to be located in the same physically
9282+// contigous block. The host structure that defines the commuication queues will
9283+// assume they are each a seperate physically contigous memory region that will
9284+// support them all being one big contigous block.
9285+// There is a command and response queue for each level and direction of
9286+// commuication. These regions are accessed by both the host and adapter.
9287+//
9288+typedef struct _COMM_QUE {
9289+
9290+ PHYSICAL_ADDRESS LogicalAddress; // This is the address we give the adapter
9291+
9292+ PQUEUE_ENTRY BaseAddress; // This is the system virtual address
9293+ QUEUE_HEADERS Headers; // A pointer to the producer and consumer queue headers for this queue
9294+ ULONG QueueEntries; // Number of queue entries on this queue
9295+ OS_CV_T QueueFull; // Event to wait on if the queue is full
9296+ OS_CV_T CommandReady; // Indicates there is a Command ready from the adapter on this queue.
9297+ // This is only valid for adapter to host command queues.
9298+ OS_SPINLOCK *QueueLock; // Spinlock for this queue must take this lock before accessing the lock
9299+ KIRQL SavedIrql; // Previous IRQL when the spin lock is taken
9300+ ddi_softintr_t ConsumerRoutine; // The DPC routine which will consume entries off this queue
9301+ // Only queues which the host will be the consumer will this field be valid
9302+ LIST_ENTRY CommandQueue; // A queue of FIBs which need to be prcessed by the FS thread. This is
9303+ // only valid for command queues which receive entries from the adapter.
9304+ LIST_ENTRY OutstandingIoQueue; // A queue of outstanding fib's to the adapter.
9305+ ULONG NumOutstandingIos; // Number of entries on outstanding queue.
9306+
9307+ PVOID Adapter; // Back pointer to adapter structure
9308+
9309+} COMM_QUE;
9310+typedef COMM_QUE *PCOMM_QUE;
9311+
9312+
9313+typedef struct _COMM_REGION {
9314+
9315+ COMM_QUE HostNormCmdQue; // Command queue for normal priority commands from the host
9316+ COMM_QUE HostNormRespQue; // A response for normal priority adapter responses
9317+
9318+ COMM_QUE HostHighCmdQue; // Command queue for high priority commands from the host
9319+ COMM_QUE HostHighRespQue; // A response for normal priority adapter responses
9320+
9321+ COMM_QUE AdapNormCmdQue; // Command queue for normal priority command from the adapter
9322+ COMM_QUE AdapNormRespQue; // A response for normal priority host responses
9323+
9324+ COMM_QUE AdapHighCmdQue; // Command queue for high priority command from the adapter
9325+ COMM_QUE AdapHighRespQue; // A response for high priority host responses
9326+
9327+ //
9328+ // The 2 threads below are the threads which handle command traffic from the
9329+ // the adapter. There is one for normal priority and one for high priority queues.
9330+ // These threads will wait on the commandready event for it's queue.
9331+ //
9332+
9333+ HANDLE NormCommandThread;
9334+ HANDLE HighCommandThread;
9335+
9336+ //
9337+ // This dpc routine will handle the setting the of not full event when the adapter
9338+ // lets us know the queue is not longer full via interrupt
9339+ //
9340+
9341+ KDPC QueueNotFullDpc;
9342+
9343+#ifdef API_THROTTLE
9344+ //
9345+ // Support for data I/O throttling to improve CLI performance
9346+ // while the system is under load.
9347+ // This is the throttling mechanism built into the COMM layer.
9348+ // Look in commsup.c, dpcsup.c and comminit.c for use.
9349+ //
9350+
9351+ int ThrottleLimit; // Max queue depth of data ops allowed during throttle
9352+ int ThrottleOutstandingFibs; // Number of data FIBs outstanding to adapter
9353+ LARGE_INTEGER ThrottleTimeout; // Duration of a a throttle period
9354+ LARGE_INTEGER ThrottleWaitTimeout; // Timeout for a suspended threads to wait
9355+ BOOLEAN ThrottleActive; // Is there a current throttle active period ?
9356+ KTIMER ThrottleTimer; // Throttle timer to end a throttle period.
9357+ KDPC ThrottleDpc; // Throttle timer timeout DPC routine.
9358+ KSEMAPHORE ThrottleReleaseSema; // Semaphore callers of SendFib wait on during a throttle.
9359+
9360+ unsigned int ThrottleExceptionsCount; // Number of times throttle exception handler executed (0!)
9361+ unsigned int ThrottleTimerFires; // Debug info - #times throttle timer Dpc has fired
9362+ unsigned int ThrottleTimerSets; // Debug info - #times throttle timer was set
9363+
9364+ unsigned int ThrottledFibs;
9365+ unsigned int ThrottleTimedoutFibs;
9366+ unsigned int ApiFibs;
9367+ unsigned int NonPassiveFibs;
9368+ unsigned int TotalFibs;
9369+ unsigned int FSInfoFibs;
9370+
9371+#endif // #ifdef API_THROTTLE
9372+
9373+} COMM_REGION;
9374+typedef COMM_REGION *PCOMM_REGION;
9375+
9376+#endif // _COMM_SUP
9377diff -burN linux-2.4.7/drivers/scsi/aacraid/include/fsact.h linux/drivers/scsi/aacraid/include/fsact.h
9378--- linux-2.4.7/drivers/scsi/aacraid/include/fsact.h Wed Dec 31 18:00:00 1969
9379+++ linux/drivers/scsi/aacraid/include/fsact.h Sat Jul 21 17:55:13 2001
9380@@ -0,0 +1,165 @@
9381+/*++
9382+ * Adaptec aacraid device driver for Linux.
9383+ *
9384+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9385+ *
9386+ * This program is free software; you can redistribute it and/or modify
9387+ * it under the terms of the GNU General Public License as published by
9388+ * the Free Software Foundation; either version 2, or (at your option)
9389+ * any later version.
9390+ *
9391+ * This program is distributed in the hope that it will be useful,
9392+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9393+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9394+ * GNU General Public License for more details.
9395+ *
9396+ * You should have received a copy of the GNU General Public License
9397+ * along with this program; see the file COPYING. If not, write to
9398+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9399+ *
9400+ * Module Name:
9401+ * fsact.h
9402+ *
9403+ * Abstract: Common container structures that are required to be
9404+ * known on both the host and adapter.
9405+ *
9406+ *
9407+ --*/
9408+#ifndef _FSACT_H_
9409+#define _FSACT_H_
9410+
9411+static char *ident_fsact = "aacraid_ident fsact.h 1.0.6 2000/10/09 Adaptec, Inc.";
9412+
9413+//#include <comstruc.h>
9414+//#include <fsatypes.h>
9415+#include <protocol.h> // definitions for FSASTATUS
9416+
9417+
9418+/*
9419+ * Object-Server / Volume-Manager Dispatch Classes
9420+ */
9421+typedef enum _VM_COMMANDS {
9422+ VM_Null = 0,
9423+ VM_NameServe,
9424+ VM_ContainerConfig,
9425+ VM_Ioctl,
9426+ VM_FilesystemIoctl,
9427+ VM_CloseAll,
9428+ VM_CtBlockRead, // see protocol.h for BlockRead command layout
9429+ VM_CtBlockWrite, // see protocol.h for BlockWrite command layout
9430+ VM_SliceBlockRead, // raw access to configured "storage objects"
9431+ VM_SliceBlockWrite,
9432+ VM_DriveBlockRead, // raw access to physical devices
9433+ VM_DriveBlockWrite,
9434+ VM_EnclosureMgt, // enclosure management
9435+ VM_Unused, // used to be diskset management
9436+ VM_CtBlockVerify, // see protocol.h for BlockVerify command layout
9437+ VM_CtPerf, // performance test
9438+ VM_CtBlockRead64, // see protocol.h for BlockRead64 command layout
9439+ VM_CtBlockWrite64, // see protocol.h for BlockWrite64 command layout
9440+ VM_CtBlockVerify64, // see protocol.h for BlockVerify64 command layout
9441+ MAX_VMCOMMAND_NUM // used for sizing stats array - leave last
9442+} _E_VMCOMMAND;
9443+
9444+#ifdef AAC_32BIT_ENUMS
9445+typedef _E_VMCOMMAND VMCOMMAND;
9446+#else
9447+typedef AAC_UINT32 VMCOMMAND;
9448+#endif
9449+
9450+
9451+
9452+//
9453+// Descriptive information (eg, vital stats)
9454+// that a content manager might report. The
9455+// FileArray filesystem component is one example
9456+// of a content manager. Raw mode might be
9457+// another.
9458+//
9459+
9460+struct FileSysInfo {
9461+/*
9462+ a) DOS usage - THINK ABOUT WHERE THIS MIGHT GO -- THXXX
9463+ b) FSA usage (implemented by ObjType and ContentState fields)
9464+ c) Block size
9465+ d) Frag size
9466+ e) Max file system extension size - (fsMaxExtendSize * fsSpaceUnits)
9467+ f) I-node density - (computed from other fields)
9468+*/
9469+ AAC_UINT32 fsTotalSize; // consumed by fs, incl. metadata
9470+ AAC_UINT32 fsBlockSize;
9471+ AAC_UINT32 fsFragSize;
9472+ AAC_UINT32 fsMaxExtendSize;
9473+ AAC_UINT32 fsSpaceUnits;
9474+ AAC_UINT32 fsMaxNumFiles;
9475+ AAC_UINT32 fsNumFreeFiles;
9476+ AAC_UINT32 fsInodeDensity;
9477+}; // valid iff ObjType == FT_FILESYS && !(ContentState & FSCS_NOTCLEAN)
9478+
9479+union ContentManagerInfo {
9480+ struct FileSysInfo FileSys; // valid iff ObjType == FT_FILESYS && !(ContentState & FSCS_NOTCLEAN)
9481+};
9482+
9483+//
9484+// Query for "mountable" objects, ie, objects that are typically
9485+// associated with a drive letter on the client (host) side.
9486+//
9487+
9488+typedef struct _MNTOBJ {
9489+
9490+ AAC_UINT32 ObjectId;
9491+ FSASTRING FileSystemName; // if applicable
9492+ ContainerCreationInfo CreateInfo; // if applicable
9493+ AAC_UINT32 Capacity;
9494+ FSAVOLTYPE VolType; // substrate structure
9495+ FTYPE ObjType; // FT_FILESYS, FT_DATABASE, etc.
9496+ AAC_UINT32 ContentState; // unready for mounting, readonly, etc.
9497+
9498+ union ContentManagerInfo
9499+ ObjExtension; // Info specific to content manager (eg, filesystem)
9500+
9501+ AAC_UINT32 AlterEgoId; // != ObjectId <==> snapshot or broken mirror exists
9502+
9503+} MNTOBJ;
9504+
9505+
9506+#define FSCS_READONLY 0x0002 // possible result of broken mirror
9507+
9508+
9509+
9510+typedef struct _MNTINFO {
9511+
9512+ VMCOMMAND Command;
9513+ FTYPE MntType;
9514+ AAC_UINT32 MntCount;
9515+
9516+} MNTINFO;
9517+typedef MNTINFO *PMNTINFO;
9518+
9519+typedef struct _MNTINFORESPONSE {
9520+
9521+ FSASTATUS Status;
9522+ FTYPE MntType; // should be same as that requested
9523+ AAC_UINT32 MntRespCount;
9524+ MNTOBJ MntTable[1];
9525+
9526+} MNTINFORESPONSE;
9527+typedef MNTINFORESPONSE *PMNTINFORESPONSE;
9528+
9529+
9530+//
9531+// The following command is sent to shut down each container.
9532+//
9533+
9534+typedef struct _CLOSECOMMAND {
9535+
9536+ VMCOMMAND Command;
9537+ AAC_UINT32 ContainerId;
9538+
9539+} CLOSECOMMAND;
9540+typedef CLOSECOMMAND *PCLOSECOMMAND;
9541+
9542+
9543+#endif /* _FSACT_H_ */
9544+
9545+
9546diff -burN linux-2.4.7/drivers/scsi/aacraid/include/fsafs.h linux/drivers/scsi/aacraid/include/fsafs.h
9547--- linux-2.4.7/drivers/scsi/aacraid/include/fsafs.h Wed Dec 31 18:00:00 1969
9548+++ linux/drivers/scsi/aacraid/include/fsafs.h Sat Jul 21 17:55:13 2001
9549@@ -0,0 +1,78 @@
9550+/*++
9551+ * Adaptec aacraid device driver for Linux.
9552+ *
9553+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9554+ *
9555+ * This program is free software; you can redistribute it and/or modify
9556+ * it under the terms of the GNU General Public License as published by
9557+ * the Free Software Foundation; either version 2, or (at your option)
9558+ * any later version.
9559+ *
9560+ * This program is distributed in the hope that it will be useful,
9561+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9562+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9563+ * GNU General Public License for more details.
9564+ *
9565+ * You should have received a copy of the GNU General Public License
9566+ * along with this program; see the file COPYING. If not, write to
9567+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9568+ *
9569+ * Module Name:
9570+ * fsafs.h
9571+ *
9572+ * Abstract: Common file system structures that are required to be
9573+ * known on both the host and adapter
9574+ *
9575+ *
9576+ *
9577+ --*/
9578+
9579+#ifndef _FSAFS_H_
9580+#define _FSAFS_H_ 1
9581+
9582+static char *ident_fsafs = "aacraid_ident fsafs.h 1.0.6 2000/10/09 Adaptec, Inc.";
9583+
9584+#include <fsatypes.h> // core types, shared by client and server, eg, u_long
9585+
9586+/*
9587+ * Maximum number of filesystems.
9588+ */
9589+#define NFILESYS 24
9590+
9591+/*
9592+ * File identifier.
9593+ * These are unique and self validating within a filesystem
9594+ * on a single machine and can persist across reboots.
9595+ * The hint field may be volatile and is not guaranteed to persist
9596+ * across reboots but is used to speed up the FID to file object translation
9597+ * if possible. The opaque f1 and f2 fields are guaranteed to uniquely identify
9598+ * the file object (assuming a filesystem context, i.e. driveno).
9599+ */
9600+typedef struct {
9601+ AAC_UINT32 hint; // last used hint for fast reclaim
9602+ AAC_UINT32 f1; // opaque
9603+ AAC_UINT32 f2; // opaque
9604+ } fileid_t; /* intra-filesystem file ID type */
9605+
9606+
9607+/*
9608+ * Generic file handle
9609+ */
9610+struct fhandle {
9611+ fsid_t fh_fsid; /* File system id of mount point */
9612+ fileid_t fh_fid; /* File sys specific file id */
9613+};
9614+typedef struct fhandle fhandle_t;
9615+
9616+#define FIDSIZE sizeof(fhandle_t)
9617+
9618+typedef struct {
9619+ union {
9620+ AAC_INT8 fid_data[FIDSIZE];
9621+ struct fhandle fsafid;
9622+ } fidu;
9623+} FSAFID; /* FSA File ID type */
9624+
9625+
9626+#endif /* _FSAFS_H_ */
9627+
9628diff -burN linux-2.4.7/drivers/scsi/aacraid/include/fsaioctl.h linux/drivers/scsi/aacraid/include/fsaioctl.h
9629--- linux-2.4.7/drivers/scsi/aacraid/include/fsaioctl.h Wed Dec 31 18:00:00 1969
9630+++ linux/drivers/scsi/aacraid/include/fsaioctl.h Sat Jul 21 17:55:13 2001
9631@@ -0,0 +1,159 @@
9632+/*++
9633+ * Adaptec aacraid device driver for Linux.
9634+ *
9635+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9636+ *
9637+ * This program is free software; you can redistribute it and/or modify
9638+ * it under the terms of the GNU General Public License as published by
9639+ * the Free Software Foundation; either version 2, or (at your option)
9640+ * any later version.
9641+ *
9642+ * This program is distributed in the hope that it will be useful,
9643+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9644+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9645+ * GNU General Public License for more details.
9646+ *
9647+ * You should have received a copy of the GNU General Public License
9648+ * along with this program; see the file COPYING. If not, write to
9649+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9650+ *
9651+ * Module Name:
9652+ * fsaioctl.h
9653+ *
9654+ * Abstract: Defines the interface structures between user mode applications
9655+ * and the fsa driver. This structures are used in
9656+ * DeviceIoControl() calls.
9657+ *
9658+ *
9659+ *
9660+ --*/
9661+#ifndef _FSAIOCTL_H_
9662+#define _FSAIOCTL_H_
9663+
9664+static char *ident_fsaioctl = "aacraid_ident fsaioctl.h 1.0.6 2000/10/09 Adaptec, Inc.";
9665+
9666+#ifndef IOTRACEUSER
9667+
9668+#ifndef CTL_CODE
9669+
9670+
9671+#define FILE_DEVICE_CONTROLLER 0x00000004
9672+
9673+//
9674+// Macro definition for defining IOCTL and FSCTL function control codes. Note
9675+// that function codes 0-2047 are reserved for Microsoft Corporation, and
9676+// 2048-4095 are reserved for customers.
9677+//
9678+
9679+#define CTL_CODE( DeviceType, Function, Method, Access ) ( \
9680+ ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
9681+)
9682+
9683+//
9684+// Define the method codes for how buffers are passed for I/O and FS controls
9685+//
9686+
9687+#define METHOD_BUFFERED 0
9688+
9689+
9690+#define METHOD_NEITHER 3
9691+
9692+//
9693+// Define the access check value for any access
9694+//
9695+//
9696+// The FILE_READ_ACCESS and FILE_WRITE_ACCESS constants are also defined in
9697+// ntioapi.h as FILE_READ_DATA and FILE_WRITE_DATA. The values for these
9698+// constants *MUST* always be in sync.
9699+//
9700+#define FILE_ANY_ACCESS 0
9701+
9702+
9703+
9704+#endif
9705+
9706+
9707+
9708+typedef struct _UNIX_QUERY_DISK {
9709+ AAC_INT32 ContainerNumber;
9710+ AAC_INT32 Bus;
9711+ AAC_INT32 Target;
9712+ AAC_INT32 Lun;
9713+ AAC_BOOLEAN Valid;
9714+ AAC_BOOLEAN Locked;
9715+ AAC_BOOLEAN Deleted;
9716+ AAC_INT32 Instance;
9717+ AAC_INT8 diskDeviceName[10];
9718+ AAC_BOOLEAN UnMapped;
9719+} UNIX_QUERY_DISK;
9720+typedef UNIX_QUERY_DISK *PUNIX_QUERY_DISK;
9721+
9722+
9723+typedef struct _DELETE_DISK {
9724+ AAC_UINT32 NtDiskNumber;
9725+ AAC_UINT32 ContainerNumber;
9726+} DELETE_DISK;
9727+typedef DELETE_DISK *PDELETE_DISK;
9728+
9729+
9730+#endif /*IOTRACEUSER*/
9731+
9732+#define FSACTL_NULL_IO_TEST 0x43 // CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 2048, METHOD_NEITHER, FILE_ANY_ACCESS)
9733+#define FSACTL_SIM_IO_TEST 0x53 // CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 2049, METHOD_NEITHER, FILE_ANY_ACCESS)
9734+
9735+
9736+#define FSACTL_SENDFIB CTL_CODE(FILE_DEVICE_CONTROLLER, 2050, METHOD_BUFFERED, FILE_ANY_ACCESS)
9737+
9738+
9739+#define FSACTL_GET_VAR 0x93
9740+#define FSACTL_SET_VAR 0xa3
9741+#define FSACTL_GET_FIBTIMES 0xb3
9742+#define FSACTL_ZERO_FIBTIMES 0xc3
9743+
9744+
9745+#define FSACTL_DELETE_DISK 0x163
9746+#define FSACTL_QUERY_DISK 0x173
9747+
9748+
9749+// AfaComm perfmon ioctls
9750+#define FSACTL_GET_COMM_PERF_DATA CTL_CODE(FILE_DEVICE_CONTROLLER, 2084, METHOD_BUFFERED, FILE_ANY_ACCESS)
9751+
9752+
9753+#define FSACTL_OPENCLS_COMM_PERF_DATA CTL_CODE(FILE_DEVICE_CONTROLLER, 2085, METHOD_BUFFERED, FILE_ANY_ACCESS)
9754+
9755+
9756+typedef struct _GET_ADAPTER_FIB_IOCTL {
9757+ char *AdapterFibContext;
9758+ int Wait;
9759+ char *AifFib;
9760+} GET_ADAPTER_FIB_IOCTL, *PGET_ADAPTER_FIB_IOCTL;
9761+
9762+//
9763+// filesystem ioctls
9764+//
9765+#define FSACTL_OPEN_GET_ADAPTER_FIB CTL_CODE(FILE_DEVICE_CONTROLLER, 2100, METHOD_BUFFERED, FILE_ANY_ACCESS)
9766+
9767+#define FSACTL_GET_NEXT_ADAPTER_FIB CTL_CODE(FILE_DEVICE_CONTROLLER, 2101, METHOD_BUFFERED, FILE_ANY_ACCESS)
9768+
9769+#define FSACTL_CLOSE_GET_ADAPTER_FIB CTL_CODE(FILE_DEVICE_CONTROLLER, 2102, METHOD_BUFFERED, FILE_ANY_ACCESS)
9770+
9771+#define FSACTL_OPEN_ADAPTER_CONFIG CTL_CODE(FILE_DEVICE_CONTROLLER, 2103, METHOD_NEITHER, FILE_ANY_ACCESS)
9772+
9773+#define FSACTL_CLOSE_ADAPTER_CONFIG CTL_CODE(FILE_DEVICE_CONTROLLER, 2104, METHOD_NEITHER, FILE_ANY_ACCESS)
9774+
9775+
9776+#define FSACTL_MINIPORT_REV_CHECK CTL_CODE(FILE_DEVICE_CONTROLLER, 2107, METHOD_BUFFERED, FILE_ANY_ACCESS)
9777+
9778+
9779+#define FSACTL_QUERY_ADAPTER_CONFIG CTL_CODE(FILE_DEVICE_CONTROLLER, 2113, METHOD_BUFFERED, FILE_ANY_ACCESS)
9780+
9781+
9782+#define FSACTL_FORCE_DELETE_DISK CTL_CODE(FILE_DEVICE_CONTROLLER, 2120, METHOD_NEITHER, FILE_ANY_ACCESS)
9783+
9784+
9785+#define FSACTL_AIF_THREAD CTL_CODE(FILE_DEVICE_CONTROLLER, 2127, METHOD_NEITHER, FILE_ANY_ACCESS)
9786+
9787+
9788+#endif // _FSAIOCTL_H_
9789+
9790+
9791diff -burN linux-2.4.7/drivers/scsi/aacraid/include/fsaport.h linux/drivers/scsi/aacraid/include/fsaport.h
9792--- linux-2.4.7/drivers/scsi/aacraid/include/fsaport.h Wed Dec 31 18:00:00 1969
9793+++ linux/drivers/scsi/aacraid/include/fsaport.h Sat Jul 21 17:55:13 2001
9794@@ -0,0 +1,223 @@
9795+/*++
9796+ * Adaptec aacraid device driver for Linux.
9797+ *
9798+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9799+ *
9800+ * This program is free software; you can redistribute it and/or modify
9801+ * it under the terms of the GNU General Public License as published by
9802+ * the Free Software Foundation; either version 2, or (at your option)
9803+ * any later version.
9804+ *
9805+ * This program is distributed in the hope that it will be useful,
9806+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9807+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9808+ * GNU General Public License for more details.
9809+ *
9810+ * You should have received a copy of the GNU General Public License
9811+ * along with this program; see the file COPYING. If not, write to
9812+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9813+ *
9814+ * Module Name:
9815+ * fsaport.h
9816+ *
9817+ * Abstract: This module defines all of the globally used procedures in the FSA
9818+ * file system.
9819+ *
9820+ *
9821+ *
9822+ --*/
9823+#ifndef _FSAPORT_
9824+#define _FSAPORT_
9825+
9826+static char *ident_fsaport = "aacraid_ident fsaport.h 1.0.6 2000/10/09 Adaptec, Inc.";
9827+
9828+//
9829+// The scatter/gather map context is the information we
9830+// we need to keep the map and transfer data to and from the
9831+// adapter.
9832+//
9833+
9834+typedef struct _SGMAP_CONTEXT {
9835+
9836+ caddr_t BaseAddress;
9837+ PVOID MapRegBase;
9838+ ULONG NumberMapRegs;
9839+ PSGMAP SgMapPtr;
9840+ ULONG ByteCount; // Used to check the Mdl length.
9841+ BOOLEAN WriteToDevice;
9842+
9843+ struct buf *bp;
9844+
9845+
9846+} SGMAP_CONTEXT;
9847+typedef SGMAP_CONTEXT *PSGMAP_CONTEXT;
9848+
9849+typedef struct _MAPFIB_CONTEXT {
9850+ PMDL Mdl;
9851+ PVOID MapRegBase;
9852+ ULONG NumberMapRegs;
9853+ PVOID FibVirtualAddress;
9854+ ULONG Size;
9855+ PVOID FibPhysicalAddress;
9856+
9857+
9858+} MAPFIB_CONTEXT;
9859+typedef MAPFIB_CONTEXT *PMAPFIB_CONTEXT;
9860+
9861+typedef BOOLEAN
9862+(*PFSA_ALLOCATE_ADAPTER_COMM_AREA)(
9863+ PVOID AdapterExtension,
9864+ IN OUT PVOID *BaseAddress,
9865+ IN ULONG Size,
9866+ IN ULONG Alignment
9867+ );
9868+
9869+typedef BOOLEAN
9870+(*PFSA_FREE_ADAPTER_COMM_AREA)(
9871+ PVOID AdapterExtension
9872+ );
9873+
9874+typedef VOID
9875+(*PFSA_FREE_DMA_RESOURCES)(
9876+ IN PVOID AdapterExtension,
9877+ IN PSGMAP_CONTEXT SgMapContext
9878+ );
9879+
9880+typedef BOOLEAN
9881+(*PFSA_ALLOCATE_AND_MAP_FIB_SPACE)(
9882+ IN PVOID AdapterExtension,
9883+ IN PMAPFIB_CONTEXT MapFibContext
9884+ );
9885+
9886+typedef BOOLEAN
9887+(*PFSA_UNMAP_AND_FREE_FIB_SPACE)(
9888+ IN PVOID AdapterExtension,
9889+ IN PMAPFIB_CONTEXT MapFibContext
9890+ );
9891+
9892+typedef VOID
9893+(*PFSA_INTERRUPT_ADAPTER)(
9894+ IN PVOID AdapterExtension
9895+ );
9896+
9897+typedef VOID
9898+(*PFSA_NOTIFY_ADAPTER)(
9899+ IN PVOID AdapterExtension,
9900+ IN HOST_2_ADAP_EVENT AdapterEvent
9901+ );
9902+
9903+typedef VOID
9904+(*PFSA_RESET_DEVICE)(
9905+ PVOID AdapterExtension
9906+ );
9907+
9908+typedef AAC_STATUS
9909+(*PFSA_BUILD_SGMAP)(
9910+ IN PVOID AdapterExtension,
9911+ IN PSGMAP_CONTEXT SgMapContext
9912+ );
9913+
9914+typedef PVOID
9915+(*PFSA_ADAPTER_ADDR_TO_SYSTEM_ADDR)(
9916+ IN PVOID AdapterExtension,
9917+ IN PVOID AdapterAddress
9918+ );
9919+
9920+typedef VOID
9921+(*PFSA_INTERRUPT_HOST)(
9922+ PVOID Adapter,
9923+ ADAPTER_EVENT AdapterEvent
9924+ );
9925+
9926+typedef VOID
9927+(*PFSA_ENABLE_INTERRUPT)(
9928+ PVOID Adapter,
9929+ ADAPTER_EVENT AdapterEvent,
9930+ BOOLEAN AtDeviceIrq
9931+ );
9932+
9933+
9934+typedef VOID
9935+(*PFSA_DISABLE_INTERRUPT)(
9936+ PVOID Adapter,
9937+ ADAPTER_EVENT AdapterEvent,
9938+ BOOLEAN AtDeviceIrq
9939+ );
9940+
9941+typedef AAC_STATUS
9942+(*PFSA_OPEN_ADAPTER) (
9943+ IN PVOID Adapter
9944+ );
9945+
9946+typedef int
9947+(*PFSA_DEVICE_CONTROL) (
9948+ IN PVOID Adapter,
9949+ IN PAFA_IOCTL_CMD IoctlCmdPtr
9950+ );
9951+
9952+typedef AAC_STATUS
9953+(*PFSA_CLOSE_ADAPTER) (
9954+ IN PVOID Adapter
9955+ );
9956+
9957+typedef BOOLEAN
9958+(*PFSA_SEND_SYNCH_FIB) (
9959+ IN PVOID Adapter,
9960+ IN ULONG FibPhysicalAddress
9961+ );
9962+
9963+typedef struct _FSAPORT_FUNCS {
9964+ ULONG SizeOfFsaPortFuncs;
9965+
9966+ PFSA_ALLOCATE_ADAPTER_COMM_AREA AllocateAdapterCommArea;
9967+ PFSA_FREE_ADAPTER_COMM_AREA FreeAdapterCommArea;
9968+ PFSA_FREE_DMA_RESOURCES FreeDmaResources;
9969+ PFSA_ALLOCATE_AND_MAP_FIB_SPACE AllocateAndMapFibSpace;
9970+ PFSA_UNMAP_AND_FREE_FIB_SPACE UnmapAndFreeFibSpace;
9971+ PFSA_INTERRUPT_ADAPTER InterruptAdapter;
9972+ PFSA_NOTIFY_ADAPTER NotifyAdapter;
9973+ PFSA_ENABLE_INTERRUPT EnableInterrupt;
9974+ PFSA_DISABLE_INTERRUPT DisableInterrupt;
9975+ PFSA_RESET_DEVICE ResetDevice;
9976+ PFSA_BUILD_SGMAP BuildSgMap;
9977+ PFSA_ADAPTER_ADDR_TO_SYSTEM_ADDR AdapterAddressToSystemAddress;
9978+
9979+ PFSA_INTERRUPT_HOST InterruptHost;
9980+ PFSA_OPEN_ADAPTER OpenAdapter;
9981+ PFSA_DEVICE_CONTROL DeviceControl;
9982+ PFSA_CLOSE_ADAPTER CloseAdapter;
9983+
9984+ PFSA_SEND_SYNCH_FIB SendSynchFib;
9985+
9986+} FSAPORT_FUNCS;
9987+typedef FSAPORT_FUNCS *PFSAPORT_FUNCS;
9988+
9989+typedef AAC_STATUS
9990+(*PFSA_SETVAR_CALLBACK) (
9991+ IN PVOID Adapter,
9992+ IN ULONG NewValue
9993+ );
9994+
9995+typedef struct _FSA_USER_VAR {
9996+ char Name[32];
9997+ ULONG *Address;
9998+ PFSA_SETVAR_CALLBACK SetVarCallback;
9999+} FSA_USER_VAR;
10000+
10001+typedef FSA_USER_VAR *PFSA_USER_VAR;
10002+
10003+typedef struct _FSA_NEW_ADAPTER {
10004+ PVOID AdapterExtension;
10005+ PFSAPORT_FUNCS AdapterFuncs;
10006+ PVOID Adapter;
10007+ BOOLEAN AdapterInterruptsBelowDpc;
10008+ PFSA_USER_VAR AdapterUserVars;
10009+ ULONG AdapterUserVarsSize;
10010+ void *Dip;
10011+} FSA_NEW_ADAPTER;
10012+typedef FSA_NEW_ADAPTER *PFSA_NEW_ADAPTER;
10013+
10014+#define FSAFS_GET_NEXT_ADAPTER CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 2048, METHOD_NEITHER, FILE_ANY_ACCESS)
10015+#define FSAFS_INIT_NEW_ADAPTER CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 2049, METHOD_NEITHER, FILE_ANY_ACCESS)
10016+
10017+#endif
10018diff -burN linux-2.4.7/drivers/scsi/aacraid/include/fsatypes.h linux/drivers/scsi/aacraid/include/fsatypes.h
10019--- linux-2.4.7/drivers/scsi/aacraid/include/fsatypes.h Wed Dec 31 18:00:00 1969
10020+++ linux/drivers/scsi/aacraid/include/fsatypes.h Sat Jul 21 17:55:13 2001
10021@@ -0,0 +1,214 @@
10022+/*++
10023+ * Adaptec aacraid device driver for Linux.
10024+ *
10025+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10026+ *
10027+ * This program is free software; you can redistribute it and/or modify
10028+ * it under the terms of the GNU General Public License as published by
10029+ * the Free Software Foundation; either version 2, or (at your option)
10030+ * any later version.
10031+ *
10032+ * This program is distributed in the hope that it will be useful,
10033+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10034+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10035+ * GNU General Public License for more details.
10036+ *
10037+ * You should have received a copy of the GNU General Public License
10038+ * along with this program; see the file COPYING. If not, write to
10039+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10040+ *
10041+ * Module Name:
10042+ * fsatypes.h
10043+ *
10044+ * Abstract: Define all shared data types here, ie, those
10045+ * types shared among several components, such
10046+ * as host (driver + apps), adapter, and BIOS.
10047+ *
10048+ *
10049+ --*/
10050+#ifndef _FSATYPES_H
10051+#define _FSATYPES_H
10052+
10053+static char *ident_fsatype = "aacraid_ident fsatypes.h 1.0.6 2000/10/09 Adaptec, Inc.";
10054+
10055+typedef AAC_UINT32 AAC_BOOLEAN;
10056+
10057+//
10058+// Define a 64-bit address structure for use on
10059+// a 32-bit processor architecture.
10060+//
10061+typedef struct {
10062+ AAC_UINT32 lo32;
10063+ AAC_UINT32 hi32;
10064+} AAC_UINT64S, *PAAC_UINT64S;
10065+
10066+
10067+
10068+//
10069+// Container Types
10070+//
10071+typedef struct {
10072+ AAC_UINT32 data[2]; // RMA FIX, make this a real serial number when we
10073+ // know what it looks like. Note, BIOS sees this
10074+ // definition and it must be coded in such a way
10075+ // that it appears to be 64 bits. ints are 16 bits
10076+ // in BIOS land; fortunately, longs are 32 bits.
10077+} SerialNumberT;
10078+
10079+
10080+
10081+//
10082+// ***********************
10083+// DON'T CHANGE THE ORDER, ctdevsw use this order to map the drivers
10084+// ***********************
10085+// drivers for CT_NONE to CT_PASSTHRU
10086+//
10087+typedef enum _FSAVOLTYPE {
10088+ CT_NONE = 0,
10089+ CT_VOLUME,
10090+ CT_MIRROR,
10091+ CT_STRIPE,
10092+ CT_RAID5,
10093+ CT_SSRW,
10094+ CT_SSRO,
10095+ CT_MORPH,
10096+ CT_PASSTHRU,
10097+ CT_RAID4,
10098+ CT_RAID10, // stripe of mirror
10099+ CT_RAID00, // stripe of stripe
10100+ CT_VOLUME_OF_MIRRORS, // volume of mirror
10101+ CT_PSEUDO_RAID3, // really raid4
10102+
10103+ CT_LAST_VOLUME_TYPE
10104+
10105+} _E_FSAVOLTYPE;
10106+
10107+#ifdef AAC_32BIT_ENUMS
10108+typedef _E_FSAVOLTYPE FSAVOLTYPE;
10109+#else
10110+typedef AAC_UINT32 FSAVOLTYPE;
10111+#endif
10112+
10113+
10114+//
10115+// Types of objects addressable in some fashion by the client.
10116+// This is a superset of those objects handled just by the filesystem
10117+// and includes "raw" objects that an administrator would use to
10118+// configure containers and filesystems.
10119+//
10120+typedef enum _FTYPE {
10121+ FT_REG = 1, // regular file
10122+ FT_DIR, // directory
10123+ FT_BLK, // "block" device - reserved
10124+ FT_CHR, // "character special" device - reserved
10125+ FT_LNK, // symbolic link
10126+ FT_SOCK, // socket
10127+ FT_FIFO, // fifo
10128+ FT_FILESYS, // ADAPTEC's "FSA"(tm) filesystem
10129+ FT_DRIVE, // physical disk - addressable in scsi by bus/target/lun
10130+ FT_SLICE, // virtual disk - raw volume - slice
10131+ FT_PARTITION, // FSA partition - carved out of a slice - building block for containers
10132+ FT_VOLUME, // Container - Volume Set
10133+ FT_STRIPE, // Container - Stripe Set
10134+ FT_MIRROR, // Container - Mirror Set
10135+ FT_RAID5, // Container - Raid 5 Set
10136+ FT_DATABASE // Storage object with "foreign" content manager
10137+} _E_FTYPE;
10138+
10139+#ifdef AAC_32BIT_ENUMS
10140+typedef _E_FTYPE FTYPE;
10141+#else
10142+typedef AAC_UINT32 FTYPE;
10143+#endif
10144+
10145+
10146+
10147+//
10148+// Host side memory scatter gather list
10149+// Used by the adapter for read, write, and readdirplus operations
10150+//
10151+typedef PAAC_UINT8 HOSTADDRESS;
10152+
10153+typedef struct _SGENTRY {
10154+ HOSTADDRESS SgAddress; /* 32-bit Base address. */
10155+ AAC_UINT32 SgByteCount; /* Length. */
10156+} SGENTRY;
10157+typedef SGENTRY *PSGENTRY;
10158+
10159+
10160+
10161+//
10162+// SGMAP
10163+//
10164+// This is the SGMAP structure for all commands that use
10165+// 32-bit addressing.
10166+//
10167+// Note that the upper 16 bits of SgCount are used as flags.
10168+// Only the lower 16 bits of SgCount are actually used as the
10169+// SG element count.
10170+//
10171+typedef struct _SGMAP {
10172+ AAC_UINT32 SgCount;
10173+ SGENTRY SgEntry[1];
10174+} SGMAP;
10175+typedef SGMAP *PSGMAP;
10176+
10177+
10178+
10179+//
10180+// SGMAP64
10181+//
10182+// This is the SGMAP structure for 64-bit container commands.
10183+//
10184+typedef struct _SGMAP64 {
10185+ AAC_UINT8 SgCount;
10186+ AAC_UINT8 SgSectorsPerPage;
10187+ AAC_UINT16 SgByteOffset; // For the first page
10188+ AAC_UINT64S SgEntry[1]; // Must be last entry
10189+} SGMAP64;
10190+typedef SGMAP64 *PSGMAP64;
10191+
10192+
10193+
10194+
10195+//
10196+// attempt at common time structure across host and adapter
10197+//
10198+typedef struct __TIME_T {
10199+
10200+ AAC_UINT32 tv_sec; /* seconds (maybe, depends upon host) */
10201+ AAC_UINT32 tv_usec; /* and nanoseconds (maybe, depends upon host)*/
10202+
10203+} TIME_T;
10204+typedef TIME_T *PTIME_T;
10205+
10206+#ifndef _TIME_T
10207+#define timespec __TIME_T
10208+#define ts_sec tv_sec
10209+#define ts_nsec tv_usec
10210+#endif
10211+
10212+
10213+
10214+
10215+typedef struct _ContainerCreationInfo
10216+{
10217+
10218+ AAC_UINT8 ViaBuildNumber; // e.g., 588
10219+ AAC_UINT8 MicroSecond; // e.g., 588
10220+ AAC_UINT8 Via; // e.g., 1 = FSU,
10221+ // 2 = API,
10222+ AAC_UINT8 YearsSince1900; // e.g., 1997 = 97
10223+ AAC_UINT32 Date; //
10224+ // unsigned Month :4; // 1 - 12
10225+ // unsigned Day :6; // 1 - 32
10226+ // unsigned Hour :6; // 0 - 23
10227+ // unsigned Minute :6; // 0 - 60
10228+ // unsigned Second :6; // 0 - 60
10229+ SerialNumberT ViaAdapterSerialNumber; // e.g., 0x1DEADB0BFAFAF001
10230+} ContainerCreationInfo;
10231+
10232+
10233+#endif // _FSATYPES_H
10234+
10235+
10236diff -burN linux-2.4.7/drivers/scsi/aacraid/include/linit.h linux/drivers/scsi/aacraid/include/linit.h
10237--- linux-2.4.7/drivers/scsi/aacraid/include/linit.h Wed Dec 31 18:00:00 1969
10238+++ linux/drivers/scsi/aacraid/include/linit.h Sat Jul 21 17:55:13 2001
10239@@ -0,0 +1,107 @@
10240+/*++
10241+ * Adaptec aacraid device driver for Linux.
10242+ *
10243+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10244+ *
10245+ * This program is free software; you can redistribute it and/or modify
10246+ * it under the terms of the GNU General Public License as published by
10247+ * the Free Software Foundation; either version 2, or (at your option)
10248+ * any later version.
10249+ *
10250+ * This program is distributed in the hope that it will be useful,
10251+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10252+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10253+ * GNU General Public License for more details.
10254+ *
10255+ * You should have received a copy of the GNU General Public License
10256+ * along with this program; see the file COPYING. If not, write to
10257+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10258+ *
10259+ * Module Name:
10260+ * linit.h
10261+ *
10262+ * Abstract: Header file for Linux Driver for Adaptec RAID Array Controller
10263+ *
10264+ --*/
10265+/*------------------------------------------------------------------------------
10266+ * I N C L U D E S
10267+ *----------------------------------------------------------------------------*/
10268+
10269+#ifndef _LINIT_H_
10270+#define _LINIT_H_
10271+
10272+static char *ident_linith = "aacraid_ident linit.h 1.0.6 2000/10/09 Adaptec, Inc.";
10273+
10274+#include <linux/config.h>
10275+
10276+/*------------------------------------------------------------------------------
10277+ * D E F I N E S
10278+ *----------------------------------------------------------------------------*/
10279+/* Define the AAC SCSI Host Template structure. */
10280+#define AAC_HOST_TEMPLATE_ENTRY \
10281+ { name: "AAC", /* Driver Name */ \
10282+ proc_info: AAC_ProcDirectoryInfo, /* ProcFS Info Func */ \
10283+ detect: AAC_DetectHostAdapter, /* Detect Host Adapter */ \
10284+ release: AAC_ReleaseHostAdapter, /* Release Host Adapter */ \
10285+ info: AAC_DriverInfo, /* Driver Info Function */ \
10286+ ioctl: AAC_Ioctl, /* ioctl Interface */ \
10287+ command: AAC_Command, /* unqueued command */ \
10288+ queuecommand: AAC_QueueCommand, /* Queue Command Function */ \
10289+ abort: AAC_AbortCommand, /* Abort Command Function */ \
10290+ reset: AAC_ResetCommand, /* Reset Command Function */ \
10291+ bios_param: AAC_BIOSDiskParameters, /* BIOS Disk Parameters */ \
10292+ can_queue: 1, /* Default initial value */ \
10293+ this_id: 0, /* Default initial value */ \
10294+ sg_tablesize: 0, /* Default initial value */ \
10295+ max_sectors: 128, /* max xfer size of 64k */ \
10296+ cmd_per_lun: 0, /* Default initial value */ \
10297+ present: 0, /* Default initial value */ \
10298+ unchecked_isa_dma: 0, /* Default Initial Value */ \
10299+ use_new_eh_code: 0, /* Default initial value */ \
10300+ eh_abort_handler: AAC_AbortCommand, /* New Abort Command func */ \
10301+ eh_strategy_handler: NULL, /* New Strategy Error Handler */ \
10302+ eh_device_reset_handler: NULL, /* New Device Reset Handler */ \
10303+ eh_bus_reset_handler: NULL, /* New Bus Reset Handler */ \
10304+ eh_host_reset_handler: NULL, /* New Host reset Handler */ \
10305+ use_clustering: ENABLE_CLUSTERING /* Disable Clustering */ \
10306+ }
10307+
10308+
10309+/*------------------------------------------------------------------------------
10310+ * T Y P E D E F S / S T R U C T S
10311+ *----------------------------------------------------------------------------*/
10312+typedef struct AAC_BIOS_DiskParameters
10313+{
10314+ int heads;
10315+ int sectors;
10316+ int cylinders;
10317+} AAC_BIOS_DiskParameters_T;
10318+
10319+
10320+/*------------------------------------------------------------------------------
10321+ * P R O G R A M G L O B A L S
10322+ *----------------------------------------------------------------------------*/
10323+
10324+const char *AAC_DriverInfo( struct Scsi_Host * );
10325+
10326+
10327+/*------------------------------------------------------------------------------
10328+ * F U N C T I O N P R O T O T Y P E S
10329+ *----------------------------------------------------------------------------*/
10330+/* Define prototypes for the AAC Driver Interface Functions. */
10331+int AAC_DetectHostAdapter( Scsi_Host_Template * );
10332+int AAC_ReleaseHostAdapter( struct Scsi_Host * );
10333+int AAC_QueueCommand( Scsi_Cmnd *, void ( *CompletionRoutine )( Scsi_Cmnd * ) );
10334+int AAC_Command( Scsi_Cmnd * );
10335+int AAC_ResetCommand( Scsi_Cmnd *, unsigned int );
10336+int AAC_BIOSDiskParameters( Disk *, kdev_t, int * );
10337+int AAC_ProcDirectoryInfo( char *, char **, off_t, int, int, int );
10338+int AAC_Ioctl( Scsi_Device *, int, void * );
10339+
10340+
10341+void AAC_SelectQueueDepths( struct Scsi_Host *, Scsi_Device * );
10342+
10343+
10344+int AAC_AbortCommand( Scsi_Cmnd *scsi_cmnd_ptr );
10345+
10346+#endif /* _LINIT_H_ */
10347diff -burN linux-2.4.7/drivers/scsi/aacraid/include/monkerapi.h linux/drivers/scsi/aacraid/include/monkerapi.h
10348--- linux-2.4.7/drivers/scsi/aacraid/include/monkerapi.h Wed Dec 31 18:00:00 1969
10349+++ linux/drivers/scsi/aacraid/include/monkerapi.h Sat Jul 21 17:55:13 2001
10350@@ -0,0 +1,98 @@
10351+/*++
10352+ * Adaptec aacraid device driver for Linux.
10353+ *
10354+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10355+ *
10356+ * This program is free software; you can redistribute it and/or modify
10357+ * it under the terms of the GNU General Public License as published by
10358+ * the Free Software Foundation; either version 2, or (at your option)
10359+ * any later version.
10360+ *
10361+ * This program is distributed in the hope that it will be useful,
10362+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10363+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10364+ * GNU General Public License for more details.
10365+ *
10366+ * You should have received a copy of the GNU General Public License
10367+ * along with this program; see the file COPYING. If not, write to
10368+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10369+ *
10370+ * Module Name:
10371+ * monkerapi.h
10372+ *
10373+ * Abstract: This module contains the definitions used by the Host Adapter
10374+ * Communications interface.
10375+ * This is the interface used for by host programs and the Adapter
10376+ * to communicate via synchronous commands via a shared set of registers
10377+ * on a platform (typically doorbells and mailboxes).
10378+ *
10379+ --*/
10380+//**********************************************************************
10381+//
10382+// Monitor / Kernel API
10383+//
10384+// 03/24/1998 Bob Peret Initial creation
10385+//
10386+//**********************************************************************
10387+
10388+#ifndef MONKER_H
10389+#define MONKER_H
10390+
10391+static char *ident_monk = "aacraid_ident monkerapi.h 1.0.6 2000/10/09 Adaptec, Inc.";
10392+
10393+#define BREAKPOINT_REQUEST 0x00000004
10394+#define INIT_STRUCT_BASE_ADDRESS 0x00000005
10395+
10396+
10397+#define SEND_SYNCHRONOUS_FIB 0x0000000c
10398+
10399+
10400+
10401+//
10402+// Adapter Status Register
10403+//
10404+// Phase Staus mailbox is 32bits:
10405+// <31:16> = Phase Status
10406+// <15:0> = Phase
10407+//
10408+// The adapter reports is present state through the phase. Only
10409+// a single phase should be ever be set. Each phase can have multiple
10410+// phase status bits to provide more detailed information about the
10411+// state of the board. Care should be taken to ensure that any phase status
10412+// bits that are set when changing the phase are also valid for the new phase
10413+// or be cleared out. Adapter software (monitor, iflash, kernel) is responsible
10414+// for properly maintining the phase status mailbox when it is running.
10415+
10416+//
10417+// MONKER_API Phases
10418+//
10419+// Phases are bit oriented. It is NOT valid
10420+// to have multiple bits set
10421+//
10422+
10423+
10424+#define SELF_TEST_FAILED 0x00000004
10425+
10426+
10427+#define KERNEL_UP_AND_RUNNING 0x00000080
10428+#define KERNEL_PANIC 0x00000100
10429+
10430+
10431+
10432+//
10433+// Doorbell bit defines
10434+//
10435+
10436+
10437+#define DoorBellPrintfDone (1<<5) // Host -> Adapter
10438+
10439+
10440+#define DoorBellAdapterNormCmdReady (1<<1) // Adapter -> Host
10441+#define DoorBellAdapterNormRespReady (1<<2) // Adapter -> Host
10442+#define DoorBellAdapterNormCmdNotFull (1<<3) // Adapter -> Host
10443+#define DoorBellAdapterNormRespNotFull (1<<4) // Adapter -> Host
10444+#define DoorBellPrintfReady (1<<5) // Adapter -> Host
10445+
10446+
10447+#endif // MONKER_H
10448+
10449diff -burN linux-2.4.7/drivers/scsi/aacraid/include/nodetype.h linux/drivers/scsi/aacraid/include/nodetype.h
10450--- linux-2.4.7/drivers/scsi/aacraid/include/nodetype.h Wed Dec 31 18:00:00 1969
10451+++ linux/drivers/scsi/aacraid/include/nodetype.h Sat Jul 21 17:55:13 2001
10452@@ -0,0 +1,67 @@
10453+/*++
10454+ * Adaptec aacraid device driver for Linux.
10455+ *
10456+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10457+ *
10458+ * This program is free software; you can redistribute it and/or modify
10459+ * it under the terms of the GNU General Public License as published by
10460+ * the Free Software Foundation; either version 2, or (at your option)
10461+ * any later version.
10462+ *
10463+ * This program is distributed in the hope that it will be useful,
10464+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10465+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10466+ * GNU General Public License for more details.
10467+ *
10468+ * You should have received a copy of the GNU General Public License
10469+ * along with this program; see the file COPYING. If not, write to
10470+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10471+ *
10472+ * Module Name:
10473+ * nodetype.h
10474+ *
10475+ * Abstract: This module defines all of the node type codes used in this development
10476+ * shell. Every major data structure in the file system is assigned a node
10477+ * type code that is. This code is the first CSHORT in the structure and is
10478+ * followed by a CSHORT containing the size, in bytes, of the structure.
10479+ *
10480+ --*/
10481+#ifndef _NODETYPE_
10482+#define _NODETYPE_
10483+
10484+static char *ident_node = "aacraid_ident nodetype.h 1.0.6 2000/10/09 Adaptec, Inc.";
10485+
10486+typedef CSHORT NODE_TYPE_CODE;
10487+
10488+
10489+#define FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT ((NODE_TYPE_CODE)0x030b)
10490+#define FSAFS_NTC_FIB_CONTEXT ((NODE_TYPE_CODE)0x030c)
10491+
10492+
10493+typedef CSHORT NODE_BYTE_SIZE;
10494+
10495+
10496+//
10497+// The following definitions are used to generate meaningful blue bugcheck
10498+// screens. On a bugcheck the file system can output 4 ulongs of useful
10499+// information. The first ulong will have encoded in it a source file id
10500+// (in the high word) and the line number of the bugcheck (in the low word).
10501+// The other values can be whatever the caller of the bugcheck routine deems
10502+// necessary.
10503+//
10504+// Each individual file that calls bugcheck needs to have defined at the
10505+// start of the file a constant called BugCheckFileId with one of the
10506+// FSAFS_BUG_CHECK_ values defined below and then use FsaBugCheck to bugcheck
10507+// the system.
10508+//
10509+
10510+
10511+#define FSAFS_BUG_CHECK_COMMSUP (0X001e0000)
10512+#define FSAFS_BUG_CHECK_DPCSUP (0X001f0000)
10513+
10514+
10515+#define FsaBugCheck(A,B,C) { cmn_err( CE_PANIC, "aacdisk: module %x, line %x, 0x%x, 0x%x, 0x%x ", BugCheckFileId, __LINE__, A, B, C); }
10516+
10517+
10518+#endif // _NODETYPE_
10519+
10520diff -burN linux-2.4.7/drivers/scsi/aacraid/include/nvramioctl.h linux/drivers/scsi/aacraid/include/nvramioctl.h
10521--- linux-2.4.7/drivers/scsi/aacraid/include/nvramioctl.h Wed Dec 31 18:00:00 1969
10522+++ linux/drivers/scsi/aacraid/include/nvramioctl.h Sat Jul 21 17:55:13 2001
10523@@ -0,0 +1,112 @@
10524+/*++
10525+ * Adaptec aacraid device driver for Linux.
10526+ *
10527+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10528+ *
10529+ * This program is free software; you can redistribute it and/or modify
10530+ * it under the terms of the GNU General Public License as published by
10531+ * the Free Software Foundation; either version 2, or (at your option)
10532+ * any later version.
10533+ *
10534+ * This program is distributed in the hope that it will be useful,
10535+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10536+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10537+ * GNU General Public License for more details.
10538+ *
10539+ * You should have received a copy of the GNU General Public License
10540+ * along with this program; see the file COPYING. If not, write to
10541+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10542+ *
10543+ * Module Name:
10544+ * nvramioctl.h
10545+ *
10546+ * Abstract: This file defines the data structures related to querying
10547+ * and controlling the FSA NVRAM/WriteCache subsystem via the NVRAMIOCTL FIB.
10548+ *
10549+ --*/
10550+#ifndef _NVRAMIOCTL_H_
10551+#define _NVRAMIOCTL_H_ 1
10552+
10553+static char *ident_nvram = "aacraid_ident nvramioctl.h 1.0.6 2000/10/09 Adaptec, Inc.";
10554+
10555+/*
10556+ * NVRAM/Write Cache subsystem states
10557+ */
10558+typedef enum _NVSTATUS {
10559+ NVSTATUS_DISABLED = 0, // present, clean, not being used
10560+ NVSTATUS_ENABLED, // present, possibly dirty, ready for use
10561+ NVSTATUS_ERROR, // present, dirty, contains dirty data
10562+ // for bad/missing device
10563+ NVSTATUS_BATTERY, // present, bad or low battery, may contain dirty data
10564+ // for bad/missing device
10565+ NVSTATUS_UNKNOWN // present?????
10566+} _E_NVSTATUS;
10567+
10568+#ifdef AAC_32BIT_ENUMS
10569+typedef _E_NVSTATUS NVSTATUS;
10570+#else
10571+typedef AAC_UINT32 NVSTATUS;
10572+#endif
10573+
10574+/*
10575+ * NVRAM/Write Cache subsystem battery component states
10576+ *
10577+ */
10578+//NB: this enum should be identical to battery_status in nvram.h
10579+// or else collapsed into one enum someday
10580+typedef enum _NVBATTSTATUS {
10581+ NVBATTSTATUS_NONE = 0, // battery has no power or is not present
10582+ NVBATTSTATUS_LOW, // battery is low on power
10583+ NVBATTSTATUS_OK, // battery is okay - normal operation possible only in this state
10584+ NVBATTSTATUS_RECONDITIONING // no battery present - reconditioning in process
10585+} _E_NVBATTSTATUS;
10586+
10587+#ifdef AAC_32BIT_ENUMS
10588+typedef _E_NVBATTSTATUS NVBATTSTATUS;
10589+#else
10590+typedef AAC_UINT32 NVBATTSTATUS;
10591+#endif
10592+
10593+/*
10594+ * battery transition type
10595+ */
10596+typedef enum _NVBATT_TRANSITION {
10597+ NVBATT_TRANSITION_NONE = 0, // battery now has no power or is not present
10598+ NVBATT_TRANSITION_LOW, // battery is now low on power
10599+ NVBATT_TRANSITION_OK // battery is now okay - normal operation possible only in this state
10600+} _E_NVBATT_TRANSITION;
10601+
10602+#ifdef AAC_32BIT_ENUMS
10603+typedef _E_NVBATT_TRANSITION NVBATT_TRANSITION;
10604+#else
10605+typedef AAC_UINT32 NVBATT_TRANSITION;
10606+#endif
10607+
10608+/*
10609+ * NVRAM Info structure returned for NVRAM_GetInfo call
10610+ */
10611+typedef struct _NVRAMDEVINFO {
10612+ AAC_UINT32 NV_Enabled; /* write caching enabled */
10613+ AAC_UINT32 NV_Error; /* device in error state */
10614+ AAC_UINT32 NV_NDirty; /* count of dirty NVRAM buffers */
10615+ AAC_UINT32 NV_NActive; /* count of NVRAM buffers being written */
10616+} NVRAMDEVINFO, *PNVRAMDEVINFO;
10617+
10618+typedef struct _NVRAMINFO {
10619+ NVSTATUS NV_Status; /* nvram subsystem status */
10620+ NVBATTSTATUS NV_BattStatus; /* battery status */
10621+ AAC_UINT32 NV_Size; /* size of WriteCache NVRAM in bytes */
10622+ AAC_UINT32 NV_BufSize; /* size of NVRAM buffers in bytes */
10623+ AAC_UINT32 NV_NBufs; /* number of NVRAM buffers */
10624+ AAC_UINT32 NV_NDirty; /* count of dirty NVRAM buffers */
10625+ AAC_UINT32 NV_NClean; /* count of clean NVRAM buffers */
10626+ AAC_UINT32 NV_NActive; /* count of NVRAM buffers being written */
10627+ AAC_UINT32 NV_NBrokered; /* count of brokered NVRAM buffers */
10628+ NVRAMDEVINFO NV_DevInfo[NFILESYS]; /* per device info */
10629+ AAC_UINT32 NV_BattNeedsReconditioning; /* boolean */
10630+ AAC_UINT32 NV_TotalSize; /* total size of all non-volatile memories in bytes */
10631+} NVRAMINFO, *PNVRAMINFO;
10632+
10633+#endif /* !_NVRAMIOCTL_H_ */
10634+
10635+
10636diff -burN linux-2.4.7/drivers/scsi/aacraid/include/osheaders.h linux/drivers/scsi/aacraid/include/osheaders.h
10637--- linux-2.4.7/drivers/scsi/aacraid/include/osheaders.h Wed Dec 31 18:00:00 1969
10638+++ linux/drivers/scsi/aacraid/include/osheaders.h Sat Jul 21 17:55:13 2001
10639@@ -0,0 +1,150 @@
10640+/*++
10641+ * Adaptec aacraid device driver for Linux.
10642+ *
10643+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10644+ *
10645+ * This program is free software; you can redistribute it and/or modify
10646+ * it under the terms of the GNU General Public License as published by
10647+ * the Free Software Foundation; either version 2, or (at your option)
10648+ * any later version.
10649+ *
10650+ * This program is distributed in the hope that it will be useful,
10651+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10652+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10653+ * GNU General Public License for more details.
10654+ *
10655+ * You should have received a copy of the GNU General Public License
10656+ * along with this program; see the file COPYING. If not, write to
10657+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10658+ *
10659+ * Module Name:
10660+ * osheaders.h
10661+ *
10662+ * Abstract: Holds all of the header file includes for a particular O/S flavor.
10663+ *
10664+ --*/
10665+#ifndef _OSHEADERS_H_
10666+#define _OSHEADERS_H_
10667+
10668+static char *ident_oshead = "aacraid_ident osheaders.h 1.0.6 2000/10/09 Adaptec, Inc.";
10669+
10670+#include <linux/autoconf.h> // retrieve the kernel configuration info
10671+#if defined( CONFIG_MODVERSIONS ) && !defined( MODVERSIONS )
10672+#define MODVERSIONS // force it on
10673+#endif
10674+
10675+#include <linux/version.h>
10676+
10677+#if defined( MODVERSIONS ) && defined( MODULE )
10678+#if DRIVER_KERNEL_CODE >= KERNEL_VERSION(2,2,12)
10679+#ifdef CONFIG_SMP
10680+#include <linux/modversions-smp.h>
10681+#elif defined( BOOT_DRIVER )
10682+#include <linux/modversions-BOOT.h>
10683+#else
10684+#include <linux/modversions-up.h>
10685+#endif // ifdef CONFIG_SMP
10686+#else
10687+#include <linux/modversions.h>
10688+#endif
10689+#endif
10690+
10691+
10692+#include <linux/kernel.h>
10693+#include <linux/config.h>
10694+#include <linux/init.h>
10695+#include <linux/types.h>
10696+#include <linux/blk.h>
10697+#include <linux/blkdev.h>
10698+#include <linux/delay.h>
10699+#include <linux/ioport.h>
10700+#include <linux/mm.h>
10701+#include <linux/sched.h>
10702+#include <linux/stat.h>
10703+#include <linux/pci.h>
10704+#include <linux/interrupt.h>
10705+#include <asm/dma.h>
10706+#include <asm/io.h>
10707+#include <linux/spinlock.h>
10708+#include <asm/system.h>
10709+#include <asm/bitops.h>
10710+#include <asm/uaccess.h>
10711+#include <linux/wait.h>
10712+#include <linux/malloc.h>
10713+#include <linux/tqueue.h>
10714+/* bmb fix
10715+#include <linux/tasks.h>
10716+*/
10717+#include <ostypes.h>
10718+#include "scsi.h"
10719+#include "hosts.h"
10720+
10721+#ifndef intptr_t
10722+#define intptr_t void *
10723+#endif
10724+
10725+#ifndef cred_t
10726+#define cred_t void
10727+#endif
10728+
10729+#ifndef paddr32_t
10730+#define paddr32_t unsigned
10731+#endif
10732+
10733+#ifndef bzero
10734+#define bzero(b,len) memset(b,0,len)
10735+#endif
10736+
10737+#ifndef bcopy
10738+#define bcopy(src,dst,len) memcpy(dst,src,len )
10739+#endif
10740+
10741+#ifndef DEVICE_NR
10742+#define DEVICE_NR(device) ( ( ( MAJOR( device ) & 7 ) << 4 ) + ( MINOR( device ) >> 4 ) )
10743+#endif
10744+
10745+typedef unsigned uint_t;
10746+
10747+typedef enum
10748+{
10749+ CE_PANIC = 0,
10750+ CE_WARN,
10751+ CE_NOTE,
10752+ CE_CONT,
10753+ CE_DEBUG,
10754+ CE_DEBUG2,
10755+ CE_TAIL
10756+} CE_ENUM_T;
10757+
10758+#define CMN_ERR_LEVEL CE_NOTE
10759+
10760+#ifndef IN
10761+#define IN
10762+#endif
10763+
10764+// usage of READ & WRITE as a typedefs in protocol.h
10765+// conflicts with <linux/fs.h> definition.
10766+#ifdef READ
10767+#undef READ
10768+#endif
10769+
10770+#ifdef WRITE
10771+#undef WRITE
10772+#endif
10773+
10774+typedef struct aac_options
10775+{
10776+ int message_level;
10777+ int reverse_scan;
10778+} aac_options_t;
10779+
10780+#endif // _OSHEADERS_H_
10781+
10782+
10783+
10784+
10785+
10786+
10787+
10788+
10789+
10790diff -burN linux-2.4.7/drivers/scsi/aacraid/include/ostypes.h linux/drivers/scsi/aacraid/include/ostypes.h
10791--- linux-2.4.7/drivers/scsi/aacraid/include/ostypes.h Wed Dec 31 18:00:00 1969
10792+++ linux/drivers/scsi/aacraid/include/ostypes.h Sat Jul 21 17:55:13 2001
10793@@ -0,0 +1,149 @@
10794+/*++
10795+ * Adaptec aacraid device driver for Linux.
10796+ *
10797+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10798+ *
10799+ * This program is free software; you can redistribute it and/or modify
10800+ * it under the terms of the GNU General Public License as published by
10801+ * the Free Software Foundation; either version 2, or (at your option)
10802+ * any later version.
10803+ *
10804+ * This program is distributed in the hope that it will be useful,
10805+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10806+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10807+ * GNU General Public License for more details.
10808+ *
10809+ * You should have received a copy of the GNU General Public License
10810+ * along with this program; see the file COPYING. If not, write to
10811+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10812+ *
10813+ * Module Name:
10814+ * ostypes.h
10815+ *
10816+ * Abstract: Holds all of the O/S specific types.
10817+ *
10818+ --*/
10819+/*------------------------------------------------------------------------------
10820+ * D E F I N E S
10821+ *----------------------------------------------------------------------------*/
10822+#ifndef _OSTYPES_H_
10823+#define _OSTYPES_H_
10824+
10825+static char *ident_ostypes = "aacraid_ident ostypes.h 1.0.7 2000/10/11 Adaptec, Inc.";
10826+
10827+#include <linux/types.h>
10828+
10829+#define MAXIMUM_NUM_CONTAINERS 64 // 4 Luns * 16 Targets
10830+#define MAXIMUM_NUM_ADAPTERS 8
10831+
10832+#define OS_ALLOC_MEM_SLEEP GFP_KERNEL
10833+
10834+#define Os_remove_softintr OsSoftInterruptRemove
10835+#define OsPrintf printk
10836+#define FsaCommPrint
10837+
10838+// the return values for copy_from_user & copy_to_user is the
10839+// number of bytes not transferred. Thus if an internal error
10840+// occurs, the return value is greater than zero.
10841+#define COPYIN(SRC,DST,COUNT,FLAGS) copy_from_user(DST,SRC,COUNT)
10842+#define COPYOUT(SRC,DST,COUNT,FLAGS) copy_to_user(DST,SRC,COUNT)
10843+
10844+#define copyin(SRC,DST,COUNT) copy_from_user(DST,SRC,COUNT)
10845+#define copyout(SRC,DST,COUNT) copy_to_user(DST,SRC,COUNT)
10846+
10847+/*------------------------------------------------------------------------------
10848+ * S T R U C T S / T Y P E D E F S
10849+ *----------------------------------------------------------------------------*/
10850+typedef struct OS_MUTEX
10851+{
10852+ unsigned long lock_var;
10853+ wait_queue_head_t wq;
10854+ unsigned owner;
10855+} OS_MUTEX;
10856+
10857+typedef struct OS_SPINLOCK
10858+{
10859+ spinlock_t spin_lock;
10860+ unsigned cpu_lock_count[NR_CPUS];
10861+ unsigned long cpu_flags[NR_CPUS];
10862+ long lockout_count;
10863+} OS_SPINLOCK;
10864+
10865+#ifdef CVLOCK_USE_SPINLOCK
10866+ typedef OS_SPINLOCK OS_CVLOCK;
10867+#else
10868+ typedef OS_MUTEX OS_CVLOCK;
10869+#endif
10870+
10871+typedef size_t OS_SIZE_T;
10872+
10873+typedef struct OS_CV_T
10874+{
10875+ unsigned long lock_var;
10876+ unsigned long type;
10877+ wait_queue_head_t wq;
10878+} OS_CV_T;
10879+
10880+struct fsa_scsi_hba {
10881+ void *CommonExtension;
10882+ unsigned long ContainerSize[MAXIMUM_NUM_CONTAINERS];
10883+ unsigned long ContainerType[MAXIMUM_NUM_CONTAINERS];
10884+ unsigned char ContainerValid[MAXIMUM_NUM_CONTAINERS];
10885+ unsigned char ContainerReadOnly[MAXIMUM_NUM_CONTAINERS];
10886+ unsigned char ContainerLocked[MAXIMUM_NUM_CONTAINERS];
10887+ unsigned char ContainerDeleted[MAXIMUM_NUM_CONTAINERS];
10888+ long ContainerDevNo[MAXIMUM_NUM_CONTAINERS];
10889+};
10890+
10891+typedef struct fsa_scsi_hba fsadev_t;
10892+
10893+typedef struct OsKI
10894+{
10895+ struct Scsi_Host *scsi_host_ptr;
10896+ void * dip; // #REVISIT#
10897+ fsadev_t fsa_dev;
10898+ int thread_pid;
10899+ int MiniPortIndex;
10900+} OsKI_t;
10901+
10902+#define dev_info_t fsadev_t
10903+
10904+typedef int OS_SPINLOCK_COOKIE;
10905+
10906+typedef unsigned int OS_STATUS;
10907+
10908+typedef struct tq_struct OS_SOFTINTR;
10909+
10910+typedef OS_SOFTINTR *ddi_softintr_t;
10911+
10912+
10913+
10914+//-----------------------------------------------------------------------------
10915+// Conditional variable functions
10916+
10917+void OsCv_init (
10918+ OS_CV_T *cv_ptr );
10919+
10920+
10921+//-----------------------------------------------------------------------------
10922+// Printing functions
10923+void printk_err(int flag, char *fmt, ...);
10924+
10925+#define cmn_err printk_err
10926+
10927+
10928+//
10929+// just ignore these solaris ddi functions in the code
10930+//
10931+#define DDI_SUCCESS 0
10932+
10933+#define ddi_add_softintr(A,B,C,D,E,F,G) OsSoftInterruptAdd(C,F,G)
10934+
10935+//#REVIEW#
10936+#define ddi_remove_softintr(A) 0
10937+#define ddi_get_soft_iblock_cookie(A, B, C) 0
10938+
10939+#define ASSERT(expr) ((void) 0)
10940+#define drv_usecwait udelay
10941+
10942+#endif // _OSTYPES_H_
10943diff -burN linux-2.4.7/drivers/scsi/aacraid/include/pcisup.h linux/drivers/scsi/aacraid/include/pcisup.h
10944--- linux-2.4.7/drivers/scsi/aacraid/include/pcisup.h Wed Dec 31 18:00:00 1969
10945+++ linux/drivers/scsi/aacraid/include/pcisup.h Sat Jul 21 17:55:13 2001
10946@@ -0,0 +1,97 @@
10947+/*++
10948+ * Adaptec aacraid device driver for Linux.
10949+ *
10950+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10951+ *
10952+ * This program is free software; you can redistribute it and/or modify
10953+ * it under the terms of the GNU General Public License as published by
10954+ * the Free Software Foundation; either version 2, or (at your option)
10955+ * any later version.
10956+ *
10957+ * This program is distributed in the hope that it will be useful,
10958+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10959+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10960+ * GNU General Public License for more details.
10961+ *
10962+ * You should have received a copy of the GNU General Public License
10963+ * along with this program; see the file COPYING. If not, write to
10964+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10965+ *
10966+ * Module Name:
10967+ * pcisup.h
10968+ *
10969+ * Abstract: This module defines functions that are defined in PciSup.c
10970+ *
10971+ --*/
10972+#ifndef _PCISUP_
10973+#define _PCISUP_
10974+
10975+static char *ident_pcisup = "aacraid_ident pcisup.h 1.0.6 2000/10/09 Adaptec, Inc.";
10976+
10977+
10978+/*
10979+ * define which interrupt handler needs to be installed
10980+ */
10981+
10982+#define SaISR 1
10983+#define RxISR 2
10984+
10985+typedef struct _PCI_MINIPORT_COMMON_EXTENSION {
10986+ ULONG AdapterNumber; // Which FSA# this miniport is
10987+
10988+ ULONG PciBusNumber; // Which PCI bus we are located on
10989+ ULONG PciSlotNumber; // Whiat PCI slot we are in
10990+
10991+ PVOID Adapter; // Back pointer to Fsa adapter object
10992+ ULONG AdapterIndex; // Index into PlxAdapterTypes array
10993+ PDEVICE_OBJECT DeviceObject; // Pointer to our device object
10994+
10995+ FSAPORT_FUNCS AdapterFuncs;
10996+ ULONG FilesystemRevision; // Main driver's revision number
10997+
10998+
10999+ PADAPTER_INIT_STRUCT InitStruct; // Holds initialization info to communicate with adapter
11000+ PVOID PhysicalInitStruct; // Holds physical address of the init struct
11001+
11002+
11003+ PVOID PrintfBufferAddress; // pointer to buffer used for printf's from the adapter
11004+
11005+ BOOLEAN AdapterPrintfsToScreen;
11006+ BOOLEAN AdapterConfigured; // set to true when we know adapter can take FIBs
11007+
11008+ void * MiniPort;
11009+
11010+ caddr_t CommAddress; // Base address of Comm area
11011+ paddr32_t CommPhysAddr; // Physical Address of Comm area
11012+ size_t CommSize;
11013+
11014+ OsKI_t OsDep; // OS dependent kernel interfaces
11015+
11016+
11017+} PCI_MINIPORT_COMMON_EXTENSION;
11018+
11019+typedef PCI_MINIPORT_COMMON_EXTENSION *PPCI_MINIPORT_COMMON_EXTENSION;
11020+
11021+typedef int
11022+(*PFSA_MINIPORT_INIT) (
11023+ IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
11024+ IN ULONG AdapterNumber,
11025+ IN ULONG PciBus,
11026+ IN ULONG PciSlot
11027+ );
11028+
11029+typedef struct _FSA_MINIPORT {
11030+ USHORT VendorId;
11031+ USHORT DeviceId;
11032+ USHORT SubVendorId;
11033+ USHORT SubSystemId;
11034+ PCHAR DevicePrefix;
11035+ PFSA_MINIPORT_INIT InitRoutine;
11036+ PCHAR DeviceName;
11037+ PCHAR Vendor;
11038+ PCHAR Model;
11039+} FSA_MINIPORT;
11040+typedef FSA_MINIPORT *PFSA_MINIPORT;
11041+
11042+
11043+#endif // _PCISUP_
11044diff -burN linux-2.4.7/drivers/scsi/aacraid/include/perfpack.h linux/drivers/scsi/aacraid/include/perfpack.h
11045--- linux-2.4.7/drivers/scsi/aacraid/include/perfpack.h Wed Dec 31 18:00:00 1969
11046+++ linux/drivers/scsi/aacraid/include/perfpack.h Sat Jul 21 17:55:13 2001
11047@@ -0,0 +1,110 @@
11048+/*++
11049+ * Adaptec aacraid device driver for Linux.
11050+ *
11051+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11052+ *
11053+ * This program is free software; you can redistribute it and/or modify
11054+ * it under the terms of the GNU General Public License as published by
11055+ * the Free Software Foundation; either version 2, or (at your option)
11056+ * any later version.
11057+ *
11058+ * This program is distributed in the hope that it will be useful,
11059+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11060+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11061+ * GNU General Public License for more details.
11062+ *
11063+ * You should have received a copy of the GNU General Public License
11064+ * along with this program; see the file COPYING. If not, write to
11065+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11066+ *
11067+ * Module Name:
11068+ * perfpack.h
11069+ *
11070+ * Abstract: This file defines the layout of the performance data that is passed
11071+ * back from the FSA filesystem driver.
11072+ *
11073+ *
11074+ --*/
11075+
11076+#ifndef _FSA_PERFPACK_H_
11077+#define _FSA_PERFPACK_H_ 1
11078+
11079+static char *ident_perf = "aacraid_ident perfpack.h 1.0.6 2000/10/09 Adaptec, Inc.";
11080+
11081+//#define FSA_DO_PERF 1 /* enable the engineering counters */
11082+
11083+#ifdef FSA_DO_PERF
11084+//
11085+// engineering counters
11086+//
11087+typedef struct _FSA_PERF_DATA {
11088+ ULONG FibsSent;
11089+ ULONG ReadDirs;
11090+ ULONG GetAttrs;
11091+ ULONG SetAttrs;
11092+ ULONG Lookups;
11093+ ULONG ReadFibs;
11094+ ULONG WriteFibs;
11095+ ULONG CreateFibs;
11096+ ULONG MakeDirs;
11097+ ULONG RemoveFibs;
11098+ ULONG RemoveDirs;
11099+ ULONG RenameFibs;
11100+ ULONG ReadDirPlus;
11101+ ULONG FsStat;
11102+ ULONG WriteBytes;
11103+ ULONG ReadBytes;
11104+// NT FSA entry points
11105+ ULONG FsaFsdCreateCount;
11106+ ULONG FsaFsdCloseCount;
11107+ ULONG FsaFsdReadCount;
11108+ ULONG FsaFsdWriteCount;
11109+ ULONG FsaFsdQueryInformationCount;
11110+
11111+ struct _FsaFsdSetInfomation{
11112+ ULONG FsaSetAllocationInfoCount;
11113+ ULONG FsaSetBasicInfoCount;
11114+ ULONG FsaSetDispositionInfoCount;
11115+ ULONG FsaSetEndOfFileInfoCount;
11116+ ULONG FsaSetPositionInfoCount;
11117+ ULONG FsaSetRenameInfoCount;
11118+ ULONG FsaClearArchiveBitCount;
11119+ };
11120+
11121+ ULONG FsaFsdFlushBuffersCount;
11122+ ULONG FsaFsdQueryVolumeInfoCount;
11123+ ULONG FsaFsdSetVolumeInfoCount;
11124+ ULONG FsaFsdCleanupCount;
11125+ ULONG FsaFsdDirectoryControlCount;
11126+ ULONG FsaFsdFileSystemControlCount;
11127+ ULONG FsaFsdLockControlCount;
11128+ ULONG FsaFsdDeviceControlCount;
11129+ ULONG FsaFsdShutdownCount;
11130+ ULONG FsaFsdQuerySecurityInfo;
11131+ ULONG FsaFsdSetSecurityInfo;
11132+ ULONG FastIoCheckIfPossibleCount;
11133+ ULONG FastIoReadCount;
11134+ ULONG FastIoWriteCount;
11135+ ULONG FastIoQueryBasicInfoCount;
11136+ ULONG FastIoQueryStandardInfoCount;
11137+ ULONG FastIoLockCount;
11138+ ULONG FastIoUnlockSingleCount;
11139+ ULONG FastIoUnlockAllCount;
11140+ ULONG FastIoUnlockAllByKeyCount;
11141+ ULONG FastIoDeviceControlCount;
11142+ } FSA_PERF_DATA;
11143+
11144+typedef FSA_PERF_DATA *PFSA_PERF_DATA;
11145+
11146+
11147+#else /* FSA_DO_PERF */
11148+
11149+//
11150+// engineering performance counters are disabled
11151+//
11152+#define FSA_DO_PERF_INC(Counter) /* */
11153+#define FSA_DO_FSP_PERF_INC(Counter) /* */
11154+
11155+#endif /* FSA_DO_PERF */
11156+
11157+#endif // _FSA_PERFPACK_H_
11158diff -burN linux-2.4.7/drivers/scsi/aacraid/include/port.h linux/drivers/scsi/aacraid/include/port.h
11159--- linux-2.4.7/drivers/scsi/aacraid/include/port.h Wed Dec 31 18:00:00 1969
11160+++ linux/drivers/scsi/aacraid/include/port.h Sat Jul 21 17:55:13 2001
11161@@ -0,0 +1,87 @@
11162+/*++
11163+ * Adaptec aacraid device driver for Linux.
11164+ *
11165+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11166+ *
11167+ * This program is free software; you can redistribute it and/or modify
11168+ * it under the terms of the GNU General Public License as published by
11169+ * the Free Software Foundation; either version 2, or (at your option)
11170+ * any later version.
11171+ *
11172+ * This program is distributed in the hope that it will be useful,
11173+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11174+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11175+ * GNU General Public License for more details.
11176+ *
11177+ * You should have received a copy of the GNU General Public License
11178+ * along with this program; see the file COPYING. If not, write to
11179+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11180+ *
11181+ * Module Name:
11182+ * port.h
11183+ *
11184+ * Abstract: This module defines functions and structures that are in common among all miniports
11185+ *
11186+ *
11187+ --*/
11188+
11189+#ifndef _PORT_
11190+#define _PORT_
11191+
11192+static char *ident_porth = "aacraid_ident port.h 1.0.6 2000/10/09 Adaptec, Inc.";
11193+
11194+#ifdef DBG
11195+#define AfaPortPrint if (AfaPortPrinting) DbgPrint
11196+extern int AfaPortPrinting;
11197+#else
11198+#define AfaPortPrint
11199+#endif DBG
11200+
11201+extern int AfaPortPrinting;
11202+
11203+
11204+BOOLEAN
11205+AfaPortAllocateAdapterCommArea(
11206+ IN PVOID Arg1,
11207+ IN OUT PVOID *CommHeaderAddress,
11208+ IN ULONG CommAreaSize,
11209+ IN ULONG CommAreaAlignment
11210+ );
11211+
11212+
11213+BOOLEAN
11214+AfaPortFreeAdapterCommArea(
11215+ IN PVOID Arg1
11216+ );
11217+
11218+
11219+AAC_STATUS
11220+AfaPortBuildSgMap(
11221+ PVOID Arg1,
11222+ IN PSGMAP_CONTEXT SgMapContext
11223+ );
11224+
11225+
11226+VOID
11227+AfaPortFreeDmaResources(
11228+ PVOID Arg1,
11229+ IN PSGMAP_CONTEXT SgMapContext
11230+ );
11231+
11232+
11233+BOOLEAN
11234+AfaPortAllocateAndMapFibSpace(
11235+ PVOID Arg1,
11236+ IN PMAPFIB_CONTEXT MapFibContext
11237+ );
11238+
11239+
11240+BOOLEAN
11241+AfaPortUnmapAndFreeFibSpace(
11242+ PVOID Arg1,
11243+ IN PMAPFIB_CONTEXT MapFibContext
11244+ );
11245+
11246+
11247+#endif // _PORT_
11248+
11249diff -burN linux-2.4.7/drivers/scsi/aacraid/include/protocol.h linux/drivers/scsi/aacraid/include/protocol.h
11250--- linux-2.4.7/drivers/scsi/aacraid/include/protocol.h Wed Dec 31 18:00:00 1969
11251+++ linux/drivers/scsi/aacraid/include/protocol.h Sat Jul 21 17:55:13 2001
11252@@ -0,0 +1,249 @@
11253+/*++
11254+ * Adaptec aacraid device driver for Linux.
11255+ *
11256+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11257+ *
11258+ * This program is free software; you can redistribute it and/or modify
11259+ * it under the terms of the GNU General Public License as published by
11260+ * the Free Software Foundation; either version 2, or (at your option)
11261+ * any later version.
11262+ *
11263+ * This program is distributed in the hope that it will be useful,
11264+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11265+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11266+ * GNU General Public License for more details.
11267+ *
11268+ * You should have received a copy of the GNU General Public License
11269+ * along with this program; see the file COPYING. If not, write to
11270+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11271+ *
11272+ * Module Name:
11273+ * protocol.h
11274+ *
11275+ * Abstract: Defines the commands and command data which enables the nt
11276+ * filesystem driver to be the client of the fsa adapter
11277+ * filesystem. This protocol is largely modeled after the NFS
11278+ * V3 protocol with modifications allowed due to the unique
11279+ * client/server model FSA works under.
11280+ *
11281+ *
11282+ *
11283+ --*/
11284+
11285+#ifndef _PROTOCOL_H_
11286+#define _PROTOCOL_H_
11287+
11288+static char *ident_protocol = "aacraid_ident protocol.h 1.0.6 2000/10/09 Adaptec, Inc.";
11289+
11290+#include <fsafs.h> // definition of FSAFID; includes fsatypes.h
11291+#include <nvramioctl.h> // for NVRAMINFO definition
11292+
11293+// #define MDL_READ_WRITE
11294+
11295+//
11296+// Define the command values
11297+//
11298+typedef enum _FSA_COMMANDS {
11299+ Null = 0,
11300+ GetAttributes,
11301+ SetAttributes,
11302+ Lookup,
11303+ ReadLink,
11304+ Read,
11305+ Write,
11306+ Create,
11307+ MakeDirectory,
11308+ SymbolicLink,
11309+ MakeNode,
11310+ Removex,
11311+ RemoveDirectoryx, // bkpfix added x to this because already defined in nt
11312+ Rename,
11313+ Link,
11314+ ReadDirectory,
11315+ ReadDirectoryPlus,
11316+ FileSystemStatus,
11317+ FileSystemInfo,
11318+ PathConfigure,
11319+ Commit,
11320+ Mount,
11321+ UnMount,
11322+ Newfs,
11323+ FsCheck,
11324+ FsSync,
11325+ SimReadWrite,
11326+ SetFileSystemStatus,
11327+ BlockRead,
11328+ BlockWrite,
11329+ NvramIoctl,
11330+ FsSyncWait,
11331+ ClearArchiveBit,
11332+#ifdef MDL_READ_WRITE
11333+ MdlReadComplete,
11334+ MdlWriteComplete,
11335+ MdlRead, // these are used solely for stats, Mdl really controlled by
11336+ MdlWrite, // flags field in Fib.
11337+#endif
11338+ SetAcl,
11339+ GetAcl,
11340+ AssignAcl,
11341+ FaultInsertion, // Fault Insertion Command
11342+ CrazyCache, // crazycache
11343+ MAX_FSACOMMAND_NUM //CJ: used for sizing stats array - leave last
11344+} _E_FSACOMMAND;
11345+
11346+#ifdef AAC_32BIT_ENUMS
11347+typedef _E_FSACOMMAND FSACOMMAND;
11348+#else
11349+typedef AAC_UINT32 FSACOMMAND;
11350+#endif
11351+
11352+
11353+
11354+//
11355+// Define the status returns
11356+//
11357+// See include\comm\errno.h for adapter kernel errno's
11358+typedef enum _FSASTATUS {
11359+ ST_OK = 0,
11360+ ST_PERM = 1,
11361+ ST_NOENT = 2,
11362+ ST_IO = 5,
11363+ ST_NXIO = 6,
11364+ ST_E2BIG = 7,
11365+ ST_ACCES = 13,
11366+ ST_EXIST = 17,
11367+ ST_XDEV = 18,
11368+ ST_NODEV = 19,
11369+ ST_NOTDIR = 20,
11370+ ST_ISDIR = 21,
11371+ ST_INVAL = 22,
11372+ ST_FBIG = 27,
11373+ ST_NOSPC = 28,
11374+ ST_ROFS = 30,
11375+ ST_MLINK = 31,
11376+ ST_WOULDBLOCK = 35,
11377+ ST_NAMETOOLONG = 63,
11378+ ST_NOTEMPTY = 66,
11379+ ST_DQUOT = 69,
11380+ ST_STALE = 70,
11381+ ST_REMOTE = 71,
11382+ ST_BADHANDLE = 10001,
11383+ ST_NOT_SYNC = 10002,
11384+ ST_BAD_COOKIE = 10003,
11385+ ST_NOTSUPP = 10004,
11386+ ST_TOOSMALL = 10005,
11387+ ST_SERVERFAULT = 10006,
11388+ ST_BADTYPE = 10007,
11389+ ST_JUKEBOX = 10008,
11390+ ST_NOTMOUNTED = 10009,
11391+ ST_MAINTMODE = 10010,
11392+ ST_STALEACL = 10011
11393+} _E_FSASTATUS;
11394+
11395+#ifdef AAC_32BIT_ENUMS
11396+typedef _E_FSASTATUS FSASTATUS;
11397+#else
11398+typedef AAC_UINT32 FSASTATUS;
11399+#endif
11400+
11401+//
11402+// On writes how does the client want the data written.
11403+//
11404+
11405+typedef enum _CACHELEVEL {
11406+ CSTABLE = 1,
11407+ CUNSTABLE
11408+} _E_CACHELEVEL;
11409+
11410+#ifdef AAC_32BIT_ENUMS
11411+typedef _E_CACHELEVEL CACHELEVEL;
11412+#else
11413+typedef AAC_UINT32 CACHELEVEL;
11414+#endif
11415+
11416+//
11417+// Lets the client know at which level the data was commited on a write request
11418+//
11419+
11420+typedef enum _COMMITLEVEL {
11421+ CMFILE_SYNCH_NVRAM = 1,
11422+ CMDATA_SYNCH_NVRAM,
11423+ CMFILE_SYNCH,
11424+ CMDATA_SYNCH,
11425+ CMUNSTABLE
11426+} _E_COMMITLEVEL;
11427+
11428+#ifdef AAC_32BIT_ENUMS
11429+typedef _E_COMMITLEVEL COMMITLEVEL;
11430+#else
11431+typedef AAC_UINT32 COMMITLEVEL;
11432+#endif
11433+
11434+
11435+
11436+//
11437+// The following are all the different commands or FIBs which can be sent to the
11438+// FSA filesystem. We will define a required subset which cannot return STATUS_NOT_IMPLEMENTED,
11439+// but others outside that subset are allowed to return not implemented. The client is then
11440+// responsible for dealing with the fact it is not implemented.
11441+//
11442+typedef AAC_INT8 FSASTRING[16];
11443+
11444+
11445+typedef AAC_UINT32 BYTECOUNT; // only 32 bit-ism
11446+
11447+
11448+
11449+//
11450+// BlockRead
11451+//
11452+
11453+typedef struct _BLOCKREAD { // variable size struct
11454+
11455+ FSACOMMAND Command;
11456+ AAC_UINT32 ContainerId;
11457+ BYTECOUNT BlockNumber;
11458+ BYTECOUNT ByteCount;
11459+ SGMAP SgMap; // Must be last in struct because it is variable
11460+
11461+} BLOCKREAD;
11462+typedef BLOCKREAD *PBLOCKREAD;
11463+
11464+typedef struct _BLOCKREADRESPONSE {
11465+
11466+ FSASTATUS Status;
11467+ BYTECOUNT ByteCount;
11468+
11469+} BLOCKREADRESPONSE;
11470+typedef BLOCKREADRESPONSE *PBLOCKREADRESPONSE;
11471+
11472+//
11473+// BlockWrite
11474+//
11475+
11476+typedef struct _BLOCKWRITE { // variable size struct
11477+
11478+ FSACOMMAND Command;
11479+ AAC_UINT32 ContainerId;
11480+ BYTECOUNT BlockNumber;
11481+ BYTECOUNT ByteCount;
11482+ CACHELEVEL Stable;
11483+ SGMAP SgMap; // Must be last in struct because it is variable
11484+
11485+} BLOCKWRITE;
11486+typedef BLOCKWRITE *PBLOCKWRITE;
11487+
11488+
11489+typedef struct _BLOCKWRITERESPONSE {
11490+
11491+ FSASTATUS Status;
11492+ BYTECOUNT ByteCount;
11493+ COMMITLEVEL Committed;
11494+
11495+} BLOCKWRITERESPONSE;
11496+typedef BLOCKWRITERESPONSE *PBLOCKWRITERESPONSE;
11497+
11498+
11499+
11500+#endif // _PROTOCOL_H_
11501+
11502diff -burN linux-2.4.7/drivers/scsi/aacraid/include/revision.h linux/drivers/scsi/aacraid/include/revision.h
11503--- linux-2.4.7/drivers/scsi/aacraid/include/revision.h Wed Dec 31 18:00:00 1969
11504+++ linux/drivers/scsi/aacraid/include/revision.h Sat Jul 21 17:55:13 2001
11505@@ -0,0 +1,350 @@
11506+/*++
11507+ * Adaptec aacraid device driver for Linux.
11508+ *
11509+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11510+ *
11511+ * This program is free software; you can redistribute it and/or modify
11512+ * it under the terms of the GNU General Public License as published by
11513+ * the Free Software Foundation; either version 2, or (at your option)
11514+ * any later version.
11515+ *
11516+ * This program is distributed in the hope that it will be useful,
11517+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11518+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11519+ * GNU General Public License for more details.
11520+ *
11521+ * You should have received a copy of the GNU General Public License
11522+ * along with this program; see the file COPYING. If not, write to
11523+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11524+ *
11525+ * Module Name:
11526+ * revision.h
11527+ *
11528+ * Abstract: This module contains all of the revision information for
11529+ * the FSA product, as well as the support routines for
11530+ * checking module compatibility.
11531+ *
11532+ * Before editing anything in this module, make sure that
11533+ * you read the comments. Some lines are changed automatically
11534+ * as part of the build, and should never be changed by hand.
11535+ *
11536+ * Routines (all inlines):
11537+ *
11538+ * RevGetBuildNumber - Retrieve current build number
11539+ * RevGetExternalRev - Retrieve revision for external use
11540+ * RevGetFullRevision - Retrieve full revision structure
11541+ *
11542+ * RevCheckCompatibility - Checks compatibility base on internal table
11543+ *
11544+ * RevCheckCompatibilityFullInfo - Check for static component
11545+ * RevGetCompInfoTableSize - Get size for static component table
11546+ * RevGetCompInfoTable - Get actual table to place on static component
11547+ * RevGetBuildNumberFromInfo - Get build number for static component.
11548+ *
11549+ *
11550+ *
11551+ --*/
11552+
11553+#ifndef _REVISION_H
11554+#define _REVISION_H
11555+
11556+static char *ident_revision = "aacraid_ident revision.h 1.0.6 2000/10/09 Adaptec, Inc.";
11557+
11558+#include "version.h" // revision numbers kept separate so they can be used by resource compiler as well
11559+
11560+typedef int REV_BOOL;
11561+
11562+#define REV_TRUE 1
11563+#define REV_FALSE 0
11564+
11565+//
11566+// Define Revision Levels for this product
11567+//
11568+// IMPORTANT: Do NOT modify BUILD_NUMBER define, this is modified
11569+// automatically by the build.
11570+//
11571+// Version is VMAJOR.MINOR-DASH TYPE (Build BUILD_NUMBER)
11572+//
11573+// IMPORTANT: Don't access these revisions directly. They can be
11574+// accessed via, the RevGetXxxxx rouines.
11575+//
11576+
11577+
11578+#define REV_AS_LONGWORD \
11579+ ((REV_MAJOR << 24) | (REV_MINOR << 16) | (REV_TYPE << 8) | (REV_DASH))
11580+
11581+
11582+
11583+#ifndef BIOS
11584+
11585+//
11586+// Enumerate the types of product levels we can have
11587+//
11588+enum {
11589+ RevType_Devo=1, // Development mode, testing all of latest
11590+ RevType_Alpha, // Alpha - Internal field test
11591+ RevType_Beta, // Beta - External field test
11592+ RevType_Release // Release - Retail version
11593+};
11594+
11595+//
11596+// Define the basic structure for all revision information. Note
11597+// that the ordering of the components is such that they should
11598+// always increase. dash will be updated the most, then the version
11599+// type, then minor and major.
11600+//
11601+typedef struct {
11602+ union {
11603+ struct {
11604+ unsigned char dash; // Dash version number
11605+ unsigned char type; // Type, 1=Devo, 2=Alpha, 3=Beta, 4=Release
11606+ unsigned char minor;// Minor version minor
11607+ unsigned char major;// Major version number
11608+ } comp; // Components to external viewed rev number
11609+ unsigned long ul; // External revision as single 32-bit value
11610+ } external; // External revision number (union)
11611+ unsigned long buildNumber; // Automatically generated build number
11612+} FsaRevision;
11613+
11614+
11615+//
11616+// Define simple routines to get basic revision information. The
11617+// definitions should never be accessed directly. These routines
11618+// are meant to be used to access all relevant information no matter
11619+// how simple.
11620+//
11621+static inline unsigned long RevGetBuildNumber() {return REV_BUILD_NUMBER;}
11622+
11623+static inline unsigned long RevGetExternalRev() {return REV_AS_LONGWORD;}
11624+
11625+
11626+//
11627+// Enumerate different components that may have to check
11628+// compatibility. This list of components can be changed
11629+// at any time.
11630+//
11631+// IMPORTANT: ONLY add to the END of this enum structure. Otherwise,
11632+// incompatibilities between component rev checking will
11633+// cause wrong checking results.
11634+//
11635+typedef enum {
11636+ RevApplication = 1, // Any user End application
11637+ RevDkiCli, // ADAPTEC proprietary interface (knows FIBs)
11638+ RevNetService, // Network Service Revision (under API)
11639+ RevApi, // ADAPTEC User mode API
11640+ RevFileSysDriver, // FSA File System Driver
11641+ RevMiniportDriver, // FSA File System Miniport Driver
11642+ RevAdapterSW, // Adapter Software (or NT Simulator)
11643+ RevMonitor, // Monitor for adapter hardware (MON960 for now)
11644+ RevRemoteApi // The remote API.
11645+ // ALWAYS ADD NEW COMPONENTS HERE - AT END
11646+} RevComponent;
11647+
11648+//
11649+// Define a structure so that we can create a compatibility table.
11650+//
11651+typedef struct {
11652+ RevComponent A,B;
11653+ unsigned long BuildNumOfB_RequiredByA;
11654+ unsigned long BuildNumOfA_RequiredByB;
11655+} RevCompareElement;
11656+
11657+//
11658+// Now, define the table. This table should only be included once,
11659+// in one program. If it is linked from 2 modules, there will likely
11660+// be a multiply defined symbol error from the linker.
11661+//
11662+// To fix this problem, REV_REFERENCE_ONLY can be defined. This will
11663+// allow access to the revision information table without a redefinition
11664+// of the tables.
11665+//
11666+extern const int RevCompareTableLength;
11667+
11668+extern const RevCompareElement RevCompareTable[];
11669+
11670+/********************************************************************\
11671+* Routine: RevCheckCompatibility(callerComp,compB,compB_BuildNumber)
11672+*
11673+* The following routine is used to check compatibility between
11674+* the calling component and a component that has some dependencies
11675+* on it. If this routine returns REV_FALSE, it is expected that the caller
11676+* will send an appropriate incompatibility message and stop.
11677+*
11678+* This routine is only meant to check for compatibility in the
11679+* absolute sense. If code wishes to execute a different path based
11680+* on the CompB_BuildNumber, then this routine is not useful. The
11681+* routine RevGetBuildNumber can be used to get the calling module's
11682+* current build number for a comparison check.
11683+*
11684+* The return value is REV_TRUE, if compatibility is possible, and REV_FALSE
11685+* if the components are definitely not compatible, or there is an
11686+* error when trying to figure it out. To be more specific:
11687+*
11688+* 1) REV_TRUE if component B is newer than calling component. (In this
11689+* case, the revision check done by component B with respect to
11690+* this component will give the real compatibility information.
11691+* It is the only one with the knowledge, since this component
11692+* could not look into the future.)
11693+* 2) REV_TRUE if calling component is more recent and table shows okay
11694+* 3) REV_FALSE if calling component more recent and table show not okay
11695+* 4) REV_FALSE if calling component is more recent and table entry to
11696+* check does not exist.
11697+*
11698+* Note that the CompB_BuildNumber must be attained by the calling
11699+* routine through some mechanism done by the caller.
11700+*
11701+* Input:
11702+*
11703+* callerComp - Name of component making this call
11704+* compB - Name of component to check compatibility with
11705+* compB_BuildNumber - Build number to component B
11706+*
11707+* Output:
11708+*
11709+* None
11710+*
11711+* Return Value:
11712+*
11713+* REV_TRUE - Component compatibility is possible, continue as usual. compB
11714+* must give true compatibility information.
11715+* REV_FALSE - Incompatible components, notify and end
11716+*
11717+\********************************************************************/
11718+static inline REV_BOOL RevCheckCompatibility(
11719+ RevComponent callerComp,
11720+ RevComponent compB,
11721+ unsigned long compB_BuildNumber)
11722+{
11723+ int i;
11724+ unsigned long RevForB;
11725+
11726+ //
11727+ // Compatibility check is possible, so we should continue. When
11728+ // compB makes this call in its own component, it will get the
11729+ // true compatibility information, since only it can know.
11730+ //
11731+ if (RevGetBuildNumber() < compB_BuildNumber) return REV_TRUE;
11732+
11733+ //
11734+ // Go through rev table. When the components are found in the
11735+ // same table entry, return the approprate number.
11736+ //
11737+ for (i=0; i<RevCompareTableLength; i++) {
11738+ if (RevCompareTable[i].A == callerComp) {
11739+ if (RevCompareTable[i].B == compB) {
11740+ RevForB = RevCompareTable[i].BuildNumOfB_RequiredByA;
11741+ return (compB_BuildNumber >= RevForB);
11742+ }
11743+ } else if (RevCompareTable[i].B == callerComp) {
11744+ if (RevCompareTable[i].A == compB) {
11745+ RevForB = RevCompareTable[i].BuildNumOfA_RequiredByB;
11746+ return (compB_BuildNumber >= RevForB);
11747+ }
11748+ }
11749+ }
11750+
11751+ //
11752+ // Uh oh! No relevant table entry was found (this should never
11753+ // happen).
11754+ //
11755+ return REV_FALSE;
11756+}
11757+
11758+
11759+//
11760+// Now create a structure that can be used by a FIB to check
11761+// compatibility.
11762+//
11763+typedef struct _RevCheck {
11764+ RevComponent callingComponent;
11765+ FsaRevision callingRevision;
11766+} RevCheck;
11767+
11768+typedef struct _RevCheckResp {
11769+ REV_BOOL possiblyCompatible;
11770+ FsaRevision adapterSWRevision;
11771+} RevCheckResp;
11772+
11773+#endif /* bios */
11774+#endif /* _REVISION_H */
11775+
11776+//
11777+// The following allows for inclusion of revision.h in other h
11778+// files. when you include this file in another h file, simply
11779+// define REV_REFERENCE_ONLY. This will be undefined later, so that
11780+// the single C file inclusion in the module will be used to
11781+// implement the global structures.
11782+//
11783+#ifndef REV_REFERENCE_ONLY
11784+#ifndef _REVISION_H_GLOBAL
11785+#define _REVISION_H_GLOBAL
11786+
11787+
11788+
11789+//
11790+// The following array is the table of compatibility. This table
11791+// can be modified in two ways:
11792+//
11793+// 1) A component which has an incompatible change done to
11794+// it, can get a new build number.
11795+//
11796+// 2) A new component can be added, requiring more entries
11797+// to be place into this table.
11798+//
11799+//
11800+// In case (1), you must change the revision number in the appropriate
11801+// column, based on which component absolutely requires an upgrade.
11802+//
11803+// Example: A new FIB used by the API, in build number 105
11804+// {RevApi, RevAdapterSW, 100, 100}
11805+// ---> would be changed to <---
11806+// {RevApi, RevAdapterSW, 105, 100}
11807+//
11808+// Example: A structure is changed for a FIB that only the API uses
11809+// {RevApi, RevAdapterSW, 100, 100}
11810+// ---> would be changed to <---
11811+// {RevApi, RevAdapterSW, 105, 105}
11812+//
11813+//
11814+// In case (2), the less common case, the enumerated list of
11815+// components must be changed to include the new component. Then
11816+// entries need to be placed into this table.
11817+//
11818+// Since the revisions must be communicated between the two
11819+// components, it is likely that you would need to put in the
11820+// current build number for both columns. That is the recommended
11821+// way to start revision test.
11822+//
11823+const RevCompareElement RevCompareTable[] = {
11824+ // Component A Component B MinBForA MinAForB
11825+ // ----------- ----------- -------- --------
11826+ {RevApplication, RevApi, 2120, 2120 },
11827+ {RevDkiCli, RevApi, 2120, 2120 },
11828+ {RevDkiCli, RevFileSysDriver, 257, 257 },
11829+ {RevDkiCli, RevMiniportDriver, 257, 257 },
11830+ {RevDkiCli, RevAdapterSW, 257, 257 },
11831+ {RevApi, RevFileSysDriver, 2120, 2120 },
11832+ {RevApi, RevMiniportDriver, 2120, 2120 },
11833+ {RevApi, RevAdapterSW, 2120, 2120 },
11834+ {RevApi, RevNetService, 2120, 2120 },
11835+ {RevFileSysDriver, RevMiniportDriver, 100, 100 },
11836+ {RevFileSysDriver, RevAdapterSW, 257, 257 },
11837+ {RevMiniportDriver, RevAdapterSW, 257, 257 },
11838+ {RevMiniportDriver, RevMonitor, 100, 100 },
11839+ {RevApi, RevNetService, 2120, 2120 },
11840+ {RevApi, RevRemoteApi, 2120, 2120 },
11841+ {RevNetService, RevRemoteApi, 2120, 2120 }
11842+};
11843+
11844+const int RevCompareTableLength = sizeof(RevCompareTable)/sizeof(RevCompareElement);
11845+
11846+#endif /* _REVISION_H_GLOBAL */
11847+#endif /* REV_REFERENCE_ONLY */
11848+#undef REV_REFERENCE_ONLY
11849+
11850+
11851+
11852+
11853+
11854+
11855+
11856diff -burN linux-2.4.7/drivers/scsi/aacraid/include/rx.h linux/drivers/scsi/aacraid/include/rx.h
11857--- linux-2.4.7/drivers/scsi/aacraid/include/rx.h Wed Dec 31 18:00:00 1969
11858+++ linux/drivers/scsi/aacraid/include/rx.h Sat Jul 21 17:55:13 2001
11859@@ -0,0 +1,81 @@
11860+/*++
11861+ * Adaptec aacraid device driver for Linux.
11862+ *
11863+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11864+ *
11865+ * This program is free software; you can redistribute it and/or modify
11866+ * it under the terms of the GNU General Public License as published by
11867+ * the Free Software Foundation; either version 2, or (at your option)
11868+ * any later version.
11869+ *
11870+ * This program is distributed in the hope that it will be useful,
11871+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11872+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11873+ * GNU General Public License for more details.
11874+ *
11875+ * You should have received a copy of the GNU General Public License
11876+ * along with this program; see the file COPYING. If not, write to
11877+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11878+ *
11879+ * Module Name:
11880+ * rx.h
11881+ *
11882+ * Abstract: Prototypes and data structures unique to the Rx based controller board.
11883+ *
11884+ *
11885+ --*/
11886+
11887+static char *ident_rxh = "aacraid_ident rx.h 1.0.6 2000/10/09 Adaptec, Inc.";
11888+
11889+typedef struct _Rx_ADAPTER_EXTENSION {
11890+
11891+ //
11892+ // The following must be first.
11893+ //
11894+ PPCI_MINIPORT_COMMON_EXTENSION Common;
11895+ struct _Rx_ADAPTER_EXTENSION *Next; // Next adapter miniport structure
11896+ USHORT LocalMaskInterruptControl;
11897+ PRx_DEVICE_REGISTERS Device;
11898+
11899+} Rx_ADAPTER_EXTENSION;
11900+
11901+
11902+typedef Rx_ADAPTER_EXTENSION *PRx_ADAPTER_EXTENSION;
11903+
11904+
11905+
11906+#ifdef LINUX
11907+/*
11908+ *
11909+ */
11910+
11911+#define Rx_READ_UCHAR(AEP, CSR) *(volatile unsigned char *) &((AEP)->Device->CSR)
11912+
11913+
11914+
11915+#define Rx_READ_ULONG(AEP, CSR) *(volatile unsigned int *) &((AEP)->Device->CSR)
11916+#define Rx_WRITE_UCHAR(AEP, CSR, Value) *(volatile unsigned char *) &((AEP)->Device->CSR) = (Value)
11917+
11918+
11919+#define Rx_WRITE_ULONG(AEP, CSR, Value) *(volatile unsigned int *) &((AEP)->Device->CSR) = (Value)
11920+
11921+#endif /* LINUX */
11922+
11923+
11924+VOID
11925+RxInterruptAdapter(
11926+ PVOID Arg1
11927+ );
11928+
11929+VOID
11930+RxNotifyAdapter(
11931+ PVOID Arg1,
11932+ IN HOST_2_ADAP_EVENT AdapterEvent
11933+ );
11934+
11935+VOID
11936+RxResetDevice(
11937+ PVOID Arg1
11938+ );
11939+
11940+
11941diff -burN linux-2.4.7/drivers/scsi/aacraid/include/rxcommon.h linux/drivers/scsi/aacraid/include/rxcommon.h
11942--- linux-2.4.7/drivers/scsi/aacraid/include/rxcommon.h Wed Dec 31 18:00:00 1969
11943+++ linux/drivers/scsi/aacraid/include/rxcommon.h Sat Jul 21 17:55:13 2001
11944@@ -0,0 +1,105 @@
11945+/*++
11946+ * Adaptec aacraid device driver for Linux.
11947+ *
11948+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11949+ *
11950+ * This program is free software; you can redistribute it and/or modify
11951+ * it under the terms of the GNU General Public License as published by
11952+ * the Free Software Foundation; either version 2, or (at your option)
11953+ * any later version.
11954+ *
11955+ * This program is distributed in the hope that it will be useful,
11956+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11957+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11958+ * GNU General Public License for more details.
11959+ *
11960+ * You should have received a copy of the GNU General Public License
11961+ * along with this program; see the file COPYING. If not, write to
11962+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11963+ *
11964+ * Module Name:
11965+ * rxcommon.h
11966+ *
11967+ * Abstract: Structures and defines for the i960 Rx chip.
11968+ *
11969+ *
11970+ --*/
11971+
11972+#ifndef _Rx_COMMON_H_
11973+#define _Rx_COMMON_H_
11974+
11975+static char *ident_rxcommon = "aacraid_ident rxcommon.h 1.0.6 2000/10/09 Adaptec, Inc.";
11976+
11977+//
11978+// Rx Message Unit Registers
11979+//
11980+
11981+typedef volatile struct _StructRxMURegisters {
11982+ // Local | PCI* | Name
11983+ // | |
11984+ unsigned ARSR; // 1300h | 00h | APIC Register Select Register
11985+ unsigned reserved0; // 1304h | 04h | Reserved
11986+ unsigned AWR; // 1308h | 08h | APIC Window Register
11987+ unsigned reserved1; // 130Ch | 0Ch | Reserved
11988+ unsigned IMRx[2]; // 1310h | 10h | Inbound Message Registers
11989+ unsigned OMRx[2]; // 1318h | 18h | Outbound Message Registers
11990+ unsigned IDR; // 1320h | 20h | Inbound Doorbell Register
11991+ unsigned IISR; // 1324h | 24h | Inbound Interrupt Status Register
11992+ unsigned IIMR; // 1328h | 28h | Inbound Interrupt Mask Register
11993+ unsigned ODR; // 132Ch | 2Ch | Outbound Doorbell Register
11994+ unsigned OISR; // 1330h | 30h | Outbound Interrupt Status Register
11995+ unsigned OIMR; // 1334h | 34h | Outbound Interrupt Mask Register
11996+ // * Must access trhough ATU Inbound Translation Window
11997+
11998+}Rx_MU_CONFIG;
11999+typedef Rx_MU_CONFIG *PRx_MU_CONFIG;
12000+
12001+typedef volatile struct _Rx_Inbound {
12002+
12003+ unsigned Mailbox[8];
12004+
12005+}Rx_Inbound;
12006+
12007+typedef Rx_Inbound *PRx_Inbound;
12008+
12009+#define InboundMailbox0 IndexRegs.Mailbox[0]
12010+#define InboundMailbox1 IndexRegs.Mailbox[1]
12011+#define InboundMailbox2 IndexRegs.Mailbox[2]
12012+#define InboundMailbox3 IndexRegs.Mailbox[3]
12013+#define InboundMailbox4 IndexRegs.Mailbox[4]
12014+
12015+
12016+
12017+#define INBOUNDDOORBELL_0 0x00000001
12018+#define INBOUNDDOORBELL_1 0x00000002
12019+#define INBOUNDDOORBELL_2 0x00000004
12020+#define INBOUNDDOORBELL_3 0x00000008
12021+#define INBOUNDDOORBELL_4 0x00000010
12022+#define INBOUNDDOORBELL_5 0x00000020
12023+#define INBOUNDDOORBELL_6 0x00000040
12024+
12025+
12026+#define OUTBOUNDDOORBELL_0 0x00000001
12027+#define OUTBOUNDDOORBELL_1 0x00000002
12028+#define OUTBOUNDDOORBELL_2 0x00000004
12029+#define OUTBOUNDDOORBELL_3 0x00000008
12030+#define OUTBOUNDDOORBELL_4 0x00000010
12031+
12032+
12033+#define InboundDoorbellReg MUnit.IDR
12034+
12035+#define OutboundDoorbellReg MUnit.ODR
12036+
12037+
12038+typedef struct _Rx_DEVICE_REGISTERS {
12039+ Rx_MU_CONFIG MUnit; // 1300h - 1334h
12040+ unsigned reserved1[6]; // 1338h - 134ch
12041+ Rx_Inbound IndexRegs;
12042+} Rx_DEVICE_REGISTERS;
12043+
12044+typedef Rx_DEVICE_REGISTERS *PRx_DEVICE_REGISTERS;
12045+
12046+
12047+#endif // _Rx_COMMON_H_
12048+
12049+
12050diff -burN linux-2.4.7/drivers/scsi/aacraid/include/sap1.h linux/drivers/scsi/aacraid/include/sap1.h
12051--- linux-2.4.7/drivers/scsi/aacraid/include/sap1.h Wed Dec 31 18:00:00 1969
12052+++ linux/drivers/scsi/aacraid/include/sap1.h Sat Jul 21 17:55:14 2001
12053@@ -0,0 +1,85 @@
12054+/*++
12055+ * Adaptec aacraid device driver for Linux.
12056+ *
12057+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
12058+ *
12059+ * This program is free software; you can redistribute it and/or modify
12060+ * it under the terms of the GNU General Public License as published by
12061+ * the Free Software Foundation; either version 2, or (at your option)
12062+ * any later version.
12063+ *
12064+ * This program is distributed in the hope that it will be useful,
12065+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12066+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12067+ * GNU General Public License for more details.
12068+ *
12069+ * You should have received a copy of the GNU General Public License
12070+ * along with this program; see the file COPYING. If not, write to
12071+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
12072+ *
12073+ * Module Name:
12074+ * sap1.h
12075+ *
12076+ * Abstract: Prototypes and data structures unique to the Strong Arm based controller board.
12077+ *
12078+ *
12079+ --*/
12080+#ifndef _SAP1_H_
12081+#define _SAP1_H_
12082+
12083+static char *ident_sap1h = "aacraid_ident sap1.h 1.0.6 2000/10/09 Adaptec, Inc.";
12084+
12085+#define Sa_MINIPORT_REVISION 1
12086+
12087+typedef struct _Sa_ADAPTER_EXTENSION {
12088+
12089+ //
12090+ // The following must be first.
12091+ //
12092+ PPCI_MINIPORT_COMMON_EXTENSION Common;
12093+ struct _Sa_ADAPTER_EXTENSION *Next; // Next adapter miniport structure
12094+ USHORT LocalMaskInterruptControl;
12095+ PSa_DEVICE_REGISTERS Device;
12096+
12097+} Sa_ADAPTER_EXTENSION;
12098+
12099+typedef Sa_ADAPTER_EXTENSION *PSa_ADAPTER_EXTENSION;
12100+
12101+
12102+
12103+#ifdef LINUX
12104+/*
12105+ *
12106+ */
12107+
12108+
12109+#define Sa_READ_USHORT(AEP, CSR) *(volatile unsigned short *) &((AEP)->Device->CSR)
12110+#define Sa_READ_ULONG(AEP, CSR) *(volatile unsigned int *) &((AEP)->Device->CSR)
12111+
12112+
12113+#define Sa_WRITE_USHORT(AEP, CSR, Value) *(volatile unsigned short *) &((AEP)->Device->CSR) = (Value)
12114+#define Sa_WRITE_ULONG(AEP, CSR, Value) *(volatile unsigned int *) &((AEP)->Device->CSR) = (Value)
12115+
12116+#endif /* LINUX */
12117+
12118+
12119+VOID
12120+SaInterruptAdapter(
12121+ PVOID Arg1
12122+ );
12123+
12124+VOID
12125+SaNotifyAdapter(
12126+ PVOID Arg1,
12127+ IN HOST_2_ADAP_EVENT AdapterEvent
12128+ );
12129+
12130+VOID
12131+SaResetDevice(
12132+ PVOID Arg1
12133+ );
12134+
12135+
12136+#endif /* _SAP1_H_ */
12137+
12138+
12139diff -burN linux-2.4.7/drivers/scsi/aacraid/include/sap1common.h linux/drivers/scsi/aacraid/include/sap1common.h
12140--- linux-2.4.7/drivers/scsi/aacraid/include/sap1common.h Wed Dec 31 18:00:00 1969
12141+++ linux/drivers/scsi/aacraid/include/sap1common.h Sat Jul 21 17:55:14 2001
12142@@ -0,0 +1,111 @@
12143+/*++
12144+ * Adaptec aacraid device driver for Linux.
12145+ *
12146+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
12147+ *
12148+ * This program is free software; you can redistribute it and/or modify
12149+ * it under the terms of the GNU General Public License as published by
12150+ * the Free Software Foundation; either version 2, or (at your option)
12151+ * any later version.
12152+ *
12153+ * This program is distributed in the hope that it will be useful,
12154+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12155+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12156+ * GNU General Public License for more details.
12157+ *
12158+ * You should have received a copy of the GNU General Public License
12159+ * along with this program; see the file COPYING. If not, write to
12160+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
12161+ *
12162+ * Module Name:
12163+ * sap1common.h
12164+ *
12165+ * Abstract: Structures and defines for the Drawbridge and StrongArm110 chip.
12166+ *
12167+ --*/
12168+
12169+#ifndef _Sa_COMMON_H_
12170+#define _Sa_COMMON_H_
12171+
12172+static char *ident_sap1common = "aacraid_ident sap1common.h 1.0.6 2000/10/09 Adaptec, Inc.";
12173+
12174+//
12175+// SaP1 Message Unit Registers
12176+//
12177+
12178+typedef volatile struct _StructSaDrawbridge_CSR_RegisterMap {
12179+ // Offset | Name
12180+ unsigned reserved[10]; // 00h-27h | Reserved
12181+ unsigned char LUT_Offset; // 28h | Looup Table Offset
12182+ unsigned char reserved1[3]; // 29h-2bh | Reserved
12183+ unsigned LUT_Data; // 2ch | Looup Table Data
12184+ unsigned reserved2[26]; // 30h-97h | Reserved
12185+ unsigned short PRICLEARIRQ; // 98h | Primary Clear Irq
12186+ unsigned short SECCLEARIRQ; // 9ah | Secondary Clear Irq
12187+ unsigned short PRISETIRQ; // 9ch | Primary Set Irq
12188+ unsigned short SECSETIRQ; // 9eh | Secondary Set Irq
12189+ unsigned short PRICLEARIRQMASK; // a0h | Primary Clear Irq Mask
12190+ unsigned short SECCLEARIRQMASK; // a2h | Secondary Clear Irq Mask
12191+ unsigned short PRISETIRQMASK; // a4h | Primary Set Irq Mask
12192+ unsigned short SECSETIRQMASK; // a6h | Secondary Set Irq Mask
12193+ unsigned MAILBOX0; // a8h | Scratchpad 0
12194+ unsigned MAILBOX1; // ach | Scratchpad 1
12195+ unsigned MAILBOX2; // b0h | Scratchpad 2
12196+ unsigned MAILBOX3; // b4h | Scratchpad 3
12197+ unsigned MAILBOX4; // b8h | Scratchpad 4
12198+ unsigned MAILBOX5; // bch | Scratchpad 5
12199+ unsigned MAILBOX6; // c0h | Scratchpad 6
12200+ unsigned MAILBOX7; // c4h | Scratchpad 7
12201+
12202+ unsigned ROM_Setup_Data; // c8h | Rom Setup and Data
12203+ unsigned ROM_Control_Addr; // cch | Rom Control and Address
12204+
12205+ unsigned reserved3[12]; // d0h-ffh | reserved
12206+ unsigned LUT[64]; // 100h-1ffh| Lookup Table Entries
12207+
12208+ //
12209+ // TO DO
12210+ // need to add DMA, I2O, UART, etc registers form 80h to 364h
12211+ //
12212+
12213+}Sa_Drawbridge_CSR;
12214+
12215+typedef Sa_Drawbridge_CSR *PSa_Drawbridge_CSR;
12216+
12217+
12218+#define Mailbox0 SaDbCSR.MAILBOX0
12219+#define Mailbox1 SaDbCSR.MAILBOX1
12220+#define Mailbox2 SaDbCSR.MAILBOX2
12221+#define Mailbox3 SaDbCSR.MAILBOX3
12222+#define Mailbox4 SaDbCSR.MAILBOX4
12223+
12224+
12225+#define Mailbox7 SaDbCSR.MAILBOX7
12226+
12227+#define DoorbellReg_p SaDbCSR.PRISETIRQ
12228+#define DoorbellReg_s SaDbCSR.SECSETIRQ
12229+#define DoorbellClrReg_p SaDbCSR.PRICLEARIRQ
12230+
12231+
12232+#define DOORBELL_0 0x00000001
12233+#define DOORBELL_1 0x00000002
12234+#define DOORBELL_2 0x00000004
12235+#define DOORBELL_3 0x00000008
12236+#define DOORBELL_4 0x00000010
12237+#define DOORBELL_5 0x00000020
12238+#define DOORBELL_6 0x00000040
12239+
12240+
12241+#define PrintfReady DOORBELL_5
12242+#define PrintfDone DOORBELL_5
12243+
12244+typedef struct _Sa_DEVICE_REGISTERS {
12245+ Sa_Drawbridge_CSR SaDbCSR; // 98h - c4h
12246+} Sa_DEVICE_REGISTERS;
12247+
12248+typedef Sa_DEVICE_REGISTERS *PSa_DEVICE_REGISTERS;
12249+
12250+
12251+#endif // _Sa_COMMON_H_
12252+
12253+
12254diff -burN linux-2.4.7/drivers/scsi/aacraid/include/version.h linux/drivers/scsi/aacraid/include/version.h
12255--- linux-2.4.7/drivers/scsi/aacraid/include/version.h Wed Dec 31 18:00:00 1969
12256+++ linux/drivers/scsi/aacraid/include/version.h Sat Jul 21 17:55:14 2001
12257@@ -0,0 +1,40 @@
12258+/*++
12259+ * Adaptec aacraid device driver for Linux.
12260+ *
12261+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
12262+ *
12263+ * This program is free software; you can redistribute it and/or modify
12264+ * it under the terms of the GNU General Public License as published by
12265+ * the Free Software Foundation; either version 2, or (at your option)
12266+ * any later version.
12267+ *
12268+ * This program is distributed in the hope that it will be useful,
12269+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12270+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12271+ * GNU General Public License for more details.
12272+ *
12273+ * You should have received a copy of the GNU General Public License
12274+ * along with this program; see the file COPYING. If not, write to
12275+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
12276+ *
12277+ * Module Name:
12278+ * version.h
12279+ *
12280+ * Abstract: Keeps track of build number for development purposes.
12281+ *
12282+ --*/
12283+#ifndef _VERSION_H_
12284+#define _VERSION_H_
12285+
12286+static char *ident_version = "aacraid_ident version.h 1.0.6 2000/10/09 Adaptec, Inc.";
12287+
12288+#include "build_number.h"
12289+
12290+#define REV_MAJOR 2
12291+#define REV_MINOR 1
12292+#define REV_TYPE RevType_Release
12293+#define REV_DASH 5
12294+
12295+#define FSA_VERSION_STRING "2.1.5.3857\0"
12296+
12297+#endif /* _VERSION_H_ */
12298diff -burN linux-2.4.7/drivers/scsi/aacraid/linit.c linux/drivers/scsi/aacraid/linit.c
12299--- linux-2.4.7/drivers/scsi/aacraid/linit.c Wed Dec 31 18:00:00 1969
12300+++ linux/drivers/scsi/aacraid/linit.c Sat Jul 21 17:55:14 2001
12301@@ -0,0 +1,1063 @@
12302+/*++
12303+ * Adaptec aacraid device driver for Linux.
12304+ *
12305+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
12306+ *
12307+ * This program is free software; you can redistribute it and/or modify
12308+ * it under the terms of the GNU General Public License as published by
12309+ * the Free Software Foundation; either version 2, or (at your option)
12310+ * any later version.
12311+ *
12312+ * This program is distributed in the hope that it will be useful,
12313+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12314+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12315+ * GNU General Public License for more details.
12316+ *
12317+ * You should have received a copy of the GNU General Public License
12318+ * along with this program; see the file COPYING. If not, write to
12319+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
12320+ *
12321+ * Module Name:
12322+ * linit.c
12323+ *
12324+ * Abstract: Linux Driver entry module for Adaptec RAID Array Controller
12325+ *
12326+ * Provides the following driver entry points:
12327+ * AAC_DetectHostAdapter()
12328+ * AAC_ReleaseHostAdapter()
12329+ * AAC_QueueCommand()
12330+ * AAC_ResetCommand()
12331+ * AAC_BIOSDiskParameters()
12332+ *
12333+ --*/
12334+
12335+static char *ident_linit = "aacraid_ident linit.c 1.0.6 2000/10/09 Adaptec, Inc.";
12336+
12337+/*------------------------------------------------------------------------------
12338+ * D E F I N E S
12339+ *----------------------------------------------------------------------------*/
12340+#define AAC_DRIVER_VERSION "0.1.1"
12341+#define AAC_DRIVER_BUILD_DATE __DATE__
12342+#define MAX_DRIVER_QUEUE_DEPTH 500
12343+
12344+/*------------------------------------------------------------------------------
12345+ * I N C L U D E S
12346+ *----------------------------------------------------------------------------*/
12347+#include "osheaders.h"
12348+
12349+#include "AacGenericTypes.h"
12350+
12351+#ifdef MODULE
12352+#include <linux/module.h>
12353+#endif
12354+#include "sd.h"
12355+#include "linit.h"
12356+#include "aac_unix_defs.h"
12357+#include "fsatypes.h"
12358+#include "comstruc.h"
12359+#include "fsaport.h"
12360+#include "pcisup.h"
12361+#include "port.h"
12362+#include "afacomm.h"
12363+#include "nodetype.h"
12364+#include "comsup.h"
12365+#include "adapter.h"
12366+
12367+/*------------------------------------------------------------------------------
12368+ * G L O B A L S
12369+ *----------------------------------------------------------------------------*/
12370+extern FSA_MINIPORT MiniPorts[];
12371+extern int CommPrinting;
12372+extern char DescriptionString[];
12373+extern char devicestr[];
12374+
12375+/*------------------------------------------------------------------------------
12376+ * M O D U L E G L O B A L S
12377+ *----------------------------------------------------------------------------*/
12378+aac_options_t g_options = { CMN_ERR_LEVEL, 0 }; // default message_level
12379+
12380+char g_DriverName[] = { "aacraid" };
12381+#define module_options aacraid_options
12382+static char * aacraid_options = NULL;
12383+
12384+PCI_MINIPORT_COMMON_EXTENSION *g_CommonExtensionPtrArray[ MAXIMUM_NUM_ADAPTERS ];
12385+unsigned g_HostAdapterCount = 0;
12386+unsigned g_chardev_major = 0;
12387+
12388+int g_single_command_done = FALSE;
12389+
12390+/*------------------------------------------------------------------------------
12391+ * F U N C T I O N P R O T O T Y P E S
12392+ *----------------------------------------------------------------------------*/
12393+int AacHba_Ioctl(
12394+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtension,
12395+ int cmd,
12396+ void * arg );
12397+
12398+int AacHba_ProbeContainers(
12399+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr );
12400+
12401+int AacHba_DoScsiCmd(
12402+ Scsi_Cmnd *scsi_cmnd_ptr,
12403+ int wait );
12404+
12405+void AacHba_DetachAdapter(
12406+ IN PVOID AdapterArg );
12407+
12408+int AacHba_ClassDriverInit(
12409+ PCI_MINIPORT_COMMON_EXTENSION * CommonExtensionPtr);
12410+
12411+void AacHba_AbortScsiCommand(
12412+ Scsi_Cmnd *scsi_cmnd_ptr );
12413+
12414+
12415+/*------------------------------------------------------------------------------
12416+ * L O C A L F U N C T I O N P R O T O T Y P E S
12417+ *----------------------------------------------------------------------------*/
12418+static int parse_keyword(
12419+ char ** str_ptr,
12420+ char * keyword );
12421+
12422+static void AAC_ParseDriverOptions(
12423+ char * cmnd_line_options_str );
12424+
12425+static void AAC_AnnounceDriver( void );
12426+
12427+int AAC_ChardevIoctl(
12428+ struct inode * inode_ptr,
12429+ struct file * file_ptr,
12430+ unsigned int cmd,
12431+ unsigned long arg );
12432+
12433+int AAC_ChardevOpen(
12434+ struct inode * inode_ptr,
12435+ struct file * file_ptr );
12436+
12437+int AAC_ChardevRelease(
12438+ struct inode * inode_ptr,
12439+ struct file * file_ptr );
12440+
12441+struct file_operations AAC_fops = {
12442+ NULL, // module name
12443+ NULL, // lseek
12444+ NULL, // read
12445+ NULL, // write
12446+ NULL, // readdir
12447+ NULL, // poll
12448+ AAC_ChardevIoctl, // ioctl
12449+ NULL, // mmap
12450+ AAC_ChardevOpen, // open
12451+ NULL, // flush
12452+ AAC_ChardevRelease, // release
12453+ NULL, // fsync
12454+ NULL, // fasync
12455+ NULL, // check media change
12456+ NULL, // revalidate
12457+ NULL // lock
12458+};
12459+
12460+/*------------------------------------------------------------------------------
12461+ * F U N C T I O N S
12462+ *----------------------------------------------------------------------------*/
12463+/*------------------------------------------------------------------------------
12464+ AAC_AnnounceDriver()
12465+
12466+ Announce the driver name, version and date.
12467+ *----------------------------------------------------------------------------*/
12468+static void AAC_AnnounceDriver( void ){
12469+ printk(KERN_ALERT "%s, %s\n",
12470+ "aacraid raid driver version", AAC_DRIVER_BUILD_DATE );
12471+ schedule();
12472+}
12473+
12474+
12475+/*------------------------------------------------------------------------------
12476+ AAC_DetectHostAdapter()
12477+
12478+ Probe for AAC Host Adapters initialize, register, and report the
12479+ configuration of each AAC Host Adapter found.
12480+
12481+ Preconditions:
12482+ Postconditions:
12483+ - Returns the number of adapters successfully initialized and
12484+ registered.
12485+ - Initialize all data necessary for this particular SCSI driver.
12486+ Notes:
12487+ The detect routine must not call any of the mid level functions
12488+ to queue commands because things are not guaranteed to be set
12489+ up yet. The detect routine can send commands to the host adapter
12490+ as long as the program control will not be passed to scsi.c in
12491+ the processing of the command. Note especially that
12492+ scsi_malloc/scsi_free must not be called.
12493+ *----------------------------------------------------------------------------*/
12494+int AAC_DetectHostAdapter (Scsi_Host_Template *HostTemplate)
12495+{
12496+ int index;
12497+ int ContainerId;
12498+ uint16_t vendor_id, device_id, sub_vendor_id, sub_system_id;
12499+ struct Scsi_Host *host_ptr;
12500+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
12501+ struct pci_dev *dev = NULL;
12502+ extern int NumMiniPorts;
12503+ fsadev_t *fsa_dev_ptr;
12504+ char *DeviceName;
12505+
12506+ struct pci_dev *devp;
12507+
12508+ int first_index, last_index, increment;
12509+
12510+ CommPrinting = TRUE;
12511+
12512+#ifdef MODULE
12513+ EXPORT_NO_SYMBOLS;
12514+#endif
12515+
12516+ AAC_AnnounceDriver();
12517+
12518+ /* setting up the proc directory structure */
12519+ HostTemplate->proc_name = "aacraid";
12520+
12521+ if( module_options != NULL ) AAC_ParseDriverOptions( module_options );
12522+
12523+ // NumMiniPorts & MiniPorts[] defined in aacid.c
12524+ if (g_options.reverse_scan == 0) {
12525+ first_index = 0;
12526+ last_index = NumMiniPorts;
12527+ increment = 1;
12528+ } else {
12529+ first_index = NumMiniPorts -1;
12530+ last_index = -1;
12531+ increment = -1;
12532+ }
12533+
12534+ for( index = first_index; index != last_index; index += increment )
12535+ {
12536+ device_id = MiniPorts[index].DeviceId;
12537+ vendor_id = MiniPorts[index].VendorId;
12538+ DeviceName = MiniPorts[index].DeviceName;
12539+ cmn_err(CE_DEBUG, "Checking %s %x/%x/%x/%x",
12540+ DeviceName, vendor_id, device_id,
12541+ MiniPorts[index].SubVendorId,
12542+ MiniPorts[index].SubSystemId);
12543+
12544+
12545+ // pci_find_device traverses the pci_devices linked list for devices
12546+ // with matching vendor and device ids.
12547+
12548+ dev = NULL; // start from beginning of list
12549+ while( ( dev = pci_find_device( vendor_id, device_id, dev ) ) )
12550+ {
12551+ if (pci_enable_device(dev)) continue;
12552+
12553+ if( pci_read_config_word( dev, PCI_SUBSYSTEM_VENDOR_ID, &sub_vendor_id ) ){
12554+ cmn_err(CE_WARN, "pci_read_config_word SUBSYS_VENDOR_ID failed");
12555+ break;
12556+ }
12557+ if( pci_read_config_word( dev, PCI_SUBSYSTEM_ID, &sub_system_id ) ){
12558+ cmn_err(CE_WARN, "pci_read_config_work SUBSYSTEM_ID failed");
12559+ break;
12560+ }
12561+
12562+ cmn_err(CE_DEBUG, " found: %x/%x/%x/%x", vendor_id, device_id, sub_vendor_id, sub_system_id);
12563+ if( ( sub_vendor_id != MiniPorts[index].SubVendorId ) ||
12564+ ( sub_system_id != MiniPorts[index].SubSystemId ) ){
12565+ continue;
12566+ }
12567+
12568+
12569+ printk(KERN_ALERT "%s device detected\n", DeviceName );
12570+ cmn_err(CE_DEBUG, "%x/%x/%x/%x", vendor_id, device_id, sub_vendor_id, sub_system_id);
12571+
12572+ // Increment the host adapter count
12573+ g_HostAdapterCount++;
12574+
12575+ // scsi_register() allocates memory for a Scsi_Hosts structure and
12576+ // links it into the linked list of host adapters. This linked list
12577+ // contains the data for all possible <supported> scsi hosts.
12578+ // This is similar to the Scsi_Host_Template, except that we have
12579+ // one entry for each actual physical host adapter on the system,
12580+ // stored as a linked list. If there are two AAC boards, then we
12581+ // will need to make two Scsi_Host entries, but there will be only
12582+ // one Scsi_Host_Template entry. The second argument to scsi_register()
12583+ // specifies the size of the extra memory we want to hold any device
12584+ // specific information.
12585+ host_ptr = scsi_register( HostTemplate, sizeof( PCI_MINIPORT_COMMON_EXTENSION ) );
12586+
12587+ // These three parameters can be used to allow for wide SCSI
12588+ // and for host adapters that support multiple buses.
12589+ host_ptr->max_id = 17;
12590+ host_ptr->max_lun = 8;
12591+ host_ptr->max_channel = 1;
12592+
12593+
12594+ host_ptr->irq = dev->irq; // Adapter IRQ number
12595+ /* host_ptr->base = ( char * )(dev->resource[0].start & ~0xff); */
12596+ host_ptr->base = ( char * )(dev->resource[0].start);
12597+ scsi_set_pci_device(host_ptr, dev);
12598+
12599+ cmn_err( CE_DEBUG, "Device base address = 0x%lx [0x%lx]", host_ptr->base, dev->resource[0].start );
12600+ cmn_err( CE_DEBUG, "Device irq = 0x%lx", dev->irq );
12601+
12602+ // The unique_id field is a unique identifier that must be assigned
12603+ // so that we have some way of identifying each host adapter properly
12604+ // and uniquely. For hosts that do not support more than one card in the
12605+ // system, this does not need to be set. It is initialized to zero in
12606+ // scsi_register(). This is the value returned from OsGetDeviceInstance().
12607+
12608+ host_ptr->unique_id = g_HostAdapterCount - 1;
12609+ host_ptr->this_id = 16; // SCSI Id for the adapter itself
12610+
12611+ // Set the maximum number of simultaneous commands supported by the driver.
12612+ host_ptr->can_queue = MAX_DRIVER_QUEUE_DEPTH;
12613+
12614+ // Define the maximum number of scatter/gather elements supported by
12615+ // the driver.
12616+
12617+ host_ptr->sg_tablesize = 16;
12618+ host_ptr->max_sectors = 128;
12619+ host_ptr->cmd_per_lun = 1; // untagged queue depth
12620+
12621+ // This function is called after the device list has been built to find
12622+ // tagged queueing depth supported for each device.
12623+
12624+ host_ptr->select_queue_depths = AAC_SelectQueueDepths;
12625+ CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )host_ptr->hostdata;
12626+
12627+ // attach a pointer back to Scsi_Host
12628+ CommonExtensionPtr->OsDep.scsi_host_ptr = host_ptr;
12629+ CommonExtensionPtr->OsDep.MiniPortIndex = index;
12630+
12631+ // Initialize the ordinal number of the device to -1
12632+ fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
12633+ for( ContainerId = 0; ContainerId < MAXIMUM_NUM_CONTAINERS; ContainerId++ )
12634+ fsa_dev_ptr->ContainerDevNo[ContainerId] = -1;
12635+
12636+ // Call initialization routine
12637+ cmn_err (CE_DEBUG, "Initializing Hardware...\n");
12638+ if( ( *MiniPorts[index].InitRoutine )
12639+ ( CommonExtensionPtr, host_ptr->unique_id, dev->bus->number, 0 ) != 0 )
12640+ {
12641+ // device initialization failed
12642+ cmn_err( CE_WARN, "%s:%d device initialization failed", DeviceName, host_ptr->unique_id );
12643+ scsi_unregister( host_ptr );
12644+ g_HostAdapterCount--;
12645+ } /* end if */
12646+ else
12647+ {
12648+ cmn_err( CE_NOTE, "%s:%d device initialization successful", DeviceName, host_ptr->unique_id );
12649+ AacHba_ClassDriverInit( CommonExtensionPtr );
12650+ cmn_err(CE_NOTE, "%s:%d AacHba_ClassDriverInit complete", DeviceName, host_ptr->unique_id);
12651+ AacHba_ProbeContainers( CommonExtensionPtr );
12652+ g_CommonExtensionPtrArray[ g_HostAdapterCount - 1 ] = CommonExtensionPtr;
12653+
12654+ } /* end else */
12655+
12656+ } /* end while */
12657+
12658+ } /* end for */
12659+
12660+ if( g_HostAdapterCount ){
12661+ if( !( g_chardev_major = register_chrdev( 0, devicestr, &AAC_fops ) ) )
12662+ cmn_err( CE_WARN, "%s: unable to register %s device", DeviceName, devicestr);
12663+ }
12664+
12665+ HostTemplate->present = g_HostAdapterCount; // # of cards of this type found
12666+
12667+ return( g_HostAdapterCount );
12668+}
12669+
12670+
12671+/*------------------------------------------------------------------------------
12672+ AAC_ReleaseHostAdapter()
12673+
12674+ Release all resources previously acquired to support a specific Host
12675+ Adapter and unregister the AAC Host Adapter.
12676+ *----------------------------------------------------------------------------*/
12677+int AAC_ReleaseHostAdapter(
12678+ struct Scsi_Host *host_ptr )
12679+/*----------------------------------------------------------------------------*/
12680+{
12681+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
12682+
12683+ cmn_err( CE_DEBUG, "AAC_ReleaseHostAdapter" );
12684+
12685+ CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )host_ptr->hostdata;
12686+
12687+ // kill any threads we started
12688+ kill_proc( CommonExtensionPtr->OsDep.thread_pid, SIGKILL, 0 );
12689+
12690+ // Call the comm layer to detach from this adapter
12691+ AacHba_DetachAdapter( CommonExtensionPtr->Adapter );
12692+
12693+ // remove interrupt binding
12694+ OsDetachInterrupt( CommonExtensionPtr->MiniPort );
12695+
12696+ SaDetachDevice( CommonExtensionPtr );
12697+
12698+ // unregister adapter
12699+ scsi_unregister( host_ptr );
12700+
12701+ if( g_chardev_major )
12702+ {
12703+ unregister_chrdev( g_chardev_major, devicestr );
12704+ g_chardev_major = 0;
12705+ }
12706+
12707+ return( 0 ); // #REVISIT# return code
12708+}
12709+
12710+
12711+/*------------------------------------------------------------------------------
12712+ AAC_QueueCommand()
12713+
12714+ Queues a command for execution by the associated Host Adapter.
12715+ *----------------------------------------------------------------------------*/
12716+int AAC_QueueCommand(
12717+ Scsi_Cmnd *scsi_cmnd_ptr,
12718+ void ( *CompletionRoutine )( Scsi_Cmnd * ) )
12719+/*----------------------------------------------------------------------------*/
12720+{
12721+ int ret;
12722+ scsi_cmnd_ptr->scsi_done = CompletionRoutine;
12723+
12724+ // AacHba_DoScsiCmd() handles command processing, setting the
12725+ // result code and calling completion routine.
12726+ #ifdef SYNC_FIB
12727+ if( (ret = AacHba_DoScsiCmd( scsi_cmnd_ptr, 1 )) != 0 ) // call with wait = TRUE
12728+ #else
12729+ if( (ret = AacHba_DoScsiCmd( scsi_cmnd_ptr, 0 )) != 0 ) // call with wait = FALSE
12730+ #endif
12731+ cmn_err( CE_DEBUG, "AacHba_DoScsiCmd failed" );
12732+ return ret;
12733+}
12734+
12735+
12736+/*------------------------------------------------------------------------------
12737+ AAC_Done()
12738+
12739+ Callback function for a non-queued command.
12740+
12741+ Postconditions
12742+ Sets g_single_command done to TRUE
12743+ *----------------------------------------------------------------------------*/
12744+void AAC_Done(
12745+ Scsi_Cmnd * scsi_cmnd_ptr )
12746+/*----------------------------------------------------------------------------*/
12747+{
12748+ g_single_command_done = TRUE;
12749+}
12750+
12751+
12752+/*------------------------------------------------------------------------------
12753+ AAC_Command()
12754+
12755+ Accepts a single command for execution by the associated Host Adapter.
12756+
12757+ Postconditions
12758+ Returns an int where:
12759+ Byte 0 = SCSI status code
12760+ Byte 1 = SCSI 1 byte message
12761+ Byte 2 = host error return
12762+ Byte 3 = mid level error return
12763+ *----------------------------------------------------------------------------*/
12764+int AAC_Command(
12765+ Scsi_Cmnd *scsi_cmnd_ptr )
12766+/*----------------------------------------------------------------------------*/
12767+{
12768+ scsi_cmnd_ptr->scsi_done = AAC_Done;
12769+
12770+ cmn_err( CE_DEBUG, "AAC_Command" );
12771+
12772+ // AacHba_DoScsiCmd() handles command processing, setting the
12773+ // result code and calling completion routine.
12774+ g_single_command_done = FALSE;
12775+
12776+ AacHba_DoScsiCmd( scsi_cmnd_ptr, 0 );
12777+ while( !g_single_command_done );
12778+ return( scsi_cmnd_ptr->result );
12779+}
12780+
12781+
12782+/*------------------------------------------------------------------------------
12783+ AAC_AbortCommand()
12784+
12785+ Abort command if possible.
12786+ *----------------------------------------------------------------------------*/
12787+int AAC_AbortCommand(
12788+ Scsi_Cmnd *scsi_cmnd_ptr )
12789+/*----------------------------------------------------------------------------*/
12790+{
12791+ int target = scsi_cmnd_ptr->target;
12792+ int hba = scsi_cmnd_ptr->host->unique_id;
12793+ int result = 0;
12794+ u_short interrupt_status;
12795+ PCI_MINIPORT_COMMON_EXTENSION *cep;
12796+ char *DeviceName;
12797+
12798+ cmn_err( CE_WARN, "%s:%d ABORT", g_DriverName, hba, target );
12799+ AacHba_AbortScsiCommand( scsi_cmnd_ptr );
12800+
12801+ cep = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
12802+ DeviceName = MiniPorts[cep->OsDep.MiniPortIndex].DeviceName;
12803+
12804+ /*
12805+ cmn_err( CE_WARN, "%s:%d Unable to abort command to target %d - "
12806+ "command already completed", DeviceName, hba, target);
12807+ result = SCSI_ABORT_NOT_RUNNING;
12808+
12809+ cmn_err(CE_WARN, "%s:%d Unable to abort command to target %d - "
12810+ "no command found\n", DeviceName, hba, target);
12811+ result = SCSI_ABORT_NOT_RUNNING;
12812+
12813+ cmn_err(CE_WARN, "%s:%d Unable to abort command to target %d - "
12814+ "command reset\n", DeviceName, hba, target);
12815+ result = SCSI_ABORT_PENDING;
12816+
12817+ cmn_err(CE_WARN, "%s:%d Unable to abort command to target %d - "
12818+ "abort tag not supported\n", DeviceName, hba, target);
12819+ result = SCSI_ABORT_SNOOZE;
12820+
12821+ cmn_err(CE_WARN, "%s:%d Aborting command to target %d - pending",
12822+ DeviceName, hba, target);
12823+ result = SCSI_ABORT_PENDING;
12824+
12825+ cmn_err(CE_WARN, "%s:%d Unable to abort command to target %d",
12826+ DeviceName, hba, target);
12827+ result = SCSI_ABORT_BUSY;
12828+
12829+ cmn_err(CE_WARN, "%s:%d Aborted command to target %d\n",
12830+ DeviceName, hba, target);
12831+ result = SCSI_ABORT_SUCCESS;
12832+ */
12833+
12834+ // Abort not supported yet
12835+ result = SCSI_ABORT_BUSY;
12836+ return result;
12837+}
12838+
12839+
12840+/*------------------------------------------------------------------------------
12841+ AAC_ResetCommand()
12842+
12843+ Reset command handling.
12844+ *----------------------------------------------------------------------------*/
12845+int AAC_ResetCommand(
12846+ struct scsi_cmnd *scsi_cmnd_ptr,
12847+ unsigned int reset_flags )
12848+/*----------------------------------------------------------------------------*/
12849+{
12850+ int target = scsi_cmnd_ptr->target;
12851+ int hba = scsi_cmnd_ptr->host->unique_id;
12852+ PCI_MINIPORT_COMMON_EXTENSION *cep;
12853+ char *DeviceName;
12854+
12855+ cep = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
12856+ DeviceName = MiniPorts[cep->OsDep.MiniPortIndex].DeviceName;
12857+
12858+ cmn_err( CE_WARN, "%s:%d RESET", DeviceName, hba, target );
12859+
12860+ return SCSI_RESET_PUNT;
12861+}
12862+
12863+
12864+/*------------------------------------------------------------------------------
12865+ AAC_DriverInfo()
12866+
12867+ Returns the host adapter name
12868+ *----------------------------------------------------------------------------*/
12869+const char *AAC_DriverInfo(
12870+ struct Scsi_Host *host_ptr )
12871+/*----------------------------------------------------------------------------*/
12872+{
12873+ PCI_MINIPORT_COMMON_EXTENSION *cep;
12874+ char *DeviceName;
12875+
12876+ cep = ( PCI_MINIPORT_COMMON_EXTENSION * )( host_ptr->hostdata );
12877+ DeviceName = MiniPorts[cep->OsDep.MiniPortIndex].DeviceName;
12878+
12879+ cmn_err( CE_DEBUG, "AAC_DriverInfo" );
12880+ return (DeviceName);
12881+}
12882+
12883+
12884+/*------------------------------------------------------------------------------
12885+ AAC_BIOSDiskParameters()
12886+
12887+ Return the Heads/Sectors/Cylinders BIOS Disk Parameters for Disk.
12888+ The default disk geometry is 64 heads, 32 sectors, and the appropriate
12889+ number of cylinders so as not to exceed drive capacity. In order for
12890+ disks equal to or larger than 1 GB to be addressable by the BIOS
12891+ without exceeding the BIOS limitation of 1024 cylinders, Extended
12892+ Translation should be enabled. With Extended Translation enabled,
12893+ drives between 1 GB inclusive and 2 GB exclusive are given a disk
12894+ geometry of 128 heads and 32 sectors, and drives above 2 GB inclusive
12895+ are given a disk geometry of 255 heads and 63 sectors. However, if
12896+ the BIOS detects that the Extended Translation setting does not match
12897+ the geometry in the partition table, then the translation inferred
12898+ from the partition table will be used by the BIOS, and a warning may
12899+ be displayed.
12900+ *----------------------------------------------------------------------------*/
12901+int AAC_BIOSDiskParameters(
12902+ Scsi_Disk *scsi_disk_ptr,
12903+ kdev_t device,
12904+ int *parameter_ptr )
12905+/*----------------------------------------------------------------------------*/
12906+{
12907+ AAC_BIOS_DiskParameters_T *disk_parameters =
12908+ ( AAC_BIOS_DiskParameters_T *)parameter_ptr;
12909+ struct buffer_head * buffer_head_ptr;
12910+
12911+ cmn_err( CE_DEBUG, "AAC_BIOSDiskParameters" );
12912+
12913+ // Assuming extended translation is enabled - #REVISIT#
12914+ if( scsi_disk_ptr->capacity >= 2 * 1024 * 1024 ) // 1 GB in 512 byte sectors
12915+ {
12916+ if( scsi_disk_ptr->capacity >= 4 * 1024 * 1024 ) // 2 GB in 512 byte sectors
12917+ {
12918+ disk_parameters->heads = 255;
12919+ disk_parameters->sectors = 63;
12920+ }
12921+ else
12922+ {
12923+ disk_parameters->heads = 128;
12924+ disk_parameters->sectors = 32;
12925+ }
12926+ }
12927+ else
12928+ {
12929+ disk_parameters->heads = 64;
12930+ disk_parameters->sectors = 32;
12931+ }
12932+
12933+ disk_parameters->cylinders = scsi_disk_ptr->capacity
12934+ /( disk_parameters->heads * disk_parameters->sectors );
12935+
12936+ // Read the first 1024 bytes from the disk device
12937+ buffer_head_ptr = bread(
12938+ MKDEV( MAJOR( device ),
12939+ MINOR( device ) & ~0x0F ),
12940+ 0, 1024 );
12941+
12942+ if( buffer_head_ptr == NULL )
12943+ return( 0 );
12944+ /*
12945+ If the boot sector partition table is valid, search for a partition
12946+ table entry whose end_head matches one of the standard geometry
12947+ translations ( 64/32, 128/32, 255/63 ).
12948+ */
12949+ if( *( unsigned short * )( buffer_head_ptr->b_data + 0x1fe ) == 0xaa55 )
12950+ {
12951+ struct partition *first_partition_entry =
12952+ ( struct partition * )( buffer_head_ptr->b_data + 0x1be );
12953+ struct partition *partition_entry = first_partition_entry;
12954+ int saved_cylinders = disk_parameters->cylinders;
12955+ int partition_number;
12956+ unsigned char partition_entry_end_head, partition_entry_end_sector;
12957+
12958+ for( partition_number = 0; partition_number < 4; partition_number++ )
12959+ {
12960+ partition_entry_end_head = partition_entry->end_head;
12961+ partition_entry_end_sector = partition_entry->end_sector & 0x3f;
12962+
12963+ if( partition_entry_end_head == ( 64 - 1 ) )
12964+ {
12965+ disk_parameters->heads = 64;
12966+ disk_parameters->sectors = 32;
12967+ break;
12968+ }
12969+ else if( partition_entry_end_head == ( 128 - 1 ) )
12970+ {
12971+ disk_parameters->heads = 128;
12972+ disk_parameters->sectors = 32;
12973+ break;
12974+ }
12975+ else if( partition_entry_end_head == ( 255 - 1 ) )
12976+ {
12977+ disk_parameters->heads = 255;
12978+ disk_parameters->sectors = 63;
12979+ break;
12980+ }
12981+ partition_entry++;
12982+ }
12983+
12984+ if( partition_number == 4 )
12985+ {
12986+ partition_entry_end_head = first_partition_entry->end_head;
12987+ partition_entry_end_sector = first_partition_entry->end_sector & 0x3f;
12988+ }
12989+
12990+ disk_parameters->cylinders = scsi_disk_ptr->capacity
12991+ /( disk_parameters->heads * disk_parameters->sectors );
12992+
12993+ if( ( partition_number < 4 ) && ( partition_entry_end_sector == disk_parameters->sectors ) )
12994+ {
12995+ if( disk_parameters->cylinders != saved_cylinders )
12996+ cmn_err( CE_DEBUG, "Adopting geometry: heads=%d, sectors=%d from partition table %d",
12997+ disk_parameters->heads, disk_parameters->sectors, partition_number );
12998+ }
12999+ else if( ( partition_entry_end_head > 0 ) || ( partition_entry_end_sector > 0 ) )
13000+ {
13001+ cmn_err( CE_DEBUG, "Strange geometry: heads=%d, sectors=%d in partition table %d",
13002+ partition_entry_end_head + 1, partition_entry_end_sector, partition_number );
13003+ cmn_err( CE_DEBUG, "Using geometry: heads=%d, sectors=%d",
13004+ disk_parameters->heads, disk_parameters->sectors );
13005+ }
13006+ }
13007+
13008+ brelse( buffer_head_ptr );
13009+
13010+ return( 0 );
13011+}
13012+
13013+
13014+/*------------------------------------------------------------------------------
13015+ AAC_SelectQueueDepths()
13016+
13017+ Selects queue depths for each target device based on the host adapter's
13018+ total capacity and the queue depth supported by the target device.
13019+ A queue depth of one automatically disables tagged queueing.
13020+ *----------------------------------------------------------------------------*/
13021+void AAC_SelectQueueDepths(
13022+ struct Scsi_Host * host_ptr,
13023+ Scsi_Device * scsi_device_ptr )
13024+/*----------------------------------------------------------------------------*/
13025+{
13026+ Scsi_Device * device_ptr;
13027+
13028+ cmn_err( CE_DEBUG, "AAC_SelectQueueDepths" );
13029+ cmn_err( CE_DEBUG, "Device # Q Depth Online" );
13030+ cmn_err( CE_DEBUG, "---------------------------" );
13031+ for( device_ptr = scsi_device_ptr; device_ptr != NULL; device_ptr = device_ptr->next )
13032+ if( device_ptr->host == host_ptr )
13033+ {
13034+ device_ptr->queue_depth = 10;
13035+ cmn_err( CE_DEBUG, " %2d %d %d",
13036+ device_ptr->id, device_ptr->queue_depth, device_ptr->online );
13037+ }
13038+}
13039+
13040+
13041+/*------------------------------------------------------------------------------
13042+ AAC_SearchBiosSignature()
13043+
13044+ Locate adapter signature in BIOS
13045+ *----------------------------------------------------------------------------*/
13046+int AAC_SearchBiosSignature( void )
13047+/*----------------------------------------------------------------------------*/
13048+{
13049+ unsigned base;
13050+ unsigned namep;
13051+ int index;
13052+ int val;
13053+ char name_buf[32];
13054+ int result = FALSE;
13055+
13056+ for( base = 0xc8000; base < 0xdffff; base += 0x4000 )
13057+ {
13058+ val = readb( base );
13059+ if( val != 0x55 )
13060+ continue;
13061+
13062+ result = TRUE;
13063+ namep = base + 0x1e;
13064+ memcpy_fromio( name_buf, namep, 32 );
13065+ name_buf[31] = '\0';
13066+ }
13067+ return( result );
13068+}
13069+
13070+
13071+/*------------------------------------------------------------------------------
13072+ AAC_Ioctl()
13073+
13074+ Handle SCSI ioctls
13075+ *----------------------------------------------------------------------------*/
13076+int AAC_Ioctl(
13077+ Scsi_Device * scsi_dev_ptr,
13078+ int cmd,
13079+ void * arg )
13080+/*----------------------------------------------------------------------------*/
13081+{
13082+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
13083+
13084+ cmn_err( CE_DEBUG, "AAC_Ioctl" );
13085+ CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )scsi_dev_ptr->host->hostdata;
13086+ return( AacHba_Ioctl( CommonExtensionPtr, cmd, arg ) );
13087+}
13088+
13089+
13090+
13091+/*------------------------------------------------------------------------------
13092+ AAC_ChardevOpen()
13093+
13094+ Handle character device open
13095+
13096+ Preconditions:
13097+ Postconditions:
13098+ Returns 0 if successful, -ENODEV or -EINVAL otherwise
13099+ *----------------------------------------------------------------------------*/
13100+int AAC_ChardevOpen(
13101+ struct inode * inode_ptr,
13102+ struct file * file_ptr )
13103+/*----------------------------------------------------------------------------*/
13104+{
13105+ unsigned minor_number;
13106+
13107+ cmn_err( CE_DEBUG, "AAC_ChardevOpen" );
13108+
13109+ // check device permissions in file_ptr->f_mode ??
13110+
13111+ // extract & check the minor number
13112+ minor_number = MINOR( inode_ptr->i_rdev );
13113+ if( minor_number > ( g_HostAdapterCount - 1 ) )
13114+ {
13115+ cmn_err( CE_WARN, "AAC_ChardevOpen: Minor number %d not supported", minor_number );
13116+ return( -ENODEV );
13117+ }
13118+
13119+#ifdef MODULE
13120+ MOD_INC_USE_COUNT;
13121+#endif
13122+
13123+ return( 0 );
13124+}
13125+
13126+
13127+/*------------------------------------------------------------------------------
13128+ AAC_ChardevRelease()
13129+
13130+ Handle character device release.
13131+
13132+ Preconditions:
13133+ Postconditions:
13134+ Returns 0 if successful, -ENODEV or -EINVAL otherwise
13135+ *----------------------------------------------------------------------------*/
13136+int AAC_ChardevRelease(
13137+ struct inode * inode_ptr,
13138+ struct file * file_ptr )
13139+/*----------------------------------------------------------------------------*/
13140+{
13141+ cmn_err( CE_DEBUG, "AAC_ChardevRelease" );
13142+
13143+#ifdef MODULE
13144+ MOD_DEC_USE_COUNT;
13145+#endif
13146+
13147+ return( 0 );
13148+}
13149+
13150+
13151+/*------------------------------------------------------------------------------
13152+ AAC_ChardevIoctl()
13153+
13154+ Handle character device interface ioctls
13155+
13156+ Preconditions:
13157+ Postconditions:
13158+ Returns 0 if successful, -ENODEV or -EINVAL otherwise
13159+ *----------------------------------------------------------------------------*/
13160+int AAC_ChardevIoctl(
13161+ struct inode * inode_ptr,
13162+ struct file * file_ptr,
13163+ unsigned int cmd,
13164+ unsigned long arg )
13165+{
13166+ unsigned minor_number;
13167+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
13168+
13169+ cmn_err( CE_DEBUG, "AAC_ChardevIoctl" );
13170+
13171+ // check device permissions in file_ptr->f_mode ??
13172+
13173+ // extract & check the minor number
13174+ minor_number = MINOR( inode_ptr->i_rdev );
13175+ if( minor_number > ( g_HostAdapterCount - 1 ) )
13176+ {
13177+ cmn_err( CE_WARN, "AAC_ChardevIoctl: Minor number %d not supported", minor_number );
13178+ return( -ENODEV );
13179+ }
13180+
13181+ // get device pointer
13182+ CommonExtensionPtr = g_CommonExtensionPtrArray[ minor_number ];
13183+
13184+ // dispatch ioctl - AacHba_Ioctl() returns zero on success
13185+ if( AacHba_Ioctl( CommonExtensionPtr, cmd, ( void * )arg ) )
13186+ return( -EINVAL );
13187+
13188+ return( 0 );
13189+}
13190+
13191+
13192+/*------------------------------------------------------------------------------
13193+ parse_keyword()
13194+
13195+ Look for the keyword in str_ptr
13196+
13197+ Preconditions:
13198+ Postconditions:
13199+ If keyword found
13200+ - return true and update the pointer str_ptr.
13201+ otherwise
13202+ - return false
13203+ *----------------------------------------------------------------------------*/
13204+static int parse_keyword(
13205+ char ** str_ptr,
13206+ char * keyword )
13207+/*----------------------------------------------------------------------------*/
13208+{
13209+ char * ptr = *str_ptr;
13210+
13211+ while( *keyword != '\0' )
13212+ {
13213+ char string_char = *ptr++;
13214+ char keyword_char = *keyword++;
13215+
13216+ if ( ( string_char >= 'A' ) && ( string_char <= 'Z' ) )
13217+ string_char += 'a' - 'Z';
13218+ if( ( keyword_char >= 'A' ) && ( keyword_char <= 'Z' ) )
13219+ keyword_char += 'a' - 'Z';
13220+ if( string_char != keyword_char )
13221+ return FALSE;
13222+ }
13223+ *str_ptr = ptr;
13224+ return TRUE;
13225+}
13226+
13227+
13228+/*------------------------------------------------------------------------------
13229+ AAC_ParseDriverOptions()
13230+
13231+ For modules the usage is:
13232+ insmod -f aacraid.o 'aacraid_options="<option_name:argument>"'
13233+ *----------------------------------------------------------------------------*/
13234+static void AAC_ParseDriverOptions(
13235+ char * cmnd_line_options_str )
13236+/*----------------------------------------------------------------------------*/
13237+{
13238+ int message_level;
13239+ int reverse_scan;
13240+ char *cp;
13241+ char *endp;
13242+
13243+ cp = cmnd_line_options_str;
13244+
13245+ cmn_err(CE_DEBUG, "AAC_ParseDriverOptions: <%s>", cp);
13246+
13247+ while( *cp ) {
13248+ if( parse_keyword( &cp, "message_level:" ) ) {
13249+ message_level = simple_strtoul( cp, 0, 0 );
13250+ if( ( message_level < CE_TAIL ) && ( message_level >= 0 ) ) {
13251+ g_options.message_level = message_level;
13252+ cmn_err( CE_WARN, "%s: new message level = %d", g_DriverName, g_options.message_level );
13253+ }
13254+ else {
13255+ cmn_err( CE_WARN, "%s: invalid message level = %d", g_DriverName, message_level );
13256+ }
13257+ } else if (parse_keyword( &cp, "reverse_scan:" ) ) {
13258+ reverse_scan = simple_strtoul( cp, 0, 0 );
13259+ if (reverse_scan) {
13260+ g_options.reverse_scan = 1;
13261+ cmn_err( CE_WARN, "%s: reversing device discovery order", g_DriverName, g_options.message_level );
13262+ }
13263+ }
13264+ else {
13265+ cmn_err( CE_WARN, "%s: unknown command line option <%s>", g_DriverName, cp );
13266+ }
13267+
13268+ /*
13269+ * skip to next option, accept " ", ";", and "," as delimiters
13270+ */
13271+ while ( *cp && (*cp != ' ') && (*cp != ';') && (*cp != ','))
13272+ cp++;
13273+
13274+ if (*cp) /* skip over the delimiter */
13275+ cp++;
13276+ }
13277+
13278+}
13279+
13280+
13281+/*------------------------------------------------------------------------------
13282+ Include Module support if requested.
13283+
13284+ To use the low level SCSI driver support using the linux kernel loadable
13285+ module interface we should initialize the global variable driver_interface
13286+ (datatype Scsi_Host_Template) and then include the file scsi_module.c.
13287+ This should also be wrapped in a #ifdef MODULE/#endif
13288+ *----------------------------------------------------------------------------*/
13289+#ifdef MODULE
13290+
13291+/*
13292+ The Loadable Kernel Module Installation Facility may pass us
13293+ a pointer to a driver specific options string to be parsed,
13294+ we assign this to options string.
13295+*/
13296+MODULE_PARM( module_options, "s" );
13297+
13298+Scsi_Host_Template driver_template = AAC_HOST_TEMPLATE_ENTRY;
13299+
13300+#include "scsi_module.c"
13301+
13302+#else
13303+Scsi_Host_Template driver_template = AAC_HOST_TEMPLATE_ENTRY;
13304+
13305+#include "scsi_module.c"
13306+#endif
13307+
13308+/*********************************************************************
13309+ AAC_ProcDirectoryInfo()
13310+
13311+ Implement /proc/scsi/<drivername>/<n>.
13312+ Used to export driver statistics and other infos to the world outside
13313+ the kernel using the proc file system. Also provides an interface to
13314+ feed the driver with information.
13315+
13316+ Postconditions
13317+ For reads
13318+ - if offset > 0 return 0
13319+ - if offset == 0 write data to proc_buffer and set the start_ptr to
13320+ beginning of proc_buffer, return the number of characters written.
13321+ For writes
13322+ - writes currently not supported, return 0
13323+************************************************************/
13324+int AAC_ProcDirectoryInfo(
13325+ char *proc_buffer, // read/write buffer
13326+ char **start_ptr, // start of valid data in the buffer
13327+ off_t offset, // offset from the beginning of the imaginary file
13328+ int bytes_available, // bytes available
13329+ int host_no, // SCSI host number
13330+ int write ) // direction of dataflow: TRUE for writes, FALSE for reads
13331+{
13332+ int length = 0;
13333+ cmn_err( CE_WARN, "AAC_ProcDirectoryInfo" );
13334+
13335+ if( ( write ) || ( offset > 0 ) )
13336+ return( 0 );
13337+
13338+ *start_ptr = proc_buffer;
13339+
13340+ return( sprintf(&proc_buffer[length], "%s %d\n", "Raid Controller, scsi hba number", host_no ) );
13341+}
13342+
13343+void aac_allocate_SyncFibs (PCI_MINIPORT_COMMON_EXTENSION *CommonExtension)
13344+{
13345+ void *BaseAddress;
13346+ ULONG PhysAddress;
13347+ int size;
13348+ int npages;
13349+ int i;
13350+
13351+ AFA_COMM_ADAPTER *Adapter;
13352+ Adapter = CommonExtension->Adapter;
13353+
13354+
13355+ // Allocate 1 fib for synch fibs
13356+ // Allocate 1 page.
13357+ BaseAddress = OsAllocMemory ( PAGE_SIZE, OS_ALLOC_MEM_SLEEP);
13358+ bzero(BaseAddress, PAGE_SIZE);
13359+ PhysAddress = virt_to_phys (BaseAddress);
13360+ Adapter->SyncFib = BaseAddress;
13361+ Adapter->SyncFibPhysicalAddress = PhysAddress;
13362+ cmn_err(CE_DEBUG,"aac_allocate_SyncFibs: syncFib: vaddr: 0x%x paddr: 0x%x ", BaseAddress, PhysAddress);
13363+
13364+}
13365diff -burN linux-2.4.7/drivers/scsi/aacraid/osddi.c linux/drivers/scsi/aacraid/osddi.c
13366--- linux-2.4.7/drivers/scsi/aacraid/osddi.c Wed Dec 31 18:00:00 1969
13367+++ linux/drivers/scsi/aacraid/osddi.c Sat Jul 21 17:55:14 2001
13368@@ -0,0 +1,512 @@
13369+/*++
13370+ * Adaptec aacraid device driver for Linux.
13371+ *
13372+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
13373+ *
13374+ * This program is free software; you can redistribute it and/or modify
13375+ * it under the terms of the GNU General Public License as published by
13376+ * the Free Software Foundation; either version 2, or (at your option)
13377+ * any later version.
13378+ *
13379+ * This program is distributed in the hope that it will be useful,
13380+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13381+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13382+ * GNU General Public License for more details.
13383+ *
13384+ * You should have received a copy of the GNU General Public License
13385+ * along with this program; see the file COPYING. If not, write to
13386+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
13387+ *
13388+ * Module Name:
13389+ * osddi.c
13390+ *
13391+ * Abstract: This file contains all the proceedures which use LINUX specific Device
13392+ * Driver Interfaces.
13393+ *
13394+ --*/
13395+
13396+static char *ident_osddi = "aacraid_ident osddi.c 1.0.6 2000/10/09 Adaptec, Inc.";
13397+
13398+#include "osheaders.h"
13399+
13400+#include <linux/smp_lock.h>
13401+
13402+#ifdef fsid_t
13403+#undef fsid_t
13404+#endif
13405+#include "AacGenericTypes.h"
13406+#include "aac_unix_defs.h"
13407+#include "comstruc.h"
13408+#include "monkerapi.h"
13409+#include "protocol.h"
13410+#include "fsafs.h"
13411+
13412+#include "sap1common.h"
13413+#include "fsaport.h"
13414+#include "pcisup.h"
13415+#include "sap1.h"
13416+#include "nodetype.h"
13417+#include "comsup.h"
13418+#include "afacomm.h"
13419+#include "adapter.h"
13420+
13421+
13422+void AacSaPciIsr(
13423+ int irq,
13424+ void * irq_data,
13425+ struct pt_regs *regs);
13426+
13427+void AacRxPciIsr(
13428+ int irq,
13429+ void * irq_data,
13430+ struct pt_regs *regs);
13431+
13432+unsigned SaPciIsr (
13433+ IN PSa_ADAPTER_EXTENSION AdapterExtension );
13434+
13435+unsigned RxPciIsr (
13436+ IN PSa_ADAPTER_EXTENSION AdapterExtension );
13437+
13438+
13439+/*----------------------------------------------------------------------------*/
13440+VOID AfaCommInterruptHost(
13441+ PVOID AdapterArg,
13442+ ADAPTER_EVENT AdapterEvent )
13443+/*----------------------------------------------------------------------------*/
13444+{
13445+ PAFA_COMM_ADAPTER Adapter = ( PAFA_COMM_ADAPTER ) AdapterArg;
13446+ PCOMM_REGION CommRegion = Adapter->CommRegion;
13447+
13448+ switch (AdapterEvent) {
13449+
13450+ case HostNormRespQue:
13451+ OsSoftInterruptTrigger( CommRegion->HostNormRespQue.ConsumerRoutine );
13452+
13453+ // #REVIEW# - what do we do with this
13454+ // if (FsaCommData.HardInterruptModeration)
13455+ // DisableInterrupt( Adapter, HostNormRespQue, TRUE );
13456+
13457+ break;
13458+
13459+ case AdapNormCmdNotFull:
13460+ OsSoftInterruptTrigger( CommRegion->QueueNotFullDpc );
13461+ break;
13462+
13463+ case HostNormCmdQue:
13464+ OsSoftInterruptTrigger( CommRegion->HostNormCmdQue.ConsumerRoutine );
13465+ break;
13466+
13467+ case AdapNormRespNotFull:
13468+ OsSoftInterruptTrigger( CommRegion->QueueNotFullDpc );
13469+ break;
13470+
13471+ // #REVIEW# - what do we do with these
13472+ case HostHighCmdQue:
13473+ case HostHighRespQue:
13474+ case AdapHighCmdNotFull:
13475+ case AdapHighRespNotFull:
13476+ case SynchCommandComplete:
13477+ case AdapInternalError:
13478+ break;
13479+ }
13480+}
13481+
13482+
13483+// get the device name associated with this instance of the device
13484+/*----------------------------------------------------------------------------*/
13485+char *OsGetDeviceName(
13486+ void *AdapterExtension )
13487+/*----------------------------------------------------------------------------*/
13488+{
13489+ return( ( ( Sa_ADAPTER_EXTENSION * )AdapterExtension )->Common->
13490+ OsDep.scsi_host_ptr->hostt->name );
13491+}
13492+
13493+
13494+/*----------------------------------------------------------------------------*/
13495+int OsGetDeviceInstance(
13496+ void *AdapterExtension )
13497+/*----------------------------------------------------------------------------*/
13498+{
13499+ return( ( int )( ( Sa_ADAPTER_EXTENSION * )AdapterExtension )->Common->
13500+ OsDep.scsi_host_ptr->unique_id );
13501+}
13502+
13503+
13504+/*------------------------------------------------------------------------------
13505+ OsMapDeviceRegisters()
13506+
13507+ Postconditions:
13508+ Return zero on success non-zero otherwise.
13509+ *----------------------------------------------------------------------------*/
13510+int OsMapDeviceRegisters(
13511+ Sa_ADAPTER_EXTENSION *AdapterExtension )
13512+/*----------------------------------------------------------------------------*/
13513+{
13514+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
13515+
13516+ CommonExtension = AdapterExtension->Common;
13517+
13518+ if( AdapterExtension->Device = ( Sa_DEVICE_REGISTERS * )
13519+ ioremap( ( unsigned long )CommonExtension->OsDep.scsi_host_ptr->base, 8192 ) )
13520+ {
13521+ cmn_err( CE_WARN, "Device mapped to virtual address 0x%x", AdapterExtension->Device );
13522+ return( 0 );
13523+ }
13524+ else
13525+ {
13526+ cmn_err( CE_WARN, "OsMapDeviceRegisters: ioremap() failed" );
13527+ return( 1 );
13528+ }
13529+}
13530+
13531+
13532+/*------------------------------------------------------------------------------
13533+ OsUnMapDeviceRegisters()
13534+
13535+ Postconditions:
13536+ *----------------------------------------------------------------------------*/
13537+void OsUnMapDeviceRegisters(
13538+ Sa_ADAPTER_EXTENSION *AdapterExtension )
13539+/*----------------------------------------------------------------------------*/
13540+{
13541+ iounmap( ( void * )AdapterExtension->Device );
13542+}
13543+
13544+
13545+/*----------------------------------------------------------------------------*/
13546+int OsAttachInterrupt(
13547+ Sa_ADAPTER_EXTENSION *AdapterExtension ,
13548+ int WhichIsr )
13549+/*----------------------------------------------------------------------------*/
13550+{
13551+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
13552+ void *irq_data;
13553+ void (*Isr)();
13554+
13555+ CommonExtension = AdapterExtension->Common;
13556+ irq_data = ( void * )AdapterExtension;
13557+
13558+ switch (WhichIsr) {
13559+ case SaISR:
13560+ Isr = AacSaPciIsr;
13561+ break;
13562+ case RxISR:
13563+ Isr = AacRxPciIsr;
13564+ break;
13565+ default:
13566+ cmn_err(CE_WARN, "OsAttachInterrupt: invalid ISR case: 0x%x", WhichIsr);
13567+ return( FAILURE );
13568+ break;
13569+ }
13570+
13571+
13572+ if ( OsRegisterInterrupt (
13573+ CommonExtension->OsDep.scsi_host_ptr->irq, // interrupt number
13574+ Isr, // handler function
13575+ irq_data )
13576+ )
13577+ {
13578+ cmn_err( CE_WARN, "OsAttachInterrupt: Failed for IRQ: 0x%x",
13579+ CommonExtension->OsDep.scsi_host_ptr->irq );
13580+ return( FAILURE );
13581+ }
13582+
13583+ return ( 0 );
13584+}
13585+
13586+
13587+/*----------------------------------------------------------------------------*/
13588+void AacSaPciIsr(
13589+ int irq,
13590+ void * irq_data,
13591+ struct pt_regs *regs)
13592+/*----------------------------------------------------------------------------*/
13593+{
13594+ // call the actual interrupt handler
13595+ SaPciIsr( ( Sa_ADAPTER_EXTENSION * )irq_data );
13596+}
13597+
13598+/*----------------------------------------------------------------------------*/
13599+void AacRxPciIsr(
13600+ int irq,
13601+ void * irq_data,
13602+ struct pt_regs *regs)
13603+/*----------------------------------------------------------------------------*/
13604+{
13605+ // call the actual interrupt handler
13606+ RxPciIsr( ( Sa_ADAPTER_EXTENSION * )irq_data );
13607+}
13608+
13609+
13610+/*----------------------------------------------------------------------------*/
13611+void OsDetachInterrupt(
13612+ Sa_ADAPTER_EXTENSION *AdapterExtension )
13613+/*----------------------------------------------------------------------------*/
13614+{
13615+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
13616+ void *irq_data;
13617+
13618+ CommonExtension = AdapterExtension->Common;
13619+ irq_data = ( void * )AdapterExtension;
13620+
13621+ OsUnregisterInterrupt (
13622+ CommonExtension->OsDep.scsi_host_ptr->irq, // interrupt number
13623+ irq_data );
13624+}
13625+
13626+
13627+/*----------------------------------------------------------------------------*/
13628+int OsAttachDMA(
13629+ Sa_ADAPTER_EXTENSION *AdapterExtension )
13630+/*----------------------------------------------------------------------------*/
13631+{
13632+ return( 0 );
13633+}
13634+
13635+/*----------------------------------------------------------------------------*/
13636+int OsAttachHBA(
13637+ Sa_ADAPTER_EXTENSION *AdapterExtension )
13638+/*----------------------------------------------------------------------------*/
13639+{
13640+ return( 0 );
13641+}
13642+
13643+/*----------------------------------------------------------------------------*/
13644+void OsDetachDevice(
13645+ Sa_ADAPTER_EXTENSION *AdapterExtension )
13646+/*----------------------------------------------------------------------------*/
13647+{
13648+ OsUnMapDeviceRegisters( AdapterExtension );
13649+ return( 0 );
13650+}
13651+
13652+/*----------------------------------------------------------------------------*/
13653+ULONG *OsAllocCommPhysMem(
13654+ Sa_ADAPTER_EXTENSION *AdapterExtension,
13655+ ULONG size,
13656+ ULONG **virt_addr_pptr,
13657+ ULONG *phys_addr_ptr )
13658+/*----------------------------------------------------------------------------*/
13659+{
13660+ if( ( *virt_addr_pptr = ( ULONG * )OsAllocMemory( size, GFP_KERNEL ) ) )
13661+ {
13662+ *phys_addr_ptr = OsVirtToPhys( ( volatile void * )*virt_addr_pptr );
13663+ if( !*phys_addr_ptr )
13664+ {
13665+ cmn_err( CE_WARN, "OsAllocCommPhysMem: OsVirtToPhys failed" );
13666+ }
13667+
13668+ return( *virt_addr_pptr );
13669+ }
13670+ else
13671+ return( NULL );
13672+}
13673+
13674+OsAifKernelThread(
13675+ Sa_ADAPTER_EXTENSION *AdapterExtension )
13676+{
13677+
13678+ struct fs_struct *fs;
13679+ int i;
13680+ struct task_struct *tsk;
13681+
13682+ tsk = current;
13683+
13684+
13685+ /*
13686+ * set up the name that will appear in 'ps'
13687+ * stored in task_struct.comm[16].
13688+ */
13689+
13690+ sprintf(tsk->comm, "AIFd");
13691+
13692+
13693+ // use_init_fs_context(); only exists in 2.2.13 onward.
13694+
13695+#ifdef CONFIG_SMP
13696+ lock_kernel();
13697+#endif
13698+
13699+ /*
13700+ * we were started as a result of loading the module.
13701+ * free all of user space pages
13702+ */
13703+
13704+ exit_mm(tsk);
13705+
13706+ exit_files(tsk);
13707+
13708+ exit_fs(tsk);
13709+
13710+ fs = init_task.fs;
13711+ tsk->fs = fs;
13712+
13713+ tsk->session = 1;
13714+ tsk->pgrp = 1;
13715+
13716+ if (fs)
13717+ atomic_inc(&fs->count);
13718+
13719+#ifdef CONFIG_SMP
13720+ unlock_kernel();
13721+#endif
13722+
13723+
13724+
13725+
13726+ NormCommandThread(AdapterExtension);
13727+ /* NOT REACHED */
13728+}
13729+
13730+/*----------------------------------------------------------------------------*/
13731+void OsStartKernelThreads(
13732+ Sa_ADAPTER_EXTENSION *AdapterExtension )
13733+/*----------------------------------------------------------------------------*/
13734+{
13735+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
13736+ AFA_COMM_ADAPTER *Adapter;
13737+ extern void NormCommandThread(void *Adapter);
13738+
13739+ CommonExtension = AdapterExtension->Common;
13740+ Adapter = (AFA_COMM_ADAPTER *)CommonExtension->Adapter;
13741+
13742+ //
13743+ // Start thread which will handle interrupts for this adapter
13744+ //
13745+ //kthread_spawn(FsaCommIntrHandler, AdapterExtension, "fsaintr",0);
13746+
13747+ //
13748+ // Start thread which will handle AdapterInititatedFibs from this adapter
13749+ //
13750+ CommonExtension->OsDep.thread_pid =
13751+ kernel_thread( ( int ( * )( void * ) )OsAifKernelThread, Adapter, 0 );
13752+// kernel_thread( ( int ( * )( void * ) )NormCommandThread, Adapter, 0 );
13753+}
13754+
13755+/*----------------------------------------------------------------------------*/
13756+BOOLEAN AfaPortAllocateAndMapFibSpace(
13757+ PVOID Arg1,
13758+ IN PMAPFIB_CONTEXT MapFibContext )
13759+/*----------------------------------------------------------------------------*/
13760+{
13761+ PVOID BaseAddress;
13762+ ULONG PhysAddress;
13763+
13764+ if( !( BaseAddress = (ULONG *)OsAllocMemory( MapFibContext->Size, GFP_KERNEL ) ) )
13765+ {
13766+ cmn_err( CE_WARN, "AfaPortAllocateAndMapFibSpace: OsAllocMemory failed" );
13767+ return( FALSE );
13768+ }
13769+
13770+ PhysAddress = OsVirtToPhys( BaseAddress );
13771+
13772+ MapFibContext->FibVirtualAddress = BaseAddress;
13773+ MapFibContext->FibPhysicalAddress = (PVOID) PhysAddress;
13774+
13775+ return (TRUE);
13776+}
13777+
13778+/*----------------------------------------------------------------------------*/
13779+BOOLEAN AfaPortUnmapAndFreeFibSpace(
13780+ PVOID Arg1,
13781+ IN PMAPFIB_CONTEXT MapFibContext )
13782+/*----------------------------------------------------------------------------*/
13783+{
13784+ PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
13785+
13786+ OsFreeMemory( MapFibContext->FibVirtualAddress, 0 );
13787+
13788+ return (TRUE);
13789+}
13790+
13791+/*----------------------------------------------------------------------------*/
13792+BOOLEAN AfaPortFreeAdapterCommArea(
13793+ IN PVOID Arg1 )
13794+/*----------------------------------------------------------------------------*/
13795+{
13796+ PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
13797+
13798+ OsFreeMemory( CommonExtension->CommAddress, 0 );
13799+
13800+ return (TRUE);
13801+}
13802+
13803+
13804+/* ================================================================================ */
13805+/*
13806+ * Not sure if the functions below here ever get called in the current code
13807+ * These probably should be a different file.
13808+ */
13809+/*
13810+ddi_dma_attr_t AfaPortDmaAttributes = {
13811+ //rpbfix : we may want something different for I/O
13812+ DMA_ATTR_V0,
13813+ 0,
13814+ 0xffffffff,
13815+ 0x0000ffff,
13816+ 1,
13817+ 1,
13818+ 1,
13819+ 0x0000ffff,
13820+ 0x0000ffff,
13821+ 17,
13822+ 512,
13823+ 0
13824+};
13825+*/
13826+
13827+AAC_STATUS
13828+AfaPortBuildSgMap(
13829+ PVOID Arg1,
13830+ IN PSGMAP_CONTEXT SgMapContext
13831+ )
13832+
13833+/*++
13834+
13835+Routine Description:
13836+
13837+ This routine build a scatter gather map using the information
13838+ in the SgMapContext.
13839+
13840+Arguments:
13841+
13842+ AdapterExtension - Pointer to adapter extension structure.
13843+ SgMapContext - Pointer to the SgMapContext for the request.
13844+
13845+
13846+Return Value:
13847+
13848+ AAC_STATUS
13849+--*/
13850+{
13851+ printk( KERN_ALERT "AfaPortBuildSgMap: unimplemented function called" );
13852+ return (STATUS_UNSUCCESSFUL);
13853+}
13854+
13855+VOID
13856+AfaPortFreeDmaResources(
13857+ PVOID Arg1,
13858+ IN PSGMAP_CONTEXT SgMapContext
13859+ )
13860+
13861+/*++
13862+
13863+Routine Description:
13864+
13865+ Given a pointer to the IRP context will free all reserved DMA resources allocated for
13866+ the completed IO operation.
13867+
13868+Arguments:
13869+
13870+ Fib - Pointer to the Fib the caller wishes to have transfered over to the adapter.
13871+ Context - Pointer to the Irp Context we use to store the dma mapping information
13872+ we need to do and complete the IO.
13873+
13874+Return Value:
13875+
13876+ Nothing
13877+
13878+--*/
13879+{
13880+}
13881diff -burN linux-2.4.7/drivers/scsi/aacraid/osfuncs.c linux/drivers/scsi/aacraid/osfuncs.c
13882--- linux-2.4.7/drivers/scsi/aacraid/osfuncs.c Wed Dec 31 18:00:00 1969
13883+++ linux/drivers/scsi/aacraid/osfuncs.c Sat Jul 21 17:55:14 2001
13884@@ -0,0 +1,598 @@
13885+/*++
13886+ * Adaptec aacraid device driver for Linux.
13887+ *
13888+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
13889+ *
13890+ * This program is free software; you can redistribute it and/or modify
13891+ * it under the terms of the GNU General Public License as published by
13892+ * the Free Software Foundation; either version 2, or (at your option)
13893+ * any later version.
13894+ *
13895+ * This program is distributed in the hope that it will be useful,
13896+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13897+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13898+ * GNU General Public License for more details.
13899+ *
13900+ * You should have received a copy of the GNU General Public License
13901+ * along with this program; see the file COPYING. If not, write to
13902+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
13903+ *
13904+ * Module Name:
13905+ * osfuncs.c
13906+ *
13907+ * Abstract: Holds all of the O/S specific interface functions.
13908+ *
13909+ --*/
13910+
13911+static char *ident_osfuncs = "aacraid_ident osfuncs.c 1.0.6 2000/10/09 Adaptec, Inc.";
13912+
13913+#include "osheaders.h"
13914+
13915+//static LKINFO_DECL(fsa_locks, "fsa_locks",0);
13916+
13917+extern aac_options_t g_options;
13918+
13919+OS_SOFTINTR g_idle_task = { 0, 0, 0, 0 };
13920+wait_queue_t * g_wait_queue_ptr = NULL;
13921+wait_queue_t g_wait;
13922+
13923+void OsTimeoutHandler(
13924+ struct semaphore * sem );
13925+
13926+int * OsIdleTask( void * data );
13927+
13928+//-----------------------------------------------------------------------------
13929+// Memory Allocation functions
13930+
13931+/*----------------------------------------------------------------------------*/
13932+void * OsAllocMemory(
13933+ OS_SIZE_T Size,
13934+ unsigned int Flags )
13935+/*----------------------------------------------------------------------------*/
13936+{
13937+ void *mem_ptr;
13938+
13939+ if( !( mem_ptr = kmalloc( Size, GFP_KERNEL ) ) )
13940+ cmn_err( CE_WARN, "OsAllocMemory: FAILED\n" );
13941+ return( mem_ptr );
13942+}
13943+
13944+
13945+/*----------------------------------------------------------------------------*/
13946+void OsFreeMemory(
13947+ void * Buffer,
13948+ OS_SIZE_T Size )
13949+/*----------------------------------------------------------------------------*/
13950+{
13951+ kfree( Buffer );
13952+}
13953+
13954+
13955+/*----------------------------------------------------------------------------*/
13956+int OsRegisterInterrupt(
13957+ unsigned int irq, // interrupt number
13958+ void ( *handler )( int, void*, struct pt_regs * ), // handler function
13959+ void *irq_data ) // argument to handler function
13960+/*----------------------------------------------------------------------------*/
13961+{
13962+ return( request_irq (irq, handler, SA_INTERRUPT | SA_SHIRQ, "aacraid", irq_data ) );
13963+}
13964+
13965+
13966+/*----------------------------------------------------------------------------*/
13967+void OsUnregisterInterrupt(
13968+ unsigned int irq, // interrupt number
13969+ void *irq_data)
13970+/*----------------------------------------------------------------------------*/
13971+{
13972+ free_irq (
13973+ irq, // interrupt number
13974+ irq_data );
13975+}
13976+
13977+
13978+/*----------------------------------------------------------------------------*/
13979+unsigned long OsVirtToPhys(
13980+ void * virtual_address )
13981+/*----------------------------------------------------------------------------*/
13982+{
13983+ return( virt_to_phys( virtual_address ) );
13984+}
13985+
13986+
13987+//-----------------------------------------------------------------------------
13988+// MUTEX functions
13989+
13990+/*----------------------------------------------------------------------------*/
13991+OS_STATUS OsMutexInit(
13992+ OS_MUTEX *Mutex,
13993+ OS_SPINLOCK_COOKIE Cookie )
13994+/*----------------------------------------------------------------------------*/
13995+{
13996+ Mutex->lock_var = 0;
13997+ // bzero (&Mutex->wq, sizeof (Mutex->wq));
13998+ init_waitqueue_head (&Mutex->wq);
13999+ return ( 0 );
14000+}
14001+
14002+
14003+/*----------------------------------------------------------------------------*/
14004+void OsMutexDestroy(
14005+ OS_MUTEX *Mutex )
14006+/*----------------------------------------------------------------------------*/
14007+{
14008+}
14009+
14010+
14011+/*----------------------------------------------------------------------------*/
14012+void OsMutexAcquire(
14013+ OS_MUTEX *Mutex )
14014+/*----------------------------------------------------------------------------*/
14015+{
14016+ // wait_queue_t wait = { current, NULL };
14017+ unsigned long time_stamp;
14018+
14019+ DECLARE_WAITQUEUE (wait, current);
14020+
14021+ time_stamp = jiffies;
14022+
14023+ if( test_and_set_bit( 0, &( Mutex->lock_var ) ) != 0 )
14024+ {
14025+ if( in_interrupt() )
14026+ panic( "OsMutexAcquire going to sleep at interrupt time\n" );
14027+ current->state = TASK_INTERRUPTIBLE;
14028+ add_wait_queue( &( Mutex->wq ), &wait );
14029+ while( test_and_set_bit( 0, &( Mutex->lock_var ) ) != 0 )
14030+ schedule();
14031+ remove_wait_queue( &( Mutex->wq ), &wait );
14032+ }
14033+
14034+ if( ( jiffies - 1 ) > time_stamp )
14035+ cmn_err( CE_WARN, "Mutex %ld locked out for %ld ticks",
14036+ Mutex, jiffies - time_stamp );
14037+}
14038+
14039+
14040+/*----------------------------------------------------------------------------*/
14041+void OsMutexRelease(
14042+ OS_MUTEX *Mutex )
14043+/*----------------------------------------------------------------------------*/
14044+{
14045+ if( test_and_clear_bit( 0, &( Mutex->lock_var ) ) == 0 )
14046+ cmn_err( CE_WARN, "OsMutexRelease: mutex not locked" );
14047+ wake_up_interruptible( &( Mutex->wq ) );
14048+}
14049+
14050+// see man hierarchy(D5)
14051+#define FSA_LOCK 1
14052+
14053+//-----------------------------------------------------------------------------
14054+// Spinlock functions
14055+
14056+/*----------------------------------------------------------------------------*/
14057+OS_SPINLOCK * OsSpinLockAlloc( void )
14058+/*----------------------------------------------------------------------------*/
14059+{
14060+ OS_SPINLOCK *SpinLock;
14061+ int i;
14062+
14063+
14064+ SpinLock = ( OS_SPINLOCK * )kmalloc( sizeof( OS_SPINLOCK ), GFP_KERNEL );
14065+
14066+ if (SpinLock == NULL)
14067+ cmn_err (CE_WARN, "WARNING: OsSpinLockAlloc Failed!!!");
14068+
14069+ SpinLock->spin_lock = SPIN_LOCK_UNLOCKED;
14070+ for( i = 0; i < NR_CPUS; i++ )
14071+ SpinLock->cpu_lock_count[ i ] = 0;
14072+ return( SpinLock );
14073+}
14074+
14075+
14076+/*----------------------------------------------------------------------------*/
14077+OS_STATUS OsSpinLockInit(
14078+ OS_SPINLOCK *SpinLock,
14079+ OS_SPINLOCK_COOKIE Cookie )
14080+/*----------------------------------------------------------------------------*/
14081+{
14082+ return( 0 );
14083+}
14084+
14085+
14086+/*----------------------------------------------------------------------------*/
14087+void OsSpinLockDestroy(
14088+ OS_SPINLOCK *SpinLock )
14089+/*----------------------------------------------------------------------------*/
14090+{
14091+ kfree( SpinLock );
14092+ SpinLock = NULL;
14093+}
14094+
14095+
14096+/*----------------------------------------------------------------------------*/
14097+void OsSpinLockAcquire(
14098+ OS_SPINLOCK *SpinLock )
14099+/*----------------------------------------------------------------------------*/
14100+{
14101+ unsigned cpu_id;
14102+
14103+ if( SpinLock )
14104+ {
14105+ cpu_id = smp_processor_id();
14106+ if( SpinLock->cpu_lock_count[ cpu_id ] ){
14107+ cmn_err (CE_PANIC, "CPU %d trying to acquire lock again: lock count = %d\n",
14108+ cpu_id, SpinLock->cpu_lock_count[ cpu_id ]);
14109+ }
14110+
14111+ spin_lock_irqsave( &( SpinLock->spin_lock ), SpinLock->cpu_flags[ cpu_id ] );
14112+ SpinLock->cpu_lock_count[ cpu_id ]++;
14113+
14114+ } else {
14115+ cmn_err( CE_WARN, "OsSpinLockAcquire: lock does not exist" );
14116+ }
14117+}
14118+
14119+
14120+/*----------------------------------------------------------------------------*/
14121+void OsSpinLockRelease(
14122+ OS_SPINLOCK *SpinLock )
14123+/*----------------------------------------------------------------------------*/
14124+{
14125+ unsigned cpu_id;
14126+
14127+ if( SpinLock )
14128+ {
14129+ cpu_id = smp_processor_id();
14130+ SpinLock->cpu_lock_count[ cpu_id ]--;
14131+ spin_unlock_irqrestore( &( SpinLock->spin_lock ), SpinLock->cpu_flags[ cpu_id ] );
14132+ }
14133+ else
14134+ cmn_err( CE_WARN, "OsSpinLockRelease: lock does not exist" );
14135+}
14136+
14137+
14138+/*----------------------------------------------------------------------------*/
14139+int OsSpinLockOwned(
14140+ OS_SPINLOCK *SpinLock )
14141+/*----------------------------------------------------------------------------*/
14142+{
14143+#ifdef CONFIG_SMP
14144+ if( SpinLock->spin_lock.lock != 0 )
14145+ return( 1 );
14146+ else
14147+#endif
14148+ return( 0 );
14149+}
14150+
14151+
14152+//-----------------------------------------------------------------------------
14153+// CvLock functions
14154+
14155+/*----------------------------------------------------------------------------*/
14156+OS_CVLOCK *OsCvLockAlloc( void )
14157+{
14158+ OS_CVLOCK *cv_lock;
14159+
14160+
14161+#ifdef CVLOCK_USE_SPINLOCK
14162+ cv_lock = OsSpinLockAlloc();
14163+#else
14164+ cv_lock = ( OS_CVLOCK * )kmalloc( sizeof( OS_CVLOCK ), GFP_KERNEL );
14165+ cv_lock->wq = NULL;
14166+ cv_lock->lock_var = 0;
14167+#endif
14168+
14169+ return( cv_lock );
14170+}
14171+
14172+
14173+/*----------------------------------------------------------------------------*/
14174+OS_STATUS OsCvLockInit(
14175+ OS_CVLOCK *cv_lock,
14176+ OS_SPINLOCK_COOKIE Cookie )
14177+/*----------------------------------------------------------------------------*/
14178+{
14179+ return ( 0 );
14180+}
14181+
14182+
14183+/*----------------------------------------------------------------------------*/
14184+void OsCvLockDestroy(
14185+ OS_CVLOCK *cv_lock )
14186+/*----------------------------------------------------------------------------*/
14187+{
14188+ if( cv_lock )
14189+ kfree( cv_lock );
14190+ cv_lock = NULL;
14191+}
14192+
14193+
14194+/*----------------------------------------------------------------------------*/
14195+void OsCvLockAcquire (OS_CVLOCK *cv_lock)
14196+{
14197+#ifdef CVLOCK_USE_SPINLOCK
14198+ OsSpinLockAcquire( cv_lock );
14199+#else
14200+ OsMutexAcquire( cv_lock );
14201+#endif
14202+}
14203+
14204+
14205+/*----------------------------------------------------------------------------*/
14206+void OsCvLockRelease(
14207+ OS_CVLOCK *cv_lock )
14208+/*----------------------------------------------------------------------------*/
14209+{
14210+#ifdef CVLOCK_USE_SPINLOCK
14211+ OsSpinLockRelease( cv_lock );
14212+#else
14213+ OsMutexRelease( cv_lock );
14214+#endif
14215+}
14216+
14217+
14218+/*----------------------------------------------------------------------------*/
14219+int OsCvLockOwned(
14220+ OS_CVLOCK *cv_lock )
14221+/*----------------------------------------------------------------------------*/
14222+{
14223+ return( 1 );
14224+}
14225+
14226+
14227+//-----------------------------------------------------------------------------
14228+// Conditional variable functions
14229+
14230+/*----------------------------------------------------------------------------*/
14231+void OsCv_init (
14232+ OS_CV_T *cv_ptr )
14233+/*----------------------------------------------------------------------------*/
14234+{
14235+ cv_ptr->lock_var = 1;
14236+ init_waitqueue_head (&cv_ptr->wq);
14237+}
14238+
14239+
14240+/*----------------------------------------------------------------------------*/
14241+void OsCv_destroy(
14242+ OS_CV_T *cv_ptr )
14243+/*----------------------------------------------------------------------------*/
14244+{
14245+}
14246+
14247+
14248+/*______________________________________________________________________________
14249+ -
14250+ -
14251+ -----------------------------------------------------------------------------*/
14252+OsCv_wait (OS_CV_T *cv_ptr, OS_CVLOCK *cv_lock_ptr)
14253+{
14254+ unsigned long flags;
14255+
14256+ DECLARE_WAITQUEUE (wait, current);
14257+
14258+ if( in_interrupt() )
14259+ panic( "OsCv_wait going to sleep at interrupt time\n" );
14260+
14261+ cv_ptr->type = TASK_UNINTERRUPTIBLE;
14262+ current->state = TASK_UNINTERRUPTIBLE;
14263+
14264+ add_wait_queue( &cv_ptr->wq, &wait );
14265+
14266+ OsCvLockRelease( cv_lock_ptr );
14267+ schedule();
14268+
14269+ while( test_and_set_bit( 0, &( cv_ptr->lock_var ) ) != 0 )
14270+ {
14271+ if( in_interrupt() )
14272+ panic( "OsCv_wait going to sleep at interrupt time\n" );
14273+ schedule();
14274+ }
14275+
14276+ remove_wait_queue( &( cv_ptr->wq ), &wait );
14277+
14278+ OsCvLockAcquire( cv_lock_ptr );
14279+}
14280+
14281+
14282+/*----------------------------------------------------------------------------*/
14283+int OsCv_wait_sig(
14284+ OS_CV_T *cv_ptr,
14285+ OS_CVLOCK *cv_lock_ptr )
14286+/*----------------------------------------------------------------------------*/
14287+{
14288+ unsigned long flags;
14289+ int signal_state = 1;
14290+
14291+ DECLARE_WAITQUEUE (wait, current);
14292+
14293+ if( in_interrupt() )
14294+ panic( "OsCv_wait_sig going to sleep at interrupt time\n" );
14295+
14296+ cv_ptr->type = TASK_INTERRUPTIBLE;
14297+ current->state = TASK_INTERRUPTIBLE;
14298+
14299+ add_wait_queue( &( cv_ptr->wq ), &wait );
14300+
14301+ OsCvLockRelease( cv_lock_ptr );
14302+ schedule();
14303+
14304+ while( ( test_and_set_bit( 0, &( cv_ptr->lock_var ) ) != 0 ) &&
14305+ ( !signal_pending( current ) ) )
14306+ {
14307+ if( in_interrupt() )
14308+ panic( "OsCv_wait_sig going to sleep at interrupt time\n" );
14309+ schedule();
14310+ }
14311+
14312+ if( signal_pending( current ) )
14313+ signal_state = 0;
14314+
14315+ remove_wait_queue( &( cv_ptr->wq ), &wait );
14316+
14317+ OsCvLockAcquire( cv_lock_ptr );
14318+ return( signal_state );
14319+}
14320+
14321+
14322+/*----------------------------------------------------------------------------*/
14323+void OsCv_signal(
14324+ OS_CV_T *cv_ptr )
14325+/*----------------------------------------------------------------------------*/
14326+{
14327+
14328+ clear_bit( 0, &( cv_ptr->lock_var ) );
14329+ if( cv_ptr->type == TASK_INTERRUPTIBLE )
14330+ wake_up_interruptible( &( cv_ptr->wq ) );
14331+ else{
14332+ wake_up( &( cv_ptr->wq ) );
14333+ }
14334+}
14335+
14336+
14337+// return time in seconds
14338+/*----------------------------------------------------------------------------*/
14339+unsigned long OsGetSeconds( void )
14340+/*----------------------------------------------------------------------------*/
14341+{
14342+ return( jiffies/HZ );
14343+}
14344+
14345+
14346+//-----------------------------------------------------------------------------
14347+// Deferred procedure call functions
14348+
14349+// create a soft interrupt object
14350+/*----------------------------------------------------------------------------*/
14351+int OsSoftInterruptAdd(
14352+ OS_SOFTINTR **ptr,
14353+ void * handler,
14354+ void * data )
14355+/*----------------------------------------------------------------------------*/
14356+{
14357+ OS_SOFTINTR *tmp_ptr;
14358+
14359+ if( !( tmp_ptr = ( OS_SOFTINTR * )kmalloc( sizeof( OS_SOFTINTR ), GFP_KERNEL ) ) )
14360+ return( -1 );
14361+ tmp_ptr->routine = handler;
14362+ tmp_ptr->data = data;
14363+ tmp_ptr->sync = 0;
14364+
14365+ *ptr = tmp_ptr;
14366+
14367+ return( 0 );
14368+}
14369+
14370+/*
14371+ Use kernel_thread( ( int ( * )( void * ) )OsIdleTask, NULL, 0 ); to start
14372+*/
14373+/*----------------------------------------------------------------------------*/
14374+int * OsIdleTask( void * data )
14375+/*----------------------------------------------------------------------------*/
14376+{
14377+ DECLARE_WAITQUEUE (wait, current);
14378+
14379+ while( 1 )
14380+ {
14381+ current->state = TASK_INTERRUPTIBLE;
14382+ add_wait_queue( &g_wait_queue_ptr, &wait );
14383+ schedule();
14384+ remove_wait_queue( &g_wait_queue_ptr, &wait );
14385+ wait.task = current;
14386+ wait.task_list.next = NULL;
14387+ }
14388+ return( NULL );
14389+}
14390+
14391+
14392+// dispatch a soft interrupt
14393+/*----------------------------------------------------------------------------*/
14394+void OsSoftInterruptTrigger(
14395+ OS_SOFTINTR *soft_intr_ptr )
14396+/*----------------------------------------------------------------------------*/
14397+{
14398+ // call the completion routine directly
14399+ soft_intr_ptr->routine( soft_intr_ptr->data );
14400+}
14401+
14402+
14403+// delete a soft interrupt object
14404+/*----------------------------------------------------------------------------*/
14405+void OsSoftInterruptRemove(
14406+ OS_SOFTINTR *arg )
14407+/*----------------------------------------------------------------------------*/
14408+{
14409+ if( arg )
14410+ kfree( arg );
14411+ arg = NULL;
14412+}
14413+
14414+
14415+/*----------------------------------------------------------------------------*/
14416+void OsSleep(
14417+ unsigned time ) // in seconds
14418+/*----------------------------------------------------------------------------*/
14419+{
14420+ struct semaphore sem;
14421+ struct timer_list timer_var;
14422+
14423+ init_MUTEX_LOCKED (&sem);
14424+
14425+ // if( in_interrupt() )
14426+ // panic( "OsSleep going to sleep at interrupt time\n" );
14427+
14428+ init_timer( &timer_var );
14429+ timer_var.function = ( void ( * )( unsigned long ) )OsTimeoutHandler;
14430+ timer_var.data = ( unsigned long )&sem;
14431+ timer_var.expires = jiffies + time * HZ;
14432+
14433+ add_timer( &timer_var );
14434+ down( &sem );
14435+
14436+ del_timer( &timer_var );
14437+}
14438+
14439+
14440+/*----------------------------------------------------------------------------*/
14441+void OsTimeoutHandler(
14442+ struct semaphore * sem )
14443+/*----------------------------------------------------------------------------*/
14444+{
14445+ if( sem != NULL )
14446+ up( sem );
14447+}
14448+
14449+
14450+/*----------------------------------------------------------------------------*/
14451+void printk_err(
14452+ int flag,
14453+ char *fmt,
14454+ ...)
14455+/*----------------------------------------------------------------------------*/
14456+{
14457+ char buf[256];
14458+ va_list ap;
14459+
14460+ va_start(ap, fmt);
14461+ (void) vsprintf(buf, fmt, ap);
14462+ va_end(ap);
14463+
14464+ if( flag <= g_options.message_level )
14465+ printk(KERN_ALERT "%s\n", buf);
14466+}
14467+
14468+/* void aac_show_tasks (struct list_head *our_tasks){ */
14469+
14470+/* cmn_err (CE_DEBUG, "Entering aac_show_tasks"); */
14471+
14472+/* if (our_tasks->next == NULL || our_tasks->next == 0) */
14473+/* cmn_err (CE_DEBUG, "list_head->next is NULL or 0"); */
14474+/* else */
14475+/* cmn_err (CE_DEBUG, "list_head->next: 0x%x", our_tasks->next); */
14476+
14477+/* if (our_tasks->prev == NULL || our_tasks->prev == 0) */
14478+/* cmn_err (CE_DEBUG, "list_head->prev is NULL or 0"); */
14479+/* else */
14480+/* cmn_err (CE_DEBUG, "list_head->prev: 0x%x", our_tasks->prev); */
14481+
14482+/* } */
14483diff -burN linux-2.4.7/drivers/scsi/aacraid/ossup.c linux/drivers/scsi/aacraid/ossup.c
14484--- linux-2.4.7/drivers/scsi/aacraid/ossup.c Wed Dec 31 18:00:00 1969
14485+++ linux/drivers/scsi/aacraid/ossup.c Sat Jul 21 17:55:14 2001
14486@@ -0,0 +1,199 @@
14487+/*++
14488+ * Adaptec aacraid device driver for Linux.
14489+ *
14490+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
14491+ *
14492+ * This program is free software; you can redistribute it and/or modify
14493+ * it under the terms of the GNU General Public License as published by
14494+ * the Free Software Foundation; either version 2, or (at your option)
14495+ * any later version.
14496+ *
14497+ * This program is distributed in the hope that it will be useful,
14498+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14499+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14500+ * GNU General Public License for more details.
14501+ *
14502+ * You should have received a copy of the GNU General Public License
14503+ * along with this program; see the file COPYING. If not, write to
14504+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
14505+ *
14506+ * Module Name:
14507+ * ossup.c
14508+ *
14509+ *
14510+ *
14511+ --*/
14512+
14513+static char *ident_ossup = "aacraid_ident ossup.c 1.0.6 2000/10/09 Adaptec, Inc.";
14514+
14515+#include "osheaders.h"
14516+
14517+#include "aac_unix_defs.h"
14518+
14519+
14520+AAC_STATUS
14521+ExInitializeZone(
14522+ IN PZONE_HEADER Zone,
14523+ IN ULONG BlockSize,
14524+ IN PVOID InitialSegment,
14525+ IN ULONG InitialSegmentSize
14526+ )
14527+
14528+/*++
14529+
14530+Routine Description:
14531+
14532+ This function initializes a zone header. Once successfully
14533+ initialized, blocks can be allocated and freed from the zone, and
14534+ the zone can be extended.
14535+
14536+Arguments:
14537+
14538+ Zone - Supplies the address of a zone header to be initialized.
14539+
14540+ BlockSize - Supplies the block size of the allocatable unit within
14541+ the zone. The size must be larger that the size of the
14542+ initial segment, and must be 64-bit aligned.
14543+
14544+ InitialSegment - Supplies the address of a segment of storage. The
14545+ first ZONE_SEGMENT_HEADER-sized portion of the segment
14546+ is used by the zone allocator. The remainder of
14547+ the segment is carved up into fixed size
14548+ (BlockSize) blocks and is made available for
14549+ allocation and deallocation from the zone. The
14550+ address of the segment must be aligned on a 64-bit
14551+ boundary.
14552+
14553+ InitialSegmentSize - Supplies the size in bytes of the InitialSegment.
14554+
14555+Return Value:
14556+
14557+ STATUS_UNSUCCESSFUL - BlockSize or InitialSegment was not aligned on
14558+ 64-bit boundaries, or BlockSize was larger than
14559+ the initial segment size.
14560+
14561+ STATUS_SUCCESS - The zone was successfully initialized.
14562+
14563+--*/
14564+
14565+{
14566+ ULONG i;
14567+ PCHAR p;
14568+
14569+
14570+ Zone->BlockSize = BlockSize;
14571+
14572+ Zone->SegmentList.Next = &((PZONE_SEGMENT_HEADER) InitialSegment)->SegmentList;
14573+ ((PZONE_SEGMENT_HEADER) InitialSegment)->SegmentList.Next = NULL;
14574+ ((PZONE_SEGMENT_HEADER) InitialSegment)->Reserved = NULL;
14575+
14576+ Zone->FreeList.Next = NULL;
14577+
14578+ p = (PCHAR)InitialSegment + sizeof(ZONE_SEGMENT_HEADER);
14579+
14580+ for (i = sizeof(ZONE_SEGMENT_HEADER);
14581+ i <= InitialSegmentSize - BlockSize;
14582+ i += BlockSize
14583+ ) {
14584+ ((PSINGLE_LIST_ENTRY)p)->Next = Zone->FreeList.Next;
14585+ Zone->FreeList.Next = (PSINGLE_LIST_ENTRY)p;
14586+ p += BlockSize;
14587+ }
14588+ Zone->TotalSegmentSize = i;
14589+
14590+#if 0
14591+ DbgPrint( "EX: ExInitializeZone( %lx, %lx, %lu, %lu, %lx )\n",
14592+ Zone, InitialSegment, InitialSegmentSize,
14593+ BlockSize, p
14594+ );
14595+#endif
14596+
14597+ return STATUS_SUCCESS;
14598+}
14599+
14600+AAC_STATUS
14601+ExExtendZone(
14602+ IN PZONE_HEADER Zone,
14603+ IN PVOID Segment,
14604+ IN ULONG SegmentSize
14605+ )
14606+
14607+/*++
14608+
14609+Routine Description:
14610+
14611+ This function extends a zone by adding another segment's worth of
14612+ blocks to the zone.
14613+
14614+Arguments:
14615+
14616+ Zone - Supplies the address of a zone header to be extended.
14617+
14618+ Segment - Supplies the address of a segment of storage. The first
14619+ ZONE_SEGMENT_HEADER-sized portion of the segment is used by the
14620+ zone allocator. The remainder of the segment is carved up
14621+ into fixed-size (BlockSize) blocks and is added to the
14622+ zone. The address of the segment must be aligned on a 64-
14623+ bit boundary.
14624+
14625+ SegmentSize - Supplies the size in bytes of Segment.
14626+
14627+Return Value:
14628+
14629+ STATUS_UNSUCCESSFUL - BlockSize or Segment was not aligned on
14630+ 64-bit boundaries, or BlockSize was larger than
14631+ the segment size.
14632+
14633+ STATUS_SUCCESS - The zone was successfully extended.
14634+
14635+--*/
14636+
14637+{
14638+ ULONG i;
14639+ PCHAR p;
14640+
14641+
14642+ ((PZONE_SEGMENT_HEADER) Segment)->SegmentList.Next = Zone->SegmentList.Next;
14643+ Zone->SegmentList.Next = &((PZONE_SEGMENT_HEADER) Segment)->SegmentList;
14644+
14645+ p = (PCHAR)Segment + sizeof(ZONE_SEGMENT_HEADER);
14646+
14647+ for (i = sizeof(ZONE_SEGMENT_HEADER);
14648+ i <= SegmentSize - Zone->BlockSize;
14649+ i += Zone->BlockSize
14650+ ) {
14651+
14652+ ((PSINGLE_LIST_ENTRY)p)->Next = Zone->FreeList.Next;
14653+ Zone->FreeList.Next = (PSINGLE_LIST_ENTRY)p;
14654+ p += Zone->BlockSize;
14655+ }
14656+ Zone->TotalSegmentSize += i;
14657+
14658+#if 0
14659+ DbgPrint( "EX: ExExtendZone( %lx, %lx, %lu, %lu, %lx )\n",
14660+ Zone, Segment, SegmentSize, Zone->BlockSize, p
14661+ );
14662+#endif
14663+
14664+ return STATUS_SUCCESS;
14665+}
14666+
14667+DbgPrint()
14668+{
14669+}
14670+
14671+/* Function: InqStrCopy()
14672+ *
14673+ * Arguments: [2] pointer to char
14674+ *
14675+ * Purpose: Copy a String from one location to another
14676+ * without copying \0
14677+ */
14678+void
14679+InqStrCopy(char *a, char *b)
14680+{
14681+
14682+ while(*a != (char)0)
14683+ *b++ = *a++;
14684+}
14685+
14686diff -burN linux-2.4.7/drivers/scsi/aacraid/port.c linux/drivers/scsi/aacraid/port.c
14687--- linux-2.4.7/drivers/scsi/aacraid/port.c Wed Dec 31 18:00:00 1969
14688+++ linux/drivers/scsi/aacraid/port.c Sat Jul 21 17:55:14 2001
14689@@ -0,0 +1,287 @@
14690+/*++
14691+ * Adaptec aacraid device driver for Linux.
14692+ *
14693+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
14694+ *
14695+ * This program is free software; you can redistribute it and/or modify
14696+ * it under the terms of the GNU General Public License as published by
14697+ * the Free Software Foundation; either version 2, or (at your option)
14698+ * any later version.
14699+ *
14700+ * This program is distributed in the hope that it will be useful,
14701+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14702+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14703+ * GNU General Public License for more details.
14704+ *
14705+ * You should have received a copy of the GNU General Public License
14706+ * along with this program; see the file COPYING. If not, write to
14707+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
14708+ *
14709+ * Module Name:
14710+ * port.c
14711+ *
14712+ * Abstract: All support routines for FSA communication which are miniport specific.
14713+ *
14714+ --*/
14715+
14716+static char *ident_port = "aacraid_ident port.c 1.0.7 2000/10/11 Adaptec, Inc.";
14717+
14718+#include "osheaders.h"
14719+
14720+
14721+#include "AacGenericTypes.h"
14722+
14723+#include "aac_unix_defs.h"
14724+
14725+#include "fsatypes.h"
14726+#include "comstruc.h"
14727+#include "protocol.h"
14728+
14729+#include "fsaport.h"
14730+#include "fsaioctl.h"
14731+
14732+#include "pcisup.h"
14733+#include "port.h"
14734+
14735+int AfaPortPrinting = 1;
14736+
14737+extern AAC_STATUS AfaPort_Err_Adapter_Printf;
14738+extern AAC_STATUS AfaPort_Warn_Adapter_Printf;
14739+extern AAC_STATUS AfaPort_Info_Adapter_Printf;
14740+extern AAC_STATUS AfaPort_Err_FastAfa_Load_Driver;
14741+
14742+
14743+
14744+VOID
14745+AfaPortLogError(
14746+ IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
14747+ IN AAC_STATUS ErrorCode,
14748+ IN PUCHAR StringBuffer,
14749+ IN ULONG StringLength
14750+ )
14751+/*++
14752+
14753+Routine Description:
14754+
14755+ Does all of the work to log an error log entry
14756+Arguments:
14757+
14758+ CommonExtension - Pointer to the adapter that caused the error.
14759+
14760+ ErrorCode - Which error is being logged.
14761+
14762+ StringBuffer - Pointer to optional String for error log entry.
14763+
14764+ StringLength - Length of StringBuffer.
14765+
14766+Return Value:
14767+
14768+ Nothing
14769+
14770+--*/
14771+
14772+{
14773+
14774+}
14775+
14776+BOOLEAN
14777+AfaPortGetNextAdapterNumber(
14778+ IN PDRIVER_OBJECT DriverObject,
14779+ OUT PDEVICE_OBJECT *FsaDeviceObject,
14780+ OUT PFILE_OBJECT *FileObject,
14781+ OUT PULONG AdapterNumber
14782+ )
14783+{
14784+}
14785+BOOLEAN
14786+AfaPortAllocateAdapterCommArea(
14787+ IN PVOID Arg1,
14788+ IN OUT PVOID *CommHeaderAddress,
14789+ IN ULONG CommAreaSize,
14790+ IN ULONG CommAreaAlignment
14791+ )
14792+{
14793+ PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
14794+ PVOID BaseAddress;
14795+ PHYSICAL_ADDRESS PhysicalBaseAddress;
14796+ ULONG TotalSize, BytesToAlign;
14797+ size_t RealLength;
14798+ uint_t Count;
14799+// ULONG SizeOfFastIoComm = sizeof(FASTIO_STRUCT);
14800+// ULONG AdapterFibsSize = PAGE_SIZE;
14801+ ULONG AdapterFibsSize = 4096;
14802+ ULONG PrintfBufferSize = 256;
14803+ PADAPTER_INIT_STRUCT InitStruct;
14804+ extern int MiniPortRevision;
14805+ ULONG PhysAddress;
14806+
14807+// TotalSize = AdapterFibsSize + sizeof(ADAPTER_INIT_STRUCT) + CommAreaSize + CommAreaAlignment +
14808+// SizeOfFastIoComm + PrintfBufferSize;
14809+ TotalSize = AdapterFibsSize + sizeof(ADAPTER_INIT_STRUCT) + CommAreaSize + CommAreaAlignment +
14810+ PrintfBufferSize;
14811+
14812+
14813+ OsAllocCommPhysMem(CommonExtension->MiniPort, TotalSize, &BaseAddress, &PhysAddress);
14814+
14815+ CommonExtension->CommAddress = BaseAddress;
14816+ CommonExtension->CommPhysAddr = PhysAddress;
14817+ CommonExtension->CommSize = TotalSize;
14818+
14819+ PhysicalBaseAddress.HighPart = 0;
14820+ PhysicalBaseAddress.LowPart = PhysAddress;
14821+
14822+ CommonExtension->InitStruct = (PADAPTER_INIT_STRUCT)((PUCHAR)(BaseAddress) + AdapterFibsSize);
14823+ CommonExtension->PhysicalInitStruct = (PADAPTER_INIT_STRUCT)((PUCHAR)(PhysicalBaseAddress.LowPart) + AdapterFibsSize);
14824+
14825+ InitStruct = CommonExtension->InitStruct;
14826+
14827+ InitStruct->InitStructRevision = ADAPTER_INIT_STRUCT_REVISION;
14828+ InitStruct->MiniPortRevision = MiniPortRevision;
14829+ InitStruct->FilesystemRevision = CommonExtension->FilesystemRevision;
14830+
14831+ //
14832+ // Adapter Fibs are the first thing allocated so that they start page aligned
14833+ //
14834+ InitStruct->AdapterFibsVirtualAddress = BaseAddress;
14835+ InitStruct->AdapterFibsPhysicalAddress = (PVOID) PhysicalBaseAddress.LowPart;
14836+ InitStruct->AdapterFibsSize = AdapterFibsSize;
14837+ InitStruct->AdapterFibAlign = sizeof(FIB);
14838+
14839+ //
14840+ // Increment the base address by the amount already used
14841+ //
14842+ BaseAddress = (PVOID)((PUCHAR)(BaseAddress) + AdapterFibsSize + sizeof(ADAPTER_INIT_STRUCT));
14843+ PhysicalBaseAddress.LowPart = (ULONG)((PUCHAR)(PhysicalBaseAddress.LowPart) + AdapterFibsSize + sizeof(ADAPTER_INIT_STRUCT));
14844+
14845+ //
14846+ // Align the beginning of Headers to CommAreaAlignment
14847+ //
14848+ BytesToAlign = (CommAreaAlignment - ((ULONG)(BaseAddress) & (CommAreaAlignment - 1)));
14849+ BaseAddress = (PVOID)((PUCHAR)(BaseAddress) + BytesToAlign);
14850+ PhysicalBaseAddress.LowPart = (ULONG)((PUCHAR)(PhysicalBaseAddress.LowPart) + BytesToAlign);
14851+
14852+ //
14853+ // Fill in addresses of the Comm Area Headers and Queues
14854+ //
14855+ *CommHeaderAddress = BaseAddress;
14856+ InitStruct->CommHeaderAddress = (PVOID)PhysicalBaseAddress.LowPart;
14857+
14858+ //
14859+ // Increment the base address by the size of the CommArea
14860+ //
14861+ BaseAddress = (PVOID)((PUCHAR)(BaseAddress) + CommAreaSize);
14862+ PhysicalBaseAddress.LowPart = (ULONG)((PUCHAR)(PhysicalBaseAddress.LowPart) + CommAreaSize);
14863+
14864+
14865+ //
14866+ // Place the Printf buffer area after the Fast I/O comm area.
14867+ //
14868+ CommonExtension->PrintfBufferAddress = (PVOID)(BaseAddress);
14869+ InitStruct->PrintfBufferAddress = (PVOID)PhysicalBaseAddress.LowPart;
14870+ InitStruct->PrintfBufferSize = PrintfBufferSize;
14871+ bzero (BaseAddress, PrintfBufferSize);
14872+
14873+ AfaPortPrint("FsaAllocateAdapterCommArea: allocated a common buffer of 0x%x bytes from address 0x%x to address 0x%x\n",
14874+ TotalSize, InitStruct->AdapterFibsVirtualAddress,
14875+ (PUCHAR)(InitStruct->AdapterFibsVirtualAddress) + TotalSize);
14876+
14877+ AfaPortPrint("Mapped on to PCI address 0x%x\n", InitStruct->AdapterFibsPhysicalAddress);
14878+
14879+ return (TRUE);
14880+}
14881+
14882+AAC_STATUS
14883+AfaPortCreate (
14884+ IN PDEVICE_OBJECT DeviceObject,
14885+ IN PIRP Irp
14886+ )
14887+/*++
14888+
14889+Routine Description:
14890+
14891+ The routine will get called each time a user issues a CreateFile on the DeviceObject
14892+ for the adapter.
14893+
14894+ The main purpose of this routine is to set up any data structures that may be needed
14895+ to handle any requests made on this DeviceObject.
14896+
14897+Arguments:
14898+
14899+ DeviceObject - Pointer to device object representing adapter
14900+
14901+ Irp - Pointer to Irp that caused this open
14902+
14903+
14904+Return Value:
14905+
14906+ Status value returned from File system driver AdapterOpen
14907+
14908+--*/
14909+
14910+{
14911+}
14912+
14913+AAC_STATUS
14914+AfaPortClose (
14915+ IN PDEVICE_OBJECT DeviceObject,
14916+ IN PIRP Irp
14917+ )
14918+/*++
14919+
14920+Routine Description:
14921+
14922+ This routine will get called each time a user issues a CloseHandle on the DeviceObject
14923+ for the adapter.
14924+
14925+ The main purpose of this routine is to cleanup any data structures that have been set up
14926+ while this FileObject has been opened.
14927+
14928+Arguments:
14929+
14930+ DeviceObject - Pointer to device object representing adapter
14931+
14932+ Irp - Pointer to Irp that caused this close
14933+
14934+Return Value:
14935+
14936+ Status value returned from File system driver AdapterClose
14937+
14938+--*/
14939+
14940+{
14941+
14942+}
14943+
14944+AAC_STATUS
14945+AfaPortDeviceControl (
14946+ IN PDEVICE_OBJECT DeviceObject,
14947+ IN PIRP Irp
14948+ )
14949+{
14950+
14951+}
14952+
14953+ULONG
14954+AfaPortGetMaxPhysicalPage(
14955+ IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension
14956+ )
14957+/*++
14958+
14959+Routine Description:
14960+
14961+ This routine determines the max physical page in host memory.
14962+
14963+Arguments:
14964+
14965+ AdapterExtension
14966+
14967+Return Value:
14968+
14969+ Max physical page in host memory.
14970+
14971+--*/
14972+{
14973+
14974+}
14975+
14976+
14977diff -burN linux-2.4.7/drivers/scsi/aacraid/rx.c linux/drivers/scsi/aacraid/rx.c
14978--- linux-2.4.7/drivers/scsi/aacraid/rx.c Wed Dec 31 18:00:00 1969
14979+++ linux/drivers/scsi/aacraid/rx.c Sat Jul 21 17:55:14 2001
14980@@ -0,0 +1,917 @@
14981+/*++
14982+ * Adaptec aacraid device driver for Linux.
14983+ *
14984+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
14985+ *
14986+ * This program is free software; you can redistribute it and/or modify
14987+ * it under the terms of the GNU General Public License as published by
14988+ * the Free Software Foundation; either version 2, or (at your option)
14989+ * any later version.
14990+ *
14991+ * This program is distributed in the hope that it will be useful,
14992+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14993+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14994+ * GNU General Public License for more details.
14995+ *
14996+ * You should have received a copy of the GNU General Public License
14997+ * along with this program; see the file COPYING. If not, write to
14998+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
14999+ *
15000+ * Module Name:
15001+ * rx.c
15002+ *
15003+ * Abstract: Hardware miniport for Drawbridge specific hardware functions.
15004+ *
15005+ --*/
15006+
15007+static char *ident_rx = "aacraid_ident rx.c 1.0.7 2000/10/11 Adaptec, Inc.";
15008+
15009+#include "osheaders.h"
15010+
15011+
15012+#include "AacGenericTypes.h"
15013+
15014+#include "aac_unix_defs.h"
15015+
15016+#include "fsatypes.h"
15017+#include "comstruc.h"
15018+#include "fsact.h"
15019+#include "protocol.h"
15020+
15021+#define DEFINE_PCI_IDS
15022+#include "rxcommon.h"
15023+#include "monkerapi.h"
15024+
15025+#include "fsaport.h"
15026+#include "fsaioctl.h"
15027+
15028+#include "pcisup.h"
15029+#include "rx.h"
15030+
15031+#include "port.h"
15032+
15033+#define BugCheckFileId (FSAFS_BUG_CHECK_CYCLONESUP)
15034+
15035+// #define RxBugCheck(A,B,C) { KeBugCheckEx(0x00000AFA, __LINE__, (ULONG)A, (ULONG)B,(ULONG)C ); }
15036+
15037+#define RxBugCheck(A, B, C) { cmn_err(CE_PANIC, "aacdisk : line %s, 0x%x, 0x%x, 0x%x ", __LINE__, A, B, C); }
15038+
15039+#define NUM_TICKS_PER_SECOND (1000 * 1000 * 10) /* time is in 100 nanoseconds */
15040+
15041+
15042+//
15043+// The list of all the Rx adapter structures
15044+//
15045+
15046+PRx_ADAPTER_EXTENSION RxAdapterList;
15047+
15048+int
15049+RxInitDevice(
15050+ IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
15051+ IN ULONG AdapterNumber,
15052+ IN ULONG PciBus,
15053+ IN ULONG PciSlot
15054+);
15055+
15056+BOOLEAN
15057+RxSendSynchFib(
15058+ PVOID Arg1,
15059+ ULONG FibPhysicalAddress
15060+ );
15061+
15062+FSA_USER_VAR RxUserVars[] = {
15063+ { "AfaPortPrinting", (PULONG)&AfaPortPrinting, NULL },
15064+};
15065+
15066+
15067+//
15068+// Declare private use routines for this modual
15069+//
15070+
15071+u_int
15072+RxPciIsr (
15073+ IN PRx_ADAPTER_EXTENSION AdapterExtension
15074+ )
15075+
15076+/*++
15077+
15078+Routine Description:
15079+
15080+ The Isr routine for fsa Rx based adapter boards.
15081+
15082+Arguments:
15083+
15084+
15085+Return Value:
15086+
15087+ TRUE - if the interrupt was handled by this isr
15088+ FALSE - if the interrupt was not handled by this isr
15089+
15090+--*/
15091+
15092+{
15093+ ULONG DoorbellBits;
15094+ UCHAR InterruptStatus, Mask;
15095+ u_int OurInterrupt = INTR_UNCLAIMED;
15096+
15097+ //cmn_err(CE_WARN, "RxPciIsr entered\n");
15098+
15099+ InterruptStatus = Rx_READ_UCHAR(AdapterExtension, MUnit.OISR);
15100+
15101+ //
15102+ // Read mask and invert because drawbridge is reversed.
15103+ //
15104+ // This allows us to only service interrupts that have been enabled.
15105+ //
15106+
15107+ Mask = ~(Rx_READ_UCHAR(AdapterExtension, MUnit.OIMR));
15108+
15109+ // Check to see if this is our interrupt. If it isn't just return FALSE.
15110+
15111+
15112+ if (InterruptStatus & Mask) {
15113+
15114+ DoorbellBits = Rx_READ_ULONG(AdapterExtension, OutboundDoorbellReg);
15115+
15116+ OurInterrupt = INTR_CLAIMED;
15117+
15118+ if (DoorbellBits & DoorBellPrintfReady) {
15119+
15120+ ULONG Length, Level;
15121+ unsigned char *cp;
15122+
15123+ cp = AdapterExtension->Common->PrintfBufferAddress;
15124+
15125+ //
15126+ // The size of the Printfbuffer is set in port.c
15127+ // There is no variable or define for it
15128+ //
15129+ if (Length > 255)
15130+ Length = 255;
15131+
15132+ if (cp[Length] != 0) {
15133+ // cmn_err (CE_NOTE, "byte %d is 0x%x, should be 0", Length, cp[Length]);
15134+ cp[Length] = 0;
15135+ }
15136+
15137+ if (Level == LOG_HIGH_ERROR)
15138+ cmn_err (CE_WARN, "%s:%s", OsGetDeviceName(AdapterExtension), AdapterExtension->Common->PrintfBufferAddress);
15139+ else
15140+ cmn_err (CE_NOTE, "%s:%s", OsGetDeviceName(AdapterExtension), AdapterExtension->Common->PrintfBufferAddress);
15141+
15142+ bzero (AdapterExtension->Common->PrintfBufferAddress, 256);
15143+
15144+ Rx_WRITE_ULONG(AdapterExtension, MUnit.ODR,DoorBellPrintfReady); //clear PrintfReady
15145+
15146+ Rx_WRITE_ULONG(AdapterExtension, InboundDoorbellReg,DoorBellPrintfDone);
15147+
15148+
15149+ } else if (DoorbellBits & DoorBellAdapterNormCmdReady) { // Adapter -> Host Normal Command Ready
15150+
15151+ AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, HostNormCmdQue);
15152+ Rx_WRITE_ULONG(AdapterExtension, MUnit.ODR, DoorBellAdapterNormCmdReady);
15153+
15154+ } else if (DoorbellBits & DoorBellAdapterNormRespReady) { // Adapter -> Host Normal Response Ready
15155+
15156+ AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, HostNormRespQue);
15157+ Rx_WRITE_ULONG(AdapterExtension, MUnit.ODR,DoorBellAdapterNormRespReady);
15158+
15159+ } else if (DoorbellBits & DoorBellAdapterNormCmdNotFull) { // Adapter -> Host Normal Command Not Full
15160+
15161+ AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, AdapNormCmdNotFull);
15162+ Rx_WRITE_ULONG(AdapterExtension, MUnit.ODR, DoorBellAdapterNormCmdNotFull);
15163+
15164+ } else if (DoorbellBits & DoorBellAdapterNormRespNotFull) { // Adapter -> Host Normal Response Not Full
15165+
15166+ AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, AdapNormRespNotFull);
15167+ Rx_WRITE_ULONG(AdapterExtension, MUnit.ODR, DoorBellAdapterNormRespNotFull);
15168+
15169+ }
15170+
15171+ }
15172+ return(OurInterrupt);
15173+}
15174+
15175+VOID
15176+RxEnableInterrupt(
15177+ PVOID Arg1,
15178+ ADAPTER_EVENT AdapterEvent,
15179+ BOOLEAN AtDeviceIrq
15180+ )
15181+/*++
15182+
15183+Routine Description:
15184+
15185+ This routine will enable the corresponding adapter event to cause an interrupt on
15186+ the host.
15187+
15188+Arguments:
15189+
15190+ AdapterExtension - Which adapter to enable.
15191+
15192+ AdapterEvent - Which adapter event.
15193+
15194+ AtDeviceIrq - Whether the system is in DEVICE irql
15195+
15196+Return Value:
15197+
15198+ Nothing.
15199+
15200+--*/
15201+{
15202+ PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
15203+ PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) CommonExtension->MiniPort;
15204+
15205+ //cmn_err(CE_WARN, "RxEnableInterrupt");
15206+ switch (AdapterEvent) {
15207+
15208+ case HostNormCmdQue:
15209+
15210+ AdapterExtension->LocalMaskInterruptControl &= ~(OUTBOUNDDOORBELL_1);
15211+
15212+ break;
15213+
15214+ case HostNormRespQue:
15215+
15216+ AdapterExtension->LocalMaskInterruptControl &= ~(OUTBOUNDDOORBELL_2);
15217+
15218+ break;
15219+
15220+ case AdapNormCmdNotFull:
15221+
15222+ AdapterExtension->LocalMaskInterruptControl &= ~(OUTBOUNDDOORBELL_3);
15223+
15224+ break;
15225+
15226+ case AdapNormRespNotFull:
15227+
15228+ AdapterExtension->LocalMaskInterruptControl &= ~(OUTBOUNDDOORBELL_4);
15229+
15230+ break;
15231+
15232+ }
15233+
15234+}
15235+
15236+VOID
15237+RxDisableInterrupt(
15238+ PVOID Arg1,
15239+ ADAPTER_EVENT AdapterEvent,
15240+ BOOLEAN AtDeviceIrq
15241+ )
15242+/*++
15243+
15244+Routine Description:
15245+
15246+ This routine will disable the corresponding adapter event to cause an interrupt on
15247+ the host.
15248+
15249+Arguments:
15250+
15251+ AdapterExtension - Which adapter to enable.
15252+
15253+ AdapterEvent - Which adapter event.
15254+
15255+ AtDeviceIrq - Whether the system is in DEVICE irql
15256+
15257+Return Value:
15258+
15259+ Nothing.
15260+
15261+--*/
15262+{
15263+ PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
15264+ PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) CommonExtension->MiniPort;
15265+
15266+ //cmn_err(CE_WARN, "RxEnableInterrupt");
15267+
15268+ switch (AdapterEvent) {
15269+
15270+
15271+ case HostNormCmdQue:
15272+
15273+ AdapterExtension->LocalMaskInterruptControl |= (OUTBOUNDDOORBELL_1);
15274+
15275+ break;
15276+
15277+ case HostNormRespQue:
15278+
15279+ AdapterExtension->LocalMaskInterruptControl |= (OUTBOUNDDOORBELL_2);
15280+
15281+ break;
15282+
15283+ case AdapNormCmdNotFull:
15284+
15285+ AdapterExtension->LocalMaskInterruptControl |= (OUTBOUNDDOORBELL_3);
15286+
15287+ break;
15288+
15289+
15290+ case AdapNormRespNotFull:
15291+
15292+ AdapterExtension->LocalMaskInterruptControl |= (OUTBOUNDDOORBELL_4);
15293+
15294+ break;
15295+
15296+ }
15297+
15298+}
15299+
15300+
15301+
15302+RxDetachDevice(
15303+ IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension
15304+ )
15305+{
15306+ PRx_ADAPTER_EXTENSION AdapterExtension = CommonExtension->MiniPort;
15307+
15308+ //
15309+ // Free the register mapping.
15310+ //
15311+
15312+ OsDetachDevice( AdapterExtension);
15313+
15314+ OsFreeMemory( AdapterExtension, sizeof(Rx_ADAPTER_EXTENSION) );
15315+
15316+}
15317+
15318+int
15319+RxInitDevice(
15320+ IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
15321+ IN ULONG AdapterNumber,
15322+ IN ULONG PciBus,
15323+ IN ULONG PciSlot
15324+)
15325+
15326+/*++
15327+
15328+Routine Description:
15329+
15330+ Scans the PCI bus looking for the Rx card. When found all resources for the
15331+ device will be allocated and the interrupt vectors and csrs will be allocated and
15332+ mapped.
15333+
15334+ The device_interface in the commregion will be allocated and linked to the comm region.
15335+
15336+Arguments:
15337+
15338+
15339+Return Value:
15340+
15341+ TRUE - if the device was setup with not problems
15342+ FALSE - if the device could not be mapped and init successfully
15343+
15344+--*/
15345+
15346+{
15347+ AAC_STATUS Status;
15348+ PRx_ADAPTER_EXTENSION AdapterExtension = NULL;
15349+ FSA_NEW_ADAPTER NewAdapter;
15350+ ULONG StartTime, EndTime, WaitTime;
15351+ ULONG InitStatus;
15352+ int instance;
15353+ int nIntrs;
15354+ char * name;
15355+
15356+ AfaPortPrint("In init device.\n");
15357+
15358+ //cmn_err(CE_WARN, "In RxInitDevice");
15359+
15360+// AdapterExtension->Common->AdapterIndex = AdapterIndex;
15361+ CommonExtension->AdapterNumber = AdapterNumber;
15362+
15363+
15364+ CommonExtension->PciBusNumber = PciBus;
15365+ CommonExtension->PciSlotNumber = PciSlot;
15366+
15367+
15368+ AdapterExtension = OsAllocMemory( sizeof(Rx_ADAPTER_EXTENSION), OS_ALLOC_MEM_SLEEP );
15369+ AdapterExtension->Common = CommonExtension;
15370+ CommonExtension->MiniPort = AdapterExtension;
15371+
15372+ instance = OsGetDeviceInstance(AdapterExtension);
15373+ name = OsGetDeviceName(AdapterExtension);
15374+ //
15375+ // Map in the registers from the adapter, register space 0 is config space,
15376+ // register space 1 is the memery space.
15377+ //
15378+
15379+ if (OsMapDeviceRegisters(AdapterExtension)) {
15380+
15381+ cmn_err(CE_CONT, "%s%d: can't map device registers\n",
15382+ OsGetDeviceName(AdapterExtension), instance);
15383+ return(FAILURE);
15384+ }
15385+
15386+ //
15387+ // Check to see if the board failed any self tests.
15388+ //
15389+
15390+ if (Rx_READ_ULONG( AdapterExtension, IndexRegs.Mailbox[7]) & SELF_TEST_FAILED) {
15391+
15392+ cmn_err(CE_CONT, "%s%d: adapter self-test failed\n",
15393+ OsGetDeviceName(AdapterExtension), instance);
15394+ return(FAILURE);
15395+
15396+ }
15397+ //cmn_err(CE_WARN, "RxInitDevice: %s%d: adapter passwd self-test\n",
15398+ // OsGetDeviceName(AdapterExtension), instance);
15399+
15400+ //
15401+ // Check to see if the board panic'd while booting.
15402+ //
15403+
15404+ if (Rx_READ_ULONG( AdapterExtension, IndexRegs.Mailbox[7]) & KERNEL_PANIC) {
15405+
15406+ cmn_err(CE_CONT, "%s%d: adapter kernel panic'd\n",
15407+ OsGetDeviceName(AdapterExtension), instance);
15408+ return(FAILURE);
15409+
15410+ }
15411+
15412+ StartTime = OsGetSeconds();
15413+ WaitTime = 0;
15414+
15415+
15416+ //
15417+ // Wait for the adapter to be up and running. Wait up until 3 minutes.
15418+ //
15419+
15420+ while (!(Rx_READ_ULONG( AdapterExtension, IndexRegs.Mailbox[7]) & KERNEL_UP_AND_RUNNING)) {
15421+
15422+ EndTime = OsGetSeconds();
15423+
15424+ WaitTime = EndTime - StartTime;
15425+
15426+ if ( WaitTime > (3 * 10) ) {
15427+
15428+ InitStatus = Rx_READ_ULONG( AdapterExtension, IndexRegs.Mailbox[7]) >> 16;
15429+
15430+ cmn_err(CE_CONT, "%s%d: adapter kernel failed to start, init status = %d\n",
15431+ OsGetDeviceName(AdapterExtension), instance, InitStatus);
15432+ return(FAILURE);
15433+
15434+ }
15435+ }
15436+
15437+ if (OsAttachInterrupt(AdapterExtension,RxISR)) {
15438+ cmn_err(CE_WARN, "%s%d RxInitDevice: failed OsAttachIntterupt", name, instance);
15439+ return(FAILURE);
15440+ }
15441+
15442+
15443+ if (OsAttachDMA(AdapterExtension)) {
15444+ cmn_err(CE_WARN, "%s%d SaInitDevice: failed OsAttachDMA", name, instance);
15445+ return(FAILURE);
15446+ }
15447+
15448+ //
15449+ // Fill in the function dispatch table.
15450+ //
15451+
15452+ AdapterExtension->Common->AdapterFuncs.SizeOfFsaPortFuncs = sizeof(FSAPORT_FUNCS);
15453+ AdapterExtension->Common->AdapterFuncs.AllocateAdapterCommArea = AfaPortAllocateAdapterCommArea;
15454+ AdapterExtension->Common->AdapterFuncs.FreeAdapterCommArea = AfaPortFreeAdapterCommArea;
15455+ AdapterExtension->Common->AdapterFuncs.BuildSgMap = AfaPortBuildSgMap;
15456+ AdapterExtension->Common->AdapterFuncs.FreeDmaResources = AfaPortFreeDmaResources;
15457+ AdapterExtension->Common->AdapterFuncs.AllocateAndMapFibSpace = AfaPortAllocateAndMapFibSpace;
15458+ AdapterExtension->Common->AdapterFuncs.UnmapAndFreeFibSpace = AfaPortUnmapAndFreeFibSpace;
15459+ AdapterExtension->Common->AdapterFuncs.InterruptAdapter = RxInterruptAdapter;
15460+ AdapterExtension->Common->AdapterFuncs.EnableInterrupt = RxEnableInterrupt;
15461+ AdapterExtension->Common->AdapterFuncs.DisableInterrupt = RxDisableInterrupt;
15462+ AdapterExtension->Common->AdapterFuncs.NotifyAdapter = RxNotifyAdapter;
15463+ AdapterExtension->Common->AdapterFuncs.ResetDevice = RxResetDevice;
15464+ AdapterExtension->Common->AdapterFuncs.InterruptHost = NULL;
15465+
15466+ AdapterExtension->Common->AdapterFuncs.SendSynchFib = RxSendSynchFib;
15467+
15468+ NewAdapter.AdapterExtension = CommonExtension;
15469+ NewAdapter.AdapterFuncs = &AdapterExtension->Common->AdapterFuncs;
15470+ NewAdapter.AdapterInterruptsBelowDpc = FALSE;
15471+ NewAdapter.AdapterUserVars = RxUserVars;
15472+ NewAdapter.AdapterUserVarsSize = sizeof(RxUserVars) / sizeof(FSA_USER_VAR);
15473+
15474+ NewAdapter.Dip = CommonExtension->OsDep.dip;
15475+
15476+
15477+ if (AfaCommInitNewAdapter( &NewAdapter ) == NULL) {
15478+
15479+ cmn_err(CE_WARN, "AfaCommInitNewAdapter failed\n");
15480+ return (FAILURE);
15481+ }
15482+
15483+
15484+ AdapterExtension->Common->Adapter = NewAdapter.Adapter;
15485+
15486+ if (AdapterExtension->Common->Adapter == NULL) {
15487+
15488+ AfaPortLogError(AdapterExtension->Common, FAILURE, NULL, 0);
15489+ cmn_err(CE_WARN, "%s%d RxInitDevice: No Adapter pointer", name, instance);
15490+
15491+
15492+ return (FAILURE);
15493+ }
15494+
15495+
15496+ //
15497+ // Start any kernel threads needed
15498+ //
15499+ OsStartKernelThreads(AdapterExtension);
15500+
15501+ //
15502+ // Tell the adapter that all is configure, and it can start accepting requests
15503+ //
15504+
15505+ RxStartAdapter(AdapterExtension);
15506+
15507+
15508+#ifdef AACDISK
15509+#endif
15510+
15511+
15512+ //
15513+ // Put this adapter into the list of Rx adapters
15514+ //
15515+
15516+ AdapterExtension->Next = RxAdapterList;
15517+ RxAdapterList = AdapterExtension;
15518+
15519+ AdapterExtension->Common->AdapterConfigured = TRUE;
15520+
15521+
15522+#ifdef AACDISK
15523+ //
15524+ // Call the disk layer to initialize itself.
15525+ //
15526+
15527+ AfaDiskInitNewAdapter( AdapterExtension->Common->AdapterNumber, AdapterExtension->Common->Adapter );
15528+#endif
15529+
15530+
15531+init_done:
15532+
15533+ AdapterExtension->Common->AdapterPrintfsToScreen = FALSE;
15534+
15535+
15536+
15537+ OsAttachHBA(AdapterExtension);
15538+
15539+ return(0);
15540+}
15541+
15542+VOID
15543+RxStartAdapter(
15544+ PRx_ADAPTER_EXTENSION AdapterExtension
15545+ )
15546+{
15547+ ULONG ReturnStatus;
15548+ LARGE_INTEGER HostTime;
15549+ ULONG ElapsedSeconds;
15550+ PADAPTER_INIT_STRUCT InitStruct;
15551+
15552+ //cmn_err(CE_WARN, "RxStartAdapter");
15553+ //
15554+ // Fill in the remaining pieces of the InitStruct.
15555+ //
15556+
15557+ InitStruct = AdapterExtension->Common->InitStruct;
15558+
15559+ InitStruct->HostPhysMemPages = AfaPortGetMaxPhysicalPage(AdapterExtension->Common);
15560+
15561+ ElapsedSeconds = OsGetSeconds();
15562+
15563+ InitStruct->HostElapsedSeconds = ElapsedSeconds;
15564+
15565+ //
15566+ // Tell the adapter we are back and up and running so it will scan its command
15567+ // queues and enable our interrupts
15568+ //
15569+
15570+ AdapterExtension->LocalMaskInterruptControl =
15571+ (DoorBellPrintfReady | OUTBOUNDDOORBELL_1 | OUTBOUNDDOORBELL_2 | OUTBOUNDDOORBELL_3 | OUTBOUNDDOORBELL_4);
15572+
15573+ //
15574+ // First clear out all interrupts. Then enable the one's that we can handle.
15575+ //
15576+
15577+ Rx_WRITE_UCHAR( AdapterExtension, MUnit.OIMR, 0xff);
15578+ Rx_WRITE_ULONG( AdapterExtension, MUnit.ODR, 0xffffffff);
15579+// Rx_WRITE_UCHAR(AdapterExtension, MUnit.OIMR, ~(UCHAR)OUTBOUND_DOORBELL_INTERRUPT_MASK);
15580+ Rx_WRITE_UCHAR( AdapterExtension, MUnit.OIMR, 0xfb);
15581+
15582+ RxSendSynchCommand(AdapterExtension,
15583+ INIT_STRUCT_BASE_ADDRESS,
15584+ (ULONG) AdapterExtension->Common->PhysicalInitStruct,
15585+ 0,
15586+ 0,
15587+ 0,
15588+ &ReturnStatus);
15589+
15590+}
15591+
15592+
15593+VOID
15594+RxResetDevice(
15595+ PVOID Arg1
15596+ )
15597+
15598+{
15599+}
15600+
15601+VOID
15602+RxInterruptAdapter(
15603+ PVOID Arg1
15604+ )
15605+/*++
15606+
15607+Routine Description:
15608+
15609+ The will cause the adapter to take a break point.
15610+
15611+Arguments:
15612+
15613+ None
15614+
15615+Return Value:
15616+
15617+ Nothing
15618+
15619+--*/
15620+{
15621+ PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
15622+ PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) CommonExtension->MiniPort;
15623+
15624+ ULONG ReturnStatus;
15625+
15626+ RxSendSynchCommand(AdapterExtension,
15627+ BREAKPOINT_REQUEST,
15628+ 0,
15629+ 0,
15630+ 0,
15631+ 0,
15632+ &ReturnStatus);
15633+
15634+}
15635+
15636+VOID
15637+RxNotifyAdapter(
15638+ PVOID Arg1,
15639+ IN HOST_2_ADAP_EVENT AdapterEvent
15640+ )
15641+/*++
15642+
15643+Routine Description:
15644+
15645+ Will read the adapter CSRs to find the reason the adapter has
15646+ interrupted us.
15647+
15648+Arguments:
15649+
15650+ AdapterEvent - Enumerated type the returns the reason why we were interrutped.
15651+
15652+Return Value:
15653+
15654+ Nothing
15655+
15656+--*/
15657+{
15658+ PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
15659+ PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) CommonExtension->MiniPort;
15660+ ULONG ReturnStatus;
15661+
15662+ //cmn_err(CE_WARN, "RxNotifyAdapter %d", AdapterEvent);
15663+
15664+ switch (AdapterEvent) {
15665+ case AdapNormCmdQue:
15666+
15667+ Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_1);
15668+ break;
15669+
15670+ case HostNormRespNotFull:
15671+
15672+ Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_4);
15673+ break;
15674+
15675+ case AdapNormRespQue:
15676+
15677+ Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_2);
15678+ break;
15679+
15680+ case HostNormCmdNotFull:
15681+
15682+ Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_3);
15683+ break;
15684+
15685+ case HostShutdown:
15686+
15687+// RxSendSynchCommand(AdapterExtension, HOST_CRASHING, 0, 0, 0, 0, &ReturnStatus);
15688+
15689+ break;
15690+
15691+ case FastIo:
15692+ Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_6);
15693+ break;
15694+
15695+ case AdapPrintfDone:
15696+ Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_5);
15697+ break;
15698+
15699+ default:
15700+
15701+ RxBugCheck(0,0,0);
15702+ AfaPortPrint("Notify requested with an invalid request 0x%x.\n",AdapterEvent);
15703+ break;
15704+ }
15705+}
15706+
15707+AAC_STATUS
15708+RxSendSynchCommand(
15709+ PVOID Arg1,
15710+ ULONG Command,
15711+ ULONG Parameter1,
15712+ ULONG Parameter2,
15713+ ULONG Parameter3,
15714+ ULONG Parameter4,
15715+ PULONG ReturnStatus
15716+ )
15717+/*++
15718+
15719+Routine Description:
15720+
15721+ This routine will send a synchronous comamnd to the adapter and wait for its
15722+ completion.
15723+
15724+Arguments:
15725+
15726+ AdapterExtension - Pointer to adapter extension structure.
15727+ Command - Which command to send
15728+ Parameter1 - 4 - Parameters for command
15729+ ReturnStatus - return status from adapter after completion of command
15730+
15731+
15732+Return Value:
15733+
15734+ AAC_STATUS
15735+
15736+--*/
15737+{
15738+ PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) Arg1;
15739+ ULONG StartTime,EndTime,WaitTime;
15740+ BOOLEAN CommandSucceeded;
15741+
15742+ //cmn_err(CE_WARN, "RxSendSyncCommand");
15743+ //
15744+ // Write the Command into Mailbox 0
15745+ //
15746+
15747+ Rx_WRITE_ULONG( AdapterExtension, InboundMailbox0, Command);
15748+
15749+ //
15750+ // Write the parameters into Mailboxes 1 - 4
15751+ //
15752+
15753+ Rx_WRITE_ULONG( AdapterExtension, InboundMailbox1, Parameter1);
15754+ Rx_WRITE_ULONG( AdapterExtension, InboundMailbox2, Parameter2);
15755+ Rx_WRITE_ULONG( AdapterExtension, InboundMailbox3, Parameter3);
15756+ Rx_WRITE_ULONG( AdapterExtension, InboundMailbox4, Parameter4);
15757+
15758+ //
15759+ // Clear the synch command doorbell to start on a clean slate.
15760+ //
15761+
15762+ Rx_WRITE_ULONG( AdapterExtension, OutboundDoorbellReg, OUTBOUNDDOORBELL_0);
15763+
15764+ //
15765+ // disable doorbell interrupts
15766+ //
15767+
15768+ Rx_WRITE_UCHAR( AdapterExtension, MUnit.OIMR,
15769+ Rx_READ_UCHAR(AdapterExtension, MUnit.OIMR) | 0x04);
15770+
15771+ //
15772+ // force the completion of the mask register write before issuing the interrupt.
15773+ //
15774+
15775+ Rx_READ_UCHAR ( AdapterExtension, MUnit.OIMR);
15776+
15777+ //
15778+ // Signal that there is a new synch command
15779+ //
15780+
15781+ Rx_WRITE_ULONG( AdapterExtension, InboundDoorbellReg, INBOUNDDOORBELL_0);
15782+
15783+ CommandSucceeded = FALSE;
15784+
15785+ StartTime = OsGetSeconds();
15786+ WaitTime = 0;
15787+
15788+ while (WaitTime < 30) { // wait up to 30 seconds
15789+
15790+ drv_usecwait(5); // delay 5 microseconds to let Mon960 get info.
15791+
15792+ //
15793+ // Mon110 will set doorbell0 bit when it has completed the command.
15794+ //
15795+
15796+ if (Rx_READ_ULONG(AdapterExtension, OutboundDoorbellReg) & OUTBOUNDDOORBELL_0) {
15797+
15798+ //
15799+ // clear the doorbell.
15800+ //
15801+
15802+ Rx_WRITE_ULONG(AdapterExtension, OutboundDoorbellReg, OUTBOUNDDOORBELL_0);
15803+
15804+ CommandSucceeded = TRUE;
15805+ break;
15806+ }
15807+
15808+ EndTime = OsGetSeconds();
15809+ WaitTime = EndTime - StartTime;
15810+
15811+ }
15812+
15813+ if (CommandSucceeded != TRUE) {
15814+
15815+ //
15816+ // restore interrupt mask even though we timed out
15817+ //
15818+
15819+ Rx_WRITE_UCHAR(AdapterExtension, MUnit.OIMR,
15820+ Rx_READ_ULONG(AdapterExtension, MUnit.OIMR) & 0xfb);
15821+
15822+ return (STATUS_IO_TIMEOUT);
15823+
15824+ }
15825+
15826+ //
15827+ // Pull the synch status from Mailbox 0.
15828+ //
15829+
15830+ *ReturnStatus = Rx_READ_ULONG(AdapterExtension, IndexRegs.Mailbox[0]);
15831+
15832+ //
15833+ // Clear the synch command doorbell.
15834+ //
15835+
15836+ Rx_WRITE_ULONG(AdapterExtension, OutboundDoorbellReg, OUTBOUNDDOORBELL_0);
15837+
15838+ //
15839+ // restore interrupt mask
15840+ //
15841+
15842+ Rx_WRITE_UCHAR(AdapterExtension, MUnit.OIMR,
15843+ Rx_READ_ULONG(AdapterExtension, MUnit.OIMR) & 0xfb);
15844+
15845+ //
15846+ // Return SUCCESS
15847+ //
15848+
15849+ return (STATUS_SUCCESS);
15850+
15851+}
15852+
15853+BOOLEAN
15854+RxSendSynchFib(
15855+ PVOID Arg1,
15856+ ULONG FibPhysicalAddress
15857+ )
15858+/*++
15859+
15860+Routine Description:
15861+
15862+ This routine will send a synchronous fib to the adapter and wait for its
15863+ completion.
15864+
15865+Arguments:
15866+
15867+ AdapterExtension - Pointer to adapter extension structure.
15868+ FibPhysicalAddress - Physical address of fib to send.
15869+
15870+
15871+Return Value:
15872+
15873+ BOOLEAN
15874+
15875+--*/
15876+{
15877+ PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
15878+ PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) CommonExtension->MiniPort;
15879+ ULONG returnStatus;
15880+
15881+ if (RxSendSynchCommand( AdapterExtension,
15882+ SEND_SYNCHRONOUS_FIB,
15883+ FibPhysicalAddress,
15884+ 0,
15885+ 0,
15886+ 0,
15887+ &returnStatus ) != STATUS_SUCCESS ) {
15888+
15889+ return (FALSE);
15890+
15891+ }
15892+
15893+ return (TRUE);
15894+
15895+}
15896+
15897+
15898diff -burN linux-2.4.7/drivers/scsi/aacraid/sap1sup.c linux/drivers/scsi/aacraid/sap1sup.c
15899--- linux-2.4.7/drivers/scsi/aacraid/sap1sup.c Wed Dec 31 18:00:00 1969
15900+++ linux/drivers/scsi/aacraid/sap1sup.c Sat Jul 21 17:55:14 2001
15901@@ -0,0 +1,859 @@
15902+/*++
15903+ * Adaptec aacraid device driver for Linux.
15904+ *
15905+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
15906+ *
15907+ * This program is free software; you can redistribute it and/or modify
15908+ * it under the terms of the GNU General Public License as published by
15909+ * the Free Software Foundation; either version 2, or (at your option)
15910+ * any later version.
15911+ *
15912+ * This program is distributed in the hope that it will be useful,
15913+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15914+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15915+ * GNU General Public License for more details.
15916+ *
15917+ * You should have received a copy of the GNU General Public License
15918+ * along with this program; see the file COPYING. If not, write to
15919+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
15920+ *
15921+ * Module Name:
15922+ * sap1sup.c
15923+ *
15924+ * Abstract: Drawbridge specific support functions
15925+ *
15926+ --*/
15927+
15928+static char *ident_sap1 = "aacraid_ident sap1sup.c 1.0.7 2000/10/11 Adaptec, Inc.";
15929+
15930+#include "osheaders.h"
15931+
15932+
15933+#include "AacGenericTypes.h"
15934+
15935+#include "aac_unix_defs.h"
15936+
15937+#include "fsatypes.h"
15938+#include "comstruc.h"
15939+#include "fsact.h"
15940+#include "protocol.h"
15941+
15942+#define DEFINE_PCI_IDS
15943+#include "sap1common.h"
15944+#include "monkerapi.h"
15945+
15946+#include "fsaport.h"
15947+#include "fsaioctl.h"
15948+
15949+
15950+#include "pcisup.h"
15951+#include "sap1.h"
15952+
15953+#include "port.h"
15954+
15955+#include "nodetype.h"
15956+#include "comsup.h"
15957+#include "afacomm.h"
15958+#include "adapter.h"
15959+
15960+#define BugCheckFileId (FSAFS_BUG_CHECK_CYCLONESUP)
15961+
15962+// #define SaBugCheck(A,B,C) { KeBugCheckEx(0x00000AFA, __LINE__, (ULONG)A, (ULONG)B,(ULONG)C ); }
15963+
15964+#define SaBugCheck(A, B, C) { cmn_err(CE_PANIC, "aacdisk : line %s, 0x%x, 0x%x, 0x%x ", __LINE__, A, B, C); }
15965+
15966+#define NUM_TICKS_PER_SECOND (1000 * 1000 * 10) /* time is in 100 nanoseconds */
15967+
15968+int MiniPortRevision = Sa_MINIPORT_REVISION;
15969+
15970+
15971+//
15972+// The list of all the Sa adapter structures
15973+//
15974+
15975+PSa_ADAPTER_EXTENSION SaAdapterList;
15976+
15977+int
15978+SaInitDevice(
15979+ IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
15980+ IN ULONG AdapterNumber,
15981+ IN ULONG PciBus,
15982+ IN ULONG PciSlot
15983+);
15984+
15985+BOOLEAN
15986+SaSendSynchFib(
15987+ PVOID Arg1,
15988+ ULONG FibPhysicalAddress
15989+ );
15990+
15991+FSA_USER_VAR SaUserVars[] = {
15992+ { "AfaPortPrinting", (PULONG)&AfaPortPrinting, NULL },
15993+};
15994+
15995+
15996+//
15997+// Declare private use routines for this modual
15998+//
15999+
16000+
16001+/*++
16002+
16003+Routine Description:
16004+
16005+ The Isr routine for fsa Sa based adapter boards.
16006+
16007+Arguments:
16008+
16009+
16010+Return Value:
16011+
16012+ TRUE - if the interrupt was handled by this isr
16013+ FALSE - if the interrupt was not handled by this isr
16014+
16015+--*/
16016+u_int
16017+SaPciIsr (IN PSa_ADAPTER_EXTENSION AdapterExtension)
16018+{
16019+ USHORT InterruptStatus, Mask;
16020+ u_int OurInterrupt = INTR_UNCLAIMED;
16021+
16022+ InterruptStatus = Sa_READ_USHORT( AdapterExtension, DoorbellReg_p);
16023+
16024+ //
16025+ // Read mask and invert because drawbridge is reversed.
16026+ //
16027+ // This allows us to only service interrupts that have been enabled.
16028+ //
16029+
16030+ Mask = ~(Sa_READ_USHORT( AdapterExtension, SaDbCSR.PRISETIRQMASK));
16031+
16032+ // Check to see if this is our interrupt. If it isn't just return FALSE.
16033+
16034+
16035+ if (InterruptStatus & Mask) {
16036+
16037+ OurInterrupt = INTR_CLAIMED;
16038+
16039+ if (InterruptStatus & PrintfReady) {
16040+
16041+ ULONG Length, Level;
16042+ unsigned char *cp;
16043+
16044+ cp = AdapterExtension->Common->PrintfBufferAddress;
16045+
16046+ //
16047+ // The size of the Printbuffer is set in port.c
16048+ // There is no variable or define for it
16049+ //
16050+ if (Length > 255)
16051+ Length = 255;
16052+
16053+ if (cp[Length] != 0) {
16054+ // cmn_err (CE_NOTE, "byte %d is 0x%x, should be 0", Length, cp[Length]);
16055+ cp[Length] = 0;
16056+ }
16057+
16058+ if (Level == LOG_HIGH_ERROR)
16059+ cmn_err (CE_WARN, "%s:%s", OsGetDeviceName(AdapterExtension), AdapterExtension->Common->PrintfBufferAddress);
16060+ else
16061+ cmn_err (CE_NOTE, "%s:%s", OsGetDeviceName(AdapterExtension), AdapterExtension->Common->PrintfBufferAddress);
16062+
16063+ bzero (AdapterExtension->Common->PrintfBufferAddress, 256);
16064+
16065+ Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p,PrintfReady); //clear PrintfReady
16066+
16067+ Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,PrintfDone);
16068+
16069+ } else if (InterruptStatus & DOORBELL_1) { // Adapter -> Host Normal Command Ready
16070+
16071+ AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, HostNormCmdQue);
16072+ Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p, DOORBELL_1);
16073+
16074+ } else if (InterruptStatus & DOORBELL_2) { // Adapter -> Host Normal Response Ready
16075+
16076+ AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, HostNormRespQue);
16077+ Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p,DOORBELL_2);
16078+
16079+ } else if (InterruptStatus & DOORBELL_3) { // Adapter -> Host Normal Command Not Full
16080+
16081+ AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, AdapNormCmdNotFull);
16082+ Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p, DOORBELL_3);
16083+
16084+ } else if (InterruptStatus & DOORBELL_4) { // Adapter -> Host Normal Response Not Full
16085+
16086+ AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, AdapNormRespNotFull);
16087+ Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p, DOORBELL_4);
16088+
16089+ }
16090+
16091+ }
16092+ return(OurInterrupt);
16093+}
16094+
16095+
16096+/*++
16097+
16098+Routine Description:
16099+
16100+ This routine will enable the corresponding adapter event to cause an interrupt on
16101+ the host.
16102+
16103+Arguments:
16104+
16105+ AdapterExtension - Which adapter to enable.
16106+
16107+ AdapterEvent - Which adapter event.
16108+
16109+ AtDeviceIrq - Whether the system is in DEVICE irql
16110+
16111+Return Value:
16112+
16113+ Nothing.
16114+
16115+--*/
16116+VOID
16117+SaEnableInterrupt (PVOID Arg1, ADAPTER_EVENT AdapterEvent, BOOLEAN AtDeviceIrq)
16118+{
16119+ PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
16120+ PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) CommonExtension->MiniPort;
16121+
16122+ switch (AdapterEvent) {
16123+
16124+ case HostNormCmdQue:
16125+
16126+ Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRICLEARIRQMASK, DOORBELL_1 );
16127+
16128+ break;
16129+
16130+ case HostNormRespQue:
16131+
16132+ Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRICLEARIRQMASK, DOORBELL_2 );
16133+
16134+ break;
16135+
16136+ case AdapNormCmdNotFull:
16137+
16138+ Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRICLEARIRQMASK, DOORBELL_3 );
16139+
16140+ break;
16141+
16142+ case AdapNormRespNotFull:
16143+
16144+ Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRICLEARIRQMASK, DOORBELL_4 );
16145+
16146+ break;
16147+
16148+ }
16149+
16150+}
16151+
16152+
16153+
16154+/*++
16155+
16156+Routine Description:
16157+
16158+ This routine will disable the corresponding adapter event to cause an interrupt on
16159+ the host.
16160+
16161+Arguments:
16162+
16163+ AdapterExtension - Which adapter to enable.
16164+
16165+ AdapterEvent - Which adapter event.
16166+
16167+ AtDeviceIrq - Whether the system is in DEVICE irql
16168+
16169+Return Value:
16170+
16171+ Nothing.
16172+
16173+--*/
16174+VOID
16175+SaDisableInterrupt (PVOID Arg1, ADAPTER_EVENT AdapterEvent, BOOLEAN AtDeviceIrq)
16176+{
16177+ PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
16178+ PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) CommonExtension->MiniPort;
16179+
16180+ switch (AdapterEvent) {
16181+
16182+
16183+ case HostNormCmdQue:
16184+
16185+ Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRISETIRQMASK, DOORBELL_1 );
16186+
16187+ break;
16188+
16189+ case HostNormRespQue:
16190+
16191+ Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRISETIRQMASK, DOORBELL_2 );
16192+
16193+ break;
16194+
16195+ case AdapNormCmdNotFull:
16196+
16197+ Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRISETIRQMASK, DOORBELL_3 );
16198+
16199+ break;
16200+
16201+
16202+ case AdapNormRespNotFull:
16203+
16204+ Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRISETIRQMASK, DOORBELL_4 );
16205+
16206+ break;
16207+
16208+ }
16209+
16210+}
16211+
16212+
16213+SaDetachDevice (IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension)
16214+{
16215+ PSa_ADAPTER_EXTENSION AdapterExtension = CommonExtension->MiniPort;
16216+
16217+ //
16218+ // Free the register mapping.
16219+ //
16220+
16221+ OsDetachDevice(AdapterExtension);
16222+
16223+ OsFreeMemory( AdapterExtension, sizeof(Sa_ADAPTER_EXTENSION) );
16224+
16225+}
16226+
16227+
16228+/*++
16229+
16230+Routine Description:
16231+
16232+ Scans the PCI bus looking for the Sa card. When found all resources for the
16233+ device will be allocated and the interrupt vectors and csrs will be allocated and
16234+ mapped.
16235+
16236+ The device_interface in the commregion will be allocated and linked to the comm region.
16237+
16238+Arguments:
16239+
16240+
16241+Return Value:
16242+
16243+ TRUE - if the device was setup with not problems
16244+ FALSE - if the device could not be mapped and init successfully
16245+
16246+--*/
16247+int
16248+SaInitDevice (IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
16249+ IN ULONG AdapterNumber, IN ULONG PciBus,
16250+ IN ULONG PciSlot)
16251+{
16252+ AAC_STATUS Status;
16253+ PSa_ADAPTER_EXTENSION AdapterExtension = NULL;
16254+ FSA_NEW_ADAPTER NewAdapter;
16255+ ULONG StartTime, EndTime, WaitTime;
16256+ ULONG InitStatus;
16257+ int instance;
16258+ char *name;
16259+
16260+ AfaPortPrint("In init device.\n");
16261+
16262+ CommonExtension->AdapterNumber = AdapterNumber;
16263+
16264+ CommonExtension->PciBusNumber = PciBus;
16265+ CommonExtension->PciSlotNumber = PciSlot;
16266+
16267+ AdapterExtension = OsAllocMemory( sizeof(Sa_ADAPTER_EXTENSION), OS_ALLOC_MEM_SLEEP );
16268+ AdapterExtension->Common = CommonExtension;
16269+ CommonExtension->MiniPort = AdapterExtension;
16270+
16271+ instance = OsGetDeviceInstance(AdapterExtension);
16272+ name = OsGetDeviceName(AdapterExtension);
16273+
16274+ //
16275+ // Map in the registers from the adapter, register space 0 is config space,
16276+ // register space 1 is the memery space.
16277+ //
16278+
16279+ if (OsMapDeviceRegisters(AdapterExtension)){
16280+ cmn_err(CE_WARN, "%s%d SaInitDevice: failed OsMapDeviceRegisters", name, instance);
16281+ return(FAILURE);
16282+ }
16283+
16284+
16285+ //
16286+ // Check to see if the board failed any self tests.
16287+ //
16288+
16289+ if (Sa_READ_ULONG( AdapterExtension, Mailbox7) & SELF_TEST_FAILED) {
16290+
16291+ cmn_err(CE_WARN, "%s%d: adapter self-test failed\n",
16292+ name, instance);
16293+ return(FAILURE);
16294+ }
16295+
16296+ //
16297+ // Check to see if the board panic'd while booting.
16298+ //
16299+
16300+ if (Sa_READ_ULONG( AdapterExtension, Mailbox7) & KERNEL_PANIC) {
16301+
16302+ cmn_err(CE_WARN, "%s%d: adapter kernel panic'd\n",
16303+ name, instance);
16304+ return(FAILURE);
16305+ }
16306+
16307+
16308+ StartTime = OsGetSeconds();
16309+ WaitTime = 0;
16310+
16311+
16312+ //
16313+ // Wait for the adapter to be up and running. Wait up until 3 minutes.
16314+ //
16315+
16316+ while (!(Sa_READ_ULONG( AdapterExtension, Mailbox7) & KERNEL_UP_AND_RUNNING)) {
16317+
16318+ EndTime = OsGetSeconds();
16319+
16320+ WaitTime = EndTime - StartTime;
16321+
16322+ if ( WaitTime > (3 * 60) ) {
16323+
16324+ InitStatus = Sa_READ_ULONG( AdapterExtension, Mailbox7) >> 16;
16325+
16326+ cmn_err(CE_WARN, "%s%d: adapter kernel failed to start, init status = %d\n",
16327+ name, instance, InitStatus);
16328+ return(FAILURE);
16329+
16330+ }
16331+ }
16332+
16333+ if (OsAttachInterrupt(AdapterExtension, SaISR)) {
16334+ cmn_err(CE_WARN, "%s%d SaInitDevice: failed OsAttachIntterupt", name, instance);
16335+ return(FAILURE);
16336+ }
16337+
16338+ if (OsAttachDMA(AdapterExtension)) {
16339+ cmn_err(CE_WARN, "%s%d SaInitDevice: failed OsAttachDMA", name, instance);
16340+ return(FAILURE);
16341+ }
16342+
16343+
16344+ //
16345+ // Fill in the function dispatch table.
16346+ //
16347+
16348+ AdapterExtension->Common->AdapterFuncs.SizeOfFsaPortFuncs = sizeof(FSAPORT_FUNCS);
16349+ AdapterExtension->Common->AdapterFuncs.AllocateAdapterCommArea = AfaPortAllocateAdapterCommArea;
16350+ AdapterExtension->Common->AdapterFuncs.FreeAdapterCommArea = AfaPortFreeAdapterCommArea;
16351+ AdapterExtension->Common->AdapterFuncs.BuildSgMap = AfaPortBuildSgMap;
16352+ AdapterExtension->Common->AdapterFuncs.FreeDmaResources = AfaPortFreeDmaResources;
16353+ AdapterExtension->Common->AdapterFuncs.AllocateAndMapFibSpace = AfaPortAllocateAndMapFibSpace;
16354+ AdapterExtension->Common->AdapterFuncs.UnmapAndFreeFibSpace = AfaPortUnmapAndFreeFibSpace;
16355+ AdapterExtension->Common->AdapterFuncs.InterruptAdapter = SaInterruptAdapter;
16356+ AdapterExtension->Common->AdapterFuncs.EnableInterrupt = SaEnableInterrupt;
16357+ AdapterExtension->Common->AdapterFuncs.DisableInterrupt = SaDisableInterrupt;
16358+ AdapterExtension->Common->AdapterFuncs.NotifyAdapter = SaNotifyAdapter;
16359+ AdapterExtension->Common->AdapterFuncs.ResetDevice = SaResetDevice;
16360+ AdapterExtension->Common->AdapterFuncs.InterruptHost = NULL;
16361+
16362+ AdapterExtension->Common->AdapterFuncs.SendSynchFib = SaSendSynchFib;
16363+
16364+ NewAdapter.AdapterExtension = CommonExtension;
16365+ NewAdapter.AdapterFuncs = &AdapterExtension->Common->AdapterFuncs;
16366+ NewAdapter.AdapterInterruptsBelowDpc = FALSE;
16367+ NewAdapter.AdapterUserVars = SaUserVars;
16368+ NewAdapter.AdapterUserVarsSize = sizeof(SaUserVars) / sizeof(FSA_USER_VAR);
16369+
16370+ NewAdapter.Dip = CommonExtension->OsDep.dip;
16371+
16372+
16373+ if ( AfaCommInitNewAdapter( &NewAdapter ) == NULL) {
16374+ cmn_err(CE_WARN, "SaInitDevice: AfaCommInitNewAdapter failed\n");
16375+ return (FAILURE);
16376+ };
16377+
16378+
16379+ AdapterExtension->Common->Adapter = NewAdapter.Adapter;
16380+
16381+ if (AdapterExtension->Common->Adapter == NULL) {
16382+
16383+ AfaPortLogError(AdapterExtension->Common, FAILURE, NULL, 0);
16384+ cmn_err(CE_WARN, "%s%d SaInitDevice: No Adapter pointer", name, instance);
16385+
16386+ return (FAILURE);
16387+ }
16388+
16389+
16390+ //
16391+ // Start any kernel threads needed
16392+ OsStartKernelThreads(AdapterExtension);
16393+
16394+ //
16395+ // Tell the adapter that all is configure, and it can start accepting requests
16396+ //
16397+
16398+ SaStartAdapter(AdapterExtension);
16399+
16400+
16401+
16402+ //
16403+ // Put this adapter into the list of Sa adapters
16404+ //
16405+
16406+ AdapterExtension->Next = SaAdapterList;
16407+ SaAdapterList = AdapterExtension;
16408+
16409+ AdapterExtension->Common->AdapterConfigured = TRUE;
16410+
16411+
16412+#ifdef AACDISK
16413+ //
16414+ // Call the disk layer to initialize itself.
16415+ //
16416+
16417+ AfaDiskInitNewAdapter( AdapterExtension->Common->AdapterNumber, AdapterExtension->Common->Adapter );
16418+#endif
16419+
16420+
16421+init_done:
16422+
16423+ AdapterExtension->Common->AdapterPrintfsToScreen = FALSE;
16424+
16425+ OsAttachHBA(AdapterExtension);
16426+
16427+ return (0);
16428+
16429+init_error:
16430+
16431+ return (FAILURE);
16432+}
16433+
16434+
16435+
16436+VOID
16437+SaStartAdapter (PSa_ADAPTER_EXTENSION AdapterExtension)
16438+{
16439+ ULONG ReturnStatus;
16440+ LARGE_INTEGER HostTime;
16441+ ULONG ElapsedSeconds;
16442+ PADAPTER_INIT_STRUCT InitStruct;
16443+
16444+ //
16445+ // Fill in the remaining pieces of the InitStruct.
16446+ //
16447+
16448+ InitStruct = AdapterExtension->Common->InitStruct;
16449+
16450+ InitStruct->HostPhysMemPages = AfaPortGetMaxPhysicalPage(AdapterExtension->Common);
16451+
16452+ ElapsedSeconds = OsGetSeconds();
16453+
16454+ InitStruct->HostElapsedSeconds = ElapsedSeconds;
16455+
16456+ //
16457+ // Tell the adapter we are back and up and running so it will scan its command
16458+ // queues and enable our interrupts
16459+ //
16460+
16461+ AdapterExtension->LocalMaskInterruptControl =
16462+ (PrintfReady | DOORBELL_1 | DOORBELL_2 | DOORBELL_3 | DOORBELL_4);
16463+
16464+
16465+ //
16466+ // First clear out all interrupts. Then enable the one's that we can handle.
16467+ //
16468+
16469+ Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRISETIRQMASK, (USHORT) 0xffff );
16470+ Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRICLEARIRQMASK,
16471+ (PrintfReady | DOORBELL_1 | DOORBELL_2 | DOORBELL_3 | DOORBELL_4) );
16472+
16473+ SaSendSynchCommand(AdapterExtension,
16474+ INIT_STRUCT_BASE_ADDRESS,
16475+ (ULONG) AdapterExtension->Common->PhysicalInitStruct,
16476+ 0,
16477+ 0,
16478+ 0,
16479+ &ReturnStatus);
16480+
16481+}
16482+
16483+
16484+VOID
16485+SaResetDevice (PVOID Arg1){
16486+
16487+}
16488+
16489+
16490+/*++
16491+
16492+Routine Description:
16493+
16494+ The will cause the adapter to take a break point.
16495+
16496+Arguments:
16497+
16498+ None
16499+
16500+Return Value:
16501+
16502+ Nothing
16503+
16504+--*/
16505+VOID
16506+SaInterruptAdapter (PVOID Arg1)
16507+{
16508+ PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
16509+ PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) CommonExtension->MiniPort;
16510+
16511+ ULONG ReturnStatus;
16512+
16513+ SaSendSynchCommand(AdapterExtension,
16514+ BREAKPOINT_REQUEST,
16515+ 0,
16516+ 0,
16517+ 0,
16518+ 0,
16519+ &ReturnStatus);
16520+
16521+}
16522+
16523+
16524+/*++
16525+
16526+Routine Description:
16527+
16528+ Will read the adapter CSRs to find the reason the adapter has
16529+ interrupted us.
16530+
16531+Arguments:
16532+
16533+ AdapterEvent - Enumerated type the returns the reason why we were interrutped.
16534+
16535+Return Value:
16536+
16537+ Nothing
16538+
16539+--*/
16540+VOID
16541+SaNotifyAdapter (PVOID Arg1, IN HOST_2_ADAP_EVENT AdapterEvent)
16542+{
16543+ PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
16544+ PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) CommonExtension->MiniPort;
16545+ ULONG ReturnStatus;
16546+
16547+ switch (AdapterEvent) {
16548+ case AdapNormCmdQue:
16549+
16550+ Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_1);
16551+ break;
16552+
16553+ case HostNormRespNotFull:
16554+
16555+ Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_4);
16556+ break;
16557+
16558+ case AdapNormRespQue:
16559+
16560+ Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_2);
16561+ break;
16562+
16563+ case HostNormCmdNotFull:
16564+
16565+ Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_3);
16566+ break;
16567+
16568+ case HostShutdown:
16569+
16570+// SaSendSynchCommand(AdapterExtension, HOST_CRASHING, 0, 0, 0, 0, &ReturnStatus);
16571+
16572+ break;
16573+
16574+ case FastIo:
16575+ Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_6);
16576+ break;
16577+
16578+ case AdapPrintfDone:
16579+ Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_5);
16580+ break;
16581+
16582+ default:
16583+
16584+ SaBugCheck(0,0,0);
16585+ AfaPortPrint("Notify requested with an invalid request 0x%x.\n",AdapterEvent);
16586+ break;
16587+ }
16588+}
16589+
16590+
16591+/*++
16592+
16593+Routine Description:
16594+
16595+ This routine will send a synchronous comamnd to the adapter and wait for its
16596+ completion.
16597+
16598+Arguments:
16599+
16600+ AdapterExtension - Pointer to adapter extension structure.
16601+ Command - Which command to send
16602+ Parameter1 - 4 - Parameters for command
16603+ ReturnStatus - return status from adapter after completion of command
16604+
16605+
16606+Return Value:
16607+
16608+ AAC_STATUS
16609+
16610+--*/
16611+AAC_STATUS
16612+SaSendSynchCommand(
16613+ PVOID Arg1,
16614+ ULONG Command,
16615+ ULONG Parameter1,
16616+ ULONG Parameter2,
16617+ ULONG Parameter3,
16618+ ULONG Parameter4,
16619+ PULONG ReturnStatus
16620+ )
16621+{
16622+ PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) Arg1;
16623+ ULONG StartTime,EndTime,WaitTime;
16624+ BOOLEAN CommandSucceeded;
16625+
16626+ //
16627+ // Write the Command into Mailbox 0
16628+ //
16629+
16630+ Sa_WRITE_ULONG( AdapterExtension, Mailbox0, Command);
16631+
16632+ //
16633+ // Write the parameters into Mailboxes 1 - 4
16634+ //
16635+
16636+ Sa_WRITE_ULONG( AdapterExtension, Mailbox1, Parameter1);
16637+ Sa_WRITE_ULONG( AdapterExtension, Mailbox2, Parameter2);
16638+ Sa_WRITE_ULONG( AdapterExtension, Mailbox3, Parameter3);
16639+ Sa_WRITE_ULONG( AdapterExtension, Mailbox4, Parameter4);
16640+
16641+ //
16642+ // Clear the synch command doorbell to start on a clean slate.
16643+ //
16644+
16645+ Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p, DOORBELL_0);
16646+
16647+ //
16648+ // Signal that there is a new synch command
16649+ //
16650+
16651+ Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s, DOORBELL_0);
16652+
16653+ CommandSucceeded = FALSE;
16654+
16655+ StartTime = OsGetSeconds();
16656+ WaitTime = 0;
16657+
16658+ while (WaitTime < 30) { // wait up to 30 seconds
16659+
16660+ drv_usecwait(5); // delay 5 microseconds to let Mon960 get info.
16661+
16662+ //
16663+ // Mon110 will set doorbell0 bit when it has completed the command.
16664+ //
16665+
16666+ if( Sa_READ_USHORT( AdapterExtension, DoorbellReg_p) & DOORBELL_0 ) {
16667+
16668+ CommandSucceeded = TRUE;
16669+ break;
16670+ }
16671+
16672+ EndTime = OsGetSeconds();
16673+ WaitTime = EndTime - StartTime;
16674+
16675+ }
16676+
16677+ if (CommandSucceeded != TRUE) {
16678+
16679+ return (STATUS_IO_TIMEOUT);
16680+
16681+ }
16682+
16683+ //
16684+ // Clear the synch command doorbell.
16685+ //
16686+
16687+ Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p, DOORBELL_0);
16688+
16689+ //
16690+ // Pull the synch status from Mailbox 0.
16691+ //
16692+
16693+ *ReturnStatus = Sa_READ_ULONG( AdapterExtension, Mailbox0);
16694+
16695+ //
16696+ // Return SUCCESS
16697+ //
16698+
16699+ return (STATUS_SUCCESS);
16700+
16701+}
16702+
16703+
16704+/*++
16705+
16706+Routine Description:
16707+
16708+ This routine will send a synchronous fib to the adapter and wait for its
16709+ completion.
16710+
16711+Arguments:
16712+
16713+ AdapterExtension - Pointer to adapter extension structure.
16714+ FibPhysicalAddress - Physical address of fib to send.
16715+
16716+
16717+Return Value:
16718+
16719+ BOOLEAN
16720+
16721+--*/
16722+BOOLEAN
16723+SaSendSynchFib (PVOID Arg1, ULONG FibPhysicalAddress)
16724+{
16725+ PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
16726+ PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) CommonExtension->MiniPort;
16727+ ULONG returnStatus;
16728+
16729+ if (SaSendSynchCommand( AdapterExtension,
16730+ SEND_SYNCHRONOUS_FIB,
16731+ FibPhysicalAddress,
16732+ 0,
16733+ 0,
16734+ 0,
16735+ &returnStatus ) != STATUS_SUCCESS ) {
16736+
16737+ return (FALSE);
16738+
16739+ }
16740+
16741+ return (TRUE);
16742+
16743+}
16744+
16745+BOOLEAN
16746+WriteFlash(
16747+ PVOID AdapterExtension,
16748+ ULONG *MappedBuffer)
16749+{
16750+ return (FALSE);
16751+}
16752+
16753+BOOLEAN
16754+ReadFlash(
16755+ PVOID AdapterExtension,
16756+ ULONG *MappedBuffer)
16757+{
16758+ return (FALSE);
16759+}
16760+
This page took 2.173553 seconds and 4 git commands to generate.