]> git.pld-linux.org Git - packages/kernel.git/blame - linux-2.4.9-aacraid-20010816.patch
- removed all Group fields translations (oure rpm now can handle translating
[packages/kernel.git] / linux-2.4.9-aacraid-20010816.patch
CommitLineData
ee3d48da
JR
1diff -burN linux-2.4.9/MAINTAINERS linux/MAINTAINERS
2--- linux-2.4.9/MAINTAINERS Thu Aug 16 13:40:30 2001
3+++ linux/MAINTAINERS Thu Aug 16 13:41:30 2001
4@@ -126,6 +126,14 @@
5 W: http://www.uni-karlsruhe.de/~Robert.Siemer/Private/
6 S: Maintained
7
8+AACRAID SCSI RAID DRIVER
9+P: Adaptec OEM Raid Solutions
10+M: linux-aacraid-devel@dell.com
11+L: linux-aacraid-devel@dell.com
12+L: linux-aacraid-announce@dell.com
13+W: http://domsch.com/linux
14+S: Supported
15+
16 ACPI
17 P: Andy Grover
18 M: andrew.grover@intel.com
19diff -burN linux-2.4.9/arch/i386/defconfig linux/arch/i386/defconfig
20--- linux-2.4.9/arch/i386/defconfig Thu Aug 16 13:40:30 2001
21+++ linux/arch/i386/defconfig Thu Aug 16 13:41:30 2001
22@@ -286,6 +286,7 @@
23 # CONFIG_SCSI_AHA152X is not set
24 # CONFIG_SCSI_AHA1542 is not set
25 # CONFIG_SCSI_AHA1740 is not set
26+# CONFIG_SCSI_AACRAID is not set
27 # CONFIG_SCSI_AIC7XXX is not set
28 # CONFIG_SCSI_AIC7XXX_OLD is not set
29 # CONFIG_SCSI_ADVANSYS is not set
30diff -burN linux-2.4.9/drivers/scsi/Config.in linux/drivers/scsi/Config.in
31--- linux-2.4.9/drivers/scsi/Config.in Thu Aug 16 13:40:11 2001
32+++ linux/drivers/scsi/Config.in Thu Aug 16 13:41:30 2001
33@@ -50,6 +50,7 @@
34 dep_tristate 'Adaptec AHA152X/2825 support' CONFIG_SCSI_AHA152X $CONFIG_SCSI
35 dep_tristate 'Adaptec AHA1542 support' CONFIG_SCSI_AHA1542 $CONFIG_SCSI
36 dep_tristate 'Adaptec AHA1740 support' CONFIG_SCSI_AHA1740 $CONFIG_SCSI
37+dep_tristate 'Adaptec AACRAID support' CONFIG_SCSI_AACRAID $CONFIG_SCSI
38 source drivers/scsi/aic7xxx/Config.in
39 if [ "$CONFIG_SCSI_AIC7XXX" != "y" ]; then
40 dep_tristate 'Old Adaptec AIC7xxx support' CONFIG_SCSI_AIC7XXX_OLD $CONFIG_SCSI
41diff -burN linux-2.4.9/drivers/scsi/Makefile linux/drivers/scsi/Makefile
42--- linux-2.4.9/drivers/scsi/Makefile Thu Aug 16 13:40:11 2001
43+++ linux/drivers/scsi/Makefile Thu Aug 16 13:41:30 2001
44@@ -70,6 +70,7 @@
45 obj-$(CONFIG_SCSI_AHA152X) += aha152x.o
46 obj-$(CONFIG_SCSI_AHA1542) += aha1542.o
47 obj-$(CONFIG_SCSI_AHA1740) += aha1740.o
48+obj-$(CONFIG_SCSI_AACRAID) += aacraid.o
49 ifeq ($(CONFIG_SCSI_AIC7XXX),y)
50 obj-$(CONFIG_SCSI_AIC7XXX) += aic7xxx/aic7xxx_drv.o
51 endif
52@@ -193,6 +194,10 @@
53 sim710_u.h: sim710_d.h
54
55 sim710.o : sim710_d.h
56+
57+aacraid.o:
58+ cd aacraid; make
59+
60
61 53c700_d.h: 53c700.scr script_asm.pl
62 $(PERL) -s script_asm.pl -ncr7x0_family < 53c700.scr
63diff -burN linux-2.4.9/drivers/scsi/aacraid/ChangeLog linux/drivers/scsi/aacraid/ChangeLog
64--- linux-2.4.9/drivers/scsi/aacraid/ChangeLog Wed Dec 31 18:00:00 1969
65+++ linux/drivers/scsi/aacraid/ChangeLog Thu Aug 16 18:18:10 2001
66@@ -0,0 +1,30 @@
67+2001-08-16 Matt Domsch <Matt_Domsch@dell.com>
68+* renamed aacraid_pciid to perc_pciid for future Dell controllers
69+* added rx_pciid and sa_pciid options for future Adaptec controllers
70+* applied changes from Adaptec (new PCI ID, some cleanups)
71+* released patch against 2.4.8
72+* released patch against 2.4.9
73+
74+2001-08-11 Matt Domsch <Matt_Domsch@dell.com>
75+* applied pciid patch to allow passing a new PCI ID to the module at insmod
76+* removed all #ifdef CONFIG_SMP and #ifdef MODULE stuff
77+* released patch against 2.4.7
78+* released patch against 2.4.8
79+
80+2001-07-21 Matt Domsch <Matt_Domsch@dell.com>
81+* changed __SMP__ to CONFIG_SMP everywhere (really this time)
82+* Applied read capacity patch
83+* released patch against 2.4.6
84+* released patch against 2.4.7
85+
86+2001-07-04 Matt Domsch <Matt_Domsch@dell.com>
87+* Started with linux-2.4.5-aacraid-043001.patch
88+* Applied Chris Pascoe's SMP fix patch
89+* Released patch against 2.4.6
90+
91+
92+2001-04-30 Matt Domsch <Matt_Domsch@dell.com>
93+* Started with linux-2.4.3-aacraid-030101.patch
94+* Applied against 2.4.4.
95+* Added scsi_set_pci_device() call in linit.c
96+
97diff -burN linux-2.4.9/drivers/scsi/aacraid/Makefile linux/drivers/scsi/aacraid/Makefile
98--- linux-2.4.9/drivers/scsi/aacraid/Makefile Wed Dec 31 18:00:00 1969
99+++ linux/drivers/scsi/aacraid/Makefile Thu Aug 16 13:41:30 2001
100@@ -0,0 +1,169 @@
101+#
102+# Makefile aacraid Raid Controller
103+#
104+
105+###############################################################################
106+### SOURCE FILES DEFINES
107+###############################################################################
108+
109+CFILES_DRIVER=\
110+ ./aachba.c \
111+ ./aacid.c \
112+ ./commctrl.c \
113+ ./comminit.c \
114+ ./commsup.c \
115+ ./dpcsup.c \
116+ ./linit.c \
117+ ./osddi.c \
118+ ./osfuncs.c \
119+ ./ossup.c \
120+ ./port.c \
121+ ./rx.c \
122+ ./sap1sup.c
123+
124+IFILES_DRIVER=\
125+ ./include/AacGenericTypes.h \
126+ ./include/aac_unix_defs.h \
127+ ./include/adapter.h \
128+ ./include/afacomm.h \
129+ ./include/aifstruc.h \
130+ ./include/build_number.h \
131+ ./include/commdata.h \
132+ ./include/commerr.h \
133+ ./include/commfibcontext.h \
134+ ./include/comprocs.h \
135+ ./include/comproto.h \
136+ ./include/comstruc.h \
137+ ./include/comsup.h \
138+ ./include/fsact.h \
139+ ./include/fsafs.h \
140+ ./include/fsaioctl.h \
141+ ./include/fsaport.h \
142+ ./include/fsatypes.h \
143+ ./include/linit.h \
144+ ./include/monkerapi.h \
145+ ./include/nodetype.h \
146+ ./include/nvramioctl.h \
147+ ./include/osheaders.h \
148+ ./include/ostypes.h \
149+ ./include/pcisup.h \
150+ ./include/perfpack.h \
151+ ./include/port.h \
152+ ./include/protocol.h \
153+ ./include/revision.h \
154+ ./include/rxcommon.h \
155+ ./include/rx.h \
156+ ./include/sap1common.h \
157+ ./include/sap1.h \
158+ ./include/version.h
159+
160+ALL_SOURCE=\
161+ ${CFILES_DRIVER} \
162+ ${IFILES_DRIVER}
163+
164+###############################################################################
165+### OBJECT FILES DEFINES
166+###############################################################################
167+
168+
169+OFILES_DRIVER=\
170+ linit.o \
171+ osfuncs.o \
172+ osddi.o \
173+ aachba.o \
174+ commctrl.o \
175+ comminit.o \
176+ commsup.o \
177+ dpcsup.o \
178+ ossup.o \
179+ port.o \
180+ rx.o \
181+ sap1sup.o
182+
183+TARGET_OFILES= ${OFILES_DRIVER} aacid.o
184+
185+###############################################################################
186+### GENERAL DEFINES
187+###############################################################################
188+
189+# Remember that we're doing a chdir one level lower, so we need an extra ../
190+INCS= \
191+ -I./include \
192+ -I../../../include -I..
193+
194+WARNINGS= -w -Wall -Wno-unused -Wno-switch -Wno-missing-prototypes -Wno-implicit
195+
196+
197+COMMON_FLAGS=\
198+ -D__KERNEL__=1 -DUNIX -DCVLOCK_USE_SPINLOCK -DLINUX \
199+ ${INCS} \
200+ ${WARNINGS}
201+
202+AACFLAGS=${CFLAGS} ${COMMON_FLAGS} ${EXTRA_FLAGS}
203+
204+###############################################################################
205+### DO GENERAL STUFF
206+###############################################################################
207+
208+.SUFFIXES:
209+.SUFFIXES: .c .o .h .a
210+
211+all: source ${TARGET_OFILES} aacraid.o
212+
213+source: ${ALL_SOURCE}
214+
215+clean:
216+ rm *.o
217+
218+###############################################################################
219+### DRIVER LINKS
220+###############################################################################
221+
222+aacraid.o: source ${TARGET_OFILES}
223+ ld -r -o $@ $(TARGET_OFILES)
224+ cp -r aacraid.o ../
225+
226+###############################################################################
227+### SIMPLE COMPILES
228+###############################################################################
229+
230+linit.o: ./linit.c
231+ $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o linit.o ./linit.c
232+
233+aachba.o: ./aachba.c
234+ $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o aachba.o ./aachba.c
235+
236+osddi.o: ./osddi.c
237+ $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o osddi.o ./osddi.c
238+
239+osfuncs.o: ./osfuncs.c
240+ $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o osfuncs.o ./osfuncs.c
241+
242+commctrl.o: ./commctrl.c
243+ $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o commctrl.o ./commctrl.c
244+
245+comminit.o: ./comminit.c
246+ $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o comminit.o ./comminit.c
247+
248+commsup.o: ./commsup.c
249+ $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o commsup.o ./commsup.c
250+
251+dpcsup.o: ./dpcsup.c
252+ $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o dpcsup.o ./dpcsup.c
253+
254+aacid.o: ./aacid.c
255+ $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o aacid.o ./aacid.c
256+
257+port.o: ./port.c
258+ $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o port.o ./port.c
259+
260+ossup.o: ./ossup.c
261+ $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o ossup.o ./ossup.c
262+
263+rx.o: ./rx.c
264+ $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o rx.o ./rx.c
265+
266+sap1sup.o: ./sap1sup.c
267+ $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o sap1sup.o ./sap1sup.c
268+
269+
270diff -burN linux-2.4.9/drivers/scsi/aacraid/README linux/drivers/scsi/aacraid/README
271--- linux-2.4.9/drivers/scsi/aacraid/README Wed Dec 31 18:00:00 1969
272+++ linux/drivers/scsi/aacraid/README Thu Aug 16 13:41:30 2001
273@@ -0,0 +1,46 @@
274+ AACRAID Driver for Linux
275+
276+Introduction
277+-------------------------
278+The aacraid driver adds support for Adaptec (http://www.adaptec.com)
279+OEM based RAID controllers.
280+
281+It is important to note the amount of test time the 2.4.x driver
282+received. Though not a great deal has changed between 2.2 and 2.4
283+for this version, it has not recevied a great deal of test time.
284+
285+A new driver version is in the works and that version will be
286+submitted to the standard distribution kernel. The previous
287+2.2 version was submitted but rejected due to the large
288+amount of code reduncdancy and NTisms. This driver was
289+initially ported from NT to Solaris and then to Linux.
290+
291+The new version is being written on Unix for Unix and
292+should be much easier to read and a great deal cleaner.
293+
294+Supported Cards/Chipsets
295+-------------------------
296+ Dell Computer Corporation PERC 2 Quad Channel
297+ Dell Computer Corporation PERC 2/Si
298+ Dell Computer Corporation PERC 3/Si
299+ Dell Computer Corporation PERC 3/Di
300+ HP NetRAID-4M
301+
302+Not Supported Devices
303+-------------------------
304+ Any and All Adaptec branded raid controllers.
305+
306+People
307+-------------------------
308+ Adaptec Unix OEM Product Group
309+
310+Mailing List
311+-------------------------
312+please see http://domsch.com/linux for information
313+on mailing lists. There is both a development and
314+an announcment list. Due to the overwhelming amount
315+of mail I receive about this driver, I can not
316+answer questions individually and requests should
317+be directed to the list server. Thanks.
318+
319+Modified by Brian Boerner February 2001
320diff -burN linux-2.4.9/drivers/scsi/aacraid/aachba.c linux/drivers/scsi/aacraid/aachba.c
321--- linux-2.4.9/drivers/scsi/aacraid/aachba.c Wed Dec 31 18:00:00 1969
322+++ linux/drivers/scsi/aacraid/aachba.c Thu Aug 16 13:41:30 2001
323@@ -0,0 +1,1897 @@
324+/*++
325+ * Adaptec aacraid device driver for Linux.
326+ *
327+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
328+ *
329+ * This program is free software; you can redistribute it and/or modify
330+ * it under the terms of the GNU General Public License as published by
331+ * the Free Software Foundation; either version 2, or (at your option)
332+ * any later version.
333+ *
334+ * This program is distributed in the hope that it will be useful,
335+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
336+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
337+ * GNU General Public License for more details.
338+ *
339+ * You should have received a copy of the GNU General Public License
340+ * along with this program; see the file COPYING. If not, write to
341+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
342+ *
343+ * Module Name:
344+ * aachba.c
345+ *
346+ * Abstract: driver...
347+ *
348+--*/
349+
350+static char *ident_aachba = "aacraid_ident aachba.c 1.0.6 2000/10/09 Adaptec, Inc.";
351+
352+/*------------------------------------------------------------------------------
353+ * I N C L U D E S
354+ *----------------------------------------------------------------------------*/
355+#include "osheaders.h"
356+#include "AacGenericTypes.h"
357+#include "aac_unix_defs.h"
358+#include "comstruc.h"
359+#include "monkerapi.h"
360+#include "protocol.h"
361+#include "fsafs.h"
362+#include "fsact.h"
363+#include "fsaioctl.h"
364+
365+#include "sap1common.h"
366+#include "fsaport.h"
367+#include "pcisup.h"
368+#include "sap1.h"
369+#include "nodetype.h"
370+#include "comsup.h"
371+#include "afacomm.h"
372+#include "adapter.h"
373+
374+/*------------------------------------------------------------------------------
375+ * D E F I N E S
376+ *----------------------------------------------------------------------------*/
377+/* SCSI Commands */
378+#define SS_TEST 0x00 /* Test unit ready */
379+#define SS_REZERO 0x01 /* Rezero unit */
380+#define SS_REQSEN 0x03 /* Request Sense */
381+#define SS_REASGN 0x07 /* Reassign blocks */
382+#define SS_READ 0x08 /* Read 6 */
383+#define SS_WRITE 0x0A /* Write 6 */
384+#define SS_INQUIR 0x12 /* inquiry */
385+#define SS_ST_SP 0x1B /* Start/Stop unit */
386+#define SS_LOCK 0x1E /* prevent/allow medium removal */
387+#define SS_RESERV 0x16 /* Reserve */
388+#define SS_RELES 0x17 /* Release */
389+#define SS_MODESEN 0x1A /* Mode Sense 6 */
390+#define SS_RDCAP 0x25 /* Read Capacity */
391+#define SM_READ 0x28 /* Read 10 */
392+#define SM_WRITE 0x2A /* Write 10 */
393+#define SS_SEEK 0x2B /* Seek */
394+
395+/* values for inqd_pdt: Peripheral device type in plain English */
396+#define INQD_PDT_DA 0x00 /* Direct-access (DISK) device */
397+#define INQD_PDT_PROC 0x03 /* Processor device */
398+#define INQD_PDT_CHNGR 0x08 /* Changer (jukebox, scsi2) */
399+#define INQD_PDT_COMM 0x09 /* Communication device (scsi2) */
400+#define INQD_PDT_NOLUN2 0x1f /* Unknown Device (scsi2) */
401+#define INQD_PDT_NOLUN 0x7f /* Logical Unit Not Present */
402+
403+#define INQD_PDT_DMASK 0x1F /* Peripheral Device Type Mask */
404+#define INQD_PDT_QMASK 0xE0 /* Peripheral Device Qualifer Mask */
405+
406+#define TARGET_LUN_TO_CONTAINER(Target, Lun) (((Lun) << 4) | Target)
407+#define CONTAINER_TO_TARGET(Container) ((Container) & 0xf)
408+#define CONTAINER_TO_LUN(Container) ((Container) >> 4)
409+
410+#define MAX_FIB_DATA (sizeof(FIB) - sizeof(FIB_HEADER))
411+
412+#define MAX_DRIVER_SG_SEGMENT_COUNT 17
413+
414+// ------------------------------------------------------
415+// Sense keys
416+//
417+#define SENKEY_NO_SENSE 0x00 //
418+#define SENKEY_UNDEFINED 0x01 //
419+#define SENKEY_NOT_READY 0x02 //
420+#define SENKEY_MEDIUM_ERR 0x03 //
421+#define SENKEY_HW_ERR 0x04 //
422+#define SENKEY_ILLEGAL 0x05 //
423+#define SENKEY_ATTENTION 0x06 //
424+#define SENKEY_PROTECTED 0x07 //
425+#define SENKEY_BLANK 0x08 //
426+#define SENKEY_V_UNIQUE 0x09 //
427+#define SENKEY_CPY_ABORT 0x0A //
428+#define SENKEY_ABORT 0x0B //
429+#define SENKEY_EQUAL 0x0C //
430+#define SENKEY_VOL_OVERFLOW 0x0D //
431+#define SENKEY_MISCOMP 0x0E //
432+#define SENKEY_RESERVED 0x0F //
433+
434+// ------------------------------------------------------
435+// Sense codes
436+//
437+#define SENCODE_NO_SENSE 0x00
438+#define SENCODE_END_OF_DATA 0x00
439+#define SENCODE_BECOMING_READY 0x04
440+#define SENCODE_INIT_CMD_REQUIRED 0x04
441+#define SENCODE_PARAM_LIST_LENGTH_ERROR 0x1A
442+#define SENCODE_INVALID_COMMAND 0x20
443+#define SENCODE_LBA_OUT_OF_RANGE 0x21
444+#define SENCODE_INVALID_CDB_FIELD 0x24
445+#define SENCODE_LUN_NOT_SUPPORTED 0x25
446+#define SENCODE_INVALID_PARAM_FIELD 0x26
447+#define SENCODE_PARAM_NOT_SUPPORTED 0x26
448+#define SENCODE_PARAM_VALUE_INVALID 0x26
449+#define SENCODE_RESET_OCCURRED 0x29
450+#define SENCODE_LUN_NOT_SELF_CONFIGURED_YET 0x3E
451+#define SENCODE_INQUIRY_DATA_CHANGED 0x3F
452+#define SENCODE_SAVING_PARAMS_NOT_SUPPORTED 0x39
453+#define SENCODE_DIAGNOSTIC_FAILURE 0x40
454+#define SENCODE_INTERNAL_TARGET_FAILURE 0x44
455+#define SENCODE_INVALID_MESSAGE_ERROR 0x49
456+#define SENCODE_LUN_FAILED_SELF_CONFIG 0x4c
457+#define SENCODE_OVERLAPPED_COMMAND 0x4E
458+
459+// ------------------------------------------------------
460+// Additional sense codes
461+//
462+#define ASENCODE_NO_SENSE 0x00
463+#define ASENCODE_END_OF_DATA 0x05
464+#define ASENCODE_BECOMING_READY 0x01
465+#define ASENCODE_INIT_CMD_REQUIRED 0x02
466+#define ASENCODE_PARAM_LIST_LENGTH_ERROR 0x00
467+#define ASENCODE_INVALID_COMMAND 0x00
468+#define ASENCODE_LBA_OUT_OF_RANGE 0x00
469+#define ASENCODE_INVALID_CDB_FIELD 0x00
470+#define ASENCODE_LUN_NOT_SUPPORTED 0x00
471+#define ASENCODE_INVALID_PARAM_FIELD 0x00
472+#define ASENCODE_PARAM_NOT_SUPPORTED 0x01
473+#define ASENCODE_PARAM_VALUE_INVALID 0x02
474+#define ASENCODE_RESET_OCCURRED 0x00
475+#define ASENCODE_LUN_NOT_SELF_CONFIGURED_YET 0x00
476+#define ASENCODE_INQUIRY_DATA_CHANGED 0x03
477+#define ASENCODE_SAVING_PARAMS_NOT_SUPPORTED 0x00
478+#define ASENCODE_DIAGNOSTIC_FAILURE 0x80
479+#define ASENCODE_INTERNAL_TARGET_FAILURE 0x00
480+#define ASENCODE_INVALID_MESSAGE_ERROR 0x00
481+#define ASENCODE_LUN_FAILED_SELF_CONFIG 0x00
482+#define ASENCODE_OVERLAPPED_COMMAND 0x00
483+
484+#define BYTE0( x ) ( unsigned char )( x )
485+#define BYTE1( x ) ( unsigned char )( x >> 8 )
486+#define BYTE2( x ) ( unsigned char )( x >> 16 )
487+#define BYTE3( x ) ( unsigned char )( x >> 24 )
488+
489+/*------------------------------------------------------------------------------
490+ * S T R U C T S / T Y P E D E F S
491+ *----------------------------------------------------------------------------*/
492+/* SCSI inquiry data */
493+struct inquiry_data {
494+ unchar inqd_pdt; /* Peripheral qualifier | Peripheral Device Type */
495+ unchar inqd_dtq; /* RMB | Device Type Qualifier */
496+ unchar inqd_ver; /* ISO version | ECMA version | ANSI-approved version */
497+ unchar inqd_rdf; /* AENC | TrmIOP | Response data format */
498+ unchar inqd_len; /* Additional length (n-4) */
499+ unchar inqd_pad1[2]; /* Reserved - must be zero */
500+ unchar inqd_pad2; /* RelAdr | WBus32 | WBus16 | Sync | Linked |Reserved| CmdQue | SftRe */
501+ unchar inqd_vid[8]; /* Vendor ID */
502+ unchar inqd_pid[16]; /* Product ID */
503+ unchar inqd_prl[4]; /* Product Revision Level */
504+};
505+
506+struct sense_data {
507+ unchar error_code; // 70h (current errors), 71h(deferred errors)
508+ unchar valid:1; // A valid bit of one indicates that the information
509+ // field contains valid information as defined in the
510+ // SCSI-2 Standard.
511+
512+ unchar segment_number; // Only used for COPY, COMPARE, or COPY AND VERIFY
513+ // commands
514+
515+ unchar sense_key:4; // Sense Key
516+ unchar reserved:1;
517+ unchar ILI:1; // Incorrect Length Indicator
518+ unchar EOM:1; // End Of Medium - reserved for random access devices
519+ unchar filemark:1; // Filemark - reserved for random access devices
520+
521+ unchar information[4]; // for direct-access devices, contains the unsigned
522+ // logical block address or residue associated with
523+ // the sense key
524+ unchar add_sense_len; // number of additional sense bytes to follow this field
525+ unchar cmnd_info[4]; // not used
526+ unchar ASC; // Additional Sense Code
527+ unchar ASCQ; // Additional Sense Code Qualifier
528+ unchar FRUC; // Field Replaceable Unit Code - not used
529+
530+ unchar bit_ptr:3; // indicates which byte of the CDB or parameter data
531+ // was in error
532+ unchar BPV:1; // bit pointer valid (BPV): 1- indicates that
533+ // the bit_ptr field has valid value
534+ unchar reserved2:2;
535+ unchar CD:1; // command data bit: 1- illegal parameter in CDB.
536+ // 0- illegal parameter in data.
537+ unchar SKSV:1;
538+
539+ unchar field_ptr[2]; // byte of the CDB or parameter data in error
540+};
541+
542+/*------------------------------------------------------------------------------
543+ * G L O B A L S
544+ *----------------------------------------------------------------------------*/
545+/*------------------------------------------------------------------------------
546+ * M O D U L E G L O B A L S
547+ *----------------------------------------------------------------------------*/
548+static fsadev_t *g_fsa_dev_array[8]; // SCSI Device Instance Pointers
549+static struct sense_data g_sense_data[MAXIMUM_NUM_CONTAINERS];
550+
551+/*------------------------------------------------------------------------------
552+ * F U N C T I O N P R O T O T Y P E S
553+ *----------------------------------------------------------------------------*/
554+AAC_STATUS AacHba_OpenAdapter( PVOID AdapterArg);
555+AAC_STATUS AacHba_CloseAdapter( PVOID AdapterArg);
556+BOOLEAN AacHba_HandleAif( PVOID AdapterArg, PFIB_CONTEXT FibContext);
557+BOOLEAN AacHba_AdapterDeviceControl ( PVOID AdapterArg,
558+ PAFA_IOCTL_CMD IoctlCmdPtr, int * ReturnStatus);
559+
560+void AacHba_CompleteScsi(
561+ Scsi_Cmnd *scsi_cmnd_ptr );
562+
563+void AacHba_CompleteScsiNoLock(
564+ Scsi_Cmnd *scsi_cmnd_ptr );
565+
566+static void AacHba_ReadCallback(
567+ void *Context,
568+ PFIB_CONTEXT FibContext,
569+ int FibStatus );
570+
571+static void AacHba_WriteCallback(
572+ void *Context,
573+ PFIB_CONTEXT FibContext,
574+ int FibStatus );
575+
576+int AacHba_DoScsiRead(
577+ Scsi_Cmnd *scsi_cmnd_ptr,
578+ int ContainerId,
579+ int wait );
580+
581+int AacHba_DoScsiWrite(
582+ Scsi_Cmnd *scsi_cmnd_ptr,
583+ int ContainerId,
584+ int wait );
585+
586+int AacHba_QueryDisk(
587+ PVOID AdapterArg, // CommonExtensionPtr
588+ IN PAFA_IOCTL_CMD IoctlCmdPtr );
589+
590+int AacHba_ForceDeleteDisk(
591+ PVOID AdapterArg, // CommonExtensionPtr
592+ IN PAFA_IOCTL_CMD IoctlCmdPtr );
593+
594+int AacHba_DeleteDisk(
595+ PVOID AdapterArg,
596+ IN PAFA_IOCTL_CMD IoctlCmdPtr );
597+
598+void AacHba_DetachAdapter(
599+ IN PVOID AdapterArg );
600+
601+BOOLEAN AacCommDetachAdapter(
602+ IN PAFA_COMM_ADAPTER Adapter );
603+
604+void AacHba_SetSenseData(
605+ char * sense_buf,
606+ unchar sense_key,
607+ unchar sense_code,
608+ unchar a_sense_code,
609+ unchar incorrect_length,
610+ unchar bit_pointer,
611+ unsigned field_pointer,
612+ unsigned long residue );
613+
614+static void get_sd_devname(
615+ long disknum,
616+ char * buffer);
617+
618+// Keep these here for the time being - #REVIEW#
619+int
620+AfaCommAdapterDeviceControl (
621+ IN PVOID AdapterArg,
622+ IN PAFA_IOCTL_CMD IoctlCmdPtr
623+ );
624+
625+AAC_STATUS
626+AfaCommRegisterNewClassDriver(
627+ IN PAFA_COMM_ADAPTER Adapter,
628+ IN PAFA_NEW_CLASS_DRIVER NewClassDriver,
629+ OUT PAFA_NEW_CLASS_DRIVER_RESPONSE NewClassDriverResponse
630+ );
631+
632+void
633+SetInqDataStr (int, void *, int);
634+/*------------------------------------------------------------------------------
635+ * F U N C T I O N S
636+ *----------------------------------------------------------------------------*/
637+
638+/*------------------------------------------------------------------------------
639+ AacHba_ClassDriverInit()
640+
641+ Setup 'core' class driver to answer ioctl's
642+ *----------------------------------------------------------------------------*/
643+int AacHba_ClassDriverInit(
644+ PCI_MINIPORT_COMMON_EXTENSION * CommonExtensionPtr)
645+/*----------------------------------------------------------------------------*/
646+{
647+ AFA_NEW_CLASS_DRIVER NewClassDriver;
648+ AFA_NEW_CLASS_DRIVER_RESPONSE NewClassDriverResponse;
649+ PAFA_COMM_ADAPTER Adapter;
650+
651+ Adapter = (AFA_COMM_ADAPTER *)CommonExtensionPtr->Adapter;
652+
653+ RtlZeroMemory( &NewClassDriver, sizeof( AFA_NEW_CLASS_DRIVER ) );
654+
655+ // ClassDriverExtension is the first argument passed to class driver functions below
656+ NewClassDriver.ClassDriverExtension = CommonExtensionPtr;
657+
658+ NewClassDriver.OpenAdapter = AacHba_OpenAdapter;
659+ NewClassDriver.CloseAdapter = AacHba_CloseAdapter;
660+ NewClassDriver.DeviceControl = AacHba_AdapterDeviceControl;
661+ NewClassDriver.HandleAif = AacHba_HandleAif;
662+ AfaCommRegisterNewClassDriver( Adapter, &NewClassDriver, &NewClassDriverResponse );
663+
664+ return(0);
665+}
666+
667+
668+/*------------------------------------------------------------------------------
669+ AacHba_ProbeContainers()
670+
671+ Make a list of all containers in the system.
672+------------------------------------------------------------------------------*/
673+int AacHba_ProbeContainers (PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr)
674+{
675+ fsadev_t *fsa_dev_ptr;
676+ int Index, Status;
677+ PMNTINFO DiskInfo;
678+ PMNTINFORESPONSE DiskInfoResponse;
679+ PFIB_CONTEXT FibContext;
680+ AFA_COMM_ADAPTER *Adapter;
681+ unsigned instance;
682+ char *bufp;
683+ int size;
684+
685+
686+ Adapter = ( AFA_COMM_ADAPTER * )CommonExtensionPtr->Adapter;
687+ fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
688+ instance = CommonExtensionPtr->OsDep.scsi_host_ptr->unique_id;
689+
690+ if( !( FibContext = Adapter->CommFuncs.AllocateFib( Adapter ) ) )
691+ {
692+ cmn_err( CE_WARN, "AacHba_ProbeContainers: AllocateFib failed" );
693+ return( STATUS_UNSUCCESSFUL );
694+ }
695+
696+ for ( Index = 0; Index < MAXIMUM_NUM_CONTAINERS; Index++ )
697+ {
698+ Adapter->CommFuncs.InitializeFib( FibContext );
699+
700+ DiskInfo = ( PMNTINFO )Adapter->CommFuncs.GetFibData( FibContext );
701+
702+ DiskInfo->Command = VM_NameServe;
703+ DiskInfo->MntCount = Index;
704+ DiskInfo->MntType = FT_FILESYS;
705+
706+ Status = Adapter->CommFuncs.SendFib( ContainerCommand,
707+ FibContext,
708+ sizeof(MNTINFO),
709+ FsaNormal,
710+ TRUE,
711+ NULL,
712+ TRUE,
713+ NULL,
714+ NULL );
715+ if ( Status )
716+ {
717+ cmn_err( CE_WARN, "ProbeContainers: SendFIb Failed" );
718+ break;
719+ }
720+
721+ DiskInfoResponse = ( PMNTINFORESPONSE )Adapter->CommFuncs.GetFibData( FibContext );
722+
723+
724+ if ( ( DiskInfoResponse->Status == ST_OK ) &&
725+ ( DiskInfoResponse->MntTable[0].VolType != CT_NONE ) )
726+ {
727+
728+
729+ fsa_dev_ptr->ContainerValid[Index] = TRUE;
730+ fsa_dev_ptr->ContainerType[Index] = DiskInfoResponse->MntTable[0].VolType;
731+ fsa_dev_ptr->ContainerSize[Index] = DiskInfoResponse->MntTable[0].Capacity;
732+
733+ if (DiskInfoResponse->MntTable[0].ContentState & FSCS_READONLY)
734+ fsa_dev_ptr->ContainerReadOnly[Index] = TRUE;
735+ }
736+
737+ Adapter->CommFuncs.CompleteFib( FibContext );
738+
739+ // If there are no more containers, then stop asking.
740+ if ((Index + 1) >= DiskInfoResponse->MntRespCount)
741+ break;
742+ } // end for()
743+
744+ Adapter->CommFuncs.FreeFib( FibContext );
745+
746+ g_fsa_dev_array[instance] = fsa_dev_ptr;
747+ return( Status );
748+}
749+
750+
751+/*------------------------------------------------------------------------------
752+ AacHba_ProbeContainer()
753+
754+ Probe a single container.
755+ *----------------------------------------------------------------------------*/
756+int AacHba_ProbeContainer(
757+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr,
758+ int ContainerId )
759+/*----------------------------------------------------------------------------*/
760+{
761+ fsadev_t *fsa_dev_ptr;
762+ int Status;
763+ PMNTINFO DiskInfo;
764+ PMNTINFORESPONSE DiskInfoResponse;
765+ PFIB_CONTEXT FibContext;
766+ AFA_COMM_ADAPTER *Adapter;
767+ unsigned instance;
768+
769+ Adapter = ( AFA_COMM_ADAPTER * )CommonExtensionPtr->Adapter;
770+ fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
771+ instance = CommonExtensionPtr->OsDep.scsi_host_ptr->unique_id;
772+
773+ if( !( FibContext = Adapter->CommFuncs.AllocateFib( Adapter ) ) )
774+ {
775+ cmn_err( CE_WARN, "AacHba_ProbeContainers: AllocateFib failed" );
776+ return( STATUS_UNSUCCESSFUL );
777+ }
778+
779+ Adapter->CommFuncs.InitializeFib( FibContext );
780+
781+ DiskInfo = ( PMNTINFO )Adapter->CommFuncs.GetFibData( FibContext );
782+
783+ DiskInfo->Command = VM_NameServe;
784+ DiskInfo->MntCount = ContainerId;
785+ DiskInfo->MntType = FT_FILESYS;
786+
787+ Status = Adapter->CommFuncs.SendFib (ContainerCommand,
788+ FibContext,
789+ sizeof(MNTINFO),
790+ FsaNormal,
791+ TRUE,
792+ NULL,
793+ TRUE,
794+ NULL,
795+ NULL );
796+ if ( Status )
797+ {
798+ cmn_err( CE_WARN, "ProbeContainers: SendFIb Failed" );
799+ Adapter->CommFuncs.CompleteFib( FibContext );
800+ Adapter->CommFuncs.FreeFib( FibContext );
801+ return( Status );
802+ }
803+
804+ DiskInfoResponse = ( PMNTINFORESPONSE )Adapter->CommFuncs.GetFibData( FibContext );
805+
806+
807+ if ( ( DiskInfoResponse->Status == ST_OK ) &&
808+ ( DiskInfoResponse->MntTable[0].VolType != CT_NONE ) )
809+ {
810+
811+ fsa_dev_ptr->ContainerValid[ContainerId] = TRUE;
812+ fsa_dev_ptr->ContainerType[ContainerId] = DiskInfoResponse->MntTable[0].VolType;
813+ fsa_dev_ptr->ContainerSize[ContainerId] = DiskInfoResponse->MntTable[0].Capacity;
814+ if (DiskInfoResponse->MntTable[0].ContentState & FSCS_READONLY)
815+ fsa_dev_ptr->ContainerReadOnly[ContainerId] = TRUE;
816+ }
817+
818+ Adapter->CommFuncs.CompleteFib( FibContext );
819+ Adapter->CommFuncs.FreeFib( FibContext );
820+
821+ return( Status );
822+}
823+
824+
825+/*------------------------------------------------------------------------------
826+ AacHba_CompleteScsi()
827+
828+ Call SCSI completion routine after acquiring io_request_lock
829+
830+ Preconditions:
831+ Postconditions:
832+ *----------------------------------------------------------------------------*/
833+void AacHba_CompleteScsi(
834+ Scsi_Cmnd *scsi_cmnd_ptr )
835+{
836+ unsigned long cpu_flags;
837+
838+ spin_lock_irqsave( &io_request_lock, cpu_flags );
839+ scsi_cmnd_ptr->scsi_done( scsi_cmnd_ptr );
840+ spin_unlock_irqrestore( &io_request_lock, cpu_flags );
841+}
842+
843+
844+/*------------------------------------------------------------------------------
845+ AacHba_CompleteScsiNoLock()
846+
847+ Call SCSI completion routine
848+
849+ Preconditions:
850+ Postconditions:
851+ *----------------------------------------------------------------------------*/
852+void AacHba_CompleteScsiNoLock(
853+ Scsi_Cmnd *scsi_cmnd_ptr )
854+{
855+ scsi_cmnd_ptr->scsi_done( scsi_cmnd_ptr );
856+}
857+
858+/*------------------------------------------------------------------------------
859+ AacHba_DoScsiCmd()
860+
861+ Process SCSI command
862+
863+ Preconditions:
864+ Postconditions:
865+ Returns 0 on success, -1 on failure
866+ *----------------------------------------------------------------------------*/
867+int AacHba_DoScsiCmd(
868+ Scsi_Cmnd *scsi_cmnd_ptr,
869+ int wait )
870+{
871+ int ContainerId = 0;
872+ fsadev_t *fsa_dev_ptr;
873+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
874+ int MiniPortIndex;
875+
876+ CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
877+ MiniPortIndex = CommonExtensionPtr->OsDep.MiniPortIndex;
878+
879+ fsa_dev_ptr = g_fsa_dev_array[ scsi_cmnd_ptr->host->unique_id ];
880+
881+ // If the bus, target or lun is out of range, return fail
882+ // Test does not apply to ID 16, the pseudo id for the controller itself.
883+ if ( scsi_cmnd_ptr->target != scsi_cmnd_ptr->host->this_id )
884+ {
885+ if( ( scsi_cmnd_ptr->channel > 0 ) ||
886+ ( scsi_cmnd_ptr->target > 15 ) ||
887+ ( scsi_cmnd_ptr->lun > 7 ) )
888+ {
889+ cmn_err( CE_DEBUG, "The bus, target or lun is out of range = %d, %d, %d",
890+ scsi_cmnd_ptr->channel,
891+ scsi_cmnd_ptr->target,
892+ scsi_cmnd_ptr->lun );
893+ scsi_cmnd_ptr->result = DID_BAD_TARGET << 16;
894+
895+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
896+
897+ return ( -1 );
898+ }
899+
900+ ContainerId = TARGET_LUN_TO_CONTAINER( scsi_cmnd_ptr->target, scsi_cmnd_ptr->lun );
901+
902+
903+ // If the target container doesn't exist, it may have been newly created
904+ if( fsa_dev_ptr->ContainerValid[ContainerId] == 0 )
905+ {
906+ switch( scsi_cmnd_ptr->cmnd[0] )
907+ {
908+ case SS_INQUIR:
909+ case SS_RDCAP:
910+ case SS_TEST:
911+ spin_unlock_irq( &io_request_lock );
912+ AacHba_ProbeContainer( CommonExtensionPtr, ContainerId );
913+ spin_lock_irq( &io_request_lock );
914+ default:
915+ break;
916+ }
917+ }
918+
919+ // If the target container still doesn't exist, return failure
920+ if( fsa_dev_ptr->ContainerValid[ContainerId] == 0 )
921+ {
922+
923+ scsi_cmnd_ptr->result = DID_BAD_TARGET << 16;
924+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
925+
926+ return ( -1 );
927+ }
928+ }
929+ else // the command is for the controller itself
930+ if( ( scsi_cmnd_ptr->cmnd[0] != SS_INQUIR ) && // only INQUIRY & TUR cmnd supported for controller
931+ ( scsi_cmnd_ptr->cmnd[0] != SS_TEST ) )
932+ {
933+ cmn_err( CE_WARN, "Only INQUIRY & TUR command supported for controller, rcvd = 0x%x",
934+ scsi_cmnd_ptr->cmnd[0] );
935+
936+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
937+
938+ AacHba_SetSenseData( (char *)&g_sense_data[ ContainerId ],
939+ SENKEY_ILLEGAL, SENCODE_INVALID_COMMAND, ASENCODE_INVALID_COMMAND,
940+ 0, 0, 0, 0 );
941+
942+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
943+
944+ return ( -1 );
945+ }
946+
947+ // Handle commands here that don't really require going out to the adapter
948+ switch ( scsi_cmnd_ptr->cmnd[0] )
949+ {
950+ case SS_INQUIR:
951+ {
952+ struct inquiry_data *inq_data_ptr;
953+
954+ cmn_err( CE_DEBUG, "INQUIRY command, ID: %d", scsi_cmnd_ptr->target );
955+ inq_data_ptr = ( struct inquiry_data * )scsi_cmnd_ptr->request_buffer;
956+ bzero( inq_data_ptr, sizeof( struct inquiry_data ) );
957+
958+ inq_data_ptr->inqd_ver = 2; // claim compliance to SCSI-2
959+
960+ inq_data_ptr->inqd_dtq = 0x80; // set RMB bit to one indicating
961+ // that the medium is removable
962+ inq_data_ptr->inqd_rdf = 2; // A response data format value of
963+ // two indicates that the data shall
964+ // be in the format specified in SCSI-2
965+ inq_data_ptr->inqd_len = 31;
966+
967+ // Set the Vendor, Product, and Revision Level see: <vendor>.c i.e. aac.c
968+ SetInqDataStr( MiniPortIndex,
969+ (void *)(inq_data_ptr->inqd_vid),
970+ fsa_dev_ptr->ContainerType[ContainerId]);
971+
972+ if ( scsi_cmnd_ptr->target == scsi_cmnd_ptr->host->this_id )
973+ inq_data_ptr->inqd_pdt = INQD_PDT_PROC; // Processor device
974+ else
975+ inq_data_ptr->inqd_pdt = INQD_PDT_DA; // Direct/random access device
976+
977+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
978+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
979+
980+ return ( 0 );
981+ }
982+
983+ case SS_RDCAP:
984+ {
985+ int capacity;
986+ char *cp;
987+
988+ cmn_err( CE_DEBUG, "READ CAPACITY command" );
989+ capacity = fsa_dev_ptr->ContainerSize[ContainerId] - 1;
990+ cp = scsi_cmnd_ptr->request_buffer;
991+ cp[0] = ( capacity >> 24 ) & 0xff;
992+ cp[1] = ( capacity >> 16 ) & 0xff;
993+ cp[2] = ( capacity >> 8 ) & 0xff;
994+ cp[3] = ( capacity >> 0 ) & 0xff;
995+ cp[4] = 0;
996+ cp[5] = 0;
997+ cp[6] = 2;
998+ cp[7] = 0;
999+
1000+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1001+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1002+
1003+ return ( 0 );
1004+ }
1005+
1006+ case SS_MODESEN:
1007+ {
1008+ char *mode_buf;
1009+
1010+ cmn_err( CE_DEBUG, "MODE SENSE command" );
1011+ mode_buf = scsi_cmnd_ptr->request_buffer;
1012+ mode_buf[0] = 0; // Mode data length (MSB)
1013+ mode_buf[1] = 6; // Mode data length (LSB)
1014+ mode_buf[2] = 0; // Medium type - default
1015+ mode_buf[3] = 0; // Device-specific param, bit 8: 0/1 = write enabled/protected
1016+ mode_buf[4] = 0; // reserved
1017+ mode_buf[5] = 0; // reserved
1018+ mode_buf[6] = 0; // Block descriptor length (MSB)
1019+ mode_buf[7] = 0; // Block descriptor length (LSB)
1020+
1021+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1022+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1023+
1024+ return ( 0 );
1025+ }
1026+
1027+
1028+ // These commands are all No-Ops
1029+ case SS_TEST:
1030+ cmn_err( CE_DEBUG, "TEST UNIT READY command" );
1031+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1032+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1033+ return ( 0 );
1034+
1035+ case SS_REQSEN:
1036+ cmn_err( CE_DEBUG, "REQUEST SENSE command" );
1037+
1038+ memcpy( scsi_cmnd_ptr->sense_buffer, &g_sense_data[ContainerId],
1039+ sizeof( struct sense_data ) );
1040+ bzero( &g_sense_data[ContainerId], sizeof( struct sense_data ) );
1041+
1042+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1043+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1044+ return ( 0 );
1045+
1046+ case SS_LOCK:
1047+ cmn_err(CE_DEBUG, "LOCK command");
1048+
1049+ if( scsi_cmnd_ptr->cmnd[4] )
1050+ fsa_dev_ptr->ContainerLocked[ContainerId] = 1;
1051+ else
1052+ fsa_dev_ptr->ContainerLocked[ContainerId] = 0;
1053+
1054+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1055+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1056+ return ( 0 );
1057+
1058+ case SS_RESERV:
1059+ cmn_err( CE_DEBUG, "RESERVE command" );
1060+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1061+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1062+ return ( 0 );
1063+
1064+ case SS_RELES:
1065+ cmn_err( CE_DEBUG, "RELEASE command" );
1066+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1067+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1068+ return ( 0 );
1069+
1070+ case SS_REZERO:
1071+ cmn_err( CE_DEBUG, "REZERO command" );
1072+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1073+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1074+ return ( 0 );
1075+
1076+ case SS_REASGN:
1077+ cmn_err( CE_DEBUG, "REASSIGN command" );
1078+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1079+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1080+ return ( 0 );
1081+
1082+ case SS_SEEK:
1083+ cmn_err( CE_DEBUG, "SEEK command" );
1084+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1085+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1086+ return ( 0 );
1087+
1088+ case SS_ST_SP:
1089+ cmn_err( CE_DEBUG, "START/STOP command" );
1090+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1091+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1092+ return ( 0 );
1093+ }
1094+
1095+ switch ( scsi_cmnd_ptr->cmnd[0] )
1096+ {
1097+ case SS_READ:
1098+ case SM_READ:
1099+ // Hack to keep track of ordinal number of the device that corresponds
1100+ // to a container. Needed to convert containers to /dev/sd device names
1101+ fsa_dev_ptr->ContainerDevNo[ContainerId] =
1102+ DEVICE_NR( scsi_cmnd_ptr->request.rq_dev );
1103+
1104+ return( AacHba_DoScsiRead( scsi_cmnd_ptr, ContainerId, wait ) );
1105+ break;
1106+
1107+ case SS_WRITE:
1108+ case SM_WRITE:
1109+
1110+ return( AacHba_DoScsiWrite( scsi_cmnd_ptr, ContainerId, wait ) );
1111+ break;
1112+ }
1113+ //
1114+ // Unhandled commands
1115+ //
1116+ cmn_err( CE_WARN, "Unhandled SCSI Command: 0x%x", scsi_cmnd_ptr->cmnd[0] );
1117+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1118+
1119+ AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1120+ SENKEY_ILLEGAL, SENCODE_INVALID_COMMAND, ASENCODE_INVALID_COMMAND,
1121+ 0, 0, 0, 0 );
1122+
1123+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1124+ return ( -1 );
1125+}
1126+
1127+
1128+/*------------------------------------------------------------------------------
1129+ AacHba_DoScsiRead()
1130+
1131+ Handles SCSI READ requests
1132+
1133+ Preconditions:
1134+ Postconditions:
1135+ Returns 0 on success, -1 on failure
1136+ *----------------------------------------------------------------------------*/
1137+int AacHba_DoScsiRead(
1138+ Scsi_Cmnd *scsi_cmnd_ptr,
1139+ int ContainerId,
1140+ int wait )
1141+/*----------------------------------------------------------------------------*/
1142+{
1143+ u_long lba;
1144+ u_long count;
1145+ u_long byte_count;
1146+ int Status;
1147+
1148+ PBLOCKREAD BlockReadDisk;
1149+ PBLOCKREADRESPONSE BlockReadResponse;
1150+ uint16_t FibSize;
1151+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
1152+ AFA_COMM_ADAPTER *Adapter;
1153+ PFIB_CONTEXT cmd_fibcontext;
1154+
1155+ CommonExtension = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
1156+ Adapter = ( AFA_COMM_ADAPTER * )CommonExtension->Adapter;
1157+
1158+ // Get block address and transfer length
1159+ if ( scsi_cmnd_ptr->cmnd[0] == SS_READ ) // 6 byte command
1160+ {
1161+ cmn_err( CE_DEBUG, "aachba: received a read(6) command on target %d", ContainerId );
1162+
1163+ lba = ( ( scsi_cmnd_ptr->cmnd[1] & 0x1F ) << 16 ) |
1164+ ( scsi_cmnd_ptr->cmnd[2] << 8 ) |
1165+ scsi_cmnd_ptr->cmnd[3];
1166+ count = scsi_cmnd_ptr->cmnd[4];
1167+
1168+ if ( count == 0 )
1169+ count = 256;
1170+ }
1171+ else
1172+ {
1173+ cmn_err( CE_DEBUG, "aachba: received a read(10) command on target %d", ContainerId );
1174+
1175+ lba = ( scsi_cmnd_ptr->cmnd[2] << 24 ) | ( scsi_cmnd_ptr->cmnd[3] << 16 ) |
1176+ ( scsi_cmnd_ptr->cmnd[4] << 8 ) | scsi_cmnd_ptr->cmnd[5];
1177+
1178+ count = ( scsi_cmnd_ptr->cmnd[7] << 8 ) | scsi_cmnd_ptr->cmnd[8];
1179+ }
1180+ cmn_err( CE_DEBUG, "AacHba_DoScsiRead[cpu %d]: lba = %lu, t = %ld", smp_processor_id(), lba, jiffies );
1181+
1182+ //-------------------------------------------------------------------------
1183+ // Alocate and initialize a Fib
1184+ // Setup BlockRead command
1185+ if( !( cmd_fibcontext = Adapter->CommFuncs.AllocateFib( Adapter ) ) )
1186+ {
1187+ cmn_err( CE_WARN, "AacHba_DoScsiRead: AllocateFib failed\n" );
1188+ scsi_cmnd_ptr->result = DID_ERROR << 16;
1189+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1190+ return ( -1 );
1191+ }
1192+
1193+ Adapter->CommFuncs.InitializeFib( cmd_fibcontext );
1194+
1195+ BlockReadDisk = ( PBLOCKREAD )Adapter->CommFuncs.GetFibData( cmd_fibcontext );
1196+ BlockReadDisk->Command = VM_CtBlockRead;
1197+ BlockReadDisk->ContainerId = ContainerId;
1198+ BlockReadDisk->BlockNumber = lba;
1199+ BlockReadDisk->ByteCount = count * 512;
1200+ BlockReadDisk->SgMap.SgCount = 1;
1201+
1202+ if( BlockReadDisk->ByteCount > ( 64 * 1024 ) )
1203+ {
1204+ cmn_err( CE_WARN, "AacHba_DoScsiRead: READ request is larger than 64K" );
1205+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1206+
1207+ AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1208+ SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD,
1209+ 0, 0, 7, 0 );
1210+
1211+ goto err_return;
1212+ }
1213+
1214+ //-------------------------------------------------------------------------
1215+ // Build Scatter/Gather list
1216+ //
1217+ if ( scsi_cmnd_ptr->use_sg ) // use scatter/gather list
1218+ {
1219+ struct scatterlist *scatterlist_ptr;
1220+ int segment;
1221+
1222+ scatterlist_ptr = ( struct scatterlist * )scsi_cmnd_ptr->request_buffer;
1223+
1224+ byte_count = 0;
1225+ for( segment = 0; segment< scsi_cmnd_ptr->use_sg; segment++ )
1226+ {
1227+ BlockReadDisk->SgMap.SgEntry[segment].SgAddress =
1228+ ( void * )OsVirtToPhys( scatterlist_ptr[segment].address );
1229+ BlockReadDisk->SgMap.SgEntry[segment].SgByteCount =
1230+ scatterlist_ptr[segment].length;
1231+
1232+#ifdef DEBUG_SGBUFFER
1233+ memset( scatterlist_ptr[segment].address, 0xa5,
1234+ scatterlist_ptr[segment].length );
1235+#endif
1236+
1237+ byte_count += scatterlist_ptr[segment].length;
1238+
1239+ if( BlockReadDisk->SgMap.SgEntry[segment].SgByteCount > ( 64 * 1024 ) )
1240+ {
1241+ cmn_err( CE_WARN, "AacHba_DoScsiRead: Segment byte count is larger than 64K" );
1242+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1243+
1244+ AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1245+ SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD,
1246+ 0, 0, 7, 0 );
1247+
1248+ goto err_return;
1249+ }
1250+ /*
1251+ cmn_err(CE_DEBUG, "SgEntry[%d].SgAddress = 0x%x, Byte count = 0x%x",
1252+ segment,
1253+ BlockReadDisk->SgMap.SgEntry[segment].SgAddress,
1254+ BlockReadDisk->SgMap.SgEntry[segment].SgByteCount);
1255+ */
1256+ }
1257+ BlockReadDisk->SgMap.SgCount = scsi_cmnd_ptr->use_sg;
1258+
1259+ if( BlockReadDisk->SgMap.SgCount > MAX_DRIVER_SG_SEGMENT_COUNT )
1260+ {
1261+ cmn_err( CE_WARN, "AacHba_DoScsiRead: READ request with SgCount > %d",
1262+ MAX_DRIVER_SG_SEGMENT_COUNT );
1263+ scsi_cmnd_ptr->result = DID_ERROR << 16;
1264+ goto err_return;
1265+ }
1266+ }
1267+ else // one piece of contiguous phys mem
1268+ {
1269+ BlockReadDisk->SgMap.SgEntry[0].SgAddress =
1270+ ( void * )OsVirtToPhys( scsi_cmnd_ptr->request_buffer );
1271+ BlockReadDisk->SgMap.SgEntry[0].SgByteCount = scsi_cmnd_ptr->request_bufflen;
1272+
1273+ byte_count = scsi_cmnd_ptr->request_bufflen;
1274+
1275+ if( BlockReadDisk->SgMap.SgEntry[0].SgByteCount > ( 64 * 1024 ) )
1276+ {
1277+ cmn_err( CE_WARN, "AacHba_DoScsiRead: Single segment byte count is larger than 64K" );
1278+ cmn_err( CE_WARN, "AacHba_DoScsiRead: ByteCount: %d", BlockReadDisk->ByteCount);
1279+ cmn_err( CE_WARN, "AacHba_DoScsiRead: SG ELEMENTS: %d", scsi_cmnd_ptr->use_sg);
1280+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1281+
1282+ AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1283+ SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD,
1284+ 0, 0, 7, 0 );
1285+
1286+ goto err_return;
1287+ }
1288+ }
1289+
1290+ if( byte_count != BlockReadDisk->ByteCount )
1291+ cmn_err( CE_WARN, "AacHba_DoScsiRead: byte_count != BlockReadDisk->ByteCount" );
1292+
1293+ //-------------------------------------------------------------------------
1294+ // Now send the Fib to the adapter
1295+ //
1296+ FibSize = sizeof( BLOCKREAD ) + ( ( BlockReadDisk->SgMap.SgCount - 1 ) * sizeof( SGENTRY ) );
1297+
1298+ if( wait )
1299+ {
1300+ // This path shouldn't ever get executed with the current driver
1301+ Status = Adapter->CommFuncs.SendFib( ContainerCommand,
1302+ cmd_fibcontext,
1303+ FibSize,
1304+ FsaNormal,
1305+ TRUE,
1306+ NULL,
1307+ TRUE,
1308+ NULL,
1309+ NULL);
1310+
1311+ BlockReadResponse = ( PBLOCKREADRESPONSE )
1312+ Adapter->CommFuncs.GetFibData( cmd_fibcontext );
1313+
1314+ Adapter->CommFuncs.CompleteFib( cmd_fibcontext );
1315+ Adapter->CommFuncs.FreeFib( cmd_fibcontext );
1316+
1317+ if( BlockReadResponse->Status != ST_OK )
1318+ {
1319+ cmn_err( CE_WARN, "AacHba_DoScsiRead: BlockReadCommand failed with status: %d",
1320+ BlockReadResponse->Status );
1321+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1322+
1323+ AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1324+ SENKEY_HW_ERR, SENCODE_INTERNAL_TARGET_FAILURE, ASENCODE_INTERNAL_TARGET_FAILURE,
1325+ 0, 0, 0, 0 );
1326+
1327+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1328+ return ( -1 );
1329+ }
1330+ else
1331+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1332+
1333+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1334+ return ( 0 );
1335+ }
1336+ else
1337+ {
1338+ Status = Adapter->CommFuncs.SendFib( ContainerCommand,
1339+ cmd_fibcontext,
1340+ FibSize,
1341+ FsaNormal,
1342+ FALSE,
1343+ NULL,
1344+ TRUE,
1345+ ( PFIB_CALLBACK )AacHba_ReadCallback,
1346+ ( void *)scsi_cmnd_ptr );
1347+
1348+ // Check that the command queued to the controller
1349+ if (Status != STATUS_PENDING) {
1350+ cmn_err( CE_WARN, "AacHba_DoScsiRead: SendFib failed with status: %d\n",
1351+ Status);
1352+
1353+ // For some reason, the Fib didn't queue, return QUEUE_FULL
1354+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | QUEUE_FULL ;
1355+ goto err_return;
1356+ }
1357+
1358+ // don't call done func here
1359+ return ( 0 );
1360+ }
1361+
1362+err_return:
1363+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1364+
1365+ Adapter->CommFuncs.CompleteFib( cmd_fibcontext );
1366+ Adapter->CommFuncs.FreeFib( cmd_fibcontext );
1367+
1368+ return ( -1 );
1369+}
1370+
1371+
1372+/*------------------------------------------------------------------------------
1373+ AacHba_DoScsiWrite()
1374+
1375+ Handles SCSI WRITE requests
1376+
1377+ Preconditions:
1378+ Postconditions:
1379+ Returns 0 on success, -1 on failure
1380+ *----------------------------------------------------------------------------*/
1381+int AacHba_DoScsiWrite(
1382+ Scsi_Cmnd *scsi_cmnd_ptr,
1383+ int ContainerId,
1384+ int wait )
1385+/*----------------------------------------------------------------------------*/
1386+{
1387+ u_long lba;
1388+ u_long count;
1389+ u_long byte_count;
1390+ int Status;
1391+
1392+ PBLOCKWRITE BlockWriteDisk;
1393+ PBLOCKWRITERESPONSE BlockWriteResponse;
1394+ uint16_t FibSize;
1395+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
1396+ AFA_COMM_ADAPTER *Adapter;
1397+ PFIB_CONTEXT cmd_fibcontext;
1398+
1399+ CommonExtension = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
1400+ Adapter = ( AFA_COMM_ADAPTER * )CommonExtension->Adapter;
1401+
1402+ // Get block address and transfer length
1403+ if ( scsi_cmnd_ptr->cmnd[0] == SS_WRITE ) // 6 byte command
1404+ {
1405+ lba = ( ( scsi_cmnd_ptr->cmnd[1] & 0x1F ) << 16 ) |
1406+ ( scsi_cmnd_ptr->cmnd[2] << 8 ) |
1407+ scsi_cmnd_ptr->cmnd[3];
1408+ count = scsi_cmnd_ptr->cmnd[4];
1409+
1410+ if ( count == 0 )
1411+ count = 256;
1412+ }
1413+ else
1414+ {
1415+ cmn_err( CE_DEBUG, "aachba: received a write(10) command on target %d", ContainerId );
1416+
1417+ lba = ( scsi_cmnd_ptr->cmnd[2] << 24 ) | ( scsi_cmnd_ptr->cmnd[3] << 16 ) |
1418+ ( scsi_cmnd_ptr->cmnd[4] << 8 ) | scsi_cmnd_ptr->cmnd[5];
1419+
1420+ count = ( scsi_cmnd_ptr->cmnd[7] << 8 ) | scsi_cmnd_ptr->cmnd[8];
1421+
1422+ }
1423+ cmn_err( CE_DEBUG, "AacHba_DoScsiWrite[cpu %d]: lba = %lu, t = %ld", smp_processor_id(), lba, jiffies );
1424+
1425+ //-------------------------------------------------------------------------
1426+ // Alocate and initialize a Fib
1427+ // Setup BlockWrite command
1428+ if( !( cmd_fibcontext = Adapter->CommFuncs.AllocateFib( Adapter ) ) )
1429+ {
1430+ cmn_err( CE_WARN, "AacHba_DoScsiWrite: AllocateFib failed\n" );
1431+ scsi_cmnd_ptr->result = DID_ERROR << 16;
1432+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1433+ return ( -1 );
1434+ }
1435+
1436+ Adapter->CommFuncs.InitializeFib( cmd_fibcontext );
1437+
1438+ BlockWriteDisk = (PBLOCKWRITE) Adapter->CommFuncs.GetFibData( cmd_fibcontext );
1439+ BlockWriteDisk->Command = VM_CtBlockWrite;
1440+ BlockWriteDisk->ContainerId = ContainerId;
1441+ BlockWriteDisk->BlockNumber = lba;
1442+ BlockWriteDisk->ByteCount = count * 512;
1443+ BlockWriteDisk->SgMap.SgCount = 1;
1444+
1445+
1446+ if ( BlockWriteDisk->ByteCount > ( 64 * 1024 ) )
1447+ {
1448+ struct scatterlist *scatterlist_ptr;
1449+ int segment;
1450+ scatterlist_ptr = (struct scatterlist *)scsi_cmnd_ptr->request_buffer;
1451+
1452+ cmn_err( CE_WARN, "\n");
1453+ cmn_err( CE_WARN, "AacHba_DoScsiWrite: WRITE request is larger than 64K");
1454+ cmn_err( CE_WARN, "AacHba_DoScsiWrite: ByteCount: %d", BlockWriteDisk->ByteCount);
1455+/* cmn_err( CE_WARN, "AacHba_DoScsiWrite: SG ELEMENTS: %d", scsi_cmnd_ptr->use_sg); */
1456+/* cmn_err( CE_WARN, "Dump SG Element Size..."); */
1457+/* for( segment = 0; segment < scsi_cmnd_ptr->use_sg; segment++ ) */
1458+/* { */
1459+/* cmn_err (CE_WARN, "SG Segment %d: %d", segment, scatterlist_ptr[segment].length); */
1460+/* } */
1461+/* cmn_err (CE_WARN, "\n"); */
1462+
1463+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1464+
1465+ AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1466+ SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD,
1467+ 0, 0, 7, 0 );
1468+
1469+ goto err_return;
1470+ }
1471+
1472+ //-------------------------------------------------------------------------
1473+ // Build Scatter/Gather list
1474+ //
1475+ if ( scsi_cmnd_ptr->use_sg ) // use scatter/gather list
1476+ {
1477+ struct scatterlist *scatterlist_ptr;
1478+ int segment;
1479+
1480+ scatterlist_ptr = ( struct scatterlist * )scsi_cmnd_ptr->request_buffer;
1481+
1482+ byte_count = 0;
1483+ for( segment = 0; segment< scsi_cmnd_ptr->use_sg; segment++ )
1484+ {
1485+ BlockWriteDisk->SgMap.SgEntry[segment].SgAddress =
1486+ ( HOSTADDRESS )OsVirtToPhys( scatterlist_ptr[segment].address );
1487+ BlockWriteDisk->SgMap.SgEntry[segment].SgByteCount =
1488+ scatterlist_ptr[segment].length;
1489+
1490+ byte_count += scatterlist_ptr[segment].length;
1491+
1492+ if ( BlockWriteDisk->SgMap.SgEntry[segment].SgByteCount > ( 64 * 1024 ) )
1493+ {
1494+ cmn_err( CE_WARN, "AacHba_DoScsiWrite: Segment byte count is larger than 64K" );
1495+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1496+
1497+ AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1498+ SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD,
1499+ 0, 0, 7, 0 );
1500+
1501+ goto err_return;
1502+ }
1503+
1504+ /*
1505+ cmn_err(CE_DEBUG, "SgEntry[%d].SgAddress = 0x%x, Byte count = 0x%x",
1506+ segment,
1507+ BlockWriteDisk->SgMap.SgEntry[segment].SgAddress,
1508+ BlockWriteDisk->SgMap.SgEntry[segment].SgByteCount);
1509+ */
1510+ }
1511+ BlockWriteDisk->SgMap.SgCount = scsi_cmnd_ptr->use_sg;
1512+
1513+ if( BlockWriteDisk->SgMap.SgCount > MAX_DRIVER_SG_SEGMENT_COUNT )
1514+ {
1515+ cmn_err( CE_WARN, "AacHba_DoScsiWrite: WRITE request with SgCount > %d",
1516+ MAX_DRIVER_SG_SEGMENT_COUNT );
1517+ scsi_cmnd_ptr->result = DID_ERROR << 16;
1518+ goto err_return;
1519+ }
1520+ }
1521+ else // one piece of contiguous phys mem
1522+ {
1523+ BlockWriteDisk->SgMap.SgEntry[0].SgAddress =
1524+ ( HOSTADDRESS )OsVirtToPhys( scsi_cmnd_ptr->request_buffer );
1525+ BlockWriteDisk->SgMap.SgEntry[0].SgByteCount = scsi_cmnd_ptr->request_bufflen;
1526+
1527+ byte_count = scsi_cmnd_ptr->request_bufflen;
1528+
1529+ if ( BlockWriteDisk->SgMap.SgEntry[0].SgByteCount > ( 64 * 1024 ) )
1530+ {
1531+ cmn_err( CE_WARN, "AacHba_DoScsiWrite: Single segment byte count is larger than 64K" );
1532+
1533+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1534+ AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1535+ SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD,
1536+ 0, 0, 7, 0 );
1537+
1538+ goto err_return;
1539+ }
1540+ }
1541+
1542+ if( byte_count != BlockWriteDisk->ByteCount )
1543+ cmn_err( CE_WARN, "AacHba_DoScsiWrite: byte_count != BlockReadDisk->ByteCount" );
1544+
1545+ //-------------------------------------------------------------------------
1546+ // Now send the Fib to the adapter
1547+ //
1548+ FibSize = sizeof( BLOCKWRITE ) + ( ( BlockWriteDisk->SgMap.SgCount - 1 ) * sizeof( SGENTRY ) );
1549+
1550+ if( wait )
1551+ {
1552+ // This path shouldn't ever get executed with the current driver
1553+ Status = Adapter->CommFuncs.SendFib( ContainerCommand,
1554+ cmd_fibcontext,
1555+ FibSize,
1556+ FsaNormal,
1557+ TRUE,
1558+ NULL,
1559+ TRUE,
1560+ NULL,
1561+ NULL );
1562+
1563+ BlockWriteResponse = ( PBLOCKWRITERESPONSE )
1564+ Adapter->CommFuncs.GetFibData( cmd_fibcontext );
1565+
1566+ Adapter->CommFuncs.CompleteFib( cmd_fibcontext );
1567+ Adapter->CommFuncs.FreeFib( cmd_fibcontext );
1568+
1569+ if( BlockWriteResponse->Status != ST_OK )
1570+ {
1571+ cmn_err( CE_WARN, "AacHba_DoScsiWrite: BlockWriteCommand failed with status: %d\n",
1572+ BlockWriteResponse->Status );
1573+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;;
1574+ AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1575+ SENKEY_HW_ERR, SENCODE_INTERNAL_TARGET_FAILURE, ASENCODE_INTERNAL_TARGET_FAILURE,
1576+ 0, 0, 0, 0 );
1577+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1578+ return ( -1 );
1579+ }
1580+ else
1581+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1582+
1583+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1584+ return ( 0 );
1585+ }
1586+ else
1587+ {
1588+ Status = Adapter->CommFuncs.SendFib( ContainerCommand,
1589+ cmd_fibcontext,
1590+ FibSize,
1591+ FsaNormal,
1592+ FALSE,
1593+ NULL,
1594+ TRUE,
1595+ ( PFIB_CALLBACK )AacHba_WriteCallback,
1596+ ( void * )scsi_cmnd_ptr );
1597+
1598+ // Check that the command queued to the controller
1599+ if (Status != STATUS_PENDING) {
1600+ cmn_err( CE_WARN, "AacHba_DoScsiWrite: SendFib failed with status: %d\n",
1601+ Status);
1602+
1603+ // For some reason, the Fib didn't queue, return QUEUE_FULL
1604+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | QUEUE_FULL ;
1605+ goto err_return;
1606+ }
1607+
1608+ // don't call done func here - it should be called by the WriteCallback
1609+ return ( 0 );
1610+ }
1611+
1612+err_return:
1613+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1614+
1615+ Adapter->CommFuncs.CompleteFib( cmd_fibcontext );
1616+ Adapter->CommFuncs.FreeFib( cmd_fibcontext );
1617+
1618+ return ( -1 );
1619+}
1620+
1621+
1622+/*------------------------------------------------------------------------------
1623+ AacHba_ReadCallback()
1624+ *----------------------------------------------------------------------------*/
1625+void AacHba_ReadCallback(
1626+ VOID *Context,
1627+ PFIB_CONTEXT FibContext,
1628+ int FibStatus )
1629+/*----------------------------------------------------------------------------*/
1630+{
1631+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
1632+ AFA_COMM_ADAPTER *Adapter;
1633+ BLOCKREADRESPONSE *BlockReadResponse;
1634+ Scsi_Cmnd * scsi_cmnd_ptr;
1635+ u_long lba;
1636+ int ContainerId;
1637+
1638+ scsi_cmnd_ptr = ( Scsi_Cmnd * )Context;
1639+
1640+ CommonExtension = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
1641+ Adapter = ( AFA_COMM_ADAPTER * )CommonExtension->Adapter;
1642+
1643+ ContainerId = TARGET_LUN_TO_CONTAINER( scsi_cmnd_ptr->target, scsi_cmnd_ptr->lun );
1644+
1645+ lba = ( ( scsi_cmnd_ptr->cmnd[1] & 0x1F ) << 16 ) |
1646+ ( scsi_cmnd_ptr->cmnd[2] << 8 ) |
1647+ scsi_cmnd_ptr->cmnd[3];
1648+ cmn_err( CE_DEBUG, "AacHba_ReadCallback[cpu %d]: lba = %ld, t = %ld", smp_processor_id(), lba, jiffies );
1649+
1650+ if( FibContext == 0 )
1651+ {
1652+ cmn_err( CE_WARN, "AacHba_ReadCallback: no fib context" );
1653+ scsi_cmnd_ptr->result = DID_ERROR << 16;
1654+ AacHba_CompleteScsi( scsi_cmnd_ptr );
1655+ return;
1656+ }
1657+
1658+ BlockReadResponse = ( PBLOCKREADRESPONSE )Adapter->CommFuncs.GetFibData( FibContext );
1659+
1660+ if ( BlockReadResponse->Status == ST_OK )
1661+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1662+ else
1663+ {
1664+ cmn_err( CE_WARN, "AacHba_ReadCallback: read failed, status = %d\n",
1665+ BlockReadResponse->Status );
1666+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1667+ AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1668+ SENKEY_HW_ERR, SENCODE_INTERNAL_TARGET_FAILURE, ASENCODE_INTERNAL_TARGET_FAILURE,
1669+ 0, 0, 0, 0 );
1670+ }
1671+
1672+#ifdef DEBUG_SGBUFFER
1673+ if ( scsi_cmnd_ptr->use_sg ) // use scatter/gather list
1674+ {
1675+ struct scatterlist *scatterlist_ptr;
1676+ int i, segment, count;
1677+ char *ptr;
1678+
1679+ scatterlist_ptr = ( struct scatterlist * )scsi_cmnd_ptr->request_buffer;
1680+
1681+ for( segment = 0; segment < scsi_cmnd_ptr->use_sg; segment++ )
1682+ {
1683+ count = 0;
1684+ ptr = scatterlist_ptr[segment].address;
1685+ for( i = 0; i < scatterlist_ptr[segment].length; i++ )
1686+ {
1687+ if( *( ptr++ ) == 0xa5 )
1688+ count++;
1689+ }
1690+ if( count == scatterlist_ptr[segment].length )
1691+ cmn_err( CE_WARN, "AacHba_ReadCallback: segment %d not filled", segment );
1692+
1693+ }
1694+ }
1695+#endif
1696+
1697+ Adapter->CommFuncs.CompleteFib( FibContext );
1698+ Adapter->CommFuncs.FreeFib( FibContext );
1699+
1700+ AacHba_CompleteScsi( scsi_cmnd_ptr );
1701+}
1702+
1703+/*------------------------------------------------------------------------------
1704+ AacHba_WriteCallback()
1705+ *----------------------------------------------------------------------------*/
1706+void AacHba_WriteCallback(
1707+ VOID *Context,
1708+ PFIB_CONTEXT FibContext,
1709+ int FibStatus )
1710+/*----------------------------------------------------------------------------*/
1711+{
1712+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
1713+ AFA_COMM_ADAPTER *Adapter;
1714+ BLOCKWRITERESPONSE *BlockWriteResponse;
1715+ Scsi_Cmnd *scsi_cmnd_ptr;
1716+ u_long lba;
1717+ int ContainerId;
1718+
1719+ scsi_cmnd_ptr = ( Scsi_Cmnd * )Context;
1720+
1721+ CommonExtension = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
1722+ Adapter = ( AFA_COMM_ADAPTER * )CommonExtension->Adapter;
1723+
1724+ ContainerId = TARGET_LUN_TO_CONTAINER( scsi_cmnd_ptr->target, scsi_cmnd_ptr->lun );
1725+
1726+ lba = ( ( scsi_cmnd_ptr->cmnd[1] & 0x1F ) << 16 ) |
1727+ ( scsi_cmnd_ptr->cmnd[2] << 8 ) |
1728+ scsi_cmnd_ptr->cmnd[3];
1729+ cmn_err( CE_DEBUG, "AacHba_WriteCallback[cpu %d]: lba = %ld, t = %ld", smp_processor_id(), lba, jiffies );
1730+ if( FibContext == 0 )
1731+ {
1732+ cmn_err( CE_WARN, "AacHba_WriteCallback: no fib context" );
1733+ scsi_cmnd_ptr->result = DID_ERROR << 16;
1734+ AacHba_CompleteScsi( scsi_cmnd_ptr );
1735+ return;
1736+ }
1737+
1738+ BlockWriteResponse = (PBLOCKWRITERESPONSE) Adapter->CommFuncs.GetFibData( FibContext );
1739+ if (BlockWriteResponse->Status == ST_OK)
1740+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1741+ else
1742+ {
1743+ cmn_err( CE_WARN, "AacHba_WriteCallback: write failed, status = %d\n",
1744+ BlockWriteResponse->Status );
1745+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1746+ AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1747+ SENKEY_HW_ERR, SENCODE_INTERNAL_TARGET_FAILURE, ASENCODE_INTERNAL_TARGET_FAILURE,
1748+ 0, 0, 0, 0 );
1749+ }
1750+
1751+ Adapter->CommFuncs.CompleteFib( FibContext );
1752+ Adapter->CommFuncs.FreeFib( FibContext );
1753+
1754+ AacHba_CompleteScsi( scsi_cmnd_ptr );
1755+}
1756+
1757+
1758+/*------------------------------------------------------------------------------
1759+ AacHba_Ioctl()
1760+
1761+ Handle IOCTL requests
1762+
1763+ Preconditions:
1764+ Postconditions:
1765+ *----------------------------------------------------------------------------*/
1766+int AacHba_Ioctl(
1767+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtension,
1768+ int cmd,
1769+ void * arg )
1770+/*----------------------------------------------------------------------------*/
1771+{
1772+ Sa_ADAPTER_EXTENSION *AdapterExtension;
1773+ AFA_IOCTL_CMD IoctlCmd;
1774+ int status;
1775+
1776+ AdapterExtension = ( Sa_ADAPTER_EXTENSION * )CommonExtension->MiniPort;
1777+
1778+ cmn_err( CE_DEBUG, "AacHba_Ioctl, type = %d", cmd );
1779+ switch( cmd )
1780+ {
1781+ case FSACTL_SENDFIB:
1782+ cmn_err( CE_DEBUG, "FSACTL_SENDFIB" );
1783+ break;
1784+
1785+ case FSACTL_AIF_THREAD:
1786+ cmn_err( CE_DEBUG, "FSACTL_AIF_THREAD" );
1787+ break;
1788+
1789+ case FSACTL_NULL_IO_TEST:
1790+ cmn_err( CE_DEBUG, "FSACTL_NULL_IO_TEST" );
1791+ break;
1792+
1793+ case FSACTL_SIM_IO_TEST:
1794+ cmn_err( CE_DEBUG, "FSACTL_SIM_IO_TEST" );
1795+ break;
1796+
1797+ case FSACTL_GET_FIBTIMES:
1798+ cmn_err( CE_DEBUG, "FSACTL_GET_FIBTIMES" );
1799+ break;
1800+
1801+ case FSACTL_ZERO_FIBTIMES:
1802+ cmn_err( CE_DEBUG, "FSACTL_ZERO_FIBTIMES");
1803+ break;
1804+
1805+ case FSACTL_GET_VAR:
1806+ cmn_err( CE_DEBUG, "FSACTL_GET_VAR" );
1807+ break;
1808+
1809+ case FSACTL_SET_VAR:
1810+ cmn_err( CE_DEBUG, "FSACTL_SET_VAR" );
1811+ break;
1812+
1813+ case FSACTL_OPEN_ADAPTER_CONFIG:
1814+ cmn_err( CE_DEBUG, "FSACTL_OPEN_ADAPTER_CONFIG" );
1815+ break;
1816+
1817+ case FSACTL_CLOSE_ADAPTER_CONFIG:
1818+ cmn_err( CE_DEBUG, "FSACTL_CLOSE_ADAPTER_CONFIG" );
1819+ break;
1820+
1821+ case FSACTL_QUERY_ADAPTER_CONFIG:
1822+ cmn_err( CE_DEBUG, "FSACTL_QUERY_ADAPTER_CONFIG" );
1823+ break;
1824+
1825+ case FSACTL_OPEN_GET_ADAPTER_FIB:
1826+ cmn_err( CE_DEBUG, "FSACTL_OPEN_GET_ADAPTER_FIB" );
1827+ break;
1828+
1829+ case FSACTL_GET_NEXT_ADAPTER_FIB:
1830+ cmn_err( CE_DEBUG, "FSACTL_GET_NEXT_ADAPTER_FIB" );
1831+ break;
1832+
1833+ case FSACTL_CLOSE_GET_ADAPTER_FIB:
1834+ cmn_err( CE_DEBUG, "FSACTL_CLOSE_GET_ADAPTER_FIB" );
1835+ break;
1836+
1837+ case FSACTL_MINIPORT_REV_CHECK:
1838+ cmn_err( CE_DEBUG, "FSACTL_MINIPORT_REV_CHECK" );
1839+ break;
1840+
1841+ case FSACTL_OPENCLS_COMM_PERF_DATA:
1842+ cmn_err( CE_DEBUG, "FSACTL_OPENCLS_COMM_PERF_DATA" );
1843+ break;
1844+
1845+ case FSACTL_GET_COMM_PERF_DATA:
1846+ cmn_err( CE_DEBUG, "FSACTL_GET_COMM_PERF_DATA" );
1847+ break;
1848+
1849+ case FSACTL_QUERY_DISK:
1850+ cmn_err( CE_DEBUG, "FSACTL_QUERY_DISK" );
1851+ break;
1852+
1853+ case FSACTL_DELETE_DISK:
1854+ cmn_err( CE_DEBUG, "FSACTL_DELETE_DISK" );
1855+ break;
1856+
1857+ default:
1858+ cmn_err( CE_DEBUG, "Unknown ioctl: 0x%x", cmd );
1859+ }
1860+
1861+ IoctlCmd.cmd = cmd;
1862+ IoctlCmd.arg = ( intptr_t )arg;
1863+ IoctlCmd.flag = 0;
1864+ IoctlCmd.cred_p = 0;
1865+ IoctlCmd.rval_p = 0;
1866+
1867+ status = AfaCommAdapterDeviceControl( CommonExtension->Adapter, &IoctlCmd );
1868+ cmn_err( CE_DEBUG, "AAC_Ioctl, completion status = %d", status );
1869+ return( status );
1870+}
1871+
1872+
1873+/*------------------------------------------------------------------------------
1874+ AacHba_AdapterDeviceControl()
1875+
1876+ Preconditions:
1877+ Postconditions:
1878+ Returns TRUE if ioctl handled, FALSE otherwise
1879+ *ReturnStatus set to completion status
1880+ *----------------------------------------------------------------------------*/
1881+BOOLEAN AacHba_AdapterDeviceControl (
1882+ PVOID AdapterArg, // CommonExtensionPtr
1883+ IN PAFA_IOCTL_CMD IoctlCmdPtr,
1884+ OUT int * ReturnStatus )
1885+/*----------------------------------------------------------------------------*/
1886+{
1887+ BOOLEAN Handled = TRUE; // start out handling it.
1888+ int Status = EFAULT;
1889+
1890+ switch( IoctlCmdPtr->cmd )
1891+ {
1892+ case FSACTL_QUERY_DISK:
1893+ Status = AacHba_QueryDisk( AdapterArg, IoctlCmdPtr );
1894+ break;
1895+
1896+ case FSACTL_DELETE_DISK:
1897+ Status = AacHba_DeleteDisk( AdapterArg, IoctlCmdPtr );
1898+ break;
1899+
1900+ case FSACTL_FORCE_DELETE_DISK:
1901+ Status = AacHba_ForceDeleteDisk( AdapterArg, IoctlCmdPtr );
1902+ break;
1903+
1904+ case 2131:
1905+ if( AacHba_ProbeContainers( ( PCI_MINIPORT_COMMON_EXTENSION * )AdapterArg ) )
1906+ Status = -EFAULT;
1907+ break;
1908+
1909+ default:
1910+ Handled = FALSE;
1911+ break;
1912+ }
1913+
1914+ *ReturnStatus = Status;
1915+
1916+ return( Handled );
1917+}
1918+
1919+
1920+/*------------------------------------------------------------------------------
1921+ AacHba_QueryDisk()
1922+
1923+ Postconditions:
1924+ Return values
1925+ 0 = OK
1926+ -EFAULT = Bad address
1927+ -EINVAL = Bad container number
1928+ *----------------------------------------------------------------------------*/
1929+int AacHba_QueryDisk(
1930+ PVOID AdapterArg, // CommonExtensionPtr
1931+ IN PAFA_IOCTL_CMD IoctlCmdPtr )
1932+/*----------------------------------------------------------------------------*/
1933+{
1934+ UNIX_QUERY_DISK QueryDisk;
1935+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
1936+ fsadev_t *fsa_dev_ptr;
1937+
1938+ CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )AdapterArg;
1939+ fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
1940+
1941+ if( copyin( IoctlCmdPtr->arg, &QueryDisk, sizeof( UNIX_QUERY_DISK ) ) )
1942+ return( -EFAULT );
1943+
1944+ if (QueryDisk.ContainerNumber == -1)
1945+ QueryDisk.ContainerNumber = TARGET_LUN_TO_CONTAINER( QueryDisk.Target, QueryDisk.Lun );
1946+ else
1947+ if( ( QueryDisk.Bus == -1 ) && ( QueryDisk.Target == -1 ) && ( QueryDisk.Lun == -1 ) )
1948+ {
1949+ if( QueryDisk.ContainerNumber > MAXIMUM_NUM_CONTAINERS )
1950+ return( -EINVAL );
1951+
1952+ QueryDisk.Instance = CommonExtensionPtr->OsDep.scsi_host_ptr->host_no;
1953+ QueryDisk.Bus = 0;
1954+ QueryDisk.Target = CONTAINER_TO_TARGET( QueryDisk.ContainerNumber );
1955+ QueryDisk.Lun = CONTAINER_TO_LUN( QueryDisk.ContainerNumber );
1956+ }
1957+ else
1958+ return( -EINVAL );
1959+
1960+ QueryDisk.Valid = fsa_dev_ptr->ContainerValid[QueryDisk.ContainerNumber];
1961+ QueryDisk.Locked = fsa_dev_ptr->ContainerLocked[QueryDisk.ContainerNumber];
1962+ QueryDisk.Deleted = fsa_dev_ptr->ContainerDeleted[QueryDisk.ContainerNumber];
1963+
1964+ if( fsa_dev_ptr->ContainerDevNo[QueryDisk.ContainerNumber] == -1 )
1965+ QueryDisk.UnMapped = TRUE;
1966+ else
1967+ QueryDisk.UnMapped = FALSE;
1968+
1969+ get_sd_devname( fsa_dev_ptr->ContainerDevNo[QueryDisk.ContainerNumber],
1970+ QueryDisk.diskDeviceName );
1971+
1972+ if( copyout( &QueryDisk, IoctlCmdPtr->arg, sizeof( UNIX_QUERY_DISK ) ) )
1973+ return( -EFAULT );
1974+
1975+ return( 0 );
1976+}
1977+
1978+
1979+/*------------------------------------------------------------------------------
1980+ get_sd_devname()
1981+ *----------------------------------------------------------------------------*/
1982+static void get_sd_devname(
1983+ long disknum,
1984+ char * buffer)
1985+/*----------------------------------------------------------------------------*/
1986+{
1987+ if( disknum < 0 )
1988+ {
1989+ sprintf(buffer, "%s", "");
1990+ return;
1991+ }
1992+
1993+ if( disknum < 26 )
1994+ sprintf(buffer, "sd%c", 'a' + disknum);
1995+ else {
1996+ unsigned int min1;
1997+ unsigned int min2;
1998+ /*
1999+ * For larger numbers of disks, we need to go to a new
2000+ * naming scheme.
2001+ */
2002+ min1 = disknum / 26;
2003+ min2 = disknum % 26;
2004+ sprintf(buffer, "sd%c%c", 'a' + min1 - 1, 'a' + min2);
2005+ }
2006+}
2007+
2008+
2009+/*------------------------------------------------------------------------------
2010+ AacHba_ForceDeleteDisk()
2011+
2012+ Postconditions:
2013+ Return values
2014+ 0 = OK
2015+ -EFAULT = Bad address
2016+ -EINVAL = Bad container number
2017+ *----------------------------------------------------------------------------*/
2018+int AacHba_ForceDeleteDisk(
2019+ PVOID AdapterArg, // CommonExtensionPtr
2020+ IN PAFA_IOCTL_CMD IoctlCmdPtr )
2021+/*----------------------------------------------------------------------------*/
2022+{
2023+ DELETE_DISK DeleteDisk;
2024+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
2025+ fsadev_t *fsa_dev_ptr;
2026+
2027+ CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )AdapterArg;
2028+ fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
2029+
2030+ if ( copyin( IoctlCmdPtr->arg, &DeleteDisk, sizeof( DELETE_DISK ) ) )
2031+ return( -EFAULT );
2032+
2033+ if ( DeleteDisk.ContainerNumber > MAXIMUM_NUM_CONTAINERS )
2034+ return( -EINVAL );
2035+
2036+ // Mark this container as being deleted.
2037+ fsa_dev_ptr->ContainerDeleted[DeleteDisk.ContainerNumber] = TRUE;
2038+
2039+ // Mark the container as no longer valid
2040+ fsa_dev_ptr->ContainerValid[DeleteDisk.ContainerNumber] = 0;
2041+
2042+ return( 0 );
2043+}
2044+
2045+
2046+/*------------------------------------------------------------------------------
2047+ AacHba_DeleteDisk()
2048+
2049+ Postconditions:
2050+ Return values
2051+ 0 = OK
2052+ -EFAULT = Bad address
2053+ -EINVAL = Bad container number
2054+ -EBUSY = Device locked
2055+ *----------------------------------------------------------------------------*/
2056+int AacHba_DeleteDisk(
2057+ PVOID AdapterArg,
2058+ IN PAFA_IOCTL_CMD IoctlCmdPtr )
2059+/*----------------------------------------------------------------------------*/
2060+{
2061+ DELETE_DISK DeleteDisk;
2062+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
2063+ fsadev_t *fsa_dev_ptr;
2064+
2065+ CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )AdapterArg;
2066+ fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
2067+
2068+ if( copyin( IoctlCmdPtr->arg, &DeleteDisk, sizeof( DELETE_DISK ) ) )
2069+ return( -EFAULT );
2070+
2071+ if( DeleteDisk.ContainerNumber > MAXIMUM_NUM_CONTAINERS )
2072+ return( -EINVAL );
2073+
2074+ // If the container is locked, it can not be deleted by the API.
2075+ if( fsa_dev_ptr->ContainerLocked[DeleteDisk.ContainerNumber] )
2076+ return( -EBUSY );
2077+ else
2078+ {
2079+ // Mark the container as no longer being valid.
2080+ fsa_dev_ptr->ContainerValid[DeleteDisk.ContainerNumber] = 0;
2081+ fsa_dev_ptr->ContainerDevNo[DeleteDisk.ContainerNumber] = -1;
2082+ return(0);
2083+ }
2084+}
2085+
2086+
2087+/*------------------------------------------------------------------------------
2088+ AacHba_OpenAdapter()
2089+ *----------------------------------------------------------------------------*/
2090+AAC_STATUS AacHba_OpenAdapter(
2091+ IN PVOID AdapterArg )
2092+/*----------------------------------------------------------------------------*/
2093+{
2094+ return( STATUS_SUCCESS );
2095+}
2096+
2097+
2098+/*------------------------------------------------------------------------------
2099+ AacHba_CloseAdapter()
2100+ *----------------------------------------------------------------------------*/
2101+AAC_STATUS AacHba_CloseAdapter(
2102+ IN PVOID AdapterArg )
2103+/*----------------------------------------------------------------------------*/
2104+{
2105+ return( STATUS_SUCCESS );
2106+}
2107+
2108+
2109+/*------------------------------------------------------------------------------
2110+ AacHba_DetachAdapter()
2111+ *----------------------------------------------------------------------------*/
2112+void AacHba_DetachAdapter(
2113+ IN PVOID AdapterArg )
2114+/*----------------------------------------------------------------------------*/
2115+{
2116+ AacCommDetachAdapter( AdapterArg );
2117+}
2118+
2119+
2120+/*------------------------------------------------------------------------------
2121+ AacHba_AbortScsiCommand()
2122+ *----------------------------------------------------------------------------*/
2123+void AacHba_AbortScsiCommand(
2124+ Scsi_Cmnd *scsi_cmnd_ptr )
2125+/*----------------------------------------------------------------------------*/
2126+{
2127+ u_short interrupt_status;
2128+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
2129+
2130+ CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
2131+ interrupt_status = Sa_READ_USHORT( ( PSa_ADAPTER_EXTENSION )( CommonExtensionPtr->MiniPort ),
2132+ DoorbellReg_p );
2133+ cmn_err( CE_WARN, "interrupt_status = %d", interrupt_status );
2134+
2135+ if( interrupt_status & DOORBELL_1) { // Adapter -> Host Normal Command Ready
2136+ cmn_err( CE_WARN, "DOORBELL_1: Adapter -> Host Normal Command Ready" );
2137+ }
2138+
2139+ if( interrupt_status & DOORBELL_2) { // Adapter -> Host Normal Response Ready
2140+ cmn_err( CE_WARN, "DOORBELL_2: Adapter -> Host Normal Response Ready" );
2141+ }
2142+
2143+ if ( interrupt_status & DOORBELL_3) { // Adapter -> Host Normal Command Not Full
2144+ cmn_err( CE_WARN, "DOORBELL_3: Adapter -> Host Normal Command Not Full" );
2145+ }
2146+
2147+ if ( interrupt_status & DOORBELL_4) { // Adapter -> Host Normal Response Not Full
2148+ cmn_err( CE_WARN, "DOORBELL_4: Adapter -> Host Normal Response Not Full" );
2149+ }
2150+
2151+}
2152+
2153+
2154+/*------------------------------------------------------------------------------
2155+ AacHba_HandleAif()
2156+ *----------------------------------------------------------------------------*/
2157+BOOLEAN AacHba_HandleAif(
2158+ IN PVOID AdapterArg,
2159+ IN PFIB_CONTEXT FibContext )
2160+/*----------------------------------------------------------------------------*/
2161+{
2162+ return( FALSE );
2163+}
2164+
2165+
2166+/*------------------------------------------------------------------------------
2167+ AacHba_SetSenseData()
2168+ Fill in the sense data.
2169+ Preconditions:
2170+ Postconditions:
2171+ *----------------------------------------------------------------------------*/
2172+void AacHba_SetSenseData(
2173+ char * sense_buf,
2174+ unchar sense_key,
2175+ unchar sense_code,
2176+ unchar a_sense_code,
2177+ unchar incorrect_length,
2178+ unchar bit_pointer,
2179+ unsigned field_pointer,
2180+ unsigned long residue )
2181+/*----------------------------------------------------------------------------*/
2182+{
2183+ sense_buf[0] = 0xF0; // Sense data valid, err code 70h (current error)
2184+ sense_buf[1] = 0; // Segment number, always zero
2185+
2186+ if( incorrect_length )
2187+ {
2188+ sense_buf[2] = sense_key | 0x20; // Set the ILI bit | sense key
2189+ sense_buf[3] = BYTE3(residue);
2190+ sense_buf[4] = BYTE2(residue);
2191+ sense_buf[5] = BYTE1(residue);
2192+ sense_buf[6] = BYTE0(residue);
2193+ }
2194+ else
2195+ sense_buf[2] = sense_key; // Sense key
2196+
2197+ if( sense_key == SENKEY_ILLEGAL )
2198+ sense_buf[7] = 10; // Additional sense length
2199+ else
2200+ sense_buf[7] = 6; // Additional sense length
2201+
2202+ sense_buf[12] = sense_code; // Additional sense code
2203+ sense_buf[13] = a_sense_code; // Additional sense code qualifier
2204+ if( sense_key == SENKEY_ILLEGAL )
2205+ {
2206+ sense_buf[15] = 0;
2207+
2208+ if( sense_code == SENCODE_INVALID_PARAM_FIELD )
2209+ sense_buf[15] = 0x80; // Std sense key specific field
2210+ // Illegal parameter is in the parameter block
2211+
2212+ if( sense_code == SENCODE_INVALID_CDB_FIELD )
2213+ sense_buf[15] = 0xc0; // Std sense key specific field
2214+ // Illegal parameter is in the CDB block
2215+ sense_buf[15] |= bit_pointer;
2216+ sense_buf[16] = field_pointer >> 8; // MSB
2217+ sense_buf[17] = field_pointer; // LSB
2218+ }
2219+}
2220+
2221diff -burN linux-2.4.9/drivers/scsi/aacraid/aacid.c linux/drivers/scsi/aacraid/aacid.c
2222--- linux-2.4.9/drivers/scsi/aacraid/aacid.c Wed Dec 31 18:00:00 1969
2223+++ linux/drivers/scsi/aacraid/aacid.c Thu Aug 16 18:10:23 2001
2224@@ -0,0 +1,157 @@
2225+/*++
2226+ * Adaptec aacraid device driver for Linux.
2227+ *
2228+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
2229+ *
2230+ * This program is free software; you can redistribute it and/or modify
2231+ * it under the terms of the GNU General Public License as published by
2232+ * the Free Software Foundation; either version 2, or (at your option)
2233+ * any later version.
2234+ *
2235+ * This program is distributed in the hope that it will be useful,
2236+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2237+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2238+ * GNU General Public License for more details.
2239+ *
2240+ * You should have received a copy of the GNU General Public License
2241+ * along with this program; see the file COPYING. If not, write to
2242+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
2243+ *
2244+ * Module Name:
2245+ * aac.c
2246+ *
2247+ * Abstract: Data structures for controller specific info.
2248+ *
2249+--*/
2250+
2251+static char *ident_aacid = "aacraid_ident aacid.c 1.0.6 2000/10/09 Adaptec, Inc.";
2252+
2253+#include "osheaders.h"
2254+
2255+#include "AacGenericTypes.h"
2256+
2257+#include "aac_unix_defs.h"
2258+
2259+#include "fsatypes.h"
2260+#include "comstruc.h"
2261+#include "fsaport.h"
2262+#include "pcisup.h"
2263+
2264+#include "version.h"
2265+
2266+
2267+/* Function Prototypes */
2268+void InqStrCopy(char *a, char *b); /* ossup.c */
2269+
2270+/* Device name used to register and unregister
2271+ the device in linit.c */
2272+char devicestr[]="aac";
2273+
2274+char *container_types[] = {
2275+ "None",
2276+ "Volume",
2277+ "Mirror",
2278+ "Stripe",
2279+ "RAID5",
2280+ "SSRW",
2281+ "SSRO",
2282+ "Morph",
2283+ "Legacy",
2284+ "RAID4",
2285+ "RAID10",
2286+ "RAID00",
2287+ "V-MIRRORS",
2288+ "PSEUDO R4",
2289+ "RAID50",
2290+ "Unknown"
2291+};
2292+
2293+/* Local Structure to set SCSI inquiry data strings */
2294+typedef struct _INQSTR {
2295+ char vid[8]; /* Vendor ID */
2296+ char pid[16]; /* Product ID */
2297+ char prl[4]; /* Product Revision Level */
2298+} INQSTR, *INQSTRP;
2299+
2300+FSA_MINIPORT MiniPorts[];
2301+
2302+/* Function: SetInqDataStr
2303+ *
2304+ * Arguments: [1] pointer to void [1] int
2305+ *
2306+ * Purpose: Sets SCSI inquiry data strings for vendor, product
2307+ * and revision level. Allows strings to be set in platform dependant
2308+ * files instead of in OS dependant driver source.
2309+ */
2310+void
2311+SetInqDataStr (
2312+ int MiniPortIndex,
2313+ void *dataPtr,
2314+ int tindex)
2315+{
2316+ INQSTRP InqStrPtr;
2317+ char *findit;
2318+ FSA_MINIPORT *mp;
2319+
2320+ mp = &MiniPorts[MiniPortIndex];
2321+
2322+ InqStrPtr = (INQSTRP)(dataPtr); /* cast dataPtr to type INQSTRP */
2323+
2324+ InqStrCopy (mp->Vendor, InqStrPtr->vid);
2325+ InqStrCopy (mp->Model, InqStrPtr->pid); /* last six chars reserved for vol type */
2326+
2327+ findit = InqStrPtr->pid;
2328+
2329+ for ( ; *findit != ' '; findit++); /* walk till we find a space then incr by 1 */
2330+ findit++;
2331+
2332+ if (tindex < (sizeof(container_types)/sizeof(char *))){
2333+ InqStrCopy (container_types[tindex], findit);
2334+ }
2335+ InqStrCopy ("0001", InqStrPtr->prl);
2336+}
2337+
2338+int
2339+SaInitDevice(
2340+ IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
2341+ IN ULONG AdapterNumber,
2342+ IN ULONG PciBus,
2343+ IN ULONG PciSlot
2344+);
2345+
2346+int
2347+RxInitDevice(
2348+ IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
2349+ IN ULONG AdapterNumber,
2350+ IN ULONG PciBus,
2351+ IN ULONG PciSlot
2352+);
2353+
2354+
2355+/*
2356+ * Because of the way Linux names scsi devices, the order in this table has
2357+ * become important. Check for on-board Raid first, add-in cards second.
2358+ */
2359+
2360+FSA_MINIPORT MiniPorts[] = {
2361+ { 0x0000, 0x0000, 0x0000, 0x0000, "afa", RxInitDevice, "percraid", "DELL ", "PERCRAID " }, /* Dell unknown - uses perc_pciid */
2362+ { 0x0000, 0x0000, 0x0000, 0x0000, "aac", RxInitDevice, "aacraid", "ADAPTEC ", "AACRAID " }, /* unknown - uses rx_pciid */
2363+ { 0x0000, 0x0000, 0x0000, 0x0000, "aac", SaInitDevice, "aacraid", "ADAPTEC ", "AACRAID " }, /* unknown - uses sa_pciid */
2364+ { 0x1028, 0x0001, 0x1028, 0x0001, "afa", RxInitDevice, "percraid", "DELL ", "PERCRAID " }, /* PERC 2/Si */
2365+ { 0x1028, 0x0002, 0x1028, 0x0002, "afa", RxInitDevice, "percraid", "DELL ", "PERCRAID " }, /* PERC 3/Di */
2366+ { 0x1028, 0x0003, 0x1028, 0x0003, "afa", RxInitDevice, "percraid", "DELL ", "PERCRAID " }, /* PERC 3/Si */
2367+ { 0x1028, 0x0004, 0x1028, 0x00d0, "afa", RxInitDevice, "percraid", "DELL ", "PERCRAID " }, /* PERC 3/Si */
2368+ { 0x1028, 0x0002, 0x1028, 0x00d1, "afa", RxInitDevice, "percraid", "DELL ", "PERCRAID " }, /* PERC 3/Di */
2369+ { 0x1028, 0x0002, 0x1028, 0x00d9, "afa", RxInitDevice, "percraid", "DELL ", "PERCRAID " }, /* PERC 3/Di */
2370+ { 0x1028, 0x000a, 0x1028, 0x0106, "afa", RxInitDevice, "percraid", "DELL ", "PERCRAID " }, /* PERC 3/Di */
2371+ { 0x1011, 0x0046, 0x9005, 0x1364, "afa", SaInitDevice, "percraid", "DELL ", "PERCRAID " }, /* Dell PERC2 "Quad Channel" */
2372+ { 0x1011, 0x0046, 0x9005, 0x0365, "aac", SaInitDevice, "aacraid", "ADAPTEC ", "Adaptec 5400S " }, /* Adaptec 5400S */
2373+ { 0x1011, 0x0046, 0x103c, 0x10c2, "hpn", SaInitDevice, "hpnraid", "HP ", "NetRAID-4M " } /* HP NetRAID-4M */
2374+};
2375+
2376+
2377+#define NUM_MINIPORTS (sizeof(MiniPorts) / sizeof(FSA_MINIPORT))
2378+
2379+int NumMiniPorts = NUM_MINIPORTS;
2380+
2381+char DescriptionString[] = "AACxxx Raid Controller" FSA_VERSION_STRING ;
2382diff -burN linux-2.4.9/drivers/scsi/aacraid/commctrl.c linux/drivers/scsi/aacraid/commctrl.c
2383--- linux-2.4.9/drivers/scsi/aacraid/commctrl.c Wed Dec 31 18:00:00 1969
2384+++ linux/drivers/scsi/aacraid/commctrl.c Thu Aug 16 13:41:30 2001
2385@@ -0,0 +1,1098 @@
2386+/*++
2387+ * Adaptec aacraid device driver for Linux.
2388+ *
2389+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
2390+ *
2391+ * This program is free software; you can redistribute it and/or modify
2392+ * it under the terms of the GNU General Public License as published by
2393+ * the Free Software Foundation; either version 2, or (at your option)
2394+ * any later version.
2395+ *
2396+ * This program is distributed in the hope that it will be useful,
2397+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2398+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2399+ * GNU General Public License for more details.
2400+ *
2401+ * You should have received a copy of the GNU General Public License
2402+ * along with this program; see the file COPYING. If not, write to
2403+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
2404+ *
2405+ * Module Name:
2406+ * commctrl.c
2407+ *
2408+ * Abstract: Contains all routines for control of the AFA comm layer
2409+ *
2410+--*/
2411+
2412+static char *ident_commctrl = "aacraid_ident commctrl.c 1.0.7 2000/10/11 Adaptec, Inc.";
2413+
2414+#include "comprocs.h"
2415+#include "osheaders.h"
2416+#include "ostypes.h"
2417+
2418+
2419+
2420+
2421+
2422+typedef BOOLEAN BOOL;
2423+#define inline /* _inline */
2424+
2425+#include <revision.h>
2426+AAC_STATUS
2427+FsaCtlCheckRevision(
2428+ IN PAFA_COMM_ADAPTER Adapter,
2429+ IN PAFA_IOCTL_CMD IoctlCmdPtr
2430+ )
2431+/*++
2432+
2433+Routine Description:
2434+
2435+ This routine validates the revision of the caller with the current revision
2436+ of the filesystem.
2437+
2438+Arguments:
2439+
2440+ Adapter - Supplies which adapter is being processed.
2441+
2442+ Irp - Supplies the Irp being processed.
2443+
2444+ IrpContext - Supplies the IrpContext.
2445+
2446+Return Value:
2447+
2448+ AAC_STATUS
2449+
2450+--*/
2451+
2452+{
2453+ RevCheck APIRevCheck;
2454+ RevCheckResp APIRevCheckResp;
2455+ RevComponent APICallingComponent;
2456+ ULONG APIBuildNumber;
2457+
2458+ if (COPYIN( (caddr_t) IoctlCmdPtr->arg, (caddr_t) &APIRevCheck, sizeof(RevCheck), IoctlCmdPtr->flag )) {
2459+ return (EFAULT);
2460+ }
2461+
2462+ APICallingComponent = APIRevCheck.callingComponent;
2463+ APIBuildNumber = APIRevCheck.callingRevision.buildNumber;
2464+
2465+ APIRevCheckResp.possiblyCompatible = RevCheckCompatibility( RevMiniportDriver , APICallingComponent, APIBuildNumber );
2466+
2467+ APIRevCheckResp.adapterSWRevision.external.ul = RevGetExternalRev();
2468+ APIRevCheckResp.adapterSWRevision.buildNumber = RevGetBuildNumber();
2469+
2470+ if (COPYOUT( (caddr_t) &APIRevCheckResp, (caddr_t) IoctlCmdPtr->arg, sizeof(RevCheckResp), IoctlCmdPtr->flag )) {
2471+ return (EFAULT);
2472+ }
2473+
2474+ return (0);
2475+}
2476+
2477+
2478+int
2479+AfaCommAdapterDeviceControl(
2480+ IN PVOID AdapterArg,
2481+ IN PAFA_IOCTL_CMD IoctlCmdPtr
2482+ )
2483+{
2484+ PAFA_COMM_ADAPTER Adapter = (PAFA_COMM_ADAPTER) AdapterArg;
2485+ int Status = ENOTTY;
2486+// PIO_STACK_LOCATION IrpSp;
2487+ PAFA_CLASS_DRIVER ClassDriver;
2488+
2489+ //
2490+ // First loop through all of the class drivers to give them a chance to handle
2491+ // the Device control first.
2492+ //
2493+
2494+ ClassDriver = Adapter->ClassDriverList;
2495+
2496+ while (ClassDriver) {
2497+
2498+ if (ClassDriver->DeviceControl) {
2499+
2500+ if (ClassDriver->DeviceControl( ClassDriver->ClassDriverExtension, IoctlCmdPtr, &Status ) ) {
2501+
2502+ return (Status);
2503+
2504+ }
2505+ }
2506+
2507+ ClassDriver = ClassDriver->Next;
2508+ }
2509+
2510+ switch (IoctlCmdPtr->cmd) {
2511+
2512+
2513+ case FSACTL_SENDFIB:
2514+
2515+ Status = AfaCommCtlSendFib( Adapter, IoctlCmdPtr );
2516+ break;
2517+
2518+ case FSACTL_AIF_THREAD:
2519+
2520+ Status = AfaCommCtlAifThread( Adapter, IoctlCmdPtr );
2521+ break;
2522+
2523+
2524+ case FSACTL_OPEN_GET_ADAPTER_FIB:
2525+
2526+ Status = FsaCtlOpenGetAdapterFib( Adapter, IoctlCmdPtr );
2527+ break;
2528+
2529+ case FSACTL_GET_NEXT_ADAPTER_FIB:
2530+
2531+ Status = FsaCtlGetNextAdapterFib( Adapter, IoctlCmdPtr );
2532+ break;
2533+
2534+ case FSACTL_CLOSE_GET_ADAPTER_FIB:
2535+
2536+ Status = FsaCtlCloseGetAdapterFib( Adapter, IoctlCmdPtr );
2537+ break;
2538+
2539+ case FSACTL_MINIPORT_REV_CHECK:
2540+
2541+ Status = FsaCtlCheckRevision( Adapter , IoctlCmdPtr );
2542+ break;
2543+
2544+
2545+ default:
2546+
2547+ Status = ENOTTY;
2548+ break;
2549+
2550+ }
2551+
2552+
2553+ return (Status);
2554+}
2555+
2556+AAC_STATUS
2557+AfaCommRegisterNewClassDriver(
2558+ IN PAFA_COMM_ADAPTER Adapter,
2559+ IN PAFA_NEW_CLASS_DRIVER NewClassDriver,
2560+ OUT PAFA_NEW_CLASS_DRIVER_RESPONSE NewClassDriverResponse
2561+ )
2562+/*++
2563+
2564+Routine Description:
2565+
2566+ This routine registers a new class driver for the comm layer.
2567+
2568+ It will return a pointer to the communication functions for the class driver
2569+ to use.
2570+
2571+Arguments:
2572+
2573+ Adapter - Supplies which adapter is being processed.
2574+
2575+ Irp - Supplies the Irp being processed.
2576+
2577+Return Value:
2578+
2579+ STATUS_SUCCESS - Everything OK.
2580+
2581+--*/
2582+{
2583+ AAC_STATUS Status;
2584+ PAFA_CLASS_DRIVER ClassDriver;
2585+
2586+
2587+ ClassDriver = (PAFA_CLASS_DRIVER) OsAllocMemory( sizeof(AFA_CLASS_DRIVER), OS_ALLOC_MEM_SLEEP );
2588+
2589+ if (ClassDriver == NULL) {
2590+
2591+ Status = STATUS_INSUFFICIENT_RESOURCES;
2592+
2593+ return Status;
2594+ }
2595+
2596+ //
2597+ // If the class driver has sent in user Vars, then copy them into the global
2598+ // area.
2599+ //
2600+
2601+ if (NewClassDriver->NumUserVars) {
2602+
2603+ PFSA_USER_VAR NewUserVars;
2604+
2605+ NewUserVars = OsAllocMemory( (FsaCommData.NumUserVars +
2606+ NewClassDriver->NumUserVars) * sizeof(FSA_USER_VAR), OS_ALLOC_MEM_SLEEP );
2607+
2608+ //
2609+ // First copy the existing into the new area.
2610+ //
2611+
2612+ RtlCopyMemory( NewUserVars, FsaCommData.UserVars, FsaCommData.NumUserVars * sizeof(FSA_USER_VAR) );
2613+
2614+ //
2615+ // Next copy the new vars passed in from class driver.
2616+ //
2617+
2618+ RtlCopyMemory( (NewUserVars + FsaCommData.NumUserVars),
2619+ NewClassDriver->UserVars,
2620+ NewClassDriver->NumUserVars * sizeof(FSA_USER_VAR) );
2621+
2622+ //
2623+ // Free up the old user vars.
2624+ //
2625+
2626+ OsFreeMemory( FsaCommData.UserVars, FsaCommData.NumUserVars * sizeof(FSA_USER_VAR) );
2627+
2628+ //
2629+ // Point the global to the new area.
2630+ //
2631+
2632+ FsaCommData.UserVars = NewUserVars;
2633+
2634+ //
2635+ // Update the total count.
2636+ //
2637+
2638+ FsaCommData.NumUserVars += NewClassDriver->NumUserVars;
2639+
2640+ }
2641+
2642+ ClassDriver->OpenAdapter = NewClassDriver->OpenAdapter;
2643+ ClassDriver->CloseAdapter = NewClassDriver->CloseAdapter;
2644+ ClassDriver->DeviceControl = NewClassDriver->DeviceControl;
2645+ ClassDriver->HandleAif = NewClassDriver->HandleAif;
2646+ ClassDriver->ClassDriverExtension = NewClassDriver->ClassDriverExtension;
2647+
2648+ ClassDriver->Next = Adapter->ClassDriverList;
2649+ Adapter->ClassDriverList = ClassDriver;
2650+
2651+ //
2652+ // Now return the information needed by the class driver to communicate to us.
2653+ //
2654+
2655+ NewClassDriverResponse->CommFuncs = &Adapter->CommFuncs;
2656+ NewClassDriverResponse->CommPortExtension = Adapter;
2657+ NewClassDriverResponse->MiniPortExtension = Adapter->AdapterExtension;
2658+ NewClassDriverResponse->SpinLockCookie = Adapter->SpinLockCookie;
2659+ NewClassDriverResponse->Dip = Adapter->Dip;
2660+
2661+ return (STATUS_SUCCESS);
2662+
2663+
2664+}
2665+
2666+int
2667+AfaCommCtlSendFib(
2668+ IN PAFA_COMM_ADAPTER Adapter,
2669+ IN PAFA_IOCTL_CMD IoctlCmdPtr
2670+)
2671+/*++
2672+
2673+Routine Description:
2674+
2675+ This routine sends a fib to the adapter on behalf of a user level
2676+ program.
2677+
2678+Arguments:
2679+
2680+ Adapter - Supplies which adapter is being processed.
2681+
2682+ IoctlCmdPtr - Pointer to the arguments to the IOCTL call
2683+
2684+Return Value:
2685+
2686+ STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2687+
2688+ STATUS_INSUFFICIENT_RESOURCES - If a memory allocation failed.
2689+
2690+ STATUS_SUCCESS - Everything OK.
2691+
2692+--*/
2693+{
2694+ PFIB KFib;
2695+// PMDL DmaMdl = NULL;
2696+ PCOMM_FIB_CONTEXT FibContext;
2697+ PSGMAP_CONTEXT SgMapContext;
2698+ SGMAP_CONTEXT _SgMapContext;
2699+ QUEUE_TYPES WhichQueue;
2700+ PVOID UsersAddress;
2701+ AAC_STATUS Status;
2702+
2703+ FibContext = AllocateFib( Adapter );
2704+
2705+ KFib = FibContext->Fib;
2706+
2707+ //
2708+ // First copy in the header so that we can check the size field.
2709+ //
2710+
2711+ if (COPYIN( (caddr_t) IoctlCmdPtr->arg, (caddr_t) KFib, sizeof(FIB_HEADER), IoctlCmdPtr->flag )) {
2712+ FreeFib( FibContext );
2713+ Status = EFAULT;
2714+ return (Status);
2715+ }
2716+
2717+ //
2718+ // Since we copy based on the fib header size, make sure that we
2719+ // will not overrun the buffer when we copy the memory. Return
2720+ // an error if we would.
2721+ //
2722+
2723+ if (KFib->Header.Size > sizeof(FIB) - sizeof(FIB_HEADER)) {
2724+ FreeFib( FibContext );
2725+ Status = EINVAL;
2726+ return Status;
2727+
2728+ }
2729+
2730+ if (COPYIN( (caddr_t) IoctlCmdPtr->arg, (caddr_t) KFib, KFib->Header.Size + sizeof(FIB_HEADER), IoctlCmdPtr->flag )) {
2731+ FreeFib( FibContext );
2732+ Status = EFAULT;
2733+ return (Status);
2734+ }
2735+
2736+ WhichQueue = AdapNormCmdQueue;
2737+
2738+
2739+ if (KFib->Header.Command == TakeABreakPt) {
2740+
2741+ InterruptAdapter(Adapter);
2742+
2743+ //
2744+ // Since we didn't really send a fib, zero out the state to allow
2745+ // cleanup code not to assert.
2746+ //
2747+
2748+ KFib->Header.XferState = 0;
2749+
2750+
2751+ } else {
2752+
2753+ if (SendFib(KFib->Header.Command, FibContext, KFib->Header.Size , FsaNormal,
2754+ TRUE, NULL, TRUE, NULL, NULL) != FSA_SUCCESS) {
2755+ FsaCommPrint("User SendFib failed!.\n");
2756+
2757+
2758+ FreeFib( FibContext );
2759+ return (ENXIO);
2760+ }
2761+
2762+ if (CompleteFib(FibContext) != FSA_SUCCESS) {
2763+ FsaCommPrint("User Complete FIB failed.\n");
2764+
2765+ FreeFib( FibContext );
2766+ return (ENXIO);
2767+ }
2768+
2769+
2770+ }
2771+
2772+
2773+ //
2774+ // Make sure that the size returned by the adapter (which includes
2775+ // the header) is less than or equal to the size of a fib, so we
2776+ // don't corrupt application data. Then copy that size to the user
2777+ // buffer. (Don't try to add the header information again, since it
2778+ // was already included by the adapter.)
2779+ //
2780+ ASSERT(KFib->Header.Size <= sizeof(FIB));
2781+
2782+ if (COPYOUT( (caddr_t) KFib, (caddr_t) IoctlCmdPtr->arg, KFib->Header.Size, IoctlCmdPtr->flag )) {
2783+ FreeFib( FibContext );
2784+ Status = EFAULT;
2785+ return (Status);
2786+ }
2787+
2788+ FreeFib( FibContext );
2789+
2790+ return (0);
2791+
2792+}
2793+
2794+int
2795+AfaCommCtlAifThread(
2796+ IN PAFA_COMM_ADAPTER Adapter,
2797+ IN PAFA_IOCTL_CMD IoctlCmdPtr
2798+)
2799+/*++
2800+
2801+Routine Description:
2802+
2803+ This routine will act as the AIF thread for this adapter.
2804+
2805+Arguments:
2806+
2807+ Adapter - Supplies which adapter is being processed.
2808+
2809+ IoctlCmdPtr - Pointer to the arguments to the IOCTL call
2810+
2811+Return Value:
2812+
2813+ STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2814+
2815+ STATUS_INSUFFICIENT_RESOURCES - If a memory allocation failed.
2816+
2817+ STATUS_SUCCESS - Everything OK.
2818+
2819+--*/
2820+{
2821+ return (NormCommandThread(Adapter));
2822+}
2823+
2824+
2825+
2826+#ifdef GATHER_FIB_TIMES
2827+AAC_STATUS
2828+AfaCommGetFibTimes(
2829+ IN PAFA_COMM_ADAPTER Adapter,
2830+ IN PIRP Irp
2831+ )
2832+/*++
2833+
2834+Routine Description:
2835+
2836+ This routine returns the gathered fibtimes to the user.
2837+
2838+Arguments:
2839+
2840+ Adapter - Supplies which adapter is being processed.
2841+
2842+ Irp - Supplies the Irp being processed.
2843+
2844+Return Value:
2845+
2846+ STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2847+
2848+ STATUS_INSUFFICIENT_RESOURCES - If a memory allocation failed.
2849+
2850+ STATUS_SUCCESS - Everything OK.
2851+
2852+--*/
2853+{
2854+ PALL_FIB_TIMES AllFibTimes;
2855+ PLARGE_INTEGER FreqPtr;
2856+ PIO_STACK_LOCATION IrpSp;
2857+
2858+ //
2859+ // Get a pointer to the current Irp stack location
2860+ //
2861+
2862+ IrpSp = IoGetCurrentIrpStackLocation( Irp );
2863+
2864+ FreqPtr = (PLARGE_INTEGER)IrpSp->Parameters.FileSystemControl.Type3InputBuffer;
2865+
2866+ *FreqPtr = Adapter->FibTimesFrequency;
2867+
2868+ AllFibTimes = (PALL_FIB_TIMES)((PUCHAR)FreqPtr + sizeof(LARGE_INTEGER));
2869+
2870+ RtlCopyMemory(AllFibTimes, Adapter->FibTimes, sizeof(ALL_FIB_TIMES));
2871+
2872+ Irp->IoStatus.Information = 0;
2873+
2874+ return (STATUS_SUCCESS);
2875+
2876+}
2877+
2878+AAC_STATUS
2879+AfaCommZeroFibTimes(
2880+ IN PAFA_COMM_ADAPTER Adapter,
2881+ IN PIRP Irp
2882+ )
2883+/*++
2884+
2885+Routine Description:
2886+
2887+ This routine zero's the FibTimes structure within the adapter structure.
2888+
2889+Arguments:
2890+
2891+ Adapter - Supplies which adapter is being processed.
2892+
2893+ Irp - Supplies the Irp being processed.
2894+
2895+Return Value:
2896+
2897+ STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2898+
2899+ STATUS_INSUFFICIENT_RESOURCES - If a memory allocation failed.
2900+
2901+ STATUS_SUCCESS - Everything OK.
2902+
2903+--*/
2904+{
2905+ PFIB_TIMES FibTimesPtr;
2906+ int i;
2907+ PIO_STACK_LOCATION IrpSp;
2908+
2909+ //
2910+ // Get a pointer to the current Irp stack location
2911+ //
2912+
2913+ IrpSp = IoGetCurrentIrpStackLocation( Irp );
2914+
2915+ //
2916+ // Initialize the Fib timing data structures
2917+ //
2918+ RtlZeroMemory(Adapter->FibTimes, sizeof(ALL_FIB_TIMES));
2919+
2920+ for (i = 0; i < MAX_FSACOMMAND_NUM; i++) {
2921+
2922+ FibTimesPtr = &Adapter->FibTimes->FileSys[i];
2923+
2924+ FibTimesPtr->Minimum.LowPart = 0xffffffff;
2925+ FibTimesPtr->Minimum.HighPart = 0x7fffffff;
2926+ FibTimesPtr->AdapterMinimum.LowPart = 0xffffffff;
2927+ FibTimesPtr->AdapterMinimum.HighPart = 0x7fffffff;
2928+ }
2929+ for (i = 0; i < MAX_RW_FIB_TIMES; i++) {
2930+
2931+ FibTimesPtr = &Adapter->FibTimes->Read[i];
2932+
2933+ FibTimesPtr->Minimum.LowPart = 0xffffffff;
2934+ FibTimesPtr->Minimum.HighPart = 0x7fffffff;
2935+ FibTimesPtr->AdapterMinimum.LowPart = 0xffffffff;
2936+ FibTimesPtr->AdapterMinimum.HighPart = 0x7fffffff;
2937+ }
2938+ for (i = 0; i < MAX_RW_FIB_TIMES; i++) {
2939+
2940+ FibTimesPtr = &Adapter->FibTimes->Write[i];
2941+
2942+ FibTimesPtr->Minimum.LowPart = 0xffffffff;
2943+ FibTimesPtr->Minimum.HighPart = 0x7fffffff;
2944+ FibTimesPtr->AdapterMinimum.LowPart = 0xffffffff;
2945+ FibTimesPtr->AdapterMinimum.HighPart = 0x7fffffff;
2946+ }
2947+
2948+ FibTimesPtr = &Adapter->FibTimes->Other;
2949+
2950+ FibTimesPtr->Minimum.LowPart = 0xffffffff;
2951+ FibTimesPtr->Minimum.HighPart = 0x7fffffff;
2952+ FibTimesPtr->AdapterMinimum.LowPart = 0xffffffff;
2953+ FibTimesPtr->AdapterMinimum.HighPart = 0x7fffffff;
2954+
2955+ Irp->IoStatus.Information = 0;
2956+
2957+ return (STATUS_SUCCESS);
2958+
2959+}
2960+#endif // GATHER_FIB_TIMES
2961+
2962+#ifndef unix_aif
2963+int
2964+FsaCtlOpenGetAdapterFib(
2965+ IN PAFA_COMM_ADAPTER Adapter,
2966+ IN PAFA_IOCTL_CMD IoctlCmdPtr
2967+ )
2968+/*++
2969+
2970+Routine Description:
2971+
2972+ This routine will get the next Fib, if available, from the AdapterFibContext
2973+ passed in from the user.
2974+
2975+Arguments:
2976+
2977+ Adapter - Supplies which adapter is being processed.
2978+
2979+ Irp - Supplies the Irp being processed.
2980+
2981+Return Value:
2982+
2983+ STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2984+
2985+ STATUS_INSUFFICIENT_RESOURCES - If a memory allocation failed.
2986+
2987+ STATUS_SUCCESS - Everything OK.
2988+
2989+--*/
2990+{
2991+ PGET_ADAPTER_FIB_CONTEXT AdapterFibContext;
2992+// HANDLE Event;
2993+// PKEVENT eventObject = (PKEVENT) NULL;
2994+ int Status;
2995+
2996+ //
2997+ // The context must be allocated from NonPagedPool because we need to use MmIsAddressValid.
2998+ //
2999+
3000+ AdapterFibContext = OsAllocMemory(sizeof(GET_ADAPTER_FIB_CONTEXT), OS_ALLOC_MEM_SLEEP);
3001+
3002+ if (AdapterFibContext == NULL) {
3003+
3004+ Status = ENOMEM;
3005+
3006+ } else {
3007+
3008+ AdapterFibContext->NodeTypeCode = FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT;
3009+ AdapterFibContext->NodeByteSize = sizeof(GET_ADAPTER_FIB_CONTEXT);
3010+
3011+
3012+ //
3013+ // Initialize the conditional variable use to wait for the next AIF.
3014+ //
3015+
3016+ OsCv_init( &AdapterFibContext->UserEvent);
3017+
3018+ //
3019+ // Set WaitingForFib to FALSE to indicate we are not in a WaitForSingleObject
3020+ //
3021+
3022+ AdapterFibContext->WaitingForFib = FALSE;
3023+
3024+ //
3025+ // Initialize the FibList and set the count of fibs on the list to 0.
3026+ //
3027+
3028+ AdapterFibContext->FibCount = 0;
3029+ InitializeListHead(&AdapterFibContext->FibList);
3030+
3031+ //
3032+ // Overload FileObject with a time stamp.
3033+ //
3034+ AdapterFibContext->FileObject = (void *)OsGetSeconds();
3035+
3036+ //
3037+ // Now add this context onto the adapter's AdapterFibContext list.
3038+ //
3039+
3040+ OsCvLockAcquire(Adapter->AdapterFibMutex);
3041+
3042+ InsertTailList(&Adapter->AdapterFibContextList, &AdapterFibContext->NextContext);
3043+
3044+ OsCvLockRelease(Adapter->AdapterFibMutex);
3045+
3046+ if (COPYOUT( &AdapterFibContext, (caddr_t) IoctlCmdPtr->arg, sizeof(PGET_ADAPTER_FIB_CONTEXT),
3047+ IoctlCmdPtr->flag )) {
3048+
3049+ Status = EFAULT;
3050+
3051+ } else {
3052+
3053+ Status = 0;
3054+
3055+ }
3056+
3057+ }
3058+
3059+ return (Status);
3060+}
3061+
3062+int
3063+FsaCtlGetNextAdapterFib(
3064+ IN PAFA_COMM_ADAPTER Adapter,
3065+ IN PAFA_IOCTL_CMD IoctlCmdPtr
3066+ )
3067+/*++
3068+
3069+Routine Description:
3070+
3071+ This routine will get the next Fib, if available, from the AdapterFibContext
3072+ passed in from the user.
3073+
3074+Arguments:
3075+
3076+ Adapter - Supplies which adapter is being processed.
3077+
3078+ Irp - Supplies the Irp being processed.
3079+
3080+Return Value:
3081+
3082+ STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
3083+
3084+ STATUS_NO_MORE_ENTRIES - There are no more Fibs for this AdapterFibContext.
3085+
3086+ STATUS_SUCCESS - Everything OK.
3087+
3088+--*/
3089+{
3090+ GET_ADAPTER_FIB_IOCTL AdapterFibIoctl;
3091+ PGET_ADAPTER_FIB_CONTEXT AdapterFibContext, aifcp;
3092+ PFIB Fib;
3093+ int Status;
3094+ PLIST_ENTRY Entry;
3095+ int found;
3096+
3097+ if (COPYIN( (caddr_t) IoctlCmdPtr->arg, (caddr_t) &AdapterFibIoctl,
3098+ sizeof(GET_ADAPTER_FIB_IOCTL), IoctlCmdPtr->flag )) {
3099+ return (EFAULT);
3100+ }
3101+
3102+ //
3103+ // Extract the AdapterFibContext from the Input parameters.
3104+ //
3105+
3106+ AdapterFibContext = (PGET_ADAPTER_FIB_CONTEXT) AdapterFibIoctl.AdapterFibContext;
3107+
3108+ //
3109+ // Verify that the HANDLE passed in was a valid AdapterFibContext
3110+ //
3111+ // Search the list of AdapterFibContext addresses on the adapter to be sure
3112+ // this is a valid address
3113+
3114+ found = 0;
3115+ Entry = Adapter->AdapterFibContextList.Flink;
3116+
3117+ while ( Entry != &Adapter->AdapterFibContextList ) {
3118+ aifcp = CONTAINING_RECORD ( Entry, GET_ADAPTER_FIB_CONTEXT, NextContext );
3119+ if ( AdapterFibContext == aifcp ) { // We found a winner
3120+ found = 1;
3121+ break;
3122+ }
3123+ Entry = Entry->Flink;
3124+ }
3125+
3126+ if ( found == 0 ) {
3127+ return ( EINVAL );;
3128+ }
3129+
3130+ if ( (AdapterFibContext->NodeTypeCode != FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT) ||
3131+ (AdapterFibContext->NodeByteSize != sizeof(GET_ADAPTER_FIB_CONTEXT)) ) {
3132+
3133+ return ( EINVAL );
3134+
3135+ }
3136+
3137+ Status = STATUS_SUCCESS;
3138+
3139+ OsCvLockAcquire(Adapter->AdapterFibMutex);
3140+
3141+ //
3142+ // If there are no fibs to send back, then either wait or return EAGAIN
3143+ //
3144+return_fib:
3145+
3146+ if (!IsListEmpty(&AdapterFibContext->FibList)) {
3147+
3148+ PLIST_ENTRY Entry;
3149+
3150+ //
3151+ // Pull the next fib from the FibList
3152+ //
3153+ Entry = RemoveHeadList(&AdapterFibContext->FibList);
3154+
3155+ Fib = CONTAINING_RECORD( Entry, FIB, Header.FibLinks );
3156+
3157+ AdapterFibContext->FibCount--;
3158+
3159+ if (COPYOUT( Fib, AdapterFibIoctl.AifFib, sizeof(FIB), IoctlCmdPtr->flag )) {
3160+
3161+ OsCvLockRelease( Adapter->AdapterFibMutex );
3162+ OsFreeMemory( Fib, sizeof(Fib) );
3163+ return (EFAULT);
3164+
3165+ }
3166+
3167+ //
3168+ // Free the space occupied by this copy of the fib.
3169+ //
3170+
3171+ OsFreeMemory(Fib, sizeof(FIB));
3172+
3173+ Status = 0;
3174+
3175+ //
3176+ // Overload FileObject with a time stamp
3177+ //
3178+ AdapterFibContext->FileObject = ( void * )OsGetSeconds();
3179+
3180+ } else {
3181+
3182+ if (AdapterFibIoctl.Wait) {
3183+
3184+ if (OsCv_wait_sig( &AdapterFibContext->UserEvent, Adapter->AdapterFibMutex ) == 0) {
3185+
3186+ Status = EINTR;
3187+
3188+ } else {
3189+
3190+ goto return_fib;
3191+
3192+ }
3193+ } else {
3194+
3195+ Status = EAGAIN;
3196+
3197+ }
3198+
3199+ }
3200+ OsCvLockRelease( Adapter->AdapterFibMutex );
3201+
3202+ return (Status);
3203+}
3204+
3205+int
3206+FsaCtlCloseGetAdapterFib(
3207+ IN PAFA_COMM_ADAPTER Adapter,
3208+ IN PAFA_IOCTL_CMD IoctlCmdPtr
3209+ )
3210+/*++
3211+
3212+Routine Description:
3213+
3214+ This routine will close down the AdapterFibContext passed in from the user.
3215+
3216+Arguments:
3217+
3218+ Adapter - Supplies which adapter is being processed.
3219+
3220+ Irp - Supplies the Irp being processed.
3221+
3222+Return Value:
3223+
3224+ STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
3225+
3226+ STATUS_SUCCESS - Everything OK.
3227+
3228+--*/
3229+{
3230+ PGET_ADAPTER_FIB_CONTEXT AdapterFibContext, aifcp;
3231+ AAC_STATUS Status;
3232+
3233+ PLIST_ENTRY Entry;
3234+ int found;
3235+
3236+ //
3237+ // Extract the AdapterFibContext from the Input parameters
3238+ //
3239+
3240+ AdapterFibContext = (PGET_ADAPTER_FIB_CONTEXT) IoctlCmdPtr->arg;
3241+
3242+ if (AdapterFibContext == 0) {
3243+ cmn_err(CE_WARN, "FsaCtlCloseGetAdapterFib: AdapterFibContext is NULL");
3244+ return(EINVAL);
3245+ }
3246+
3247+ //
3248+ // Verify that the HANDLE passed in was a valid AdapterFibContext
3249+ //
3250+ // Search the list of AdapterFibContext addresses on the adapter to be sure
3251+ // this is a valid address
3252+
3253+ found = 0;
3254+ Entry = Adapter->AdapterFibContextList.Flink;
3255+
3256+ while ( Entry != &Adapter->AdapterFibContextList ) {
3257+ aifcp = CONTAINING_RECORD ( Entry, GET_ADAPTER_FIB_CONTEXT, NextContext );
3258+ if ( AdapterFibContext == aifcp ) { // We found a winner
3259+ found = 1;
3260+ break;
3261+ }
3262+ Entry = Entry->Flink;
3263+ }
3264+
3265+ if ( found == 0 ) {
3266+ return ( 0 ); // Already Gone
3267+ }
3268+
3269+ if ( (AdapterFibContext->NodeTypeCode != FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT) ||
3270+ (AdapterFibContext->NodeByteSize != sizeof(GET_ADAPTER_FIB_CONTEXT)) ) {
3271+
3272+ return (EINVAL);
3273+
3274+ }
3275+
3276+ OsCvLockAcquire(Adapter->AdapterFibMutex);
3277+
3278+ Status = FsaCloseAdapterFibContext(Adapter, AdapterFibContext);
3279+
3280+ OsCvLockRelease(Adapter->AdapterFibMutex);
3281+
3282+ return (Status);
3283+}
3284+
3285+int
3286+FsaCloseAdapterFibContext(
3287+ IN PAFA_COMM_ADAPTER Adapter,
3288+ IN PGET_ADAPTER_FIB_CONTEXT AdapterFibContext
3289+ )
3290+{
3291+ int Status;
3292+ PFIB Fib;
3293+
3294+ //
3295+ // First free any FIBs that have not been consumed yet.
3296+ //
3297+
3298+ while (!IsListEmpty(&AdapterFibContext->FibList)) {
3299+
3300+ PLIST_ENTRY Entry;
3301+
3302+ //
3303+ // Pull the next fib from the FibList
3304+ //
3305+
3306+ Entry = RemoveHeadList(&AdapterFibContext->FibList);
3307+
3308+ Fib = CONTAINING_RECORD( Entry, FIB, Header.FibLinks );
3309+
3310+ AdapterFibContext->FibCount--;
3311+
3312+ //
3313+ // Free the space occupied by this copy of the fib.
3314+ //
3315+
3316+ OsFreeMemory(Fib, sizeof(FIB));
3317+ }
3318+
3319+ //
3320+ // Remove the Context from the AdapterFibContext List
3321+ //
3322+
3323+ RemoveEntryList(&AdapterFibContext->NextContext);
3324+
3325+ OsCv_destroy( &AdapterFibContext->UserEvent );
3326+
3327+ //
3328+ // Invalidate context
3329+ //
3330+
3331+ AdapterFibContext->NodeTypeCode = 0;
3332+
3333+ //
3334+ // Free the space occupied by the Context
3335+ //
3336+
3337+ OsFreeMemory(AdapterFibContext, sizeof(GET_ADAPTER_FIB_CONTEXT));
3338+
3339+ Status = STATUS_SUCCESS;
3340+
3341+ return Status;
3342+}
3343+#endif
3344+
3345+AAC_STATUS
3346+AfaCommOpenAdapter(
3347+ IN PVOID Arg
3348+ )
3349+/*++
3350+
3351+Routine Description:
3352+
3353+ The routine will get called by the miniport each time a user issues a CreateFile on the DeviceObject
3354+ for the adapter.
3355+
3356+ The main purpose of this routine is to set up any data structures that may be needed
3357+ to handle any requests made on this DeviceObject.
3358+
3359+Arguments:
3360+
3361+ Adapter - Pointer to which adapter miniport was opened.
3362+
3363+
3364+Return Value:
3365+
3366+ STATUS_SUCCESS
3367+
3368+--*/
3369+
3370+{
3371+ PAFA_COMM_ADAPTER Adapter = (PAFA_COMM_ADAPTER) Arg;
3372+ AAC_STATUS Status = STATUS_SUCCESS;
3373+ PAFA_CLASS_DRIVER ClassDriver;
3374+
3375+ ClassDriver = Adapter->ClassDriverList;
3376+
3377+ while (ClassDriver) {
3378+
3379+ if (ClassDriver->OpenAdapter) {
3380+
3381+ Status = ClassDriver->OpenAdapter( ClassDriver->ClassDriverExtension );
3382+
3383+ if (Status != STATUS_SUCCESS)
3384+ break;
3385+ }
3386+
3387+ ClassDriver = ClassDriver->Next;
3388+ }
3389+
3390+ return ( Status );
3391+}
3392+
3393+AAC_STATUS
3394+AfaCommCloseAdapter(
3395+ IN PVOID Arg
3396+ )
3397+/*++
3398+
3399+Routine Description:
3400+
3401+ This routine will get called by the miniport each time a user issues a CloseHandle on the DeviceObject
3402+ for the adapter.
3403+
3404+ The main purpose of this routine is to cleanup any data structures that have been set up
3405+ while this FileObject has been opened.
3406+
3407+ This routine loops through all of the AdapterFibContext structures to determine if any need
3408+ to be deleted for this FileObject.
3409+
3410+Arguments:
3411+
3412+ Adapter - Pointer to adapter miniport
3413+
3414+ Irp - Pointer to Irp that caused this close
3415+
3416+Return Value:
3417+
3418+ Status value returned from File system driver AdapterClose
3419+
3420+--*/
3421+{
3422+ PAFA_COMM_ADAPTER Adapter = (PAFA_COMM_ADAPTER) Arg;
3423+ PLIST_ENTRY Entry, NextEntry;
3424+ PGET_ADAPTER_FIB_CONTEXT AdapterFibContext;
3425+ AAC_STATUS Status = STATUS_SUCCESS;
3426+ PAFA_CLASS_DRIVER ClassDriver;
3427+
3428+ OsCvLockAcquire(Adapter->AdapterFibMutex);
3429+
3430+ Entry = Adapter->AdapterFibContextList.Flink;
3431+
3432+ //
3433+ // Loop through all of the AdapterFibContext, looking for any that
3434+ // were created with the FileObject that is being closed.
3435+ //
3436+ while (Entry != &Adapter->AdapterFibContextList) {
3437+
3438+ //
3439+ // Extract the AdapterFibContext
3440+ //
3441+ AdapterFibContext = CONTAINING_RECORD( Entry, GET_ADAPTER_FIB_CONTEXT, NextContext );
3442+
3443+ //
3444+ // Save the next entry because CloseAdapterFibContext will delete the AdapterFibContext
3445+ //
3446+ NextEntry = Entry->Flink;
3447+
3448+ Entry = NextEntry;
3449+
3450+ }
3451+
3452+#ifdef unix_config_file
3453+ //
3454+ // If this FileObject had the adapter open for configuration, then release it.
3455+ //
3456+ if ( Adapter->AdapterConfigFileObject == IrpSp->FileObject ) {
3457+
3458+ Adapter->AdapterConfigFileObject = NULL;
3459+
3460+ }
3461+#endif
3462+
3463+ OsCvLockRelease(Adapter->AdapterFibMutex);
3464+
3465+ ClassDriver = Adapter->ClassDriverList;
3466+
3467+ while (ClassDriver) {
3468+
3469+ if (ClassDriver->CloseAdapter) {
3470+
3471+ Status = ClassDriver->CloseAdapter( ClassDriver->ClassDriverExtension );
3472+
3473+ if (Status != STATUS_SUCCESS)
3474+ break;
3475+ }
3476+
3477+ ClassDriver = ClassDriver->Next;
3478+ }
3479+
3480+ return ( Status );
3481+
3482+}
3483+
3484diff -burN linux-2.4.9/drivers/scsi/aacraid/comminit.c linux/drivers/scsi/aacraid/comminit.c
3485--- linux-2.4.9/drivers/scsi/aacraid/comminit.c Wed Dec 31 18:00:00 1969
3486+++ linux/drivers/scsi/aacraid/comminit.c Thu Aug 16 13:41:30 2001
3487@@ -0,0 +1,986 @@
3488+/*++
3489+ * Adaptec aacraid device driver for Linux.
3490+ *
3491+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
3492+ *
3493+ * This program is free software; you can redistribute it and/or modify
3494+ * it under the terms of the GNU General Public License as published by
3495+ * the Free Software Foundation; either version 2, or (at your option)
3496+ * any later version.
3497+ *
3498+ * This program is distributed in the hope that it will be useful,
3499+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3500+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3501+ * GNU General Public License for more details.
3502+ *
3503+ * You should have received a copy of the GNU General Public License
3504+ * along with this program; see the file COPYING. If not, write to
3505+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
3506+ *
3507+ * Module Name:
3508+ * comminit.c
3509+ *
3510+ * Abstract: This supports the initialization of the host adapter commuication interface.
3511+ * This is a platform dependent module for the pci cyclone board.
3512+ *
3513+ --*/
3514+
3515+static char *ident_comminit = "aacraid_ident comminit.c 1.0.6 2000/10/09 Adaptec, Inc.";
3516+
3517+#include "comprocs.h"
3518+
3519+#define BugCheckFileId (FSAFS_BUG_CHECK_COMMINIT)
3520+
3521+VOID
3522+AfaCommBugcheckHandler(
3523+ IN PVOID Buffer,
3524+ IN ULONG Length
3525+ );
3526+
3527+VOID
3528+ThrottlePeriodEndDpcRtn(
3529+ IN PKDPC Dpc,
3530+ IN PVOID DeferredContext,
3531+ IN PVOID SystemArgument1,
3532+ IN PVOID SystemArgument2);
3533+
3534+FSA_COMM_DATA FsaCommData;
3535+
3536+AAC_STATUS
3537+HardInterruptModeration1Changed(
3538+ IN PVOID AdapterContext,
3539+ IN ULONG NewValue
3540+ )
3541+{
3542+ PAFA_COMM_ADAPTER Adapter = AdapterContext;
3543+
3544+ //
3545+ // If we are using interrupt moderation, then disable the interrupt
3546+ // until we need to use it.
3547+ //
3548+ if (FsaCommData.HardInterruptModeration1)
3549+ DisableInterrupt( Adapter, AdapNormCmdNotFull, FALSE );
3550+ else
3551+ EnableInterrupt( Adapter, AdapNormCmdNotFull, FALSE );
3552+
3553+ return (STATUS_SUCCESS);
3554+}
3555+
3556+AAC_STATUS
3557+FsaFibTimeoutChanged(
3558+ IN PVOID AdapterContext,
3559+ IN ULONG NewValue
3560+ )
3561+{
3562+ //
3563+ // scale the new timeout from seconds to 100 nsec units
3564+ //
3565+// FsaCommData.AdapterTimeout = RtlConvertLongToLargeInteger(-10*1000*1000*NewValue);
3566+
3567+ return (STATUS_SUCCESS);
3568+}
3569+
3570+#ifdef GATHER_FIB_TIMES
3571+extern int GatherFibTimes;
3572+#endif
3573+
3574+FSA_USER_VAR FsaCommUserVars[] = {
3575+#ifdef FIB_CHECKSUMS
3576+ { "do_fib_checksums", (PULONG)&FsaCommData.do_fib_checksums, NULL },
3577+#endif
3578+#ifdef GATHER_FIB_TIMES
3579+ { "GatherFibTimes", (PULONG)&GatherFibTimes, NULL },
3580+#endif
3581+ { "EnableAdapterTimeouts", (PULONG)&FsaCommData.EnableAdapterTimeouts, NULL},
3582+ { "EnableInterruptModeration", (PULONG)&FsaCommData.EnableInterruptModeration, NULL },
3583+ { "FsaDataFibsSent", (PULONG) &FsaCommData.FibsSent, NULL },
3584+ { "FsaDataFibRecved", (PULONG) &FsaCommData.FibRecved, NULL },
3585+ { "HardInterruptModeration", (PULONG)&FsaCommData.HardInterruptModeration, NULL},
3586+ { "HardInterruptModeration1", (PULONG)&FsaCommData.HardInterruptModeration1, HardInterruptModeration1Changed},
3587+ { "EnableFibTimeoutBreak", (PULONG)&FsaCommData.EnableFibTimeoutBreak, NULL},
3588+ { "PeakFibsConsumed", (PULONG)&FsaCommData.PeakFibsConsumed, NULL },
3589+ { "ZeroFibsConsumed", (PULONG)&FsaCommData.ZeroFibsConsumed, NULL },
3590+ { "FibTimeoutSeconds", (PULONG) &FsaCommData.FibTimeoutSeconds, FsaFibTimeoutChanged },
3591+};
3592+
3593+#define NUM_COMM_USER_VARS (sizeof(FsaCommUserVars) / sizeof(FSA_USER_VAR) )
3594+
3595+\f
3596+AAC_STATUS
3597+AacCommDriverEntry(
3598+ )
3599+
3600+/*++
3601+
3602+Routine Description:
3603+
3604+ This is the initialization routine for the FileArray Comm layer device driver.
3605+
3606+Arguments:
3607+
3608+ DriverObject - Pointer to driver object created by the system.
3609+
3610+Return Value:
3611+
3612+ AAC_STATUS - The function value is the final status from the initialization
3613+ operation.
3614+
3615+--*/
3616+
3617+{
3618+ AAC_STATUS Status;
3619+ PVOID BugCheckBuffer;
3620+
3621+ RtlZeroMemory( &FsaCommData, sizeof(FSA_COMM_DATA) );
3622+
3623+
3624+ //
3625+ // Load the global timeout value for the adapter timeout
3626+ // Also init the global that enables or disables adapter timeouts
3627+ //
3628+
3629+// FsaCommData.AdapterTimeout = RtlConvertLongToLargeInteger(-10*1000*1000*180);
3630+
3631+ FsaCommData.FibTimeoutSeconds = 180;
3632+
3633+ FsaCommData.EnableAdapterTimeouts = TRUE;
3634+
3635+// FsaCommData.QueueFreeTimeout = RtlConvertLongToLargeInteger(QUEUE_ENTRY_FREE_TIMEOUT);
3636+
3637+#ifdef unix_fib_timeout
3638+ FsaCommData.FibTimeoutIncrement = (180 * 1000 * 1000 * 10) / KeQueryTimeIncrement();
3639+#endif
3640+
3641+ FsaCommData.EnableInterruptModeration = FALSE;
3642+
3643+ //
3644+ // Preload UserVars with all variables from the comm layer. The class layers will
3645+ // include theirs when they register.
3646+ //
3647+
3648+ FsaCommData.UserVars = OsAllocMemory(NUM_COMM_USER_VARS * sizeof(FSA_USER_VAR), OS_ALLOC_MEM_SLEEP );
3649+ FsaCommData.NumUserVars = NUM_COMM_USER_VARS;
3650+
3651+ RtlCopyMemory( FsaCommData.UserVars, &FsaCommUserVars, NUM_COMM_USER_VARS * sizeof(FSA_USER_VAR) );
3652+
3653+
3654+#ifdef AACDISK
3655+ //
3656+ // Call the disk driver to initialize itself.
3657+ //
3658+
3659+ AacDiskDriverEntry();
3660+
3661+#endif
3662+
3663+
3664+
3665+ return (STATUS_SUCCESS);
3666+}
3667+
3668+
3669+VOID
3670+DetachNTQueue(
3671+ IN PAFA_COMM_ADAPTER Adapter,
3672+ IN OUT PCOMM_QUE Queue,
3673+ IN QUEUE_TYPES WhichQueue
3674+ )
3675+/*++
3676+
3677+Routine Description:
3678+
3679+ This routine will release all of the resources used by a given queue.
3680+
3681+Arguments:
3682+
3683+ Adapter - Which adapter the queue belongs to
3684+ Queue - Pointer to the queue itself
3685+ WhichQueue - Identifies which of the host queues this is.
3686+
3687+Return Value:
3688+
3689+ NONE.
3690+
3691+--*/
3692+{
3693+ switch (WhichQueue) {
3694+
3695+ case HostNormCmdQueue:
3696+
3697+ Os_remove_softintr( Queue->ConsumerRoutine );
3698+ OsSpinLockDestroy( Queue->QueueLock );
3699+ OsCv_destroy( &Queue->CommandReady );
3700+
3701+ break;
3702+
3703+ case HostHighCmdQueue:
3704+
3705+ Os_remove_softintr( Queue->ConsumerRoutine );
3706+ OsSpinLockDestroy( Queue->QueueLock );
3707+ OsCv_destroy( &Queue->CommandReady );
3708+
3709+ break;
3710+
3711+ case HostNormRespQueue:
3712+
3713+ Os_remove_softintr( Queue->ConsumerRoutine );
3714+ OsSpinLockDestroy( Queue->QueueLock );
3715+ break;
3716+
3717+ case HostHighRespQueue:
3718+
3719+ Os_remove_softintr( Queue->ConsumerRoutine );
3720+ OsSpinLockDestroy( Queue->QueueLock );
3721+ break;
3722+
3723+ case AdapNormCmdQueue:
3724+ case AdapHighCmdQueue:
3725+ case AdapNormRespQueue:
3726+ case AdapHighRespQueue:
3727+ OsCv_destroy( &Queue->QueueFull );
3728+ break;
3729+ }
3730+}
3731+
3732+VOID
3733+InitializeNTQueue(
3734+ IN PAFA_COMM_ADAPTER Adapter,
3735+ IN OUT PCOMM_QUE Queue,
3736+ IN QUEUE_TYPES WhichQueue
3737+ )
3738+/*++
3739+
3740+Routine Description:
3741+
3742+ Will initialize all entries in the queue that is NT specific.
3743+
3744+Arguments:
3745+
3746+Return Value:
3747+
3748+ Nothing there is nothing to allocate so nothing should fail
3749+
3750+--*/
3751+{
3752+
3753+ Queue->NumOutstandingIos = 0;
3754+
3755+ //
3756+ // Store a pointer to the adapter structure.
3757+ //
3758+
3759+ Queue->Adapter = Adapter;
3760+
3761+ InitializeListHead( &Queue->OutstandingIoQueue );
3762+
3763+ switch (WhichQueue) {
3764+
3765+ case HostNormCmdQueue:
3766+
3767+ OsCv_init( &Queue->CommandReady);
3768+ OsSpinLockInit( Queue->QueueLock, Adapter->SpinLockCookie);
3769+ if (ddi_add_softintr( Adapter->Dip, DDI_SOFTINT_HIGH, &Queue->ConsumerRoutine, NULL,
3770+ NULL, (PUNIX_INTR_HANDLER)HostCommandNormDpc,
3771+ (caddr_t)Queue ) != DDI_SUCCESS) {
3772+
3773+ cmn_err(CE_CONT, "OS_addr_intr failed\n");
3774+ }
3775+
3776+ InitializeListHead(&Queue->CommandQueue);
3777+
3778+ break;
3779+
3780+ case HostHighCmdQueue:
3781+
3782+ OsCv_init( &Queue->CommandReady);
3783+ OsSpinLockInit( Queue->QueueLock, Adapter->SpinLockCookie);
3784+ if (ddi_add_softintr( Adapter->Dip, DDI_SOFTINT_HIGH, &Queue->ConsumerRoutine, NULL,
3785+ NULL, (PUNIX_INTR_HANDLER)HostCommandHighDpc,
3786+ (caddr_t) Queue ) != DDI_SUCCESS) {
3787+
3788+ cmn_err(CE_CONT, "OS_addr_intr failed\n");
3789+ }
3790+
3791+ InitializeListHead(&Queue->CommandQueue);
3792+ break;
3793+
3794+ case HostNormRespQueue:
3795+
3796+ OsSpinLockInit( Queue->QueueLock, Adapter->SpinLockCookie);
3797+ if (ddi_add_softintr( Adapter->Dip, DDI_SOFTINT_HIGH, &Queue->ConsumerRoutine, NULL,
3798+ NULL, (PUNIX_INTR_HANDLER)HostResponseNormalDpc,
3799+ (caddr_t) Queue ) != DDI_SUCCESS) {
3800+
3801+ cmn_err(CE_CONT, "OS_addr_intr failed\n");
3802+ }
3803+ break;
3804+
3805+ case HostHighRespQueue:
3806+
3807+
3808+ OsSpinLockInit( Queue->QueueLock, Adapter->SpinLockCookie);
3809+ if (ddi_add_softintr( Adapter->Dip, DDI_SOFTINT_HIGH, &Queue->ConsumerRoutine, NULL,
3810+ NULL, (PUNIX_INTR_HANDLER)HostResponseHighDpc,
3811+ (caddr_t) Queue ) != DDI_SUCCESS) {
3812+
3813+ cmn_err(CE_CONT, "OS_addr_intr failed\n");
3814+ }
3815+ break;
3816+
3817+ case AdapNormCmdQueue:
3818+ case AdapHighCmdQueue:
3819+ case AdapNormRespQueue:
3820+ case AdapHighRespQueue:
3821+
3822+ OsCv_init( &Queue->QueueFull);
3823+ break;
3824+ }
3825+}
3826+
3827+BOOLEAN
3828+StartFsaCommandThreads(PAFA_COMM_ADAPTER Adapter)
3829+/*++
3830+
3831+Routine Description:
3832+
3833+ Create and start the command receiver threads.
3834+
3835+Arguments:
3836+
3837+
3838+Return Value:
3839+
3840+ Nothing
3841+
3842+--*/
3843+
3844+{
3845+ return(TRUE);
3846+}
3847+
3848+
3849+
3850+/*++
3851+
3852+Routine Description:
3853+
3854+ This routine gets called to detach all resources that have been allocated for
3855+ this adapter.
3856+
3857+Arguments:
3858+
3859+ Adapter - Pointer to the adapter structure to detach.
3860+
3861+Return Value:
3862+
3863+ TRUE - All resources have been properly released.
3864+ FALSE - An error occured while trying to release resources.
3865+--*/
3866+BOOLEAN
3867+AacCommDetachAdapter (IN PAFA_COMM_ADAPTER Adapter)
3868+{
3869+ PAFA_CLASS_DRIVER ClassDriver;
3870+ //
3871+ // First remove this adapter from the list of adapters.
3872+ //
3873+
3874+ if (FsaCommData.AdapterList == Adapter) {
3875+
3876+ FsaCommData.AdapterList = Adapter->NextAdapter;
3877+
3878+ } else {
3879+
3880+ PAFA_COMM_ADAPTER CurrentAdapter, NextAdapter;
3881+
3882+ CurrentAdapter = FsaCommData.AdapterList;
3883+ NextAdapter = CurrentAdapter->NextAdapter;
3884+
3885+ while (NextAdapter) {
3886+
3887+ if (NextAdapter == Adapter) {
3888+
3889+ CurrentAdapter->NextAdapter = NextAdapter->NextAdapter;
3890+ break;
3891+
3892+ }
3893+
3894+ CurrentAdapter = NextAdapter;
3895+ NextAdapter = CurrentAdapter->NextAdapter;
3896+ }
3897+ }
3898+
3899+ //
3900+ // First send a shutdown to the adapter.
3901+ //
3902+
3903+ AfaCommShutdown( Adapter );
3904+
3905+ //
3906+ // Destroy the FibContextZone for this adapter. This will free up all
3907+ // of the fib space used by this adapter.
3908+ //
3909+
3910+ FsaFreeFibContextZone( Adapter );
3911+
3912+ //
3913+ // Destroy the mutex used for synch'ing adapter fibs.
3914+ //
3915+
3916+ OsCvLockDestroy( Adapter->AdapterFibMutex );
3917+
3918+ //
3919+ // Detach all of the host queues.
3920+ //
3921+
3922+ DetachNTQueue( Adapter, &Adapter->CommRegion->AdapHighRespQue, AdapHighRespQueue );
3923+ DetachNTQueue( Adapter, &Adapter->CommRegion->AdapNormRespQue, AdapNormRespQueue );
3924+ DetachNTQueue( Adapter, &Adapter->CommRegion->HostHighRespQue, HostHighRespQueue );
3925+ DetachNTQueue( Adapter, &Adapter->CommRegion->HostNormRespQue, HostNormRespQueue );
3926+ DetachNTQueue( Adapter, &Adapter->CommRegion->AdapHighCmdQue, AdapHighCmdQueue );
3927+ DetachNTQueue( Adapter, &Adapter->CommRegion->AdapNormCmdQue, AdapNormCmdQueue );
3928+ DetachNTQueue( Adapter, &Adapter->CommRegion->HostHighCmdQue, HostHighCmdQueue );
3929+ DetachNTQueue( Adapter, &Adapter->CommRegion->HostNormCmdQue, HostNormCmdQueue );
3930+
3931+ //
3932+ // Destroy the mutex used to protect the FibContextZone
3933+ //
3934+
3935+ OsSpinLockDestroy( Adapter->FibContextZoneSpinLock );
3936+
3937+ //
3938+ // Call the miniport to free the space allocated for the shared comm queues
3939+ // between the host and the adapter.
3940+ //
3941+
3942+ FsaFreeAdapterCommArea( Adapter );
3943+
3944+ //
3945+ // Free the memory used by the comm region for this adapter
3946+ //
3947+
3948+ OsFreeMemory( Adapter->CommRegion, sizeof(COMM_REGION) );
3949+
3950+ //
3951+ // Free the memory used by the adapter structure.
3952+ //
3953+ ClassDriver = Adapter->ClassDriverList;
3954+ Adapter->ClassDriverList = Adapter->ClassDriverList->Next;
3955+ OsFreeMemory( ClassDriver, sizeof(AFA_CLASS_DRIVER) );
3956+
3957+ OsFreeMemory( Adapter, sizeof(AFA_COMM_ADAPTER) );
3958+
3959+ return (TRUE);
3960+}
3961+
3962+PVOID
3963+AfaCommInitNewAdapter (IN PFSA_NEW_ADAPTER NewAdapter)
3964+{
3965+ PVOID BugCheckBuffer;
3966+ PAFA_COMM_ADAPTER Adapter;
3967+ MAPFIB_CONTEXT MapFibContext;
3968+ LARGE_INTEGER Time;
3969+ char ErrorBuffer[60];
3970+
3971+ Adapter = (PAFA_COMM_ADAPTER) OsAllocMemory( sizeof(AFA_COMM_ADAPTER) , OS_ALLOC_MEM_SLEEP );
3972+
3973+ if (Adapter == NULL)
3974+ return (NULL);
3975+
3976+ RtlZeroMemory(Adapter, sizeof(AFA_COMM_ADAPTER));
3977+
3978+
3979+ //
3980+ // Save the current adapter number and increment the total number.
3981+ //
3982+
3983+ Adapter->AdapterNumber = FsaCommData.TotalAdapters++;
3984+
3985+
3986+ //
3987+ // Fill in the pointer back to the device specific structures.
3988+ // The device specific driver has also passed a pointer for us to
3989+ // fill in with the Adapter object that we have created.
3990+ //
3991+
3992+ Adapter->AdapterExtension = NewAdapter->AdapterExtension;
3993+ Adapter->AdapterFuncs = NewAdapter->AdapterFuncs;
3994+ Adapter->InterruptsBelowDpc = NewAdapter->AdapterInterruptsBelowDpc;
3995+ Adapter->AdapterUserVars = NewAdapter->AdapterUserVars;
3996+ Adapter->AdapterUserVarsSize = NewAdapter->AdapterUserVarsSize;
3997+
3998+ Adapter->Dip = NewAdapter->Dip;
3999+
4000+ //
4001+ // Fill in Our address into the function dispatch table
4002+ //
4003+
4004+ NewAdapter->AdapterFuncs->InterruptHost = AfaCommInterruptHost;
4005+ NewAdapter->AdapterFuncs->OpenAdapter = AfaCommOpenAdapter;
4006+ NewAdapter->AdapterFuncs->CloseAdapter = AfaCommCloseAdapter;
4007+ NewAdapter->AdapterFuncs->DeviceControl = AfaCommAdapterDeviceControl;
4008+
4009+ //
4010+ // Ok now init the communication subsystem
4011+ //
4012+
4013+ Adapter->CommRegion = (PCOMM_REGION) OsAllocMemory(sizeof(COMM_REGION), OS_ALLOC_MEM_SLEEP);
4014+ if (Adapter->CommRegion == NULL) {
4015+ cmn_err(CE_WARN, "Error could not allocate comm region.\n");
4016+ return (NULL);
4017+ }
4018+ RtlZeroMemory(Adapter->CommRegion, sizeof(COMM_REGION));
4019+
4020+ //
4021+ // Get a pointer to the iblock_cookie
4022+ //
4023+
4024+ ddi_get_soft_iblock_cookie( Adapter->Dip, DDI_SOFTINT_HIGH, &Adapter->SpinLockCookie );
4025+
4026+ if (!CommInit(Adapter)) {
4027+ FsaCommPrint("Failed to init the commuication subsystem.\n");
4028+ return(NULL);
4029+ }
4030+
4031+
4032+ //
4033+ // Initialize the list of AdapterFibContext's.
4034+ //
4035+
4036+ InitializeListHead(&Adapter->AdapterFibContextList);
4037+
4038+ //
4039+ // Initialize the fast mutex used for synchronization of the adapter fibs
4040+ //
4041+
4042+ Adapter->AdapterFibMutex = OsCvLockAlloc();
4043+ OsCvLockInit(Adapter->AdapterFibMutex, NULL);
4044+
4045+ //
4046+ // Allocate and start the FSA command threads. These threads will handle
4047+ // command requests from the adapter. They will wait on an event then pull
4048+ // all CDBs off the thread's queue. Each CDB will be given to a worker thread
4049+ // upto a defined limit. When that limit is reached wait a event will be waited
4050+ // on till a worker thread is finished.
4051+ //
4052+
4053+ if (!StartFsaCommandThreads(Adapter)) {
4054+ FsaCommPrint("Fsainit could not initilize the command receiver threads.\n");
4055+ return (NULL);
4056+ }
4057+
4058+#ifdef unix_crash_dump
4059+ //
4060+ // Allocate and map a fib for use by the synch path, which is used for crash
4061+ // dumps.
4062+ //
4063+ // Allocate an entire page so that alignment is correct.
4064+ //
4065+
4066+ Adapter->SyncFib = OsAllocMemory( PAGE_SIZE, OS_ALLOC_MEM_SLEEP );
4067+ MapFibContext.Fib = Adapter->SyncFib;
4068+ MapFibContext.Size = sizeof(FIB);
4069+ MapFib( Adapter, &MapFibContext );
4070+ Adapter->SyncFibPhysicalAddress = MapFibContext.LogicalFibAddress.LowPart;
4071+#endif
4072+
4073+ Adapter->CommFuncs.SizeOfAfaCommFuncs = sizeof(AFACOMM_FUNCS);
4074+
4075+ Adapter->CommFuncs.AllocateFib = AllocateFib;
4076+
4077+ Adapter->CommFuncs.FreeFib = FreeFib;
4078+ Adapter->CommFuncs.FreeFibFromDpc = FreeFibFromDpc;
4079+ Adapter->CommFuncs.DeallocateFib = DeallocateFib;
4080+
4081+ Adapter->CommFuncs.InitializeFib = InitializeFib;
4082+ Adapter->CommFuncs.GetFibData = FsaGetFibData;
4083+ Adapter->CommFuncs.SendFib = SendFib;
4084+ Adapter->CommFuncs.CompleteFib = CompleteFib;
4085+ Adapter->CommFuncs.CompleteAdapterFib = CompleteAdapterFib;
4086+
4087+ Adapter->CommFuncs.SendSynchFib = SendSynchFib;
4088+
4089+ Adapter->CommFuncs.FreeDmaResources = Adapter->AdapterFuncs->FreeDmaResources;
4090+ Adapter->CommFuncs.BuildSgMap = Adapter->AdapterFuncs->BuildSgMap;
4091+
4092+ //
4093+ // Add this adapter in to our Adapter List.
4094+ //
4095+
4096+ Adapter->NextAdapter = FsaCommData.AdapterList;
4097+ FsaCommData.AdapterList = Adapter;
4098+
4099+ NewAdapter->Adapter = Adapter;
4100+
4101+// AfaDiskInitNewAdapter( Adapter->AdapterNumber, Adapter );
4102+
4103+ return (Adapter);
4104+}
4105+
4106+AAC_STATUS
4107+CommInitialize(
4108+ PAFA_COMM_ADAPTER Adapter
4109+ )
4110+{
4111+ //
4112+ // Now allocate and initialize the zone structures used as our pool
4113+ // of FIB context records. The size of the zone is based on the
4114+ // system memory size. We also initialize the mutex used to protect
4115+ // the zone.
4116+ //
4117+ Adapter->FibContextZoneSpinLock = OsSpinLockAlloc();
4118+ OsSpinLockInit( Adapter->FibContextZoneSpinLock, Adapter->SpinLockCookie );
4119+
4120+ Adapter->FibContextZoneExtendSize = 64;
4121+
4122+ return (STATUS_SUCCESS);
4123+}
4124+
4125+
4126+
4127+/*++
4128+
4129+Routine Description:
4130+
4131+ Initializes the data structures that are required for the FSA commuication
4132+ interface to operate.
4133+
4134+Arguments:
4135+
4136+ None - all global or allocated data.
4137+
4138+Return Value:
4139+
4140+ TRUE - if we were able to init the commuication interface.
4141+ FALSE - If there were errors initing. This is a fatal error.
4142+--*/
4143+BOOLEAN
4144+CommInit(PAFA_COMM_ADAPTER Adapter)
4145+{
4146+
4147+ ULONG SizeOfHeaders = (sizeof(QUEUE_INDEX) * NUMBER_OF_COMM_QUEUES) * 2;
4148+ ULONG SizeOfQueues = sizeof(QUEUE_ENTRY) * TOTAL_QUEUE_ENTRIES;
4149+ PQUEUE_INDEX Headers;
4150+ PQUEUE_ENTRY Queues;
4151+ ULONG TotalSize;
4152+ PCOMM_REGION CommRegion = Adapter->CommRegion;
4153+
4154+ CommInitialize( Adapter );
4155+
4156+ FsaCommPrint("CommInit: Queue entry size is 0x%x, Queue index size is 0x%x, Number of total entries is 0x%x, # queues = 0x%x.\n",
4157+ sizeof(QUEUE_ENTRY), sizeof(QUEUE_INDEX), TOTAL_QUEUE_ENTRIES, NUMBER_OF_COMM_QUEUES);
4158+ //
4159+ //
4160+ // Allocate the physically contigous space for the commuication queue
4161+ // headers.
4162+ //
4163+
4164+ TotalSize = SizeOfHeaders + SizeOfQueues;
4165+
4166+ if (!FsaAllocateAdapterCommArea(Adapter, (PVOID *)&Headers, TotalSize, QUEUE_ALIGNMENT))
4167+ return (FALSE);
4168+
4169+ Queues = (PQUEUE_ENTRY)((PUCHAR)Headers + SizeOfHeaders);
4170+
4171+ if (ddi_add_softintr( Adapter->Dip, DDI_SOFTINT_HIGH, &CommRegion->QueueNotFullDpc, NULL,
4172+ NULL, (PUNIX_INTR_HANDLER)CommonNotFullDpc,
4173+ (caddr_t)CommRegion ) != DDI_SUCCESS) {
4174+
4175+ cmn_err(CE_CONT, "Os_addr_intr failed\n");
4176+ }
4177+
4178+
4179+ // Adapter to Host normal priority Command queue
4180+
4181+
4182+ CommRegion->HostNormCmdQue.Headers.ProducerIndex = Headers++;
4183+ CommRegion->HostNormCmdQue.Headers.ConsumerIndex = Headers++;
4184+ *CommRegion->HostNormCmdQue.Headers.ProducerIndex = HOST_NORM_CMD_ENTRIES;
4185+ *CommRegion->HostNormCmdQue.Headers.ConsumerIndex = HOST_NORM_CMD_ENTRIES;
4186+
4187+ CommRegion->HostNormCmdQue.SavedIrql = 0;
4188+ CommRegion->HostNormCmdQue.BaseAddress = Queues;
4189+ CommRegion->HostNormCmdQue.QueueEntries = HOST_NORM_CMD_ENTRIES;
4190+
4191+ CommRegion->HostNormCmdQue.QueueLock = OsSpinLockAlloc();
4192+ if (CommRegion->HostNormCmdQue.QueueLock == NULL) {
4193+ return (FALSE);
4194+ }
4195+ InitializeNTQueue(Adapter, &CommRegion->HostNormCmdQue, HostNormCmdQueue);
4196+
4197+
4198+ Queues += HOST_NORM_CMD_ENTRIES;
4199+
4200+ // Adapter to Host high priority command queue
4201+
4202+ CommRegion->HostHighCmdQue.Headers.ProducerIndex = Headers++;
4203+ CommRegion->HostHighCmdQue.Headers.ConsumerIndex = Headers++;
4204+ *CommRegion->HostHighCmdQue.Headers.ProducerIndex = HOST_HIGH_CMD_ENTRIES;
4205+ *CommRegion->HostHighCmdQue.Headers.ConsumerIndex = HOST_HIGH_CMD_ENTRIES;
4206+
4207+ CommRegion->HostHighCmdQue.SavedIrql = 0;
4208+ CommRegion->HostHighCmdQue.BaseAddress = Queues;
4209+ CommRegion->HostHighCmdQue.QueueEntries = HOST_HIGH_CMD_ENTRIES;
4210+// CommRegion->HostHighCmdQue.QueueLock = (PKSPIN_LOCK) ExAllocatePool(NonPagedPool, sizeof(KSPIN_LOCK));
4211+ CommRegion->HostHighCmdQue.QueueLock = OsSpinLockAlloc();
4212+ if (CommRegion->HostHighCmdQue.QueueLock == NULL) {
4213+ return (FALSE);
4214+ }
4215+ InitializeNTQueue(Adapter, &CommRegion->HostHighCmdQue, HostHighCmdQueue);
4216+
4217+ Queues += HOST_HIGH_CMD_ENTRIES;
4218+
4219+ // Host to adapter normal priority command queue
4220+
4221+ CommRegion->AdapNormCmdQue.Headers.ProducerIndex = Headers++;
4222+ CommRegion->AdapNormCmdQue.Headers.ConsumerIndex = Headers++;
4223+ *CommRegion->AdapNormCmdQue.Headers.ProducerIndex = ADAP_NORM_CMD_ENTRIES;
4224+ *CommRegion->AdapNormCmdQue.Headers.ConsumerIndex = ADAP_NORM_CMD_ENTRIES;
4225+
4226+ CommRegion->AdapNormCmdQue.SavedIrql = 0;
4227+ CommRegion->AdapNormCmdQue.BaseAddress = Queues;
4228+ CommRegion->AdapNormCmdQue.QueueEntries = ADAP_NORM_CMD_ENTRIES;
4229+ InitializeNTQueue(Adapter, &CommRegion->AdapNormCmdQue, AdapNormCmdQueue);
4230+
4231+ Queues += ADAP_NORM_CMD_ENTRIES;
4232+
4233+ // host to adapter high priority command queue
4234+
4235+ CommRegion->AdapHighCmdQue.Headers.ProducerIndex = Headers++;
4236+ CommRegion->AdapHighCmdQue.Headers.ConsumerIndex = Headers++;
4237+ *CommRegion->AdapHighCmdQue.Headers.ProducerIndex = ADAP_HIGH_CMD_ENTRIES;
4238+ *CommRegion->AdapHighCmdQue.Headers.ConsumerIndex = ADAP_HIGH_CMD_ENTRIES;
4239+
4240+ CommRegion->AdapHighCmdQue.SavedIrql = 0;
4241+ CommRegion->AdapHighCmdQue.BaseAddress = Queues;
4242+ CommRegion->AdapHighCmdQue.QueueEntries = ADAP_HIGH_CMD_ENTRIES;
4243+ InitializeNTQueue(Adapter, &CommRegion->AdapHighCmdQue, AdapHighCmdQueue);
4244+
4245+ Queues += ADAP_HIGH_CMD_ENTRIES;
4246+
4247+ // adapter to host normal priority response queue
4248+
4249+ CommRegion->HostNormRespQue.Headers.ProducerIndex = Headers++;
4250+ CommRegion->HostNormRespQue.Headers.ConsumerIndex = Headers++;
4251+ *CommRegion->HostNormRespQue.Headers.ProducerIndex = HOST_NORM_RESP_ENTRIES;
4252+ *CommRegion->HostNormRespQue.Headers.ConsumerIndex = HOST_NORM_RESP_ENTRIES;
4253+
4254+ CommRegion->HostNormRespQue.SavedIrql = 0;
4255+ CommRegion->HostNormRespQue.BaseAddress = Queues;
4256+ CommRegion->HostNormRespQue.QueueEntries = HOST_NORM_RESP_ENTRIES;
4257+// CommRegion->HostNormRespQue.QueueLock = (PKSPIN_LOCK) ExAllocatePool(NonPagedPool, sizeof(KSPIN_LOCK));
4258+ CommRegion->HostNormRespQue.QueueLock = OsSpinLockAlloc();
4259+ if (CommRegion->HostNormRespQue.QueueLock == NULL) {
4260+ return (FALSE);
4261+ }
4262+ InitializeNTQueue(Adapter, &CommRegion->HostNormRespQue, HostNormRespQueue);
4263+
4264+ Queues += HOST_NORM_RESP_ENTRIES;
4265+
4266+ // adapter to host high priority response queue
4267+
4268+ CommRegion->HostHighRespQue.Headers.ProducerIndex = Headers++;
4269+ CommRegion->HostHighRespQue.Headers.ConsumerIndex = Headers++;
4270+ *CommRegion->HostHighRespQue.Headers.ProducerIndex = HOST_HIGH_RESP_ENTRIES;
4271+ *CommRegion->HostHighRespQue.Headers.ConsumerIndex = HOST_HIGH_RESP_ENTRIES;
4272+
4273+ CommRegion->HostHighRespQue.SavedIrql = 0;
4274+ CommRegion->HostHighRespQue.BaseAddress = Queues;
4275+ CommRegion->HostHighRespQue.QueueEntries = HOST_HIGH_RESP_ENTRIES;
4276+// CommRegion->HostHighRespQue.QueueLock = (PKSPIN_LOCK) ExAllocatePool(NonPagedPool, sizeof(KSPIN_LOCK));
4277+ CommRegion->HostHighRespQue.QueueLock = OsSpinLockAlloc();
4278+ if (CommRegion->HostHighRespQue.QueueLock == NULL) {
4279+ return (FALSE);
4280+ }
4281+ InitializeNTQueue(Adapter, &CommRegion->HostHighRespQue, HostHighRespQueue);
4282+
4283+ Queues += HOST_HIGH_RESP_ENTRIES;
4284+
4285+ // host to adapter normal priority response queue
4286+
4287+ CommRegion->AdapNormRespQue.Headers.ProducerIndex = Headers++;
4288+ CommRegion->AdapNormRespQue.Headers.ConsumerIndex = Headers++;
4289+ *CommRegion->AdapNormRespQue.Headers.ProducerIndex = ADAP_NORM_RESP_ENTRIES;
4290+ *CommRegion->AdapNormRespQue.Headers.ConsumerIndex = ADAP_NORM_RESP_ENTRIES;
4291+
4292+ CommRegion->AdapNormRespQue.SavedIrql = 0;
4293+ CommRegion->AdapNormRespQue.BaseAddress = Queues;
4294+ CommRegion->AdapNormRespQue.QueueEntries = ADAP_NORM_RESP_ENTRIES;
4295+ InitializeNTQueue(Adapter, &CommRegion->AdapNormRespQue, AdapNormRespQueue);
4296+
4297+ Queues += ADAP_NORM_RESP_ENTRIES;
4298+
4299+ // host to adapter high priority response queue
4300+
4301+ CommRegion->AdapHighRespQue.Headers.ProducerIndex = Headers++;
4302+ CommRegion->AdapHighRespQue.Headers.ConsumerIndex = Headers++;
4303+ *CommRegion->AdapHighRespQue.Headers.ProducerIndex = ADAP_HIGH_RESP_ENTRIES;
4304+ *CommRegion->AdapHighRespQue.Headers.ConsumerIndex = ADAP_HIGH_RESP_ENTRIES;
4305+
4306+ CommRegion->AdapHighRespQue.SavedIrql = 0;
4307+ CommRegion->AdapHighRespQue.BaseAddress = Queues;
4308+ CommRegion->AdapHighRespQue.QueueEntries = ADAP_HIGH_RESP_ENTRIES;
4309+ InitializeNTQueue(Adapter, &CommRegion->AdapHighRespQue, AdapHighRespQueue);
4310+
4311+ CommRegion->AdapNormCmdQue.QueueLock = CommRegion->HostNormRespQue.QueueLock;
4312+ CommRegion->AdapHighCmdQue.QueueLock = CommRegion->HostHighRespQue.QueueLock;
4313+ CommRegion->AdapNormRespQue.QueueLock = CommRegion->HostNormCmdQue.QueueLock;
4314+ CommRegion->AdapHighRespQue.QueueLock = CommRegion->HostHighCmdQue.QueueLock;
4315+
4316+ return(TRUE);
4317+}
4318+
4319+AAC_STATUS
4320+AfaCommShutdown(
4321+ PAFA_COMM_ADAPTER Adapter
4322+ )
4323+/*++
4324+
4325+Routine Description:
4326+
4327+ This routine will send a shutdown request to each adapter.
4328+
4329+Arguments:
4330+
4331+ Adapter - which adapter to send the shutdown to.
4332+
4333+Return Value:
4334+
4335+ NT Status success.
4336+
4337+--*/
4338+
4339+{
4340+ PFIB_CONTEXT FibContext;
4341+ PCLOSECOMMAND CloseCommand;
4342+ AAC_STATUS Status;
4343+
4344+ FibContext = AllocateFib( Adapter );
4345+
4346+ InitializeFib( FibContext );
4347+
4348+ CloseCommand = (PCLOSECOMMAND) FsaGetFibData( FibContext );
4349+
4350+ CloseCommand->Command = VM_CloseAll;
4351+ CloseCommand->ContainerId = 0xffffffff;
4352+
4353+ Status = SendFib( ContainerCommand, FibContext, sizeof(CLOSECOMMAND), FsaNormal, TRUE, NULL, TRUE, NULL, NULL );
4354+
4355+ if (Status != STATUS_SUCCESS) {
4356+
4357+ FreeFib( FibContext );
4358+
4359+ goto ret;
4360+
4361+ }
4362+
4363+ CompleteFib( FibContext );
4364+
4365+ FreeFib( FibContext );
4366+
4367+
4368+ Status = STATUS_SUCCESS;
4369+
4370+ret:
4371+
4372+ return (Status);
4373+
4374+}
4375+
4376+VOID
4377+AfaCommBugcheckHandler(
4378+ IN PVOID Buffer,
4379+ IN ULONG Length
4380+ )
4381+/*++
4382+
4383+Routine Description:
4384+
4385+ This routine will shutdown the adapter if there is a bugcheck and
4386+ copy the shutdown data from the adapter response into the buffer
4387+ so it will show up in the host dump file.
4388+p
4389+Arguments:
4390+
4391+ Buffer - This buffer will be written to the host dump by nt for us.
4392+
4393+ Length - The size of the buffer.
4394+
4395+Return Value:
4396+
4397+ N/A
4398+
4399+--*/
4400+{
4401+ PAFA_COMM_ADAPTER Adapter = FsaCommData.AdapterList;
4402+
4403+ while (Adapter) {
4404+
4405+ NotifyAdapter(Adapter, HostShutdown);
4406+
4407+ Adapter = Adapter->NextAdapter;
4408+
4409+ }
4410+
4411+}
4412+
4413+VOID
4414+FsaCommLogEvent(
4415+ PFIB_CONTEXT FibContext,
4416+ PDEVICE_OBJECT DeviceObject,
4417+ AAC_STATUS FsaStatus,
4418+ AAC_STATUS AacStatus,
4419+ ULONG LocationCode,
4420+ USHORT Category,
4421+ PUCHAR String,
4422+ BOOLEAN DumpFib
4423+)
4424+{
4425+}
4426+
4427+AfaCommProbeDisks(
4428+ PAFA_COMM_ADAPTER Adapter
4429+ )
4430+{
4431+ PMNTINFO DiskInfo;
4432+ PMNTINFORESPONSE DiskInfoResponse;
4433+ AAC_STATUS Status;
4434+ PCOMM_FIB_CONTEXT FibContext;
4435+
4436+ FibContext = AllocateFib( Adapter );
4437+
4438+ InitializeFib( FibContext );
4439+
4440+ DiskInfo = (PMNTINFO) FibContext->Fib->data;
4441+ DiskInfo->Command = VM_NameServe;
4442+ DiskInfo->MntCount = 0;
4443+ DiskInfo->MntType = FT_FILESYS;
4444+
4445+ Status = SendFib(ContainerCommand,
4446+ FibContext,
4447+ sizeof(MNTINFO),
4448+ FsaNormal,
4449+ TRUE,
4450+ NULL,
4451+ TRUE,
4452+ NULL,
4453+ NULL);
4454+
4455+ DiskInfoResponse = (PMNTINFORESPONSE) FibContext->Fib->data;
4456+
4457+ if (DiskInfoResponse->MntRespCount) {
4458+
4459+ cmn_err(CE_CONT, "container found on adapter, size = 0x%x blocks\n",
4460+ DiskInfoResponse->MntTable[0].Capacity);
4461+
4462+ } else {
4463+
4464+ cmn_err(CE_CONT, "no containers found on adapter\n");
4465+
4466+ }
4467+
4468+ CompleteFib( FibContext );
4469+
4470+ FreeFib( FibContext );
4471+}
4472+
4473+
4474diff -burN linux-2.4.9/drivers/scsi/aacraid/commsup.c linux/drivers/scsi/aacraid/commsup.c
4475--- linux-2.4.9/drivers/scsi/aacraid/commsup.c Wed Dec 31 18:00:00 1969
4476+++ linux/drivers/scsi/aacraid/commsup.c Thu Aug 16 13:41:30 2001
4477@@ -0,0 +1,2185 @@
4478+/*++
4479+ * Adaptec aacraid device driver for Linux.
4480+ *
4481+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
4482+ *
4483+ * This program is free software; you can redistribute it and/or modify
4484+ * it under the terms of the GNU General Public License as published by
4485+ * the Free Software Foundation; either version 2, or (at your option)
4486+ * any later version.
4487+ *
4488+ * This program is distributed in the hope that it will be useful,
4489+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4490+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4491+ * GNU General Public License for more details.
4492+ *
4493+ * You should have received a copy of the GNU General Public License
4494+ * along with this program; see the file COPYING. If not, write to
4495+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
4496+ *
4497+ * Module Name:
4498+ * commsup.c
4499+ *
4500+ * Abstract: Contain all routines that are required for FSA host/adapter
4501+ * commuication.
4502+ *
4503+ *
4504+ --*/
4505+
4506+static char *ident_commsup = "aacraid_ident commsup.c 1.0.7 2000/10/11 Adaptec, Inc.";
4507+
4508+#include "comprocs.h"
4509+
4510+#define BugCheckFileId (FSAFS_BUG_CHECK_COMMSUP)
4511+
4512+int CommPrinting;
4513+
4514+void
4515+ThrottleExceptionHandler(
4516+ IN PCOMM_REGION CommRegion,
4517+ AAC_STATUS Status
4518+ );
4519+
4520+void ThrottlePeriodEndDpcRtn(
4521+ IN PKDPC Dpc,
4522+ IN PVOID DeferredContext,
4523+ IN PVOID SystemArgument1,
4524+ IN PVOID SystemArgument2
4525+ );
4526+
4527+
4528+/*++
4529+
4530+Routine Description:
4531+
4532+ This routine will free all resources used by a given FibContextSegment.
4533+
4534+Arguments:
4535+
4536+ Adapter - The adapter that this COMM_FIB_CONTEXT will communicate with.
4537+ ZoneSegment - The segment to release resources from.
4538+
4539+Return Value:
4540+
4541+ TRUE - All resources were properly freed.
4542+ FALSE - An Error occured while freeing resources.
4543+
4544+--*/
4545+BOOLEAN
4546+FsaFreeFibContextSegment (PAFA_COMM_ADAPTER Adapter,
4547+ PFIB_CONTEXT_ZONE_SEGMENT ZoneSegment)
4548+{
4549+ PCOMM_FIB_CONTEXT FibContext;
4550+ int i;
4551+
4552+ // Account for the ZONE_SEGMENT_HEADER before the first actual FibContext.
4553+
4554+ for (i = 0, FibContext = (PCOMM_FIB_CONTEXT)((PUCHAR)ZoneSegment->FibContextSegment + sizeof(ZONE_SEGMENT_HEADER));
4555+ i < ZoneSegment->ExtendSize; i++, FibContext++) {
4556+
4557+ OsCvLockDestroy( FibContext->FsaEventMutex );
4558+ OsCv_destroy( &FibContext->FsaEvent );
4559+
4560+ }
4561+
4562+ UnmapAndFreeFibSpace( Adapter, &ZoneSegment->MapFibContext );
4563+
4564+ OsFreeMemory( ZoneSegment->FibContextSegment, ZoneSegment->FibContextSegmentSize );
4565+
4566+ OsFreeMemory( ZoneSegment, sizeof( FIB_CONTEXT_ZONE_SEGMENT ) );
4567+
4568+ return (TRUE);
4569+}
4570+
4571+BOOLEAN
4572+FsaFreeFibContextZone(
4573+ PAFA_COMM_ADAPTER Adapter
4574+ )
4575+/*++
4576+
4577+Routine Description:
4578+
4579+ This routine will walk through the FibContextSegmentList and free up all
4580+ resources used by the FibContextZone.
4581+
4582+Arguments:
4583+
4584+ Adapter - The adapter that this COMM_FIB_CONTEXT will communicate with.
4585+
4586+Return Value:
4587+
4588+ TRUE - All resources were properly freed.
4589+ FALSE - An Error occured while freeing resources.
4590+
4591+--*/
4592+
4593+{
4594+ PFIB_CONTEXT_ZONE_SEGMENT ZoneSegment, NextZoneSegment;
4595+
4596+ ZoneSegment = Adapter->FibContextSegmentList;
4597+
4598+ while (ZoneSegment) {
4599+
4600+ NextZoneSegment = ZoneSegment->Next;
4601+
4602+ FsaFreeFibContextSegment( Adapter, ZoneSegment );
4603+
4604+ ZoneSegment = NextZoneSegment;
4605+ }
4606+
4607+ return (TRUE);
4608+}
4609+
4610+
4611+
4612+BOOLEAN
4613+FsaExtendFibContextZone (IN PAFA_COMM_ADAPTER Adapter)
4614+{
4615+ int ExtendSize;
4616+ KIRQL SavedIrql;
4617+ ULONG ZoneSegmentAllocSize, FibAllocSize;
4618+ PVOID FibContextSegment;
4619+ PCOMM_FIB_CONTEXT FibContext;
4620+ PFIB Fib;
4621+ PVOID FibPhysicalAddress;
4622+ int i;
4623+ PFIB_CONTEXT_ZONE_SEGMENT ZoneSegment;
4624+
4625+ //
4626+ // Allocate space to describe this zone segment.
4627+ //
4628+
4629+ cmn_err (CE_DEBUG, "Entered FsaExtendFibContextZone");
4630+ ZoneSegment = OsAllocMemory( sizeof( FIB_CONTEXT_ZONE_SEGMENT ), OS_ALLOC_MEM_SLEEP );
4631+ if (ZoneSegment == NULL) {
4632+ return (FALSE);
4633+ }
4634+
4635+ ExtendSize = Adapter->FibContextZoneExtendSize;
4636+ ZoneSegmentAllocSize = (ExtendSize * sizeof(COMM_FIB_CONTEXT)) + sizeof(ZONE_SEGMENT_HEADER);
4637+
4638+ FibContextSegment = OsAllocMemory( ZoneSegmentAllocSize, OS_ALLOC_MEM_SLEEP );
4639+
4640+ if (FibContextSegment == NULL) {
4641+ OsFreeMemory(ZoneSegment);
4642+ return (FALSE);
4643+ }
4644+
4645+ RtlZeroMemory( FibContextSegment, ZoneSegmentAllocSize );
4646+
4647+ ZoneSegment->FibContextSegment = FibContextSegment;
4648+ ZoneSegment->FibContextSegmentSize = ZoneSegmentAllocSize;
4649+ ZoneSegment->ExtendSize = ExtendSize;
4650+
4651+ FibAllocSize = ExtendSize * sizeof(FIB);
4652+
4653+
4654+ ZoneSegment->MapFibContext.Size = FibAllocSize;
4655+
4656+ AllocateAndMapFibSpace( Adapter, &ZoneSegment->MapFibContext );
4657+
4658+ Fib = ZoneSegment->MapFibContext.FibVirtualAddress;
4659+ FibPhysicalAddress = ZoneSegment->MapFibContext.FibPhysicalAddress;
4660+
4661+ RtlZeroMemory( Fib, FibAllocSize );
4662+
4663+ // Account for the ZONE_SEGMENT_HEADER before the first actual FibContext.
4664+
4665+ for (i = 0, FibContext = (PCOMM_FIB_CONTEXT)((PUCHAR)FibContextSegment + sizeof(ZONE_SEGMENT_HEADER));
4666+ i < ExtendSize; i++, FibContext++) {
4667+
4668+ FibContext->Adapter = Adapter;
4669+
4670+ FibContext->Fib = Fib;
4671+ FibContext->FibData = (PVOID) FibContext->Fib->data;
4672+
4673+ OsCv_init( &FibContext->FsaEvent);
4674+ FibContext->FsaEventMutex = OsCvLockAlloc();
4675+ OsCvLockInit( FibContext->FsaEventMutex, Adapter->SpinLockCookie );
4676+
4677+ Fib->Header.XferState = 0xffffffff;
4678+ Fib->Header.SenderSize = sizeof(FIB);
4679+
4680+ FibContext->LogicalFibAddress.LowPart = (ULONG) FibPhysicalAddress;
4681+
4682+ Fib = (PFIB)((PUCHAR)Fib + sizeof(FIB));
4683+ FibPhysicalAddress = (PVOID)((PUCHAR)FibPhysicalAddress + sizeof(FIB));
4684+ }
4685+
4686+ //
4687+ // If FibContextZone.TotalSegmentSize is non-zero, then a zone has already been
4688+ // initialized, we just need to extend it.
4689+ //
4690+
4691+ if (Adapter->FibContextZone.TotalSegmentSize) {
4692+
4693+ OsSpinLockAcquire( Adapter->FibContextZoneSpinLock );
4694+
4695+ ExExtendZone( &Adapter->FibContextZone,
4696+ FibContextSegment,
4697+ ZoneSegmentAllocSize );
4698+
4699+ OsSpinLockRelease( Adapter->FibContextZoneSpinLock );
4700+
4701+ } else {
4702+
4703+ if (ExInitializeZone( &Adapter->FibContextZone,
4704+ sizeof(COMM_FIB_CONTEXT),
4705+ FibContextSegment,
4706+ ZoneSegmentAllocSize ) != STATUS_SUCCESS)
4707+ FsaBugCheck(0,0,0);
4708+
4709+ }
4710+
4711+ //
4712+ // Add this segment to the adapter's list of segments
4713+ //
4714+
4715+ ZoneSegment->Next = Adapter->FibContextSegmentList;
4716+ Adapter->FibContextSegmentList = ZoneSegment;
4717+
4718+ return (TRUE);
4719+}
4720+
4721+
4722+
4723+/*++
4724+
4725+Routine Description:
4726+
4727+ This routine creates a new COMM_FIB_CONTEXT record
4728+
4729+Arguments:
4730+
4731+ Adapter - The adapter that this COMM_FIB_CONTEXT will communicate with.
4732+
4733+Return Value:
4734+
4735+ PCOMM_FIB_CONTEXT - returns a pointer to the newly allocate COMM_FIB_CONTEXT Record
4736+
4737+--*/
4738+PFIB_CONTEXT
4739+AllocateFib (IN PVOID AdapterArg)
4740+{
4741+ PAFA_COMM_ADAPTER Adapter = (PAFA_COMM_ADAPTER) AdapterArg;
4742+ KIRQL SavedIrql;
4743+ PCOMM_FIB_CONTEXT FibContext;
4744+ int FullZoneLoopCounter = 0;
4745+
4746+
4747+ //
4748+ // Acquire the zone spin lock, and check to see if the zone is full.
4749+ // If it is, then release the spin lock and allocate more fibs for the
4750+ // zone. The ExtendFibZone routine will re-acquire the spin lock to add
4751+ // the new fibs onto the zone.
4752+ //
4753+
4754+ OsSpinLockAcquire( Adapter->FibContextZoneSpinLock );
4755+
4756+ while (ExIsFullZone( &Adapter->FibContextZone )) {
4757+
4758+ if (++FullZoneLoopCounter > 10)
4759+ FsaBugCheck(0,0,0);
4760+
4761+ OsSpinLockRelease( Adapter->FibContextZoneSpinLock );
4762+
4763+ // bmb debug
4764+ cmn_err (CE_DEBUG, "Extending FibContextZone");
4765+ if (FsaExtendFibContextZone(Adapter) == FALSE) {
4766+ return (NULL);
4767+ }
4768+
4769+ OsSpinLockAcquire( Adapter->FibContextZoneSpinLock );
4770+
4771+ }
4772+
4773+ //
4774+ // At this point we now know that the zone has at least one more
4775+ // IRP context record available. So allocate from the zone and
4776+ // then release the mutex.
4777+ //
4778+
4779+ FibContext = (PCOMM_FIB_CONTEXT) ExAllocateFromZone( &Adapter->FibContextZone );
4780+
4781+ OsSpinLockRelease( Adapter->FibContextZoneSpinLock );
4782+
4783+ //
4784+ // Set the proper node type code and node byte size
4785+ //
4786+
4787+ FibContext->NodeTypeCode = FSAFS_NTC_FIB_CONTEXT;
4788+ FibContext->NodeByteSize = sizeof( COMM_FIB_CONTEXT );
4789+
4790+ //
4791+ // Null out fields that depend on being zero at the start of each I/O
4792+ //
4793+
4794+ FibContext->Fib->Header.XferState = 0;
4795+ FibContext->FibCallback = NULL;
4796+ FibContext->FibCallbackContext = NULL;
4797+
4798+
4799+ //
4800+ // return and tell the caller
4801+ //
4802+
4803+ return ((PFIB_CONTEXT) FibContext);
4804+}
4805+
4806+
4807+/*++
4808+
4809+Routine Description:
4810+
4811+ This routine deallocates and removes the specified COMM_FIB_CONTEXT record
4812+ from the Fsafs in memory data structures. It should only be called
4813+ by FsaCompleteRequest.
4814+
4815+Arguments:
4816+
4817+ FibContext - Supplies the COMM_FIB_CONTEXT to remove
4818+
4819+Return Value:
4820+
4821+ None
4822+
4823+--*/
4824+VOID
4825+FreeFib (IN PFIB_CONTEXT Context)
4826+{
4827+ KIRQL SavedIrql;
4828+ PCOMM_FIB_CONTEXT FibContext = Context;
4829+
4830+ ASSERT(FibContext->NodeTypeCode == FSAFS_NTC_FIB_CONTEXT);
4831+
4832+ OsSpinLockAcquire( FibContext->Adapter->FibContextZoneSpinLock );
4833+
4834+ if (FibContext->Flags & FIB_CONTEXT_FLAG_TIMED_OUT) {
4835+
4836+ FsaCommData.TimedOutFibs++;
4837+
4838+ FibContext->Next = FibContext->Adapter->FibContextTimedOutList;
4839+ FibContext->Adapter->FibContextTimedOutList = FibContext;
4840+
4841+ } else {
4842+
4843+ ASSERT(FibContext->Fib->Header.XferState == 0);
4844+
4845+ if (FibContext->Fib->Header.XferState != 0) {
4846+ cmn_err(CE_WARN, "FreeFib, XferState != 0, FibContext = 0x%x, XferState = 0x%x\n",
4847+ FibContext, FibContext->Fib->Header.XferState);
4848+ }
4849+
4850+ ExFreeToZone( &FibContext->Adapter->FibContextZone, FibContext );
4851+
4852+ }
4853+
4854+ OsSpinLockRelease( FibContext->Adapter->FibContextZoneSpinLock );
4855+
4856+ //
4857+ // return and tell the caller
4858+ //
4859+
4860+ return;
4861+}
4862+
4863+
4864+/*++
4865+
4866+Routine Description:
4867+
4868+ This routine deallocates and removes the specified COMM_FIB_CONTEXT record
4869+ from the Fsafs in memory data structures. It should only be called
4870+ from the dpc routines to from dpc to free an FibContext from an async or
4871+ no response io
4872+
4873+Arguments:
4874+
4875+ FibContext - Supplies the COMM_FIB_CONTEXT to remove
4876+
4877+Return Value:
4878+
4879+ None
4880+
4881+--*/
4882+VOID
4883+FreeFibFromDpc (IN PFIB_CONTEXT Context)
4884+{
4885+ PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
4886+
4887+ ASSERT(FibContext->NodeTypeCode == FSAFS_NTC_FIB_CONTEXT);
4888+
4889+ OsSpinLockAcquire(FibContext->Adapter->FibContextZoneSpinLock);
4890+
4891+ if (FibContext->Flags & FIB_CONTEXT_FLAG_TIMED_OUT) {
4892+
4893+ FsaCommData.TimedOutFibs++;
4894+
4895+ FibContext->Next = FibContext->Adapter->FibContextTimedOutList;
4896+ FibContext->Adapter->FibContextTimedOutList = FibContext;
4897+
4898+ } else {
4899+
4900+ ASSERT(FibContext->Fib->Header.XferState == 0);
4901+
4902+ if (FibContext->Fib->Header.XferState != 0) {
4903+ cmn_err(CE_WARN, "FreeFibFromDpc, XferState != 0, FibContext = 0x%x, XferState = 0x%x\n",
4904+ FibContext, FibContext->Fib->Header.XferState);
4905+ }
4906+
4907+
4908+ ExFreeToZone( &FibContext->Adapter->FibContextZone, FibContext );
4909+
4910+ }
4911+
4912+ OsSpinLockRelease(FibContext->Adapter->FibContextZoneSpinLock);
4913+
4914+ //
4915+ // return and tell the caller
4916+ //
4917+
4918+ return;
4919+}
4920+
4921+
4922+/*++
4923+
4924+Routine Description:
4925+
4926+ Will initialize a FIB of the requested size.
4927+
4928+Arguments:
4929+
4930+ Fib is a pointer to a location which will receive the address of the allocated
4931+ FIB.
4932+
4933+ Size is the size of the Fib to allocate.
4934+
4935+Return Value:
4936+
4937+ NT_SUCCESS if a Fib was returned to the caller.
4938+ NT_ERROR if event was an invalid event.
4939+
4940+--*/
4941+AAC_STATUS
4942+InitializeFib (IN PFIB_CONTEXT Context)
4943+{
4944+ PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
4945+ PFIB Fib = FibContext->Fib;
4946+
4947+ Fib->Header.StructType = TFib;
4948+ Fib->Header.Size = sizeof(FIB);
4949+// if (Fib->Header.XferState & AllocatedFromPool)
4950+// Fib->Header.XferState = HostOwned | FibInitialized | FibEmpty | AllocatedFromPool;
4951+// else
4952+ Fib->Header.XferState = HostOwned | FibInitialized | FibEmpty | FastResponseCapable;
4953+ Fib->Header.SenderFibAddress = 0;
4954+ Fib->Header.ReceiverFibAddress = 0;
4955+ Fib->Header.SenderSize = sizeof(FIB);
4956+
4957+ return(STATUS_SUCCESS);
4958+}
4959+
4960+
4961+/*++
4962+
4963+Routine Description:
4964+
4965+ Will allocate and initialize a FIB of the requested size and return a
4966+ pointer to the structure. The size allocated may be larger than the size
4967+ requested due to allocation performace optimizations.
4968+
4969+Arguments:
4970+
4971+ Fib is a pointer to a location which will receive the address of the allocated
4972+ FIB.
4973+
4974+ Size is the size of the Fib to allocate.
4975+
4976+ JustInitialize is a boolean which indicates a Fib has been allocated most likly in an
4977+ imbedded structure the FS always allocates. So just initiaize it and return.
4978+
4979+Return Value:
4980+
4981+ NT_SUCCESS if a Fib was returned to the caller.
4982+ NT_ERROR if event was an invalid event.
4983+
4984+--*/
4985+AAC_STATUS
4986+AllocatePoolFib (OUT PFIB *Fib, IN USHORT Size)
4987+{}
4988+
4989+
4990+/*++
4991+
4992+Routine Description:
4993+
4994+ Will deallocate and return to the free pool the FIB pointed to by the
4995+ caller. Upon return accessing locations pointed to by the FIB parameter
4996+ could cause system access faults.
4997+
4998+Arguments:
4999+
5000+ Fib is a pointer to the FIB that caller wishes to deallocate.
5001+
5002+Return Value:
5003+
5004+ NT_SUCCESS if a Fib was returned to the caller.
5005+ NT_ERROR if event was an invalid event.
5006+
5007+--*/
5008+AAC_STATUS
5009+DeallocateFib (PFIB_CONTEXT Context)
5010+{
5011+ PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
5012+ PFIB Fib = FibContext->Fib;
5013+
5014+ if ( Fib->Header.StructType != TFib ) {
5015+ FsaCommPrint("Error CompleteFib called with a non Fib structure.\n");
5016+ return(STATUS_UNSUCCESSFUL);
5017+ }
5018+
5019+
5020+ Fib->Header.XferState = 0;
5021+
5022+ return(STATUS_SUCCESS);
5023+
5024+}
5025+
5026+
5027+AAC_STATUS
5028+GetResponse(
5029+ IN PCOMM_QUE ResponseQueue,
5030+ OUT PFIB Fib
5031+ )
5032+/*++
5033+
5034+Routine Description:
5035+
5036+ Gets a QE off the requested response queue and gets the response FIB into
5037+ host memory. The FIB may already be in host memory depending on the bus
5038+ interface, or may require the host to DMA it over from the adapter. The routine
5039+ will return the FIB to the caller.
5040+
5041+Arguments:
5042+
5043+ ResponseQueue - Is the queue the caller wishes to have the response gotten from.
5044+ Fib - Is the Fib which was the response from the adapter
5045+
5046+Return Value:
5047+
5048+ NT_SUCCESS if a Fib was returned to the caller.
5049+ NT_ERROR if there was no Fib to return to the caller.
5050+ bkpfix - add in all the other possible errors ect
5051+
5052+--*/
5053+{
5054+return(STATUS_UNSUCCESSFUL);
5055+}
5056+
5057+//
5058+// Commuication primitives define and support the queuing method we use to
5059+// support host to adapter commuication. All queue accesses happen through
5060+// these routines and are the only routines which have a knowledge of the
5061+// how these queues are implemented.
5062+//
5063+
5064+
5065+/*++
5066+
5067+Routine Description:
5068+
5069+ With a priority the routine returns a queue entry if the queue has free entries. If the queue
5070+ is full(no free entries) than no entry is returned and the function returns FALSE otherwise TRUE is
5071+ returned.
5072+
5073+Arguments:
5074+
5075+ Priority is an enumerated type which determines which priority level
5076+ command queue the QE is going to be queued on.
5077+
5078+ Entry is a pointer to the address of where to return the address of
5079+ the queue entry from the requested command queue.
5080+
5081+ Index is a pointer to the address of where to store the index of the new
5082+ queue entry returned.
5083+
5084+ DontInterrupt - We set this true if the queue state is such that we don't
5085+ need to interrupt the adapter for this queue entry.
5086+
5087+Return Value:
5088+
5089+ TRUE - If a queue entry is returned
5090+ FALSE - If there are no free queue entries on the requested command queue.
5091+
5092+--*/
5093+BOOLEAN
5094+GetEntry (IN PAFA_COMM_ADAPTER Adapter, IN QUEUE_TYPES WhichQueue,
5095+ OUT PQUEUE_ENTRY *Entry, OUT PQUEUE_INDEX Index,
5096+ OUT ULONG *DontInterrupt)
5097+{
5098+ ULONG QueueOffset;
5099+ BOOLEAN status;
5100+ PCOMM_REGION CommRegion;
5101+
5102+ CommRegion = Adapter->CommRegion;
5103+
5104+ //
5105+ // All of the queues wrap when they reach the end, so we check to see if they
5106+ // have reached the end and if they have we just set the index back to zero.
5107+ // This is a wrap. You could or off the high bits in all updates but this is
5108+ // a bit faster I think.
5109+ //
5110+
5111+ if (WhichQueue == AdapHighCmdQueue) {
5112+ *Index = *(CommRegion->AdapHighCmdQue.Headers.ProducerIndex);
5113+
5114+ if (*Index - 2 == *(CommRegion->AdapHighCmdQue.Headers.ConsumerIndex))
5115+ *DontInterrupt = TRUE;
5116+
5117+ if (*Index >= ADAP_HIGH_CMD_ENTRIES)
5118+ *Index = 0;
5119+
5120+ if (*Index + 1 == *(CommRegion->AdapHighCmdQue.Headers.ConsumerIndex)) { // Queue is full
5121+ status = FALSE;
5122+ cmn_err(CE_WARN, "Adapter High Command Queue full, %d outstanding",
5123+ CommRegion->AdapHighCmdQue.NumOutstandingIos);
5124+ } else {
5125+ QueueOffset = sizeof(QUEUE_ENTRY) * (*Index);
5126+ *Entry = QueueOffset + CommRegion->AdapHighCmdQue.BaseAddress;
5127+
5128+ status = TRUE;
5129+ }
5130+ } else if (WhichQueue == AdapNormCmdQueue) {
5131+
5132+ *Index = *(CommRegion->AdapNormCmdQue.Headers.ProducerIndex);
5133+
5134+ if (*Index - 2 == *(CommRegion->AdapNormCmdQue.Headers.ConsumerIndex))
5135+ *DontInterrupt = TRUE;
5136+
5137+ //
5138+ // If we are at the end of the QUEUE then wrap back to
5139+ // the beginning.
5140+ //
5141+
5142+ if (*Index >= ADAP_NORM_CMD_ENTRIES)
5143+ *Index = 0; // Wrap to front of the Producer Queue.
5144+
5145+ //
5146+ // The IEEE spec says that it the producer is one behind the consumer then
5147+ // the queue is full.
5148+ //
5149+
5150+ ASSERT(*(CommRegion->AdapNormCmdQue.Headers.ConsumerIndex) != 0);
5151+
5152+ if (*Index + 1 == *(CommRegion->AdapNormCmdQue.Headers.ConsumerIndex)) { // Queue is full
5153+ cmn_err(CE_WARN, "Adapter Norm Command Queue full, %d outstanding",
5154+ CommRegion->AdapNormCmdQue.NumOutstandingIos);
5155+ status = FALSE;
5156+ } else {
5157+ //
5158+ // The success case just falls through and returns the a valid queue entry.
5159+ //
5160+
5161+#ifdef commdebug
5162+ FsaCommPrint("queue entry = %x.\n",CommRegion->AdapNormCmdQue.BaseAddress + *Index);
5163+ FsaCommPrint("GetEntry: Index = %d, QueueOffset = %x, Entry = %x, *Entry = %x.\n",
5164+ *Index, QueueOffset, Entry, *Entry);
5165+#endif
5166+ *Entry = CommRegion->AdapNormCmdQue.BaseAddress + *Index;
5167+
5168+ status = TRUE;
5169+ }
5170+ } else if (WhichQueue == AdapHighRespQueue) {
5171+
5172+ *Index = *(CommRegion->AdapHighRespQue.Headers.ProducerIndex);
5173+
5174+ if (*Index - 2 == *(CommRegion->AdapHighRespQue.Headers.ConsumerIndex))
5175+ *DontInterrupt = TRUE;
5176+
5177+ if (*Index >= ADAP_HIGH_RESP_ENTRIES)
5178+ *Index = 0;
5179+
5180+ if (*Index + 1 == *(CommRegion->AdapHighRespQue.Headers.ConsumerIndex)) { // Queue is full
5181+ status = FALSE;
5182+ cmn_err(CE_WARN, "Adapter High Resp Queue full, %d outstanding",
5183+ CommRegion->AdapHighRespQue.NumOutstandingIos);
5184+ } else {
5185+ *Entry = CommRegion->AdapHighRespQue.BaseAddress + *Index;
5186+ status = TRUE;
5187+ }
5188+ } else if (WhichQueue == AdapNormRespQueue) {
5189+
5190+ *Index = *(CommRegion->AdapNormRespQue.Headers.ProducerIndex);
5191+
5192+ if (*Index - 2 == *(CommRegion->AdapNormRespQue.Headers.ConsumerIndex))
5193+ *DontInterrupt = TRUE;
5194+
5195+ //
5196+ // If we are at the end of the QUEUE then wrap back to
5197+ // the beginning.
5198+ //
5199+
5200+ if (*Index >= ADAP_NORM_RESP_ENTRIES)
5201+ *Index = 0; // Wrap to front of the Producer Queue.
5202+
5203+ //
5204+ // The IEEE spec says that it the producer is one behind the consumer then
5205+ // the queue is full.
5206+ //
5207+
5208+ if (*Index + 1 == *(CommRegion->AdapNormRespQue.Headers.ConsumerIndex)) { // Queue is full
5209+ status = FALSE;
5210+ cmn_err(CE_WARN, "Adapter Norm Resp Queue full, %d outstanding",
5211+ CommRegion->AdapNormRespQue.NumOutstandingIos);
5212+ } else {
5213+ //
5214+ // The success case just falls through and returns the a valid queue entry.
5215+ //
5216+
5217+ *Entry = CommRegion->AdapNormRespQue.BaseAddress + *Index;
5218+
5219+#ifdef commdebug
5220+ FsaCommPrint("queue entry = %x.\n",CommRegion->AdapNormRespQue.BaseAddress + *Index);
5221+ FsaCommPrint("GetEntry: Index = %d, Entry = %x, *Entry = %x.\n",*Index, Entry, *Entry);
5222+#endif
5223+ status = TRUE;
5224+ }
5225+ } else {
5226+ cmn_err(CE_PANIC, "GetEntry: invalid queue %d", WhichQueue);
5227+ }
5228+
5229+
5230+ return (status);
5231+}
5232+
5233+
5234+
5235+#ifdef API_THROTTLE
5236+
5237+void ThrottleCheck(
5238+ IN PAFA_COMM_ADAPTER Adapter,
5239+ IN PFIB Fib
5240+ )
5241+/*++
5242+
5243+Routine Description:
5244+
5245+ This routine implements data I/O throttling. Throttling occurs when
5246+ a CLI FIB is detected. To ensure the CLI responds quickly (the user
5247+ is waiting for the response), this mechanism restricts the queue
5248+ depth of data IOs at the adapter for a period of time (called the
5249+ Throttle Period, default 5 seconds).
5250+
5251+ The mechanism uses a counted semaphore to place threads into a wait
5252+ state should there be too many data I/Os outstanding.
5253+
5254+ At the start of a throttle period (indicated by the first CLI FIB)
5255+ a timer is started. When the timer expires, new requests can go to
5256+ the adapter freely. Throttled requests gradually drain to the
5257+ adapter as each outstanding throttle I/O completes.
5258+
5259+ To avoid hurting regular I/O performance, we use a flag in the FIB
5260+ header to mark FIBs involved in throttling. This means we only need
5261+ take the extra spinlock in the response DPC routine for FIBs who
5262+ were subject to throttling. If no throttling is occurring, the cost
5263+ to the regular code paths is a handful of instructions.
5264+
5265+Arguments:
5266+
5267+ Adapter - Pointer to per-adapter context. This is used to locate the
5268+ throttle information for this adapter.
5269+
5270+ Fib - Pointer to the header for the fib being sent.
5271+
5272+Return Value:
5273+
5274+ None.
5275+
5276+--*/
5277+{
5278+ PCOMM_REGION CommRegion = Adapter->CommRegion;
5279+ AAC_STATUS Status;
5280+
5281+ //
5282+ // This routine is called under protection of the queue spinlock.
5283+ // As such we are allowed to check and change the counts for the
5284+ // throttle.
5285+ // Check the FIB. If its not a data operation, send it on without
5286+ // throttle check. If it is a data operation, check for throttle.
5287+ //
5288+
5289+ CommRegion->TotalFibs++; // Keep statistics
5290+
5291+ if ((Fib->Header.XferState & ApiFib) != 0) {
5292+
5293+ CommRegion->ApiFibs++; // Keep statistics
5294+
5295+ //
5296+ // Its an API fib. If the throttle is not already active,
5297+ // make it so. This will prevent new data Fibs being sent
5298+ // if they exceed the throttle check.
5299+ //
5300+
5301+ if (!CommRegion->ThrottleActive) {
5302+ BOOLEAN InQue;
5303+
5304+ CommRegion->ThrottleActive = TRUE; // This causes new data I/Os to be throttled
5305+
5306+ //
5307+ // Schedule a timer for the throttle active period. When
5308+ // it expires, we'll be called back at routine ThrottleDpcRoutine
5309+ // above. This will signify the throttle active period ended
5310+ // and any waiting threads will be signalled to restart.
5311+ //
5312+
5313+ FsaCommPrint("Throttle Period Start - CommRegion: %x\n", CommRegion);
5314+ CommRegion->ThrottleTimerSets++;
5315+ InQue = KeSetTimer( &CommRegion->ThrottleTimer,
5316+ CommRegion->ThrottleTimeout,
5317+ &CommRegion->ThrottleDpc);
5318+ ASSERT(InQue == FALSE);
5319+ }
5320+
5321+ return;
5322+ }
5323+
5324+ //
5325+ // Its a non-API fib, so subject to throttle checks.
5326+ // The following are exempt from throttling:
5327+ // o FIBs marked as "throttle exempt" by upper layers.
5328+ // o I/Os issued from a raised IRQL. We can't suspend
5329+ // a thread when at raised IRQL so throttling is exempt.
5330+ //
5331+
5332+ if (CommRegion->AdapNormCmdQue.SavedIrql != PASSIVE_LEVEL) {
5333+
5334+ CommRegion->NonPassiveFibs++;
5335+ FsaCommPrint("ThrottleCheck: Non-Passive level FIB bypasses throttle: %x\n", Fib);
5336+ return;
5337+
5338+ }
5339+
5340+ if (CommRegion->ThrottleActive) {
5341+
5342+ //
5343+ // Throttle is active.
5344+ // Check if the FIB is a read or write. If so, and its to the
5345+ // file system information area, let it through without throttling.
5346+ //
5347+
5348+ if (Fib->Header.Command == ContainerCommand) {
5349+ PBLOCKREAD BlockDisk = (PBLOCKREAD) &Fib->data;
5350+
5351+ //
5352+ // *** Note *** We are using read and write command formats
5353+ // interchangably here. This is ok for this purpose as the
5354+ // command is in the same place for both. Read and write command
5355+ // formats are different at higher offsets though.
5356+ //
5357+
5358+ if ( ((BlockDisk->Command == VM_CtBlockRead) ||
5359+ (BlockDisk->Command == VM_CtBlockWrite)) &&
5360+ (BlockDisk->BlockNumber <= FILESYSTEM_INFO_MAX_BLKNO)) {
5361+
5362+ CommRegion->FSInfoFibs++; // Keep statistics
5363+ return;
5364+
5365+ }
5366+
5367+ }
5368+
5369+ //
5370+ // Throttle the FIB.
5371+ // Mark it as throttle active so that it can signal a waiter
5372+ // when it completes.
5373+
5374+ CommRegion->ThrottledFibs++;
5375+ Fib->Header.Flags |= ThrottledFib;
5376+
5377+ //
5378+ // Release the spinlock so we can wait the thread if necessary.
5379+ // Since we specify a timeout, check the caller is at passive level.
5380+ //
5381+
5382+ OsSpinLockRelease((CommRegion->AdapNormCmdQue.QueueLock), CommRegion->AdapNormCmdQue.SavedIrql);
5383+
5384+ FsaCommPrint("ThrottleCheck - Thread Suspension - FIB: %x\n", Fib);
5385+
5386+ Status = KeWaitForSingleObject(&CommRegion->ThrottleReleaseSema,
5387+ Executive, // Don't allow user APCs to wake us
5388+ KernelMode, // Wait in kernel mode
5389+ FALSE, // Not alertable
5390+ &CommRegion->ThrottleWaitTimeout); // Timeout after this time
5391+
5392+ //
5393+ // Check the signal status. If we've timed out, clear the throttle
5394+ // flag on the FIB to avoid us signalling the semaphore on completion.
5395+ // We never acquired the semaphore.
5396+ //
5397+ if (Status == STATUS_TIMEOUT) {
5398+
5399+ CommRegion->ThrottleTimedoutFibs++;
5400+ FsaCommPrint("ThrottledFib Timed Out - FIB: %x\n", Fib);
5401+ Fib->Header.Flags &= ~ThrottledFib; // Clear the throttledfib flag
5402+
5403+ } else {
5404+
5405+ ASSERT(Status == STATUS_SUCCESS); // No other return is possible
5406+
5407+ }
5408+
5409+ //
5410+ // We've been woken up and can now send the FIB to the adapter.
5411+ // Acquire the spinlock again so we can get a queue entry. This
5412+ // returns to GetQueueEntry.
5413+ //
5414+
5415+ FsaCommPrint("ThrottleCheck - Thread Resume - FIB: %x\n", Fib);
5416+ KeAcquireSpinLock((CommRegion->AdapNormCmdQue.QueueLock), &(CommRegion->AdapNormCmdQue.SavedIrql));
5417+ CommRegion->ThrottleOutstandingFibs++; // There's another throttle controlled FIB going.
5418+ return;
5419+
5420+ }
5421+}
5422+
5423+#endif //#ifdef API_THROTTLE
5424+
5425+int GetQueueEntryTimeouts = 0;
5426+
5427+
5428+/*++
5429+
5430+Routine Description:
5431+
5432+ Gets the next free QE off the requested priorty adapter command queue and
5433+ associates the Fib with the QE. The QE represented by index is ready to
5434+ insert on the queue when this routine returns success.
5435+
5436+Arguments:
5437+
5438+ Index is the returned value which represents the QE which is ready to
5439+ insert on the adapter's command queue.
5440+
5441+ Priority is an enumerated type which determines which priority level
5442+ command queue the QE is going to be queued on.
5443+
5444+ Fib is a pointer to the FIB the caller wishes to have associated with the
5445+ QE.
5446+
5447+ Wait is a boolean which determines if the routine will wait if there are
5448+ no free QEs on the requested priority command queue.
5449+
5450+ FibContext is where the driver stores all system resources required to execute the
5451+ command requested from the calling thread. This includes mapping resources for
5452+ the FIB and the 'users' buffer.
5453+
5454+ DontInterrupt - We set this true if the queue state is such that we don't
5455+ need to interrupt the adapter for this queue entry.
5456+
5457+Return Value:
5458+
5459+ NT_SUCCESS if a Fib was returned to the caller.
5460+ NT_ERROR if event was an invalid event.
5461+
5462+--*/
5463+AAC_STATUS
5464+GetQueueEntry (IN PAFA_COMM_ADAPTER Adapter, OUT PQUEUE_INDEX Index,
5465+ IN QUEUE_TYPES WhichQueue, IN PFIB Fib, IN BOOLEAN Wait,
5466+ IN PCOMM_FIB_CONTEXT FibContext, OUT ULONG *DontInterrupt)
5467+{
5468+ PQUEUE_ENTRY QueueEntry = NULL;
5469+ BOOLEAN MapAddress = FALSE;
5470+ int timeouts = 0;
5471+ AAC_STATUS Status;
5472+ PCOMM_REGION CommRegion;
5473+
5474+ CommRegion = Adapter->CommRegion;
5475+
5476+ //
5477+ // Get the spinlock for the queue we are putting a command on
5478+ //
5479+
5480+ if (WhichQueue == AdapHighCmdQueue)
5481+ OsSpinLockAcquire(CommRegion->AdapHighCmdQue.QueueLock);
5482+ else if (WhichQueue == AdapNormCmdQueue)
5483+ OsSpinLockAcquire(CommRegion->AdapNormCmdQue.QueueLock);
5484+ else if (WhichQueue == AdapHighRespQueue)
5485+ OsSpinLockAcquire(CommRegion->AdapHighRespQue.QueueLock);
5486+ else if (WhichQueue == AdapNormRespQueue)
5487+ OsSpinLockAcquire(CommRegion->AdapNormRespQue.QueueLock);
5488+ else {
5489+ FsaCommPrint("Invalid queue priority passed to GetQueueEntry.\n");
5490+ return(FSA_INVALID_QUEUE);
5491+ }
5492+
5493+ //
5494+ // Get the pointers to a queue entry on the queue the caller wishes to queue
5495+ // a command request on. If there are no entries then wait if that is what the
5496+ // caller requested.
5497+ //
5498+
5499+ if (WhichQueue == AdapHighCmdQueue) {
5500+ // if no entries wait for some if caller wants to
5501+ while ( !GetEntry(Adapter, AdapHighCmdQueue, &QueueEntry, Index, DontInterrupt) ) {
5502+ cmn_err(CE_PANIC, "GetEntries failed (1)\n");
5503+ }
5504+
5505+ //
5506+ // Setup queue entry with a command, status and Fib mapped
5507+ //
5508+
5509+ QueueEntry->Size = Fib->Header.Size;
5510+ MapAddress = TRUE;
5511+
5512+ } else if (WhichQueue == AdapNormCmdQueue) {
5513+ // if no entries wait for some if caller wants to
5514+ while ( !GetEntry(Adapter, AdapNormCmdQueue, &QueueEntry, Index, DontInterrupt) ) {
5515+ cmn_err(CE_PANIC, "GetEntries failed (2)\n");
5516+ }
5517+
5518+ //
5519+ // Setup queue entry with command, status and Fib mapped
5520+ //
5521+
5522+ QueueEntry->Size = Fib->Header.Size;
5523+ MapAddress = TRUE;
5524+
5525+ } else if (WhichQueue == AdapHighRespQueue) {
5526+
5527+ while ( !GetEntry(Adapter, AdapHighRespQueue, &QueueEntry, Index, DontInterrupt) ) { // if no entries wait for some if caller wants to
5528+ }
5529+
5530+ //
5531+ // Setup queue entry with command, status and Fib mapped
5532+ //
5533+
5534+ QueueEntry->Size = Fib->Header.Size;
5535+ QueueEntry->FibAddress = Fib->Header.SenderFibAddress; // Restore adapters pointer to the FIB
5536+ Fib->Header.ReceiverFibAddress = Fib->Header.SenderFibAddress; // Let the adapter now where to find its data
5537+ MapAddress = FALSE;
5538+
5539+ } else if (WhichQueue == AdapNormRespQueue) {
5540+ while ( !GetEntry(Adapter, AdapNormRespQueue, &QueueEntry, Index, DontInterrupt) ) { // if no entries wait for some if caller wants to
5541+ }
5542+
5543+ //
5544+ // Setup queue entry with command, status, adapter's pointer to the Fib it sent
5545+ //
5546+
5547+ QueueEntry->Size = Fib->Header.Size;
5548+ QueueEntry->FibAddress = Fib->Header.SenderFibAddress; // Restore adapters pointer to the FIB
5549+ Fib->Header.ReceiverFibAddress = Fib->Header.SenderFibAddress; // Let the adapter now where to find its data
5550+ MapAddress = FALSE;
5551+ }
5552+
5553+ //
5554+ // If MapFib is true than we need to map the Fib and put pointers in the queue entry.
5555+ //
5556+
5557+ if (MapAddress) {
5558+ QueueEntry->FibAddress = (ULONG)(FibContext->LogicalFibAddress.LowPart);
5559+ }
5560+
5561+ //
5562+ // Return
5563+ //
5564+#ifdef commdebug
5565+ FsaCommPrint("Queue Entry contents:.\n");
5566+ FsaCommPrint(" Command = %d.\n", QueueEntry->Command);
5567+ FsaCommPrint(" Status = %x.\n", QueueEntry->Status);
5568+ FsaCommPrint(" Rec Fib address low = %x.\n", QueueEntry->FibAddressLow);
5569+ FsaCommPrint(" Fib size in bytes = %d.\n", QueueEntry->Size);
5570+#endif
5571+
5572+ return(FSA_SUCCESS);
5573+}
5574+
5575+
5576+/*++
5577+
5578+Routine Description:
5579+
5580+ Gets the next free QE off the requested priorty adapter command queue and
5581+ associates the Fib with the QE. The QE represented by index is ready to
5582+ insert on the queue when this routine returns success.
5583+
5584+Arguments:
5585+
5586+ Index is the returned value which represents the QE which is ready to
5587+ insert on the adapter's command queue.
5588+
5589+ WhichQueue tells us which queue the caller wishes to have the entry put.
5590+
5591+Return Value:
5592+
5593+ NT_SUCCESS if a Fib was returned to the caller.
5594+ NT_ERROR if event was an invalid event.
5595+
5596+--*/
5597+AAC_STATUS
5598+InsertQueueEntry(
5599+ IN PAFA_COMM_ADAPTER Adapter,
5600+ IN QUEUE_INDEX Index,
5601+ IN QUEUE_TYPES WhichQueue,
5602+ IN ULONG DontInterrupt
5603+ )
5604+{
5605+ PCOMM_REGION CommRegion;
5606+
5607+ CommRegion = Adapter->CommRegion;
5608+
5609+ //
5610+ // We have already verified the queue in getentry, but we still have to make
5611+ // sure we don't wrap here too.
5612+ //
5613+
5614+ if (WhichQueue == AdapHighCmdQueue) {
5615+
5616+ *(CommRegion->AdapHighCmdQue.Headers.ProducerIndex) = Index + 1;
5617+
5618+ OsSpinLockRelease(CommRegion->AdapHighCmdQue.QueueLock);
5619+
5620+ if (!DontInterrupt)
5621+ NotifyAdapter(Adapter, AdapHighCmdQue);
5622+
5623+ } else if (WhichQueue == AdapNormCmdQueue) {
5624+
5625+#ifdef commdebug
5626+ FsaCommPrint("InsertQueueEntry: Inerting with an index of %d.\n",Index);
5627+#endif
5628+ *(CommRegion->AdapNormCmdQue.Headers.ProducerIndex) = Index + 1;
5629+
5630+ OsSpinLockRelease(CommRegion->AdapNormCmdQue.QueueLock);
5631+
5632+ if (!DontInterrupt)
5633+ NotifyAdapter(Adapter, AdapNormCmdQue);
5634+
5635+ } else if (WhichQueue == AdapHighRespQueue) {
5636+
5637+ *(CommRegion->AdapHighRespQue.Headers.ProducerIndex) = Index + 1;
5638+
5639+ OsSpinLockRelease(CommRegion->AdapHighRespQue.QueueLock);
5640+
5641+ if (!DontInterrupt)
5642+ NotifyAdapter(Adapter, AdapHighRespQue);
5643+
5644+ } else if (WhichQueue == AdapNormRespQueue) {
5645+
5646+ *(CommRegion->AdapNormRespQue.Headers.ProducerIndex) = Index + 1;
5647+
5648+ OsSpinLockRelease(CommRegion->AdapNormRespQue.QueueLock);
5649+
5650+ if (!DontInterrupt)
5651+ NotifyAdapter(Adapter, AdapNormRespQue);
5652+
5653+ } else {
5654+ FsaCommPrint("Invalid queue priority passed to InsertQueueEntry.\n");
5655+ return(FSA_INVALID_QUEUE_PRIORITY);
5656+ }
5657+
5658+ return(FSA_SUCCESS);
5659+}
5660+
5661+extern int GatherFibTimes;
5662+
5663+BOOLEAN
5664+SendSynchFib(
5665+ PVOID Arg,
5666+ FIB_COMMAND Command,
5667+ PVOID Data,
5668+ USHORT Size,
5669+ PVOID Response,
5670+ USHORT *ResponseSize
5671+ )
5672+/*++
5673+
5674+Routine Description:
5675+
5676+ This routine will send a synchronous FIB to the adapter and wait for its
5677+ completion.
5678+
5679+Arguments:
5680+
5681+ DeviceExtension - Pointer to adapter extension structure.
5682+
5683+
5684+Return Value:
5685+
5686+ BOOLEAN
5687+
5688+--*/
5689+{
5690+ PAFA_COMM_ADAPTER Adapter = Arg;
5691+ FIB *Fib;
5692+ ULONG returnStatus;
5693+
5694+ Fib = Adapter->SyncFib;
5695+
5696+ Fib->Header.StructType = TFib;
5697+ Fib->Header.Size = sizeof(FIB);
5698+ Fib->Header.XferState = HostOwned | FibInitialized | FibEmpty;
5699+ Fib->Header.ReceiverFibAddress = 0;
5700+ Fib->Header.SenderSize = sizeof(FIB);
5701+ Fib->Header.SenderFibAddress = (ULONG)Fib;
5702+ Fib->Header.Command = Command;
5703+
5704+ //
5705+ // Copy the Data portion into the Fib.
5706+ //
5707+
5708+ RtlCopyMemory( Fib->data, Data, Size );
5709+
5710+
5711+ Fib->Header.XferState |= (SentFromHost | NormalPriority);
5712+
5713+ //
5714+ // Set the size of the Fib we want to send to the adapter
5715+ //
5716+
5717+ Fib->Header.Size = sizeof(FIB_HEADER) + Size;
5718+
5719+ if (!Adapter->AdapterFuncs->SendSynchFib( Adapter->AdapterExtension,
5720+ Adapter->SyncFibPhysicalAddress )) {
5721+
5722+ return (FALSE);
5723+
5724+ }
5725+
5726+ //
5727+ // Copy the response back to the caller's buffer.
5728+ //
5729+
5730+ RtlCopyMemory( Response, Fib->data, Fib->Header.Size - sizeof(FIB_HEADER) );
5731+
5732+ *ResponseSize = Fib->Header.Size - sizeof(FIB_HEADER);
5733+
5734+ //
5735+ // Indicate success
5736+ //
5737+
5738+ return (TRUE);
5739+}
5740+
5741+//
5742+// Define the highest level of host to adapter communication routines. These
5743+// routines will support host to adapter FS commuication. These routines have
5744+// no knowledge of the commuication method used. This level sends and receives
5745+// FIBs. This level has no knowledge of how these FIBs get passed back and forth.
5746+//
5747+
5748+
5749+
5750+/*++
5751+
5752+Routine Description:
5753+
5754+ Sends the requested FIB to the adapter and optionally will wait for a
5755+ response FIB. If the caller does not wish to wait for a response than
5756+ an event to wait on must be supplied. This event will be set when a
5757+ response FIB is received from the adapter.
5758+
5759+Arguments:
5760+
5761+ Fib is a pointer to the FIB the caller wishes to send to the adapter.
5762+
5763+ Size - Size of the data portion of the Fib.
5764+
5765+ Priority is an enumerated type which determines which priority level
5766+ the caller wishes to send this command at.
5767+
5768+ Wait is a boolean which determines if the routine will wait for the
5769+ completion Fib to be returned(TRUE), or return when the Fib has been
5770+ successfully received by the adapter(FALSE).
5771+
5772+ WaitOn is only vaild when Wait is FALSE. The Event will be set when the response
5773+ FIB has been returned by the adapter.
5774+
5775+ ReturnFib is an optional pointer to a FIB that if present the response FIB will
5776+ copied to.
5777+
5778+Return Value:
5779+
5780+ NT_SUCCESS if a Fib was returned to the caller.
5781+ NT_ERROR if event was an invalid event.
5782+
5783+ --*/
5784+AAC_STATUS
5785+SendFib (IN FIB_COMMAND Command,
5786+ IN PFIB_CONTEXT Context,
5787+ IN ULONG Size,
5788+ IN COMM_PRIORITIES Priority,
5789+ IN BOOLEAN Wait,
5790+ IN PVOID WaitOn,
5791+ IN BOOLEAN ResponseExpected,
5792+ IN PFIB_CALLBACK FibCallback,
5793+ IN PVOID FibCallbackContext)
5794+{
5795+ PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
5796+ QUEUE_INDEX Index;
5797+ QUEUE_TYPES WhichQueue;
5798+ LARGE_INTEGER Timeout;
5799+ AAC_STATUS Status;
5800+ PAFA_COMM_ADAPTER Adapter = FibContext->Adapter;
5801+ ULONG DontInterrupt = FALSE;
5802+ PFIB Fib = FibContext->Fib;
5803+ IN PCOMM_QUE OurQueue;
5804+
5805+ Timeout = FsaCommData.AdapterTimeout;
5806+
5807+ if (!(Fib->Header.XferState & HostOwned)) {
5808+ FsaCommPrint("SendFib was called with a xfer state not set to HostOwned!\n");
5809+ FsaCommLogEvent(FibContext,
5810+ FsaCommData.DeviceObject,
5811+ FSAFS_FIB_INVALID,
5812+ STATUS_UNSUCCESSFUL,
5813+ BugCheckFileId | __LINE__,
5814+ FACILITY_FSAFS_ERROR_CODE,
5815+ NULL,
5816+ TRUE);
5817+
5818+ return(STATUS_UNSUCCESSFUL);
5819+
5820+ }
5821+
5822+ //
5823+ // There are 5 cases with the wait and reponse requested flags. The only invalid cases
5824+ // are if the caller requests to wait and does not request a response and if the
5825+ // caller does not want a response and the Fib is not allocated from pool. If a response
5826+ // is not requesed the Fib will just be deallocaed by the DPC routine when the response
5827+ // comes back from the adapter. No further processing will be done besides deleting the
5828+ // Fib. We will have a debug mode where the adapter can notify the host it had a problem
5829+ // and the host can log that fact.
5830+
5831+ if (Wait && !ResponseExpected) {
5832+
5833+ FsaCommLogEvent(FibContext,
5834+ FsaCommData.DeviceObject,
5835+ FSAFS_FIB_INVALID,
5836+ STATUS_UNSUCCESSFUL,
5837+ BugCheckFileId | __LINE__,
5838+ FACILITY_FSAFS_ERROR_CODE,
5839+ NULL,
5840+ TRUE);
5841+
5842+ return(STATUS_UNSUCCESSFUL);
5843+
5844+ } else if (!Wait && ResponseExpected) {
5845+ Fib->Header.XferState |= (Async | ResponseExpected);
5846+ FIB_COUNTER_INCREMENT(FsaCommData.AsyncSent);
5847+ } else if (!Wait && !ResponseExpected) {
5848+ Fib->Header.XferState |= NoResponseExpected;
5849+ FIB_COUNTER_INCREMENT(FsaCommData.NoResponseSent);
5850+ } else if (Wait && ResponseExpected) {
5851+ Fib->Header.XferState |= ResponseExpected;
5852+ FIB_COUNTER_INCREMENT(FsaCommData.NormalSent);
5853+ }
5854+
5855+ Fib->Header.SenderData = (ULONG)FibContext; // so we can complete the io in the dpc routine
5856+
5857+ //
5858+ // Set FIB state to indicate where it came from and if we want a response from the
5859+ // adapter. Also load the command from the caller.
5860+ //
5861+
5862+ Fib->Header.SenderFibAddress = (ULONG)Fib;
5863+ Fib->Header.Command = Command;
5864+ Fib->Header.XferState |= SentFromHost;
5865+ FibContext->Fib->Header.Flags = 0; // Zero the flags field - its internal only...
5866+
5867+ //
5868+ // Set the size of the Fib we want to send to the adapter
5869+ //
5870+
5871+ Fib->Header.Size = sizeof(FIB_HEADER) + Size;
5872+ if (Fib->Header.Size > Fib->Header.SenderSize) {
5873+ return(STATUS_BUFFER_OVERFLOW);
5874+ }
5875+
5876+ //
5877+ // Get a queue entry connect the FIB to it and send an notify the adapter a command is ready.
5878+ //
5879+
5880+ if (Priority == FsaHigh) {
5881+ Fib->Header.XferState |= HighPriority;
5882+ WhichQueue = AdapHighCmdQueue;
5883+ OurQueue = &Adapter->CommRegion->AdapHighCmdQue;
5884+ } else {
5885+ Fib->Header.XferState |= NormalPriority;
5886+ WhichQueue = AdapNormCmdQueue;
5887+ OurQueue = &Adapter->CommRegion->AdapNormCmdQue;
5888+ }
5889+
5890+ if (Wait) {
5891+ OsCvLockAcquire( FibContext->FsaEventMutex );
5892+ }
5893+
5894+ if ( GetQueueEntry( Adapter, &Index, WhichQueue, Fib, TRUE, FibContext, &DontInterrupt) != FSA_SUCCESS )
5895+ return(STATUS_UNSUCCESSFUL);
5896+
5897+ // bmb debug
5898+
5899+ cmn_err (CE_DEBUG,"SendFib: inserting a queue entry at index %d.\n",Index);
5900+ cmn_err (CE_DEBUG,"Fib contents:.\n");
5901+ cmn_err (CE_DEBUG," Command = %d.\n", Fib->Header.Command);
5902+ cmn_err (CE_DEBUG," XferState = %x.\n", Fib->Header.XferState );
5903+
5904+ //
5905+ // Fill in the Callback and CallbackContext if we are not going to wait.
5906+ //
5907+
5908+ if (!Wait) {
5909+
5910+ FibContext->FibCallback = FibCallback;
5911+ FibContext->FibCallbackContext = FibCallbackContext;
5912+
5913+ }
5914+
5915+ FIB_COUNTER_INCREMENT(FsaCommData.FibsSent);
5916+
5917+ InsertTailList( &OurQueue->OutstandingIoQueue, &FibContext->QueueEntry );
5918+ OurQueue->NumOutstandingIos++;
5919+
5920+ FibContext->FibComplete = 0;
5921+
5922+
5923+
5924+ if ( InsertQueueEntry( Adapter, Index, WhichQueue, (DontInterrupt & FsaCommData.EnableInterruptModeration)) != FSA_SUCCESS )
5925+ return(STATUS_UNSUCCESSFUL);
5926+
5927+ //
5928+ // If the caller wanted us to wait for response wait now.
5929+ // If Timeouts are enabled than set the timeout otherwise wait forever.
5930+ //
5931+
5932+ if (Wait) {
5933+ while (FibContext->FibComplete == 0) {
5934+ OsCv_wait( &FibContext->FsaEvent, FibContext->FsaEventMutex );
5935+ }
5936+
5937+ OsCvLockRelease( FibContext->FsaEventMutex );
5938+
5939+ if ( (FibContext->Flags & FIB_CONTEXT_FLAG_TIMED_OUT) ) {
5940+ return(STATUS_IO_TIMEOUT);
5941+ } else {
5942+ return(STATUS_SUCCESS);
5943+ }
5944+ }
5945+
5946+ //
5947+ // If the user does not want a response than return success otherwise return pending
5948+ //
5949+
5950+ ASSERT( FibCallback );
5951+
5952+ if (ResponseExpected)
5953+ return(STATUS_PENDING);
5954+ else
5955+ return(STATUS_SUCCESS);
5956+}
5957+
5958+BOOLEAN
5959+GetConsumerEntry(
5960+ IN PAFA_COMM_ADAPTER Adapter,
5961+ PCOMM_QUE OurQueue,
5962+ OUT PQUEUE_ENTRY *Entry
5963+ )
5964+/*++
5965+
5966+Routine Description:
5967+
5968+ Will return a pointer to the entry on the top of the queue requested that we are a consumer
5969+ of, and return the address of the queue entry. It does not change the state of the queue.
5970+
5971+Arguments:
5972+
5973+ OurQueue - is the queue the queue entry should be removed from.
5974+
5975+ Entry - is a pointer where the address of the queue entry should be returned.
5976+
5977+Return Value:
5978+
5979+ TRUE if there was a queue entry on the response queue for the host to consume.
5980+ FALSE if there were no queue entries to consume.
5981+
5982+--*/
5983+
5984+{
5985+ QUEUE_INDEX Index;
5986+ BOOLEAN status;
5987+
5988+ if (*OurQueue->Headers.ProducerIndex == *OurQueue->Headers.ConsumerIndex) {
5989+ status = FALSE;
5990+ } else {
5991+
5992+ //
5993+ // The consumer index must be wrapped if we have reached the end of
5994+ // the queue.
5995+ // Else we just use the entry pointed to by the header index
5996+ //
5997+
5998+ if (*OurQueue->Headers.ConsumerIndex >= OurQueue->QueueEntries)
5999+ Index = 0;
6000+ else
6001+ Index = *OurQueue->Headers.ConsumerIndex;
6002+
6003+ *Entry = OurQueue->BaseAddress + Index;
6004+
6005+#ifdef commdebug
6006+ FsaCommPrint("Got a QE at Index %d, QE Addrss of %x.\n",Index,*Entry);
6007+#endif
6008+ status = TRUE;
6009+ }
6010+
6011+ return(status);
6012+}
6013+
6014+BOOLEAN
6015+ConsumerEntryAvailable(
6016+ IN PAFA_COMM_ADAPTER Adapter,
6017+ PCOMM_QUE OurQueue
6018+ )
6019+{
6020+ return (*OurQueue->Headers.ProducerIndex != *OurQueue->Headers.ConsumerIndex);
6021+}
6022+
6023+VOID
6024+FreeConsumerEntry(
6025+ IN PAFA_COMM_ADAPTER Adapter,
6026+ PCOMM_QUE OurQueue,
6027+ QUEUE_TYPES WhichQueue
6028+ )
6029+/*++
6030+
6031+Routine Description:
6032+
6033+ Frees up the current top of the queue we are a consumer of. If the queue was full
6034+ notify the producer that the queue is no longer full.
6035+
6036+Arguments:
6037+
6038+ OurQueue - is the queue we will free the current consumer entry on.
6039+
6040+Return Value:
6041+
6042+ TRUE if there was a queue entry on the response queue for the host to consume.
6043+ FALSE if there were no queue entries to consume.
6044+
6045+--*/
6046+
6047+{
6048+ BOOLEAN WasFull = FALSE;
6049+ HOST_2_ADAP_EVENT Notify;
6050+
6051+ if (*OurQueue->Headers.ProducerIndex+1 == *OurQueue->Headers.ConsumerIndex)
6052+ WasFull = TRUE;
6053+
6054+ if (*OurQueue->Headers.ConsumerIndex >= OurQueue->QueueEntries)
6055+ *OurQueue->Headers.ConsumerIndex = 1;
6056+ else
6057+ *OurQueue->Headers.ConsumerIndex += 1;
6058+
6059+ if (WasFull) {
6060+ switch (WhichQueue) {
6061+
6062+ case HostNormCmdQueue:
6063+ Notify = HostNormCmdNotFull;
6064+ break;
6065+ case HostHighCmdQueue:
6066+ Notify = HostHighCmdNotFull;
6067+ break;
6068+
6069+ case HostNormRespQueue:
6070+ Notify = HostNormRespNotFull;
6071+ break;
6072+
6073+ case HostHighRespQueue:
6074+ Notify = HostHighRespNotFull;
6075+ break;
6076+
6077+ }
6078+ NotifyAdapter(Adapter, Notify);
6079+ }
6080+
6081+}
6082+
6083+AAC_STATUS
6084+CompleteAdapterFib(
6085+ IN PFIB_CONTEXT Context,
6086+ IN USHORT Size
6087+ )
6088+/*++
6089+
6090+Routine Description:
6091+
6092+ Will do all necessary work to complete a FIB that was sent from the adapter.
6093+
6094+Arguments:
6095+
6096+ Fib is a pointer to the FIB that caller wishes to complete processing on.
6097+
6098+ Size - Size of the completion Packet(Opitional). If not present than the current
6099+ largest size in the Fib will be used
6100+
6101+ Adapter - Pointer to which adapter sent this FIB
6102+
6103+Return Value:
6104+
6105+ NT_SUCCESS if a Fib was returned to the caller.
6106+ NT_ERROR if event was an invalid event.
6107+
6108+--*/
6109+{
6110+ PCOMM_FIB_CONTEXT FibContext = Context;
6111+ PFIB Fib = FibContext->Fib;
6112+ PAFA_COMM_ADAPTER Adapter = FibContext->Adapter;
6113+ ULONG DontInterrupt = FALSE;
6114+
6115+ if (Fib->Header.XferState == 0)
6116+ return(STATUS_SUCCESS);
6117+
6118+ //
6119+ // If we plan to do anything check the structure type first.
6120+ //
6121+
6122+ if ( Fib->Header.StructType != TFib ) {
6123+ FsaCommPrint("Error CompleteFib called with a non Fib structure.\n");
6124+ return(STATUS_UNSUCCESSFUL);
6125+ }
6126+
6127+ //
6128+ // This block handles the case where the adapter had sent us a command and we
6129+ // have finished processing the command. We call completeFib when we are done
6130+ // processing the command and want to send a response back to the adapter. This
6131+ // will send the completed cdb to the adapter.
6132+ //
6133+
6134+ if (Fib->Header.XferState & SentFromAdapter) {
6135+ Fib->Header.XferState |= HostProcessed;
6136+ if (Fib->Header.XferState & HighPriority) {
6137+ QUEUE_INDEX Index;
6138+
6139+ if (Size) {
6140+ Size += sizeof(FIB_HEADER);
6141+ if (Size > Fib->Header.SenderSize)
6142+ return(STATUS_BUFFER_OVERFLOW);
6143+ Fib->Header.Size = Size;
6144+ }
6145+
6146+ if (GetQueueEntry(Adapter, &Index, AdapHighRespQueue, Fib, TRUE, NULL, &DontInterrupt) != STATUS_SUCCESS) {
6147+ FsaCommPrint("CompleteFib got an error geting a queue entry for a response.\n");
6148+ return(FSA_FATAL);
6149+ }
6150+ if (InsertQueueEntry(Adapter,
6151+ Index,
6152+ AdapHighRespQueue,
6153+ (DontInterrupt & (BOOLEAN)FsaCommData.EnableInterruptModeration)) != STATUS_SUCCESS) {
6154+ FsaCommPrint("CompleteFib failed while inserting entry on the queue.\n");
6155+ }
6156+ } else if (Fib->Header.XferState & NormalPriority) {
6157+ QUEUE_INDEX Index;
6158+
6159+ if (Size) {
6160+ Size += sizeof(FIB_HEADER);
6161+ if (Size > Fib->Header.SenderSize)
6162+ return(STATUS_BUFFER_OVERFLOW);
6163+ Fib->Header.Size = Size;
6164+ }
6165+
6166+ if (GetQueueEntry(Adapter, &Index, AdapNormRespQueue, Fib, TRUE, NULL, &DontInterrupt) != STATUS_SUCCESS) {
6167+ FsaCommPrint("CompleteFib got an error geting a queue entry for a response.\n");
6168+ return(FSA_FATAL);
6169+ }
6170+ if (InsertQueueEntry(Adapter,
6171+ Index,
6172+ AdapNormRespQueue,
6173+ (DontInterrupt & (BOOLEAN)FsaCommData.EnableInterruptModeration)) != STATUS_SUCCESS) {
6174+ FsaCommPrint("CompleteFib failed while inserting entry on the queue.\n");
6175+ }
6176+ }
6177+ } else {
6178+ cmn_err(CE_WARN, "CompleteFib: Unknown xferstate detected.\n");
6179+ FsaBugCheck(0,0,0);
6180+ }
6181+ return(STATUS_SUCCESS);
6182+}
6183+
6184+AAC_STATUS
6185+CompleteFib(
6186+ IN PFIB_CONTEXT Context
6187+ )
6188+/*++
6189+
6190+Routine Description:
6191+
6192+ Will do all necessary work to complete a FIB. If the caller wishes to
6193+ reuse the FIB after post processing has been completed Reinitialize
6194+ should be called set to TRUE, otherwise the FIB will be returned to the
6195+ free FIB pool. If Reinitialize is set to TRUE then the FIB header is
6196+ reinitialzied and is ready for reuse on return from this routine.
6197+
6198+Arguments:
6199+
6200+ Fib is a pointer to the FIB that caller wishes to complete processing on.
6201+
6202+ Size - Size of the completion Packet(Opitional). If not present than the current
6203+ largest size in the Fib will be used
6204+
6205+ Reinitialize is a boolean which determines if the routine will ready the
6206+ completed FIB for reuse(TRUE) or not(FALSE).
6207+
6208+Return Value:
6209+
6210+ NT_SUCCESS if a Fib was returned to the caller.
6211+ NT_ERROR if event was an invalid event.
6212+
6213+--*/
6214+{
6215+ PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
6216+ PAFA_COMM_ADAPTER Adapter = FibContext->Adapter;
6217+ PFIB Fib = FibContext->Fib;
6218+
6219+ //
6220+ // Check for a fib which has already been completed
6221+ //
6222+
6223+// ASSERT(Fib->Header.XferState & AdapterProcessed);
6224+ if (Fib->Header.XferState == 0)
6225+ return(STATUS_SUCCESS);
6226+
6227+ //
6228+ // If we plan to do anything check the structure type first.
6229+ //
6230+
6231+ if ( Fib->Header.StructType != TFib ) {
6232+ FsaCommPrint("Error CompleteFib called with a non Fib structure.\n");
6233+ return(STATUS_UNSUCCESSFUL);
6234+ }
6235+
6236+#if 0
6237+//#if FSA_ADAPTER_METER
6238+ //
6239+ // Meter the completion
6240+ //
6241+ fsaMeterEnd( // meter the end of an operation
6242+ &(Adapter->FibMeter), // .. the meter
6243+ IrpContext->FibMeterType, // .. type of operation
6244+ &(IrpContext->FibStartTime), // .. ptr to operation start timestamp
6245+ FibGetMeterSize(Fib, // .. number of bytes in operation
6246+ IrpContext->FibMeterType,
6247+ IrpContext->FibSubCommand));
6248+#endif // FSA_ADAPTER_METER
6249+
6250+ //
6251+ // This block completes a cdb which orginated on the host and we just need
6252+ // to deallocate the cdb or reinit it. At this point the command is complete
6253+ // that we had sent to the adapter and this cdb could be reused.
6254+ //
6255+
6256+ if ( (Fib->Header.XferState & SentFromHost) &&
6257+ (Fib->Header.XferState & AdapterProcessed)) {
6258+
6259+ ASSERT(FibContext->LogicalFibAddress.LowPart != 0);
6260+
6261+ return( DeallocateFib(FibContext) );
6262+
6263+ //
6264+ // This handles the case when the host has aborted the I/O to the
6265+ // adapter because the adapter is not responding
6266+ //
6267+
6268+ } else if (Fib->Header.XferState & SentFromHost) {
6269+
6270+ ASSERT(FibContext->LogicalFibAddress.LowPart != 0);
6271+
6272+
6273+ return( DeallocateFib(FibContext) );
6274+
6275+ } else if (Fib->Header.XferState & HostOwned) {
6276+
6277+ return(DeallocateFib(FibContext));
6278+
6279+ } else {
6280+ cmn_err(CE_WARN, "CompleteFib: Unknown xferstate detected.\n");
6281+ FsaBugCheck(0,0,0);
6282+ }
6283+ return(STATUS_SUCCESS);
6284+}
6285+
6286+VOID
6287+HandleDriverAif(
6288+ IN PAFA_COMM_ADAPTER Adapter,
6289+ IN PCOMM_FIB_CONTEXT FibContext
6290+ )
6291+/*++
6292+
6293+Routine Description:
6294+
6295+ This routine handles a driver notify fib from the adapter and dispatches it to
6296+ the appropriate routine for handling.
6297+
6298+Arguments:
6299+
6300+ Adapter - Which adapter this fib is from
6301+ FibContext - Pointer to FibContext from adapter.
6302+
6303+Return Value:
6304+
6305+ Nothing.
6306+
6307+--*/
6308+{
6309+ PFIB Fib = FibContext->Fib;
6310+ PAFA_CLASS_DRIVER ClassDriver;
6311+ BOOLEAN Handled = FALSE;
6312+
6313+
6314+ //
6315+ // First loop through all of the class drivers to give them a chance to handle
6316+ // the Fib.
6317+ //
6318+
6319+ ClassDriver = Adapter->ClassDriverList;
6320+
6321+ while (ClassDriver) {
6322+
6323+ if (ClassDriver->HandleAif) {
6324+
6325+ if (ClassDriver->HandleAif( ClassDriver->ClassDriverExtension, FibContext ) ) {
6326+
6327+ Handled = TRUE;
6328+ break;
6329+
6330+ }
6331+ }
6332+
6333+ ClassDriver = ClassDriver->Next;
6334+ }
6335+
6336+ if (!Handled) {
6337+
6338+ //
6339+ // Set the status of this FIB to be Invalid parameter.
6340+ //
6341+
6342+// *(FSASTATUS *)Fib->data = ST_INVAL;
6343+ *(FSASTATUS *)Fib->data = ST_OK;
6344+
6345+
6346+ CompleteAdapterFib(FibContext, sizeof(FSASTATUS));
6347+
6348+ }
6349+}
6350+
6351+int
6352+NormCommandThread(
6353+ IN PAFA_COMM_ADAPTER Adapter
6354+ )
6355+/*++
6356+
6357+Routine Description:
6358+
6359+ Waits on the commandready event in it's queue. When the event gets set it will
6360+ pull FIBs off it's queue. It will continue to pull FIBs off till the queue is empty.
6361+ When the queue is empty it will wait for more FIBs.
6362+
6363+Arguments:
6364+
6365+ Context is used. All data os global
6366+
6367+Return Value:
6368+ Nothing.
6369+
6370+--*/
6371+{
6372+ PFIB Fib, NewFib;
6373+ COMM_FIB_CONTEXT FibContext; // for error logging
6374+ KIRQL SavedIrql;
6375+ PCOMM_REGION CommRegion = Adapter->CommRegion;
6376+ PLIST_ENTRY Entry;
6377+ PGET_ADAPTER_FIB_CONTEXT AdapterFibContext;
6378+
6379+ //
6380+ // We can only have one thread per adapter for AIF's.
6381+ //
6382+
6383+ if (Adapter->AifThreadStarted) {
6384+ return (EINVAL);
6385+ }
6386+
6387+// cmn_err(CE_DEBUG, "AIF thread started");
6388+
6389+ //
6390+ // Let the DPC know it has a place to send the AIF's to.
6391+ //
6392+
6393+ Adapter->AifThreadStarted = TRUE;
6394+
6395+ RtlZeroMemory(&FibContext, sizeof(COMM_FIB_CONTEXT));
6396+
6397+ OsSpinLockAcquire(CommRegion->HostNormCmdQue.QueueLock);
6398+
6399+ while (TRUE) {
6400+
6401+ //
6402+ // NOTE : the QueueLock is held at the top of each loop.
6403+ //
6404+
6405+ ASSERT(OsSpinLockOwned(CommRegion->HostNormCmdQue.QueueLock));
6406+
6407+ while (!IsListEmpty(&(CommRegion->HostNormCmdQue.CommandQueue))) {
6408+ PLIST_ENTRY Entry;
6409+ PAIFCOMMANDTOHOST AifCommandToHost;
6410+
6411+ Entry = RemoveHeadList(&(CommRegion->HostNormCmdQue.CommandQueue));
6412+
6413+ OsSpinLockRelease(CommRegion->HostNormCmdQue.QueueLock);
6414+
6415+ Fib = CONTAINING_RECORD( Entry, FIB, Header.FibLinks );
6416+
6417+ //
6418+ // We will process the FIB here or pass it to a worker thread that is TBD. We Really
6419+ // can't do anything at this point since we don't have anything defined for this thread to
6420+ // do.
6421+ //
6422+
6423+ // cmn_err(CE_DEBUG, "Got Fib from the adapter with a NORMAL priority, command 0x%x.\n", Fib->Header.Command);
6424+
6425+ RtlZeroMemory( &FibContext, sizeof(COMM_FIB_CONTEXT) );
6426+
6427+
6428+ FibContext.NodeTypeCode = FSAFS_NTC_FIB_CONTEXT;
6429+ FibContext.NodeByteSize = sizeof( COMM_FIB_CONTEXT );
6430+ FibContext.Fib = Fib;
6431+ FibContext.FibData = Fib->data;
6432+ FibContext.Adapter = Adapter;
6433+
6434+
6435+ //
6436+ // We only handle AifRequest fibs from the adapter.
6437+ //
6438+
6439+ ASSERT(Fib->Header.Command == AifRequest);
6440+
6441+
6442+ AifCommandToHost = (PAIFCOMMANDTOHOST) Fib->data;
6443+
6444+ if (AifCommandToHost->command == AifCmdDriverNotify) {
6445+
6446+
6447+
6448+ HandleDriverAif( Adapter, &FibContext );
6449+
6450+ } else {
6451+ AAC_UINT32 time_now, time_last;
6452+ time_now = (AAC_UINT32)OsGetSeconds();
6453+
6454+
6455+ OsCvLockAcquire(Adapter->AdapterFibMutex);
6456+
6457+ Entry = Adapter->AdapterFibContextList.Flink;
6458+
6459+ //
6460+ // For each Context that is on the AdapterFibContextList, make a copy of the
6461+ // fib, and then set the event to wake up the thread that is waiting for it.
6462+ //
6463+
6464+ while (Entry != &Adapter->AdapterFibContextList) {
6465+
6466+ //
6467+ // Extract the AdapterFibContext
6468+ //
6469+
6470+ AdapterFibContext = CONTAINING_RECORD( Entry, GET_ADAPTER_FIB_CONTEXT, NextContext );
6471+
6472+ //
6473+ // Check if the queue is getting backlogged
6474+ //
6475+ if ( AdapterFibContext->FibCount > 20 ) {
6476+ time_last = (AAC_UINT32)(AdapterFibContext->FileObject);
6477+
6478+ //
6479+ // has it been > 2 minutes since the last read off the queue?
6480+ //
6481+ if ((time_now - time_last) > 120) {
6482+ Entry = Entry->Flink;
6483+ // cmn_err (CE_WARN, "aifd: Flushing orphaned AdapterFibContext: idle %d seconds, %d fibs",
6484+ // time_now - time_last,
6485+ // AdapterFibContext->FibCount);
6486+ FsaCloseAdapterFibContext ( Adapter, AdapterFibContext );
6487+ continue;
6488+ }
6489+ }
6490+
6491+// Warning: sleep possible while holding spinlock
6492+ NewFib = OsAllocMemory(sizeof(FIB), OS_ALLOC_MEM_SLEEP);
6493+
6494+ if (NewFib) {
6495+
6496+ //
6497+ // Make the copy of the FIB
6498+ //
6499+
6500+ RtlCopyMemory(NewFib, Fib, sizeof(FIB));
6501+
6502+ //
6503+ // Put the FIB onto the AdapterFibContext's FibList
6504+ //
6505+
6506+ InsertTailList(&AdapterFibContext->FibList, &NewFib->Header.FibLinks);
6507+ AdapterFibContext->FibCount++;
6508+
6509+ //
6510+ // Set the event to wake up the thread that will waiting.
6511+ //
6512+
6513+ OsCv_signal(&AdapterFibContext->UserEvent);
6514+
6515+ } else {
6516+
6517+ cmn_err (CE_WARN, "aifd: didn't allocate NewFib");
6518+
6519+ }
6520+
6521+ Entry = Entry->Flink;
6522+ }
6523+
6524+ //
6525+ // Set the status of this FIB
6526+ //
6527+
6528+ *(FSASTATUS *)Fib->data = ST_OK;
6529+
6530+ CompleteAdapterFib( &FibContext, sizeof(FSASTATUS) );
6531+
6532+ OsCvLockRelease(Adapter->AdapterFibMutex);
6533+
6534+ }
6535+
6536+ OsSpinLockAcquire(CommRegion->HostNormCmdQue.QueueLock);
6537+
6538+ }
6539+
6540+ //
6541+ // There are no more AIF's, call cv_wait_sig to wait for more
6542+ // to process.
6543+ //
6544+
6545+ // cmn_err(CE_DEBUG, "no more AIF's going to sleep\n");
6546+
6547+ if (OsCv_wait_sig( &(CommRegion->HostNormCmdQue.CommandReady),
6548+ CommRegion->HostNormCmdQue.QueueLock ) == 0) {
6549+
6550+ OsSpinLockRelease(CommRegion->HostNormCmdQue.QueueLock);
6551+
6552+ Adapter->AifThreadStarted = FALSE;
6553+
6554+ // cmn_err(CE_DEBUG, "AifThread awoken by a signal\n");
6555+
6556+ return (EINTR);
6557+
6558+ }
6559+
6560+ // cmn_err(CE_DEBUG, "Aif thread awake, going to look for more AIF's\n");
6561+
6562+ }
6563+}
6564+
6565+
6566+PVOID
6567+FsaGetFibData(
6568+ IN PFIB_CONTEXT Context
6569+ )
6570+{
6571+ PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
6572+
6573+ return ((PVOID)FibContext->Fib->data);
6574+}
6575+
6576+
6577+#ifdef API_THROTTLE
6578+
6579+void ThrottlePeriodEndDpcRtn(
6580+ IN PKDPC Dpc,
6581+ IN PVOID DeferredContext,
6582+ IN PVOID SystemArgument1,
6583+ IN PVOID SystemArgument2
6584+ )
6585+/*++
6586+
6587+Routine Description:
6588+
6589+ This routine is called as a DPC when a throttle period expires. It
6590+ restarts all threads suspended due to the throttling flow control.
6591+
6592+ The throttling counted semaphore is signalled for all waiting threads
6593+ and the indicator of throttling active is cleared.
6594+
6595+Arguments:
6596+
6597+ Dpc - Pointer to Dpc structure. Not used.
6598+ DefferedContext - Pointer to per-adapter context. This is used to locate the
6599+ throttle information for this adapter.
6600+ SystemArgument1 - Not used
6601+ SystemArgument2 - Not used
6602+
6603+Return Value:
6604+
6605+ None.
6606+
6607+--*/
6608+{
6609+ PCOMM_REGION CommRegion;
6610+ PAFA_COMM_ADAPTER Adapter = (PAFA_COMM_ADAPTER) DeferredContext;
6611+
6612+ CommRegion = Adapter->CommRegion;
6613+
6614+ //
6615+ // Acquire the spinlock protecting the throttle status.
6616+ //
6617+ OsSpinLockAcquire(CommRegion->AdapNormCmdQue.QueueLock);
6618+
6619+ FsaCommPrint("ThrottlePeriodEndDpc\n");
6620+
6621+ //
6622+ // Check that the timer has fired as many times as it was set !
6623+ //
6624+
6625+ CommRegion->ThrottleTimerFires++;
6626+ ASSERT(CommRegion->ThrottleTimerFires == CommRegion->ThrottleTimerSets);
6627+
6628+ //
6629+ // The throttle period is now over. Restart all threads waiting
6630+ // on the throttle being released.
6631+ // Clear the throttle active indicator. This will allow new FIBs
6632+ // to be sent to the adapter once we release the spinlock on exiting
6633+ // the DPC. This means all restarted threads will be runnable
6634+ // threads by then.
6635+ //
6636+
6637+ ASSERT(CommRegion->ThrottleActive == TRUE); // The throttle had better be on !
6638+ CommRegion->ThrottleActive = FALSE; // This allows new data FIBs to go to the adapter on dpc exit
6639+
6640+ OsSpinLockRelease(CommRegion->AdapNormCmdQue.QueueLock);
6641+}
6642+
6643+#endif // #ifdef API_THROTTLE
6644+
6645+/*
6646+ * Overrides for Emacs so that we almost follow Linus's tabbing style.
6647+ * Emacs will notice this stuff at the end of the file and automatically
6648+ * adjust the settings for this buffer only. This must remain at the end
6649+ * of the file.
6650+ * ---------------------------------------------------------------------------
6651+ * Local variables:
6652+ * c-indent-level: 4
6653+ * c-brace-imaginary-offset: 0
6654+ * c-brace-offset: -4
6655+ * c-argdecl-indent: 4
6656+ * c-label-offset: -4
6657+ * c-continued-statement-offset: 4
6658+ * c-continued-brace-offset: 0
6659+ * indent-tabs-mode: nil
6660+ * tab-width: 8
6661+ * End:
6662+ */
6663diff -burN linux-2.4.9/drivers/scsi/aacraid/dpcsup.c linux/drivers/scsi/aacraid/dpcsup.c
6664--- linux-2.4.9/drivers/scsi/aacraid/dpcsup.c Wed Dec 31 18:00:00 1969
6665+++ linux/drivers/scsi/aacraid/dpcsup.c Thu Aug 16 13:41:30 2001
6666@@ -0,0 +1,443 @@
6667+/*++
6668+ * Adaptec aacraid device driver for Linux.
6669+ *
6670+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
6671+ *
6672+ * This program is free software; you can redistribute it and/or modify
6673+ * it under the terms of the GNU General Public License as published by
6674+ * the Free Software Foundation; either version 2, or (at your option)
6675+ * any later version.
6676+ *
6677+ * This program is distributed in the hope that it will be useful,
6678+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6679+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6680+ * GNU General Public License for more details.
6681+ *
6682+ * You should have received a copy of the GNU General Public License
6683+ * along with this program; see the file COPYING. If not, write to
6684+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
6685+ *
6686+ * Module Name:
6687+ * dpcsup.c
6688+ *
6689+ * Abstract: All DPC processing routines for the cyclone board occur here.
6690+ *
6691+ *
6692+ --*/
6693+
6694+static char *ident_dpcsup = "aacraid_ident dpcsup.c 1.0.6 2000/10/09 Adaptec, Inc.";
6695+
6696+#include "comprocs.h"
6697+
6698+
6699+//
6700+// The Bug check file id for this module
6701+//
6702+
6703+#define BugCheckFileId (FSAFS_BUG_CHECK_DPCSUP)
6704+
6705+#define Dbg (DEBUG_TRACE_DPCSUP)
6706+
6707+u_int
6708+CommonNotFullDpc(
6709+ IN PCOMM_REGION CommRegion
6710+ )
6711+/*++
6712+
6713+Routine Description:
6714+
6715+ This DPC routine will be queued when the adapter interrupts us to let us know the queue is
6716+ no longer full. The Isr will pass the queue that we will set the not full event.
6717+
6718+Arguments:
6719+
6720+ Dpc - Pointer to this routine.
6721+
6722+ Dummy - is a pointer to the comm region which is global so we don't need it anyway
6723+
6724+ Queue is a pointer to the queue structure we will operate on.
6725+
6726+ MoreData2 are DPC parameters we don't need for this function. Maybe we can add some accounting
6727+ stuff in here.
6728+
6729+Return Value:
6730+ Nothing.
6731+
6732+--*/
6733+{
6734+
6735+#ifdef unix_queue_full
6736+ KeSetEvent(&Queue->QueueFull, 0, FALSE);
6737+#endif
6738+
6739+}
6740+
6741+int GatherFibTimes = 0;
6742+
6743+// XXX - hack this in until I figure out which header file should contain it. <smb>
6744+extern ULONG
6745+FibGetMeterSize(
6746+ PFIB pFib,
6747+ ULONG MeterType,
6748+ char SubCommand
6749+ );
6750+
6751+
6752+/*++
6753+
6754+Routine Description:
6755+
6756+ This DPC routine will be queued when the adapter interrupts us to let us know there
6757+ is a response on our normal priority queue. We will pull off all QE there are and wake
6758+ up all the waiters before exiting. We will take a spinlock out on the queue before operating
6759+ on it.
6760+
6761+Arguments:
6762+
6763+ Dpc - Pointer to this routine.
6764+
6765+ OurQueue is a pointer to the queue structure we will operate on.
6766+
6767+ MoreData1&2 are DPC parameters we don't need for this function. Maybe we can add some accounting
6768+ stuff in here.
6769+
6770+Return Value:
6771+ Nothing.
6772+
6773+--*/
6774+u_int
6775+HostResponseNormalDpc (IN PCOMM_QUE OurQueue)
6776+{
6777+ PAFA_COMM_ADAPTER Adapter = OurQueue->Adapter;
6778+ PQUEUE_ENTRY QueueEntry;
6779+ PFIB Fib;
6780+ PCOMM_FIB_CONTEXT FibContext;
6781+ int Consumed = 0;
6782+ KIRQL OldIrql;
6783+
6784+ LARGE_INTEGER ResponseAllocSize;
6785+
6786+#ifdef commdebug
6787+ FsaCommPrint("entering the host normal reponse dpc routine.\n");
6788+#endif
6789+
6790+ OsSpinLockAcquire( OurQueue->QueueLock );
6791+
6792+ //
6793+ // Keep pulling response QEs off the response queue and waking
6794+ // up the waiters until there are no more QEs. We then return
6795+ // back to the system. If no response was requesed we just
6796+ // deallocate the Fib here and continue.
6797+ //
6798+
6799+ loop:
6800+ while ( GetConsumerEntry( Adapter, OurQueue, &QueueEntry) ) {
6801+
6802+ int IsFastResponse;
6803+
6804+ IsFastResponse = (int) (QueueEntry->FibAddress & 0x01);
6805+ Fib = (PFIB) (QueueEntry->FibAddress & ~0x01);
6806+
6807+ FreeConsumerEntry(Adapter, OurQueue, HostNormRespQueue);
6808+
6809+ FibContext = (PCOMM_FIB_CONTEXT)Fib->Header.SenderData;
6810+
6811+ ASSERT(FibContext->Fib == Fib);
6812+
6813+ //
6814+ // Remove this FibContext from the Outstanding I/O queue.
6815+ // But only if it has not already been timed out.
6816+ //
6817+ // If the fib has been timed out already, then just continue.
6818+ // The caller has already been notified that the fib timed out.
6819+ //
6820+
6821+ if (!(FibContext->Flags & FIB_CONTEXT_FLAG_TIMED_OUT)) {
6822+
6823+ RemoveEntryList( &FibContext->QueueEntry );
6824+ Adapter->CommRegion->AdapNormCmdQue.NumOutstandingIos--;
6825+
6826+ } else {
6827+
6828+ FsaCommLogEvent(FibContext,
6829+ FsaCommData.DeviceObject,
6830+ FSAFS_TIMED_OUT_FIB_COMPLETED,
6831+ STATUS_UNSUCCESSFUL,
6832+ BugCheckFileId | __LINE__,
6833+ FACILITY_FSAFS_ERROR_CODE,
6834+ NULL,
6835+ TRUE);
6836+
6837+ continue;
6838+
6839+ }
6840+
6841+ OsSpinLockRelease( OurQueue->QueueLock );
6842+
6843+ if (IsFastResponse) {
6844+
6845+ //
6846+ // doctor the fib
6847+ //
6848+
6849+ *(FSASTATUS *)Fib->data = ST_OK;
6850+
6851+ Fib->Header.XferState |= AdapterProcessed;
6852+
6853+ }
6854+
6855+ ASSERT((Fib->Header.XferState & (AdapterProcessed | HostOwned | SentFromHost)) == (AdapterProcessed | HostOwned | SentFromHost));
6856+
6857+ FIB_COUNTER_INCREMENT(FsaCommData.FibRecved);
6858+
6859+ ASSERT(FsaCommData.FibsSent >= FsaCommData.FibRecved);
6860+
6861+
6862+ if (Fib->Header.Command == NuFileSystem) {
6863+
6864+ FSASTATUS *pStatus = (FSASTATUS *)Fib->data;
6865+
6866+ if (*pStatus & 0xffff0000) {
6867+
6868+ ULONG Hint = *pStatus;
6869+
6870+ *pStatus = ST_OK;
6871+
6872+/*
6873+ DbgPrint("Replacing hint in fid (drive = %d, f1 = 0x%x, f2 = 0x%x, hint = 0x%x, new_hint = 0x%x)\n",
6874+ IrpContext->NonPaged->FileId.fid_driveno,
6875+ IrpContext->NonPaged->FileId.fid_f1,
6876+ IrpContext->NonPaged->FileId.fid_f2,
6877+ IrpContext->NonPaged->FileId.fid_hint,
6878+ Hint);
6879+*/
6880+
6881+ }
6882+
6883+ }
6884+
6885+ if (Fib->Header.XferState & (NoResponseExpected | Async) ) {
6886+
6887+ ASSERT(FibContext->FibCallback);
6888+
6889+ if (Fib->Header.XferState & NoResponseExpected)
6890+ FIB_COUNTER_INCREMENT(FsaCommData.NoResponseRecved);
6891+ else
6892+ FIB_COUNTER_INCREMENT(FsaCommData.AsyncRecved);
6893+
6894+ //
6895+ // NOTE: we can not touch the FibContext after this call, because it may have been
6896+ // deallocated.
6897+ //
6898+
6899+ FibContext->FibCallback(FibContext->FibCallbackContext, FibContext, STATUS_SUCCESS);
6900+
6901+ } else {
6902+
6903+ OsCvLockAcquire( FibContext->FsaEventMutex);
6904+
6905+ FibContext->FibComplete = 1;
6906+
6907+ OsCv_signal( &FibContext->FsaEvent );
6908+
6909+ OsCvLockRelease( FibContext->FsaEventMutex );
6910+
6911+ FIB_COUNTER_INCREMENT(FsaCommData.NormalRecved);
6912+
6913+ }
6914+
6915+
6916+ Consumed++;
6917+
6918+ OsSpinLockAcquire( OurQueue->QueueLock );
6919+
6920+ }
6921+
6922+ if (Consumed > FsaCommData.PeakFibsConsumed)
6923+ FsaCommData.PeakFibsConsumed = Consumed;
6924+
6925+ if (Consumed == 0)
6926+ FsaCommData.ZeroFibsConsumed++;
6927+
6928+ if (FsaCommData.HardInterruptModeration) {
6929+
6930+ //
6931+ // Re-Enable the interrupt from the adapter, then recheck to see if anything has
6932+ // been put on the queue. This removes the race condition that exists between the
6933+ // last time we checked the queue, and when we re-enabled the interrupt.
6934+ //
6935+ // If there is something on the queue, then go handle it.
6936+ //
6937+
6938+ EnableInterrupt( Adapter, HostNormRespQue, FALSE );
6939+
6940+ if (ConsumerEntryAvailable( Adapter, OurQueue ) ) {
6941+
6942+ DisableInterrupt( Adapter, HostNormRespQue, FALSE );
6943+
6944+ goto loop;
6945+
6946+ }
6947+ }
6948+
6949+#ifdef commdebug
6950+ FsaCommPrint("Exiting host normal reponse dpc routine after consuming %d QE(s).\n",Consumed);
6951+#endif
6952+
6953+ OsSpinLockRelease( OurQueue->QueueLock );
6954+
6955+}
6956+
6957+/*++
6958+
6959+Routine Description:
6960+
6961+ This DPC routine wiol be queued when the adapter interrupts us to let us know there
6962+ is a response on our high priority queue. We will pull off all QE there are and wake
6963+ up all the waiters before exiting. We will take a spinlock out on the queue before operating
6964+ on it.
6965+
6966+Arguments:
6967+
6968+ Dpc - Pointer to this routine.
6969+
6970+ OurQueue is a pointer to the queue structure we will operate on.
6971+
6972+ MoreData1&2 are DPC parameters we don't need for this function. Maybe we can add some accounting
6973+ stuff in here.
6974+
6975+Return Value:
6976+ Nothing.
6977+
6978+--*/
6979+u_int
6980+HostResponseHighDpc (IN PCOMM_QUE OurQueue)
6981+{}
6982+
6983+
6984+/*++
6985+
6986+Routine Description:
6987+
6988+ This DPC routine will be queued when the adapter interrupts us to let us know there
6989+ is a command on our high priority queue. We will pull off all QE there are and wake
6990+ up all the waiters before exiting. We will take a spinlock out on the queue before operating
6991+ on it.
6992+
6993+Arguments:
6994+
6995+ Dpc - Pointer to this routine.
6996+
6997+ OurQueue is a pointer to the queue structure we will operate on.
6998+
6999+ MoreData1&2 are DPC parameters we don't need for this function. Maybe we can add some accounting
7000+ stuff in here.
7001+
7002+Return Value:
7003+ Nothing.
7004+
7005+--*/
7006+u_int
7007+HostCommandHighDpc (IN PCOMM_QUE OurQueue)
7008+{}
7009+
7010+
7011+/*++
7012+
7013+Routine Description:
7014+
7015+ This DPC routine will be queued when the adapter interrupts us to let us know there
7016+ is a command on our normal priority queue. We will pull off all QE there are and wake
7017+ up all the waiters before exiting. We will take a spinlock out on the queue before operating
7018+ on it.
7019+
7020+Arguments:
7021+
7022+ Dpc - Pointer to this routine.
7023+
7024+ OurQueue is a pointer to the queue structure we will operate on.
7025+
7026+ MoreData1&2 are DPC parameters we don't need for this function. Maybe we can add some accounting
7027+ stuff in here.
7028+
7029+Return Value:
7030+ Nothing.
7031+
7032+--*/
7033+u_int
7034+HostCommandNormDpc (IN PCOMM_QUE OurQueue)
7035+{
7036+ PAFA_COMM_ADAPTER Adapter = OurQueue->Adapter;
7037+ PQUEUE_ENTRY QueueEntry;
7038+
7039+ OsSpinLockAcquire( OurQueue->QueueLock );
7040+
7041+ //
7042+ // Keep pulling response QEs off the response queue and waking
7043+ // up the waiters until there are no more QEs. We then return
7044+ // back to the system.
7045+ //
7046+
7047+ while ( GetConsumerEntry( Adapter, OurQueue, &QueueEntry) ) {
7048+
7049+ PFIB Fib;
7050+
7051+ Fib = (PFIB)QueueEntry->FibAddress;
7052+
7053+
7054+ if (Adapter->AifThreadStarted) {
7055+
7056+
7057+// cmn_err(CE_CONT, "^Received AIF, putting onto command queue\n");
7058+
7059+
7060+ InsertTailList(&OurQueue->CommandQueue, &Fib->Header.FibLinks);
7061+ FreeConsumerEntry(Adapter, OurQueue, HostNormCmdQueue);
7062+ OsCv_signal(&OurQueue->CommandReady);
7063+
7064+
7065+
7066+ } else {
7067+
7068+
7069+
7070+ COMM_FIB_CONTEXT FibContext;
7071+
7072+
7073+
7074+ FreeConsumerEntry(Adapter, OurQueue, HostNormCmdQueue);
7075+
7076+
7077+
7078+ OsSpinLockRelease( OurQueue->QueueLock );
7079+
7080+
7081+
7082+// cmn_err(CE_CONT, "^Received AIF, thread not started\n");
7083+
7084+
7085+ RtlZeroMemory( &FibContext, sizeof(COMM_FIB_CONTEXT) );
7086+
7087+ FibContext.NodeTypeCode = FSAFS_NTC_FIB_CONTEXT;
7088+ FibContext.NodeByteSize = sizeof( COMM_FIB_CONTEXT );
7089+ FibContext.Fib = Fib;
7090+ FibContext.FibData = Fib->data;
7091+ FibContext.Adapter = Adapter;
7092+
7093+ //
7094+ // Set the status of this FIB
7095+ //
7096+
7097+ *(FSASTATUS *)Fib->data = ST_OK;
7098+
7099+ CompleteAdapterFib( &FibContext, sizeof(FSASTATUS) );
7100+
7101+
7102+
7103+ OsSpinLockAcquire( OurQueue->QueueLock );
7104+ }
7105+ }
7106+
7107+ OsSpinLockRelease( OurQueue->QueueLock );
7108+
7109+}
7110diff -burN linux-2.4.9/drivers/scsi/aacraid/include/AacGenericTypes.h linux/drivers/scsi/aacraid/include/AacGenericTypes.h
7111--- linux-2.4.9/drivers/scsi/aacraid/include/AacGenericTypes.h Wed Dec 31 18:00:00 1969
7112+++ linux/drivers/scsi/aacraid/include/AacGenericTypes.h Thu Aug 16 13:41:30 2001
7113@@ -0,0 +1,57 @@
7114+/*++
7115+ * Adaptec aacraid device driver for Linux.
7116+ *
7117+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
7118+ *
7119+ * This program is free software; you can redistribute it and/or modify
7120+ * it under the terms of the GNU General Public License as published by
7121+ * the Free Software Foundation; either version 2, or (at your option)
7122+ * any later version.
7123+ *
7124+ * This program is distributed in the hope that it will be useful,
7125+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7126+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7127+ * GNU General Public License for more details.
7128+ *
7129+ * You should have received a copy of the GNU General Public License
7130+ * along with this program; see the file COPYING. If not, write to
7131+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
7132+ *
7133+ * Module Name:
7134+ *
7135+ * AacGenericTypes.h
7136+ *
7137+ * Abstract:
7138+ *
7139+ * The module defines the generic data types that all of the other header files
7140+ * depend upon.
7141+ --*/
7142+
7143+#ifndef _AAC_GENERIC_TYPES
7144+#define _AAC_GENERIC_TYPES
7145+
7146+static char *ident_AacGeneric = "aacraid_ident AacGenericTypes.h 1.0.6 2000/10/09 Adaptec, Inc.";
7147+
7148+typedef char AAC_INT8, *PAAC_INT8;
7149+typedef short AAC_INT16, *PAAC_INT16;
7150+typedef int AAC_INT32, *PAAC_INT32;
7151+typedef long long AAC_INT64, *PAAC_INT64;
7152+
7153+typedef unsigned char AAC_UINT8, *PAAC_UINT8;
7154+typedef unsigned short AAC_UINT16, *PAAC_UINT16;
7155+typedef unsigned int AAC_UINT32, *PAAC_UINT32;
7156+typedef unsigned long long AAC_UINT64, *PAAC_UINT64;
7157+
7158+typedef void AAC_VOID, *PAAC_VOID;
7159+
7160+//
7161+// this compiler uses 32 bit enum data types
7162+//
7163+
7164+#define AAC_32BIT_ENUMS 1
7165+#define FAILURE 1
7166+#define INTR_UNCLAIMED 1
7167+#define INTR_CLAIMED 0
7168+
7169+#endif // _AAC_GENERIC_TYPES
7170+
7171diff -burN linux-2.4.9/drivers/scsi/aacraid/include/aac_unix_defs.h linux/drivers/scsi/aacraid/include/aac_unix_defs.h
7172--- linux-2.4.9/drivers/scsi/aacraid/include/aac_unix_defs.h Wed Dec 31 18:00:00 1969
7173+++ linux/drivers/scsi/aacraid/include/aac_unix_defs.h Thu Aug 16 13:41:30 2001
7174@@ -0,0 +1,300 @@
7175+/*++
7176+ * Adaptec aacraid device driver for Linux.
7177+ *
7178+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
7179+ *
7180+ * This program is free software; you can redistribute it and/or modify
7181+ * it under the terms of the GNU General Public License as published by
7182+ * the Free Software Foundation; either version 2, or (at your option)
7183+ * any later version.
7184+ *
7185+ * This program is distributed in the hope that it will be useful,
7186+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7187+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7188+ * GNU General Public License for more details.
7189+ *
7190+ * You should have received a copy of the GNU General Public License
7191+ * along with this program; see the file COPYING. If not, write to
7192+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
7193+ *
7194+ * Module Name:
7195+ *
7196+ * aac_unix_defs.h
7197+ *
7198+ * Abstract:
7199+ *
7200+ * Macro definition and typedefs
7201+ *
7202+ --*/
7203+
7204+#ifndef _AAC_UNIX_DEFS
7205+#define _AAC_UNIX_DEFS
7206+
7207+static char *ident_aac_unix = "aacraid_ident aac_unix_defs.h 1.0.6 2000/10/09 Adaptec, Inc.";
7208+
7209+#define AAC_MAX_ADAPTERS 64
7210+
7211+#ifndef TRUE
7212+#define TRUE 1
7213+#define FALSE 0
7214+#endif
7215+
7216+#define PAGE_SIZE 4096
7217+
7218+typedef void VOID;
7219+typedef VOID *PVOID;
7220+
7221+typedef char CHAR, *PCHAR;
7222+typedef unsigned char UCHAR, *PUCHAR;
7223+typedef short SHORT, *PSHORT;
7224+typedef short CSHORT, *PCSHORT;
7225+typedef unsigned short USHORT, *PUSHORT;
7226+typedef unsigned long ULONG, *PULONG;
7227+typedef long LONG, *PLONG;
7228+
7229+typedef unsigned long BOOLEAN;
7230+
7231+typedef unsigned long AAC_STATUS, *PNT_STATUS;
7232+
7233+typedef struct {
7234+ unsigned long LowPart;
7235+ unsigned long HighPart;
7236+} LARGE_INTEGER;
7237+
7238+typedef LARGE_INTEGER PHYSICAL_ADDRESS;
7239+
7240+
7241+typedef struct _AFA_IOCTL_CMD {
7242+ int cmd;
7243+ intptr_t arg;
7244+ int flag;
7245+ cred_t *cred_p;
7246+ int *rval_p;
7247+} AFA_IOCTL_CMD, *PAFA_IOCTL_CMD;
7248+
7249+
7250+//
7251+// Singly linked list structure. Can be used as either a list head, or
7252+// as link words.
7253+//
7254+
7255+typedef struct _SINGLE_LIST_ENTRY {
7256+ struct _SINGLE_LIST_ENTRY *Next;
7257+} SINGLE_LIST_ENTRY, *PSINGLE_LIST_ENTRY;
7258+
7259+
7260+//
7261+// Calculate the address of the base of the structure given its type, and an
7262+// address of a field within the structure.
7263+//
7264+
7265+#define CONTAINING_RECORD(address, type, field) ((type *)( \
7266+ (PCHAR)(address) - \
7267+ (PCHAR)(&((type *)0)->field)))
7268+
7269+typedef PVOID PMDL;
7270+typedef PVOID PDEVICE_OBJECT;
7271+typedef PVOID PADAPTER_OBJECT;
7272+typedef ULONG KIRQL;
7273+typedef PVOID HANDLE;
7274+typedef PVOID KDPC, *PKDPC;
7275+typedef PVOID PFILE_OBJECT;
7276+typedef PVOID PIRP;
7277+typedef PVOID PDRIVER_OBJECT;
7278+typedef ULONG KTIMER;
7279+
7280+
7281+#define STATUS_SUCCESS 0x00000000
7282+#define STATUS_PENDING 0x40000001
7283+#define STATUS_IO_TIMEOUT 0xc0000001
7284+#define STATUS_UNSUCCESSFUL 0xc0000002
7285+#define STATUS_INSUFFICIENT_RESOURCES 0xc0000005
7286+#define STATUS_BUFFER_OVERFLOW 0xc0000003
7287+
7288+
7289+#define OUT
7290+
7291+
7292+
7293+typedef u_int
7294+(*PUNIX_INTR_HANDLER)(caddr_t Arg);
7295+
7296+//
7297+// Zone Allocation
7298+//
7299+
7300+typedef struct _ZONE_SEGMENT_HEADER {
7301+ SINGLE_LIST_ENTRY SegmentList;
7302+ PVOID Reserved;
7303+} ZONE_SEGMENT_HEADER, *PZONE_SEGMENT_HEADER;
7304+
7305+typedef struct _ZONE_HEADER {
7306+ SINGLE_LIST_ENTRY FreeList;
7307+ SINGLE_LIST_ENTRY SegmentList;
7308+ ULONG BlockSize;
7309+ ULONG TotalSegmentSize;
7310+} ZONE_HEADER, *PZONE_HEADER;
7311+
7312+
7313+//++
7314+//
7315+// PVOID
7316+// ExAllocateFromZone(
7317+// IN PZONE_HEADER Zone
7318+// )
7319+//
7320+// Routine Description:
7321+//
7322+// This routine removes an entry from the zone and returns a pointer to it.
7323+//
7324+// Arguments:
7325+//
7326+// Zone - Pointer to the zone header controlling the storage from which the
7327+// entry is to be allocated.
7328+//
7329+// Return Value:
7330+//
7331+// The function value is a pointer to the storage allocated from the zone.
7332+//
7333+//--
7334+
7335+#define ExAllocateFromZone(Zone) \
7336+ (PVOID)((Zone)->FreeList.Next); \
7337+ if ( (Zone)->FreeList.Next ) (Zone)->FreeList.Next = (Zone)->FreeList.Next->Next
7338+
7339+//++
7340+//
7341+// PVOID
7342+// ExFreeToZone(
7343+// IN PZONE_HEADER Zone,
7344+// IN PVOID Block
7345+// )
7346+//
7347+// Routine Description:
7348+//
7349+// This routine places the specified block of storage back onto the free
7350+// list in the specified zone.
7351+//
7352+// Arguments:
7353+//
7354+// Zone - Pointer to the zone header controlling the storage to which the
7355+// entry is to be inserted.
7356+//
7357+// Block - Pointer to the block of storage to be freed back to the zone.
7358+//
7359+// Return Value:
7360+//
7361+// Pointer to previous block of storage that was at the head of the free
7362+// list. NULL implies the zone went from no available free blocks to
7363+// at least one free block.
7364+//
7365+//--
7366+
7367+#define ExFreeToZone(Zone,Block) \
7368+ ( ((PSINGLE_LIST_ENTRY)(Block))->Next = (Zone)->FreeList.Next, \
7369+ (Zone)->FreeList.Next = ((PSINGLE_LIST_ENTRY)(Block)), \
7370+ ((PSINGLE_LIST_ENTRY)(Block))->Next \
7371+ )
7372+
7373+//++
7374+//
7375+// BOOLEAN
7376+// ExIsFullZone(
7377+// IN PZONE_HEADER Zone
7378+// )
7379+//
7380+// Routine Description:
7381+//
7382+// This routine determines if the specified zone is full or not. A zone
7383+// is considered full if the free list is empty.
7384+//
7385+// Arguments:
7386+//
7387+// Zone - Pointer to the zone header to be tested.
7388+//
7389+// Return Value:
7390+//
7391+// TRUE if the zone is full and FALSE otherwise.
7392+//
7393+//--
7394+
7395+#define ExIsFullZone(Zone) \
7396+ ( (Zone)->FreeList.Next == (PSINGLE_LIST_ENTRY)NULL )
7397+
7398+
7399+#define RtlCopyMemory( Destination, Source, Size ) bcopy( (Source), (Destination), (Size) )
7400+#define RtlZeroMemory( Destination, Size ) bzero( (Destination), (Size) )
7401+
7402+//
7403+// Doubly-linked list manipulation routines. Implemented as macros
7404+// but logically these are procedures.
7405+//
7406+
7407+//
7408+// VOID
7409+// InitializeListHead(
7410+// PLIST_ENTRY ListHead
7411+// );
7412+//
7413+
7414+#define InitializeListHead(ListHead) (\
7415+ (ListHead)->Flink = (ListHead)->Blink = (ListHead))
7416+
7417+//
7418+// BOOLEAN
7419+// IsListEmpty(
7420+// PLIST_ENTRY ListHead
7421+// );
7422+//
7423+
7424+#define IsListEmpty(ListHead) \
7425+ ((ListHead)->Flink == (ListHead))
7426+
7427+//
7428+// PLIST_ENTRY
7429+// RemoveHeadList(
7430+// PLIST_ENTRY ListHead
7431+// );
7432+//
7433+
7434+#define RemoveHeadList(ListHead) \
7435+ (ListHead)->Flink;\
7436+ {RemoveEntryList((ListHead)->Flink)}
7437+
7438+
7439+//
7440+// VOID
7441+// RemoveEntryList(
7442+// PLIST_ENTRY Entry
7443+// );
7444+//
7445+
7446+#define RemoveEntryList(Entry) {\
7447+ PLIST_ENTRY _EX_Blink;\
7448+ PLIST_ENTRY _EX_Flink;\
7449+ _EX_Flink = (Entry)->Flink;\
7450+ _EX_Blink = (Entry)->Blink;\
7451+ _EX_Blink->Flink = _EX_Flink;\
7452+ _EX_Flink->Blink = _EX_Blink;\
7453+ }
7454+
7455+//
7456+// VOID
7457+// InsertTailList(
7458+// PLIST_ENTRY ListHead,
7459+// PLIST_ENTRY Entry
7460+// );
7461+//
7462+
7463+#define InsertTailList(ListHead,Entry) {\
7464+ PLIST_ENTRY _EX_Blink;\
7465+ PLIST_ENTRY _EX_ListHead;\
7466+ _EX_ListHead = (ListHead);\
7467+ _EX_Blink = _EX_ListHead->Blink;\
7468+ (Entry)->Flink = _EX_ListHead;\
7469+ (Entry)->Blink = _EX_Blink;\
7470+ _EX_Blink->Flink = (Entry);\
7471+ _EX_ListHead->Blink = (Entry);\
7472+ }
7473+
7474+#endif /* AAC_UNIX_DEFS */
7475diff -burN linux-2.4.9/drivers/scsi/aacraid/include/adapter.h linux/drivers/scsi/aacraid/include/adapter.h
7476--- linux-2.4.9/drivers/scsi/aacraid/include/adapter.h Wed Dec 31 18:00:00 1969
7477+++ linux/drivers/scsi/aacraid/include/adapter.h Thu Aug 16 13:41:30 2001
7478@@ -0,0 +1,164 @@
7479+/*++
7480+ * Adaptec aacraid device driver for Linux.
7481+ *
7482+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
7483+ *
7484+ * This program is free software; you can redistribute it and/or modify
7485+ * it under the terms of the GNU General Public License as published by
7486+ * the Free Software Foundation; either version 2, or (at your option)
7487+ * any later version.
7488+ *
7489+ * This program is distributed in the hope that it will be useful,
7490+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7491+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7492+ * GNU General Public License for more details.
7493+ *
7494+ * You should have received a copy of the GNU General Public License
7495+ * along with this program; see the file COPYING. If not, write to
7496+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
7497+ *
7498+ * Module Name:
7499+ *
7500+ * Adapter.h
7501+ *
7502+ * Abstract:
7503+ * The module contains the definitions for a comm layer view of the adapter.
7504+ *
7505+ *
7506+ *
7507+ --*/
7508+
7509+#ifndef _ADAPTER_
7510+#define _ADAPTER_
7511+
7512+static char *ident_adapter = "aacraid_ident adapter.h 1.0.6 2000/10/09 Adaptec, Inc.";
7513+
7514+typedef struct _GET_ADAPTER_FIB_CONTEXT {
7515+
7516+ NODE_TYPE_CODE NodeTypeCode; // used for verification of structure
7517+ NODE_BYTE_SIZE NodeByteSize;
7518+ PFILE_OBJECT FileObject; // used for cleanup
7519+ LIST_ENTRY NextContext; // used to link context's into a linked list
7520+ OS_CV_T UserEvent; // this is used to wait for the next fib to arrive.
7521+ BOOLEAN WaitingForFib; // Set to true when thread is in WaitForSingleObject
7522+ ULONG FibCount; // total number of FIBs on FibList
7523+ LIST_ENTRY FibList;
7524+} GET_ADAPTER_FIB_CONTEXT;
7525+typedef GET_ADAPTER_FIB_CONTEXT *PGET_ADAPTER_FIB_CONTEXT;
7526+
7527+
7528+typedef struct _FIB_CONTEXT_ZONE_SEGMENT {
7529+
7530+ struct _FIB_CONTEXT_ZONE_SEGMENT *Next;
7531+ ULONG FibContextSegmentSize;
7532+ PVOID FibContextSegment;
7533+ ULONG ExtendSize;
7534+ MAPFIB_CONTEXT MapFibContext;
7535+
7536+} FIB_CONTEXT_ZONE_SEGMENT;
7537+typedef FIB_CONTEXT_ZONE_SEGMENT *PFIB_CONTEXT_ZONE_SEGMENT;
7538+
7539+typedef struct _AFA_COMM_ADAPTER {
7540+
7541+ struct _AFA_COMM_ADAPTER *NextAdapter;
7542+
7543+ //
7544+ // The following fields are used to allocate FIB context structures
7545+ // using the zone allocator, and other fixed sized structures from a
7546+ // small cache. The mutex protects access to the zone/lists
7547+ //
7548+
7549+ ZONE_HEADER FibContextZone;
7550+ OS_SPINLOCK *FibContextZoneSpinLock;
7551+ int FibContextZoneExtendSize;
7552+
7553+ PFIB_CONTEXT_ZONE_SEGMENT FibContextSegmentList;
7554+
7555+ PVOID FibContextTimedOutList;
7556+
7557+ PFIB SyncFib;
7558+ ULONG SyncFibPhysicalAddress;
7559+
7560+ PCOMM_REGION CommRegion;
7561+
7562+ OS_SPINLOCK_COOKIE SpinLockCookie;
7563+
7564+ //
7565+ // The user API will use an IOCTL to register itself to receive FIBs
7566+ // from the adapter. The following list is used to keep track of all
7567+ // the threads that have requested these FIBs. The mutex is used to
7568+ // synchronize access to all data associated with the adapter fibs.
7569+ //
7570+ LIST_ENTRY AdapterFibContextList;
7571+ OS_CVLOCK *AdapterFibMutex;
7572+
7573+ //
7574+ // The following holds which FileObject is allow to send configuration
7575+ // commands to the adapter that would modify the configuration.
7576+ //
7577+ // This is controlled by the FSACTL_OPEN_ADAPTER_CONFIG and FSACTL_CLOSE_ADAPTER_CONFIG
7578+ // ioctls.
7579+ //
7580+ PFILE_OBJECT AdapterConfigFileObject;
7581+
7582+ //
7583+ // The following is really here because of the simulator
7584+ //
7585+ BOOLEAN InterruptsBelowDpc;
7586+
7587+ //
7588+ // The following is the device specific extension.
7589+ //
7590+ PVOID AdapterExtension;
7591+ PFSAPORT_FUNCS AdapterFuncs;
7592+ void *Dip;
7593+
7594+ //
7595+ // The following are user variables that are specific to the mini port.
7596+ //
7597+ PFSA_USER_VAR AdapterUserVars;
7598+ ULONG AdapterUserVarsSize;
7599+
7600+ //
7601+ // The following is the number of the individual adapter..i.e. \Device\Afa0
7602+ //
7603+ LONG AdapterNumber;
7604+
7605+ AFACOMM_FUNCS CommFuncs;
7606+
7607+ PAFA_CLASS_DRIVER ClassDriverList;
7608+
7609+ BOOLEAN AifThreadStarted;
7610+
7611+} AFA_COMM_ADAPTER;
7612+
7613+typedef AFA_COMM_ADAPTER *PAFA_COMM_ADAPTER;
7614+
7615+
7616+#define FsaAllocateAdapterCommArea(Adapter, BaseAddress, Size, Alignment) \
7617+ Adapter->AdapterFuncs->AllocateAdapterCommArea(Adapter->AdapterExtension, BaseAddress, Size, Alignment)
7618+
7619+#define FsaFreeAdapterCommArea(Adapter) \
7620+ Adapter->AdapterFuncs->FreeAdapterCommArea(Adapter->AdapterExtension)
7621+
7622+
7623+#define AllocateAndMapFibSpace(Adapter, MapFibContext) \
7624+ Adapter->AdapterFuncs->AllocateAndMapFibSpace(Adapter->AdapterExtension, MapFibContext)
7625+
7626+#define UnmapAndFreeFibSpace(Adapter, MapFibContext) \
7627+ Adapter->AdapterFuncs->UnmapAndFreeFibSpace(Adapter->AdapterExtension, MapFibContext)
7628+
7629+#define InterruptAdapter(Adapter) \
7630+ Adapter->AdapterFuncs->InterruptAdapter(Adapter->AdapterExtension)
7631+
7632+#define NotifyAdapter(Adapter, AdapterEvent) \
7633+ Adapter->AdapterFuncs->NotifyAdapter(Adapter->AdapterExtension, AdapterEvent)
7634+
7635+#define EnableInterrupt(Adapter, AdapterEvent, AtDeviceIrq) \
7636+ Adapter->AdapterFuncs->EnableInterrupt(Adapter->AdapterExtension, AdapterEvent, AtDeviceIrq)
7637+
7638+#define DisableInterrupt(Adapter, AdapterEvent, AtDeviceIrq) \
7639+ Adapter->AdapterFuncs->DisableInterrupt(Adapter->AdapterExtension, AdapterEvent, AtDeviceIrq)
7640+
7641+
7642+#endif // _ADAPTER_
7643diff -burN linux-2.4.9/drivers/scsi/aacraid/include/afacomm.h linux/drivers/scsi/aacraid/include/afacomm.h
7644--- linux-2.4.9/drivers/scsi/aacraid/include/afacomm.h Wed Dec 31 18:00:00 1969
7645+++ linux/drivers/scsi/aacraid/include/afacomm.h Thu Aug 16 13:41:30 2001
7646@@ -0,0 +1,191 @@
7647+/*++
7648+ * Adaptec aacraid device driver for Linux.
7649+ *
7650+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
7651+ *
7652+ * This program is free software; you can redistribute it and/or modify
7653+ * it under the terms of the GNU General Public License as published by
7654+ * the Free Software Foundation; either version 2, or (at your option)
7655+ * any later version.
7656+ *
7657+ * This program is distributed in the hope that it will be useful,
7658+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7659+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7660+ * GNU General Public License for more details.
7661+ *
7662+ * You should have received a copy of the GNU General Public License
7663+ * along with this program; see the file COPYING. If not, write to
7664+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
7665+ *
7666+ * Module Name:
7667+ * AfaComm.h
7668+ *
7669+ * Abstract:
7670+ * This module defines all of the external interfaces to the AFA comm layer.
7671+ *
7672+ *
7673+ *
7674+ --*/
7675+#ifndef _AFACOMM_
7676+#define _AFACOMM_
7677+
7678+static char *ident_afacomm = "aacraid_ident afacomm.h 1.0.6 2000/10/09 Adaptec, Inc.";
7679+
7680+#include "fsaport.h"
7681+
7682+typedef void *PFIB_CONTEXT;
7683+
7684+typedef VOID
7685+(*PFIB_CALLBACK)(
7686+ PVOID FibCallbackContext,
7687+ PFIB_CONTEXT FibContext,
7688+ AAC_STATUS Status
7689+ );
7690+
7691+
7692+typedef PFIB_CONTEXT
7693+(*PAFA_COMM_ALLOCATE_FIB) (
7694+ IN PVOID AdapterExtension
7695+ );
7696+
7697+typedef VOID
7698+(*PAFA_COMM_FREE_FIB) (
7699+ IN PFIB_CONTEXT FibContext
7700+ );
7701+
7702+
7703+typedef AAC_STATUS
7704+(*PAFA_COMM_DEALLOCATE_FIB) (
7705+ IN PFIB_CONTEXT FibContext
7706+ );
7707+
7708+
7709+typedef VOID
7710+(*PAFA_COMM_FREE_FIB_FROM_DPC) (
7711+ IN PFIB_CONTEXT FibContext
7712+ );
7713+
7714+typedef AAC_STATUS
7715+(*PAFA_COMM_INITIALIZE_FIB) (
7716+ IN PFIB_CONTEXT FibContext
7717+ );
7718+
7719+typedef PVOID
7720+(*PAFA_COMM_GET_FIB_DATA) (
7721+ IN PFIB_CONTEXT FibContext
7722+ );
7723+
7724+typedef AAC_STATUS
7725+(*PAFA_COMM_SEND_FIB) (
7726+ IN FIB_COMMAND Command,
7727+ IN PFIB_CONTEXT FibContext,
7728+ IN ULONG Size,
7729+ IN COMM_PRIORITIES Priority,
7730+ IN BOOLEAN Wait,
7731+ IN PVOID WaitOn,
7732+ IN BOOLEAN ResponseExpected,
7733+ IN PFIB_CALLBACK FibCallback,
7734+ IN PVOID FibCallbackContext
7735+ );
7736+
7737+typedef AAC_STATUS
7738+(*PAFA_COMM_COMPLETE_FIB) (
7739+ IN PFIB_CONTEXT FibContext
7740+ );
7741+
7742+typedef AAC_STATUS
7743+(*PAFA_COMM_COMPLETE_ADAPTER_FIB) (
7744+ IN PFIB_CONTEXT FibContext,
7745+ IN USHORT Size
7746+ );
7747+
7748+typedef BOOLEAN
7749+(*PAFA_COMM_SEND_SYNCH_FIB) (
7750+ PVOID AdapterExtension,
7751+ FIB_COMMAND Command,
7752+ PVOID Data,
7753+ USHORT Size,
7754+ PVOID Response,
7755+ USHORT *ResponseSize
7756+ );
7757+
7758+
7759+typedef struct _AFACOMM_FUNCS {
7760+ ULONG SizeOfAfaCommFuncs;
7761+ PAFA_COMM_ALLOCATE_FIB AllocateFib;
7762+ PAFA_COMM_FREE_FIB FreeFib;
7763+ PAFA_COMM_FREE_FIB_FROM_DPC FreeFibFromDpc;
7764+ PAFA_COMM_DEALLOCATE_FIB DeallocateFib;
7765+ PAFA_COMM_INITIALIZE_FIB InitializeFib;
7766+ PAFA_COMM_GET_FIB_DATA GetFibData;
7767+ PAFA_COMM_SEND_FIB SendFib;
7768+ PAFA_COMM_COMPLETE_FIB CompleteFib;
7769+ PAFA_COMM_COMPLETE_ADAPTER_FIB CompleteAdapterFib;
7770+ PAFA_COMM_SEND_SYNCH_FIB SendSynchFib;
7771+ PFSA_FREE_DMA_RESOURCES FreeDmaResources;
7772+ PFSA_BUILD_SGMAP BuildSgMap;
7773+ PFSA_ADAPTER_ADDR_TO_SYSTEM_ADDR AdapterAddressToSystemAddress;
7774+} AFACOMM_FUNCS;
7775+typedef AFACOMM_FUNCS *PAFACOMM_FUNCS;
7776+
7777+
7778+typedef AAC_STATUS
7779+(*PAFA_CLASS_OPEN_ADAPTER) (
7780+ IN PVOID Adapter
7781+ );
7782+
7783+
7784+typedef AAC_STATUS
7785+(*PAFA_CLASS_CLOSE_ADAPTER) (
7786+ IN PVOID Adapter
7787+ );
7788+
7789+
7790+typedef BOOLEAN
7791+(*PAFA_CLASS_DEV_CONTROL) (
7792+ IN PVOID Adapter,
7793+ IN PAFA_IOCTL_CMD IoctlCmdPtr,
7794+ OUT int * Status
7795+ );
7796+
7797+typedef BOOLEAN
7798+(*PAFA_CLASS_HANDLE_AIF) (
7799+ IN PVOID Adapter,
7800+ IN PFIB_CONTEXT FibContext
7801+ );
7802+
7803+
7804+typedef struct _AFA_NEW_CLASS_DRIVER {
7805+ PVOID ClassDriverExtension;
7806+ PAFA_CLASS_OPEN_ADAPTER OpenAdapter;
7807+ PAFA_CLASS_CLOSE_ADAPTER CloseAdapter;
7808+ PAFA_CLASS_DEV_CONTROL DeviceControl;
7809+ PAFA_CLASS_HANDLE_AIF HandleAif;
7810+ PFSA_USER_VAR UserVars;
7811+ ULONG NumUserVars;
7812+} AFA_NEW_CLASS_DRIVER;
7813+typedef AFA_NEW_CLASS_DRIVER *PAFA_NEW_CLASS_DRIVER;
7814+
7815+
7816+typedef struct _AFA_NEW_CLASS_DRIVER_RESPONSE {
7817+ PAFACOMM_FUNCS CommFuncs;
7818+ PVOID CommPortExtension;
7819+ PVOID MiniPortExtension;
7820+ OS_SPINLOCK_COOKIE SpinLockCookie;
7821+ void *Dip;
7822+} AFA_NEW_CLASS_DRIVER_RESPONSE;
7823+typedef AFA_NEW_CLASS_DRIVER_RESPONSE *PAFA_NEW_CLASS_DRIVER_RESPONSE;
7824+
7825+
7826+typedef struct _AFA_CLASS_DRIVER {
7827+ struct _AFA_CLASS_DRIVER *Next;
7828+ PVOID ClassDriverExtension;
7829+ PAFA_CLASS_OPEN_ADAPTER OpenAdapter;
7830+ PAFA_CLASS_CLOSE_ADAPTER CloseAdapter;
7831+ PAFA_CLASS_DEV_CONTROL DeviceControl;
7832+ PAFA_CLASS_HANDLE_AIF HandleAif;
7833+} AFA_CLASS_DRIVER;
7834+typedef AFA_CLASS_DRIVER *PAFA_CLASS_DRIVER;
7835+
7836+
7837+#endif // _AFACOMM_
7838diff -burN linux-2.4.9/drivers/scsi/aacraid/include/aifstruc.h linux/drivers/scsi/aacraid/include/aifstruc.h
7839--- linux-2.4.9/drivers/scsi/aacraid/include/aifstruc.h Wed Dec 31 18:00:00 1969
7840+++ linux/drivers/scsi/aacraid/include/aifstruc.h Thu Aug 16 13:41:30 2001
7841@@ -0,0 +1,319 @@
7842+/*++
7843+ * Adaptec aacraid device driver for Linux.
7844+ *
7845+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
7846+ *
7847+ * This program is free software; you can redistribute it and/or modify
7848+ * it under the terms of the GNU General Public License as published by
7849+ * the Free Software Foundation; either version 2, or (at your option)
7850+ * any later version.
7851+ *
7852+ * This program is distributed in the hope that it will be useful,
7853+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7854+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7855+ * GNU General Public License for more details.
7856+ *
7857+ * You should have received a copy of the GNU General Public License
7858+ * along with this program; see the file COPYING. If not, write to
7859+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
7860+ *
7861+ * Module Name:
7862+ * Aifstruc.h
7863+ *
7864+ * Abstract:
7865+ * Define all shared data types relating to
7866+ * the set of features utilizing Adapter
7867+ * Initiated Fibs.
7868+ *
7869+ *
7870+ *
7871+ --*/
7872+#ifndef _AIFSTRUC_H
7873+#define _AIFSTRUC_H
7874+
7875+static char *ident_aifstruc = "aacraid_ident aifstruc.h 1.0.6 2000/10/09 Adaptec, Inc.";
7876+
7877+#include <protocol.h>
7878+
7879+//
7880+// Progress report structure definitions
7881+//
7882+typedef enum {
7883+ AifJobStsSuccess = 1,
7884+ AifJobStsFinished,
7885+ AifJobStsAborted,
7886+ AifJobStsFailed,
7887+ AifJobStsLastReportMarker = 100, // All before mean last report
7888+ AifJobStsSuspended,
7889+ AifJobStsRunning
7890+} _E_AifJobStatus;
7891+
7892+#ifdef AAC_32BIT_ENUMS
7893+typedef _E_AifJobStatus AifJobStatus;
7894+#else
7895+typedef AAC_UINT32 AifJobStatus;
7896+#endif
7897+
7898+
7899+typedef enum {
7900+ AifJobScsiMin = 1, // Minimum value for Scsi operation
7901+ AifJobScsiZero, // SCSI device clear operation
7902+ AifJobScsiVerify, // SCSI device Verify operation NO REPAIR
7903+ AifJobScsiExercise, // SCSI device Exercise operation
7904+ AifJobScsiVerifyRepair, // SCSI device Verify operation WITH repair
7905+ // Add new SCSI task types above this line
7906+ AifJobScsiMax = 99, // Max Scsi value
7907+ AifJobCtrMin, // Min Ctr op value
7908+ AifJobCtrZero, // Container clear operation
7909+ AifJobCtrCopy, // Container copy operation
7910+ AifJobCtrCreateMirror, // Container Create Mirror operation
7911+ AifJobCtrMergeMirror, // Container Merge Mirror operation
7912+ AifJobCtrScrubMirror, // Container Scrub Mirror operation
7913+ AifJobCtrRebuildRaid5, // Container Rebuild Raid5 operation
7914+ AifJobCtrScrubRaid5, // Container Scrub Raid5 operation
7915+ AifJobCtrMorph, // Container morph operation
7916+ AifJobCtrPartCopy, // Container Partition copy operation
7917+ AifJobCtrRebuildMirror, // Container Rebuild Mirror operation
7918+ AifJobCtrCrazyCache, // crazy cache
7919+ // Add new container task types above this line
7920+ AifJobCtrMax = 199, // Max Ctr type operation
7921+ AifJobFsMin, // Min Fs type operation
7922+ AifJobFsCreate, // File System Create operation
7923+ AifJobFsVerify, // File System Verify operation
7924+ AifJobFsExtend, // File System Extend operation
7925+ // Add new file system task types above this line
7926+ AifJobFsMax = 299, // Max Fs type operation
7927+ // Add new API task types here
7928+ AifJobApiFormatNTFS, // Format a drive to NTFS
7929+ AifJobApiFormatFAT, // Format a drive to FAT
7930+ AifJobApiUpdateSnapshot, // update the read/write half of a snapshot
7931+ AifJobApiFormatFAT32, // Format a drive to FAT32
7932+ AifJobApiMax = 399, // Max API type operation
7933+ AifJobCtlContinuousCtrVerify, // Controller operation
7934+ AifJobCtlMax = 499 // Max Controller type operation
7935+
7936+} _E_AifJobType;
7937+
7938+#ifdef AAC_32BIT_ENUMS
7939+typedef _E_AifJobType AifJobType;
7940+#else
7941+typedef AAC_UINT32 AifJobType;
7942+#endif
7943+
7944+union SrcContainer {
7945+ AAC_UINT32 from;
7946+ AAC_UINT32 master;
7947+ AAC_UINT32 container;
7948+};
7949+
7950+union DstContainer {
7951+ AAC_UINT32 to;
7952+ AAC_UINT32 slave;
7953+ AAC_UINT32 container;
7954+};
7955+
7956+
7957+struct AifContainers {
7958+ union SrcContainer src;
7959+ union DstContainer dst;
7960+};
7961+
7962+union AifJobClient {
7963+
7964+ struct AifContainers container; // For Container nd file system progress ops;
7965+ AAC_INT32 scsi_dh; // For SCSI progress ops
7966+};
7967+
7968+struct AifJobDesc {
7969+ AAC_UINT32 jobID; // DO NOT FILL IN! Will be filled in by AIF
7970+ AifJobType type; // Operation that is being performed
7971+ union AifJobClient client; // Details
7972+};
7973+
7974+struct AifJobProgressReport {
7975+ struct AifJobDesc jd;
7976+ AifJobStatus status;
7977+ AAC_UINT32 finalTick;
7978+ AAC_UINT32 currentTick;
7979+ AAC_UINT32 jobSpecificData1;
7980+ AAC_UINT32 jobSpecificData2;
7981+};
7982+
7983+//
7984+// Notification of events structure definition starts here
7985+//
7986+typedef enum {
7987+ // General application notifies start here
7988+ AifEnGeneric = 1, // Generic notification
7989+ AifEnTaskComplete, // Task has completed
7990+ AifEnConfigChange, // Adapter configuration change occurred
7991+ AifEnContainerChange, // Adapter specific container configuration change
7992+ AifEnDeviceFailure, // SCSI device failed
7993+ AifEnMirrorFailover, // Mirror failover started
7994+ AifEnContainerEvent, // Significant container event
7995+ AifEnFileSystemChange, // File system changed
7996+ AifEnConfigPause, // Container pause event
7997+ AifEnConfigResume, // Container resume event
7998+ AifEnFailoverChange, // Failover space assignment changed
7999+ AifEnRAID5RebuildDone, // RAID5 rebuild finished
8000+ AifEnEnclosureManagement, // Enclosure management event
8001+ AifEnBatteryEvent, // Significant NV battery event
8002+ AifEnAddContainer, // A new container was created.
8003+ AifEnDeleteContainer, // A container was deleted.
8004+ AifEnSMARTEvent, // SMART Event
8005+ AifEnBatteryNeedsRecond, // The battery needs reconditioning
8006+ AifEnClusterEvent, // Some cluster event
8007+ AifEnDiskSetEvent, // A disk set event occured.
8008+ // Add general application notifies above this comment
8009+ AifDriverNotifyStart=199, // Notifies for host driver go here
8010+ // Host driver notifications start here
8011+ AifDenMorphComplete, // A morph operation completed
8012+ AifDenVolumeExtendComplete // A volume expand operation completed
8013+ // Add host driver notifications above this comment
8014+} _E_AifEventNotifyType;
8015+
8016+#ifdef AAC_32BIT_ENUMS
8017+typedef _E_AifEventNotifyType AifEventNotifyType;
8018+#else
8019+typedef AAC_UINT32 AifEventNotifyType;
8020+#endif
8021+
8022+struct AifEnsGeneric {
8023+ AAC_INT8 text[132]; // Generic text
8024+};
8025+
8026+struct AifEnsDeviceFailure {
8027+ AAC_INT32 deviceHandle; // SCSI device handle
8028+};
8029+
8030+struct AifEnsMirrorFailover {
8031+ AAC_UINT32 container; // Container with failed element
8032+ AAC_UINT32 failedSlice; // Old slice which failed
8033+ AAC_UINT32 creatingSlice; // New slice used for auto-create
8034+};
8035+
8036+struct AifEnsContainerChange {
8037+ AAC_UINT32 container[2]; // container that changed, -1 if no container
8038+};
8039+
8040+struct AifEnsContainerEvent {
8041+ AAC_UINT32 container; // container number
8042+ AAC_UINT32 eventType; // event type
8043+};
8044+
8045+struct AifEnsEnclosureEvent {
8046+ AAC_UINT32 empID; // enclosure management processor number
8047+ AAC_UINT32 unitID; // unitId, fan id, power supply id, slot id, tempsensor id.
8048+ AAC_UINT32 eventType; // event type
8049+};
8050+
8051+
8052+struct AifEnsBatteryEvent {
8053+ NVBATT_TRANSITION transition_type; // e.g. from low to ok
8054+ NVBATTSTATUS current_state; // current battery state
8055+ NVBATTSTATUS prior_state; // previous battery state
8056+};
8057+
8058+struct AifEnsDiskSetEvent {
8059+ AAC_UINT32 eventType;
8060+ AAC_UINT32 DsNum[2];
8061+ AAC_UINT32 CreatorId[2];
8062+};
8063+
8064+
8065+
8066+typedef enum _CLUSTER_AIF_EVENT {
8067+ CLUSTER_NULL_EVENT = 0,
8068+ CLUSTER_PARTNER_NAME_EVENT, // change in partner hostname or adaptername from NULL to non-NULL
8069+ // (partner's agent may be up)
8070+ CLUSTER_PARTNER_NULL_NAME_EVENT // change in partner hostname or adaptername from non-null to NULL
8071+ // (partner has rebooted)
8072+} _E_CLUSTER_AIF_EVENT;
8073+
8074+#ifdef AAC_32BIT_ENUMS
8075+typedef _E_CLUSTER_AIF_EVENT CLUSTER_AIF_EVENT;
8076+#else
8077+typedef AAC_UINT32 CLUSTER_AIF_EVENT;
8078+#endif
8079+
8080+struct AifEnsClusterEvent {
8081+ CLUSTER_AIF_EVENT eventType;
8082+};
8083+
8084+struct AifEventNotify {
8085+ AifEventNotifyType type;
8086+ union {
8087+ struct AifEnsGeneric EG;
8088+ struct AifEnsDeviceFailure EDF;
8089+ struct AifEnsMirrorFailover EMF;
8090+ struct AifEnsContainerChange ECC;
8091+ struct AifEnsContainerEvent ECE;
8092+ struct AifEnsEnclosureEvent EEE;
8093+ struct AifEnsBatteryEvent EBE;
8094+ struct AifEnsDiskSetEvent EDS;
8095+#ifdef BRIDGE
8096+ struct AifEnsSMARTEvent ES;
8097+#endif
8098+ struct AifEnsClusterEvent ECLE;
8099+ } data;
8100+};
8101+
8102+//
8103+// Generic API structure
8104+//
8105+#define AIF_API_REPORT_MAX_SIZE 64
8106+typedef AAC_INT8 AifApiReport[AIF_API_REPORT_MAX_SIZE];
8107+
8108+
8109+
8110+//
8111+// For FIB communication, we need all of the following things
8112+// to send back to the user.
8113+//
8114+typedef enum {
8115+ AifCmdEventNotify = 1, // Notify of event
8116+ AifCmdJobProgress, // Progress report
8117+ AifCmdAPIReport, // Report from other user of API
8118+ AifCmdDriverNotify, // Notify host driver of event
8119+ AifReqJobList = 100, // Gets back complete job list
8120+ AifReqJobsForCtr, // Gets back jobs for specific container
8121+ AifReqJobsForScsi, // Gets back jobs for specific SCSI device
8122+ AifReqJobReport, // Gets back a specific job report or list of them
8123+ AifReqTerminateJob, // Terminates job
8124+ AifReqSuspendJob, // Suspends a job
8125+ AifReqResumeJob, // Resumes a job
8126+ AifReqSendAPIReport, // API generic report requests
8127+ AifReqAPIJobStart, // Start a job from the API
8128+ AifReqAPIJobUpdate, // Update a job report from the API
8129+ AifReqAPIJobFinish // Finish a job from the API
8130+} _E_AIFCOMMAND;
8131+
8132+#ifdef AAC_32BIT_ENUMS
8133+typedef _E_AIFCOMMAND AIFCOMMAND;
8134+#else
8135+typedef AAC_UINT32 AIFCOMMAND;
8136+#endif
8137+
8138+
8139+
8140+//
8141+// Adapter Initiated FIB command structures. Start with the adapter
8142+// initiated FIBs that really come from the adapter, and get responded
8143+// to by the host.
8144+//
8145+typedef struct _AIFCOMMANDTOHOST {
8146+ AIFCOMMAND command; // Tell host what type of notify this is
8147+ AAC_UINT32 seqNumber; // To allow ordering of reports (if necessary)
8148+ union {
8149+ // First define data going to the adapter
8150+ struct AifEventNotify EN; // Event notify structure
8151+ struct AifJobProgressReport PR[1]; // Progress report
8152+ AifApiReport AR;
8153+ } data;
8154+} AIFCOMMANDTOHOST, *PAIFCOMMANDTOHOST;
8155+
8156+
8157+#endif // _AIFSTRUC_H
8158+
8159+
8160+
8161diff -burN linux-2.4.9/drivers/scsi/aacraid/include/build_number.h linux/drivers/scsi/aacraid/include/build_number.h
8162--- linux-2.4.9/drivers/scsi/aacraid/include/build_number.h Wed Dec 31 18:00:00 1969
8163+++ linux/drivers/scsi/aacraid/include/build_number.h Thu Aug 16 18:16:55 2001
8164@@ -0,0 +1,39 @@
8165+/*++
8166+ * Adaptec aacraid device driver for Linux.
8167+ *
8168+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8169+ *
8170+ * This program is free software; you can redistribute it and/or modify
8171+ * it under the terms of the GNU General Public License as published by
8172+ * the Free Software Foundation; either version 2, or (at your option)
8173+ * any later version.
8174+ *
8175+ * This program is distributed in the hope that it will be useful,
8176+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
8177+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8178+ * GNU General Public License for more details.
8179+ *
8180+ * You should have received a copy of the GNU General Public License
8181+ * along with this program; see the file COPYING. If not, write to
8182+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8183+ *
8184+ * Module Name:
8185+ * build_number.h
8186+ *
8187+ * Abstract:
8188+ * DThis module contains the single location where the build number
8189+ * is kept.
8190+ *
8191+ *
8192+ *
8193+ --*/
8194+#ifndef _BUILD_NUMBER_H
8195+#define _BUILD_NUMBER_H
8196+
8197+static char *ident_build_num = "aacraid_ident build_number.h 1.0.7 2001/08/10 Adaptec, Inc.";
8198+
8199+#define REV_BUILD_NUMBER 5125
8200+
8201+
8202+#endif // _BUILD_NUMBER_H
8203+
8204diff -burN linux-2.4.9/drivers/scsi/aacraid/include/commdata.h linux/drivers/scsi/aacraid/include/commdata.h
8205--- linux-2.4.9/drivers/scsi/aacraid/include/commdata.h Wed Dec 31 18:00:00 1969
8206+++ linux/drivers/scsi/aacraid/include/commdata.h Thu Aug 16 13:41:30 2001
8207@@ -0,0 +1,112 @@
8208+/*++
8209+ * Adaptec aacraid device driver for Linux.
8210+ *
8211+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8212+ *
8213+ * This program is free software; you can redistribute it and/or modify
8214+ * it under the terms of the GNU General Public License as published by
8215+ * the Free Software Foundation; either version 2, or (at your option)
8216+ * any later version.
8217+ *
8218+ * This program is distributed in the hope that it will be useful,
8219+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
8220+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8221+ * GNU General Public License for more details.
8222+ *
8223+ * You should have received a copy of the GNU General Public License
8224+ * along with this program; see the file COPYING. If not, write to
8225+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8226+ *
8227+ * Module Name:
8228+ * commdata.h
8229+ *
8230+ * Abstract: Define the communication layer of the adapter
8231+ *
8232+ *
8233+ *
8234+ --*/
8235+#ifndef _COMMDATA_
8236+#define _COMMDATA_
8237+
8238+static char *ident_commdata = "aacraid_ident commdata.h 1.0.6 2000/10/09 Adaptec, Inc.";
8239+
8240+typedef struct _FSA_COMM_DATA {
8241+
8242+ //
8243+ // A pointer to the Driver and Device object we were initialized with
8244+ //
8245+
8246+ PDRIVER_OBJECT DriverObject;
8247+ PDEVICE_OBJECT DeviceObject;
8248+
8249+ //
8250+ // A list of all adapters we have configured.
8251+ //
8252+
8253+ PAFA_COMM_ADAPTER AdapterList;
8254+ ULONG TotalAdapters;
8255+
8256+ //
8257+ // Adapter timeout support. This is the default timeout to wait for the
8258+ // adapter to respond(setup in initfs.c), and a boolean to indicate if
8259+ // we should timeout requests to the adapter or not.
8260+ //
8261+
8262+ LARGE_INTEGER QueueFreeTimeout;
8263+ LARGE_INTEGER AdapterTimeout;
8264+ BOOLEAN EnableAdapterTimeouts;
8265+
8266+ ULONG FibTimeoutIncrement;
8267+
8268+ ULONG FibsSent;
8269+ ULONG FibRecved;
8270+ ULONG NoResponseSent;
8271+ ULONG NoResponseRecved;
8272+ ULONG AsyncSent;
8273+ ULONG AsyncRecved;
8274+ ULONG NormalSent;
8275+ ULONG NormalRecved;
8276+
8277+ ULONG TimedOutFibs;
8278+
8279+ KDPC TimeoutDPC;
8280+ KTIMER TimeoutTimer;
8281+
8282+ //
8283+ // If this value is set to 1 then interrupt moderation will occur
8284+ // in the base commuication support.
8285+ //
8286+
8287+ ULONG EnableInterruptModeration;
8288+
8289+ int HardInterruptModeration;
8290+ int HardInterruptModeration1;
8291+ int PeakFibsConsumed;
8292+ int ZeroFibsConsumed;
8293+ int EnableFibTimeoutBreak;
8294+ ULONG FibTimeoutSeconds;
8295+
8296+ //
8297+ // The following holds all of the available user settable variables.
8298+ // This includes all for the comm layer as well as any from the class
8299+ // drivers as well.
8300+ //
8301+
8302+ FSA_USER_VAR *UserVars;
8303+ ULONG NumUserVars;
8304+
8305+
8306+ ULONG MeterFlag;
8307+
8308+#ifdef FIB_CHECKSUMS
8309+ int do_fib_checksums;
8310+#endif
8311+
8312+} FSA_COMM_DATA;
8313+typedef FSA_COMM_DATA *PFSA_COMM_DATA;
8314+
8315+extern FSA_COMM_DATA FsaCommData;
8316+
8317+
8318+#endif // _COMMDATA_
8319+
8320diff -burN linux-2.4.9/drivers/scsi/aacraid/include/commerr.h linux/drivers/scsi/aacraid/include/commerr.h
8321--- linux-2.4.9/drivers/scsi/aacraid/include/commerr.h Wed Dec 31 18:00:00 1969
8322+++ linux/drivers/scsi/aacraid/include/commerr.h Thu Aug 16 18:16:55 2001
8323@@ -0,0 +1,125 @@
8324+/*++
8325+ * Adaptec aacraid device driver for Linux.
8326+ *
8327+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8328+ *
8329+ * This program is free software; you can redistribute it and/or modify
8330+ * it under the terms of the GNU General Public License as published by
8331+ * the Free Software Foundation; either version 2, or (at your option)
8332+ * any later version.
8333+ *
8334+ * This program is distributed in the hope that it will be useful,
8335+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
8336+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8337+ * GNU General Public License for more details.
8338+ *
8339+ * You should have received a copy of the GNU General Public License
8340+ * along with this program; see the file COPYING. If not, write to
8341+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8342+ *
8343+ * Module Name:
8344+ * commerr.h
8345+ *
8346+ * Abstract: This file defines all errors that are unique to the Adaptec Fsa Filesystem
8347+ *
8348+ *
8349+ *
8350+ --*/
8351+
8352+#ifndef _FSAERR_
8353+#define _FSAERR_
8354+
8355+static char *ident_commerr = "aacraid_ident commerr.h 1.0.6 2000/10/09 Adaptec, Inc.";
8356+
8357+//
8358+// Note: comments in the .mc file must use both ";" and "//".
8359+//
8360+// Status values are 32 bit values layed out as follows:
8361+//
8362+// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
8363+// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
8364+// +---+-+-------------------------+-------------------------------+
8365+// |Sev|C| Facility | Code |
8366+// +---+-+-------------------------+-------------------------------+
8367+//
8368+// where
8369+//
8370+// Sev - is the severity code
8371+//
8372+// 00 - Success
8373+// 01 - Informational
8374+// 10 - Warning
8375+// 11 - Error
8376+//
8377+// C - is the Customer code flag
8378+//
8379+// Facility - is the facility code
8380+//
8381+// Code - is the facility's status code
8382+//
8383+
8384+
8385+//
8386+// %1 is reserved by the IO Manager. If IoAllocateErrorLogEntry is
8387+// called with a device, the name of the device will be inserted into
8388+// the message at %1. Otherwise, the place of %1 will be left empty.
8389+// In either case, the insertion strings from the driver's error log
8390+// entry starts at %2. In other words, the first insertion string goes
8391+// to %2, the second to %3 and so on.
8392+//
8393+
8394+//
8395+// Values are 32 bit values layed out as follows:
8396+//
8397+// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
8398+// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
8399+// +---+-+-+-----------------------+-------------------------------+
8400+// |Sev|C|R| Facility | Code |
8401+// +---+-+-+-----------------------+-------------------------------+
8402+//
8403+// where
8404+//
8405+// Sev - is the severity code
8406+//
8407+// 00 - Success
8408+// 01 - Informational
8409+// 10 - Warning
8410+// 11 - Error
8411+//
8412+// C - is the Customer code flag
8413+//
8414+// R - is a reserved bit
8415+//
8416+// Facility - is the facility code
8417+//
8418+// Code - is the facility's status code
8419+//
8420+//
8421+// Define the facility codes
8422+//
8423+
8424+
8425+#define FACILITY_FSAFS_ERROR_CODE 0x7
8426+
8427+
8428+
8429+//
8430+// MessageId: FSAFS_FIB_INVALID
8431+//
8432+// MessageText:
8433+//
8434+// A communication packet was detected to be formatted poorly. Please Contact Adaptec support.
8435+//
8436+#define FSAFS_FIB_INVALID ((AAC_STATUS)0xE0070009L)
8437+
8438+
8439+//
8440+// MessageId: FSAFS_TIMED_OUT_FIB_COMPLETED
8441+//
8442+// MessageText:
8443+//
8444+// A Fib previously timed out by host has been completed by the adapter. (\\.\Afa%2)
8445+//
8446+#define FSAFS_TIMED_OUT_FIB_COMPLETED ((AAC_STATUS)0xA007000EL)
8447+
8448+#endif /* _FSAERR_ */
8449diff -burN linux-2.4.9/drivers/scsi/aacraid/include/commfibcontext.h linux/drivers/scsi/aacraid/include/commfibcontext.h
8450--- linux-2.4.9/drivers/scsi/aacraid/include/commfibcontext.h Wed Dec 31 18:00:00 1969
8451+++ linux/drivers/scsi/aacraid/include/commfibcontext.h Thu Aug 16 13:41:30 2001
8452@@ -0,0 +1,98 @@
8453+/*++
8454+ * Adaptec aacraid device driver for Linux.
8455+ *
8456+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8457+ *
8458+ * This program is free software; you can redistribute it and/or modify
8459+ * it under the terms of the GNU General Public License as published by
8460+ * the Free Software Foundation; either version 2, or (at your option)
8461+ * any later version.
8462+ *
8463+ * This program is distributed in the hope that it will be useful,
8464+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
8465+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8466+ * GNU General Public License for more details.
8467+ *
8468+ * You should have received a copy of the GNU General Public License
8469+ * along with this program; see the file COPYING. If not, write to
8470+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8471+ *
8472+ * Module Name:
8473+ * commfibcontext.h
8474+ *
8475+ * Abstract: defines the _COMM_FIB_CONTEXT strcuture
8476+ *
8477+ *
8478+ *
8479+ --*/
8480+#ifndef _COMM_FIB_CONTEXT_
8481+#define _COMM_FIB_CONTEXT_
8482+
8483+static char *ident_commfib = "aacraid_ident commfibcontext.h 1.0.6 2000/10/09 Adaptec, Inc.";
8484+
8485+typedef struct _COMM_FIB_CONTEXT {
8486+
8487+ PVOID Next; // this is used by the zone allocation
8488+
8489+ //
8490+ // Type and size of this record (must be FSA_NTC_FIB_CONTEXT)
8491+ //
8492+ // NOTE: THIS STRUCTURE MUST REMAIN 64-bit ALIGNED IN SIZE, SINCE
8493+ // IT IS ZONE ALLOCATED, AND REPINNED_BCBS_ARRAY_SIZE AFFECTS
8494+ // ITS SIZE.
8495+ //
8496+
8497+ NODE_TYPE_CODE NodeTypeCode;
8498+ NODE_BYTE_SIZE NodeByteSize;
8499+
8500+ //
8501+ // The Adapter that this I/O is destined for.
8502+ //
8503+
8504+ PAFA_COMM_ADAPTER Adapter;
8505+
8506+ PHYSICAL_ADDRESS LogicalFibAddress;
8507+
8508+ //
8509+ // This is the event the sendfib routine will wait on if the
8510+ // caller did not pass one and this is synch io.
8511+ //
8512+
8513+ OS_CV_T FsaEvent;
8514+ OS_CVLOCK *FsaEventMutex;
8515+
8516+ ULONG FibComplete; // gets set to 1 when fib is complete
8517+
8518+ PFIB_CALLBACK FibCallback;
8519+ PVOID FibCallbackContext;
8520+
8521+ ULONG Flags;
8522+
8523+
8524+#ifdef GATHER_FIB_TIMES
8525+ LARGE_INTEGER FibTimeStamp;
8526+ PFIB_TIMES FibTimesPtr;
8527+#endif
8528+
8529+ //
8530+ // The following is used to put this fib context onto the Outstanding I/O queue.
8531+ //
8532+
8533+ LIST_ENTRY QueueEntry;
8534+
8535+ //
8536+ // The following is used to timeout a fib to the adapter.
8537+ //
8538+
8539+ LARGE_INTEGER TimeoutValue;
8540+
8541+ PVOID FibData;
8542+
8543+ PFIB Fib;
8544+
8545+} COMM_FIB_CONTEXT;
8546+typedef COMM_FIB_CONTEXT *PCOMM_FIB_CONTEXT;
8547+
8548+#define FIB_CONTEXT_FLAG_TIMED_OUT (0x00000001)
8549+
8550+#endif /* _COMM_FIB_CONTEXT_ */
8551diff -burN linux-2.4.9/drivers/scsi/aacraid/include/comprocs.h linux/drivers/scsi/aacraid/include/comprocs.h
8552--- linux-2.4.9/drivers/scsi/aacraid/include/comprocs.h Wed Dec 31 18:00:00 1969
8553+++ linux/drivers/scsi/aacraid/include/comprocs.h Thu Aug 16 13:41:30 2001
8554@@ -0,0 +1,93 @@
8555+/*++
8556+ * Adaptec aacraid device driver for Linux.
8557+ *
8558+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8559+ *
8560+ * This program is free software; you can redistribute it and/or modify
8561+ * it under the terms of the GNU General Public License as published by
8562+ * the Free Software Foundation; either version 2, or (at your option)
8563+ * any later version.
8564+ *
8565+ * This program is distributed in the hope that it will be useful,
8566+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
8567+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8568+ * GNU General Public License for more details.
8569+ *
8570+ * You should have received a copy of the GNU General Public License
8571+ * along with this program; see the file COPYING. If not, write to
8572+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8573+ *
8574+ * Module Name:
8575+ * comprocs.h
8576+ *
8577+ * Abstract: This module defines all of the globally used procedures in the Afa comm layer
8578+ *
8579+ *
8580+ *
8581+ --*/
8582+#ifndef _COMPROCS_
8583+#define _COMPROCS_
8584+
8585+static char *ident_comproc = "aacraid_ident comprocs.h 1.0.6 2000/10/09 Adaptec, Inc.";
8586+
8587+#include "osheaders.h"
8588+
8589+#include "AacGenericTypes.h"
8590+
8591+#include "aac_unix_defs.h"
8592+
8593+#include "nodetype.h"
8594+
8595+// #define GATHER_FIB_TIMES
8596+
8597+#include "fsatypes.h"
8598+
8599+#include "perfpack.h"
8600+
8601+#include "comstruc.h"
8602+
8603+//#include "unix_protocol.h"
8604+
8605+#include "fsact.h"
8606+
8607+#include "protocol.h"
8608+
8609+#include "fsaioctl.h"
8610+
8611+#undef GATHER_FIB_TIMES
8612+
8613+#include "aifstruc.h"
8614+
8615+#include "fsaport.h"
8616+#include "comsup.h"
8617+#include "afacomm.h"
8618+#include "adapter.h"
8619+
8620+#include "commfibcontext.h"
8621+#include "comproto.h"
8622+#include "commdata.h"
8623+#include "commerr.h"
8624+
8625+
8626+
8627+
8628+//
8629+// The following macro is used when sending and receiving FIBs. It is only used for
8630+// debugging.
8631+
8632+#if DBG
8633+#define FIB_COUNTER_INCREMENT(Counter) InterlockedIncrement(&(Counter))
8634+#else
8635+#define FIB_COUNTER_INCREMENT(Counter)
8636+#endif
8637+
8638+
8639+
8640+int
8641+AfaCommAdapterDeviceControl (
8642+ IN PVOID AdapterArg,
8643+ IN PAFA_IOCTL_CMD IoctlCmdPtr
8644+ );
8645+
8646+
8647+#endif // _COMPROCS_
8648diff -burN linux-2.4.9/drivers/scsi/aacraid/include/comproto.h linux/drivers/scsi/aacraid/include/comproto.h
8649--- linux-2.4.9/drivers/scsi/aacraid/include/comproto.h Wed Dec 31 18:00:00 1969
8650+++ linux/drivers/scsi/aacraid/include/comproto.h Thu Aug 16 13:41:30 2001
8651@@ -0,0 +1,170 @@
8652+/*++
8653+ * Adaptec aacraid device driver for Linux.
8654+ *
8655+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8656+ *
8657+ * This program is free software; you can redistribute it and/or modify
8658+ * it under the terms of the GNU General Public License as published by
8659+ * the Free Software Foundation; either version 2, or (at your option)
8660+ * any later version.
8661+ *
8662+ * This program is distributed in the hope that it will be useful,
8663+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
8664+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8665+ * GNU General Public License for more details.
8666+ *
8667+ * You should have received a copy of the GNU General Public License
8668+ * along with this program; see the file COPYING. If not, write to
8669+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8670+ *
8671+ * Module Name:
8672+ * comproto.h
8673+ *
8674+ * Abstract: Global routines for the commuication interface that are device
8675+ * independant.
8676+ *
8677+ *
8678+ *
8679+ --*/
8680+#ifndef _COMM_PROTO
8681+#define _COMM_PROTO
8682+
8683+static char *ident_comproto = "aacraid_ident comproto.h 1.0.6 2000/10/09 Adaptec, Inc.";
8684+
8685+//
8686+// define the routines we need so we can commuicate with the
8687+// fsa adapter
8688+//
8689+
8690+//
8691+// The following 4 dpc routines will support commuication from the adapter to the
8692+// host. There is one DPC routine to deal with each type of queue that supports
8693+// commuication from the adapter. (adapter to host resposes, adapter to host commands)
8694+// These routines will simply pull off the QE and set an event. In the case of a
8695+// adapter to host command they will also put the FIB on a queue to be processed by
8696+// a FS thread running at passive level.
8697+//
8698+
8699+// Handle queue not full notification to the file system thread waiting for a queue entry
8700+
8701+u_int
8702+CommonNotFullDpc(
8703+ IN PCOMM_REGION CommRegion
8704+ );
8705+
8706+// Adapter to host normal priority responses
8707+
8708+u_int
8709+HostResponseNormalDpc(
8710+ IN PCOMM_QUE OurQueue
8711+ );
8712+
8713+// Adapter to host high priority responses
8714+u_int
8715+HostResponseHighDpc(
8716+ IN PCOMM_QUE OurQueue
8717+ );
8718+
8719+// Adapter to host high priority commands
8720+u_int
8721+HostCommandHighDpc(
8722+ IN PCOMM_QUE OurQueue
8723+ );
8724+
8725+
8726+// Adapter to host normal priority commands
8727+u_int
8728+HostCommandNormDpc(
8729+ IN PCOMM_QUE OurQueue
8730+ );
8731+
8732+
8733+
8734+BOOLEAN
8735+SendSynchFib(
8736+ PVOID Arg,
8737+ FIB_COMMAND Command,
8738+ PVOID Data,
8739+ USHORT Size,
8740+ PVOID Response,
8741+ USHORT *ResponseSize
8742+ );
8743+
8744+PFIB_CONTEXT
8745+AllocateFib (
8746+ IN PVOID Adapter
8747+ );
8748+
8749+VOID
8750+FreeFib (
8751+ IN PFIB_CONTEXT FibContext
8752+ );
8753+
8754+VOID
8755+FreeFibFromDpc(
8756+ IN PFIB_CONTEXT FibContext
8757+ );
8758+
8759+AAC_STATUS
8760+DeallocateFib(
8761+ IN PFIB_CONTEXT FibContext
8762+ );
8763+
8764+
8765+
8766+AAC_STATUS
8767+SendFib(
8768+ IN FIB_COMMAND Command,
8769+ IN PFIB_CONTEXT FibContext,
8770+ IN ULONG Size,
8771+ IN COMM_PRIORITIES Priority,
8772+ IN BOOLEAN Wait,
8773+ IN PVOID WaitOn,
8774+ IN BOOLEAN ResponseExpected,
8775+ IN PFIB_CALLBACK FibCallback,
8776+ IN PVOID FibCallbackContext
8777+ );
8778+
8779+AAC_STATUS
8780+CompleteFib(
8781+ IN PFIB_CONTEXT FibContext
8782+ );
8783+
8784+AAC_STATUS
8785+CompleteAdapterFib(
8786+ IN PFIB_CONTEXT FibContext,
8787+ IN USHORT Size
8788+ );
8789+
8790+AAC_STATUS
8791+InitializeFib(
8792+ IN PFIB_CONTEXT FibContext
8793+ );
8794+
8795+
8796+PVOID
8797+FsaGetFibData(
8798+ IN PFIB_CONTEXT FibContext
8799+ );
8800+
8801+
8802+
8803+AAC_STATUS
8804+AfaCommOpenAdapter (
8805+ IN PVOID AdapterArg
8806+ );
8807+
8808+AAC_STATUS
8809+AfaCommCloseAdapter (
8810+ IN PVOID AdapterArg
8811+ );
8812+
8813+
8814+VOID
8815+AfaCommInterruptHost(
8816+ PVOID Adapter,
8817+ ADAPTER_EVENT AdapterEvent
8818+ );
8819+
8820+
8821+#endif // _COMM_PROTO
8822diff -burN linux-2.4.9/drivers/scsi/aacraid/include/comstruc.h linux/drivers/scsi/aacraid/include/comstruc.h
8823--- linux-2.4.9/drivers/scsi/aacraid/include/comstruc.h Wed Dec 31 18:00:00 1969
8824+++ linux/drivers/scsi/aacraid/include/comstruc.h Thu Aug 16 13:41:30 2001
8825@@ -0,0 +1,435 @@
8826+/*++
8827+ * Adaptec aacraid device driver for Linux.
8828+ *
8829+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8830+ *
8831+ * This program is free software; you can redistribute it and/or modify
8832+ * it under the terms of the GNU General Public License as published by
8833+ * the Free Software Foundation; either version 2, or (at your option)
8834+ * any later version.
8835+ *
8836+ * This program is distributed in the hope that it will be useful,
8837+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
8838+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8839+ * GNU General Public License for more details.
8840+ *
8841+ * You should have received a copy of the GNU General Public License
8842+ * along with this program; see the file COPYING. If not, write to
8843+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8844+ *
8845+ * Module Name:
8846+ * comstruc.h
8847+ *
8848+ * Abstract: This module defines the data structures that make up the communication
8849+ * region for the FSA filesystem. This region is how the host based code
8850+ * communicates both control and data to the adapter based code.
8851+ *
8852+ *
8853+ *
8854+ --*/
8855+#ifndef _COMM_STRUCT
8856+#define _COMM_STRUCT
8857+
8858+static char *ident_comstruc = "aacraid_ident comstruc.h 1.0.7 2000/10/11 Adaptec, Inc.";
8859+
8860+//
8861+// Define all the constants needed for the communication interface
8862+//
8863+
8864+// Define how many queue entries each queue will have and the total number of
8865+// entries for the entire communication interface. Also define how many queues
8866+// we support.
8867+
8868+#define NUMBER_OF_COMM_QUEUES 8 // 4 command; 4 response
8869+#define HOST_HIGH_CMD_ENTRIES 4
8870+#define HOST_NORM_CMD_ENTRIES 8
8871+#define ADAP_HIGH_CMD_ENTRIES 4
8872+#define ADAP_NORM_CMD_ENTRIES 512
8873+#define HOST_HIGH_RESP_ENTRIES 4
8874+#define HOST_NORM_RESP_ENTRIES 512
8875+#define ADAP_HIGH_RESP_ENTRIES 4
8876+#define ADAP_NORM_RESP_ENTRIES 8
8877+
8878+#define TOTAL_QUEUE_ENTRIES \
8879+ (HOST_NORM_CMD_ENTRIES + HOST_HIGH_CMD_ENTRIES + ADAP_NORM_CMD_ENTRIES + ADAP_HIGH_CMD_ENTRIES + \
8880+ HOST_NORM_RESP_ENTRIES + HOST_HIGH_RESP_ENTRIES + ADAP_NORM_RESP_ENTRIES + ADAP_HIGH_RESP_ENTRIES)
8881+
8882+
8883+
8884+
8885+// Set the queues on a 16 byte alignment
8886+#define QUEUE_ALIGNMENT 16
8887+
8888+
8889+//
8890+// The queue headers define the Communication Region queues. These
8891+// are physically contiguous and accessible by both the adapter and the
8892+// host. Even though all queue headers are in the same contiguous block they will be
8893+// represented as individual units in the data structures.
8894+//
8895+
8896+typedef AAC_UINT32 QUEUE_INDEX;
8897+
8898+typedef QUEUE_INDEX *PQUEUE_INDEX;
8899+
8900+typedef struct _QUEUE_ENTRY {
8901+
8902+ AAC_UINT32 Size; // Size in bytes of the Fib which this QE points to
8903+ AAC_UINT32 FibAddress; // Receiver addressable address of the FIB (low 32 address bits)
8904+
8905+} QUEUE_ENTRY;
8906+
8907+typedef QUEUE_ENTRY *PQUEUE_ENTRY;
8908+
8909+
8910+
8911+// The adapter assumes the ProducerIndex and ConsumerIndex are grouped
8912+// adjacently and in that order.
8913+//
8914+typedef struct _QUEUE_HEADERS {
8915+
8916+ PHYSICAL_ADDRESS LogicalHeaderAddress; // Address to hand the adapter to access to this queue head
8917+ PQUEUE_INDEX ProducerIndex; // The producer index for this queue (host address)
8918+ PQUEUE_INDEX ConsumerIndex; // The consumer index for this queue (host address)
8919+
8920+} QUEUE_HEADERS;
8921+typedef QUEUE_HEADERS *PQUEUE_HEADERS;
8922+
8923+//
8924+// Define all the events which the adapter would like to notify
8925+// the host of.
8926+//
8927+typedef enum _ADAPTER_EVENT {
8928+ HostNormCmdQue = 1, // Change in host normal priority command queue
8929+ HostHighCmdQue, // Change in host high priority command queue
8930+ HostNormRespQue, // Change in host normal priority response queue
8931+ HostHighRespQue, // Change in host high priority response queue
8932+ AdapNormRespNotFull,
8933+ AdapHighRespNotFull,
8934+ AdapNormCmdNotFull,
8935+ AdapHighCmdNotFull,
8936+ SynchCommandComplete,
8937+ AdapInternalError = 0xfe // The adapter detected an internal error shutting down
8938+
8939+} _E_ADAPTER_EVENT;
8940+
8941+#ifdef AAC_32BIT_ENUMS
8942+typedef _E_ADAPTER_EVENT ADAPTER_EVENT;
8943+#else
8944+typedef AAC_UINT32 ADAPTER_EVENT;
8945+#endif
8946+
8947+//
8948+// Define all the events the host wishes to notify the
8949+// adapter of.
8950+//
8951+typedef enum _HOST_2_ADAP_EVENT {
8952+ AdapNormCmdQue = 1,
8953+ AdapHighCmdQue,
8954+ AdapNormRespQue,
8955+ AdapHighRespQue,
8956+ HostShutdown,
8957+ HostPowerFail,
8958+ FatalCommError,
8959+ HostNormRespNotFull,
8960+ HostHighRespNotFull,
8961+ HostNormCmdNotFull,
8962+ HostHighCmdNotFull,
8963+ FastIo,
8964+ AdapPrintfDone
8965+} _E_HOST_2_ADAP_EVENT;
8966+
8967+#ifdef AAC_32BIT_ENUMS
8968+typedef _E_HOST_2_ADAP_EVENT HOST_2_ADAP_EVENT;
8969+#else
8970+typedef AAC_UINT32 HOST_2_ADAP_EVENT;
8971+#endif
8972+
8973+//
8974+// Define all the queues that the adapter and host use to communicate
8975+//
8976+
8977+typedef enum _QUEUE_TYPES {
8978+ HostNormCmdQueue = 1, // Adapter to host normal priority command traffic
8979+ HostHighCmdQueue, // Adapter to host high priority command traffic
8980+ AdapNormRespQueue, // Host to adapter normal priority response traffic
8981+ AdapHighRespQueue, // Host to adapter high priority response traffic
8982+ AdapNormCmdQueue, // Host to adapter normal priority command traffic
8983+ AdapHighCmdQueue, // Host to adapter high priority command traffic
8984+ HostNormRespQueue, // Adapter to host normal priority response traffic
8985+ HostHighRespQueue // Adapter to host high priority response traffic
8986+} _E_QUEUE_TYPES;
8987+
8988+#ifdef AAC_32BIT_ENUMS
8989+typedef _E_QUEUE_TYPES QUEUE_TYPES;
8990+#else
8991+typedef AAC_UINT32 QUEUE_TYPES;
8992+#endif
8993+
8994+
8995+//
8996+// Assign type values to the FSA communication data structures
8997+//
8998+
8999+typedef enum _STRUCT_TYPES {
9000+ TFib = 1,
9001+ TQe,
9002+ TCtPerf
9003+} _E_STRUCT_TYPES;
9004+
9005+#ifdef AAC_32BIT_ENUMS
9006+typedef _E_STRUCT_TYPES STRUCT_TYPES;
9007+#else
9008+typedef AAC_UINT32 STRUCT_TYPES;
9009+#endif
9010+
9011+//
9012+// Define the priority levels the FSA communication routines support.
9013+//
9014+
9015+typedef enum _COMM_PRIORITIES {
9016+ FsaNormal = 1,
9017+ FsaHigh
9018+} _E_COMM_PRIORITIES;
9019+
9020+#ifdef AAC_32BIT_ENUMS
9021+typedef _E_COMM_PRIORITIES COMM_PRIORITIES;
9022+#else
9023+typedef AAC_UINT32 COMM_PRIORITIES;
9024+#endif
9025+
9026+
9027+
9028+//
9029+// Define the LIST_ENTRY structure. This structure is used on the NT side to link
9030+// the FIBs together in a linked list. Since this structure gets compiled on the adapter
9031+// as well, we need to define this structure for the adapter's use. If '_NT_DEF_'
9032+// is defined, then this header is being included from the NT side, and therefore LIST_ENTRY
9033+// is already defined.
9034+#if !defined(_NTDEF_) && !defined(_WINNT_)
9035+typedef struct _LIST_ENTRY {
9036+ struct _LIST_ENTRY *Flink;
9037+ struct _LIST_ENTRY *Blink;
9038+} LIST_ENTRY;
9039+typedef LIST_ENTRY *PLIST_ENTRY;
9040+#endif
9041+
9042+
9043+//
9044+// Define the FIB. The FIB is the where all the requested data and
9045+// command information are put to the application on the FSA adapter.
9046+//
9047+
9048+typedef struct _FIB_HEADER {
9049+ AAC_UINT32 XferState; // Current transfer state for this CCB
9050+ AAC_UINT16 Command; // Routing information for the destination
9051+ AAC_UINT8 StructType; // Type FIB
9052+ AAC_UINT8 Flags; // Flags for FIB
9053+ AAC_UINT16 Size; // Size of this FIB in bytes
9054+ AAC_UINT16 SenderSize; // Size of the FIB in the sender (for response sizing)
9055+ AAC_UINT32 SenderFibAddress; // Host defined data in the FIB
9056+ AAC_UINT32 ReceiverFibAddress; // Logical address of this FIB for the adapter
9057+ AAC_UINT32 SenderData; // Place holder for the sender to store data
9058+#ifndef __midl
9059+ union {
9060+ struct {
9061+ AAC_UINT32 _ReceiverTimeStart; // Timestamp for receipt of fib
9062+ AAC_UINT32 _ReceiverTimeDone; // Timestamp for completion of fib
9063+ } _s;
9064+ LIST_ENTRY _FibLinks; // Used to link Adapter Initiated Fibs on the host
9065+ } _u;
9066+#else // The MIDL compiler does not support unions without a discriminant.
9067+ struct { // Since nothing during the midl compile actually looks into this
9068+ struct { // structure, this shoudl be ok.
9069+ AAC_UINT32 _ReceiverTimeStart; // Timestamp for receipt of fib
9070+ AAC_UINT32 _ReceiverTimeDone; // Timestamp for completion of fib
9071+ } _s;
9072+ } _u;
9073+#endif
9074+} FIB_HEADER;
9075+
9076+
9077+#define FibLinks _u._FibLinks
9078+
9079+
9080+#define FIB_DATA_SIZE_IN_BYTES (512 - sizeof(FIB_HEADER))
9081+
9082+
9083+typedef struct _FIB {
9084+
9085+#ifdef BRIDGE //rma
9086+ DLQUE link;
9087+#endif
9088+ FIB_HEADER Header;
9089+
9090+ AAC_UINT8 data[FIB_DATA_SIZE_IN_BYTES]; // Command specific data
9091+
9092+} FIB;
9093+typedef FIB *PFIB;
9094+
9095+
9096+
9097+//
9098+// FIB commands
9099+//
9100+
9101+typedef enum _FIB_COMMANDS {
9102+ TestCommandResponse = 1,
9103+ TestAdapterCommand = 2,
9104+
9105+ // Lowlevel and comm commands
9106+
9107+ LastTestCommand = 100,
9108+ ReinitHostNormCommandQueue = 101,
9109+ ReinitHostHighCommandQueue = 102,
9110+ ReinitHostHighRespQueue = 103,
9111+ ReinitHostNormRespQueue = 104,
9112+ ReinitAdapNormCommandQueue = 105,
9113+ ReinitAdapHighCommandQueue = 107,
9114+ ReinitAdapHighRespQueue = 108,
9115+ ReinitAdapNormRespQueue = 109,
9116+ InterfaceShutdown = 110,
9117+ DmaCommandFib = 120,
9118+ StartProfile = 121,
9119+ TermProfile = 122,
9120+ SpeedTest = 123,
9121+ TakeABreakPt = 124,
9122+ RequestPerfData = 125,
9123+ SetInterruptDefTimer= 126,
9124+ SetInterruptDefCount= 127,
9125+ GetInterruptDefStatus= 128,
9126+ LastCommCommand = 129,
9127+
9128+ // Filesystem commands
9129+
9130+ NuFileSystem = 300,
9131+ UFS = 301,
9132+ HostFileSystem = 302,
9133+ LastFileSystemCommand = 303,
9134+
9135+ // Container Commands
9136+
9137+ ContainerCommand = 500,
9138+ ContainerCommand64 = 501,
9139+
9140+ // Cluster Commands
9141+
9142+ ClusterCommand = 550,
9143+
9144+ // Scsi Port commands (scsi passthrough)
9145+
9146+ ScsiPortCommand = 600,
9147+
9148+ // misc house keeping and generic adapter initiated commands
9149+
9150+ AifRequest = 700,
9151+ CheckRevision = 701,
9152+ FsaHostShutdown = 702,
9153+ RequestAdapterInfo = 703,
9154+ IsAdapterPaused = 704,
9155+ SendHostTime = 705,
9156+ LastMiscCommand = 706
9157+
9158+} _E_FIB_COMMANDS;
9159+
9160+
9161+
9162+typedef AAC_UINT16 FIB_COMMAND;
9163+
9164+//
9165+// Commands that will target the failover level on the FSA adapter
9166+//
9167+
9168+typedef enum _FIB_XFER_STATE {
9169+ HostOwned = (1<<0),
9170+ AdapterOwned = (1<<1),
9171+ FibInitialized = (1<<2),
9172+ FibEmpty = (1<<3),
9173+ AllocatedFromPool = (1<<4),
9174+ SentFromHost = (1<<5),
9175+ SentFromAdapter = (1<<6),
9176+ ResponseExpected = (1<<7),
9177+ NoResponseExpected = (1<<8),
9178+ AdapterProcessed = (1<<9),
9179+ HostProcessed = (1<<10),
9180+ HighPriority = (1<<11),
9181+ NormalPriority = (1<<12),
9182+ Async = (1<<13),
9183+ AsyncIo = (1<<13), // rpbfix: remove with new regime
9184+ PageFileIo = (1<<14), // rpbfix: remove with new regime
9185+ ShutdownRequest = (1<<15),
9186+ LazyWrite = (1<<16), // rpbfix: remove with new regime
9187+ AdapterMicroFib = (1<<17),
9188+ BIOSFibPath = (1<<18),
9189+ FastResponseCapable = (1<<19),
9190+ ApiFib = (1<<20) // Its an API Fib.
9191+
9192+} _E_FIB_XFER_STATE;
9193+
9194+
9195+typedef enum _FSA_ERRORS {
9196+ FSA_NORMAL = 0,
9197+ FSA_SUCCESS = 0,
9198+ FSA_PENDING = 0x01,
9199+ FSA_FATAL = 0x02,
9200+ FSA_INVALID_QUEUE = 0x03,
9201+ FSA_NOENTRIES = 0x04,
9202+ FSA_SENDFAILED = 0x05,
9203+ FSA_INVALID_QUEUE_PRIORITY = 0x06,
9204+ FSA_FIB_ALLOCATION_FAILED = 0x07,
9205+ FSA_FIB_DEALLOCATION_FAILED = 0x08
9206+
9207+} _E_FSA_ERRORS;
9208+
9209+
9210+//
9211+// The following defines needs to be updated any time there is an incompatible change made
9212+// to the ADAPTER_INIT_STRUCT structure.
9213+//
9214+#define ADAPTER_INIT_STRUCT_REVISION 3
9215+
9216+typedef struct _ADAPTER_INIT_STRUCT {
9217+ AAC_UINT32 InitStructRevision;
9218+ AAC_UINT32 MiniPortRevision;
9219+ AAC_UINT32 FilesystemRevision;
9220+ PAAC_VOID CommHeaderAddress;
9221+ PAAC_VOID FastIoCommAreaAddress;
9222+ PAAC_VOID AdapterFibsPhysicalAddress;
9223+ PAAC_VOID AdapterFibsVirtualAddress;
9224+ AAC_UINT32 AdapterFibsSize;
9225+ AAC_UINT32 AdapterFibAlign;
9226+ PAAC_VOID PrintfBufferAddress;
9227+ AAC_UINT32 PrintfBufferSize;
9228+ AAC_UINT32 HostPhysMemPages; // number of 4k pages of host physical memory
9229+ AAC_UINT32 HostElapsedSeconds; // number of seconds since 1970.
9230+} ADAPTER_INIT_STRUCT;
9231+typedef ADAPTER_INIT_STRUCT *PADAPTER_INIT_STRUCT;
9232+
9233+#ifdef AAC_32BIT_ENUMS
9234+typedef _E_FSA_ERRORS FSA_ERRORS;
9235+#else
9236+typedef AAC_UINT32 FSA_ERRORS;
9237+#endif
9238+
9239+typedef enum _LOG_LEVEL {
9240+ LOG_INIT = 10,
9241+ LOG_INFORMATIONAL = 20,
9242+ LOG_WARNING = 30,
9243+ LOG_LOW_ERROR = 40,
9244+ LOG_MEDIUM_ERROR = 50,
9245+ LOG_HIGH_ERROR = 60,
9246+ LOG_PANIC = 70,
9247+ LOG_DEBUG = 80,
9248+ LOG_WINDBG_PRINT = 90
9249+} _E_LOG_LEVEL;
9250+
9251+#ifdef AAC_32BIT_ENUMS
9252+typedef _E_LOG_LEVEL LOG_LEVEL;
9253+#else
9254+typedef AAC_UINT32 LOG_LEVEL;
9255+#endif
9256+
9257+
9258+#endif //_COMM_STRUCT
9259+
9260+
9261diff -burN linux-2.4.9/drivers/scsi/aacraid/include/comsup.h linux/drivers/scsi/aacraid/include/comsup.h
9262--- linux-2.4.9/drivers/scsi/aacraid/include/comsup.h Wed Dec 31 18:00:00 1969
9263+++ linux/drivers/scsi/aacraid/include/comsup.h Thu Aug 16 13:41:30 2001
9264@@ -0,0 +1,132 @@
9265+/*++
9266+ * Adaptec aacraid device driver for Linux.
9267+ *
9268+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9269+ *
9270+ * This program is free software; you can redistribute it and/or modify
9271+ * it under the terms of the GNU General Public License as published by
9272+ * the Free Software Foundation; either version 2, or (at your option)
9273+ * any later version.
9274+ *
9275+ * This program is distributed in the hope that it will be useful,
9276+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9277+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9278+ * GNU General Public License for more details.
9279+ *
9280+ * You should have received a copy of the GNU General Public License
9281+ * along with this program; see the file COPYING. If not, write to
9282+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9283+ *
9284+ * Module Name:
9285+ * comsup.h
9286+ *
9287+ * Abstract: This module defines the data structures that make up the
9288+ * commuication region for the FSA filesystem. This region is
9289+ * how the host based code commuicates both control and data
9290+ * to the adapter based code.
9291+ *
9292+ *
9293+ *
9294+ --*/
9295+#ifndef _COMM_SUP_DEF
9296+#define _COMM_SUP_DEF
9297+
9298+static char *ident_comsup = "aacraid_ident comsup.h 1.0.6 2000/10/09 Adaptec, Inc.";
9299+
9300+//
9301+// The adapter interface specs all queues to be located in the same physically
9302+// contigous block. The host structure that defines the commuication queues will
9303+// assume they are each a seperate physically contigous memory region that will
9304+// support them all being one big contigous block.
9305+// There is a command and response queue for each level and direction of
9306+// commuication. These regions are accessed by both the host and adapter.
9307+//
9308+typedef struct _COMM_QUE {
9309+
9310+ PHYSICAL_ADDRESS LogicalAddress; // This is the address we give the adapter
9311+
9312+ PQUEUE_ENTRY BaseAddress; // This is the system virtual address
9313+ QUEUE_HEADERS Headers; // A pointer to the producer and consumer queue headers for this queue
9314+ ULONG QueueEntries; // Number of queue entries on this queue
9315+ OS_CV_T QueueFull; // Event to wait on if the queue is full
9316+ OS_CV_T CommandReady; // Indicates there is a Command ready from the adapter on this queue.
9317+ // This is only valid for adapter to host command queues.
9318+ OS_SPINLOCK *QueueLock; // Spinlock for this queue must take this lock before accessing the lock
9319+ KIRQL SavedIrql; // Previous IRQL when the spin lock is taken
9320+ ddi_softintr_t ConsumerRoutine; // The DPC routine which will consume entries off this queue
9321+ // Only queues which the host will be the consumer will this field be valid
9322+ LIST_ENTRY CommandQueue; // A queue of FIBs which need to be prcessed by the FS thread. This is
9323+ // only valid for command queues which receive entries from the adapter.
9324+ LIST_ENTRY OutstandingIoQueue; // A queue of outstanding fib's to the adapter.
9325+ ULONG NumOutstandingIos; // Number of entries on outstanding queue.
9326+
9327+ PVOID Adapter; // Back pointer to adapter structure
9328+
9329+} COMM_QUE;
9330+typedef COMM_QUE *PCOMM_QUE;
9331+
9332+
9333+typedef struct _COMM_REGION {
9334+
9335+ COMM_QUE HostNormCmdQue; // Command queue for normal priority commands from the host
9336+ COMM_QUE HostNormRespQue; // A response for normal priority adapter responses
9337+
9338+ COMM_QUE HostHighCmdQue; // Command queue for high priority commands from the host
9339+ COMM_QUE HostHighRespQue; // A response for normal priority adapter responses
9340+
9341+ COMM_QUE AdapNormCmdQue; // Command queue for normal priority command from the adapter
9342+ COMM_QUE AdapNormRespQue; // A response for normal priority host responses
9343+
9344+ COMM_QUE AdapHighCmdQue; // Command queue for high priority command from the adapter
9345+ COMM_QUE AdapHighRespQue; // A response for high priority host responses
9346+
9347+ //
9348+ // The 2 threads below are the threads which handle command traffic from the
9349+ // the adapter. There is one for normal priority and one for high priority queues.
9350+ // These threads will wait on the commandready event for it's queue.
9351+ //
9352+
9353+ HANDLE NormCommandThread;
9354+ HANDLE HighCommandThread;
9355+
9356+ //
9357+ // This dpc routine will handle the setting the of not full event when the adapter
9358+ // lets us know the queue is not longer full via interrupt
9359+ //
9360+
9361+ KDPC QueueNotFullDpc;
9362+
9363+#ifdef API_THROTTLE
9364+ //
9365+ // Support for data I/O throttling to improve CLI performance
9366+ // while the system is under load.
9367+ // This is the throttling mechanism built into the COMM layer.
9368+ // Look in commsup.c, dpcsup.c and comminit.c for use.
9369+ //
9370+
9371+ int ThrottleLimit; // Max queue depth of data ops allowed during throttle
9372+ int ThrottleOutstandingFibs; // Number of data FIBs outstanding to adapter
9373+ LARGE_INTEGER ThrottleTimeout; // Duration of a a throttle period
9374+ LARGE_INTEGER ThrottleWaitTimeout; // Timeout for a suspended threads to wait
9375+ BOOLEAN ThrottleActive; // Is there a current throttle active period ?
9376+ KTIMER ThrottleTimer; // Throttle timer to end a throttle period.
9377+ KDPC ThrottleDpc; // Throttle timer timeout DPC routine.
9378+ KSEMAPHORE ThrottleReleaseSema; // Semaphore callers of SendFib wait on during a throttle.
9379+
9380+ unsigned int ThrottleExceptionsCount; // Number of times throttle exception handler executed (0!)
9381+ unsigned int ThrottleTimerFires; // Debug info - #times throttle timer Dpc has fired
9382+ unsigned int ThrottleTimerSets; // Debug info - #times throttle timer was set
9383+
9384+ unsigned int ThrottledFibs;
9385+ unsigned int ThrottleTimedoutFibs;
9386+ unsigned int ApiFibs;
9387+ unsigned int NonPassiveFibs;
9388+ unsigned int TotalFibs;
9389+ unsigned int FSInfoFibs;
9390+
9391+#endif // #ifdef API_THROTTLE
9392+
9393+} COMM_REGION;
9394+typedef COMM_REGION *PCOMM_REGION;
9395+
9396+#endif // _COMM_SUP
9397diff -burN linux-2.4.9/drivers/scsi/aacraid/include/fsact.h linux/drivers/scsi/aacraid/include/fsact.h
9398--- linux-2.4.9/drivers/scsi/aacraid/include/fsact.h Wed Dec 31 18:00:00 1969
9399+++ linux/drivers/scsi/aacraid/include/fsact.h Thu Aug 16 13:41:30 2001
9400@@ -0,0 +1,165 @@
9401+/*++
9402+ * Adaptec aacraid device driver for Linux.
9403+ *
9404+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9405+ *
9406+ * This program is free software; you can redistribute it and/or modify
9407+ * it under the terms of the GNU General Public License as published by
9408+ * the Free Software Foundation; either version 2, or (at your option)
9409+ * any later version.
9410+ *
9411+ * This program is distributed in the hope that it will be useful,
9412+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9413+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9414+ * GNU General Public License for more details.
9415+ *
9416+ * You should have received a copy of the GNU General Public License
9417+ * along with this program; see the file COPYING. If not, write to
9418+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9419+ *
9420+ * Module Name:
9421+ * fsact.h
9422+ *
9423+ * Abstract: Common container structures that are required to be
9424+ * known on both the host and adapter.
9425+ *
9426+ *
9427+ --*/
9428+#ifndef _FSACT_H_
9429+#define _FSACT_H_
9430+
9431+static char *ident_fsact = "aacraid_ident fsact.h 1.0.6 2000/10/09 Adaptec, Inc.";
9432+
9433+//#include <comstruc.h>
9434+//#include <fsatypes.h>
9435+#include <protocol.h> // definitions for FSASTATUS
9436+
9437+
9438+/*
9439+ * Object-Server / Volume-Manager Dispatch Classes
9440+ */
9441+typedef enum _VM_COMMANDS {
9442+ VM_Null = 0,
9443+ VM_NameServe,
9444+ VM_ContainerConfig,
9445+ VM_Ioctl,
9446+ VM_FilesystemIoctl,
9447+ VM_CloseAll,
9448+ VM_CtBlockRead, // see protocol.h for BlockRead command layout
9449+ VM_CtBlockWrite, // see protocol.h for BlockWrite command layout
9450+ VM_SliceBlockRead, // raw access to configured "storage objects"
9451+ VM_SliceBlockWrite,
9452+ VM_DriveBlockRead, // raw access to physical devices
9453+ VM_DriveBlockWrite,
9454+ VM_EnclosureMgt, // enclosure management
9455+ VM_Unused, // used to be diskset management
9456+ VM_CtBlockVerify, // see protocol.h for BlockVerify command layout
9457+ VM_CtPerf, // performance test
9458+ VM_CtBlockRead64, // see protocol.h for BlockRead64 command layout
9459+ VM_CtBlockWrite64, // see protocol.h for BlockWrite64 command layout
9460+ VM_CtBlockVerify64, // see protocol.h for BlockVerify64 command layout
9461+ MAX_VMCOMMAND_NUM // used for sizing stats array - leave last
9462+} _E_VMCOMMAND;
9463+
9464+#ifdef AAC_32BIT_ENUMS
9465+typedef _E_VMCOMMAND VMCOMMAND;
9466+#else
9467+typedef AAC_UINT32 VMCOMMAND;
9468+#endif
9469+
9470+
9471+
9472+//
9473+// Descriptive information (eg, vital stats)
9474+// that a content manager might report. The
9475+// FileArray filesystem component is one example
9476+// of a content manager. Raw mode might be
9477+// another.
9478+//
9479+
9480+struct FileSysInfo {
9481+/*
9482+ a) DOS usage - THINK ABOUT WHERE THIS MIGHT GO -- THXXX
9483+ b) FSA usage (implemented by ObjType and ContentState fields)
9484+ c) Block size
9485+ d) Frag size
9486+ e) Max file system extension size - (fsMaxExtendSize * fsSpaceUnits)
9487+ f) I-node density - (computed from other fields)
9488+*/
9489+ AAC_UINT32 fsTotalSize; // consumed by fs, incl. metadata
9490+ AAC_UINT32 fsBlockSize;
9491+ AAC_UINT32 fsFragSize;
9492+ AAC_UINT32 fsMaxExtendSize;
9493+ AAC_UINT32 fsSpaceUnits;
9494+ AAC_UINT32 fsMaxNumFiles;
9495+ AAC_UINT32 fsNumFreeFiles;
9496+ AAC_UINT32 fsInodeDensity;
9497+}; // valid iff ObjType == FT_FILESYS && !(ContentState & FSCS_NOTCLEAN)
9498+
9499+union ContentManagerInfo {
9500+ struct FileSysInfo FileSys; // valid iff ObjType == FT_FILESYS && !(ContentState & FSCS_NOTCLEAN)
9501+};
9502+
9503+//
9504+// Query for "mountable" objects, ie, objects that are typically
9505+// associated with a drive letter on the client (host) side.
9506+//
9507+
9508+typedef struct _MNTOBJ {
9509+
9510+ AAC_UINT32 ObjectId;
9511+ FSASTRING FileSystemName; // if applicable
9512+ ContainerCreationInfo CreateInfo; // if applicable
9513+ AAC_UINT32 Capacity;
9514+ FSAVOLTYPE VolType; // substrate structure
9515+ FTYPE ObjType; // FT_FILESYS, FT_DATABASE, etc.
9516+ AAC_UINT32 ContentState; // unready for mounting, readonly, etc.
9517+
9518+ union ContentManagerInfo
9519+ ObjExtension; // Info specific to content manager (eg, filesystem)
9520+
9521+ AAC_UINT32 AlterEgoId; // != ObjectId <==> snapshot or broken mirror exists
9522+
9523+} MNTOBJ;
9524+
9525+
9526+#define FSCS_READONLY 0x0002 // possible result of broken mirror
9527+
9528+
9529+
9530+typedef struct _MNTINFO {
9531+
9532+ VMCOMMAND Command;
9533+ FTYPE MntType;
9534+ AAC_UINT32 MntCount;
9535+
9536+} MNTINFO;
9537+typedef MNTINFO *PMNTINFO;
9538+
9539+typedef struct _MNTINFORESPONSE {
9540+
9541+ FSASTATUS Status;
9542+ FTYPE MntType; // should be same as that requested
9543+ AAC_UINT32 MntRespCount;
9544+ MNTOBJ MntTable[1];
9545+
9546+} MNTINFORESPONSE;
9547+typedef MNTINFORESPONSE *PMNTINFORESPONSE;
9548+
9549+
9550+//
9551+// The following command is sent to shut down each container.
9552+//
9553+
9554+typedef struct _CLOSECOMMAND {
9555+
9556+ VMCOMMAND Command;
9557+ AAC_UINT32 ContainerId;
9558+
9559+} CLOSECOMMAND;
9560+typedef CLOSECOMMAND *PCLOSECOMMAND;
9561+
9562+
9563+#endif /* _FSACT_H_ */
9564+
9565+
9566diff -burN linux-2.4.9/drivers/scsi/aacraid/include/fsafs.h linux/drivers/scsi/aacraid/include/fsafs.h
9567--- linux-2.4.9/drivers/scsi/aacraid/include/fsafs.h Wed Dec 31 18:00:00 1969
9568+++ linux/drivers/scsi/aacraid/include/fsafs.h Thu Aug 16 13:41:30 2001
9569@@ -0,0 +1,78 @@
9570+/*++
9571+ * Adaptec aacraid device driver for Linux.
9572+ *
9573+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9574+ *
9575+ * This program is free software; you can redistribute it and/or modify
9576+ * it under the terms of the GNU General Public License as published by
9577+ * the Free Software Foundation; either version 2, or (at your option)
9578+ * any later version.
9579+ *
9580+ * This program is distributed in the hope that it will be useful,
9581+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9582+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9583+ * GNU General Public License for more details.
9584+ *
9585+ * You should have received a copy of the GNU General Public License
9586+ * along with this program; see the file COPYING. If not, write to
9587+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9588+ *
9589+ * Module Name:
9590+ * fsafs.h
9591+ *
9592+ * Abstract: Common file system structures that are required to be
9593+ * known on both the host and adapter
9594+ *
9595+ *
9596+ *
9597+ --*/
9598+
9599+#ifndef _FSAFS_H_
9600+#define _FSAFS_H_ 1
9601+
9602+static char *ident_fsafs = "aacraid_ident fsafs.h 1.0.6 2000/10/09 Adaptec, Inc.";
9603+
9604+#include <fsatypes.h> // core types, shared by client and server, eg, u_long
9605+
9606+/*
9607+ * Maximum number of filesystems.
9608+ */
9609+#define NFILESYS 24
9610+
9611+/*
9612+ * File identifier.
9613+ * These are unique and self validating within a filesystem
9614+ * on a single machine and can persist across reboots.
9615+ * The hint field may be volatile and is not guaranteed to persist
9616+ * across reboots but is used to speed up the FID to file object translation
9617+ * if possible. The opaque f1 and f2 fields are guaranteed to uniquely identify
9618+ * the file object (assuming a filesystem context, i.e. driveno).
9619+ */
9620+typedef struct {
9621+ AAC_UINT32 hint; // last used hint for fast reclaim
9622+ AAC_UINT32 f1; // opaque
9623+ AAC_UINT32 f2; // opaque
9624+ } fileid_t; /* intra-filesystem file ID type */
9625+
9626+
9627+/*
9628+ * Generic file handle
9629+ */
9630+struct fhandle {
9631+ fsid_t fh_fsid; /* File system id of mount point */
9632+ fileid_t fh_fid; /* File sys specific file id */
9633+};
9634+typedef struct fhandle fhandle_t;
9635+
9636+#define FIDSIZE sizeof(fhandle_t)
9637+
9638+typedef struct {
9639+ union {
9640+ AAC_INT8 fid_data[FIDSIZE];
9641+ struct fhandle fsafid;
9642+ } fidu;
9643+} FSAFID; /* FSA File ID type */
9644+
9645+
9646+#endif /* _FSAFS_H_ */
9647+
9648diff -burN linux-2.4.9/drivers/scsi/aacraid/include/fsaioctl.h linux/drivers/scsi/aacraid/include/fsaioctl.h
9649--- linux-2.4.9/drivers/scsi/aacraid/include/fsaioctl.h Wed Dec 31 18:00:00 1969
9650+++ linux/drivers/scsi/aacraid/include/fsaioctl.h Thu Aug 16 13:41:30 2001
9651@@ -0,0 +1,159 @@
9652+/*++
9653+ * Adaptec aacraid device driver for Linux.
9654+ *
9655+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9656+ *
9657+ * This program is free software; you can redistribute it and/or modify
9658+ * it under the terms of the GNU General Public License as published by
9659+ * the Free Software Foundation; either version 2, or (at your option)
9660+ * any later version.
9661+ *
9662+ * This program is distributed in the hope that it will be useful,
9663+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9664+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9665+ * GNU General Public License for more details.
9666+ *
9667+ * You should have received a copy of the GNU General Public License
9668+ * along with this program; see the file COPYING. If not, write to
9669+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9670+ *
9671+ * Module Name:
9672+ * fsaioctl.h
9673+ *
9674+ * Abstract: Defines the interface structures between user mode applications
9675+ * and the fsa driver. This structures are used in
9676+ * DeviceIoControl() calls.
9677+ *
9678+ *
9679+ *
9680+ --*/
9681+#ifndef _FSAIOCTL_H_
9682+#define _FSAIOCTL_H_
9683+
9684+static char *ident_fsaioctl = "aacraid_ident fsaioctl.h 1.0.6 2000/10/09 Adaptec, Inc.";
9685+
9686+#ifndef IOTRACEUSER
9687+
9688+#ifndef CTL_CODE
9689+
9690+
9691+#define FILE_DEVICE_CONTROLLER 0x00000004
9692+
9693+//
9694+// Macro definition for defining IOCTL and FSCTL function control codes. Note
9695+// that function codes 0-2047 are reserved for Microsoft Corporation, and
9696+// 2048-4095 are reserved for customers.
9697+//
9698+
9699+#define CTL_CODE( DeviceType, Function, Method, Access ) ( \
9700+ ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
9701+)
9702+
9703+//
9704+// Define the method codes for how buffers are passed for I/O and FS controls
9705+//
9706+
9707+#define METHOD_BUFFERED 0
9708+
9709+
9710+#define METHOD_NEITHER 3
9711+
9712+//
9713+// Define the access check value for any access
9714+//
9715+//
9716+// The FILE_READ_ACCESS and FILE_WRITE_ACCESS constants are also defined in
9717+// ntioapi.h as FILE_READ_DATA and FILE_WRITE_DATA. The values for these
9718+// constants *MUST* always be in sync.
9719+//
9720+#define FILE_ANY_ACCESS 0
9721+
9722+
9723+
9724+#endif
9725+
9726+
9727+
9728+typedef struct _UNIX_QUERY_DISK {
9729+ AAC_INT32 ContainerNumber;
9730+ AAC_INT32 Bus;
9731+ AAC_INT32 Target;
9732+ AAC_INT32 Lun;
9733+ AAC_BOOLEAN Valid;
9734+ AAC_BOOLEAN Locked;
9735+ AAC_BOOLEAN Deleted;
9736+ AAC_INT32 Instance;
9737+ AAC_INT8 diskDeviceName[10];
9738+ AAC_BOOLEAN UnMapped;
9739+} UNIX_QUERY_DISK;
9740+typedef UNIX_QUERY_DISK *PUNIX_QUERY_DISK;
9741+
9742+
9743+typedef struct _DELETE_DISK {
9744+ AAC_UINT32 NtDiskNumber;
9745+ AAC_UINT32 ContainerNumber;
9746+} DELETE_DISK;
9747+typedef DELETE_DISK *PDELETE_DISK;
9748+
9749+
9750+#endif /*IOTRACEUSER*/
9751+
9752+#define FSACTL_NULL_IO_TEST 0x43 // CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 2048, METHOD_NEITHER, FILE_ANY_ACCESS)
9753+#define FSACTL_SIM_IO_TEST 0x53 // CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 2049, METHOD_NEITHER, FILE_ANY_ACCESS)
9754+
9755+
9756+#define FSACTL_SENDFIB CTL_CODE(FILE_DEVICE_CONTROLLER, 2050, METHOD_BUFFERED, FILE_ANY_ACCESS)
9757+
9758+
9759+#define FSACTL_GET_VAR 0x93
9760+#define FSACTL_SET_VAR 0xa3
9761+#define FSACTL_GET_FIBTIMES 0xb3
9762+#define FSACTL_ZERO_FIBTIMES 0xc3
9763+
9764+
9765+#define FSACTL_DELETE_DISK 0x163
9766+#define FSACTL_QUERY_DISK 0x173
9767+
9768+
9769+// AfaComm perfmon ioctls
9770+#define FSACTL_GET_COMM_PERF_DATA CTL_CODE(FILE_DEVICE_CONTROLLER, 2084, METHOD_BUFFERED, FILE_ANY_ACCESS)
9771+
9772+
9773+#define FSACTL_OPENCLS_COMM_PERF_DATA CTL_CODE(FILE_DEVICE_CONTROLLER, 2085, METHOD_BUFFERED, FILE_ANY_ACCESS)
9774+
9775+
9776+typedef struct _GET_ADAPTER_FIB_IOCTL {
9777+ char *AdapterFibContext;
9778+ int Wait;
9779+ char *AifFib;
9780+} GET_ADAPTER_FIB_IOCTL, *PGET_ADAPTER_FIB_IOCTL;
9781+
9782+//
9783+// filesystem ioctls
9784+//
9785+#define FSACTL_OPEN_GET_ADAPTER_FIB CTL_CODE(FILE_DEVICE_CONTROLLER, 2100, METHOD_BUFFERED, FILE_ANY_ACCESS)
9786+
9787+#define FSACTL_GET_NEXT_ADAPTER_FIB CTL_CODE(FILE_DEVICE_CONTROLLER, 2101, METHOD_BUFFERED, FILE_ANY_ACCESS)
9788+
9789+#define FSACTL_CLOSE_GET_ADAPTER_FIB CTL_CODE(FILE_DEVICE_CONTROLLER, 2102, METHOD_BUFFERED, FILE_ANY_ACCESS)
9790+
9791+#define FSACTL_OPEN_ADAPTER_CONFIG CTL_CODE(FILE_DEVICE_CONTROLLER, 2103, METHOD_NEITHER, FILE_ANY_ACCESS)
9792+
9793+#define FSACTL_CLOSE_ADAPTER_CONFIG CTL_CODE(FILE_DEVICE_CONTROLLER, 2104, METHOD_NEITHER, FILE_ANY_ACCESS)
9794+
9795+
9796+#define FSACTL_MINIPORT_REV_CHECK CTL_CODE(FILE_DEVICE_CONTROLLER, 2107, METHOD_BUFFERED, FILE_ANY_ACCESS)
9797+
9798+
9799+#define FSACTL_QUERY_ADAPTER_CONFIG CTL_CODE(FILE_DEVICE_CONTROLLER, 2113, METHOD_BUFFERED, FILE_ANY_ACCESS)
9800+
9801+
9802+#define FSACTL_FORCE_DELETE_DISK CTL_CODE(FILE_DEVICE_CONTROLLER, 2120, METHOD_NEITHER, FILE_ANY_ACCESS)
9803+
9804+
9805+#define FSACTL_AIF_THREAD CTL_CODE(FILE_DEVICE_CONTROLLER, 2127, METHOD_NEITHER, FILE_ANY_ACCESS)
9806+
9807+
9808+#endif // _FSAIOCTL_H_
9809+
9810+
9811diff -burN linux-2.4.9/drivers/scsi/aacraid/include/fsaport.h linux/drivers/scsi/aacraid/include/fsaport.h
9812--- linux-2.4.9/drivers/scsi/aacraid/include/fsaport.h Wed Dec 31 18:00:00 1969
9813+++ linux/drivers/scsi/aacraid/include/fsaport.h Thu Aug 16 13:41:30 2001
9814@@ -0,0 +1,223 @@
9815+/*++
9816+ * Adaptec aacraid device driver for Linux.
9817+ *
9818+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9819+ *
9820+ * This program is free software; you can redistribute it and/or modify
9821+ * it under the terms of the GNU General Public License as published by
9822+ * the Free Software Foundation; either version 2, or (at your option)
9823+ * any later version.
9824+ *
9825+ * This program is distributed in the hope that it will be useful,
9826+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9827+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9828+ * GNU General Public License for more details.
9829+ *
9830+ * You should have received a copy of the GNU General Public License
9831+ * along with this program; see the file COPYING. If not, write to
9832+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9833+ *
9834+ * Module Name:
9835+ * fsaport.h
9836+ *
9837+ * Abstract: This module defines all of the globally used procedures in the FSA
9838+ * file system.
9839+ *
9840+ *
9841+ *
9842+ --*/
9843+#ifndef _FSAPORT_
9844+#define _FSAPORT_
9845+
9846+static char *ident_fsaport = "aacraid_ident fsaport.h 1.0.6 2000/10/09 Adaptec, Inc.";
9847+
9848+//
9849+// The scatter/gather map context is the information we
9850+// we need to keep the map and transfer data to and from the
9851+// adapter.
9852+//
9853+
9854+typedef struct _SGMAP_CONTEXT {
9855+
9856+ caddr_t BaseAddress;
9857+ PVOID MapRegBase;
9858+ ULONG NumberMapRegs;
9859+ PSGMAP SgMapPtr;
9860+ ULONG ByteCount; // Used to check the Mdl length.
9861+ BOOLEAN WriteToDevice;
9862+
9863+ struct buf *bp;
9864+
9865+
9866+} SGMAP_CONTEXT;
9867+typedef SGMAP_CONTEXT *PSGMAP_CONTEXT;
9868+
9869+typedef struct _MAPFIB_CONTEXT {
9870+ PMDL Mdl;
9871+ PVOID MapRegBase;
9872+ ULONG NumberMapRegs;
9873+ PVOID FibVirtualAddress;
9874+ ULONG Size;
9875+ PVOID FibPhysicalAddress;
9876+
9877+
9878+} MAPFIB_CONTEXT;
9879+typedef MAPFIB_CONTEXT *PMAPFIB_CONTEXT;
9880+
9881+typedef BOOLEAN
9882+(*PFSA_ALLOCATE_ADAPTER_COMM_AREA)(
9883+ PVOID AdapterExtension,
9884+ IN OUT PVOID *BaseAddress,
9885+ IN ULONG Size,
9886+ IN ULONG Alignment
9887+ );
9888+
9889+typedef BOOLEAN
9890+(*PFSA_FREE_ADAPTER_COMM_AREA)(
9891+ PVOID AdapterExtension
9892+ );
9893+
9894+typedef VOID
9895+(*PFSA_FREE_DMA_RESOURCES)(
9896+ IN PVOID AdapterExtension,
9897+ IN PSGMAP_CONTEXT SgMapContext
9898+ );
9899+
9900+typedef BOOLEAN
9901+(*PFSA_ALLOCATE_AND_MAP_FIB_SPACE)(
9902+ IN PVOID AdapterExtension,
9903+ IN PMAPFIB_CONTEXT MapFibContext
9904+ );
9905+
9906+typedef BOOLEAN
9907+(*PFSA_UNMAP_AND_FREE_FIB_SPACE)(
9908+ IN PVOID AdapterExtension,
9909+ IN PMAPFIB_CONTEXT MapFibContext
9910+ );
9911+
9912+typedef VOID
9913+(*PFSA_INTERRUPT_ADAPTER)(
9914+ IN PVOID AdapterExtension
9915+ );
9916+
9917+typedef VOID
9918+(*PFSA_NOTIFY_ADAPTER)(
9919+ IN PVOID AdapterExtension,
9920+ IN HOST_2_ADAP_EVENT AdapterEvent
9921+ );
9922+
9923+typedef VOID
9924+(*PFSA_RESET_DEVICE)(
9925+ PVOID AdapterExtension
9926+ );
9927+
9928+typedef AAC_STATUS
9929+(*PFSA_BUILD_SGMAP)(
9930+ IN PVOID AdapterExtension,
9931+ IN PSGMAP_CONTEXT SgMapContext
9932+ );
9933+
9934+typedef PVOID
9935+(*PFSA_ADAPTER_ADDR_TO_SYSTEM_ADDR)(
9936+ IN PVOID AdapterExtension,
9937+ IN PVOID AdapterAddress
9938+ );
9939+
9940+typedef VOID
9941+(*PFSA_INTERRUPT_HOST)(
9942+ PVOID Adapter,
9943+ ADAPTER_EVENT AdapterEvent
9944+ );
9945+
9946+typedef VOID
9947+(*PFSA_ENABLE_INTERRUPT)(
9948+ PVOID Adapter,
9949+ ADAPTER_EVENT AdapterEvent,
9950+ BOOLEAN AtDeviceIrq
9951+ );
9952+
9953+
9954+typedef VOID
9955+(*PFSA_DISABLE_INTERRUPT)(
9956+ PVOID Adapter,
9957+ ADAPTER_EVENT AdapterEvent,
9958+ BOOLEAN AtDeviceIrq
9959+ );
9960+
9961+typedef AAC_STATUS
9962+(*PFSA_OPEN_ADAPTER) (
9963+ IN PVOID Adapter
9964+ );
9965+
9966+typedef int
9967+(*PFSA_DEVICE_CONTROL) (
9968+ IN PVOID Adapter,
9969+ IN PAFA_IOCTL_CMD IoctlCmdPtr
9970+ );
9971+
9972+typedef AAC_STATUS
9973+(*PFSA_CLOSE_ADAPTER) (
9974+ IN PVOID Adapter
9975+ );
9976+
9977+typedef BOOLEAN
9978+(*PFSA_SEND_SYNCH_FIB) (
9979+ IN PVOID Adapter,
9980+ IN ULONG FibPhysicalAddress
9981+ );
9982+
9983+typedef struct _FSAPORT_FUNCS {
9984+ ULONG SizeOfFsaPortFuncs;
9985+
9986+ PFSA_ALLOCATE_ADAPTER_COMM_AREA AllocateAdapterCommArea;
9987+ PFSA_FREE_ADAPTER_COMM_AREA FreeAdapterCommArea;
9988+ PFSA_FREE_DMA_RESOURCES FreeDmaResources;
9989+ PFSA_ALLOCATE_AND_MAP_FIB_SPACE AllocateAndMapFibSpace;
9990+ PFSA_UNMAP_AND_FREE_FIB_SPACE UnmapAndFreeFibSpace;
9991+ PFSA_INTERRUPT_ADAPTER InterruptAdapter;
9992+ PFSA_NOTIFY_ADAPTER NotifyAdapter;
9993+ PFSA_ENABLE_INTERRUPT EnableInterrupt;
9994+ PFSA_DISABLE_INTERRUPT DisableInterrupt;
9995+ PFSA_RESET_DEVICE ResetDevice;
9996+ PFSA_BUILD_SGMAP BuildSgMap;
9997+ PFSA_ADAPTER_ADDR_TO_SYSTEM_ADDR AdapterAddressToSystemAddress;
9998+
9999+ PFSA_INTERRUPT_HOST InterruptHost;
10000+ PFSA_OPEN_ADAPTER OpenAdapter;
10001+ PFSA_DEVICE_CONTROL DeviceControl;
10002+ PFSA_CLOSE_ADAPTER CloseAdapter;
10003+
10004+ PFSA_SEND_SYNCH_FIB SendSynchFib;
10005+
10006+} FSAPORT_FUNCS;
10007+typedef FSAPORT_FUNCS *PFSAPORT_FUNCS;
10008+
10009+typedef AAC_STATUS
10010+(*PFSA_SETVAR_CALLBACK) (
10011+ IN PVOID Adapter,
10012+ IN ULONG NewValue
10013+ );
10014+
10015+typedef struct _FSA_USER_VAR {
10016+ char Name[32];
10017+ ULONG *Address;
10018+ PFSA_SETVAR_CALLBACK SetVarCallback;
10019+} FSA_USER_VAR;
10020+
10021+typedef FSA_USER_VAR *PFSA_USER_VAR;
10022+
10023+typedef struct _FSA_NEW_ADAPTER {
10024+ PVOID AdapterExtension;
10025+ PFSAPORT_FUNCS AdapterFuncs;
10026+ PVOID Adapter;
10027+ BOOLEAN AdapterInterruptsBelowDpc;
10028+ PFSA_USER_VAR AdapterUserVars;
10029+ ULONG AdapterUserVarsSize;
10030+ void *Dip;
10031+} FSA_NEW_ADAPTER;
10032+typedef FSA_NEW_ADAPTER *PFSA_NEW_ADAPTER;
10033+
10034+#define FSAFS_GET_NEXT_ADAPTER CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 2048, METHOD_NEITHER, FILE_ANY_ACCESS)
10035+#define FSAFS_INIT_NEW_ADAPTER CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 2049, METHOD_NEITHER, FILE_ANY_ACCESS)
10036+
10037+#endif
10038diff -burN linux-2.4.9/drivers/scsi/aacraid/include/fsatypes.h linux/drivers/scsi/aacraid/include/fsatypes.h
10039--- linux-2.4.9/drivers/scsi/aacraid/include/fsatypes.h Wed Dec 31 18:00:00 1969
10040+++ linux/drivers/scsi/aacraid/include/fsatypes.h Thu Aug 16 13:41:30 2001
10041@@ -0,0 +1,214 @@
10042+/*++
10043+ * Adaptec aacraid device driver for Linux.
10044+ *
10045+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10046+ *
10047+ * This program is free software; you can redistribute it and/or modify
10048+ * it under the terms of the GNU General Public License as published by
10049+ * the Free Software Foundation; either version 2, or (at your option)
10050+ * any later version.
10051+ *
10052+ * This program is distributed in the hope that it will be useful,
10053+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10054+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10055+ * GNU General Public License for more details.
10056+ *
10057+ * You should have received a copy of the GNU General Public License
10058+ * along with this program; see the file COPYING. If not, write to
10059+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10060+ *
10061+ * Module Name:
10062+ * fsatypes.h
10063+ *
10064+ * Abstract: Define all shared data types here, ie, those
10065+ * types shared among several components, such
10066+ * as host (driver + apps), adapter, and BIOS.
10067+ *
10068+ *
10069+ --*/
10070+#ifndef _FSATYPES_H
10071+#define _FSATYPES_H
10072+
10073+static char *ident_fsatype = "aacraid_ident fsatypes.h 1.0.6 2000/10/09 Adaptec, Inc.";
10074+
10075+typedef AAC_UINT32 AAC_BOOLEAN;
10076+
10077+//
10078+// Define a 64-bit address structure for use on
10079+// a 32-bit processor architecture.
10080+//
10081+typedef struct {
10082+ AAC_UINT32 lo32;
10083+ AAC_UINT32 hi32;
10084+} AAC_UINT64S, *PAAC_UINT64S;
10085+
10086+
10087+
10088+//
10089+// Container Types
10090+//
10091+typedef struct {
10092+ AAC_UINT32 data[2]; // RMA FIX, make this a real serial number when we
10093+ // know what it looks like. Note, BIOS sees this
10094+ // definition and it must be coded in such a way
10095+ // that it appears to be 64 bits. ints are 16 bits
10096+ // in BIOS land; fortunately, longs are 32 bits.
10097+} SerialNumberT;
10098+
10099+
10100+
10101+//
10102+// ***********************
10103+// DON'T CHANGE THE ORDER, ctdevsw use this order to map the drivers
10104+// ***********************
10105+// drivers for CT_NONE to CT_PASSTHRU
10106+//
10107+typedef enum _FSAVOLTYPE {
10108+ CT_NONE = 0,
10109+ CT_VOLUME,
10110+ CT_MIRROR,
10111+ CT_STRIPE,
10112+ CT_RAID5,
10113+ CT_SSRW,
10114+ CT_SSRO,
10115+ CT_MORPH,
10116+ CT_PASSTHRU,
10117+ CT_RAID4,
10118+ CT_RAID10, // stripe of mirror
10119+ CT_RAID00, // stripe of stripe
10120+ CT_VOLUME_OF_MIRRORS, // volume of mirror
10121+ CT_PSEUDO_RAID3, // really raid4
10122+
10123+ CT_LAST_VOLUME_TYPE
10124+
10125+} _E_FSAVOLTYPE;
10126+
10127+#ifdef AAC_32BIT_ENUMS
10128+typedef _E_FSAVOLTYPE FSAVOLTYPE;
10129+#else
10130+typedef AAC_UINT32 FSAVOLTYPE;
10131+#endif
10132+
10133+
10134+//
10135+// Types of objects addressable in some fashion by the client.
10136+// This is a superset of those objects handled just by the filesystem
10137+// and includes "raw" objects that an administrator would use to
10138+// configure containers and filesystems.
10139+//
10140+typedef enum _FTYPE {
10141+ FT_REG = 1, // regular file
10142+ FT_DIR, // directory
10143+ FT_BLK, // "block" device - reserved
10144+ FT_CHR, // "character special" device - reserved
10145+ FT_LNK, // symbolic link
10146+ FT_SOCK, // socket
10147+ FT_FIFO, // fifo
10148+ FT_FILESYS, // ADAPTEC's "FSA"(tm) filesystem
10149+ FT_DRIVE, // physical disk - addressable in scsi by bus/target/lun
10150+ FT_SLICE, // virtual disk - raw volume - slice
10151+ FT_PARTITION, // FSA partition - carved out of a slice - building block for containers
10152+ FT_VOLUME, // Container - Volume Set
10153+ FT_STRIPE, // Container - Stripe Set
10154+ FT_MIRROR, // Container - Mirror Set
10155+ FT_RAID5, // Container - Raid 5 Set
10156+ FT_DATABASE // Storage object with "foreign" content manager
10157+} _E_FTYPE;
10158+
10159+#ifdef AAC_32BIT_ENUMS
10160+typedef _E_FTYPE FTYPE;
10161+#else
10162+typedef AAC_UINT32 FTYPE;
10163+#endif
10164+
10165+
10166+
10167+//
10168+// Host side memory scatter gather list
10169+// Used by the adapter for read, write, and readdirplus operations
10170+//
10171+typedef PAAC_UINT8 HOSTADDRESS;
10172+
10173+typedef struct _SGENTRY {
10174+ HOSTADDRESS SgAddress; /* 32-bit Base address. */
10175+ AAC_UINT32 SgByteCount; /* Length. */
10176+} SGENTRY;
10177+typedef SGENTRY *PSGENTRY;
10178+
10179+
10180+
10181+//
10182+// SGMAP
10183+//
10184+// This is the SGMAP structure for all commands that use
10185+// 32-bit addressing.
10186+//
10187+// Note that the upper 16 bits of SgCount are used as flags.
10188+// Only the lower 16 bits of SgCount are actually used as the
10189+// SG element count.
10190+//
10191+typedef struct _SGMAP {
10192+ AAC_UINT32 SgCount;
10193+ SGENTRY SgEntry[1];
10194+} SGMAP;
10195+typedef SGMAP *PSGMAP;
10196+
10197+
10198+
10199+//
10200+// SGMAP64
10201+//
10202+// This is the SGMAP structure for 64-bit container commands.
10203+//
10204+typedef struct _SGMAP64 {
10205+ AAC_UINT8 SgCount;
10206+ AAC_UINT8 SgSectorsPerPage;
10207+ AAC_UINT16 SgByteOffset; // For the first page
10208+ AAC_UINT64S SgEntry[1]; // Must be last entry
10209+} SGMAP64;
10210+typedef SGMAP64 *PSGMAP64;
10211+
10212+
10213+
10214+
10215+//
10216+// attempt at common time structure across host and adapter
10217+//
10218+typedef struct __TIME_T {
10219+
10220+ AAC_UINT32 tv_sec; /* seconds (maybe, depends upon host) */
10221+ AAC_UINT32 tv_usec; /* and nanoseconds (maybe, depends upon host)*/
10222+
10223+} TIME_T;
10224+typedef TIME_T *PTIME_T;
10225+
10226+#ifndef _TIME_T
10227+#define timespec __TIME_T
10228+#define ts_sec tv_sec
10229+#define ts_nsec tv_usec
10230+#endif
10231+
10232+
10233+
10234+
10235+typedef struct _ContainerCreationInfo
10236+{
10237+
10238+ AAC_UINT8 ViaBuildNumber; // e.g., 588
10239+ AAC_UINT8 MicroSecond; // e.g., 588
10240+ AAC_UINT8 Via; // e.g., 1 = FSU,
10241+ // 2 = API,
10242+ AAC_UINT8 YearsSince1900; // e.g., 1997 = 97
10243+ AAC_UINT32 Date; //
10244+ // unsigned Month :4; // 1 - 12
10245+ // unsigned Day :6; // 1 - 32
10246+ // unsigned Hour :6; // 0 - 23
10247+ // unsigned Minute :6; // 0 - 60
10248+ // unsigned Second :6; // 0 - 60
10249+ SerialNumberT ViaAdapterSerialNumber; // e.g., 0x1DEADB0BFAFAF001
10250+} ContainerCreationInfo;
10251+
10252+
10253+#endif // _FSATYPES_H
10254+
10255+
10256diff -burN linux-2.4.9/drivers/scsi/aacraid/include/linit.h linux/drivers/scsi/aacraid/include/linit.h
10257--- linux-2.4.9/drivers/scsi/aacraid/include/linit.h Wed Dec 31 18:00:00 1969
10258+++ linux/drivers/scsi/aacraid/include/linit.h Thu Aug 16 13:41:30 2001
10259@@ -0,0 +1,107 @@
10260+/*++
10261+ * Adaptec aacraid device driver for Linux.
10262+ *
10263+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10264+ *
10265+ * This program is free software; you can redistribute it and/or modify
10266+ * it under the terms of the GNU General Public License as published by
10267+ * the Free Software Foundation; either version 2, or (at your option)
10268+ * any later version.
10269+ *
10270+ * This program is distributed in the hope that it will be useful,
10271+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10272+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10273+ * GNU General Public License for more details.
10274+ *
10275+ * You should have received a copy of the GNU General Public License
10276+ * along with this program; see the file COPYING. If not, write to
10277+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10278+ *
10279+ * Module Name:
10280+ * linit.h
10281+ *
10282+ * Abstract: Header file for Linux Driver for Adaptec RAID Array Controller
10283+ *
10284+ --*/
10285+/*------------------------------------------------------------------------------
10286+ * I N C L U D E S
10287+ *----------------------------------------------------------------------------*/
10288+
10289+#ifndef _LINIT_H_
10290+#define _LINIT_H_
10291+
10292+static char *ident_linith = "aacraid_ident linit.h 1.0.6 2000/10/09 Adaptec, Inc.";
10293+
10294+#include <linux/config.h>
10295+
10296+/*------------------------------------------------------------------------------
10297+ * D E F I N E S
10298+ *----------------------------------------------------------------------------*/
10299+/* Define the AAC SCSI Host Template structure. */
10300+#define AAC_HOST_TEMPLATE_ENTRY \
10301+ { name: "AAC", /* Driver Name */ \
10302+ proc_info: AAC_ProcDirectoryInfo, /* ProcFS Info Func */ \
10303+ detect: AAC_DetectHostAdapter, /* Detect Host Adapter */ \
10304+ release: AAC_ReleaseHostAdapter, /* Release Host Adapter */ \
10305+ info: AAC_DriverInfo, /* Driver Info Function */ \
10306+ ioctl: AAC_Ioctl, /* ioctl Interface */ \
10307+ command: AAC_Command, /* unqueued command */ \
10308+ queuecommand: AAC_QueueCommand, /* Queue Command Function */ \
10309+ abort: AAC_AbortCommand, /* Abort Command Function */ \
10310+ reset: AAC_ResetCommand, /* Reset Command Function */ \
10311+ bios_param: AAC_BIOSDiskParameters, /* BIOS Disk Parameters */ \
10312+ can_queue: 1, /* Default initial value */ \
10313+ this_id: 0, /* Default initial value */ \
10314+ sg_tablesize: 0, /* Default initial value */ \
10315+ max_sectors: 128, /* max xfer size of 64k */ \
10316+ cmd_per_lun: 0, /* Default initial value */ \
10317+ present: 0, /* Default initial value */ \
10318+ unchecked_isa_dma: 0, /* Default Initial Value */ \
10319+ use_new_eh_code: 0, /* Default initial value */ \
10320+ eh_abort_handler: AAC_AbortCommand, /* New Abort Command func */ \
10321+ eh_strategy_handler: NULL, /* New Strategy Error Handler */ \
10322+ eh_device_reset_handler: NULL, /* New Device Reset Handler */ \
10323+ eh_bus_reset_handler: NULL, /* New Bus Reset Handler */ \
10324+ eh_host_reset_handler: NULL, /* New Host reset Handler */ \
10325+ use_clustering: ENABLE_CLUSTERING /* Disable Clustering */ \
10326+ }
10327+
10328+
10329+/*------------------------------------------------------------------------------
10330+ * T Y P E D E F S / S T R U C T S
10331+ *----------------------------------------------------------------------------*/
10332+typedef struct AAC_BIOS_DiskParameters
10333+{
10334+ int heads;
10335+ int sectors;
10336+ int cylinders;
10337+} AAC_BIOS_DiskParameters_T;
10338+
10339+
10340+/*------------------------------------------------------------------------------
10341+ * P R O G R A M G L O B A L S
10342+ *----------------------------------------------------------------------------*/
10343+
10344+const char *AAC_DriverInfo( struct Scsi_Host * );
10345+
10346+
10347+/*------------------------------------------------------------------------------
10348+ * F U N C T I O N P R O T O T Y P E S
10349+ *----------------------------------------------------------------------------*/
10350+/* Define prototypes for the AAC Driver Interface Functions. */
10351+int AAC_DetectHostAdapter( Scsi_Host_Template * );
10352+int AAC_ReleaseHostAdapter( struct Scsi_Host * );
10353+int AAC_QueueCommand( Scsi_Cmnd *, void ( *CompletionRoutine )( Scsi_Cmnd * ) );
10354+int AAC_Command( Scsi_Cmnd * );
10355+int AAC_ResetCommand( Scsi_Cmnd *, unsigned int );
10356+int AAC_BIOSDiskParameters( Disk *, kdev_t, int * );
10357+int AAC_ProcDirectoryInfo( char *, char **, off_t, int, int, int );
10358+int AAC_Ioctl( Scsi_Device *, int, void * );
10359+
10360+
10361+void AAC_SelectQueueDepths( struct Scsi_Host *, Scsi_Device * );
10362+
10363+
10364+int AAC_AbortCommand( Scsi_Cmnd *scsi_cmnd_ptr );
10365+
10366+#endif /* _LINIT_H_ */
10367diff -burN linux-2.4.9/drivers/scsi/aacraid/include/monkerapi.h linux/drivers/scsi/aacraid/include/monkerapi.h
10368--- linux-2.4.9/drivers/scsi/aacraid/include/monkerapi.h Wed Dec 31 18:00:00 1969
10369+++ linux/drivers/scsi/aacraid/include/monkerapi.h Thu Aug 16 13:41:30 2001
10370@@ -0,0 +1,98 @@
10371+/*++
10372+ * Adaptec aacraid device driver for Linux.
10373+ *
10374+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10375+ *
10376+ * This program is free software; you can redistribute it and/or modify
10377+ * it under the terms of the GNU General Public License as published by
10378+ * the Free Software Foundation; either version 2, or (at your option)
10379+ * any later version.
10380+ *
10381+ * This program is distributed in the hope that it will be useful,
10382+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10383+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10384+ * GNU General Public License for more details.
10385+ *
10386+ * You should have received a copy of the GNU General Public License
10387+ * along with this program; see the file COPYING. If not, write to
10388+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10389+ *
10390+ * Module Name:
10391+ * monkerapi.h
10392+ *
10393+ * Abstract: This module contains the definitions used by the Host Adapter
10394+ * Communications interface.
10395+ * This is the interface used for by host programs and the Adapter
10396+ * to communicate via synchronous commands via a shared set of registers
10397+ * on a platform (typically doorbells and mailboxes).
10398+ *
10399+ --*/
10400+//**********************************************************************
10401+//
10402+// Monitor / Kernel API
10403+//
10404+// 03/24/1998 Bob Peret Initial creation
10405+//
10406+//**********************************************************************
10407+
10408+#ifndef MONKER_H
10409+#define MONKER_H
10410+
10411+static char *ident_monk = "aacraid_ident monkerapi.h 1.0.6 2000/10/09 Adaptec, Inc.";
10412+
10413+#define BREAKPOINT_REQUEST 0x00000004
10414+#define INIT_STRUCT_BASE_ADDRESS 0x00000005
10415+
10416+
10417+#define SEND_SYNCHRONOUS_FIB 0x0000000c
10418+
10419+
10420+
10421+//
10422+// Adapter Status Register
10423+//
10424+// Phase Staus mailbox is 32bits:
10425+// <31:16> = Phase Status
10426+// <15:0> = Phase
10427+//
10428+// The adapter reports is present state through the phase. Only
10429+// a single phase should be ever be set. Each phase can have multiple
10430+// phase status bits to provide more detailed information about the
10431+// state of the board. Care should be taken to ensure that any phase status
10432+// bits that are set when changing the phase are also valid for the new phase
10433+// or be cleared out. Adapter software (monitor, iflash, kernel) is responsible
10434+// for properly maintining the phase status mailbox when it is running.
10435+
10436+//
10437+// MONKER_API Phases
10438+//
10439+// Phases are bit oriented. It is NOT valid
10440+// to have multiple bits set
10441+//
10442+
10443+
10444+#define SELF_TEST_FAILED 0x00000004
10445+
10446+
10447+#define KERNEL_UP_AND_RUNNING 0x00000080
10448+#define KERNEL_PANIC 0x00000100
10449+
10450+
10451+
10452+//
10453+// Doorbell bit defines
10454+//
10455+
10456+
10457+#define DoorBellPrintfDone (1<<5) // Host -> Adapter
10458+
10459+
10460+#define DoorBellAdapterNormCmdReady (1<<1) // Adapter -> Host
10461+#define DoorBellAdapterNormRespReady (1<<2) // Adapter -> Host
10462+#define DoorBellAdapterNormCmdNotFull (1<<3) // Adapter -> Host
10463+#define DoorBellAdapterNormRespNotFull (1<<4) // Adapter -> Host
10464+#define DoorBellPrintfReady (1<<5) // Adapter -> Host
10465+
10466+
10467+#endif // MONKER_H
10468+
10469diff -burN linux-2.4.9/drivers/scsi/aacraid/include/nodetype.h linux/drivers/scsi/aacraid/include/nodetype.h
10470--- linux-2.4.9/drivers/scsi/aacraid/include/nodetype.h Wed Dec 31 18:00:00 1969
10471+++ linux/drivers/scsi/aacraid/include/nodetype.h Thu Aug 16 13:41:30 2001
10472@@ -0,0 +1,67 @@
10473+/*++
10474+ * Adaptec aacraid device driver for Linux.
10475+ *
10476+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10477+ *
10478+ * This program is free software; you can redistribute it and/or modify
10479+ * it under the terms of the GNU General Public License as published by
10480+ * the Free Software Foundation; either version 2, or (at your option)
10481+ * any later version.
10482+ *
10483+ * This program is distributed in the hope that it will be useful,
10484+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10485+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10486+ * GNU General Public License for more details.
10487+ *
10488+ * You should have received a copy of the GNU General Public License
10489+ * along with this program; see the file COPYING. If not, write to
10490+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10491+ *
10492+ * Module Name:
10493+ * nodetype.h
10494+ *
10495+ * Abstract: This module defines all of the node type codes used in this development
10496+ * shell. Every major data structure in the file system is assigned a node
10497+ * type code that is. This code is the first CSHORT in the structure and is
10498+ * followed by a CSHORT containing the size, in bytes, of the structure.
10499+ *
10500+ --*/
10501+#ifndef _NODETYPE_
10502+#define _NODETYPE_
10503+
10504+static char *ident_node = "aacraid_ident nodetype.h 1.0.6 2000/10/09 Adaptec, Inc.";
10505+
10506+typedef CSHORT NODE_TYPE_CODE;
10507+
10508+
10509+#define FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT ((NODE_TYPE_CODE)0x030b)
10510+#define FSAFS_NTC_FIB_CONTEXT ((NODE_TYPE_CODE)0x030c)
10511+
10512+
10513+typedef CSHORT NODE_BYTE_SIZE;
10514+
10515+
10516+//
10517+// The following definitions are used to generate meaningful blue bugcheck
10518+// screens. On a bugcheck the file system can output 4 ulongs of useful
10519+// information. The first ulong will have encoded in it a source file id
10520+// (in the high word) and the line number of the bugcheck (in the low word).
10521+// The other values can be whatever the caller of the bugcheck routine deems
10522+// necessary.
10523+//
10524+// Each individual file that calls bugcheck needs to have defined at the
10525+// start of the file a constant called BugCheckFileId with one of the
10526+// FSAFS_BUG_CHECK_ values defined below and then use FsaBugCheck to bugcheck
10527+// the system.
10528+//
10529+
10530+
10531+#define FSAFS_BUG_CHECK_COMMSUP (0X001e0000)
10532+#define FSAFS_BUG_CHECK_DPCSUP (0X001f0000)
10533+
10534+
10535+#define FsaBugCheck(A,B,C) { cmn_err( CE_PANIC, "aacdisk: module %x, line %x, 0x%x, 0x%x, 0x%x ", BugCheckFileId, __LINE__, A, B, C); }
10536+
10537+
10538+#endif // _NODETYPE_
10539+
10540diff -burN linux-2.4.9/drivers/scsi/aacraid/include/nvramioctl.h linux/drivers/scsi/aacraid/include/nvramioctl.h
10541--- linux-2.4.9/drivers/scsi/aacraid/include/nvramioctl.h Wed Dec 31 18:00:00 1969
10542+++ linux/drivers/scsi/aacraid/include/nvramioctl.h Thu Aug 16 13:41:30 2001
10543@@ -0,0 +1,112 @@
10544+/*++
10545+ * Adaptec aacraid device driver for Linux.
10546+ *
10547+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10548+ *
10549+ * This program is free software; you can redistribute it and/or modify
10550+ * it under the terms of the GNU General Public License as published by
10551+ * the Free Software Foundation; either version 2, or (at your option)
10552+ * any later version.
10553+ *
10554+ * This program is distributed in the hope that it will be useful,
10555+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10556+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10557+ * GNU General Public License for more details.
10558+ *
10559+ * You should have received a copy of the GNU General Public License
10560+ * along with this program; see the file COPYING. If not, write to
10561+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10562+ *
10563+ * Module Name:
10564+ * nvramioctl.h
10565+ *
10566+ * Abstract: This file defines the data structures related to querying
10567+ * and controlling the FSA NVRAM/WriteCache subsystem via the NVRAMIOCTL FIB.
10568+ *
10569+ --*/
10570+#ifndef _NVRAMIOCTL_H_
10571+#define _NVRAMIOCTL_H_ 1
10572+
10573+static char *ident_nvram = "aacraid_ident nvramioctl.h 1.0.6 2000/10/09 Adaptec, Inc.";
10574+
10575+/*
10576+ * NVRAM/Write Cache subsystem states
10577+ */
10578+typedef enum _NVSTATUS {
10579+ NVSTATUS_DISABLED = 0, // present, clean, not being used
10580+ NVSTATUS_ENABLED, // present, possibly dirty, ready for use
10581+ NVSTATUS_ERROR, // present, dirty, contains dirty data
10582+ // for bad/missing device
10583+ NVSTATUS_BATTERY, // present, bad or low battery, may contain dirty data
10584+ // for bad/missing device
10585+ NVSTATUS_UNKNOWN // present?????
10586+} _E_NVSTATUS;
10587+
10588+#ifdef AAC_32BIT_ENUMS
10589+typedef _E_NVSTATUS NVSTATUS;
10590+#else
10591+typedef AAC_UINT32 NVSTATUS;
10592+#endif
10593+
10594+/*
10595+ * NVRAM/Write Cache subsystem battery component states
10596+ *
10597+ */
10598+//NB: this enum should be identical to battery_status in nvram.h
10599+// or else collapsed into one enum someday
10600+typedef enum _NVBATTSTATUS {
10601+ NVBATTSTATUS_NONE = 0, // battery has no power or is not present
10602+ NVBATTSTATUS_LOW, // battery is low on power
10603+ NVBATTSTATUS_OK, // battery is okay - normal operation possible only in this state
10604+ NVBATTSTATUS_RECONDITIONING // no battery present - reconditioning in process
10605+} _E_NVBATTSTATUS;
10606+
10607+#ifdef AAC_32BIT_ENUMS
10608+typedef _E_NVBATTSTATUS NVBATTSTATUS;
10609+#else
10610+typedef AAC_UINT32 NVBATTSTATUS;
10611+#endif
10612+
10613+/*
10614+ * battery transition type
10615+ */
10616+typedef enum _NVBATT_TRANSITION {
10617+ NVBATT_TRANSITION_NONE = 0, // battery now has no power or is not present
10618+ NVBATT_TRANSITION_LOW, // battery is now low on power
10619+ NVBATT_TRANSITION_OK // battery is now okay - normal operation possible only in this state
10620+} _E_NVBATT_TRANSITION;
10621+
10622+#ifdef AAC_32BIT_ENUMS
10623+typedef _E_NVBATT_TRANSITION NVBATT_TRANSITION;
10624+#else
10625+typedef AAC_UINT32 NVBATT_TRANSITION;
10626+#endif
10627+
10628+/*
10629+ * NVRAM Info structure returned for NVRAM_GetInfo call
10630+ */
10631+typedef struct _NVRAMDEVINFO {
10632+ AAC_UINT32 NV_Enabled; /* write caching enabled */
10633+ AAC_UINT32 NV_Error; /* device in error state */
10634+ AAC_UINT32 NV_NDirty; /* count of dirty NVRAM buffers */
10635+ AAC_UINT32 NV_NActive; /* count of NVRAM buffers being written */
10636+} NVRAMDEVINFO, *PNVRAMDEVINFO;
10637+
10638+typedef struct _NVRAMINFO {
10639+ NVSTATUS NV_Status; /* nvram subsystem status */
10640+ NVBATTSTATUS NV_BattStatus; /* battery status */
10641+ AAC_UINT32 NV_Size; /* size of WriteCache NVRAM in bytes */
10642+ AAC_UINT32 NV_BufSize; /* size of NVRAM buffers in bytes */
10643+ AAC_UINT32 NV_NBufs; /* number of NVRAM buffers */
10644+ AAC_UINT32 NV_NDirty; /* count of dirty NVRAM buffers */
10645+ AAC_UINT32 NV_NClean; /* count of clean NVRAM buffers */
10646+ AAC_UINT32 NV_NActive; /* count of NVRAM buffers being written */
10647+ AAC_UINT32 NV_NBrokered; /* count of brokered NVRAM buffers */
10648+ NVRAMDEVINFO NV_DevInfo[NFILESYS]; /* per device info */
10649+ AAC_UINT32 NV_BattNeedsReconditioning; /* boolean */
10650+ AAC_UINT32 NV_TotalSize; /* total size of all non-volatile memories in bytes */
10651+} NVRAMINFO, *PNVRAMINFO;
10652+
10653+#endif /* !_NVRAMIOCTL_H_ */
10654+
10655+
10656diff -burN linux-2.4.9/drivers/scsi/aacraid/include/osheaders.h linux/drivers/scsi/aacraid/include/osheaders.h
10657--- linux-2.4.9/drivers/scsi/aacraid/include/osheaders.h Wed Dec 31 18:00:00 1969
10658+++ linux/drivers/scsi/aacraid/include/osheaders.h Thu Aug 16 18:12:22 2001
10659@@ -0,0 +1,127 @@
10660+/*++
10661+ * Adaptec aacraid device driver for Linux.
10662+ *
10663+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10664+ *
10665+ * This program is free software; you can redistribute it and/or modify
10666+ * it under the terms of the GNU General Public License as published by
10667+ * the Free Software Foundation; either version 2, or (at your option)
10668+ * any later version.
10669+ *
10670+ * This program is distributed in the hope that it will be useful,
10671+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10672+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10673+ * GNU General Public License for more details.
10674+ *
10675+ * You should have received a copy of the GNU General Public License
10676+ * along with this program; see the file COPYING. If not, write to
10677+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10678+ *
10679+ * Module Name:
10680+ * osheaders.h
10681+ *
10682+ * Abstract: Holds all of the header file includes for a particular O/S flavor.
10683+ *
10684+ --*/
10685+#ifndef _OSHEADERS_H_
10686+#define _OSHEADERS_H_
10687+
10688+static char *ident_oshead = "aacraid_ident osheaders.h 1.0.6 2000/10/09 Adaptec, Inc.";
10689+
10690+
10691+#include <linux/version.h>
10692+#include <linux/kernel.h>
10693+#include <linux/config.h>
10694+#include <linux/init.h>
10695+#include <linux/types.h>
10696+#include <linux/blk.h>
10697+#include <linux/blkdev.h>
10698+#include <linux/delay.h>
10699+#include <linux/ioport.h>
10700+#include <linux/mm.h>
10701+#include <linux/sched.h>
10702+#include <linux/stat.h>
10703+#include <linux/pci.h>
10704+#include <linux/interrupt.h>
10705+#include <asm/dma.h>
10706+#include <asm/io.h>
10707+#include <linux/spinlock.h>
10708+#include <asm/system.h>
10709+#include <asm/bitops.h>
10710+#include <asm/uaccess.h>
10711+#include <linux/wait.h>
10712+#include <linux/slab.h>
10713+#include <linux/tqueue.h>
10714+#include "ostypes.h"
10715+#include "scsi.h"
10716+#include "hosts.h"
10717+
10718+#ifndef intptr_t
10719+#define intptr_t void *
10720+#endif
10721+
10722+#ifndef cred_t
10723+#define cred_t void
10724+#endif
10725+
10726+#ifndef paddr32_t
10727+#define paddr32_t unsigned
10728+#endif
10729+
10730+#ifndef bzero
10731+#define bzero(b,len) memset(b,0,len)
10732+#endif
10733+
10734+#ifndef bcopy
10735+#define bcopy(src,dst,len) memcpy(dst,src,len )
10736+#endif
10737+
10738+#ifndef DEVICE_NR
10739+#define DEVICE_NR(device) ( ( ( MAJOR( device ) & 7 ) << 4 ) + ( MINOR( device ) >> 4 ) )
10740+#endif
10741+
10742+typedef unsigned uint_t;
10743+
10744+typedef enum
10745+{
10746+ CE_PANIC = 0,
10747+ CE_WARN,
10748+ CE_NOTE,
10749+ CE_CONT,
10750+ CE_DEBUG,
10751+ CE_DEBUG2,
10752+ CE_TAIL
10753+} CE_ENUM_T;
10754+
10755+#define CMN_ERR_LEVEL CE_NOTE
10756+
10757+#ifndef IN
10758+#define IN
10759+#endif
10760+
10761+// usage of READ & WRITE as a typedefs in protocol.h
10762+// conflicts with <linux/fs.h> definition.
10763+#ifdef READ
10764+#undef READ
10765+#endif
10766+
10767+#ifdef WRITE
10768+#undef WRITE
10769+#endif
10770+
10771+typedef struct aac_options
10772+{
10773+ int message_level;
10774+ int reverse_scan;
10775+} aac_options_t;
10776+
10777+#endif // _OSHEADERS_H_
10778+
10779+
10780+
10781+
10782+
10783+
10784+
10785+
10786+
10787diff -burN linux-2.4.9/drivers/scsi/aacraid/include/ostypes.h linux/drivers/scsi/aacraid/include/ostypes.h
10788--- linux-2.4.9/drivers/scsi/aacraid/include/ostypes.h Wed Dec 31 18:00:00 1969
10789+++ linux/drivers/scsi/aacraid/include/ostypes.h Thu Aug 16 13:41:30 2001
10790@@ -0,0 +1,149 @@
10791+/*++
10792+ * Adaptec aacraid device driver for Linux.
10793+ *
10794+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10795+ *
10796+ * This program is free software; you can redistribute it and/or modify
10797+ * it under the terms of the GNU General Public License as published by
10798+ * the Free Software Foundation; either version 2, or (at your option)
10799+ * any later version.
10800+ *
10801+ * This program is distributed in the hope that it will be useful,
10802+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10803+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10804+ * GNU General Public License for more details.
10805+ *
10806+ * You should have received a copy of the GNU General Public License
10807+ * along with this program; see the file COPYING. If not, write to
10808+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10809+ *
10810+ * Module Name:
10811+ * ostypes.h
10812+ *
10813+ * Abstract: Holds all of the O/S specific types.
10814+ *
10815+ --*/
10816+/*------------------------------------------------------------------------------
10817+ * D E F I N E S
10818+ *----------------------------------------------------------------------------*/
10819+#ifndef _OSTYPES_H_
10820+#define _OSTYPES_H_
10821+
10822+static char *ident_ostypes = "aacraid_ident ostypes.h 1.0.7 2000/10/11 Adaptec, Inc.";
10823+
10824+#include <linux/types.h>
10825+
10826+#define MAXIMUM_NUM_CONTAINERS 64 // 4 Luns * 16 Targets
10827+#define MAXIMUM_NUM_ADAPTERS 8
10828+
10829+#define OS_ALLOC_MEM_SLEEP GFP_KERNEL
10830+
10831+#define Os_remove_softintr OsSoftInterruptRemove
10832+#define OsPrintf printk
10833+#define FsaCommPrint
10834+
10835+// the return values for copy_from_user & copy_to_user is the
10836+// number of bytes not transferred. Thus if an internal error
10837+// occurs, the return value is greater than zero.
10838+#define COPYIN(SRC,DST,COUNT,FLAGS) copy_from_user(DST,SRC,COUNT)
10839+#define COPYOUT(SRC,DST,COUNT,FLAGS) copy_to_user(DST,SRC,COUNT)
10840+
10841+#define copyin(SRC,DST,COUNT) copy_from_user(DST,SRC,COUNT)
10842+#define copyout(SRC,DST,COUNT) copy_to_user(DST,SRC,COUNT)
10843+
10844+/*------------------------------------------------------------------------------
10845+ * S T R U C T S / T Y P E D E F S
10846+ *----------------------------------------------------------------------------*/
10847+typedef struct OS_MUTEX
10848+{
10849+ unsigned long lock_var;
10850+ wait_queue_head_t wq;
10851+ unsigned owner;
10852+} OS_MUTEX;
10853+
10854+typedef struct OS_SPINLOCK
10855+{
10856+ spinlock_t spin_lock;
10857+ unsigned cpu_lock_count[NR_CPUS];
10858+ unsigned long cpu_flags[NR_CPUS];
10859+ long lockout_count;
10860+} OS_SPINLOCK;
10861+
10862+#ifdef CVLOCK_USE_SPINLOCK
10863+ typedef OS_SPINLOCK OS_CVLOCK;
10864+#else
10865+ typedef OS_MUTEX OS_CVLOCK;
10866+#endif
10867+
10868+typedef size_t OS_SIZE_T;
10869+
10870+typedef struct OS_CV_T
10871+{
10872+ unsigned long lock_var;
10873+ unsigned long type;
10874+ wait_queue_head_t wq;
10875+} OS_CV_T;
10876+
10877+struct fsa_scsi_hba {
10878+ void *CommonExtension;
10879+ unsigned long ContainerSize[MAXIMUM_NUM_CONTAINERS];
10880+ unsigned long ContainerType[MAXIMUM_NUM_CONTAINERS];
10881+ unsigned char ContainerValid[MAXIMUM_NUM_CONTAINERS];
10882+ unsigned char ContainerReadOnly[MAXIMUM_NUM_CONTAINERS];
10883+ unsigned char ContainerLocked[MAXIMUM_NUM_CONTAINERS];
10884+ unsigned char ContainerDeleted[MAXIMUM_NUM_CONTAINERS];
10885+ long ContainerDevNo[MAXIMUM_NUM_CONTAINERS];
10886+};
10887+
10888+typedef struct fsa_scsi_hba fsadev_t;
10889+
10890+typedef struct OsKI
10891+{
10892+ struct Scsi_Host *scsi_host_ptr;
10893+ void * dip; // #REVISIT#
10894+ fsadev_t fsa_dev;
10895+ int thread_pid;
10896+ int MiniPortIndex;
10897+} OsKI_t;
10898+
10899+#define dev_info_t fsadev_t
10900+
10901+typedef int OS_SPINLOCK_COOKIE;
10902+
10903+typedef unsigned int OS_STATUS;
10904+
10905+typedef struct tq_struct OS_SOFTINTR;
10906+
10907+typedef OS_SOFTINTR *ddi_softintr_t;
10908+
10909+
10910+
10911+//-----------------------------------------------------------------------------
10912+// Conditional variable functions
10913+
10914+void OsCv_init (
10915+ OS_CV_T *cv_ptr );
10916+
10917+
10918+//-----------------------------------------------------------------------------
10919+// Printing functions
10920+void printk_err(int flag, char *fmt, ...);
10921+
10922+#define cmn_err printk_err
10923+
10924+
10925+//
10926+// just ignore these solaris ddi functions in the code
10927+//
10928+#define DDI_SUCCESS 0
10929+
10930+#define ddi_add_softintr(A,B,C,D,E,F,G) OsSoftInterruptAdd(C,F,G)
10931+
10932+//#REVIEW#
10933+#define ddi_remove_softintr(A) 0
10934+#define ddi_get_soft_iblock_cookie(A, B, C) 0
10935+
10936+#define ASSERT(expr) ((void) 0)
10937+#define drv_usecwait udelay
10938+
10939+#endif // _OSTYPES_H_
10940diff -burN linux-2.4.9/drivers/scsi/aacraid/include/pcisup.h linux/drivers/scsi/aacraid/include/pcisup.h
10941--- linux-2.4.9/drivers/scsi/aacraid/include/pcisup.h Wed Dec 31 18:00:00 1969
10942+++ linux/drivers/scsi/aacraid/include/pcisup.h Thu Aug 16 13:41:30 2001
10943@@ -0,0 +1,97 @@
10944+/*++
10945+ * Adaptec aacraid device driver for Linux.
10946+ *
10947+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10948+ *
10949+ * This program is free software; you can redistribute it and/or modify
10950+ * it under the terms of the GNU General Public License as published by
10951+ * the Free Software Foundation; either version 2, or (at your option)
10952+ * any later version.
10953+ *
10954+ * This program is distributed in the hope that it will be useful,
10955+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10956+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10957+ * GNU General Public License for more details.
10958+ *
10959+ * You should have received a copy of the GNU General Public License
10960+ * along with this program; see the file COPYING. If not, write to
10961+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10962+ *
10963+ * Module Name:
10964+ * pcisup.h
10965+ *
10966+ * Abstract: This module defines functions that are defined in PciSup.c
10967+ *
10968+ --*/
10969+#ifndef _PCISUP_
10970+#define _PCISUP_
10971+
10972+static char *ident_pcisup = "aacraid_ident pcisup.h 1.0.6 2000/10/09 Adaptec, Inc.";
10973+
10974+
10975+/*
10976+ * define which interrupt handler needs to be installed
10977+ */
10978+
10979+#define SaISR 1
10980+#define RxISR 2
10981+
10982+typedef struct _PCI_MINIPORT_COMMON_EXTENSION {
10983+ ULONG AdapterNumber; // Which FSA# this miniport is
10984+
10985+ ULONG PciBusNumber; // Which PCI bus we are located on
10986+ ULONG PciSlotNumber; // Whiat PCI slot we are in
10987+
10988+ PVOID Adapter; // Back pointer to Fsa adapter object
10989+ ULONG AdapterIndex; // Index into PlxAdapterTypes array
10990+ PDEVICE_OBJECT DeviceObject; // Pointer to our device object
10991+
10992+ FSAPORT_FUNCS AdapterFuncs;
10993+ ULONG FilesystemRevision; // Main driver's revision number
10994+
10995+
10996+ PADAPTER_INIT_STRUCT InitStruct; // Holds initialization info to communicate with adapter
10997+ PVOID PhysicalInitStruct; // Holds physical address of the init struct
10998+
10999+
11000+ PVOID PrintfBufferAddress; // pointer to buffer used for printf's from the adapter
11001+
11002+ BOOLEAN AdapterPrintfsToScreen;
11003+ BOOLEAN AdapterConfigured; // set to true when we know adapter can take FIBs
11004+
11005+ void * MiniPort;
11006+
11007+ caddr_t CommAddress; // Base address of Comm area
11008+ paddr32_t CommPhysAddr; // Physical Address of Comm area
11009+ size_t CommSize;
11010+
11011+ OsKI_t OsDep; // OS dependent kernel interfaces
11012+
11013+
11014+} PCI_MINIPORT_COMMON_EXTENSION;
11015+
11016+typedef PCI_MINIPORT_COMMON_EXTENSION *PPCI_MINIPORT_COMMON_EXTENSION;
11017+
11018+typedef int
11019+(*PFSA_MINIPORT_INIT) (
11020+ IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
11021+ IN ULONG AdapterNumber,
11022+ IN ULONG PciBus,
11023+ IN ULONG PciSlot
11024+ );
11025+
11026+typedef struct _FSA_MINIPORT {
11027+ USHORT VendorId;
11028+ USHORT DeviceId;
11029+ USHORT SubVendorId;
11030+ USHORT SubSystemId;
11031+ PCHAR DevicePrefix;
11032+ PFSA_MINIPORT_INIT InitRoutine;
11033+ PCHAR DeviceName;
11034+ PCHAR Vendor;
11035+ PCHAR Model;
11036+} FSA_MINIPORT;
11037+typedef FSA_MINIPORT *PFSA_MINIPORT;
11038+
11039+
11040+#endif // _PCISUP_
11041diff -burN linux-2.4.9/drivers/scsi/aacraid/include/perfpack.h linux/drivers/scsi/aacraid/include/perfpack.h
11042--- linux-2.4.9/drivers/scsi/aacraid/include/perfpack.h Wed Dec 31 18:00:00 1969
11043+++ linux/drivers/scsi/aacraid/include/perfpack.h Thu Aug 16 13:41:30 2001
11044@@ -0,0 +1,110 @@
11045+/*++
11046+ * Adaptec aacraid device driver for Linux.
11047+ *
11048+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11049+ *
11050+ * This program is free software; you can redistribute it and/or modify
11051+ * it under the terms of the GNU General Public License as published by
11052+ * the Free Software Foundation; either version 2, or (at your option)
11053+ * any later version.
11054+ *
11055+ * This program is distributed in the hope that it will be useful,
11056+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11057+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11058+ * GNU General Public License for more details.
11059+ *
11060+ * You should have received a copy of the GNU General Public License
11061+ * along with this program; see the file COPYING. If not, write to
11062+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11063+ *
11064+ * Module Name:
11065+ * perfpack.h
11066+ *
11067+ * Abstract: This file defines the layout of the performance data that is passed
11068+ * back from the FSA filesystem driver.
11069+ *
11070+ *
11071+ --*/
11072+
11073+#ifndef _FSA_PERFPACK_H_
11074+#define _FSA_PERFPACK_H_ 1
11075+
11076+static char *ident_perf = "aacraid_ident perfpack.h 1.0.6 2000/10/09 Adaptec, Inc.";
11077+
11078+//#define FSA_DO_PERF 1 /* enable the engineering counters */
11079+
11080+#ifdef FSA_DO_PERF
11081+//
11082+// engineering counters
11083+//
11084+typedef struct _FSA_PERF_DATA {
11085+ ULONG FibsSent;
11086+ ULONG ReadDirs;
11087+ ULONG GetAttrs;
11088+ ULONG SetAttrs;
11089+ ULONG Lookups;
11090+ ULONG ReadFibs;
11091+ ULONG WriteFibs;
11092+ ULONG CreateFibs;
11093+ ULONG MakeDirs;
11094+ ULONG RemoveFibs;
11095+ ULONG RemoveDirs;
11096+ ULONG RenameFibs;
11097+ ULONG ReadDirPlus;
11098+ ULONG FsStat;
11099+ ULONG WriteBytes;
11100+ ULONG ReadBytes;
11101+// NT FSA entry points
11102+ ULONG FsaFsdCreateCount;
11103+ ULONG FsaFsdCloseCount;
11104+ ULONG FsaFsdReadCount;
11105+ ULONG FsaFsdWriteCount;
11106+ ULONG FsaFsdQueryInformationCount;
11107+
11108+ struct _FsaFsdSetInfomation{
11109+ ULONG FsaSetAllocationInfoCount;
11110+ ULONG FsaSetBasicInfoCount;
11111+ ULONG FsaSetDispositionInfoCount;
11112+ ULONG FsaSetEndOfFileInfoCount;
11113+ ULONG FsaSetPositionInfoCount;
11114+ ULONG FsaSetRenameInfoCount;
11115+ ULONG FsaClearArchiveBitCount;
11116+ };
11117+
11118+ ULONG FsaFsdFlushBuffersCount;
11119+ ULONG FsaFsdQueryVolumeInfoCount;
11120+ ULONG FsaFsdSetVolumeInfoCount;
11121+ ULONG FsaFsdCleanupCount;
11122+ ULONG FsaFsdDirectoryControlCount;
11123+ ULONG FsaFsdFileSystemControlCount;
11124+ ULONG FsaFsdLockControlCount;
11125+ ULONG FsaFsdDeviceControlCount;
11126+ ULONG FsaFsdShutdownCount;
11127+ ULONG FsaFsdQuerySecurityInfo;
11128+ ULONG FsaFsdSetSecurityInfo;
11129+ ULONG FastIoCheckIfPossibleCount;
11130+ ULONG FastIoReadCount;
11131+ ULONG FastIoWriteCount;
11132+ ULONG FastIoQueryBasicInfoCount;
11133+ ULONG FastIoQueryStandardInfoCount;
11134+ ULONG FastIoLockCount;
11135+ ULONG FastIoUnlockSingleCount;
11136+ ULONG FastIoUnlockAllCount;
11137+ ULONG FastIoUnlockAllByKeyCount;
11138+ ULONG FastIoDeviceControlCount;
11139+ } FSA_PERF_DATA;
11140+
11141+typedef FSA_PERF_DATA *PFSA_PERF_DATA;
11142+
11143+
11144+#else /* FSA_DO_PERF */
11145+
11146+//
11147+// engineering performance counters are disabled
11148+//
11149+#define FSA_DO_PERF_INC(Counter) /* */
11150+#define FSA_DO_FSP_PERF_INC(Counter) /* */
11151+
11152+#endif /* FSA_DO_PERF */
11153+
11154+#endif // _FSA_PERFPACK_H_
11155diff -burN linux-2.4.9/drivers/scsi/aacraid/include/port.h linux/drivers/scsi/aacraid/include/port.h
11156--- linux-2.4.9/drivers/scsi/aacraid/include/port.h Wed Dec 31 18:00:00 1969
11157+++ linux/drivers/scsi/aacraid/include/port.h Thu Aug 16 18:16:55 2001
11158@@ -0,0 +1,87 @@
11159+/*++
11160+ * Adaptec aacraid device driver for Linux.
11161+ *
11162+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11163+ *
11164+ * This program is free software; you can redistribute it and/or modify
11165+ * it under the terms of the GNU General Public License as published by
11166+ * the Free Software Foundation; either version 2, or (at your option)
11167+ * any later version.
11168+ *
11169+ * This program is distributed in the hope that it will be useful,
11170+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11171+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11172+ * GNU General Public License for more details.
11173+ *
11174+ * You should have received a copy of the GNU General Public License
11175+ * along with this program; see the file COPYING. If not, write to
11176+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11177+ *
11178+ * Module Name:
11179+ * port.h
11180+ *
11181+ * Abstract: This module defines functions and structures that are in common among all miniports
11182+ *
11183+ *
11184+ --*/
11185+
11186+#ifndef _PORT_
11187+#define _PORT_
11188+
11189+static char *ident_porth = "aacraid_ident port.h 1.0.6 2000/10/09 Adaptec, Inc.";
11190+
11191+#ifdef DBG
11192+#define AfaPortPrint if (AfaPortPrinting) DbgPrint
11193+extern int AfaPortPrinting;
11194+#else
11195+#define AfaPortPrint
11196+#endif /* DBG */
11197+
11198+extern int AfaPortPrinting;
11199+
11200+
11201+BOOLEAN
11202+AfaPortAllocateAdapterCommArea(
11203+ IN PVOID Arg1,
11204+ IN OUT PVOID *CommHeaderAddress,
11205+ IN ULONG CommAreaSize,
11206+ IN ULONG CommAreaAlignment
11207+ );
11208+
11209+
11210+BOOLEAN
11211+AfaPortFreeAdapterCommArea(
11212+ IN PVOID Arg1
11213+ );
11214+
11215+
11216+AAC_STATUS
11217+AfaPortBuildSgMap(
11218+ PVOID Arg1,
11219+ IN PSGMAP_CONTEXT SgMapContext
11220+ );
11221+
11222+
11223+VOID
11224+AfaPortFreeDmaResources(
11225+ PVOID Arg1,
11226+ IN PSGMAP_CONTEXT SgMapContext
11227+ );
11228+
11229+
11230+BOOLEAN
11231+AfaPortAllocateAndMapFibSpace(
11232+ PVOID Arg1,
11233+ IN PMAPFIB_CONTEXT MapFibContext
11234+ );
11235+
11236+
11237+BOOLEAN
11238+AfaPortUnmapAndFreeFibSpace(
11239+ PVOID Arg1,
11240+ IN PMAPFIB_CONTEXT MapFibContext
11241+ );
11242+
11243+
11244+#endif // _PORT_
11245+
11246diff -burN linux-2.4.9/drivers/scsi/aacraid/include/protocol.h linux/drivers/scsi/aacraid/include/protocol.h
11247--- linux-2.4.9/drivers/scsi/aacraid/include/protocol.h Wed Dec 31 18:00:00 1969
11248+++ linux/drivers/scsi/aacraid/include/protocol.h Thu Aug 16 13:41:30 2001
11249@@ -0,0 +1,249 @@
11250+/*++
11251+ * Adaptec aacraid device driver for Linux.
11252+ *
11253+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11254+ *
11255+ * This program is free software; you can redistribute it and/or modify
11256+ * it under the terms of the GNU General Public License as published by
11257+ * the Free Software Foundation; either version 2, or (at your option)
11258+ * any later version.
11259+ *
11260+ * This program is distributed in the hope that it will be useful,
11261+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11262+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11263+ * GNU General Public License for more details.
11264+ *
11265+ * You should have received a copy of the GNU General Public License
11266+ * along with this program; see the file COPYING. If not, write to
11267+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11268+ *
11269+ * Module Name:
11270+ * protocol.h
11271+ *
11272+ * Abstract: Defines the commands and command data which enables the nt
11273+ * filesystem driver to be the client of the fsa adapter
11274+ * filesystem. This protocol is largely modeled after the NFS
11275+ * V3 protocol with modifications allowed due to the unique
11276+ * client/server model FSA works under.
11277+ *
11278+ *
11279+ *
11280+ --*/
11281+
11282+#ifndef _PROTOCOL_H_
11283+#define _PROTOCOL_H_
11284+
11285+static char *ident_protocol = "aacraid_ident protocol.h 1.0.6 2000/10/09 Adaptec, Inc.";
11286+
11287+#include <fsafs.h> // definition of FSAFID; includes fsatypes.h
11288+#include <nvramioctl.h> // for NVRAMINFO definition
11289+
11290+// #define MDL_READ_WRITE
11291+
11292+//
11293+// Define the command values
11294+//
11295+typedef enum _FSA_COMMANDS {
11296+ Null = 0,
11297+ GetAttributes,
11298+ SetAttributes,
11299+ Lookup,
11300+ ReadLink,
11301+ Read,
11302+ Write,
11303+ Create,
11304+ MakeDirectory,
11305+ SymbolicLink,
11306+ MakeNode,
11307+ Removex,
11308+ RemoveDirectoryx, // bkpfix added x to this because already defined in nt
11309+ Rename,
11310+ Link,
11311+ ReadDirectory,
11312+ ReadDirectoryPlus,
11313+ FileSystemStatus,
11314+ FileSystemInfo,
11315+ PathConfigure,
11316+ Commit,
11317+ Mount,
11318+ UnMount,
11319+ Newfs,
11320+ FsCheck,
11321+ FsSync,
11322+ SimReadWrite,
11323+ SetFileSystemStatus,
11324+ BlockRead,
11325+ BlockWrite,
11326+ NvramIoctl,
11327+ FsSyncWait,
11328+ ClearArchiveBit,
11329+#ifdef MDL_READ_WRITE
11330+ MdlReadComplete,
11331+ MdlWriteComplete,
11332+ MdlRead, // these are used solely for stats, Mdl really controlled by
11333+ MdlWrite, // flags field in Fib.
11334+#endif
11335+ SetAcl,
11336+ GetAcl,
11337+ AssignAcl,
11338+ FaultInsertion, // Fault Insertion Command
11339+ CrazyCache, // crazycache
11340+ MAX_FSACOMMAND_NUM //CJ: used for sizing stats array - leave last
11341+} _E_FSACOMMAND;
11342+
11343+#ifdef AAC_32BIT_ENUMS
11344+typedef _E_FSACOMMAND FSACOMMAND;
11345+#else
11346+typedef AAC_UINT32 FSACOMMAND;
11347+#endif
11348+
11349+
11350+
11351+//
11352+// Define the status returns
11353+//
11354+// See include\comm\errno.h for adapter kernel errno's
11355+typedef enum _FSASTATUS {
11356+ ST_OK = 0,
11357+ ST_PERM = 1,
11358+ ST_NOENT = 2,
11359+ ST_IO = 5,
11360+ ST_NXIO = 6,
11361+ ST_E2BIG = 7,
11362+ ST_ACCES = 13,
11363+ ST_EXIST = 17,
11364+ ST_XDEV = 18,
11365+ ST_NODEV = 19,
11366+ ST_NOTDIR = 20,
11367+ ST_ISDIR = 21,
11368+ ST_INVAL = 22,
11369+ ST_FBIG = 27,
11370+ ST_NOSPC = 28,
11371+ ST_ROFS = 30,
11372+ ST_MLINK = 31,
11373+ ST_WOULDBLOCK = 35,
11374+ ST_NAMETOOLONG = 63,
11375+ ST_NOTEMPTY = 66,
11376+ ST_DQUOT = 69,
11377+ ST_STALE = 70,
11378+ ST_REMOTE = 71,
11379+ ST_BADHANDLE = 10001,
11380+ ST_NOT_SYNC = 10002,
11381+ ST_BAD_COOKIE = 10003,
11382+ ST_NOTSUPP = 10004,
11383+ ST_TOOSMALL = 10005,
11384+ ST_SERVERFAULT = 10006,
11385+ ST_BADTYPE = 10007,
11386+ ST_JUKEBOX = 10008,
11387+ ST_NOTMOUNTED = 10009,
11388+ ST_MAINTMODE = 10010,
11389+ ST_STALEACL = 10011
11390+} _E_FSASTATUS;
11391+
11392+#ifdef AAC_32BIT_ENUMS
11393+typedef _E_FSASTATUS FSASTATUS;
11394+#else
11395+typedef AAC_UINT32 FSASTATUS;
11396+#endif
11397+
11398+//
11399+// On writes how does the client want the data written.
11400+//
11401+
11402+typedef enum _CACHELEVEL {
11403+ CSTABLE = 1,
11404+ CUNSTABLE
11405+} _E_CACHELEVEL;
11406+
11407+#ifdef AAC_32BIT_ENUMS
11408+typedef _E_CACHELEVEL CACHELEVEL;
11409+#else
11410+typedef AAC_UINT32 CACHELEVEL;
11411+#endif
11412+
11413+//
11414+// Lets the client know at which level the data was commited on a write request
11415+//
11416+
11417+typedef enum _COMMITLEVEL {
11418+ CMFILE_SYNCH_NVRAM = 1,
11419+ CMDATA_SYNCH_NVRAM,
11420+ CMFILE_SYNCH,
11421+ CMDATA_SYNCH,
11422+ CMUNSTABLE
11423+} _E_COMMITLEVEL;
11424+
11425+#ifdef AAC_32BIT_ENUMS
11426+typedef _E_COMMITLEVEL COMMITLEVEL;
11427+#else
11428+typedef AAC_UINT32 COMMITLEVEL;
11429+#endif
11430+
11431+
11432+
11433+//
11434+// The following are all the different commands or FIBs which can be sent to the
11435+// FSA filesystem. We will define a required subset which cannot return STATUS_NOT_IMPLEMENTED,
11436+// but others outside that subset are allowed to return not implemented. The client is then
11437+// responsible for dealing with the fact it is not implemented.
11438+//
11439+typedef AAC_INT8 FSASTRING[16];
11440+
11441+
11442+typedef AAC_UINT32 BYTECOUNT; // only 32 bit-ism
11443+
11444+
11445+
11446+//
11447+// BlockRead
11448+//
11449+
11450+typedef struct _BLOCKREAD { // variable size struct
11451+
11452+ FSACOMMAND Command;
11453+ AAC_UINT32 ContainerId;
11454+ BYTECOUNT BlockNumber;
11455+ BYTECOUNT ByteCount;
11456+ SGMAP SgMap; // Must be last in struct because it is variable
11457+
11458+} BLOCKREAD;
11459+typedef BLOCKREAD *PBLOCKREAD;
11460+
11461+typedef struct _BLOCKREADRESPONSE {
11462+
11463+ FSASTATUS Status;
11464+ BYTECOUNT ByteCount;
11465+
11466+} BLOCKREADRESPONSE;
11467+typedef BLOCKREADRESPONSE *PBLOCKREADRESPONSE;
11468+
11469+//
11470+// BlockWrite
11471+//
11472+
11473+typedef struct _BLOCKWRITE { // variable size struct
11474+
11475+ FSACOMMAND Command;
11476+ AAC_UINT32 ContainerId;
11477+ BYTECOUNT BlockNumber;
11478+ BYTECOUNT ByteCount;
11479+ CACHELEVEL Stable;
11480+ SGMAP SgMap; // Must be last in struct because it is variable
11481+
11482+} BLOCKWRITE;
11483+typedef BLOCKWRITE *PBLOCKWRITE;
11484+
11485+
11486+typedef struct _BLOCKWRITERESPONSE {
11487+
11488+ FSASTATUS Status;
11489+ BYTECOUNT ByteCount;
11490+ COMMITLEVEL Committed;
11491+
11492+} BLOCKWRITERESPONSE;
11493+typedef BLOCKWRITERESPONSE *PBLOCKWRITERESPONSE;
11494+
11495+
11496+
11497+#endif // _PROTOCOL_H_
11498+
11499diff -burN linux-2.4.9/drivers/scsi/aacraid/include/revision.h linux/drivers/scsi/aacraid/include/revision.h
11500--- linux-2.4.9/drivers/scsi/aacraid/include/revision.h Wed Dec 31 18:00:00 1969
11501+++ linux/drivers/scsi/aacraid/include/revision.h Thu Aug 16 13:41:30 2001
11502@@ -0,0 +1,350 @@
11503+/*++
11504+ * Adaptec aacraid device driver for Linux.
11505+ *
11506+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11507+ *
11508+ * This program is free software; you can redistribute it and/or modify
11509+ * it under the terms of the GNU General Public License as published by
11510+ * the Free Software Foundation; either version 2, or (at your option)
11511+ * any later version.
11512+ *
11513+ * This program is distributed in the hope that it will be useful,
11514+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11515+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11516+ * GNU General Public License for more details.
11517+ *
11518+ * You should have received a copy of the GNU General Public License
11519+ * along with this program; see the file COPYING. If not, write to
11520+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11521+ *
11522+ * Module Name:
11523+ * revision.h
11524+ *
11525+ * Abstract: This module contains all of the revision information for
11526+ * the FSA product, as well as the support routines for
11527+ * checking module compatibility.
11528+ *
11529+ * Before editing anything in this module, make sure that
11530+ * you read the comments. Some lines are changed automatically
11531+ * as part of the build, and should never be changed by hand.
11532+ *
11533+ * Routines (all inlines):
11534+ *
11535+ * RevGetBuildNumber - Retrieve current build number
11536+ * RevGetExternalRev - Retrieve revision for external use
11537+ * RevGetFullRevision - Retrieve full revision structure
11538+ *
11539+ * RevCheckCompatibility - Checks compatibility base on internal table
11540+ *
11541+ * RevCheckCompatibilityFullInfo - Check for static component
11542+ * RevGetCompInfoTableSize - Get size for static component table
11543+ * RevGetCompInfoTable - Get actual table to place on static component
11544+ * RevGetBuildNumberFromInfo - Get build number for static component.
11545+ *
11546+ *
11547+ *
11548+ --*/
11549+
11550+#ifndef _REVISION_H
11551+#define _REVISION_H
11552+
11553+static char *ident_revision = "aacraid_ident revision.h 1.0.6 2000/10/09 Adaptec, Inc.";
11554+
11555+#include "version.h" // revision numbers kept separate so they can be used by resource compiler as well
11556+
11557+typedef int REV_BOOL;
11558+
11559+#define REV_TRUE 1
11560+#define REV_FALSE 0
11561+
11562+//
11563+// Define Revision Levels for this product
11564+//
11565+// IMPORTANT: Do NOT modify BUILD_NUMBER define, this is modified
11566+// automatically by the build.
11567+//
11568+// Version is VMAJOR.MINOR-DASH TYPE (Build BUILD_NUMBER)
11569+//
11570+// IMPORTANT: Don't access these revisions directly. They can be
11571+// accessed via, the RevGetXxxxx rouines.
11572+//
11573+
11574+
11575+#define REV_AS_LONGWORD \
11576+ ((REV_MAJOR << 24) | (REV_MINOR << 16) | (REV_TYPE << 8) | (REV_DASH))
11577+
11578+
11579+
11580+#ifndef BIOS
11581+
11582+//
11583+// Enumerate the types of product levels we can have
11584+//
11585+enum {
11586+ RevType_Devo=1, // Development mode, testing all of latest
11587+ RevType_Alpha, // Alpha - Internal field test
11588+ RevType_Beta, // Beta - External field test
11589+ RevType_Release // Release - Retail version
11590+};
11591+
11592+//
11593+// Define the basic structure for all revision information. Note
11594+// that the ordering of the components is such that they should
11595+// always increase. dash will be updated the most, then the version
11596+// type, then minor and major.
11597+//
11598+typedef struct {
11599+ union {
11600+ struct {
11601+ unsigned char dash; // Dash version number
11602+ unsigned char type; // Type, 1=Devo, 2=Alpha, 3=Beta, 4=Release
11603+ unsigned char minor;// Minor version minor
11604+ unsigned char major;// Major version number
11605+ } comp; // Components to external viewed rev number
11606+ unsigned long ul; // External revision as single 32-bit value
11607+ } external; // External revision number (union)
11608+ unsigned long buildNumber; // Automatically generated build number
11609+} FsaRevision;
11610+
11611+
11612+//
11613+// Define simple routines to get basic revision information. The
11614+// definitions should never be accessed directly. These routines
11615+// are meant to be used to access all relevant information no matter
11616+// how simple.
11617+//
11618+static inline unsigned long RevGetBuildNumber() {return REV_BUILD_NUMBER;}
11619+
11620+static inline unsigned long RevGetExternalRev() {return REV_AS_LONGWORD;}
11621+
11622+
11623+//
11624+// Enumerate different components that may have to check
11625+// compatibility. This list of components can be changed
11626+// at any time.
11627+//
11628+// IMPORTANT: ONLY add to the END of this enum structure. Otherwise,
11629+// incompatibilities between component rev checking will
11630+// cause wrong checking results.
11631+//
11632+typedef enum {
11633+ RevApplication = 1, // Any user End application
11634+ RevDkiCli, // ADAPTEC proprietary interface (knows FIBs)
11635+ RevNetService, // Network Service Revision (under API)
11636+ RevApi, // ADAPTEC User mode API
11637+ RevFileSysDriver, // FSA File System Driver
11638+ RevMiniportDriver, // FSA File System Miniport Driver
11639+ RevAdapterSW, // Adapter Software (or NT Simulator)
11640+ RevMonitor, // Monitor for adapter hardware (MON960 for now)
11641+ RevRemoteApi // The remote API.
11642+ // ALWAYS ADD NEW COMPONENTS HERE - AT END
11643+} RevComponent;
11644+
11645+//
11646+// Define a structure so that we can create a compatibility table.
11647+//
11648+typedef struct {
11649+ RevComponent A,B;
11650+ unsigned long BuildNumOfB_RequiredByA;
11651+ unsigned long BuildNumOfA_RequiredByB;
11652+} RevCompareElement;
11653+
11654+//
11655+// Now, define the table. This table should only be included once,
11656+// in one program. If it is linked from 2 modules, there will likely
11657+// be a multiply defined symbol error from the linker.
11658+//
11659+// To fix this problem, REV_REFERENCE_ONLY can be defined. This will
11660+// allow access to the revision information table without a redefinition
11661+// of the tables.
11662+//
11663+extern const int RevCompareTableLength;
11664+
11665+extern const RevCompareElement RevCompareTable[];
11666+
11667+/********************************************************************\
11668+* Routine: RevCheckCompatibility(callerComp,compB,compB_BuildNumber)
11669+*
11670+* The following routine is used to check compatibility between
11671+* the calling component and a component that has some dependencies
11672+* on it. If this routine returns REV_FALSE, it is expected that the caller
11673+* will send an appropriate incompatibility message and stop.
11674+*
11675+* This routine is only meant to check for compatibility in the
11676+* absolute sense. If code wishes to execute a different path based
11677+* on the CompB_BuildNumber, then this routine is not useful. The
11678+* routine RevGetBuildNumber can be used to get the calling module's
11679+* current build number for a comparison check.
11680+*
11681+* The return value is REV_TRUE, if compatibility is possible, and REV_FALSE
11682+* if the components are definitely not compatible, or there is an
11683+* error when trying to figure it out. To be more specific:
11684+*
11685+* 1) REV_TRUE if component B is newer than calling component. (In this
11686+* case, the revision check done by component B with respect to
11687+* this component will give the real compatibility information.
11688+* It is the only one with the knowledge, since this component
11689+* could not look into the future.)
11690+* 2) REV_TRUE if calling component is more recent and table shows okay
11691+* 3) REV_FALSE if calling component more recent and table show not okay
11692+* 4) REV_FALSE if calling component is more recent and table entry to
11693+* check does not exist.
11694+*
11695+* Note that the CompB_BuildNumber must be attained by the calling
11696+* routine through some mechanism done by the caller.
11697+*
11698+* Input:
11699+*
11700+* callerComp - Name of component making this call
11701+* compB - Name of component to check compatibility with
11702+* compB_BuildNumber - Build number to component B
11703+*
11704+* Output:
11705+*
11706+* None
11707+*
11708+* Return Value:
11709+*
11710+* REV_TRUE - Component compatibility is possible, continue as usual. compB
11711+* must give true compatibility information.
11712+* REV_FALSE - Incompatible components, notify and end
11713+*
11714+\********************************************************************/
11715+static inline REV_BOOL RevCheckCompatibility(
11716+ RevComponent callerComp,
11717+ RevComponent compB,
11718+ unsigned long compB_BuildNumber)
11719+{
11720+ int i;
11721+ unsigned long RevForB;
11722+
11723+ //
11724+ // Compatibility check is possible, so we should continue. When
11725+ // compB makes this call in its own component, it will get the
11726+ // true compatibility information, since only it can know.
11727+ //
11728+ if (RevGetBuildNumber() < compB_BuildNumber) return REV_TRUE;
11729+
11730+ //
11731+ // Go through rev table. When the components are found in the
11732+ // same table entry, return the approprate number.
11733+ //
11734+ for (i=0; i<RevCompareTableLength; i++) {
11735+ if (RevCompareTable[i].A == callerComp) {
11736+ if (RevCompareTable[i].B == compB) {
11737+ RevForB = RevCompareTable[i].BuildNumOfB_RequiredByA;
11738+ return (compB_BuildNumber >= RevForB);
11739+ }
11740+ } else if (RevCompareTable[i].B == callerComp) {
11741+ if (RevCompareTable[i].A == compB) {
11742+ RevForB = RevCompareTable[i].BuildNumOfA_RequiredByB;
11743+ return (compB_BuildNumber >= RevForB);
11744+ }
11745+ }
11746+ }
11747+
11748+ //
11749+ // Uh oh! No relevant table entry was found (this should never
11750+ // happen).
11751+ //
11752+ return REV_FALSE;
11753+}
11754+
11755+
11756+//
11757+// Now create a structure that can be used by a FIB to check
11758+// compatibility.
11759+//
11760+typedef struct _RevCheck {
11761+ RevComponent callingComponent;
11762+ FsaRevision callingRevision;
11763+} RevCheck;
11764+
11765+typedef struct _RevCheckResp {
11766+ REV_BOOL possiblyCompatible;
11767+ FsaRevision adapterSWRevision;
11768+} RevCheckResp;
11769+
11770+#endif /* bios */
11771+#endif /* _REVISION_H */
11772+
11773+//
11774+// The following allows for inclusion of revision.h in other h
11775+// files. when you include this file in another h file, simply
11776+// define REV_REFERENCE_ONLY. This will be undefined later, so that
11777+// the single C file inclusion in the module will be used to
11778+// implement the global structures.
11779+//
11780+#ifndef REV_REFERENCE_ONLY
11781+#ifndef _REVISION_H_GLOBAL
11782+#define _REVISION_H_GLOBAL
11783+
11784+
11785+
11786+//
11787+// The following array is the table of compatibility. This table
11788+// can be modified in two ways:
11789+//
11790+// 1) A component which has an incompatible change done to
11791+// it, can get a new build number.
11792+//
11793+// 2) A new component can be added, requiring more entries
11794+// to be place into this table.
11795+//
11796+//
11797+// In case (1), you must change the revision number in the appropriate
11798+// column, based on which component absolutely requires an upgrade.
11799+//
11800+// Example: A new FIB used by the API, in build number 105
11801+// {RevApi, RevAdapterSW, 100, 100}
11802+// ---> would be changed to <---
11803+// {RevApi, RevAdapterSW, 105, 100}
11804+//
11805+// Example: A structure is changed for a FIB that only the API uses
11806+// {RevApi, RevAdapterSW, 100, 100}
11807+// ---> would be changed to <---
11808+// {RevApi, RevAdapterSW, 105, 105}
11809+//
11810+//
11811+// In case (2), the less common case, the enumerated list of
11812+// components must be changed to include the new component. Then
11813+// entries need to be placed into this table.
11814+//
11815+// Since the revisions must be communicated between the two
11816+// components, it is likely that you would need to put in the
11817+// current build number for both columns. That is the recommended
11818+// way to start revision test.
11819+//
11820+const RevCompareElement RevCompareTable[] = {
11821+ // Component A Component B MinBForA MinAForB
11822+ // ----------- ----------- -------- --------
11823+ {RevApplication, RevApi, 2120, 2120 },
11824+ {RevDkiCli, RevApi, 2120, 2120 },
11825+ {RevDkiCli, RevFileSysDriver, 257, 257 },
11826+ {RevDkiCli, RevMiniportDriver, 257, 257 },
11827+ {RevDkiCli, RevAdapterSW, 257, 257 },
11828+ {RevApi, RevFileSysDriver, 2120, 2120 },
11829+ {RevApi, RevMiniportDriver, 2120, 2120 },
11830+ {RevApi, RevAdapterSW, 2120, 2120 },
11831+ {RevApi, RevNetService, 2120, 2120 },
11832+ {RevFileSysDriver, RevMiniportDriver, 100, 100 },
11833+ {RevFileSysDriver, RevAdapterSW, 257, 257 },
11834+ {RevMiniportDriver, RevAdapterSW, 257, 257 },
11835+ {RevMiniportDriver, RevMonitor, 100, 100 },
11836+ {RevApi, RevNetService, 2120, 2120 },
11837+ {RevApi, RevRemoteApi, 2120, 2120 },
11838+ {RevNetService, RevRemoteApi, 2120, 2120 }
11839+};
11840+
11841+const int RevCompareTableLength = sizeof(RevCompareTable)/sizeof(RevCompareElement);
11842+
11843+#endif /* _REVISION_H_GLOBAL */
11844+#endif /* REV_REFERENCE_ONLY */
11845+#undef REV_REFERENCE_ONLY
11846+
11847+
11848+
11849+
11850+
11851+
11852+
11853diff -burN linux-2.4.9/drivers/scsi/aacraid/include/rx.h linux/drivers/scsi/aacraid/include/rx.h
11854--- linux-2.4.9/drivers/scsi/aacraid/include/rx.h Wed Dec 31 18:00:00 1969
11855+++ linux/drivers/scsi/aacraid/include/rx.h Thu Aug 16 13:41:30 2001
11856@@ -0,0 +1,81 @@
11857+/*++
11858+ * Adaptec aacraid device driver for Linux.
11859+ *
11860+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11861+ *
11862+ * This program is free software; you can redistribute it and/or modify
11863+ * it under the terms of the GNU General Public License as published by
11864+ * the Free Software Foundation; either version 2, or (at your option)
11865+ * any later version.
11866+ *
11867+ * This program is distributed in the hope that it will be useful,
11868+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11869+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11870+ * GNU General Public License for more details.
11871+ *
11872+ * You should have received a copy of the GNU General Public License
11873+ * along with this program; see the file COPYING. If not, write to
11874+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11875+ *
11876+ * Module Name:
11877+ * rx.h
11878+ *
11879+ * Abstract: Prototypes and data structures unique to the Rx based controller board.
11880+ *
11881+ *
11882+ --*/
11883+
11884+static char *ident_rxh = "aacraid_ident rx.h 1.0.6 2000/10/09 Adaptec, Inc.";
11885+
11886+typedef struct _Rx_ADAPTER_EXTENSION {
11887+
11888+ //
11889+ // The following must be first.
11890+ //
11891+ PPCI_MINIPORT_COMMON_EXTENSION Common;
11892+ struct _Rx_ADAPTER_EXTENSION *Next; // Next adapter miniport structure
11893+ USHORT LocalMaskInterruptControl;
11894+ PRx_DEVICE_REGISTERS Device;
11895+
11896+} Rx_ADAPTER_EXTENSION;
11897+
11898+
11899+typedef Rx_ADAPTER_EXTENSION *PRx_ADAPTER_EXTENSION;
11900+
11901+
11902+
11903+#ifdef LINUX
11904+/*
11905+ *
11906+ */
11907+
11908+#define Rx_READ_UCHAR(AEP, CSR) *(volatile unsigned char *) &((AEP)->Device->CSR)
11909+
11910+
11911+
11912+#define Rx_READ_ULONG(AEP, CSR) *(volatile unsigned int *) &((AEP)->Device->CSR)
11913+#define Rx_WRITE_UCHAR(AEP, CSR, Value) *(volatile unsigned char *) &((AEP)->Device->CSR) = (Value)
11914+
11915+
11916+#define Rx_WRITE_ULONG(AEP, CSR, Value) *(volatile unsigned int *) &((AEP)->Device->CSR) = (Value)
11917+
11918+#endif /* LINUX */
11919+
11920+
11921+VOID
11922+RxInterruptAdapter(
11923+ PVOID Arg1
11924+ );
11925+
11926+VOID
11927+RxNotifyAdapter(
11928+ PVOID Arg1,
11929+ IN HOST_2_ADAP_EVENT AdapterEvent
11930+ );
11931+
11932+VOID
11933+RxResetDevice(
11934+ PVOID Arg1
11935+ );
11936+
11937+
11938diff -burN linux-2.4.9/drivers/scsi/aacraid/include/rxcommon.h linux/drivers/scsi/aacraid/include/rxcommon.h
11939--- linux-2.4.9/drivers/scsi/aacraid/include/rxcommon.h Wed Dec 31 18:00:00 1969
11940+++ linux/drivers/scsi/aacraid/include/rxcommon.h Thu Aug 16 13:41:30 2001
11941@@ -0,0 +1,105 @@
11942+/*++
11943+ * Adaptec aacraid device driver for Linux.
11944+ *
11945+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11946+ *
11947+ * This program is free software; you can redistribute it and/or modify
11948+ * it under the terms of the GNU General Public License as published by
11949+ * the Free Software Foundation; either version 2, or (at your option)
11950+ * any later version.
11951+ *
11952+ * This program is distributed in the hope that it will be useful,
11953+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11954+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11955+ * GNU General Public License for more details.
11956+ *
11957+ * You should have received a copy of the GNU General Public License
11958+ * along with this program; see the file COPYING. If not, write to
11959+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11960+ *
11961+ * Module Name:
11962+ * rxcommon.h
11963+ *
11964+ * Abstract: Structures and defines for the i960 Rx chip.
11965+ *
11966+ *
11967+ --*/
11968+
11969+#ifndef _Rx_COMMON_H_
11970+#define _Rx_COMMON_H_
11971+
11972+static char *ident_rxcommon = "aacraid_ident rxcommon.h 1.0.6 2000/10/09 Adaptec, Inc.";
11973+
11974+//
11975+// Rx Message Unit Registers
11976+//
11977+
11978+typedef volatile struct _StructRxMURegisters {
11979+ // Local | PCI* | Name
11980+ // | |
11981+ unsigned ARSR; // 1300h | 00h | APIC Register Select Register
11982+ unsigned reserved0; // 1304h | 04h | Reserved
11983+ unsigned AWR; // 1308h | 08h | APIC Window Register
11984+ unsigned reserved1; // 130Ch | 0Ch | Reserved
11985+ unsigned IMRx[2]; // 1310h | 10h | Inbound Message Registers
11986+ unsigned OMRx[2]; // 1318h | 18h | Outbound Message Registers
11987+ unsigned IDR; // 1320h | 20h | Inbound Doorbell Register
11988+ unsigned IISR; // 1324h | 24h | Inbound Interrupt Status Register
11989+ unsigned IIMR; // 1328h | 28h | Inbound Interrupt Mask Register
11990+ unsigned ODR; // 132Ch | 2Ch | Outbound Doorbell Register
11991+ unsigned OISR; // 1330h | 30h | Outbound Interrupt Status Register
11992+ unsigned OIMR; // 1334h | 34h | Outbound Interrupt Mask Register
11993+ // * Must access trhough ATU Inbound Translation Window
11994+
11995+}Rx_MU_CONFIG;
11996+typedef Rx_MU_CONFIG *PRx_MU_CONFIG;
11997+
11998+typedef volatile struct _Rx_Inbound {
11999+
12000+ unsigned Mailbox[8];
12001+
12002+}Rx_Inbound;
12003+
12004+typedef Rx_Inbound *PRx_Inbound;
12005+
12006+#define InboundMailbox0 IndexRegs.Mailbox[0]
12007+#define InboundMailbox1 IndexRegs.Mailbox[1]
12008+#define InboundMailbox2 IndexRegs.Mailbox[2]
12009+#define InboundMailbox3 IndexRegs.Mailbox[3]
12010+#define InboundMailbox4 IndexRegs.Mailbox[4]
12011+
12012+
12013+
12014+#define INBOUNDDOORBELL_0 0x00000001
12015+#define INBOUNDDOORBELL_1 0x00000002
12016+#define INBOUNDDOORBELL_2 0x00000004
12017+#define INBOUNDDOORBELL_3 0x00000008
12018+#define INBOUNDDOORBELL_4 0x00000010
12019+#define INBOUNDDOORBELL_5 0x00000020
12020+#define INBOUNDDOORBELL_6 0x00000040
12021+
12022+
12023+#define OUTBOUNDDOORBELL_0 0x00000001
12024+#define OUTBOUNDDOORBELL_1 0x00000002
12025+#define OUTBOUNDDOORBELL_2 0x00000004
12026+#define OUTBOUNDDOORBELL_3 0x00000008
12027+#define OUTBOUNDDOORBELL_4 0x00000010
12028+
12029+
12030+#define InboundDoorbellReg MUnit.IDR
12031+
12032+#define OutboundDoorbellReg MUnit.ODR
12033+
12034+
12035+typedef struct _Rx_DEVICE_REGISTERS {
12036+ Rx_MU_CONFIG MUnit; // 1300h - 1334h
12037+ unsigned reserved1[6]; // 1338h - 134ch
12038+ Rx_Inbound IndexRegs;
12039+} Rx_DEVICE_REGISTERS;
12040+
12041+typedef Rx_DEVICE_REGISTERS *PRx_DEVICE_REGISTERS;
12042+
12043+
12044+#endif // _Rx_COMMON_H_
12045+
12046+
12047diff -burN linux-2.4.9/drivers/scsi/aacraid/include/sap1.h linux/drivers/scsi/aacraid/include/sap1.h
12048--- linux-2.4.9/drivers/scsi/aacraid/include/sap1.h Wed Dec 31 18:00:00 1969
12049+++ linux/drivers/scsi/aacraid/include/sap1.h Thu Aug 16 13:41:30 2001
12050@@ -0,0 +1,85 @@
12051+/*++
12052+ * Adaptec aacraid device driver for Linux.
12053+ *
12054+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
12055+ *
12056+ * This program is free software; you can redistribute it and/or modify
12057+ * it under the terms of the GNU General Public License as published by
12058+ * the Free Software Foundation; either version 2, or (at your option)
12059+ * any later version.
12060+ *
12061+ * This program is distributed in the hope that it will be useful,
12062+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12063+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12064+ * GNU General Public License for more details.
12065+ *
12066+ * You should have received a copy of the GNU General Public License
12067+ * along with this program; see the file COPYING. If not, write to
12068+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
12069+ *
12070+ * Module Name:
12071+ * sap1.h
12072+ *
12073+ * Abstract: Prototypes and data structures unique to the Strong Arm based controller board.
12074+ *
12075+ *
12076+ --*/
12077+#ifndef _SAP1_H_
12078+#define _SAP1_H_
12079+
12080+static char *ident_sap1h = "aacraid_ident sap1.h 1.0.6 2000/10/09 Adaptec, Inc.";
12081+
12082+#define Sa_MINIPORT_REVISION 1
12083+
12084+typedef struct _Sa_ADAPTER_EXTENSION {
12085+
12086+ //
12087+ // The following must be first.
12088+ //
12089+ PPCI_MINIPORT_COMMON_EXTENSION Common;
12090+ struct _Sa_ADAPTER_EXTENSION *Next; // Next adapter miniport structure
12091+ USHORT LocalMaskInterruptControl;
12092+ PSa_DEVICE_REGISTERS Device;
12093+
12094+} Sa_ADAPTER_EXTENSION;
12095+
12096+typedef Sa_ADAPTER_EXTENSION *PSa_ADAPTER_EXTENSION;
12097+
12098+
12099+
12100+#ifdef LINUX
12101+/*
12102+ *
12103+ */
12104+
12105+
12106+#define Sa_READ_USHORT(AEP, CSR) *(volatile unsigned short *) &((AEP)->Device->CSR)
12107+#define Sa_READ_ULONG(AEP, CSR) *(volatile unsigned int *) &((AEP)->Device->CSR)
12108+
12109+
12110+#define Sa_WRITE_USHORT(AEP, CSR, Value) *(volatile unsigned short *) &((AEP)->Device->CSR) = (Value)
12111+#define Sa_WRITE_ULONG(AEP, CSR, Value) *(volatile unsigned int *) &((AEP)->Device->CSR) = (Value)
12112+
12113+#endif /* LINUX */
12114+
12115+
12116+VOID
12117+SaInterruptAdapter(
12118+ PVOID Arg1
12119+ );
12120+
12121+VOID
12122+SaNotifyAdapter(
12123+ PVOID Arg1,
12124+ IN HOST_2_ADAP_EVENT AdapterEvent
12125+ );
12126+
12127+VOID
12128+SaResetDevice(
12129+ PVOID Arg1
12130+ );
12131+
12132+
12133+#endif /* _SAP1_H_ */
12134+
12135+
12136diff -burN linux-2.4.9/drivers/scsi/aacraid/include/sap1common.h linux/drivers/scsi/aacraid/include/sap1common.h
12137--- linux-2.4.9/drivers/scsi/aacraid/include/sap1common.h Wed Dec 31 18:00:00 1969
12138+++ linux/drivers/scsi/aacraid/include/sap1common.h Thu Aug 16 13:41:30 2001
12139@@ -0,0 +1,111 @@
12140+/*++
12141+ * Adaptec aacraid device driver for Linux.
12142+ *
12143+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
12144+ *
12145+ * This program is free software; you can redistribute it and/or modify
12146+ * it under the terms of the GNU General Public License as published by
12147+ * the Free Software Foundation; either version 2, or (at your option)
12148+ * any later version.
12149+ *
12150+ * This program is distributed in the hope that it will be useful,
12151+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12152+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12153+ * GNU General Public License for more details.
12154+ *
12155+ * You should have received a copy of the GNU General Public License
12156+ * along with this program; see the file COPYING. If not, write to
12157+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
12158+ *
12159+ * Module Name:
12160+ * sap1common.h
12161+ *
12162+ * Abstract: Structures and defines for the Drawbridge and StrongArm110 chip.
12163+ *
12164+ --*/
12165+
12166+#ifndef _Sa_COMMON_H_
12167+#define _Sa_COMMON_H_
12168+
12169+static char *ident_sap1common = "aacraid_ident sap1common.h 1.0.6 2000/10/09 Adaptec, Inc.";
12170+
12171+//
12172+// SaP1 Message Unit Registers
12173+//
12174+
12175+typedef volatile struct _StructSaDrawbridge_CSR_RegisterMap {
12176+ // Offset | Name
12177+ unsigned reserved[10]; // 00h-27h | Reserved
12178+ unsigned char LUT_Offset; // 28h | Looup Table Offset
12179+ unsigned char reserved1[3]; // 29h-2bh | Reserved
12180+ unsigned LUT_Data; // 2ch | Looup Table Data
12181+ unsigned reserved2[26]; // 30h-97h | Reserved
12182+ unsigned short PRICLEARIRQ; // 98h | Primary Clear Irq
12183+ unsigned short SECCLEARIRQ; // 9ah | Secondary Clear Irq
12184+ unsigned short PRISETIRQ; // 9ch | Primary Set Irq
12185+ unsigned short SECSETIRQ; // 9eh | Secondary Set Irq
12186+ unsigned short PRICLEARIRQMASK; // a0h | Primary Clear Irq Mask
12187+ unsigned short SECCLEARIRQMASK; // a2h | Secondary Clear Irq Mask
12188+ unsigned short PRISETIRQMASK; // a4h | Primary Set Irq Mask
12189+ unsigned short SECSETIRQMASK; // a6h | Secondary Set Irq Mask
12190+ unsigned MAILBOX0; // a8h | Scratchpad 0
12191+ unsigned MAILBOX1; // ach | Scratchpad 1
12192+ unsigned MAILBOX2; // b0h | Scratchpad 2
12193+ unsigned MAILBOX3; // b4h | Scratchpad 3
12194+ unsigned MAILBOX4; // b8h | Scratchpad 4
12195+ unsigned MAILBOX5; // bch | Scratchpad 5
12196+ unsigned MAILBOX6; // c0h | Scratchpad 6
12197+ unsigned MAILBOX7; // c4h | Scratchpad 7
12198+
12199+ unsigned ROM_Setup_Data; // c8h | Rom Setup and Data
12200+ unsigned ROM_Control_Addr; // cch | Rom Control and Address
12201+
12202+ unsigned reserved3[12]; // d0h-ffh | reserved
12203+ unsigned LUT[64]; // 100h-1ffh| Lookup Table Entries
12204+
12205+ //
12206+ // TO DO
12207+ // need to add DMA, I2O, UART, etc registers form 80h to 364h
12208+ //
12209+
12210+}Sa_Drawbridge_CSR;
12211+
12212+typedef Sa_Drawbridge_CSR *PSa_Drawbridge_CSR;
12213+
12214+
12215+#define Mailbox0 SaDbCSR.MAILBOX0
12216+#define Mailbox1 SaDbCSR.MAILBOX1
12217+#define Mailbox2 SaDbCSR.MAILBOX2
12218+#define Mailbox3 SaDbCSR.MAILBOX3
12219+#define Mailbox4 SaDbCSR.MAILBOX4
12220+
12221+
12222+#define Mailbox7 SaDbCSR.MAILBOX7
12223+
12224+#define DoorbellReg_p SaDbCSR.PRISETIRQ
12225+#define DoorbellReg_s SaDbCSR.SECSETIRQ
12226+#define DoorbellClrReg_p SaDbCSR.PRICLEARIRQ
12227+
12228+
12229+#define DOORBELL_0 0x00000001
12230+#define DOORBELL_1 0x00000002
12231+#define DOORBELL_2 0x00000004
12232+#define DOORBELL_3 0x00000008
12233+#define DOORBELL_4 0x00000010
12234+#define DOORBELL_5 0x00000020
12235+#define DOORBELL_6 0x00000040
12236+
12237+
12238+#define PrintfReady DOORBELL_5
12239+#define PrintfDone DOORBELL_5
12240+
12241+typedef struct _Sa_DEVICE_REGISTERS {
12242+ Sa_Drawbridge_CSR SaDbCSR; // 98h - c4h
12243+} Sa_DEVICE_REGISTERS;
12244+
12245+typedef Sa_DEVICE_REGISTERS *PSa_DEVICE_REGISTERS;
12246+
12247+
12248+#endif // _Sa_COMMON_H_
12249+
12250+
12251diff -burN linux-2.4.9/drivers/scsi/aacraid/include/version.h linux/drivers/scsi/aacraid/include/version.h
12252--- linux-2.4.9/drivers/scsi/aacraid/include/version.h Wed Dec 31 18:00:00 1969
12253+++ linux/drivers/scsi/aacraid/include/version.h Thu Aug 16 18:16:55 2001
12254@@ -0,0 +1,40 @@
12255+/*++
12256+ * Adaptec aacraid device driver for Linux.
12257+ *
12258+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
12259+ *
12260+ * This program is free software; you can redistribute it and/or modify
12261+ * it under the terms of the GNU General Public License as published by
12262+ * the Free Software Foundation; either version 2, or (at your option)
12263+ * any later version.
12264+ *
12265+ * This program is distributed in the hope that it will be useful,
12266+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12267+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12268+ * GNU General Public License for more details.
12269+ *
12270+ * You should have received a copy of the GNU General Public License
12271+ * along with this program; see the file COPYING. If not, write to
12272+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
12273+ *
12274+ * Module Name:
12275+ * version.h
12276+ *
12277+ * Abstract: Keeps track of build number for development purposes.
12278+ *
12279+ --*/
12280+#ifndef _VERSION_H_
12281+#define _VERSION_H_
12282+
12283+static char *ident_version = "aacraid_ident version.h 1.0.7 2000/8/10 Adaptec, Inc.";
12284+
12285+#include "build_number.h"
12286+
12287+#define REV_MAJOR 3
12288+#define REV_MINOR 0
12289+#define REV_TYPE RevType_Release
12290+#define REV_DASH 0
12291+
12292+#define FSA_VERSION_STRING "3.0.0.5125\0"
12293+
12294+#endif /* _VERSION_H_ */
12295diff -burN linux-2.4.9/drivers/scsi/aacraid/linit.c linux/drivers/scsi/aacraid/linit.c
12296--- linux-2.4.9/drivers/scsi/aacraid/linit.c Wed Dec 31 18:00:00 1969
12297+++ linux/drivers/scsi/aacraid/linit.c Thu Aug 16 13:41:30 2001
12298@@ -0,0 +1,1086 @@
12299+/*++
12300+ * Adaptec aacraid device driver for Linux.
12301+ *
12302+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
12303+ *
12304+ * This program is free software; you can redistribute it and/or modify
12305+ * it under the terms of the GNU General Public License as published by
12306+ * the Free Software Foundation; either version 2, or (at your option)
12307+ * any later version.
12308+ *
12309+ * This program is distributed in the hope that it will be useful,
12310+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12311+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12312+ * GNU General Public License for more details.
12313+ *
12314+ * You should have received a copy of the GNU General Public License
12315+ * along with this program; see the file COPYING. If not, write to
12316+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
12317+ *
12318+ * Module Name:
12319+ * linit.c
12320+ *
12321+ * Abstract: Linux Driver entry module for Adaptec RAID Array Controller
12322+ *
12323+ * Provides the following driver entry points:
12324+ * AAC_DetectHostAdapter()
12325+ * AAC_ReleaseHostAdapter()
12326+ * AAC_QueueCommand()
12327+ * AAC_ResetCommand()
12328+ * AAC_BIOSDiskParameters()
12329+ *
12330+ --*/
12331+
12332+static char *ident_linit = "aacraid_ident linit.c 1.0.6 2000/10/09 Adaptec, Inc.";
12333+
12334+/*------------------------------------------------------------------------------
12335+ * D E F I N E S
12336+ *----------------------------------------------------------------------------*/
12337+#define AAC_DRIVER_VERSION "0.1.1"
12338+#define AAC_DRIVER_BUILD_DATE __DATE__
12339+#define MAX_DRIVER_QUEUE_DEPTH 500
12340+
12341+/*------------------------------------------------------------------------------
12342+ * I N C L U D E S
12343+ *----------------------------------------------------------------------------*/
12344+#include "osheaders.h"
12345+
12346+#include "AacGenericTypes.h"
12347+
12348+#include <linux/module.h>
12349+#include "sd.h"
12350+#include "linit.h"
12351+#include "aac_unix_defs.h"
12352+#include "fsatypes.h"
12353+#include "comstruc.h"
12354+#include "fsaport.h"
12355+#include "pcisup.h"
12356+#include "port.h"
12357+#include "afacomm.h"
12358+#include "nodetype.h"
12359+#include "comsup.h"
12360+#include "adapter.h"
12361+
12362+/*------------------------------------------------------------------------------
12363+ * G L O B A L S
12364+ *----------------------------------------------------------------------------*/
12365+extern FSA_MINIPORT MiniPorts[];
12366+extern int CommPrinting;
12367+extern char DescriptionString[];
12368+extern char devicestr[];
12369+
12370+/*------------------------------------------------------------------------------
12371+ * M O D U L E G L O B A L S
12372+ *----------------------------------------------------------------------------*/
12373+aac_options_t g_options = { CMN_ERR_LEVEL, 0 }; // default message_level
12374+
12375+char g_DriverName[] = { "aacraid" };
12376+
12377+/*
12378+ The Loadable Kernel Module Installation Facility may pass us
12379+ a pointer to a driver specific options string to be parsed,
12380+ we assign this to options string.
12381+*/
12382+
12383+static char * aacraid_options = NULL;
12384+MODULE_PARM ( aacraid_options, "s" );
12385+MODULE_PARM_DESC ( aacraid_options, "message_level:(int) reverse_scan:1 (default 0)");
12386+
12387+
12388+static unsigned short perc_pciid[4] = { 0, 0, 0, 0 };
12389+MODULE_PARM ( perc_pciid, "4h");
12390+MODULE_PARM_DESC ( perc_pciid, "PCI vendor,device,subsystem vendor,subsystem device, for non-auto-recognized Dell PERC controllers.");
12391+
12392+static unsigned short rx_pciid[4] = { 0, 0, 0, 0 };
12393+MODULE_PARM ( rx_pciid, "4h");
12394+MODULE_PARM_DESC ( rx_pciid, "PCI vendor,device,subsystem vendor,subsystem device, for non-auto-recognized Adaptec Rx controllers.");
12395+
12396+static unsigned short sa_pciid[4] = { 0, 0, 0, 0 };
12397+MODULE_PARM ( sa_pciid, "4h");
12398+MODULE_PARM_DESC ( sa_pciid, "PCI vendor,device,subsystem vendor,subsystem device, for non-auto-recognized Adaptec Sa controllers.");
12399+
12400+MODULE_AUTHOR ("Adaptec OEM RAID Solutions");
12401+
12402+
12403+
12404+PCI_MINIPORT_COMMON_EXTENSION *g_CommonExtensionPtrArray[ MAXIMUM_NUM_ADAPTERS ];
12405+unsigned g_HostAdapterCount = 0;
12406+unsigned g_chardev_major = 0;
12407+
12408+int g_single_command_done = FALSE;
12409+
12410+/*------------------------------------------------------------------------------
12411+ * F U N C T I O N P R O T O T Y P E S
12412+ *----------------------------------------------------------------------------*/
12413+int AacHba_Ioctl(
12414+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtension,
12415+ int cmd,
12416+ void * arg );
12417+
12418+int AacHba_ProbeContainers(
12419+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr );
12420+
12421+int AacHba_DoScsiCmd(
12422+ Scsi_Cmnd *scsi_cmnd_ptr,
12423+ int wait );
12424+
12425+void AacHba_DetachAdapter(
12426+ IN PVOID AdapterArg );
12427+
12428+int AacHba_ClassDriverInit(
12429+ PCI_MINIPORT_COMMON_EXTENSION * CommonExtensionPtr);
12430+
12431+void AacHba_AbortScsiCommand(
12432+ Scsi_Cmnd *scsi_cmnd_ptr );
12433+
12434+
12435+/*------------------------------------------------------------------------------
12436+ * L O C A L F U N C T I O N P R O T O T Y P E S
12437+ *----------------------------------------------------------------------------*/
12438+static int parse_keyword(
12439+ char ** str_ptr,
12440+ char * keyword );
12441+
12442+static void AAC_ParseDriverOptions(
12443+ char * cmnd_line_options_str );
12444+
12445+static void AAC_AnnounceDriver( void );
12446+
12447+int AAC_ChardevIoctl(
12448+ struct inode * inode_ptr,
12449+ struct file * file_ptr,
12450+ unsigned int cmd,
12451+ unsigned long arg );
12452+
12453+int AAC_ChardevOpen(
12454+ struct inode * inode_ptr,
12455+ struct file * file_ptr );
12456+
12457+int AAC_ChardevRelease(
12458+ struct inode * inode_ptr,
12459+ struct file * file_ptr );
12460+
12461+struct file_operations AAC_fops = {
12462+ NULL, // module name
12463+ NULL, // lseek
12464+ NULL, // read
12465+ NULL, // write
12466+ NULL, // readdir
12467+ NULL, // poll
12468+ AAC_ChardevIoctl, // ioctl
12469+ NULL, // mmap
12470+ AAC_ChardevOpen, // open
12471+ NULL, // flush
12472+ AAC_ChardevRelease, // release
12473+ NULL, // fsync
12474+ NULL, // fasync
12475+ NULL, // check media change
12476+ NULL, // revalidate
12477+ NULL // lock
12478+};
12479+
12480+/*------------------------------------------------------------------------------
12481+ * F U N C T I O N S
12482+ *----------------------------------------------------------------------------*/
12483+/*------------------------------------------------------------------------------
12484+ AAC_AnnounceDriver()
12485+
12486+ Announce the driver name, version and date.
12487+ *----------------------------------------------------------------------------*/
12488+static void AAC_AnnounceDriver( void ){
12489+ printk(KERN_ALERT "%s, %s\n",
12490+ "aacraid raid driver version", AAC_DRIVER_BUILD_DATE );
12491+ schedule();
12492+}
12493+
12494+
12495+/*------------------------------------------------------------------------------
12496+ AAC_DetectHostAdapter()
12497+
12498+ Probe for AAC Host Adapters initialize, register, and report the
12499+ configuration of each AAC Host Adapter found.
12500+
12501+ Preconditions:
12502+ Postconditions:
12503+ - Returns the number of adapters successfully initialized and
12504+ registered.
12505+ - Initialize all data necessary for this particular SCSI driver.
12506+ Notes:
12507+ The detect routine must not call any of the mid level functions
12508+ to queue commands because things are not guaranteed to be set
12509+ up yet. The detect routine can send commands to the host adapter
12510+ as long as the program control will not be passed to scsi.c in
12511+ the processing of the command. Note especially that
12512+ scsi_malloc/scsi_free must not be called.
12513+ *----------------------------------------------------------------------------*/
12514+int AAC_DetectHostAdapter (Scsi_Host_Template *HostTemplate)
12515+{
12516+ int index;
12517+ int ContainerId;
12518+ uint16_t vendor_id, device_id, sub_vendor_id, sub_system_id;
12519+ struct Scsi_Host *host_ptr;
12520+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
12521+ struct pci_dev *dev = NULL;
12522+ extern int NumMiniPorts;
12523+ fsadev_t *fsa_dev_ptr;
12524+ char *DeviceName;
12525+
12526+ struct pci_dev *devp;
12527+
12528+ int first_index, last_index, increment;
12529+
12530+ CommPrinting = TRUE;
12531+
12532+ EXPORT_NO_SYMBOLS;
12533+
12534+ AAC_AnnounceDriver();
12535+
12536+ /* setting up the proc directory structure */
12537+ HostTemplate->proc_name = "aacraid";
12538+
12539+ if( aacraid_options != NULL ) AAC_ParseDriverOptions( aacraid_options );
12540+
12541+ /* If we were passed a PCI device ID, handle that first. */
12542+ if ( perc_pciid[0] != 0 ) {
12543+ MiniPorts[0].VendorId = perc_pciid[0];
12544+ MiniPorts[0].DeviceId = perc_pciid[1];
12545+ MiniPorts[0].SubVendorId = perc_pciid[2];
12546+ MiniPorts[0].SubSystemId = perc_pciid[3];
12547+ }
12548+ if ( rx_pciid[0] != 0 ) {
12549+ MiniPorts[1].VendorId = rx_pciid[0];
12550+ MiniPorts[1].DeviceId = rx_pciid[1];
12551+ MiniPorts[1].SubVendorId = rx_pciid[2];
12552+ MiniPorts[1].SubSystemId = rx_pciid[3];
12553+ }
12554+ if ( sa_pciid[0] != 0 ) {
12555+ MiniPorts[2].VendorId = sa_pciid[0];
12556+ MiniPorts[2].DeviceId = sa_pciid[1];
12557+ MiniPorts[2].SubVendorId = sa_pciid[2];
12558+ MiniPorts[2].SubSystemId = sa_pciid[3];
12559+ }
12560+
12561+ // NumMiniPorts & MiniPorts[] defined in aacid.c
12562+ if (g_options.reverse_scan == 0) {
12563+ first_index = 0;
12564+ last_index = NumMiniPorts;
12565+ increment = 1;
12566+ } else {
12567+ first_index = NumMiniPorts -1;
12568+ last_index = -1;
12569+ increment = -1;
12570+ }
12571+
12572+ for( index = first_index; index != last_index; index += increment )
12573+ {
12574+ device_id = MiniPorts[index].DeviceId;
12575+ vendor_id = MiniPorts[index].VendorId;
12576+ DeviceName = MiniPorts[index].DeviceName;
12577+ cmn_err(CE_DEBUG, "Checking %s %x/%x/%x/%x",
12578+ DeviceName, vendor_id, device_id,
12579+ MiniPorts[index].SubVendorId,
12580+ MiniPorts[index].SubSystemId);
12581+
12582+ /* If vendor and device ID are 0, this is an unused entry, so skip! */
12583+ if ( vendor_id == 0 && device_id == 0 ) continue;
12584+
12585+ // pci_find_device traverses the pci_devices linked list for devices
12586+ // with matching vendor and device ids.
12587+
12588+ dev = NULL; // start from beginning of list
12589+ while( ( dev = pci_find_device( vendor_id, device_id, dev ) ) )
12590+ {
12591+ if (pci_enable_device(dev)) continue;
12592+
12593+ if( pci_read_config_word( dev, PCI_SUBSYSTEM_VENDOR_ID, &sub_vendor_id ) ){
12594+ cmn_err(CE_WARN, "pci_read_config_word SUBSYS_VENDOR_ID failed");
12595+ break;
12596+ }
12597+ if( pci_read_config_word( dev, PCI_SUBSYSTEM_ID, &sub_system_id ) ){
12598+ cmn_err(CE_WARN, "pci_read_config_work SUBSYSTEM_ID failed");
12599+ break;
12600+ }
12601+
12602+ cmn_err(CE_DEBUG, " found: %x/%x/%x/%x", vendor_id, device_id, sub_vendor_id, sub_system_id);
12603+ if( ( sub_vendor_id != MiniPorts[index].SubVendorId ) ||
12604+ ( sub_system_id != MiniPorts[index].SubSystemId ) ){
12605+ continue;
12606+ }
12607+
12608+
12609+ printk(KERN_ALERT "%s device detected\n", DeviceName );
12610+ cmn_err(CE_DEBUG, "%x/%x/%x/%x", vendor_id, device_id, sub_vendor_id, sub_system_id);
12611+
12612+ // Increment the host adapter count
12613+ g_HostAdapterCount++;
12614+
12615+ // scsi_register() allocates memory for a Scsi_Hosts structure and
12616+ // links it into the linked list of host adapters. This linked list
12617+ // contains the data for all possible <supported> scsi hosts.
12618+ // This is similar to the Scsi_Host_Template, except that we have
12619+ // one entry for each actual physical host adapter on the system,
12620+ // stored as a linked list. If there are two AAC boards, then we
12621+ // will need to make two Scsi_Host entries, but there will be only
12622+ // one Scsi_Host_Template entry. The second argument to scsi_register()
12623+ // specifies the size of the extra memory we want to hold any device
12624+ // specific information.
12625+ host_ptr = scsi_register( HostTemplate, sizeof( PCI_MINIPORT_COMMON_EXTENSION ) );
12626+
12627+ // These three parameters can be used to allow for wide SCSI
12628+ // and for host adapters that support multiple buses.
12629+ host_ptr->max_id = 17;
12630+ host_ptr->max_lun = 8;
12631+ host_ptr->max_channel = 1;
12632+
12633+
12634+ host_ptr->irq = dev->irq; // Adapter IRQ number
12635+ /* host_ptr->base = ( char * )(dev->resource[0].start & ~0xff); */
12636+ host_ptr->base = ( char * )(dev->resource[0].start);
12637+ scsi_set_pci_device(host_ptr, dev);
12638+
12639+ cmn_err( CE_DEBUG, "Device base address = 0x%lx [0x%lx]", host_ptr->base, dev->resource[0].start );
12640+ cmn_err( CE_DEBUG, "Device irq = 0x%lx", dev->irq );
12641+
12642+ // The unique_id field is a unique identifier that must be assigned
12643+ // so that we have some way of identifying each host adapter properly
12644+ // and uniquely. For hosts that do not support more than one card in the
12645+ // system, this does not need to be set. It is initialized to zero in
12646+ // scsi_register(). This is the value returned from OsGetDeviceInstance().
12647+
12648+ host_ptr->unique_id = g_HostAdapterCount - 1;
12649+ host_ptr->this_id = 16; // SCSI Id for the adapter itself
12650+
12651+ // Set the maximum number of simultaneous commands supported by the driver.
12652+ host_ptr->can_queue = MAX_DRIVER_QUEUE_DEPTH;
12653+
12654+ // Define the maximum number of scatter/gather elements supported by
12655+ // the driver.
12656+
12657+ host_ptr->sg_tablesize = 16;
12658+ host_ptr->max_sectors = 128;
12659+ host_ptr->cmd_per_lun = 1; // untagged queue depth
12660+
12661+ // This function is called after the device list has been built to find
12662+ // tagged queueing depth supported for each device.
12663+
12664+ host_ptr->select_queue_depths = AAC_SelectQueueDepths;
12665+ CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )host_ptr->hostdata;
12666+
12667+ // attach a pointer back to Scsi_Host
12668+ CommonExtensionPtr->OsDep.scsi_host_ptr = host_ptr;
12669+ CommonExtensionPtr->OsDep.MiniPortIndex = index;
12670+
12671+ // Initialize the ordinal number of the device to -1
12672+ fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
12673+ for( ContainerId = 0; ContainerId < MAXIMUM_NUM_CONTAINERS; ContainerId++ )
12674+ fsa_dev_ptr->ContainerDevNo[ContainerId] = -1;
12675+
12676+ // Call initialization routine
12677+ cmn_err (CE_DEBUG, "Initializing Hardware...\n");
12678+ if( ( *MiniPorts[index].InitRoutine )
12679+ ( CommonExtensionPtr, host_ptr->unique_id, dev->bus->number, 0 ) != 0 )
12680+ {
12681+ // device initialization failed
12682+ cmn_err( CE_WARN, "%s:%d device initialization failed", DeviceName, host_ptr->unique_id );
12683+ scsi_unregister( host_ptr );
12684+ g_HostAdapterCount--;
12685+ } /* end if */
12686+ else
12687+ {
12688+ cmn_err( CE_NOTE, "%s:%d device initialization successful", DeviceName, host_ptr->unique_id );
12689+ AacHba_ClassDriverInit( CommonExtensionPtr );
12690+ cmn_err(CE_NOTE, "%s:%d AacHba_ClassDriverInit complete", DeviceName, host_ptr->unique_id);
12691+ AacHba_ProbeContainers( CommonExtensionPtr );
12692+ g_CommonExtensionPtrArray[ g_HostAdapterCount - 1 ] = CommonExtensionPtr;
12693+
12694+ } /* end else */
12695+
12696+ } /* end while */
12697+
12698+ } /* end for */
12699+
12700+ if( g_HostAdapterCount ){
12701+ if( !( g_chardev_major = register_chrdev( 0, devicestr, &AAC_fops ) ) )
12702+ cmn_err( CE_WARN, "%s: unable to register %s device", DeviceName, devicestr);
12703+ }
12704+
12705+ HostTemplate->present = g_HostAdapterCount; // # of cards of this type found
12706+
12707+ return( g_HostAdapterCount );
12708+}
12709+
12710+
12711+/*------------------------------------------------------------------------------
12712+ AAC_ReleaseHostAdapter()
12713+
12714+ Release all resources previously acquired to support a specific Host
12715+ Adapter and unregister the AAC Host Adapter.
12716+ *----------------------------------------------------------------------------*/
12717+int AAC_ReleaseHostAdapter(
12718+ struct Scsi_Host *host_ptr )
12719+/*----------------------------------------------------------------------------*/
12720+{
12721+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
12722+
12723+ cmn_err( CE_DEBUG, "AAC_ReleaseHostAdapter" );
12724+
12725+ CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )host_ptr->hostdata;
12726+
12727+ // kill any threads we started
12728+ kill_proc( CommonExtensionPtr->OsDep.thread_pid, SIGKILL, 0 );
12729+
12730+ // Call the comm layer to detach from this adapter
12731+ AacHba_DetachAdapter( CommonExtensionPtr->Adapter );
12732+
12733+ // remove interrupt binding
12734+ OsDetachInterrupt( CommonExtensionPtr->MiniPort );
12735+
12736+ SaDetachDevice( CommonExtensionPtr );
12737+
12738+ // unregister adapter
12739+ scsi_unregister( host_ptr );
12740+
12741+ if( g_chardev_major )
12742+ {
12743+ unregister_chrdev( g_chardev_major, devicestr );
12744+ g_chardev_major = 0;
12745+ }
12746+
12747+ return( 0 ); // #REVISIT# return code
12748+}
12749+
12750+
12751+/*------------------------------------------------------------------------------
12752+ AAC_QueueCommand()
12753+
12754+ Queues a command for execution by the associated Host Adapter.
12755+ *----------------------------------------------------------------------------*/
12756+int AAC_QueueCommand(
12757+ Scsi_Cmnd *scsi_cmnd_ptr,
12758+ void ( *CompletionRoutine )( Scsi_Cmnd * ) )
12759+/*----------------------------------------------------------------------------*/
12760+{
12761+ int ret;
12762+ scsi_cmnd_ptr->scsi_done = CompletionRoutine;
12763+
12764+ // AacHba_DoScsiCmd() handles command processing, setting the
12765+ // result code and calling completion routine.
12766+ #ifdef SYNC_FIB
12767+ if( (ret = AacHba_DoScsiCmd( scsi_cmnd_ptr, 1 )) != 0 ) // call with wait = TRUE
12768+ #else
12769+ if( (ret = AacHba_DoScsiCmd( scsi_cmnd_ptr, 0 )) != 0 ) // call with wait = FALSE
12770+ #endif
12771+ cmn_err( CE_DEBUG, "AacHba_DoScsiCmd failed" );
12772+ return ret;
12773+}
12774+
12775+
12776+/*------------------------------------------------------------------------------
12777+ AAC_Done()
12778+
12779+ Callback function for a non-queued command.
12780+
12781+ Postconditions
12782+ Sets g_single_command done to TRUE
12783+ *----------------------------------------------------------------------------*/
12784+void AAC_Done(
12785+ Scsi_Cmnd * scsi_cmnd_ptr )
12786+/*----------------------------------------------------------------------------*/
12787+{
12788+ g_single_command_done = TRUE;
12789+}
12790+
12791+
12792+/*------------------------------------------------------------------------------
12793+ AAC_Command()
12794+
12795+ Accepts a single command for execution by the associated Host Adapter.
12796+
12797+ Postconditions
12798+ Returns an int where:
12799+ Byte 0 = SCSI status code
12800+ Byte 1 = SCSI 1 byte message
12801+ Byte 2 = host error return
12802+ Byte 3 = mid level error return
12803+ *----------------------------------------------------------------------------*/
12804+int AAC_Command(
12805+ Scsi_Cmnd *scsi_cmnd_ptr )
12806+/*----------------------------------------------------------------------------*/
12807+{
12808+ scsi_cmnd_ptr->scsi_done = AAC_Done;
12809+
12810+ cmn_err( CE_DEBUG, "AAC_Command" );
12811+
12812+ // AacHba_DoScsiCmd() handles command processing, setting the
12813+ // result code and calling completion routine.
12814+ g_single_command_done = FALSE;
12815+
12816+ AacHba_DoScsiCmd( scsi_cmnd_ptr, 0 );
12817+ while( !g_single_command_done );
12818+ return( scsi_cmnd_ptr->result );
12819+}
12820+
12821+
12822+/*------------------------------------------------------------------------------
12823+ AAC_AbortCommand()
12824+
12825+ Abort command if possible.
12826+ *----------------------------------------------------------------------------*/
12827+int AAC_AbortCommand(
12828+ Scsi_Cmnd *scsi_cmnd_ptr )
12829+/*----------------------------------------------------------------------------*/
12830+{
12831+ int target = scsi_cmnd_ptr->target;
12832+ int hba = scsi_cmnd_ptr->host->unique_id;
12833+ int result = 0;
12834+ u_short interrupt_status;
12835+ PCI_MINIPORT_COMMON_EXTENSION *cep;
12836+ char *DeviceName;
12837+
12838+ cmn_err( CE_WARN, "%s:%d ABORT", g_DriverName, hba, target );
12839+ AacHba_AbortScsiCommand( scsi_cmnd_ptr );
12840+
12841+ cep = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
12842+ DeviceName = MiniPorts[cep->OsDep.MiniPortIndex].DeviceName;
12843+
12844+ /*
12845+ cmn_err( CE_WARN, "%s:%d Unable to abort command to target %d - "
12846+ "command already completed", DeviceName, hba, target);
12847+ result = SCSI_ABORT_NOT_RUNNING;
12848+
12849+ cmn_err(CE_WARN, "%s:%d Unable to abort command to target %d - "
12850+ "no command found\n", DeviceName, hba, target);
12851+ result = SCSI_ABORT_NOT_RUNNING;
12852+
12853+ cmn_err(CE_WARN, "%s:%d Unable to abort command to target %d - "
12854+ "command reset\n", DeviceName, hba, target);
12855+ result = SCSI_ABORT_PENDING;
12856+
12857+ cmn_err(CE_WARN, "%s:%d Unable to abort command to target %d - "
12858+ "abort tag not supported\n", DeviceName, hba, target);
12859+ result = SCSI_ABORT_SNOOZE;
12860+
12861+ cmn_err(CE_WARN, "%s:%d Aborting command to target %d - pending",
12862+ DeviceName, hba, target);
12863+ result = SCSI_ABORT_PENDING;
12864+
12865+ cmn_err(CE_WARN, "%s:%d Unable to abort command to target %d",
12866+ DeviceName, hba, target);
12867+ result = SCSI_ABORT_BUSY;
12868+
12869+ cmn_err(CE_WARN, "%s:%d Aborted command to target %d\n",
12870+ DeviceName, hba, target);
12871+ result = SCSI_ABORT_SUCCESS;
12872+ */
12873+
12874+ // Abort not supported yet
12875+ result = SCSI_ABORT_BUSY;
12876+ return result;
12877+}
12878+
12879+
12880+/*------------------------------------------------------------------------------
12881+ AAC_ResetCommand()
12882+
12883+ Reset command handling.
12884+ *----------------------------------------------------------------------------*/
12885+int AAC_ResetCommand(
12886+ struct scsi_cmnd *scsi_cmnd_ptr,
12887+ unsigned int reset_flags )
12888+/*----------------------------------------------------------------------------*/
12889+{
12890+ int target = scsi_cmnd_ptr->target;
12891+ int hba = scsi_cmnd_ptr->host->unique_id;
12892+ PCI_MINIPORT_COMMON_EXTENSION *cep;
12893+ char *DeviceName;
12894+
12895+ cep = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
12896+ DeviceName = MiniPorts[cep->OsDep.MiniPortIndex].DeviceName;
12897+
12898+ cmn_err( CE_WARN, "%s:%d RESET", DeviceName, hba, target );
12899+
12900+ return SCSI_RESET_PUNT;
12901+}
12902+
12903+
12904+/*------------------------------------------------------------------------------
12905+ AAC_DriverInfo()
12906+
12907+ Returns the host adapter name
12908+ *----------------------------------------------------------------------------*/
12909+const char *AAC_DriverInfo(
12910+ struct Scsi_Host *host_ptr )
12911+/*----------------------------------------------------------------------------*/
12912+{
12913+ PCI_MINIPORT_COMMON_EXTENSION *cep;
12914+ char *DeviceName;
12915+
12916+ cep = ( PCI_MINIPORT_COMMON_EXTENSION * )( host_ptr->hostdata );
12917+ DeviceName = MiniPorts[cep->OsDep.MiniPortIndex].DeviceName;
12918+
12919+ cmn_err( CE_DEBUG, "AAC_DriverInfo" );
12920+ return (DeviceName);
12921+}
12922+
12923+
12924+/*------------------------------------------------------------------------------
12925+ AAC_BIOSDiskParameters()
12926+
12927+ Return the Heads/Sectors/Cylinders BIOS Disk Parameters for Disk.
12928+ The default disk geometry is 64 heads, 32 sectors, and the appropriate
12929+ number of cylinders so as not to exceed drive capacity. In order for
12930+ disks equal to or larger than 1 GB to be addressable by the BIOS
12931+ without exceeding the BIOS limitation of 1024 cylinders, Extended
12932+ Translation should be enabled. With Extended Translation enabled,
12933+ drives between 1 GB inclusive and 2 GB exclusive are given a disk
12934+ geometry of 128 heads and 32 sectors, and drives above 2 GB inclusive
12935+ are given a disk geometry of 255 heads and 63 sectors. However, if
12936+ the BIOS detects that the Extended Translation setting does not match
12937+ the geometry in the partition table, then the translation inferred
12938+ from the partition table will be used by the BIOS, and a warning may
12939+ be displayed.
12940+ *----------------------------------------------------------------------------*/
12941+int AAC_BIOSDiskParameters(
12942+ Scsi_Disk *scsi_disk_ptr,
12943+ kdev_t device,
12944+ int *parameter_ptr )
12945+/*----------------------------------------------------------------------------*/
12946+{
12947+ AAC_BIOS_DiskParameters_T *disk_parameters =
12948+ ( AAC_BIOS_DiskParameters_T *)parameter_ptr;
12949+ struct buffer_head * buffer_head_ptr;
12950+
12951+ cmn_err( CE_DEBUG, "AAC_BIOSDiskParameters" );
12952+
12953+ // Assuming extended translation is enabled - #REVISIT#
12954+ if( scsi_disk_ptr->capacity >= 2 * 1024 * 1024 ) // 1 GB in 512 byte sectors
12955+ {
12956+ if( scsi_disk_ptr->capacity >= 4 * 1024 * 1024 ) // 2 GB in 512 byte sectors
12957+ {
12958+ disk_parameters->heads = 255;
12959+ disk_parameters->sectors = 63;
12960+ }
12961+ else
12962+ {
12963+ disk_parameters->heads = 128;
12964+ disk_parameters->sectors = 32;
12965+ }
12966+ }
12967+ else
12968+ {
12969+ disk_parameters->heads = 64;
12970+ disk_parameters->sectors = 32;
12971+ }
12972+
12973+ disk_parameters->cylinders = scsi_disk_ptr->capacity
12974+ /( disk_parameters->heads * disk_parameters->sectors );
12975+
12976+ // Read the first 1024 bytes from the disk device
12977+ buffer_head_ptr = bread(
12978+ MKDEV( MAJOR( device ),
12979+ MINOR( device ) & ~0x0F ),
12980+ 0, 1024 );
12981+
12982+ if( buffer_head_ptr == NULL )
12983+ return( 0 );
12984+ /*
12985+ If the boot sector partition table is valid, search for a partition
12986+ table entry whose end_head matches one of the standard geometry
12987+ translations ( 64/32, 128/32, 255/63 ).
12988+ */
12989+ if( *( unsigned short * )( buffer_head_ptr->b_data + 0x1fe ) == 0xaa55 )
12990+ {
12991+ struct partition *first_partition_entry =
12992+ ( struct partition * )( buffer_head_ptr->b_data + 0x1be );
12993+ struct partition *partition_entry = first_partition_entry;
12994+ int saved_cylinders = disk_parameters->cylinders;
12995+ int partition_number;
12996+ unsigned char partition_entry_end_head, partition_entry_end_sector;
12997+
12998+ for( partition_number = 0; partition_number < 4; partition_number++ )
12999+ {
13000+ partition_entry_end_head = partition_entry->end_head;
13001+ partition_entry_end_sector = partition_entry->end_sector & 0x3f;
13002+
13003+ if( partition_entry_end_head == ( 64 - 1 ) )
13004+ {
13005+ disk_parameters->heads = 64;
13006+ disk_parameters->sectors = 32;
13007+ break;
13008+ }
13009+ else if( partition_entry_end_head == ( 128 - 1 ) )
13010+ {
13011+ disk_parameters->heads = 128;
13012+ disk_parameters->sectors = 32;
13013+ break;
13014+ }
13015+ else if( partition_entry_end_head == ( 255 - 1 ) )
13016+ {
13017+ disk_parameters->heads = 255;
13018+ disk_parameters->sectors = 63;
13019+ break;
13020+ }
13021+ partition_entry++;
13022+ }
13023+
13024+ if( partition_number == 4 )
13025+ {
13026+ partition_entry_end_head = first_partition_entry->end_head;
13027+ partition_entry_end_sector = first_partition_entry->end_sector & 0x3f;
13028+ }
13029+
13030+ disk_parameters->cylinders = scsi_disk_ptr->capacity
13031+ /( disk_parameters->heads * disk_parameters->sectors );
13032+
13033+ if( ( partition_number < 4 ) && ( partition_entry_end_sector == disk_parameters->sectors ) )
13034+ {
13035+ if( disk_parameters->cylinders != saved_cylinders )
13036+ cmn_err( CE_DEBUG, "Adopting geometry: heads=%d, sectors=%d from partition table %d",
13037+ disk_parameters->heads, disk_parameters->sectors, partition_number );
13038+ }
13039+ else if( ( partition_entry_end_head > 0 ) || ( partition_entry_end_sector > 0 ) )
13040+ {
13041+ cmn_err( CE_DEBUG, "Strange geometry: heads=%d, sectors=%d in partition table %d",
13042+ partition_entry_end_head + 1, partition_entry_end_sector, partition_number );
13043+ cmn_err( CE_DEBUG, "Using geometry: heads=%d, sectors=%d",
13044+ disk_parameters->heads, disk_parameters->sectors );
13045+ }
13046+ }
13047+
13048+ brelse( buffer_head_ptr );
13049+
13050+ return( 0 );
13051+}
13052+
13053+
13054+/*------------------------------------------------------------------------------
13055+ AAC_SelectQueueDepths()
13056+
13057+ Selects queue depths for each target device based on the host adapter's
13058+ total capacity and the queue depth supported by the target device.
13059+ A queue depth of one automatically disables tagged queueing.
13060+ *----------------------------------------------------------------------------*/
13061+void AAC_SelectQueueDepths(
13062+ struct Scsi_Host * host_ptr,
13063+ Scsi_Device * scsi_device_ptr )
13064+/*----------------------------------------------------------------------------*/
13065+{
13066+ Scsi_Device * device_ptr;
13067+
13068+ cmn_err( CE_DEBUG, "AAC_SelectQueueDepths" );
13069+ cmn_err( CE_DEBUG, "Device # Q Depth Online" );
13070+ cmn_err( CE_DEBUG, "---------------------------" );
13071+ for( device_ptr = scsi_device_ptr; device_ptr != NULL; device_ptr = device_ptr->next )
13072+ if( device_ptr->host == host_ptr )
13073+ {
13074+ device_ptr->queue_depth = 10;
13075+ cmn_err( CE_DEBUG, " %2d %d %d",
13076+ device_ptr->id, device_ptr->queue_depth, device_ptr->online );
13077+ }
13078+}
13079+
13080+
13081+/*------------------------------------------------------------------------------
13082+ AAC_SearchBiosSignature()
13083+
13084+ Locate adapter signature in BIOS
13085+ *----------------------------------------------------------------------------*/
13086+int AAC_SearchBiosSignature( void )
13087+/*----------------------------------------------------------------------------*/
13088+{
13089+ unsigned base;
13090+ unsigned namep;
13091+ int index;
13092+ int val;
13093+ char name_buf[32];
13094+ int result = FALSE;
13095+
13096+ for( base = 0xc8000; base < 0xdffff; base += 0x4000 )
13097+ {
13098+ val = readb( base );
13099+ if( val != 0x55 )
13100+ continue;
13101+
13102+ result = TRUE;
13103+ namep = base + 0x1e;
13104+ memcpy_fromio( name_buf, namep, 32 );
13105+ name_buf[31] = '\0';
13106+ }
13107+ return( result );
13108+}
13109+
13110+
13111+/*------------------------------------------------------------------------------
13112+ AAC_Ioctl()
13113+
13114+ Handle SCSI ioctls
13115+ *----------------------------------------------------------------------------*/
13116+int AAC_Ioctl(
13117+ Scsi_Device * scsi_dev_ptr,
13118+ int cmd,
13119+ void * arg )
13120+/*----------------------------------------------------------------------------*/
13121+{
13122+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
13123+
13124+ cmn_err( CE_DEBUG, "AAC_Ioctl" );
13125+ CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )scsi_dev_ptr->host->hostdata;
13126+ return( AacHba_Ioctl( CommonExtensionPtr, cmd, arg ) );
13127+}
13128+
13129+
13130+
13131+/*------------------------------------------------------------------------------
13132+ AAC_ChardevOpen()
13133+
13134+ Handle character device open
13135+
13136+ Preconditions:
13137+ Postconditions:
13138+ Returns 0 if successful, -ENODEV or -EINVAL otherwise
13139+ *----------------------------------------------------------------------------*/
13140+int AAC_ChardevOpen(
13141+ struct inode * inode_ptr,
13142+ struct file * file_ptr )
13143+/*----------------------------------------------------------------------------*/
13144+{
13145+ unsigned minor_number;
13146+
13147+ cmn_err( CE_DEBUG, "AAC_ChardevOpen" );
13148+
13149+ // check device permissions in file_ptr->f_mode ??
13150+
13151+ // extract & check the minor number
13152+ minor_number = MINOR( inode_ptr->i_rdev );
13153+ if( minor_number > ( g_HostAdapterCount - 1 ) )
13154+ {
13155+ cmn_err( CE_WARN, "AAC_ChardevOpen: Minor number %d not supported", minor_number );
13156+ return( -ENODEV );
13157+ }
13158+
13159+ MOD_INC_USE_COUNT;
13160+
13161+ return( 0 );
13162+}
13163+
13164+
13165+/*------------------------------------------------------------------------------
13166+ AAC_ChardevRelease()
13167+
13168+ Handle character device release.
13169+
13170+ Preconditions:
13171+ Postconditions:
13172+ Returns 0 if successful, -ENODEV or -EINVAL otherwise
13173+ *----------------------------------------------------------------------------*/
13174+int AAC_ChardevRelease(
13175+ struct inode * inode_ptr,
13176+ struct file * file_ptr )
13177+/*----------------------------------------------------------------------------*/
13178+{
13179+ cmn_err( CE_DEBUG, "AAC_ChardevRelease" );
13180+
13181+ MOD_DEC_USE_COUNT;
13182+
13183+ return( 0 );
13184+}
13185+
13186+
13187+/*------------------------------------------------------------------------------
13188+ AAC_ChardevIoctl()
13189+
13190+ Handle character device interface ioctls
13191+
13192+ Preconditions:
13193+ Postconditions:
13194+ Returns 0 if successful, -ENODEV or -EINVAL otherwise
13195+ *----------------------------------------------------------------------------*/
13196+int AAC_ChardevIoctl(
13197+ struct inode * inode_ptr,
13198+ struct file * file_ptr,
13199+ unsigned int cmd,
13200+ unsigned long arg )
13201+{
13202+ unsigned minor_number;
13203+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
13204+
13205+ cmn_err( CE_DEBUG, "AAC_ChardevIoctl" );
13206+
13207+ // check device permissions in file_ptr->f_mode ??
13208+
13209+ // extract & check the minor number
13210+ minor_number = MINOR( inode_ptr->i_rdev );
13211+ if( minor_number > ( g_HostAdapterCount - 1 ) )
13212+ {
13213+ cmn_err( CE_WARN, "AAC_ChardevIoctl: Minor number %d not supported", minor_number );
13214+ return( -ENODEV );
13215+ }
13216+
13217+ // get device pointer
13218+ CommonExtensionPtr = g_CommonExtensionPtrArray[ minor_number ];
13219+
13220+ // dispatch ioctl - AacHba_Ioctl() returns zero on success
13221+ if( AacHba_Ioctl( CommonExtensionPtr, cmd, ( void * )arg ) )
13222+ return( -EINVAL );
13223+
13224+ return( 0 );
13225+}
13226+
13227+
13228+/*------------------------------------------------------------------------------
13229+ parse_keyword()
13230+
13231+ Look for the keyword in str_ptr
13232+
13233+ Preconditions:
13234+ Postconditions:
13235+ If keyword found
13236+ - return true and update the pointer str_ptr.
13237+ otherwise
13238+ - return false
13239+ *----------------------------------------------------------------------------*/
13240+static int parse_keyword(
13241+ char ** str_ptr,
13242+ char * keyword )
13243+/*----------------------------------------------------------------------------*/
13244+{
13245+ char * ptr = *str_ptr;
13246+
13247+ while( *keyword != '\0' )
13248+ {
13249+ char string_char = *ptr++;
13250+ char keyword_char = *keyword++;
13251+
13252+ if ( ( string_char >= 'A' ) && ( string_char <= 'Z' ) )
13253+ string_char += 'a' - 'Z';
13254+ if( ( keyword_char >= 'A' ) && ( keyword_char <= 'Z' ) )
13255+ keyword_char += 'a' - 'Z';
13256+ if( string_char != keyword_char )
13257+ return FALSE;
13258+ }
13259+ *str_ptr = ptr;
13260+ return TRUE;
13261+}
13262+
13263+
13264+/*------------------------------------------------------------------------------
13265+ AAC_ParseDriverOptions()
13266+
13267+ For modules the usage is:
13268+ insmod -f aacraid.o 'aacraid_options="<option_name:argument>"'
13269+ *----------------------------------------------------------------------------*/
13270+static void AAC_ParseDriverOptions(
13271+ char * cmnd_line_options_str )
13272+/*----------------------------------------------------------------------------*/
13273+{
13274+ int message_level;
13275+ int reverse_scan;
13276+ char *cp;
13277+ char *endp;
13278+
13279+ cp = cmnd_line_options_str;
13280+
13281+ cmn_err(CE_DEBUG, "AAC_ParseDriverOptions: <%s>", cp);
13282+
13283+ while( *cp ) {
13284+ if( parse_keyword( &cp, "message_level:" ) ) {
13285+ message_level = simple_strtoul( cp, 0, 0 );
13286+ if( ( message_level < CE_TAIL ) && ( message_level >= 0 ) ) {
13287+ g_options.message_level = message_level;
13288+ cmn_err( CE_WARN, "%s: new message level = %d", g_DriverName, g_options.message_level );
13289+ }
13290+ else {
13291+ cmn_err( CE_WARN, "%s: invalid message level = %d", g_DriverName, message_level );
13292+ }
13293+ } else if (parse_keyword( &cp, "reverse_scan:" ) ) {
13294+ reverse_scan = simple_strtoul( cp, 0, 0 );
13295+ if (reverse_scan) {
13296+ g_options.reverse_scan = 1;
13297+ cmn_err( CE_WARN, "%s: reversing device discovery order", g_DriverName, g_options.message_level );
13298+ }
13299+ }
13300+ else {
13301+ cmn_err( CE_WARN, "%s: unknown command line option <%s>", g_DriverName, cp );
13302+ }
13303+
13304+ /*
13305+ * skip to next option, accept " ", ";", and "," as delimiters
13306+ */
13307+ while ( *cp && (*cp != ' ') && (*cp != ';') && (*cp != ','))
13308+ cp++;
13309+
13310+ if (*cp) /* skip over the delimiter */
13311+ cp++;
13312+ }
13313+
13314+}
13315+
13316+
13317+/*------------------------------------------------------------------------------
13318+ To use the low level SCSI driver support using the linux kernel loadable
13319+ module interface we should initialize the global variable driver_interface
13320+ (datatype Scsi_Host_Template) and then include the file scsi_module.c.
13321+ *----------------------------------------------------------------------------*/
13322+
13323+Scsi_Host_Template driver_template = AAC_HOST_TEMPLATE_ENTRY;
13324+
13325+#include "scsi_module.c"
13326+
13327+
13328+/*********************************************************************
13329+ AAC_ProcDirectoryInfo()
13330+
13331+ Implement /proc/scsi/<drivername>/<n>.
13332+ Used to export driver statistics and other infos to the world outside
13333+ the kernel using the proc file system. Also provides an interface to
13334+ feed the driver with information.
13335+
13336+ Postconditions
13337+ For reads
13338+ - if offset > 0 return 0
13339+ - if offset == 0 write data to proc_buffer and set the start_ptr to
13340+ beginning of proc_buffer, return the number of characters written.
13341+ For writes
13342+ - writes currently not supported, return 0
13343+************************************************************/
13344+int AAC_ProcDirectoryInfo(
13345+ char *proc_buffer, // read/write buffer
13346+ char **start_ptr, // start of valid data in the buffer
13347+ off_t offset, // offset from the beginning of the imaginary file
13348+ int bytes_available, // bytes available
13349+ int host_no, // SCSI host number
13350+ int write ) // direction of dataflow: TRUE for writes, FALSE for reads
13351+{
13352+ int length = 0;
13353+ cmn_err( CE_WARN, "AAC_ProcDirectoryInfo" );
13354+
13355+ if( ( write ) || ( offset > 0 ) )
13356+ return( 0 );
13357+
13358+ *start_ptr = proc_buffer;
13359+
13360+ return( sprintf(&proc_buffer[length], "%s %d\n", "Raid Controller, scsi hba number", host_no ) );
13361+}
13362+
13363+void aac_allocate_SyncFibs (PCI_MINIPORT_COMMON_EXTENSION *CommonExtension)
13364+{
13365+ void *BaseAddress;
13366+ ULONG PhysAddress;
13367+ int size;
13368+ int npages;
13369+ int i;
13370+
13371+ AFA_COMM_ADAPTER *Adapter;
13372+ Adapter = CommonExtension->Adapter;
13373+
13374+
13375+ // Allocate 1 fib for synch fibs
13376+ // Allocate 1 page.
13377+ BaseAddress = OsAllocMemory ( PAGE_SIZE, OS_ALLOC_MEM_SLEEP);
13378+ bzero(BaseAddress, PAGE_SIZE);
13379+ PhysAddress = virt_to_phys (BaseAddress);
13380+ Adapter->SyncFib = BaseAddress;
13381+ Adapter->SyncFibPhysicalAddress = PhysAddress;
13382+ cmn_err(CE_DEBUG,"aac_allocate_SyncFibs: syncFib: vaddr: 0x%x paddr: 0x%x ", BaseAddress, PhysAddress);
13383+
13384+}
13385diff -burN linux-2.4.9/drivers/scsi/aacraid/osddi.c linux/drivers/scsi/aacraid/osddi.c
13386--- linux-2.4.9/drivers/scsi/aacraid/osddi.c Wed Dec 31 18:00:00 1969
13387+++ linux/drivers/scsi/aacraid/osddi.c Thu Aug 16 13:41:30 2001
13388@@ -0,0 +1,508 @@
13389+/*++
13390+ * Adaptec aacraid device driver for Linux.
13391+ *
13392+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
13393+ *
13394+ * This program is free software; you can redistribute it and/or modify
13395+ * it under the terms of the GNU General Public License as published by
13396+ * the Free Software Foundation; either version 2, or (at your option)
13397+ * any later version.
13398+ *
13399+ * This program is distributed in the hope that it will be useful,
13400+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13401+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13402+ * GNU General Public License for more details.
13403+ *
13404+ * You should have received a copy of the GNU General Public License
13405+ * along with this program; see the file COPYING. If not, write to
13406+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
13407+ *
13408+ * Module Name:
13409+ * osddi.c
13410+ *
13411+ * Abstract: This file contains all the proceedures which use LINUX specific Device
13412+ * Driver Interfaces.
13413+ *
13414+ --*/
13415+
13416+static char *ident_osddi = "aacraid_ident osddi.c 1.0.6 2000/10/09 Adaptec, Inc.";
13417+
13418+#include "osheaders.h"
13419+
13420+#include <linux/smp_lock.h>
13421+
13422+#ifdef fsid_t
13423+#undef fsid_t
13424+#endif
13425+#include "AacGenericTypes.h"
13426+#include "aac_unix_defs.h"
13427+#include "comstruc.h"
13428+#include "monkerapi.h"
13429+#include "protocol.h"
13430+#include "fsafs.h"
13431+
13432+#include "sap1common.h"
13433+#include "fsaport.h"
13434+#include "pcisup.h"
13435+#include "sap1.h"
13436+#include "nodetype.h"
13437+#include "comsup.h"
13438+#include "afacomm.h"
13439+#include "adapter.h"
13440+
13441+
13442+void AacSaPciIsr(
13443+ int irq,
13444+ void * irq_data,
13445+ struct pt_regs *regs);
13446+
13447+void AacRxPciIsr(
13448+ int irq,
13449+ void * irq_data,
13450+ struct pt_regs *regs);
13451+
13452+unsigned SaPciIsr (
13453+ IN PSa_ADAPTER_EXTENSION AdapterExtension );
13454+
13455+unsigned RxPciIsr (
13456+ IN PSa_ADAPTER_EXTENSION AdapterExtension );
13457+
13458+
13459+/*----------------------------------------------------------------------------*/
13460+VOID AfaCommInterruptHost(
13461+ PVOID AdapterArg,
13462+ ADAPTER_EVENT AdapterEvent )
13463+/*----------------------------------------------------------------------------*/
13464+{
13465+ PAFA_COMM_ADAPTER Adapter = ( PAFA_COMM_ADAPTER ) AdapterArg;
13466+ PCOMM_REGION CommRegion = Adapter->CommRegion;
13467+
13468+ switch (AdapterEvent) {
13469+
13470+ case HostNormRespQue:
13471+ OsSoftInterruptTrigger( CommRegion->HostNormRespQue.ConsumerRoutine );
13472+
13473+ // #REVIEW# - what do we do with this
13474+ // if (FsaCommData.HardInterruptModeration)
13475+ // DisableInterrupt( Adapter, HostNormRespQue, TRUE );
13476+
13477+ break;
13478+
13479+ case AdapNormCmdNotFull:
13480+ OsSoftInterruptTrigger( CommRegion->QueueNotFullDpc );
13481+ break;
13482+
13483+ case HostNormCmdQue:
13484+ OsSoftInterruptTrigger( CommRegion->HostNormCmdQue.ConsumerRoutine );
13485+ break;
13486+
13487+ case AdapNormRespNotFull:
13488+ OsSoftInterruptTrigger( CommRegion->QueueNotFullDpc );
13489+ break;
13490+
13491+ // #REVIEW# - what do we do with these
13492+ case HostHighCmdQue:
13493+ case HostHighRespQue:
13494+ case AdapHighCmdNotFull:
13495+ case AdapHighRespNotFull:
13496+ case SynchCommandComplete:
13497+ case AdapInternalError:
13498+ break;
13499+ }
13500+}
13501+
13502+
13503+// get the device name associated with this instance of the device
13504+/*----------------------------------------------------------------------------*/
13505+char *OsGetDeviceName(
13506+ void *AdapterExtension )
13507+/*----------------------------------------------------------------------------*/
13508+{
13509+ return( ( ( Sa_ADAPTER_EXTENSION * )AdapterExtension )->Common->
13510+ OsDep.scsi_host_ptr->hostt->name );
13511+}
13512+
13513+
13514+/*----------------------------------------------------------------------------*/
13515+int OsGetDeviceInstance(
13516+ void *AdapterExtension )
13517+/*----------------------------------------------------------------------------*/
13518+{
13519+ return( ( int )( ( Sa_ADAPTER_EXTENSION * )AdapterExtension )->Common->
13520+ OsDep.scsi_host_ptr->unique_id );
13521+}
13522+
13523+
13524+/*------------------------------------------------------------------------------
13525+ OsMapDeviceRegisters()
13526+
13527+ Postconditions:
13528+ Return zero on success non-zero otherwise.
13529+ *----------------------------------------------------------------------------*/
13530+int OsMapDeviceRegisters(
13531+ Sa_ADAPTER_EXTENSION *AdapterExtension )
13532+/*----------------------------------------------------------------------------*/
13533+{
13534+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
13535+
13536+ CommonExtension = AdapterExtension->Common;
13537+
13538+ if( AdapterExtension->Device = ( Sa_DEVICE_REGISTERS * )
13539+ ioremap( ( unsigned long )CommonExtension->OsDep.scsi_host_ptr->base, 8192 ) )
13540+ {
13541+ cmn_err( CE_WARN, "Device mapped to virtual address 0x%x", AdapterExtension->Device );
13542+ return( 0 );
13543+ }
13544+ else
13545+ {
13546+ cmn_err( CE_WARN, "OsMapDeviceRegisters: ioremap() failed" );
13547+ return( 1 );
13548+ }
13549+}
13550+
13551+
13552+/*------------------------------------------------------------------------------
13553+ OsUnMapDeviceRegisters()
13554+
13555+ Postconditions:
13556+ *----------------------------------------------------------------------------*/
13557+void OsUnMapDeviceRegisters(
13558+ Sa_ADAPTER_EXTENSION *AdapterExtension )
13559+/*----------------------------------------------------------------------------*/
13560+{
13561+ iounmap( ( void * )AdapterExtension->Device );
13562+}
13563+
13564+
13565+/*----------------------------------------------------------------------------*/
13566+int OsAttachInterrupt(
13567+ Sa_ADAPTER_EXTENSION *AdapterExtension ,
13568+ int WhichIsr )
13569+/*----------------------------------------------------------------------------*/
13570+{
13571+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
13572+ void *irq_data;
13573+ void (*Isr)();
13574+
13575+ CommonExtension = AdapterExtension->Common;
13576+ irq_data = ( void * )AdapterExtension;
13577+
13578+ switch (WhichIsr) {
13579+ case SaISR:
13580+ Isr = AacSaPciIsr;
13581+ break;
13582+ case RxISR:
13583+ Isr = AacRxPciIsr;
13584+ break;
13585+ default:
13586+ cmn_err(CE_WARN, "OsAttachInterrupt: invalid ISR case: 0x%x", WhichIsr);
13587+ return( FAILURE );
13588+ break;
13589+ }
13590+
13591+
13592+ if ( OsRegisterInterrupt (
13593+ CommonExtension->OsDep.scsi_host_ptr->irq, // interrupt number
13594+ Isr, // handler function
13595+ irq_data )
13596+ )
13597+ {
13598+ cmn_err( CE_WARN, "OsAttachInterrupt: Failed for IRQ: 0x%x",
13599+ CommonExtension->OsDep.scsi_host_ptr->irq );
13600+ return( FAILURE );
13601+ }
13602+
13603+ return ( 0 );
13604+}
13605+
13606+
13607+/*----------------------------------------------------------------------------*/
13608+void AacSaPciIsr(
13609+ int irq,
13610+ void * irq_data,
13611+ struct pt_regs *regs)
13612+/*----------------------------------------------------------------------------*/
13613+{
13614+ // call the actual interrupt handler
13615+ SaPciIsr( ( Sa_ADAPTER_EXTENSION * )irq_data );
13616+}
13617+
13618+/*----------------------------------------------------------------------------*/
13619+void AacRxPciIsr(
13620+ int irq,
13621+ void * irq_data,
13622+ struct pt_regs *regs)
13623+/*----------------------------------------------------------------------------*/
13624+{
13625+ // call the actual interrupt handler
13626+ RxPciIsr( ( Sa_ADAPTER_EXTENSION * )irq_data );
13627+}
13628+
13629+
13630+/*----------------------------------------------------------------------------*/
13631+void OsDetachInterrupt(
13632+ Sa_ADAPTER_EXTENSION *AdapterExtension )
13633+/*----------------------------------------------------------------------------*/
13634+{
13635+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
13636+ void *irq_data;
13637+
13638+ CommonExtension = AdapterExtension->Common;
13639+ irq_data = ( void * )AdapterExtension;
13640+
13641+ OsUnregisterInterrupt (
13642+ CommonExtension->OsDep.scsi_host_ptr->irq, // interrupt number
13643+ irq_data );
13644+}
13645+
13646+
13647+/*----------------------------------------------------------------------------*/
13648+int OsAttachDMA(
13649+ Sa_ADAPTER_EXTENSION *AdapterExtension )
13650+/*----------------------------------------------------------------------------*/
13651+{
13652+ return( 0 );
13653+}
13654+
13655+/*----------------------------------------------------------------------------*/
13656+int OsAttachHBA(
13657+ Sa_ADAPTER_EXTENSION *AdapterExtension )
13658+/*----------------------------------------------------------------------------*/
13659+{
13660+ return( 0 );
13661+}
13662+
13663+/*----------------------------------------------------------------------------*/
13664+void OsDetachDevice(
13665+ Sa_ADAPTER_EXTENSION *AdapterExtension )
13666+/*----------------------------------------------------------------------------*/
13667+{
13668+ OsUnMapDeviceRegisters( AdapterExtension );
13669+ return( 0 );
13670+}
13671+
13672+/*----------------------------------------------------------------------------*/
13673+ULONG *OsAllocCommPhysMem(
13674+ Sa_ADAPTER_EXTENSION *AdapterExtension,
13675+ ULONG size,
13676+ ULONG **virt_addr_pptr,
13677+ ULONG *phys_addr_ptr )
13678+/*----------------------------------------------------------------------------*/
13679+{
13680+ if( ( *virt_addr_pptr = ( ULONG * )OsAllocMemory( size, GFP_KERNEL ) ) )
13681+ {
13682+ *phys_addr_ptr = OsVirtToPhys( ( volatile void * )*virt_addr_pptr );
13683+ if( !*phys_addr_ptr )
13684+ {
13685+ cmn_err( CE_WARN, "OsAllocCommPhysMem: OsVirtToPhys failed" );
13686+ }
13687+
13688+ return( *virt_addr_pptr );
13689+ }
13690+ else
13691+ return( NULL );
13692+}
13693+
13694+OsAifKernelThread(
13695+ Sa_ADAPTER_EXTENSION *AdapterExtension )
13696+{
13697+
13698+ struct fs_struct *fs;
13699+ int i;
13700+ struct task_struct *tsk;
13701+
13702+ tsk = current;
13703+
13704+
13705+ /*
13706+ * set up the name that will appear in 'ps'
13707+ * stored in task_struct.comm[16].
13708+ */
13709+
13710+ sprintf(tsk->comm, "AIFd");
13711+
13712+
13713+ // use_init_fs_context(); only exists in 2.2.13 onward.
13714+
13715+ lock_kernel();
13716+
13717+ /*
13718+ * we were started as a result of loading the module.
13719+ * free all of user space pages
13720+ */
13721+
13722+ exit_mm(tsk);
13723+
13724+ exit_files(tsk);
13725+
13726+ exit_fs(tsk);
13727+
13728+ fs = init_task.fs;
13729+ tsk->fs = fs;
13730+
13731+ tsk->session = 1;
13732+ tsk->pgrp = 1;
13733+
13734+ if (fs)
13735+ atomic_inc(&fs->count);
13736+
13737+ unlock_kernel();
13738+
13739+
13740+
13741+
13742+ NormCommandThread(AdapterExtension);
13743+ /* NOT REACHED */
13744+}
13745+
13746+/*----------------------------------------------------------------------------*/
13747+void OsStartKernelThreads(
13748+ Sa_ADAPTER_EXTENSION *AdapterExtension )
13749+/*----------------------------------------------------------------------------*/
13750+{
13751+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
13752+ AFA_COMM_ADAPTER *Adapter;
13753+ extern void NormCommandThread(void *Adapter);
13754+
13755+ CommonExtension = AdapterExtension->Common;
13756+ Adapter = (AFA_COMM_ADAPTER *)CommonExtension->Adapter;
13757+
13758+ //
13759+ // Start thread which will handle interrupts for this adapter
13760+ //
13761+ //kthread_spawn(FsaCommIntrHandler, AdapterExtension, "fsaintr",0);
13762+
13763+ //
13764+ // Start thread which will handle AdapterInititatedFibs from this adapter
13765+ //
13766+ CommonExtension->OsDep.thread_pid =
13767+ kernel_thread( ( int ( * )( void * ) )OsAifKernelThread, Adapter, 0 );
13768+// kernel_thread( ( int ( * )( void * ) )NormCommandThread, Adapter, 0 );
13769+}
13770+
13771+/*----------------------------------------------------------------------------*/
13772+BOOLEAN AfaPortAllocateAndMapFibSpace(
13773+ PVOID Arg1,
13774+ IN PMAPFIB_CONTEXT MapFibContext )
13775+/*----------------------------------------------------------------------------*/
13776+{
13777+ PVOID BaseAddress;
13778+ ULONG PhysAddress;
13779+
13780+ if( !( BaseAddress = (ULONG *)OsAllocMemory( MapFibContext->Size, GFP_KERNEL ) ) )
13781+ {
13782+ cmn_err( CE_WARN, "AfaPortAllocateAndMapFibSpace: OsAllocMemory failed" );
13783+ return( FALSE );
13784+ }
13785+
13786+ PhysAddress = OsVirtToPhys( BaseAddress );
13787+
13788+ MapFibContext->FibVirtualAddress = BaseAddress;
13789+ MapFibContext->FibPhysicalAddress = (PVOID) PhysAddress;
13790+
13791+ return (TRUE);
13792+}
13793+
13794+/*----------------------------------------------------------------------------*/
13795+BOOLEAN AfaPortUnmapAndFreeFibSpace(
13796+ PVOID Arg1,
13797+ IN PMAPFIB_CONTEXT MapFibContext )
13798+/*----------------------------------------------------------------------------*/
13799+{
13800+ PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
13801+
13802+ OsFreeMemory( MapFibContext->FibVirtualAddress, 0 );
13803+
13804+ return (TRUE);
13805+}
13806+
13807+/*----------------------------------------------------------------------------*/
13808+BOOLEAN AfaPortFreeAdapterCommArea(
13809+ IN PVOID Arg1 )
13810+/*----------------------------------------------------------------------------*/
13811+{
13812+ PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
13813+
13814+ OsFreeMemory( CommonExtension->CommAddress, 0 );
13815+
13816+ return (TRUE);
13817+}
13818+
13819+
13820+/* ================================================================================ */
13821+/*
13822+ * Not sure if the functions below here ever get called in the current code
13823+ * These probably should be a different file.
13824+ */
13825+/*
13826+ddi_dma_attr_t AfaPortDmaAttributes = {
13827+ //rpbfix : we may want something different for I/O
13828+ DMA_ATTR_V0,
13829+ 0,
13830+ 0xffffffff,
13831+ 0x0000ffff,
13832+ 1,
13833+ 1,
13834+ 1,
13835+ 0x0000ffff,
13836+ 0x0000ffff,
13837+ 17,
13838+ 512,
13839+ 0
13840+};
13841+*/
13842+
13843+AAC_STATUS
13844+AfaPortBuildSgMap(
13845+ PVOID Arg1,
13846+ IN PSGMAP_CONTEXT SgMapContext
13847+ )
13848+
13849+/*++
13850+
13851+Routine Description:
13852+
13853+ This routine build a scatter gather map using the information
13854+ in the SgMapContext.
13855+
13856+Arguments:
13857+
13858+ AdapterExtension - Pointer to adapter extension structure.
13859+ SgMapContext - Pointer to the SgMapContext for the request.
13860+
13861+
13862+Return Value:
13863+
13864+ AAC_STATUS
13865+--*/
13866+{
13867+ printk( KERN_ALERT "AfaPortBuildSgMap: unimplemented function called" );
13868+ return (STATUS_UNSUCCESSFUL);
13869+}
13870+
13871+VOID
13872+AfaPortFreeDmaResources(
13873+ PVOID Arg1,
13874+ IN PSGMAP_CONTEXT SgMapContext
13875+ )
13876+
13877+/*++
13878+
13879+Routine Description:
13880+
13881+ Given a pointer to the IRP context will free all reserved DMA resources allocated for
13882+ the completed IO operation.
13883+
13884+Arguments:
13885+
13886+ Fib - Pointer to the Fib the caller wishes to have transfered over to the adapter.
13887+ Context - Pointer to the Irp Context we use to store the dma mapping information
13888+ we need to do and complete the IO.
13889+
13890+Return Value:
13891+
13892+ Nothing
13893+
13894+--*/
13895+{
13896+}
13897diff -burN linux-2.4.9/drivers/scsi/aacraid/osfuncs.c linux/drivers/scsi/aacraid/osfuncs.c
13898--- linux-2.4.9/drivers/scsi/aacraid/osfuncs.c Wed Dec 31 18:00:00 1969
13899+++ linux/drivers/scsi/aacraid/osfuncs.c Thu Aug 16 18:15:01 2001
13900@@ -0,0 +1,594 @@
13901+/*++
13902+ * Adaptec aacraid device driver for Linux.
13903+ *
13904+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
13905+ *
13906+ * This program is free software; you can redistribute it and/or modify
13907+ * it under the terms of the GNU General Public License as published by
13908+ * the Free Software Foundation; either version 2, or (at your option)
13909+ * any later version.
13910+ *
13911+ * This program is distributed in the hope that it will be useful,
13912+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13913+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13914+ * GNU General Public License for more details.
13915+ *
13916+ * You should have received a copy of the GNU General Public License
13917+ * along with this program; see the file COPYING. If not, write to
13918+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
13919+ *
13920+ * Module Name:
13921+ * osfuncs.c
13922+ *
13923+ * Abstract: Holds all of the O/S specific interface functions.
13924+ *
13925+ --*/
13926+
13927+static char *ident_osfuncs = "aacraid_ident osfuncs.c 1.0.6 2000/10/09 Adaptec, Inc.";
13928+
13929+#include "osheaders.h"
13930+
13931+//static LKINFO_DECL(fsa_locks, "fsa_locks",0);
13932+
13933+extern aac_options_t g_options;
13934+
13935+OS_SOFTINTR g_idle_task = { 0, 0, 0, 0 };
13936+wait_queue_t * g_wait_queue_ptr = NULL;
13937+wait_queue_t g_wait;
13938+
13939+void OsTimeoutHandler(
13940+ struct semaphore * sem );
13941+
13942+int * OsIdleTask( void * data );
13943+
13944+//-----------------------------------------------------------------------------
13945+// Memory Allocation functions
13946+
13947+/*----------------------------------------------------------------------------*/
13948+void * OsAllocMemory(
13949+ OS_SIZE_T Size,
13950+ unsigned int Flags )
13951+/*----------------------------------------------------------------------------*/
13952+{
13953+ void *mem_ptr;
13954+
13955+ if( !( mem_ptr = kmalloc( Size, GFP_KERNEL ) ) )
13956+ cmn_err( CE_WARN, "OsAllocMemory: FAILED\n" );
13957+ return( mem_ptr );
13958+}
13959+
13960+
13961+/*----------------------------------------------------------------------------*/
13962+void OsFreeMemory(
13963+ void * Buffer,
13964+ OS_SIZE_T Size )
13965+/*----------------------------------------------------------------------------*/
13966+{
13967+ kfree( Buffer );
13968+}
13969+
13970+
13971+/*----------------------------------------------------------------------------*/
13972+int OsRegisterInterrupt(
13973+ unsigned int irq, // interrupt number
13974+ void ( *handler )( int, void*, struct pt_regs * ), // handler function
13975+ void *irq_data ) // argument to handler function
13976+/*----------------------------------------------------------------------------*/
13977+{
13978+ return( request_irq (irq, handler, SA_INTERRUPT | SA_SHIRQ, "aacraid", irq_data ) );
13979+}
13980+
13981+
13982+/*----------------------------------------------------------------------------*/
13983+void OsUnregisterInterrupt(
13984+ unsigned int irq, // interrupt number
13985+ void *irq_data)
13986+/*----------------------------------------------------------------------------*/
13987+{
13988+ free_irq (
13989+ irq, // interrupt number
13990+ irq_data );
13991+}
13992+
13993+
13994+/*----------------------------------------------------------------------------*/
13995+unsigned long OsVirtToPhys(
13996+ void * virtual_address )
13997+/*----------------------------------------------------------------------------*/
13998+{
13999+ return( virt_to_phys( virtual_address ) );
14000+}
14001+
14002+
14003+//-----------------------------------------------------------------------------
14004+// MUTEX functions
14005+
14006+/*----------------------------------------------------------------------------*/
14007+OS_STATUS OsMutexInit(
14008+ OS_MUTEX *Mutex,
14009+ OS_SPINLOCK_COOKIE Cookie )
14010+/*----------------------------------------------------------------------------*/
14011+{
14012+ Mutex->lock_var = 0;
14013+ // bzero (&Mutex->wq, sizeof (Mutex->wq));
14014+ init_waitqueue_head (&Mutex->wq);
14015+ return ( 0 );
14016+}
14017+
14018+
14019+/*----------------------------------------------------------------------------*/
14020+void OsMutexDestroy(
14021+ OS_MUTEX *Mutex )
14022+/*----------------------------------------------------------------------------*/
14023+{
14024+}
14025+
14026+
14027+/*----------------------------------------------------------------------------*/
14028+void OsMutexAcquire(
14029+ OS_MUTEX *Mutex )
14030+/*----------------------------------------------------------------------------*/
14031+{
14032+ // wait_queue_t wait = { current, NULL };
14033+ unsigned long time_stamp;
14034+
14035+ DECLARE_WAITQUEUE (wait, current);
14036+
14037+ time_stamp = jiffies;
14038+
14039+ if( test_and_set_bit( 0, &( Mutex->lock_var ) ) != 0 )
14040+ {
14041+ if( in_interrupt() )
14042+ panic( "OsMutexAcquire going to sleep at interrupt time\n" );
14043+ current->state = TASK_INTERRUPTIBLE;
14044+ add_wait_queue( &( Mutex->wq ), &wait );
14045+ while( test_and_set_bit( 0, &( Mutex->lock_var ) ) != 0 )
14046+ schedule();
14047+ remove_wait_queue( &( Mutex->wq ), &wait );
14048+ }
14049+
14050+ if( ( jiffies - 1 ) > time_stamp )
14051+ cmn_err( CE_WARN, "Mutex %ld locked out for %ld ticks",
14052+ Mutex, jiffies - time_stamp );
14053+}
14054+
14055+
14056+/*----------------------------------------------------------------------------*/
14057+void OsMutexRelease(
14058+ OS_MUTEX *Mutex )
14059+/*----------------------------------------------------------------------------*/
14060+{
14061+ if( test_and_clear_bit( 0, &( Mutex->lock_var ) ) == 0 )
14062+ cmn_err( CE_WARN, "OsMutexRelease: mutex not locked" );
14063+ wake_up_interruptible( &( Mutex->wq ) );
14064+}
14065+
14066+// see man hierarchy(D5)
14067+#define FSA_LOCK 1
14068+
14069+//-----------------------------------------------------------------------------
14070+// Spinlock functions
14071+
14072+/*----------------------------------------------------------------------------*/
14073+OS_SPINLOCK * OsSpinLockAlloc( void )
14074+/*----------------------------------------------------------------------------*/
14075+{
14076+ OS_SPINLOCK *SpinLock;
14077+ int i;
14078+
14079+
14080+ SpinLock = ( OS_SPINLOCK * )kmalloc( sizeof( OS_SPINLOCK ), GFP_KERNEL );
14081+
14082+ if (SpinLock == NULL)
14083+ cmn_err (CE_WARN, "WARNING: OsSpinLockAlloc Failed!!!");
14084+
14085+ SpinLock->spin_lock = SPIN_LOCK_UNLOCKED;
14086+ for( i = 0; i < NR_CPUS; i++ )
14087+ SpinLock->cpu_lock_count[ i ] = 0;
14088+ return( SpinLock );
14089+}
14090+
14091+
14092+/*----------------------------------------------------------------------------*/
14093+OS_STATUS OsSpinLockInit(
14094+ OS_SPINLOCK *SpinLock,
14095+ OS_SPINLOCK_COOKIE Cookie )
14096+/*----------------------------------------------------------------------------*/
14097+{
14098+ return( 0 );
14099+}
14100+
14101+
14102+/*----------------------------------------------------------------------------*/
14103+void OsSpinLockDestroy(
14104+ OS_SPINLOCK *SpinLock )
14105+/*----------------------------------------------------------------------------*/
14106+{
14107+ kfree( SpinLock );
14108+ SpinLock = NULL;
14109+}
14110+
14111+
14112+/*----------------------------------------------------------------------------*/
14113+void OsSpinLockAcquire(
14114+ OS_SPINLOCK *SpinLock )
14115+/*----------------------------------------------------------------------------*/
14116+{
14117+ unsigned cpu_id;
14118+
14119+ if( SpinLock )
14120+ {
14121+ cpu_id = smp_processor_id();
14122+ if( SpinLock->cpu_lock_count[ cpu_id ] ){
14123+ cmn_err (CE_PANIC, "CPU %d trying to acquire lock again: lock count = %d\n",
14124+ cpu_id, SpinLock->cpu_lock_count[ cpu_id ]);
14125+ }
14126+
14127+ spin_lock_irqsave( &( SpinLock->spin_lock ), SpinLock->cpu_flags[ cpu_id ] );
14128+ SpinLock->cpu_lock_count[ cpu_id ]++;
14129+
14130+ } else {
14131+ cmn_err( CE_WARN, "OsSpinLockAcquire: lock does not exist" );
14132+ }
14133+}
14134+
14135+
14136+/*----------------------------------------------------------------------------*/
14137+void OsSpinLockRelease(
14138+ OS_SPINLOCK *SpinLock )
14139+/*----------------------------------------------------------------------------*/
14140+{
14141+ unsigned cpu_id;
14142+
14143+ if( SpinLock )
14144+ {
14145+ cpu_id = smp_processor_id();
14146+ SpinLock->cpu_lock_count[ cpu_id ]--;
14147+ spin_unlock_irqrestore( &( SpinLock->spin_lock ), SpinLock->cpu_flags[ cpu_id ] );
14148+ }
14149+ else
14150+ cmn_err( CE_WARN, "OsSpinLockRelease: lock does not exist" );
14151+}
14152+
14153+
14154+/*----------------------------------------------------------------------------*/
14155+inline int OsSpinLockOwned(
14156+ OS_SPINLOCK *SpinLock )
14157+/*----------------------------------------------------------------------------*/
14158+{
14159+ return spin_is_locked (&SpinLock->spin_lock);
14160+}
14161+
14162+
14163+//-----------------------------------------------------------------------------
14164+// CvLock functions
14165+
14166+/*----------------------------------------------------------------------------*/
14167+OS_CVLOCK *OsCvLockAlloc( void )
14168+{
14169+ OS_CVLOCK *cv_lock;
14170+
14171+
14172+#ifdef CVLOCK_USE_SPINLOCK
14173+ cv_lock = OsSpinLockAlloc();
14174+#else
14175+ cv_lock = ( OS_CVLOCK * )kmalloc( sizeof( OS_CVLOCK ), GFP_KERNEL );
14176+ cv_lock->wq = NULL;
14177+ cv_lock->lock_var = 0;
14178+#endif
14179+
14180+ return( cv_lock );
14181+}
14182+
14183+
14184+/*----------------------------------------------------------------------------*/
14185+OS_STATUS OsCvLockInit(
14186+ OS_CVLOCK *cv_lock,
14187+ OS_SPINLOCK_COOKIE Cookie )
14188+/*----------------------------------------------------------------------------*/
14189+{
14190+ return ( 0 );
14191+}
14192+
14193+
14194+/*----------------------------------------------------------------------------*/
14195+void OsCvLockDestroy(
14196+ OS_CVLOCK *cv_lock )
14197+/*----------------------------------------------------------------------------*/
14198+{
14199+ if( cv_lock )
14200+ kfree( cv_lock );
14201+ cv_lock = NULL;
14202+}
14203+
14204+
14205+/*----------------------------------------------------------------------------*/
14206+void OsCvLockAcquire (OS_CVLOCK *cv_lock)
14207+{
14208+#ifdef CVLOCK_USE_SPINLOCK
14209+ OsSpinLockAcquire( cv_lock );
14210+#else
14211+ OsMutexAcquire( cv_lock );
14212+#endif
14213+}
14214+
14215+
14216+/*----------------------------------------------------------------------------*/
14217+void OsCvLockRelease(
14218+ OS_CVLOCK *cv_lock )
14219+/*----------------------------------------------------------------------------*/
14220+{
14221+#ifdef CVLOCK_USE_SPINLOCK
14222+ OsSpinLockRelease( cv_lock );
14223+#else
14224+ OsMutexRelease( cv_lock );
14225+#endif
14226+}
14227+
14228+
14229+/*----------------------------------------------------------------------------*/
14230+int OsCvLockOwned(
14231+ OS_CVLOCK *cv_lock )
14232+/*----------------------------------------------------------------------------*/
14233+{
14234+ return( 1 );
14235+}
14236+
14237+
14238+//-----------------------------------------------------------------------------
14239+// Conditional variable functions
14240+
14241+/*----------------------------------------------------------------------------*/
14242+void OsCv_init (
14243+ OS_CV_T *cv_ptr )
14244+/*----------------------------------------------------------------------------*/
14245+{
14246+ cv_ptr->lock_var = 1;
14247+ init_waitqueue_head (&cv_ptr->wq);
14248+}
14249+
14250+
14251+/*----------------------------------------------------------------------------*/
14252+void OsCv_destroy(
14253+ OS_CV_T *cv_ptr )
14254+/*----------------------------------------------------------------------------*/
14255+{
14256+}
14257+
14258+
14259+/*______________________________________________________________________________
14260+ -
14261+ -
14262+ -----------------------------------------------------------------------------*/
14263+OsCv_wait (OS_CV_T *cv_ptr, OS_CVLOCK *cv_lock_ptr)
14264+{
14265+ unsigned long flags;
14266+
14267+ DECLARE_WAITQUEUE (wait, current);
14268+
14269+ if( in_interrupt() )
14270+ panic( "OsCv_wait going to sleep at interrupt time\n" );
14271+
14272+ cv_ptr->type = TASK_UNINTERRUPTIBLE;
14273+ current->state = TASK_UNINTERRUPTIBLE;
14274+
14275+ add_wait_queue( &cv_ptr->wq, &wait );
14276+
14277+ OsCvLockRelease( cv_lock_ptr );
14278+ schedule();
14279+
14280+ while( test_and_set_bit( 0, &( cv_ptr->lock_var ) ) != 0 )
14281+ {
14282+ if( in_interrupt() )
14283+ panic( "OsCv_wait going to sleep at interrupt time\n" );
14284+ schedule();
14285+ }
14286+
14287+ remove_wait_queue( &( cv_ptr->wq ), &wait );
14288+
14289+ OsCvLockAcquire( cv_lock_ptr );
14290+}
14291+
14292+
14293+/*----------------------------------------------------------------------------*/
14294+int OsCv_wait_sig(
14295+ OS_CV_T *cv_ptr,
14296+ OS_CVLOCK *cv_lock_ptr )
14297+/*----------------------------------------------------------------------------*/
14298+{
14299+ unsigned long flags;
14300+ int signal_state = 1;
14301+
14302+ DECLARE_WAITQUEUE (wait, current);
14303+
14304+ if( in_interrupt() )
14305+ panic( "OsCv_wait_sig going to sleep at interrupt time\n" );
14306+
14307+ cv_ptr->type = TASK_INTERRUPTIBLE;
14308+ current->state = TASK_INTERRUPTIBLE;
14309+
14310+ add_wait_queue( &( cv_ptr->wq ), &wait );
14311+
14312+ OsCvLockRelease( cv_lock_ptr );
14313+ schedule();
14314+
14315+ while( ( test_and_set_bit( 0, &( cv_ptr->lock_var ) ) != 0 ) &&
14316+ ( !signal_pending( current ) ) )
14317+ {
14318+ if( in_interrupt() )
14319+ panic( "OsCv_wait_sig going to sleep at interrupt time\n" );
14320+ schedule();
14321+ }
14322+
14323+ if( signal_pending( current ) )
14324+ signal_state = 0;
14325+
14326+ remove_wait_queue( &( cv_ptr->wq ), &wait );
14327+
14328+ OsCvLockAcquire( cv_lock_ptr );
14329+ return( signal_state );
14330+}
14331+
14332+
14333+/*----------------------------------------------------------------------------*/
14334+void OsCv_signal(
14335+ OS_CV_T *cv_ptr )
14336+/*----------------------------------------------------------------------------*/
14337+{
14338+
14339+ clear_bit( 0, &( cv_ptr->lock_var ) );
14340+ if( cv_ptr->type == TASK_INTERRUPTIBLE )
14341+ wake_up_interruptible( &( cv_ptr->wq ) );
14342+ else{
14343+ wake_up( &( cv_ptr->wq ) );
14344+ }
14345+}
14346+
14347+
14348+// return time in seconds
14349+/*----------------------------------------------------------------------------*/
14350+unsigned long OsGetSeconds( void )
14351+/*----------------------------------------------------------------------------*/
14352+{
14353+ return( jiffies/HZ );
14354+}
14355+
14356+
14357+//-----------------------------------------------------------------------------
14358+// Deferred procedure call functions
14359+
14360+// create a soft interrupt object
14361+/*----------------------------------------------------------------------------*/
14362+int OsSoftInterruptAdd(
14363+ OS_SOFTINTR **ptr,
14364+ void * handler,
14365+ void * data )
14366+/*----------------------------------------------------------------------------*/
14367+{
14368+ OS_SOFTINTR *tmp_ptr;
14369+
14370+ if( !( tmp_ptr = ( OS_SOFTINTR * )kmalloc( sizeof( OS_SOFTINTR ), GFP_KERNEL ) ) )
14371+ return( -1 );
14372+ tmp_ptr->routine = handler;
14373+ tmp_ptr->data = data;
14374+ tmp_ptr->sync = 0;
14375+ INIT_LIST_HEAD(&tmp_ptr->list);
14376+
14377+ *ptr = tmp_ptr;
14378+
14379+ return( 0 );
14380+}
14381+
14382+/*
14383+ Use kernel_thread( ( int ( * )( void * ) )OsIdleTask, NULL, 0 ); to start
14384+*/
14385+/*----------------------------------------------------------------------------*/
14386+int * OsIdleTask( void * data )
14387+/*----------------------------------------------------------------------------*/
14388+{
14389+ DECLARE_WAITQUEUE (wait, current);
14390+
14391+ while( 1 )
14392+ {
14393+ current->state = TASK_INTERRUPTIBLE;
14394+ add_wait_queue( &g_wait_queue_ptr, &wait );
14395+ schedule();
14396+ remove_wait_queue( &g_wait_queue_ptr, &wait );
14397+ wait.task = current;
14398+ wait.task_list.next = NULL;
14399+ }
14400+ return( NULL );
14401+}
14402+
14403+
14404+// dispatch a soft interrupt
14405+/*----------------------------------------------------------------------------*/
14406+void OsSoftInterruptTrigger(
14407+ OS_SOFTINTR *soft_intr_ptr )
14408+/*----------------------------------------------------------------------------*/
14409+{
14410+ // call the completion routine directly
14411+ soft_intr_ptr->routine( soft_intr_ptr->data );
14412+}
14413+
14414+
14415+// delete a soft interrupt object
14416+/*----------------------------------------------------------------------------*/
14417+void OsSoftInterruptRemove(
14418+ OS_SOFTINTR *arg )
14419+/*----------------------------------------------------------------------------*/
14420+{
14421+ if( arg )
14422+ kfree( arg );
14423+ arg = NULL;
14424+}
14425+
14426+
14427+/*----------------------------------------------------------------------------*/
14428+void OsSleep(
14429+ unsigned time ) // in seconds
14430+/*----------------------------------------------------------------------------*/
14431+{
14432+ struct semaphore sem;
14433+ struct timer_list timer_var;
14434+
14435+ init_MUTEX_LOCKED (&sem);
14436+
14437+ // if( in_interrupt() )
14438+ // panic( "OsSleep going to sleep at interrupt time\n" );
14439+
14440+ init_timer( &timer_var );
14441+ timer_var.function = ( void ( * )( unsigned long ) )OsTimeoutHandler;
14442+ timer_var.data = ( unsigned long )&sem;
14443+ timer_var.expires = jiffies + time * HZ;
14444+
14445+ add_timer( &timer_var );
14446+ down( &sem );
14447+
14448+ del_timer( &timer_var );
14449+}
14450+
14451+
14452+/*----------------------------------------------------------------------------*/
14453+void OsTimeoutHandler(
14454+ struct semaphore * sem )
14455+/*----------------------------------------------------------------------------*/
14456+{
14457+ if( sem != NULL )
14458+ up( sem );
14459+}
14460+
14461+
14462+/*----------------------------------------------------------------------------*/
14463+void printk_err(
14464+ int flag,
14465+ char *fmt,
14466+ ...)
14467+/*----------------------------------------------------------------------------*/
14468+{
14469+ char buf[256];
14470+ va_list ap;
14471+
14472+ va_start(ap, fmt);
14473+ (void) vsprintf(buf, fmt, ap);
14474+ va_end(ap);
14475+
14476+ if( flag <= g_options.message_level )
14477+ printk(KERN_ALERT "%s\n", buf);
14478+}
14479+
14480+/* void aac_show_tasks (struct list_head *our_tasks){ */
14481+
14482+/* cmn_err (CE_DEBUG, "Entering aac_show_tasks"); */
14483+
14484+/* if (our_tasks->next == NULL || our_tasks->next == 0) */
14485+/* cmn_err (CE_DEBUG, "list_head->next is NULL or 0"); */
14486+/* else */
14487+/* cmn_err (CE_DEBUG, "list_head->next: 0x%x", our_tasks->next); */
14488+
14489+/* if (our_tasks->prev == NULL || our_tasks->prev == 0) */
14490+/* cmn_err (CE_DEBUG, "list_head->prev is NULL or 0"); */
14491+/* else */
14492+/* cmn_err (CE_DEBUG, "list_head->prev: 0x%x", our_tasks->prev); */
14493+
14494+/* } */
14495diff -burN linux-2.4.9/drivers/scsi/aacraid/ossup.c linux/drivers/scsi/aacraid/ossup.c
14496--- linux-2.4.9/drivers/scsi/aacraid/ossup.c Wed Dec 31 18:00:00 1969
14497+++ linux/drivers/scsi/aacraid/ossup.c Thu Aug 16 13:41:30 2001
14498@@ -0,0 +1,199 @@
14499+/*++
14500+ * Adaptec aacraid device driver for Linux.
14501+ *
14502+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
14503+ *
14504+ * This program is free software; you can redistribute it and/or modify
14505+ * it under the terms of the GNU General Public License as published by
14506+ * the Free Software Foundation; either version 2, or (at your option)
14507+ * any later version.
14508+ *
14509+ * This program is distributed in the hope that it will be useful,
14510+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14511+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14512+ * GNU General Public License for more details.
14513+ *
14514+ * You should have received a copy of the GNU General Public License
14515+ * along with this program; see the file COPYING. If not, write to
14516+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
14517+ *
14518+ * Module Name:
14519+ * ossup.c
14520+ *
14521+ *
14522+ *
14523+ --*/
14524+
14525+static char *ident_ossup = "aacraid_ident ossup.c 1.0.6 2000/10/09 Adaptec, Inc.";
14526+
14527+#include "osheaders.h"
14528+
14529+#include "aac_unix_defs.h"
14530+
14531+
14532+AAC_STATUS
14533+ExInitializeZone(
14534+ IN PZONE_HEADER Zone,
14535+ IN ULONG BlockSize,
14536+ IN PVOID InitialSegment,
14537+ IN ULONG InitialSegmentSize
14538+ )
14539+
14540+/*++
14541+
14542+Routine Description:
14543+
14544+ This function initializes a zone header. Once successfully
14545+ initialized, blocks can be allocated and freed from the zone, and
14546+ the zone can be extended.
14547+
14548+Arguments:
14549+
14550+ Zone - Supplies the address of a zone header to be initialized.
14551+
14552+ BlockSize - Supplies the block size of the allocatable unit within
14553+ the zone. The size must be larger that the size of the
14554+ initial segment, and must be 64-bit aligned.
14555+
14556+ InitialSegment - Supplies the address of a segment of storage. The
14557+ first ZONE_SEGMENT_HEADER-sized portion of the segment
14558+ is used by the zone allocator. The remainder of
14559+ the segment is carved up into fixed size
14560+ (BlockSize) blocks and is made available for
14561+ allocation and deallocation from the zone. The
14562+ address of the segment must be aligned on a 64-bit
14563+ boundary.
14564+
14565+ InitialSegmentSize - Supplies the size in bytes of the InitialSegment.
14566+
14567+Return Value:
14568+
14569+ STATUS_UNSUCCESSFUL - BlockSize or InitialSegment was not aligned on
14570+ 64-bit boundaries, or BlockSize was larger than
14571+ the initial segment size.
14572+
14573+ STATUS_SUCCESS - The zone was successfully initialized.
14574+
14575+--*/
14576+
14577+{
14578+ ULONG i;
14579+ PCHAR p;
14580+
14581+
14582+ Zone->BlockSize = BlockSize;
14583+
14584+ Zone->SegmentList.Next = &((PZONE_SEGMENT_HEADER) InitialSegment)->SegmentList;
14585+ ((PZONE_SEGMENT_HEADER) InitialSegment)->SegmentList.Next = NULL;
14586+ ((PZONE_SEGMENT_HEADER) InitialSegment)->Reserved = NULL;
14587+
14588+ Zone->FreeList.Next = NULL;
14589+
14590+ p = (PCHAR)InitialSegment + sizeof(ZONE_SEGMENT_HEADER);
14591+
14592+ for (i = sizeof(ZONE_SEGMENT_HEADER);
14593+ i <= InitialSegmentSize - BlockSize;
14594+ i += BlockSize
14595+ ) {
14596+ ((PSINGLE_LIST_ENTRY)p)->Next = Zone->FreeList.Next;
14597+ Zone->FreeList.Next = (PSINGLE_LIST_ENTRY)p;
14598+ p += BlockSize;
14599+ }
14600+ Zone->TotalSegmentSize = i;
14601+
14602+#if 0
14603+ DbgPrint( "EX: ExInitializeZone( %lx, %lx, %lu, %lu, %lx )\n",
14604+ Zone, InitialSegment, InitialSegmentSize,
14605+ BlockSize, p
14606+ );
14607+#endif
14608+
14609+ return STATUS_SUCCESS;
14610+}
14611+
14612+AAC_STATUS
14613+ExExtendZone(
14614+ IN PZONE_HEADER Zone,
14615+ IN PVOID Segment,
14616+ IN ULONG SegmentSize
14617+ )
14618+
14619+/*++
14620+
14621+Routine Description:
14622+
14623+ This function extends a zone by adding another segment's worth of
14624+ blocks to the zone.
14625+
14626+Arguments:
14627+
14628+ Zone - Supplies the address of a zone header to be extended.
14629+
14630+ Segment - Supplies the address of a segment of storage. The first
14631+ ZONE_SEGMENT_HEADER-sized portion of the segment is used by the
14632+ zone allocator. The remainder of the segment is carved up
14633+ into fixed-size (BlockSize) blocks and is added to the
14634+ zone. The address of the segment must be aligned on a 64-
14635+ bit boundary.
14636+
14637+ SegmentSize - Supplies the size in bytes of Segment.
14638+
14639+Return Value:
14640+
14641+ STATUS_UNSUCCESSFUL - BlockSize or Segment was not aligned on
14642+ 64-bit boundaries, or BlockSize was larger than
14643+ the segment size.
14644+
14645+ STATUS_SUCCESS - The zone was successfully extended.
14646+
14647+--*/
14648+
14649+{
14650+ ULONG i;
14651+ PCHAR p;
14652+
14653+
14654+ ((PZONE_SEGMENT_HEADER) Segment)->SegmentList.Next = Zone->SegmentList.Next;
14655+ Zone->SegmentList.Next = &((PZONE_SEGMENT_HEADER) Segment)->SegmentList;
14656+
14657+ p = (PCHAR)Segment + sizeof(ZONE_SEGMENT_HEADER);
14658+
14659+ for (i = sizeof(ZONE_SEGMENT_HEADER);
14660+ i <= SegmentSize - Zone->BlockSize;
14661+ i += Zone->BlockSize
14662+ ) {
14663+
14664+ ((PSINGLE_LIST_ENTRY)p)->Next = Zone->FreeList.Next;
14665+ Zone->FreeList.Next = (PSINGLE_LIST_ENTRY)p;
14666+ p += Zone->BlockSize;
14667+ }
14668+ Zone->TotalSegmentSize += i;
14669+
14670+#if 0
14671+ DbgPrint( "EX: ExExtendZone( %lx, %lx, %lu, %lu, %lx )\n",
14672+ Zone, Segment, SegmentSize, Zone->BlockSize, p
14673+ );
14674+#endif
14675+
14676+ return STATUS_SUCCESS;
14677+}
14678+
14679+DbgPrint()
14680+{
14681+}
14682+
14683+/* Function: InqStrCopy()
14684+ *
14685+ * Arguments: [2] pointer to char
14686+ *
14687+ * Purpose: Copy a String from one location to another
14688+ * without copying \0
14689+ */
14690+void
14691+InqStrCopy(char *a, char *b)
14692+{
14693+
14694+ while(*a != (char)0)
14695+ *b++ = *a++;
14696+}
14697+
14698diff -burN linux-2.4.9/drivers/scsi/aacraid/port.c linux/drivers/scsi/aacraid/port.c
14699--- linux-2.4.9/drivers/scsi/aacraid/port.c Wed Dec 31 18:00:00 1969
14700+++ linux/drivers/scsi/aacraid/port.c Thu Aug 16 13:41:30 2001
14701@@ -0,0 +1,287 @@
14702+/*++
14703+ * Adaptec aacraid device driver for Linux.
14704+ *
14705+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
14706+ *
14707+ * This program is free software; you can redistribute it and/or modify
14708+ * it under the terms of the GNU General Public License as published by
14709+ * the Free Software Foundation; either version 2, or (at your option)
14710+ * any later version.
14711+ *
14712+ * This program is distributed in the hope that it will be useful,
14713+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14714+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14715+ * GNU General Public License for more details.
14716+ *
14717+ * You should have received a copy of the GNU General Public License
14718+ * along with this program; see the file COPYING. If not, write to
14719+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
14720+ *
14721+ * Module Name:
14722+ * port.c
14723+ *
14724+ * Abstract: All support routines for FSA communication which are miniport specific.
14725+ *
14726+ --*/
14727+
14728+static char *ident_port = "aacraid_ident port.c 1.0.7 2000/10/11 Adaptec, Inc.";
14729+
14730+#include "osheaders.h"
14731+
14732+
14733+#include "AacGenericTypes.h"
14734+
14735+#include "aac_unix_defs.h"
14736+
14737+#include "fsatypes.h"
14738+#include "comstruc.h"
14739+#include "protocol.h"
14740+
14741+#include "fsaport.h"
14742+#include "fsaioctl.h"
14743+
14744+#include "pcisup.h"
14745+#include "port.h"
14746+
14747+int AfaPortPrinting = 1;
14748+
14749+extern AAC_STATUS AfaPort_Err_Adapter_Printf;
14750+extern AAC_STATUS AfaPort_Warn_Adapter_Printf;
14751+extern AAC_STATUS AfaPort_Info_Adapter_Printf;
14752+extern AAC_STATUS AfaPort_Err_FastAfa_Load_Driver;
14753+
14754+
14755+
14756+VOID
14757+AfaPortLogError(
14758+ IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
14759+ IN AAC_STATUS ErrorCode,
14760+ IN PUCHAR StringBuffer,
14761+ IN ULONG StringLength
14762+ )
14763+/*++
14764+
14765+Routine Description:
14766+
14767+ Does all of the work to log an error log entry
14768+Arguments:
14769+
14770+ CommonExtension - Pointer to the adapter that caused the error.
14771+
14772+ ErrorCode - Which error is being logged.
14773+
14774+ StringBuffer - Pointer to optional String for error log entry.
14775+
14776+ StringLength - Length of StringBuffer.
14777+
14778+Return Value:
14779+
14780+ Nothing
14781+
14782+--*/
14783+
14784+{
14785+
14786+}
14787+
14788+BOOLEAN
14789+AfaPortGetNextAdapterNumber(
14790+ IN PDRIVER_OBJECT DriverObject,
14791+ OUT PDEVICE_OBJECT *FsaDeviceObject,
14792+ OUT PFILE_OBJECT *FileObject,
14793+ OUT PULONG AdapterNumber
14794+ )
14795+{
14796+}
14797+BOOLEAN
14798+AfaPortAllocateAdapterCommArea(
14799+ IN PVOID Arg1,
14800+ IN OUT PVOID *CommHeaderAddress,
14801+ IN ULONG CommAreaSize,
14802+ IN ULONG CommAreaAlignment
14803+ )
14804+{
14805+ PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
14806+ PVOID BaseAddress;
14807+ PHYSICAL_ADDRESS PhysicalBaseAddress;
14808+ ULONG TotalSize, BytesToAlign;
14809+ size_t RealLength;
14810+ uint_t Count;
14811+// ULONG SizeOfFastIoComm = sizeof(FASTIO_STRUCT);
14812+// ULONG AdapterFibsSize = PAGE_SIZE;
14813+ ULONG AdapterFibsSize = 4096;
14814+ ULONG PrintfBufferSize = 256;
14815+ PADAPTER_INIT_STRUCT InitStruct;
14816+ extern int MiniPortRevision;
14817+ ULONG PhysAddress;
14818+
14819+// TotalSize = AdapterFibsSize + sizeof(ADAPTER_INIT_STRUCT) + CommAreaSize + CommAreaAlignment +
14820+// SizeOfFastIoComm + PrintfBufferSize;
14821+ TotalSize = AdapterFibsSize + sizeof(ADAPTER_INIT_STRUCT) + CommAreaSize + CommAreaAlignment +
14822+ PrintfBufferSize;
14823+
14824+
14825+ OsAllocCommPhysMem(CommonExtension->MiniPort, TotalSize, &BaseAddress, &PhysAddress);
14826+
14827+ CommonExtension->CommAddress = BaseAddress;
14828+ CommonExtension->CommPhysAddr = PhysAddress;
14829+ CommonExtension->CommSize = TotalSize;
14830+
14831+ PhysicalBaseAddress.HighPart = 0;
14832+ PhysicalBaseAddress.LowPart = PhysAddress;
14833+
14834+ CommonExtension->InitStruct = (PADAPTER_INIT_STRUCT)((PUCHAR)(BaseAddress) + AdapterFibsSize);
14835+ CommonExtension->PhysicalInitStruct = (PADAPTER_INIT_STRUCT)((PUCHAR)(PhysicalBaseAddress.LowPart) + AdapterFibsSize);
14836+
14837+ InitStruct = CommonExtension->InitStruct;
14838+
14839+ InitStruct->InitStructRevision = ADAPTER_INIT_STRUCT_REVISION;
14840+ InitStruct->MiniPortRevision = MiniPortRevision;
14841+ InitStruct->FilesystemRevision = CommonExtension->FilesystemRevision;
14842+
14843+ //
14844+ // Adapter Fibs are the first thing allocated so that they start page aligned
14845+ //
14846+ InitStruct->AdapterFibsVirtualAddress = BaseAddress;
14847+ InitStruct->AdapterFibsPhysicalAddress = (PVOID) PhysicalBaseAddress.LowPart;
14848+ InitStruct->AdapterFibsSize = AdapterFibsSize;
14849+ InitStruct->AdapterFibAlign = sizeof(FIB);
14850+
14851+ //
14852+ // Increment the base address by the amount already used
14853+ //
14854+ BaseAddress = (PVOID)((PUCHAR)(BaseAddress) + AdapterFibsSize + sizeof(ADAPTER_INIT_STRUCT));
14855+ PhysicalBaseAddress.LowPart = (ULONG)((PUCHAR)(PhysicalBaseAddress.LowPart) + AdapterFibsSize + sizeof(ADAPTER_INIT_STRUCT));
14856+
14857+ //
14858+ // Align the beginning of Headers to CommAreaAlignment
14859+ //
14860+ BytesToAlign = (CommAreaAlignment - ((ULONG)(BaseAddress) & (CommAreaAlignment - 1)));
14861+ BaseAddress = (PVOID)((PUCHAR)(BaseAddress) + BytesToAlign);
14862+ PhysicalBaseAddress.LowPart = (ULONG)((PUCHAR)(PhysicalBaseAddress.LowPart) + BytesToAlign);
14863+
14864+ //
14865+ // Fill in addresses of the Comm Area Headers and Queues
14866+ //
14867+ *CommHeaderAddress = BaseAddress;
14868+ InitStruct->CommHeaderAddress = (PVOID)PhysicalBaseAddress.LowPart;
14869+
14870+ //
14871+ // Increment the base address by the size of the CommArea
14872+ //
14873+ BaseAddress = (PVOID)((PUCHAR)(BaseAddress) + CommAreaSize);
14874+ PhysicalBaseAddress.LowPart = (ULONG)((PUCHAR)(PhysicalBaseAddress.LowPart) + CommAreaSize);
14875+
14876+
14877+ //
14878+ // Place the Printf buffer area after the Fast I/O comm area.
14879+ //
14880+ CommonExtension->PrintfBufferAddress = (PVOID)(BaseAddress);
14881+ InitStruct->PrintfBufferAddress = (PVOID)PhysicalBaseAddress.LowPart;
14882+ InitStruct->PrintfBufferSize = PrintfBufferSize;
14883+ bzero (BaseAddress, PrintfBufferSize);
14884+
14885+ AfaPortPrint("FsaAllocateAdapterCommArea: allocated a common buffer of 0x%x bytes from address 0x%x to address 0x%x\n",
14886+ TotalSize, InitStruct->AdapterFibsVirtualAddress,
14887+ (PUCHAR)(InitStruct->AdapterFibsVirtualAddress) + TotalSize);
14888+
14889+ AfaPortPrint("Mapped on to PCI address 0x%x\n", InitStruct->AdapterFibsPhysicalAddress);
14890+
14891+ return (TRUE);
14892+}
14893+
14894+AAC_STATUS
14895+AfaPortCreate (
14896+ IN PDEVICE_OBJECT DeviceObject,
14897+ IN PIRP Irp
14898+ )
14899+/*++
14900+
14901+Routine Description:
14902+
14903+ The routine will get called each time a user issues a CreateFile on the DeviceObject
14904+ for the adapter.
14905+
14906+ The main purpose of this routine is to set up any data structures that may be needed
14907+ to handle any requests made on this DeviceObject.
14908+
14909+Arguments:
14910+
14911+ DeviceObject - Pointer to device object representing adapter
14912+
14913+ Irp - Pointer to Irp that caused this open
14914+
14915+
14916+Return Value:
14917+
14918+ Status value returned from File system driver AdapterOpen
14919+
14920+--*/
14921+
14922+{
14923+}
14924+
14925+AAC_STATUS
14926+AfaPortClose (
14927+ IN PDEVICE_OBJECT DeviceObject,
14928+ IN PIRP Irp
14929+ )
14930+/*++
14931+
14932+Routine Description:
14933+
14934+ This routine will get called each time a user issues a CloseHandle on the DeviceObject
14935+ for the adapter.
14936+
14937+ The main purpose of this routine is to cleanup any data structures that have been set up
14938+ while this FileObject has been opened.
14939+
14940+Arguments:
14941+
14942+ DeviceObject - Pointer to device object representing adapter
14943+
14944+ Irp - Pointer to Irp that caused this close
14945+
14946+Return Value:
14947+
14948+ Status value returned from File system driver AdapterClose
14949+
14950+--*/
14951+
14952+{
14953+
14954+}
14955+
14956+AAC_STATUS
14957+AfaPortDeviceControl (
14958+ IN PDEVICE_OBJECT DeviceObject,
14959+ IN PIRP Irp
14960+ )
14961+{
14962+
14963+}
14964+
14965+ULONG
14966+AfaPortGetMaxPhysicalPage(
14967+ IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension
14968+ )
14969+/*++
14970+
14971+Routine Description:
14972+
14973+ This routine determines the max physical page in host memory.
14974+
14975+Arguments:
14976+
14977+ AdapterExtension
14978+
14979+Return Value:
14980+
14981+ Max physical page in host memory.
14982+
14983+--*/
14984+{
14985+
14986+}
14987+
14988+
14989diff -burN linux-2.4.9/drivers/scsi/aacraid/rx.c linux/drivers/scsi/aacraid/rx.c
14990--- linux-2.4.9/drivers/scsi/aacraid/rx.c Wed Dec 31 18:00:00 1969
14991+++ linux/drivers/scsi/aacraid/rx.c Thu Aug 16 13:41:30 2001
14992@@ -0,0 +1,917 @@
14993+/*++
14994+ * Adaptec aacraid device driver for Linux.
14995+ *
14996+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
14997+ *
14998+ * This program is free software; you can redistribute it and/or modify
14999+ * it under the terms of the GNU General Public License as published by
15000+ * the Free Software Foundation; either version 2, or (at your option)
15001+ * any later version.
15002+ *
15003+ * This program is distributed in the hope that it will be useful,
15004+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15005+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15006+ * GNU General Public License for more details.
15007+ *
15008+ * You should have received a copy of the GNU General Public License
15009+ * along with this program; see the file COPYING. If not, write to
15010+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
15011+ *
15012+ * Module Name:
15013+ * rx.c
15014+ *
15015+ * Abstract: Hardware miniport for Drawbridge specific hardware functions.
15016+ *
15017+ --*/
15018+
15019+static char *ident_rx = "aacraid_ident rx.c 1.0.7 2000/10/11 Adaptec, Inc.";
15020+
15021+#include "osheaders.h"
15022+
15023+
15024+#include "AacGenericTypes.h"
15025+
15026+#include "aac_unix_defs.h"
15027+
15028+#include "fsatypes.h"
15029+#include "comstruc.h"
15030+#include "fsact.h"
15031+#include "protocol.h"
15032+
15033+#define DEFINE_PCI_IDS
15034+#include "rxcommon.h"
15035+#include "monkerapi.h"
15036+
15037+#include "fsaport.h"
15038+#include "fsaioctl.h"
15039+
15040+#include "pcisup.h"
15041+#include "rx.h"
15042+
15043+#include "port.h"
15044+
15045+#define BugCheckFileId (FSAFS_BUG_CHECK_CYCLONESUP)
15046+
15047+// #define RxBugCheck(A,B,C) { KeBugCheckEx(0x00000AFA, __LINE__, (ULONG)A, (ULONG)B,(ULONG)C ); }
15048+
15049+#define RxBugCheck(A, B, C) { cmn_err(CE_PANIC, "aacdisk : line %s, 0x%x, 0x%x, 0x%x ", __LINE__, A, B, C); }
15050+
15051+#define NUM_TICKS_PER_SECOND (1000 * 1000 * 10) /* time is in 100 nanoseconds */
15052+
15053+
15054+//
15055+// The list of all the Rx adapter structures
15056+//
15057+
15058+PRx_ADAPTER_EXTENSION RxAdapterList;
15059+
15060+int
15061+RxInitDevice(
15062+ IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
15063+ IN ULONG AdapterNumber,
15064+ IN ULONG PciBus,
15065+ IN ULONG PciSlot
15066+);
15067+
15068+BOOLEAN
15069+RxSendSynchFib(
15070+ PVOID Arg1,
15071+ ULONG FibPhysicalAddress
15072+ );
15073+
15074+FSA_USER_VAR RxUserVars[] = {
15075+ { "AfaPortPrinting", (PULONG)&AfaPortPrinting, NULL },
15076+};
15077+
15078+
15079+//
15080+// Declare private use routines for this modual
15081+//
15082+
15083+u_int
15084+RxPciIsr (
15085+ IN PRx_ADAPTER_EXTENSION AdapterExtension
15086+ )
15087+
15088+/*++
15089+
15090+Routine Description:
15091+
15092+ The Isr routine for fsa Rx based adapter boards.
15093+
15094+Arguments:
15095+
15096+
15097+Return Value:
15098+
15099+ TRUE - if the interrupt was handled by this isr
15100+ FALSE - if the interrupt was not handled by this isr
15101+
15102+--*/
15103+
15104+{
15105+ ULONG DoorbellBits;
15106+ UCHAR InterruptStatus, Mask;
15107+ u_int OurInterrupt = INTR_UNCLAIMED;
15108+
15109+ //cmn_err(CE_WARN, "RxPciIsr entered\n");
15110+
15111+ InterruptStatus = Rx_READ_UCHAR(AdapterExtension, MUnit.OISR);
15112+
15113+ //
15114+ // Read mask and invert because drawbridge is reversed.
15115+ //
15116+ // This allows us to only service interrupts that have been enabled.
15117+ //
15118+
15119+ Mask = ~(Rx_READ_UCHAR(AdapterExtension, MUnit.OIMR));
15120+
15121+ // Check to see if this is our interrupt. If it isn't just return FALSE.
15122+
15123+
15124+ if (InterruptStatus & Mask) {
15125+
15126+ DoorbellBits = Rx_READ_ULONG(AdapterExtension, OutboundDoorbellReg);
15127+
15128+ OurInterrupt = INTR_CLAIMED;
15129+
15130+ if (DoorbellBits & DoorBellPrintfReady) {
15131+
15132+ ULONG Length, Level;
15133+ unsigned char *cp;
15134+
15135+ cp = AdapterExtension->Common->PrintfBufferAddress;
15136+
15137+ //
15138+ // The size of the Printfbuffer is set in port.c
15139+ // There is no variable or define for it
15140+ //
15141+ if (Length > 255)
15142+ Length = 255;
15143+
15144+ if (cp[Length] != 0) {
15145+ // cmn_err (CE_NOTE, "byte %d is 0x%x, should be 0", Length, cp[Length]);
15146+ cp[Length] = 0;
15147+ }
15148+
15149+ if (Level == LOG_HIGH_ERROR)
15150+ cmn_err (CE_WARN, "%s:%s", OsGetDeviceName(AdapterExtension), AdapterExtension->Common->PrintfBufferAddress);
15151+ else
15152+ cmn_err (CE_NOTE, "%s:%s", OsGetDeviceName(AdapterExtension), AdapterExtension->Common->PrintfBufferAddress);
15153+
15154+ bzero (AdapterExtension->Common->PrintfBufferAddress, 256);
15155+
15156+ Rx_WRITE_ULONG(AdapterExtension, MUnit.ODR,DoorBellPrintfReady); //clear PrintfReady
15157+
15158+ Rx_WRITE_ULONG(AdapterExtension, InboundDoorbellReg,DoorBellPrintfDone);
15159+
15160+
15161+ } else if (DoorbellBits & DoorBellAdapterNormCmdReady) { // Adapter -> Host Normal Command Ready
15162+
15163+ AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, HostNormCmdQue);
15164+ Rx_WRITE_ULONG(AdapterExtension, MUnit.ODR, DoorBellAdapterNormCmdReady);
15165+
15166+ } else if (DoorbellBits & DoorBellAdapterNormRespReady) { // Adapter -> Host Normal Response Ready
15167+
15168+ AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, HostNormRespQue);
15169+ Rx_WRITE_ULONG(AdapterExtension, MUnit.ODR,DoorBellAdapterNormRespReady);
15170+
15171+ } else if (DoorbellBits & DoorBellAdapterNormCmdNotFull) { // Adapter -> Host Normal Command Not Full
15172+
15173+ AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, AdapNormCmdNotFull);
15174+ Rx_WRITE_ULONG(AdapterExtension, MUnit.ODR, DoorBellAdapterNormCmdNotFull);
15175+
15176+ } else if (DoorbellBits & DoorBellAdapterNormRespNotFull) { // Adapter -> Host Normal Response Not Full
15177+
15178+ AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, AdapNormRespNotFull);
15179+ Rx_WRITE_ULONG(AdapterExtension, MUnit.ODR, DoorBellAdapterNormRespNotFull);
15180+
15181+ }
15182+
15183+ }
15184+ return(OurInterrupt);
15185+}
15186+
15187+VOID
15188+RxEnableInterrupt(
15189+ PVOID Arg1,
15190+ ADAPTER_EVENT AdapterEvent,
15191+ BOOLEAN AtDeviceIrq
15192+ )
15193+/*++
15194+
15195+Routine Description:
15196+
15197+ This routine will enable the corresponding adapter event to cause an interrupt on
15198+ the host.
15199+
15200+Arguments:
15201+
15202+ AdapterExtension - Which adapter to enable.
15203+
15204+ AdapterEvent - Which adapter event.
15205+
15206+ AtDeviceIrq - Whether the system is in DEVICE irql
15207+
15208+Return Value:
15209+
15210+ Nothing.
15211+
15212+--*/
15213+{
15214+ PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
15215+ PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) CommonExtension->MiniPort;
15216+
15217+ //cmn_err(CE_WARN, "RxEnableInterrupt");
15218+ switch (AdapterEvent) {
15219+
15220+ case HostNormCmdQue:
15221+
15222+ AdapterExtension->LocalMaskInterruptControl &= ~(OUTBOUNDDOORBELL_1);
15223+
15224+ break;
15225+
15226+ case HostNormRespQue:
15227+
15228+ AdapterExtension->LocalMaskInterruptControl &= ~(OUTBOUNDDOORBELL_2);
15229+
15230+ break;
15231+
15232+ case AdapNormCmdNotFull:
15233+
15234+ AdapterExtension->LocalMaskInterruptControl &= ~(OUTBOUNDDOORBELL_3);
15235+
15236+ break;
15237+
15238+ case AdapNormRespNotFull:
15239+
15240+ AdapterExtension->LocalMaskInterruptControl &= ~(OUTBOUNDDOORBELL_4);
15241+
15242+ break;
15243+
15244+ }
15245+
15246+}
15247+
15248+VOID
15249+RxDisableInterrupt(
15250+ PVOID Arg1,
15251+ ADAPTER_EVENT AdapterEvent,
15252+ BOOLEAN AtDeviceIrq
15253+ )
15254+/*++
15255+
15256+Routine Description:
15257+
15258+ This routine will disable the corresponding adapter event to cause an interrupt on
15259+ the host.
15260+
15261+Arguments:
15262+
15263+ AdapterExtension - Which adapter to enable.
15264+
15265+ AdapterEvent - Which adapter event.
15266+
15267+ AtDeviceIrq - Whether the system is in DEVICE irql
15268+
15269+Return Value:
15270+
15271+ Nothing.
15272+
15273+--*/
15274+{
15275+ PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
15276+ PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) CommonExtension->MiniPort;
15277+
15278+ //cmn_err(CE_WARN, "RxEnableInterrupt");
15279+
15280+ switch (AdapterEvent) {
15281+
15282+
15283+ case HostNormCmdQue:
15284+
15285+ AdapterExtension->LocalMaskInterruptControl |= (OUTBOUNDDOORBELL_1);
15286+
15287+ break;
15288+
15289+ case HostNormRespQue:
15290+
15291+ AdapterExtension->LocalMaskInterruptControl |= (OUTBOUNDDOORBELL_2);
15292+
15293+ break;
15294+
15295+ case AdapNormCmdNotFull:
15296+
15297+ AdapterExtension->LocalMaskInterruptControl |= (OUTBOUNDDOORBELL_3);
15298+
15299+ break;
15300+
15301+
15302+ case AdapNormRespNotFull:
15303+
15304+ AdapterExtension->LocalMaskInterruptControl |= (OUTBOUNDDOORBELL_4);
15305+
15306+ break;
15307+
15308+ }
15309+
15310+}
15311+
15312+
15313+
15314+RxDetachDevice(
15315+ IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension
15316+ )
15317+{
15318+ PRx_ADAPTER_EXTENSION AdapterExtension = CommonExtension->MiniPort;
15319+
15320+ //
15321+ // Free the register mapping.
15322+ //
15323+
15324+ OsDetachDevice( AdapterExtension);
15325+
15326+ OsFreeMemory( AdapterExtension, sizeof(Rx_ADAPTER_EXTENSION) );
15327+
15328+}
15329+
15330+int
15331+RxInitDevice(
15332+ IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
15333+ IN ULONG AdapterNumber,
15334+ IN ULONG PciBus,
15335+ IN ULONG PciSlot
15336+)
15337+
15338+/*++
15339+
15340+Routine Description:
15341+
15342+ Scans the PCI bus looking for the Rx card. When found all resources for the
15343+ device will be allocated and the interrupt vectors and csrs will be allocated and
15344+ mapped.
15345+
15346+ The device_interface in the commregion will be allocated and linked to the comm region.
15347+
15348+Arguments:
15349+
15350+
15351+Return Value:
15352+
15353+ TRUE - if the device was setup with not problems
15354+ FALSE - if the device could not be mapped and init successfully
15355+
15356+--*/
15357+
15358+{
15359+ AAC_STATUS Status;
15360+ PRx_ADAPTER_EXTENSION AdapterExtension = NULL;
15361+ FSA_NEW_ADAPTER NewAdapter;
15362+ ULONG StartTime, EndTime, WaitTime;
15363+ ULONG InitStatus;
15364+ int instance;
15365+ int nIntrs;
15366+ char * name;
15367+
15368+ AfaPortPrint("In init device.\n");
15369+
15370+ //cmn_err(CE_WARN, "In RxInitDevice");
15371+
15372+// AdapterExtension->Common->AdapterIndex = AdapterIndex;
15373+ CommonExtension->AdapterNumber = AdapterNumber;
15374+
15375+
15376+ CommonExtension->PciBusNumber = PciBus;
15377+ CommonExtension->PciSlotNumber = PciSlot;
15378+
15379+
15380+ AdapterExtension = OsAllocMemory( sizeof(Rx_ADAPTER_EXTENSION), OS_ALLOC_MEM_SLEEP );
15381+ AdapterExtension->Common = CommonExtension;
15382+ CommonExtension->MiniPort = AdapterExtension;
15383+
15384+ instance = OsGetDeviceInstance(AdapterExtension);
15385+ name = OsGetDeviceName(AdapterExtension);
15386+ //
15387+ // Map in the registers from the adapter, register space 0 is config space,
15388+ // register space 1 is the memery space.
15389+ //
15390+
15391+ if (OsMapDeviceRegisters(AdapterExtension)) {
15392+
15393+ cmn_err(CE_CONT, "%s%d: can't map device registers\n",
15394+ OsGetDeviceName(AdapterExtension), instance);
15395+ return(FAILURE);
15396+ }
15397+
15398+ //
15399+ // Check to see if the board failed any self tests.
15400+ //
15401+
15402+ if (Rx_READ_ULONG( AdapterExtension, IndexRegs.Mailbox[7]) & SELF_TEST_FAILED) {
15403+
15404+ cmn_err(CE_CONT, "%s%d: adapter self-test failed\n",
15405+ OsGetDeviceName(AdapterExtension), instance);
15406+ return(FAILURE);
15407+
15408+ }
15409+ //cmn_err(CE_WARN, "RxInitDevice: %s%d: adapter passwd self-test\n",
15410+ // OsGetDeviceName(AdapterExtension), instance);
15411+
15412+ //
15413+ // Check to see if the board panic'd while booting.
15414+ //
15415+
15416+ if (Rx_READ_ULONG( AdapterExtension, IndexRegs.Mailbox[7]) & KERNEL_PANIC) {
15417+
15418+ cmn_err(CE_CONT, "%s%d: adapter kernel panic'd\n",
15419+ OsGetDeviceName(AdapterExtension), instance);
15420+ return(FAILURE);
15421+
15422+ }
15423+
15424+ StartTime = OsGetSeconds();
15425+ WaitTime = 0;
15426+
15427+
15428+ //
15429+ // Wait for the adapter to be up and running. Wait up until 3 minutes.
15430+ //
15431+
15432+ while (!(Rx_READ_ULONG( AdapterExtension, IndexRegs.Mailbox[7]) & KERNEL_UP_AND_RUNNING)) {
15433+
15434+ EndTime = OsGetSeconds();
15435+
15436+ WaitTime = EndTime - StartTime;
15437+
15438+ if ( WaitTime > (3 * 10) ) {
15439+
15440+ InitStatus = Rx_READ_ULONG( AdapterExtension, IndexRegs.Mailbox[7]) >> 16;
15441+
15442+ cmn_err(CE_CONT, "%s%d: adapter kernel failed to start, init status = %d\n",
15443+ OsGetDeviceName(AdapterExtension), instance, InitStatus);
15444+ return(FAILURE);
15445+
15446+ }
15447+ }
15448+
15449+ if (OsAttachInterrupt(AdapterExtension,RxISR)) {
15450+ cmn_err(CE_WARN, "%s%d RxInitDevice: failed OsAttachIntterupt", name, instance);
15451+ return(FAILURE);
15452+ }
15453+
15454+
15455+ if (OsAttachDMA(AdapterExtension)) {
15456+ cmn_err(CE_WARN, "%s%d SaInitDevice: failed OsAttachDMA", name, instance);
15457+ return(FAILURE);
15458+ }
15459+
15460+ //
15461+ // Fill in the function dispatch table.
15462+ //
15463+
15464+ AdapterExtension->Common->AdapterFuncs.SizeOfFsaPortFuncs = sizeof(FSAPORT_FUNCS);
15465+ AdapterExtension->Common->AdapterFuncs.AllocateAdapterCommArea = AfaPortAllocateAdapterCommArea;
15466+ AdapterExtension->Common->AdapterFuncs.FreeAdapterCommArea = AfaPortFreeAdapterCommArea;
15467+ AdapterExtension->Common->AdapterFuncs.BuildSgMap = AfaPortBuildSgMap;
15468+ AdapterExtension->Common->AdapterFuncs.FreeDmaResources = AfaPortFreeDmaResources;
15469+ AdapterExtension->Common->AdapterFuncs.AllocateAndMapFibSpace = AfaPortAllocateAndMapFibSpace;
15470+ AdapterExtension->Common->AdapterFuncs.UnmapAndFreeFibSpace = AfaPortUnmapAndFreeFibSpace;
15471+ AdapterExtension->Common->AdapterFuncs.InterruptAdapter = RxInterruptAdapter;
15472+ AdapterExtension->Common->AdapterFuncs.EnableInterrupt = RxEnableInterrupt;
15473+ AdapterExtension->Common->AdapterFuncs.DisableInterrupt = RxDisableInterrupt;
15474+ AdapterExtension->Common->AdapterFuncs.NotifyAdapter = RxNotifyAdapter;
15475+ AdapterExtension->Common->AdapterFuncs.ResetDevice = RxResetDevice;
15476+ AdapterExtension->Common->AdapterFuncs.InterruptHost = NULL;
15477+
15478+ AdapterExtension->Common->AdapterFuncs.SendSynchFib = RxSendSynchFib;
15479+
15480+ NewAdapter.AdapterExtension = CommonExtension;
15481+ NewAdapter.AdapterFuncs = &AdapterExtension->Common->AdapterFuncs;
15482+ NewAdapter.AdapterInterruptsBelowDpc = FALSE;
15483+ NewAdapter.AdapterUserVars = RxUserVars;
15484+ NewAdapter.AdapterUserVarsSize = sizeof(RxUserVars) / sizeof(FSA_USER_VAR);
15485+
15486+ NewAdapter.Dip = CommonExtension->OsDep.dip;
15487+
15488+
15489+ if (AfaCommInitNewAdapter( &NewAdapter ) == NULL) {
15490+
15491+ cmn_err(CE_WARN, "AfaCommInitNewAdapter failed\n");
15492+ return (FAILURE);
15493+ }
15494+
15495+
15496+ AdapterExtension->Common->Adapter = NewAdapter.Adapter;
15497+
15498+ if (AdapterExtension->Common->Adapter == NULL) {
15499+
15500+ AfaPortLogError(AdapterExtension->Common, FAILURE, NULL, 0);
15501+ cmn_err(CE_WARN, "%s%d RxInitDevice: No Adapter pointer", name, instance);
15502+
15503+
15504+ return (FAILURE);
15505+ }
15506+
15507+
15508+ //
15509+ // Start any kernel threads needed
15510+ //
15511+ OsStartKernelThreads(AdapterExtension);
15512+
15513+ //
15514+ // Tell the adapter that all is configure, and it can start accepting requests
15515+ //
15516+
15517+ RxStartAdapter(AdapterExtension);
15518+
15519+
15520+#ifdef AACDISK
15521+#endif
15522+
15523+
15524+ //
15525+ // Put this adapter into the list of Rx adapters
15526+ //
15527+
15528+ AdapterExtension->Next = RxAdapterList;
15529+ RxAdapterList = AdapterExtension;
15530+
15531+ AdapterExtension->Common->AdapterConfigured = TRUE;
15532+
15533+
15534+#ifdef AACDISK
15535+ //
15536+ // Call the disk layer to initialize itself.
15537+ //
15538+
15539+ AfaDiskInitNewAdapter( AdapterExtension->Common->AdapterNumber, AdapterExtension->Common->Adapter );
15540+#endif
15541+
15542+
15543+init_done:
15544+
15545+ AdapterExtension->Common->AdapterPrintfsToScreen = FALSE;
15546+
15547+
15548+
15549+ OsAttachHBA(AdapterExtension);
15550+
15551+ return(0);
15552+}
15553+
15554+VOID
15555+RxStartAdapter(
15556+ PRx_ADAPTER_EXTENSION AdapterExtension
15557+ )
15558+{
15559+ ULONG ReturnStatus;
15560+ LARGE_INTEGER HostTime;
15561+ ULONG ElapsedSeconds;
15562+ PADAPTER_INIT_STRUCT InitStruct;
15563+
15564+ //cmn_err(CE_WARN, "RxStartAdapter");
15565+ //
15566+ // Fill in the remaining pieces of the InitStruct.
15567+ //
15568+
15569+ InitStruct = AdapterExtension->Common->InitStruct;
15570+
15571+ InitStruct->HostPhysMemPages = AfaPortGetMaxPhysicalPage(AdapterExtension->Common);
15572+
15573+ ElapsedSeconds = OsGetSeconds();
15574+
15575+ InitStruct->HostElapsedSeconds = ElapsedSeconds;
15576+
15577+ //
15578+ // Tell the adapter we are back and up and running so it will scan its command
15579+ // queues and enable our interrupts
15580+ //
15581+
15582+ AdapterExtension->LocalMaskInterruptControl =
15583+ (DoorBellPrintfReady | OUTBOUNDDOORBELL_1 | OUTBOUNDDOORBELL_2 | OUTBOUNDDOORBELL_3 | OUTBOUNDDOORBELL_4);
15584+
15585+ //
15586+ // First clear out all interrupts. Then enable the one's that we can handle.
15587+ //
15588+
15589+ Rx_WRITE_UCHAR( AdapterExtension, MUnit.OIMR, 0xff);
15590+ Rx_WRITE_ULONG( AdapterExtension, MUnit.ODR, 0xffffffff);
15591+// Rx_WRITE_UCHAR(AdapterExtension, MUnit.OIMR, ~(UCHAR)OUTBOUND_DOORBELL_INTERRUPT_MASK);
15592+ Rx_WRITE_UCHAR( AdapterExtension, MUnit.OIMR, 0xfb);
15593+
15594+ RxSendSynchCommand(AdapterExtension,
15595+ INIT_STRUCT_BASE_ADDRESS,
15596+ (ULONG) AdapterExtension->Common->PhysicalInitStruct,
15597+ 0,
15598+ 0,
15599+ 0,
15600+ &ReturnStatus);
15601+
15602+}
15603+
15604+
15605+VOID
15606+RxResetDevice(
15607+ PVOID Arg1
15608+ )
15609+
15610+{
15611+}
15612+
15613+VOID
15614+RxInterruptAdapter(
15615+ PVOID Arg1
15616+ )
15617+/*++
15618+
15619+Routine Description:
15620+
15621+ The will cause the adapter to take a break point.
15622+
15623+Arguments:
15624+
15625+ None
15626+
15627+Return Value:
15628+
15629+ Nothing
15630+
15631+--*/
15632+{
15633+ PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
15634+ PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) CommonExtension->MiniPort;
15635+
15636+ ULONG ReturnStatus;
15637+
15638+ RxSendSynchCommand(AdapterExtension,
15639+ BREAKPOINT_REQUEST,
15640+ 0,
15641+ 0,
15642+ 0,
15643+ 0,
15644+ &ReturnStatus);
15645+
15646+}
15647+
15648+VOID
15649+RxNotifyAdapter(
15650+ PVOID Arg1,
15651+ IN HOST_2_ADAP_EVENT AdapterEvent
15652+ )
15653+/*++
15654+
15655+Routine Description:
15656+
15657+ Will read the adapter CSRs to find the reason the adapter has
15658+ interrupted us.
15659+
15660+Arguments:
15661+
15662+ AdapterEvent - Enumerated type the returns the reason why we were interrutped.
15663+
15664+Return Value:
15665+
15666+ Nothing
15667+
15668+--*/
15669+{
15670+ PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
15671+ PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) CommonExtension->MiniPort;
15672+ ULONG ReturnStatus;
15673+
15674+ //cmn_err(CE_WARN, "RxNotifyAdapter %d", AdapterEvent);
15675+
15676+ switch (AdapterEvent) {
15677+ case AdapNormCmdQue:
15678+
15679+ Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_1);
15680+ break;
15681+
15682+ case HostNormRespNotFull:
15683+
15684+ Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_4);
15685+ break;
15686+
15687+ case AdapNormRespQue:
15688+
15689+ Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_2);
15690+ break;
15691+
15692+ case HostNormCmdNotFull:
15693+
15694+ Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_3);
15695+ break;
15696+
15697+ case HostShutdown:
15698+
15699+// RxSendSynchCommand(AdapterExtension, HOST_CRASHING, 0, 0, 0, 0, &ReturnStatus);
15700+
15701+ break;
15702+
15703+ case FastIo:
15704+ Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_6);
15705+ break;
15706+
15707+ case AdapPrintfDone:
15708+ Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_5);
15709+ break;
15710+
15711+ default:
15712+
15713+ RxBugCheck(0,0,0);
15714+ AfaPortPrint("Notify requested with an invalid request 0x%x.\n",AdapterEvent);
15715+ break;
15716+ }
15717+}
15718+
15719+AAC_STATUS
15720+RxSendSynchCommand(
15721+ PVOID Arg1,
15722+ ULONG Command,
15723+ ULONG Parameter1,
15724+ ULONG Parameter2,
15725+ ULONG Parameter3,
15726+ ULONG Parameter4,
15727+ PULONG ReturnStatus
15728+ )
15729+/*++
15730+
15731+Routine Description:
15732+
15733+ This routine will send a synchronous comamnd to the adapter and wait for its
15734+ completion.
15735+
15736+Arguments:
15737+
15738+ AdapterExtension - Pointer to adapter extension structure.
15739+ Command - Which command to send
15740+ Parameter1 - 4 - Parameters for command
15741+ ReturnStatus - return status from adapter after completion of command
15742+
15743+
15744+Return Value:
15745+
15746+ AAC_STATUS
15747+
15748+--*/
15749+{
15750+ PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) Arg1;
15751+ ULONG StartTime,EndTime,WaitTime;
15752+ BOOLEAN CommandSucceeded;
15753+
15754+ //cmn_err(CE_WARN, "RxSendSyncCommand");
15755+ //
15756+ // Write the Command into Mailbox 0
15757+ //
15758+
15759+ Rx_WRITE_ULONG( AdapterExtension, InboundMailbox0, Command);
15760+
15761+ //
15762+ // Write the parameters into Mailboxes 1 - 4
15763+ //
15764+
15765+ Rx_WRITE_ULONG( AdapterExtension, InboundMailbox1, Parameter1);
15766+ Rx_WRITE_ULONG( AdapterExtension, InboundMailbox2, Parameter2);
15767+ Rx_WRITE_ULONG( AdapterExtension, InboundMailbox3, Parameter3);
15768+ Rx_WRITE_ULONG( AdapterExtension, InboundMailbox4, Parameter4);
15769+
15770+ //
15771+ // Clear the synch command doorbell to start on a clean slate.
15772+ //
15773+
15774+ Rx_WRITE_ULONG( AdapterExtension, OutboundDoorbellReg, OUTBOUNDDOORBELL_0);
15775+
15776+ //
15777+ // disable doorbell interrupts
15778+ //
15779+
15780+ Rx_WRITE_UCHAR( AdapterExtension, MUnit.OIMR,
15781+ Rx_READ_UCHAR(AdapterExtension, MUnit.OIMR) | 0x04);
15782+
15783+ //
15784+ // force the completion of the mask register write before issuing the interrupt.
15785+ //
15786+
15787+ Rx_READ_UCHAR ( AdapterExtension, MUnit.OIMR);
15788+
15789+ //
15790+ // Signal that there is a new synch command
15791+ //
15792+
15793+ Rx_WRITE_ULONG( AdapterExtension, InboundDoorbellReg, INBOUNDDOORBELL_0);
15794+
15795+ CommandSucceeded = FALSE;
15796+
15797+ StartTime = OsGetSeconds();
15798+ WaitTime = 0;
15799+
15800+ while (WaitTime < 30) { // wait up to 30 seconds
15801+
15802+ drv_usecwait(5); // delay 5 microseconds to let Mon960 get info.
15803+
15804+ //
15805+ // Mon110 will set doorbell0 bit when it has completed the command.
15806+ //
15807+
15808+ if (Rx_READ_ULONG(AdapterExtension, OutboundDoorbellReg) & OUTBOUNDDOORBELL_0) {
15809+
15810+ //
15811+ // clear the doorbell.
15812+ //
15813+
15814+ Rx_WRITE_ULONG(AdapterExtension, OutboundDoorbellReg, OUTBOUNDDOORBELL_0);
15815+
15816+ CommandSucceeded = TRUE;
15817+ break;
15818+ }
15819+
15820+ EndTime = OsGetSeconds();
15821+ WaitTime = EndTime - StartTime;
15822+
15823+ }
15824+
15825+ if (CommandSucceeded != TRUE) {
15826+
15827+ //
15828+ // restore interrupt mask even though we timed out
15829+ //
15830+
15831+ Rx_WRITE_UCHAR(AdapterExtension, MUnit.OIMR,
15832+ Rx_READ_ULONG(AdapterExtension, MUnit.OIMR) & 0xfb);
15833+
15834+ return (STATUS_IO_TIMEOUT);
15835+
15836+ }
15837+
15838+ //
15839+ // Pull the synch status from Mailbox 0.
15840+ //
15841+
15842+ *ReturnStatus = Rx_READ_ULONG(AdapterExtension, IndexRegs.Mailbox[0]);
15843+
15844+ //
15845+ // Clear the synch command doorbell.
15846+ //
15847+
15848+ Rx_WRITE_ULONG(AdapterExtension, OutboundDoorbellReg, OUTBOUNDDOORBELL_0);
15849+
15850+ //
15851+ // restore interrupt mask
15852+ //
15853+
15854+ Rx_WRITE_UCHAR(AdapterExtension, MUnit.OIMR,
15855+ Rx_READ_ULONG(AdapterExtension, MUnit.OIMR) & 0xfb);
15856+
15857+ //
15858+ // Return SUCCESS
15859+ //
15860+
15861+ return (STATUS_SUCCESS);
15862+
15863+}
15864+
15865+BOOLEAN
15866+RxSendSynchFib(
15867+ PVOID Arg1,
15868+ ULONG FibPhysicalAddress
15869+ )
15870+/*++
15871+
15872+Routine Description:
15873+
15874+ This routine will send a synchronous fib to the adapter and wait for its
15875+ completion.
15876+
15877+Arguments:
15878+
15879+ AdapterExtension - Pointer to adapter extension structure.
15880+ FibPhysicalAddress - Physical address of fib to send.
15881+
15882+
15883+Return Value:
15884+
15885+ BOOLEAN
15886+
15887+--*/
15888+{
15889+ PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
15890+ PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) CommonExtension->MiniPort;
15891+ ULONG returnStatus;
15892+
15893+ if (RxSendSynchCommand( AdapterExtension,
15894+ SEND_SYNCHRONOUS_FIB,
15895+ FibPhysicalAddress,
15896+ 0,
15897+ 0,
15898+ 0,
15899+ &returnStatus ) != STATUS_SUCCESS ) {
15900+
15901+ return (FALSE);
15902+
15903+ }
15904+
15905+ return (TRUE);
15906+
15907+}
15908+
15909+
15910diff -burN linux-2.4.9/drivers/scsi/aacraid/sap1sup.c linux/drivers/scsi/aacraid/sap1sup.c
15911--- linux-2.4.9/drivers/scsi/aacraid/sap1sup.c Wed Dec 31 18:00:00 1969
15912+++ linux/drivers/scsi/aacraid/sap1sup.c Thu Aug 16 13:41:30 2001
15913@@ -0,0 +1,859 @@
15914+/*++
15915+ * Adaptec aacraid device driver for Linux.
15916+ *
15917+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
15918+ *
15919+ * This program is free software; you can redistribute it and/or modify
15920+ * it under the terms of the GNU General Public License as published by
15921+ * the Free Software Foundation; either version 2, or (at your option)
15922+ * any later version.
15923+ *
15924+ * This program is distributed in the hope that it will be useful,
15925+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15926+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15927+ * GNU General Public License for more details.
15928+ *
15929+ * You should have received a copy of the GNU General Public License
15930+ * along with this program; see the file COPYING. If not, write to
15931+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
15932+ *
15933+ * Module Name:
15934+ * sap1sup.c
15935+ *
15936+ * Abstract: Drawbridge specific support functions
15937+ *
15938+ --*/
15939+
15940+static char *ident_sap1 = "aacraid_ident sap1sup.c 1.0.7 2000/10/11 Adaptec, Inc.";
15941+
15942+#include "osheaders.h"
15943+
15944+
15945+#include "AacGenericTypes.h"
15946+
15947+#include "aac_unix_defs.h"
15948+
15949+#include "fsatypes.h"
15950+#include "comstruc.h"
15951+#include "fsact.h"
15952+#include "protocol.h"
15953+
15954+#define DEFINE_PCI_IDS
15955+#include "sap1common.h"
15956+#include "monkerapi.h"
15957+
15958+#include "fsaport.h"
15959+#include "fsaioctl.h"
15960+
15961+
15962+#include "pcisup.h"
15963+#include "sap1.h"
15964+
15965+#include "port.h"
15966+
15967+#include "nodetype.h"
15968+#include "comsup.h"
15969+#include "afacomm.h"
15970+#include "adapter.h"
15971+
15972+#define BugCheckFileId (FSAFS_BUG_CHECK_CYCLONESUP)
15973+
15974+// #define SaBugCheck(A,B,C) { KeBugCheckEx(0x00000AFA, __LINE__, (ULONG)A, (ULONG)B,(ULONG)C ); }
15975+
15976+#define SaBugCheck(A, B, C) { cmn_err(CE_PANIC, "aacdisk : line %s, 0x%x, 0x%x, 0x%x ", __LINE__, A, B, C); }
15977+
15978+#define NUM_TICKS_PER_SECOND (1000 * 1000 * 10) /* time is in 100 nanoseconds */
15979+
15980+int MiniPortRevision = Sa_MINIPORT_REVISION;
15981+
15982+
15983+//
15984+// The list of all the Sa adapter structures
15985+//
15986+
15987+PSa_ADAPTER_EXTENSION SaAdapterList;
15988+
15989+int
15990+SaInitDevice(
15991+ IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
15992+ IN ULONG AdapterNumber,
15993+ IN ULONG PciBus,
15994+ IN ULONG PciSlot
15995+);
15996+
15997+BOOLEAN
15998+SaSendSynchFib(
15999+ PVOID Arg1,
16000+ ULONG FibPhysicalAddress
16001+ );
16002+
16003+FSA_USER_VAR SaUserVars[] = {
16004+ { "AfaPortPrinting", (PULONG)&AfaPortPrinting, NULL },
16005+};
16006+
16007+
16008+//
16009+// Declare private use routines for this modual
16010+//
16011+
16012+
16013+/*++
16014+
16015+Routine Description:
16016+
16017+ The Isr routine for fsa Sa based adapter boards.
16018+
16019+Arguments:
16020+
16021+
16022+Return Value:
16023+
16024+ TRUE - if the interrupt was handled by this isr
16025+ FALSE - if the interrupt was not handled by this isr
16026+
16027+--*/
16028+u_int
16029+SaPciIsr (IN PSa_ADAPTER_EXTENSION AdapterExtension)
16030+{
16031+ USHORT InterruptStatus, Mask;
16032+ u_int OurInterrupt = INTR_UNCLAIMED;
16033+
16034+ InterruptStatus = Sa_READ_USHORT( AdapterExtension, DoorbellReg_p);
16035+
16036+ //
16037+ // Read mask and invert because drawbridge is reversed.
16038+ //
16039+ // This allows us to only service interrupts that have been enabled.
16040+ //
16041+
16042+ Mask = ~(Sa_READ_USHORT( AdapterExtension, SaDbCSR.PRISETIRQMASK));
16043+
16044+ // Check to see if this is our interrupt. If it isn't just return FALSE.
16045+
16046+
16047+ if (InterruptStatus & Mask) {
16048+
16049+ OurInterrupt = INTR_CLAIMED;
16050+
16051+ if (InterruptStatus & PrintfReady) {
16052+
16053+ ULONG Length, Level;
16054+ unsigned char *cp;
16055+
16056+ cp = AdapterExtension->Common->PrintfBufferAddress;
16057+
16058+ //
16059+ // The size of the Printbuffer is set in port.c
16060+ // There is no variable or define for it
16061+ //
16062+ if (Length > 255)
16063+ Length = 255;
16064+
16065+ if (cp[Length] != 0) {
16066+ // cmn_err (CE_NOTE, "byte %d is 0x%x, should be 0", Length, cp[Length]);
16067+ cp[Length] = 0;
16068+ }
16069+
16070+ if (Level == LOG_HIGH_ERROR)
16071+ cmn_err (CE_WARN, "%s:%s", OsGetDeviceName(AdapterExtension), AdapterExtension->Common->PrintfBufferAddress);
16072+ else
16073+ cmn_err (CE_NOTE, "%s:%s", OsGetDeviceName(AdapterExtension), AdapterExtension->Common->PrintfBufferAddress);
16074+
16075+ bzero (AdapterExtension->Common->PrintfBufferAddress, 256);
16076+
16077+ Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p,PrintfReady); //clear PrintfReady
16078+
16079+ Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,PrintfDone);
16080+
16081+ } else if (InterruptStatus & DOORBELL_1) { // Adapter -> Host Normal Command Ready
16082+
16083+ AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, HostNormCmdQue);
16084+ Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p, DOORBELL_1);
16085+
16086+ } else if (InterruptStatus & DOORBELL_2) { // Adapter -> Host Normal Response Ready
16087+
16088+ AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, HostNormRespQue);
16089+ Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p,DOORBELL_2);
16090+
16091+ } else if (InterruptStatus & DOORBELL_3) { // Adapter -> Host Normal Command Not Full
16092+
16093+ AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, AdapNormCmdNotFull);
16094+ Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p, DOORBELL_3);
16095+
16096+ } else if (InterruptStatus & DOORBELL_4) { // Adapter -> Host Normal Response Not Full
16097+
16098+ AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, AdapNormRespNotFull);
16099+ Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p, DOORBELL_4);
16100+
16101+ }
16102+
16103+ }
16104+ return(OurInterrupt);
16105+}
16106+
16107+
16108+/*++
16109+
16110+Routine Description:
16111+
16112+ This routine will enable the corresponding adapter event to cause an interrupt on
16113+ the host.
16114+
16115+Arguments:
16116+
16117+ AdapterExtension - Which adapter to enable.
16118+
16119+ AdapterEvent - Which adapter event.
16120+
16121+ AtDeviceIrq - Whether the system is in DEVICE irql
16122+
16123+Return Value:
16124+
16125+ Nothing.
16126+
16127+--*/
16128+VOID
16129+SaEnableInterrupt (PVOID Arg1, ADAPTER_EVENT AdapterEvent, BOOLEAN AtDeviceIrq)
16130+{
16131+ PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
16132+ PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) CommonExtension->MiniPort;
16133+
16134+ switch (AdapterEvent) {
16135+
16136+ case HostNormCmdQue:
16137+
16138+ Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRICLEARIRQMASK, DOORBELL_1 );
16139+
16140+ break;
16141+
16142+ case HostNormRespQue:
16143+
16144+ Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRICLEARIRQMASK, DOORBELL_2 );
16145+
16146+ break;
16147+
16148+ case AdapNormCmdNotFull:
16149+
16150+ Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRICLEARIRQMASK, DOORBELL_3 );
16151+
16152+ break;
16153+
16154+ case AdapNormRespNotFull:
16155+
16156+ Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRICLEARIRQMASK, DOORBELL_4 );
16157+
16158+ break;
16159+
16160+ }
16161+
16162+}
16163+
16164+
16165+
16166+/*++
16167+
16168+Routine Description:
16169+
16170+ This routine will disable the corresponding adapter event to cause an interrupt on
16171+ the host.
16172+
16173+Arguments:
16174+
16175+ AdapterExtension - Which adapter to enable.
16176+
16177+ AdapterEvent - Which adapter event.
16178+
16179+ AtDeviceIrq - Whether the system is in DEVICE irql
16180+
16181+Return Value:
16182+
16183+ Nothing.
16184+
16185+--*/
16186+VOID
16187+SaDisableInterrupt (PVOID Arg1, ADAPTER_EVENT AdapterEvent, BOOLEAN AtDeviceIrq)
16188+{
16189+ PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
16190+ PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) CommonExtension->MiniPort;
16191+
16192+ switch (AdapterEvent) {
16193+
16194+
16195+ case HostNormCmdQue:
16196+
16197+ Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRISETIRQMASK, DOORBELL_1 );
16198+
16199+ break;
16200+
16201+ case HostNormRespQue:
16202+
16203+ Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRISETIRQMASK, DOORBELL_2 );
16204+
16205+ break;
16206+
16207+ case AdapNormCmdNotFull:
16208+
16209+ Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRISETIRQMASK, DOORBELL_3 );
16210+
16211+ break;
16212+
16213+
16214+ case AdapNormRespNotFull:
16215+
16216+ Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRISETIRQMASK, DOORBELL_4 );
16217+
16218+ break;
16219+
16220+ }
16221+
16222+}
16223+
16224+
16225+SaDetachDevice (IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension)
16226+{
16227+ PSa_ADAPTER_EXTENSION AdapterExtension = CommonExtension->MiniPort;
16228+
16229+ //
16230+ // Free the register mapping.
16231+ //
16232+
16233+ OsDetachDevice(AdapterExtension);
16234+
16235+ OsFreeMemory( AdapterExtension, sizeof(Sa_ADAPTER_EXTENSION) );
16236+
16237+}
16238+
16239+
16240+/*++
16241+
16242+Routine Description:
16243+
16244+ Scans the PCI bus looking for the Sa card. When found all resources for the
16245+ device will be allocated and the interrupt vectors and csrs will be allocated and
16246+ mapped.
16247+
16248+ The device_interface in the commregion will be allocated and linked to the comm region.
16249+
16250+Arguments:
16251+
16252+
16253+Return Value:
16254+
16255+ TRUE - if the device was setup with not problems
16256+ FALSE - if the device could not be mapped and init successfully
16257+
16258+--*/
16259+int
16260+SaInitDevice (IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
16261+ IN ULONG AdapterNumber, IN ULONG PciBus,
16262+ IN ULONG PciSlot)
16263+{
16264+ AAC_STATUS Status;
16265+ PSa_ADAPTER_EXTENSION AdapterExtension = NULL;
16266+ FSA_NEW_ADAPTER NewAdapter;
16267+ ULONG StartTime, EndTime, WaitTime;
16268+ ULONG InitStatus;
16269+ int instance;
16270+ char *name;
16271+
16272+ AfaPortPrint("In init device.\n");
16273+
16274+ CommonExtension->AdapterNumber = AdapterNumber;
16275+
16276+ CommonExtension->PciBusNumber = PciBus;
16277+ CommonExtension->PciSlotNumber = PciSlot;
16278+
16279+ AdapterExtension = OsAllocMemory( sizeof(Sa_ADAPTER_EXTENSION), OS_ALLOC_MEM_SLEEP );
16280+ AdapterExtension->Common = CommonExtension;
16281+ CommonExtension->MiniPort = AdapterExtension;
16282+
16283+ instance = OsGetDeviceInstance(AdapterExtension);
16284+ name = OsGetDeviceName(AdapterExtension);
16285+
16286+ //
16287+ // Map in the registers from the adapter, register space 0 is config space,
16288+ // register space 1 is the memery space.
16289+ //
16290+
16291+ if (OsMapDeviceRegisters(AdapterExtension)){
16292+ cmn_err(CE_WARN, "%s%d SaInitDevice: failed OsMapDeviceRegisters", name, instance);
16293+ return(FAILURE);
16294+ }
16295+
16296+
16297+ //
16298+ // Check to see if the board failed any self tests.
16299+ //
16300+
16301+ if (Sa_READ_ULONG( AdapterExtension, Mailbox7) & SELF_TEST_FAILED) {
16302+
16303+ cmn_err(CE_WARN, "%s%d: adapter self-test failed\n",
16304+ name, instance);
16305+ return(FAILURE);
16306+ }
16307+
16308+ //
16309+ // Check to see if the board panic'd while booting.
16310+ //
16311+
16312+ if (Sa_READ_ULONG( AdapterExtension, Mailbox7) & KERNEL_PANIC) {
16313+
16314+ cmn_err(CE_WARN, "%s%d: adapter kernel panic'd\n",
16315+ name, instance);
16316+ return(FAILURE);
16317+ }
16318+
16319+
16320+ StartTime = OsGetSeconds();
16321+ WaitTime = 0;
16322+
16323+
16324+ //
16325+ // Wait for the adapter to be up and running. Wait up until 3 minutes.
16326+ //
16327+
16328+ while (!(Sa_READ_ULONG( AdapterExtension, Mailbox7) & KERNEL_UP_AND_RUNNING)) {
16329+
16330+ EndTime = OsGetSeconds();
16331+
16332+ WaitTime = EndTime - StartTime;
16333+
16334+ if ( WaitTime > (3 * 60) ) {
16335+
16336+ InitStatus = Sa_READ_ULONG( AdapterExtension, Mailbox7) >> 16;
16337+
16338+ cmn_err(CE_WARN, "%s%d: adapter kernel failed to start, init status = %d\n",
16339+ name, instance, InitStatus);
16340+ return(FAILURE);
16341+
16342+ }
16343+ }
16344+
16345+ if (OsAttachInterrupt(AdapterExtension, SaISR)) {
16346+ cmn_err(CE_WARN, "%s%d SaInitDevice: failed OsAttachIntterupt", name, instance);
16347+ return(FAILURE);
16348+ }
16349+
16350+ if (OsAttachDMA(AdapterExtension)) {
16351+ cmn_err(CE_WARN, "%s%d SaInitDevice: failed OsAttachDMA", name, instance);
16352+ return(FAILURE);
16353+ }
16354+
16355+
16356+ //
16357+ // Fill in the function dispatch table.
16358+ //
16359+
16360+ AdapterExtension->Common->AdapterFuncs.SizeOfFsaPortFuncs = sizeof(FSAPORT_FUNCS);
16361+ AdapterExtension->Common->AdapterFuncs.AllocateAdapterCommArea = AfaPortAllocateAdapterCommArea;
16362+ AdapterExtension->Common->AdapterFuncs.FreeAdapterCommArea = AfaPortFreeAdapterCommArea;
16363+ AdapterExtension->Common->AdapterFuncs.BuildSgMap = AfaPortBuildSgMap;
16364+ AdapterExtension->Common->AdapterFuncs.FreeDmaResources = AfaPortFreeDmaResources;
16365+ AdapterExtension->Common->AdapterFuncs.AllocateAndMapFibSpace = AfaPortAllocateAndMapFibSpace;
16366+ AdapterExtension->Common->AdapterFuncs.UnmapAndFreeFibSpace = AfaPortUnmapAndFreeFibSpace;
16367+ AdapterExtension->Common->AdapterFuncs.InterruptAdapter = SaInterruptAdapter;
16368+ AdapterExtension->Common->AdapterFuncs.EnableInterrupt = SaEnableInterrupt;
16369+ AdapterExtension->Common->AdapterFuncs.DisableInterrupt = SaDisableInterrupt;
16370+ AdapterExtension->Common->AdapterFuncs.NotifyAdapter = SaNotifyAdapter;
16371+ AdapterExtension->Common->AdapterFuncs.ResetDevice = SaResetDevice;
16372+ AdapterExtension->Common->AdapterFuncs.InterruptHost = NULL;
16373+
16374+ AdapterExtension->Common->AdapterFuncs.SendSynchFib = SaSendSynchFib;
16375+
16376+ NewAdapter.AdapterExtension = CommonExtension;
16377+ NewAdapter.AdapterFuncs = &AdapterExtension->Common->AdapterFuncs;
16378+ NewAdapter.AdapterInterruptsBelowDpc = FALSE;
16379+ NewAdapter.AdapterUserVars = SaUserVars;
16380+ NewAdapter.AdapterUserVarsSize = sizeof(SaUserVars) / sizeof(FSA_USER_VAR);
16381+
16382+ NewAdapter.Dip = CommonExtension->OsDep.dip;
16383+
16384+
16385+ if ( AfaCommInitNewAdapter( &NewAdapter ) == NULL) {
16386+ cmn_err(CE_WARN, "SaInitDevice: AfaCommInitNewAdapter failed\n");
16387+ return (FAILURE);
16388+ };
16389+
16390+
16391+ AdapterExtension->Common->Adapter = NewAdapter.Adapter;
16392+
16393+ if (AdapterExtension->Common->Adapter == NULL) {
16394+
16395+ AfaPortLogError(AdapterExtension->Common, FAILURE, NULL, 0);
16396+ cmn_err(CE_WARN, "%s%d SaInitDevice: No Adapter pointer", name, instance);
16397+
16398+ return (FAILURE);
16399+ }
16400+
16401+
16402+ //
16403+ // Start any kernel threads needed
16404+ OsStartKernelThreads(AdapterExtension);
16405+
16406+ //
16407+ // Tell the adapter that all is configure, and it can start accepting requests
16408+ //
16409+
16410+ SaStartAdapter(AdapterExtension);
16411+
16412+
16413+
16414+ //
16415+ // Put this adapter into the list of Sa adapters
16416+ //
16417+
16418+ AdapterExtension->Next = SaAdapterList;
16419+ SaAdapterList = AdapterExtension;
16420+
16421+ AdapterExtension->Common->AdapterConfigured = TRUE;
16422+
16423+
16424+#ifdef AACDISK
16425+ //
16426+ // Call the disk layer to initialize itself.
16427+ //
16428+
16429+ AfaDiskInitNewAdapter( AdapterExtension->Common->AdapterNumber, AdapterExtension->Common->Adapter );
16430+#endif
16431+
16432+
16433+init_done:
16434+
16435+ AdapterExtension->Common->AdapterPrintfsToScreen = FALSE;
16436+
16437+ OsAttachHBA(AdapterExtension);
16438+
16439+ return (0);
16440+
16441+init_error:
16442+
16443+ return (FAILURE);
16444+}
16445+
16446+
16447+
16448+VOID
16449+SaStartAdapter (PSa_ADAPTER_EXTENSION AdapterExtension)
16450+{
16451+ ULONG ReturnStatus;
16452+ LARGE_INTEGER HostTime;
16453+ ULONG ElapsedSeconds;
16454+ PADAPTER_INIT_STRUCT InitStruct;
16455+
16456+ //
16457+ // Fill in the remaining pieces of the InitStruct.
16458+ //
16459+
16460+ InitStruct = AdapterExtension->Common->InitStruct;
16461+
16462+ InitStruct->HostPhysMemPages = AfaPortGetMaxPhysicalPage(AdapterExtension->Common);
16463+
16464+ ElapsedSeconds = OsGetSeconds();
16465+
16466+ InitStruct->HostElapsedSeconds = ElapsedSeconds;
16467+
16468+ //
16469+ // Tell the adapter we are back and up and running so it will scan its command
16470+ // queues and enable our interrupts
16471+ //
16472+
16473+ AdapterExtension->LocalMaskInterruptControl =
16474+ (PrintfReady | DOORBELL_1 | DOORBELL_2 | DOORBELL_3 | DOORBELL_4);
16475+
16476+
16477+ //
16478+ // First clear out all interrupts. Then enable the one's that we can handle.
16479+ //
16480+
16481+ Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRISETIRQMASK, (USHORT) 0xffff );
16482+ Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRICLEARIRQMASK,
16483+ (PrintfReady | DOORBELL_1 | DOORBELL_2 | DOORBELL_3 | DOORBELL_4) );
16484+
16485+ SaSendSynchCommand(AdapterExtension,
16486+ INIT_STRUCT_BASE_ADDRESS,
16487+ (ULONG) AdapterExtension->Common->PhysicalInitStruct,
16488+ 0,
16489+ 0,
16490+ 0,
16491+ &ReturnStatus);
16492+
16493+}
16494+
16495+
16496+VOID
16497+SaResetDevice (PVOID Arg1){
16498+
16499+}
16500+
16501+
16502+/*++
16503+
16504+Routine Description:
16505+
16506+ The will cause the adapter to take a break point.
16507+
16508+Arguments:
16509+
16510+ None
16511+
16512+Return Value:
16513+
16514+ Nothing
16515+
16516+--*/
16517+VOID
16518+SaInterruptAdapter (PVOID Arg1)
16519+{
16520+ PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
16521+ PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) CommonExtension->MiniPort;
16522+
16523+ ULONG ReturnStatus;
16524+
16525+ SaSendSynchCommand(AdapterExtension,
16526+ BREAKPOINT_REQUEST,
16527+ 0,
16528+ 0,
16529+ 0,
16530+ 0,
16531+ &ReturnStatus);
16532+
16533+}
16534+
16535+
16536+/*++
16537+
16538+Routine Description:
16539+
16540+ Will read the adapter CSRs to find the reason the adapter has
16541+ interrupted us.
16542+
16543+Arguments:
16544+
16545+ AdapterEvent - Enumerated type the returns the reason why we were interrutped.
16546+
16547+Return Value:
16548+
16549+ Nothing
16550+
16551+--*/
16552+VOID
16553+SaNotifyAdapter (PVOID Arg1, IN HOST_2_ADAP_EVENT AdapterEvent)
16554+{
16555+ PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
16556+ PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) CommonExtension->MiniPort;
16557+ ULONG ReturnStatus;
16558+
16559+ switch (AdapterEvent) {
16560+ case AdapNormCmdQue:
16561+
16562+ Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_1);
16563+ break;
16564+
16565+ case HostNormRespNotFull:
16566+
16567+ Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_4);
16568+ break;
16569+
16570+ case AdapNormRespQue:
16571+
16572+ Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_2);
16573+ break;
16574+
16575+ case HostNormCmdNotFull:
16576+
16577+ Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_3);
16578+ break;
16579+
16580+ case HostShutdown:
16581+
16582+// SaSendSynchCommand(AdapterExtension, HOST_CRASHING, 0, 0, 0, 0, &ReturnStatus);
16583+
16584+ break;
16585+
16586+ case FastIo:
16587+ Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_6);
16588+ break;
16589+
16590+ case AdapPrintfDone:
16591+ Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_5);
16592+ break;
16593+
16594+ default:
16595+
16596+ SaBugCheck(0,0,0);
16597+ AfaPortPrint("Notify requested with an invalid request 0x%x.\n",AdapterEvent);
16598+ break;
16599+ }
16600+}
16601+
16602+
16603+/*++
16604+
16605+Routine Description:
16606+
16607+ This routine will send a synchronous comamnd to the adapter and wait for its
16608+ completion.
16609+
16610+Arguments:
16611+
16612+ AdapterExtension - Pointer to adapter extension structure.
16613+ Command - Which command to send
16614+ Parameter1 - 4 - Parameters for command
16615+ ReturnStatus - return status from adapter after completion of command
16616+
16617+
16618+Return Value:
16619+
16620+ AAC_STATUS
16621+
16622+--*/
16623+AAC_STATUS
16624+SaSendSynchCommand(
16625+ PVOID Arg1,
16626+ ULONG Command,
16627+ ULONG Parameter1,
16628+ ULONG Parameter2,
16629+ ULONG Parameter3,
16630+ ULONG Parameter4,
16631+ PULONG ReturnStatus
16632+ )
16633+{
16634+ PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) Arg1;
16635+ ULONG StartTime,EndTime,WaitTime;
16636+ BOOLEAN CommandSucceeded;
16637+
16638+ //
16639+ // Write the Command into Mailbox 0
16640+ //
16641+
16642+ Sa_WRITE_ULONG( AdapterExtension, Mailbox0, Command);
16643+
16644+ //
16645+ // Write the parameters into Mailboxes 1 - 4
16646+ //
16647+
16648+ Sa_WRITE_ULONG( AdapterExtension, Mailbox1, Parameter1);
16649+ Sa_WRITE_ULONG( AdapterExtension, Mailbox2, Parameter2);
16650+ Sa_WRITE_ULONG( AdapterExtension, Mailbox3, Parameter3);
16651+ Sa_WRITE_ULONG( AdapterExtension, Mailbox4, Parameter4);
16652+
16653+ //
16654+ // Clear the synch command doorbell to start on a clean slate.
16655+ //
16656+
16657+ Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p, DOORBELL_0);
16658+
16659+ //
16660+ // Signal that there is a new synch command
16661+ //
16662+
16663+ Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s, DOORBELL_0);
16664+
16665+ CommandSucceeded = FALSE;
16666+
16667+ StartTime = OsGetSeconds();
16668+ WaitTime = 0;
16669+
16670+ while (WaitTime < 30) { // wait up to 30 seconds
16671+
16672+ drv_usecwait(5); // delay 5 microseconds to let Mon960 get info.
16673+
16674+ //
16675+ // Mon110 will set doorbell0 bit when it has completed the command.
16676+ //
16677+
16678+ if( Sa_READ_USHORT( AdapterExtension, DoorbellReg_p) & DOORBELL_0 ) {
16679+
16680+ CommandSucceeded = TRUE;
16681+ break;
16682+ }
16683+
16684+ EndTime = OsGetSeconds();
16685+ WaitTime = EndTime - StartTime;
16686+
16687+ }
16688+
16689+ if (CommandSucceeded != TRUE) {
16690+
16691+ return (STATUS_IO_TIMEOUT);
16692+
16693+ }
16694+
16695+ //
16696+ // Clear the synch command doorbell.
16697+ //
16698+
16699+ Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p, DOORBELL_0);
16700+
16701+ //
16702+ // Pull the synch status from Mailbox 0.
16703+ //
16704+
16705+ *ReturnStatus = Sa_READ_ULONG( AdapterExtension, Mailbox0);
16706+
16707+ //
16708+ // Return SUCCESS
16709+ //
16710+
16711+ return (STATUS_SUCCESS);
16712+
16713+}
16714+
16715+
16716+/*++
16717+
16718+Routine Description:
16719+
16720+ This routine will send a synchronous fib to the adapter and wait for its
16721+ completion.
16722+
16723+Arguments:
16724+
16725+ AdapterExtension - Pointer to adapter extension structure.
16726+ FibPhysicalAddress - Physical address of fib to send.
16727+
16728+
16729+Return Value:
16730+
16731+ BOOLEAN
16732+
16733+--*/
16734+BOOLEAN
16735+SaSendSynchFib (PVOID Arg1, ULONG FibPhysicalAddress)
16736+{
16737+ PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
16738+ PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) CommonExtension->MiniPort;
16739+ ULONG returnStatus;
16740+
16741+ if (SaSendSynchCommand( AdapterExtension,
16742+ SEND_SYNCHRONOUS_FIB,
16743+ FibPhysicalAddress,
16744+ 0,
16745+ 0,
16746+ 0,
16747+ &returnStatus ) != STATUS_SUCCESS ) {
16748+
16749+ return (FALSE);
16750+
16751+ }
16752+
16753+ return (TRUE);
16754+
16755+}
16756+
16757+BOOLEAN
16758+WriteFlash(
16759+ PVOID AdapterExtension,
16760+ ULONG *MappedBuffer)
16761+{
16762+ return (FALSE);
16763+}
16764+
16765+BOOLEAN
16766+ReadFlash(
16767+ PVOID AdapterExtension,
16768+ ULONG *MappedBuffer)
16769+{
16770+ return (FALSE);
16771+}
16772+
16773diff -burN linux-2.4.9/drivers/scsi/scsi_scan.c linux/drivers/scsi/scsi_scan.c
16774--- linux-2.4.9/drivers/scsi/scsi_scan.c Thu Aug 16 13:40:31 2001
16775+++ linux/drivers/scsi/scsi_scan.c Thu Aug 16 18:10:10 2001
16776@@ -160,6 +160,8 @@
16777 {"SONY", "TSL", "*", BLIST_FORCELUN}, // DDS3 & DDS4 autoloaders
16778 {"DELL", "PERCRAID", "*", BLIST_FORCELUN},
16779 {"HP", "NetRAID-4M", "*", BLIST_FORCELUN},
16780+ {"ADAPTEC", "AACRAID", "*", BLIST_FORCELUN},
16781+ {"ADAPTEC", "Adaptec 5400S", "*", BLIST_FORCELUN},
16782
16783 /*
16784 * Must be at end of list...
This page took 6.151651 seconds and 4 git commands to generate.